8 Commits

Author SHA1 Message Date
362fb9ada9 fix: address v0.5.0 review findings
- Add --to/--test-cmd mutual exclusivity guard in rollback script
- Convert all jq string interpolation to --arg (cmd_extract, cmd_inject, cmd_forget)
- Fix CRITICAL/WARNING grep to match table rows only (not prose)
- Add thorough+cycle-1 guard to fast-path bash snippet in check-phase
- Clarify prev_run_id selection comment (tail -1 = most recent non-current)
2026-04-04 08:44:16 +02:00
c3f5df8161 docs: update CHANGELOG and version for v0.5.0 2026-04-04 08:44:16 +02:00
c5174e88eb feat: flesh out check-phase with parallel reviewer spawning protocol 2026-04-04 08:44:16 +02:00
5e2117c9be feat: add cross-run finding regression detection 2026-04-04 08:44:16 +02:00
30ddc6a2c4 feat: add per-workflow model assignment configuration 2026-04-04 08:44:16 +02:00
e09538e5e0 feat: add phase rollback support to archeflow-rollback.sh 2026-04-04 08:44:16 +02:00
92b56e714b docs: add hook points documentation and config template 2026-04-04 08:44:16 +02:00
008315b0c4 feat: add lib script validation at run initialization 2026-04-04 08:44:16 +02:00
12 changed files with 508 additions and 28 deletions

View File

@@ -1,7 +1,7 @@
# ArcheFlow Configuration
# Copy to your project's .archeflow/config.yaml and customize
version: "0.3.0"
version: "0.5.0"
# Budget
costs:
@@ -26,7 +26,54 @@ memory:
max_lessons: 10
decay_after_runs: 10
# Models — default and per-archetype/per-workflow model selection.
# ArcheFlow reads this to assign models to agents. The default applies unless overridden.
models:
default: sonnet
# Per-archetype overrides (uncomment to customize):
# archetypes:
# explorer: haiku # Cheap model for research/exploration
# creator: sonnet # Creative tasks need stronger model
# maker: sonnet # Implementation needs full capability
# guardian: sonnet # Security review — don't skimp
# skeptic: haiku # Assumption checking is analytical
# sage: haiku # Quality review can use cheaper model
# trickster: sonnet # Adversarial testing benefits from stronger model
# Per-workflow overrides (uncomment to customize):
# workflows:
# fast:
# default: haiku # Fast workflow uses cheaper models by default
# archetypes:
# guardian: sonnet # Except Guardian — always needs strong model
# standard:
# default: sonnet
# thorough:
# default: sonnet
# Progress
progress:
enabled: true
file: .archeflow/progress.md
# Hooks — commands to run at orchestration lifecycle events.
# Uncomment and customize as needed.
#
# hooks:
# run-start:
# command: "echo 'ArcheFlow run starting'"
# fail_action: warn # warn | abort
# phase-complete:
# command: "./scripts/on-phase-complete.sh"
# fail_action: warn
# agent-complete:
# command: "./scripts/on-agent-complete.sh"
# fail_action: warn
# pre-merge:
# command: "./scripts/pre-merge-checks.sh"
# fail_action: abort # abort recommended — blocks bad merges
# post-merge:
# command: "./scripts/post-merge-notify.sh"
# fail_action: warn
# run-complete:
# command: "./scripts/on-run-complete.sh"
# fail_action: warn

View File

@@ -1,7 +1,7 @@
{
"name": "archeflow",
"description": "Multi-agent orchestration with Jungian archetypes. PDCA quality cycles, shadow detection, git worktree isolation. Zero dependencies — works with any Claude Code session.",
"version": "0.3.0",
"version": "0.5.0",
"author": {
"name": "Chris Nennemann"
},

View File

@@ -2,6 +2,16 @@
All notable changes to ArcheFlow are documented in this file.
## [0.5.0] -- 2026-04-04
### Added
- Lib script validation at run initialization — fail fast if required scripts or `jq` are missing
- Hook points documentation with 6 lifecycle events (run-start, phase-complete, agent-complete, pre-merge, post-merge, run-complete) and config template
- Phase rollback support in `archeflow-rollback.sh` via `--to <phase>` flag
- Per-workflow model assignment configuration with fallback chain (per-workflow per-archetype > per-workflow default > per-archetype > global default)
- Cross-run finding regression detection in `archeflow-memory.sh` — compares current findings against previously resolved fixes
- Check-phase parallel reviewer spawning protocol with Guardian-first sequence, A2 fast-path evaluation, timeout handling, and re-check protocol
## [0.3.0] -- 2026-04-03
### Added

View File

@@ -309,7 +309,7 @@ archetypes: [explorer, creator, maker, guardian, db-specialist]
```
archeflow/
├── .claude-plugin/plugin.json # Plugin manifest (v0.3.0)
├── .claude-plugin/plugin.json # Plugin manifest (v0.5.0)
├── agents/ # 7 archetype personas (behavioral protocols)
│ ├── explorer.md # Plan: research and context mapping
│ ├── creator.md # Plan: solution design and proposals

88
docs/hooks.md Normal file
View File

@@ -0,0 +1,88 @@
# ArcheFlow Hook Points
Hooks let you run custom commands at key points during an ArcheFlow orchestration run. Use them for notifications, custom validation, CI integration, or project-specific checks.
## Available Hooks
| Hook | When | Env Vars | Default `fail_action` |
|------|------|----------|----------------------|
| `run-start` | After initialization, before Plan phase begins | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_WORKFLOW`, `ARCHEFLOW_TASK` | `warn` |
| `phase-complete` | After each PDCA phase finishes | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_PHASE`, `ARCHEFLOW_CYCLE` | `warn` |
| `agent-complete` | After each agent returns | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_AGENT`, `ARCHEFLOW_PHASE`, `ARCHEFLOW_DURATION_MS` | `warn` |
| `pre-merge` | After all reviewers approve, before merging to target branch | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_BRANCH`, `ARCHEFLOW_TARGET` | `abort` |
| `post-merge` | After successful merge to target branch | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_BRANCH`, `ARCHEFLOW_MERGE_COMMIT` | `warn` |
| `run-complete` | After the run finishes (success or failure) | `ARCHEFLOW_RUN_ID`, `ARCHEFLOW_STATUS`, `ARCHEFLOW_CYCLES`, `ARCHEFLOW_DURATION_S` | `warn` |
## Configuration
Add a `hooks:` section to your project's `.archeflow/config.yaml`:
```yaml
hooks:
run-start:
command: "echo 'Run starting: $ARCHEFLOW_RUN_ID'"
fail_action: warn
pre-merge:
command: "./scripts/lint-check.sh"
fail_action: abort
run-complete:
command: "curl -X POST https://slack.example.com/webhook -d '{\"text\": \"ArcheFlow run $ARCHEFLOW_STATUS\"}'"
fail_action: warn
```
Each hook entry has two fields:
- **`command`** -- shell command to execute. Env vars are available. Runs with `bash -c`.
- **`fail_action`** -- what happens if the command exits non-zero:
- `warn` -- log a warning, continue the run
- `abort` -- stop the run immediately, report the failure
## `fail_action` Semantics
| `fail_action` | On command exit 0 | On command exit non-zero |
|---------------|-------------------|------------------------|
| `warn` | Continue silently | Log warning, continue |
| `abort` | Continue silently | Emit `decision` event with `"chosen":"hook_abort"`, halt run, report to user |
**Recommended settings:**
- Use `abort` for `pre-merge` -- a failing pre-merge check should block the merge
- Use `warn` for informational hooks (`run-start`, `run-complete`, `post-merge`)
- Use `warn` for `agent-complete` and `phase-complete` unless you have strict SLA requirements
## Examples
### Slack notification on run complete
```yaml
hooks:
run-complete:
command: >
curl -s -X POST "$SLACK_WEBHOOK_URL"
-H 'Content-Type: application/json'
-d '{"text":"ArcheFlow run '"$ARCHEFLOW_RUN_ID"' '"$ARCHEFLOW_STATUS"' ('"$ARCHEFLOW_CYCLES"' cycles, '"$ARCHEFLOW_DURATION_S"'s)"}'
fail_action: warn
```
### Pre-merge lint gate
```yaml
hooks:
pre-merge:
command: "npm run lint && npm run typecheck"
fail_action: abort
```
### Log phase timing
```yaml
hooks:
phase-complete:
command: "echo \"$(date -u +%H:%M:%S) phase=$ARCHEFLOW_PHASE cycle=$ARCHEFLOW_CYCLE run=$ARCHEFLOW_RUN_ID\" >> .archeflow/phase-timing.log"
fail_action: warn
```
## Hook Execution
Hooks are executed by the `archeflow:run` skill at the corresponding lifecycle point. The command runs in the project root directory with `bash -c`. A 30-second timeout applies to each hook -- if a hook exceeds this, it is killed and treated as a failure (subject to `fail_action`).
Hooks are optional. If no `hooks:` section exists in config, no hooks run. If a specific hook event is not configured, it is silently skipped.

View File

@@ -11,6 +11,7 @@
# ./lib/archeflow-memory.sh list # List all active lessons
# ./lib/archeflow-memory.sh decay # Apply decay to all lessons
# ./lib/archeflow-memory.sh forget <id> # Archive a lesson by ID
# ./lib/archeflow-memory.sh regression-check <events> # Detect regressions from previously fixed findings
#
# Dependencies: jq, bash 4+
@@ -140,14 +141,14 @@ cmd_extract() {
if [[ "$overlap" -ge 50 ]]; then
# Match found — update existing lesson
local tmp_file="${LESSONS_FILE}.tmp"
jq -c "
if .id == \"$lesson_id\" then
jq -c --arg lid "$lesson_id" --arg ts "$(now_ts)" --arg rid "$run_id" '
if .id == $lid then
.frequency += 1 |
.ts = \"$(now_ts)\" |
.last_seen_run = \"$run_id\" |
.ts = $ts |
.last_seen_run = $rid |
.runs_since_last_seen = 0
else . end
" "$LESSONS_FILE" > "$tmp_file"
' "$LESSONS_FILE" > "$tmp_file"
mv "$tmp_file" "$LESSONS_FILE"
matched=true
updated=$((updated + 1))
@@ -223,25 +224,25 @@ cmd_inject() {
# - Filter by domain (match or "general") and archetype (if provided)
# - Sort by frequency desc, cap at 10
local lessons
lessons=$(jq -c "
lessons=$(jq -c --arg domain "$domain" --arg archetype "$archetype" '
select(
(.type == \"preference\") or
(.type == "preference") or
(.frequency >= 5) or
(
(.frequency >= 2) and
(
(\"$domain\" == \"\") or
(.domain == \"$domain\") or
(.domain == \"general\")
($domain == "") or
(.domain == $domain) or
(.domain == "general")
) and
(
(\"$archetype\" == \"\") or
($archetype == "") or
(.archetype == null) or
(.archetype == \"$archetype\")
(.archetype == $archetype)
)
)
)
" "$LESSONS_FILE" 2>/dev/null | jq -sc 'sort_by(-.frequency) | .[:10][]' 2>/dev/null || true)
' "$LESSONS_FILE" 2>/dev/null | jq -sc 'sort_by(-.frequency) | .[:10][]' 2>/dev/null || true)
if [[ -z "$lessons" ]]; then
return 0
@@ -361,6 +362,88 @@ cmd_audit_check() {
done <<< "$lesson_ids"
}
cmd_regression_check() {
local events_file="${1:?Usage: $0 regression-check <events.jsonl>}"
if [[ ! -f "$events_file" ]]; then
echo "Error: events file not found: $events_file" >&2
exit 1
fi
# Extract current run_id
local run_id
run_id=$(jq -r '.run_id' "$events_file" | head -1)
# Find the previous run from index.jsonl
local INDEX_FILE=".archeflow/events/index.jsonl"
if [[ ! -f "$INDEX_FILE" ]]; then
echo "[archeflow-memory] No index.jsonl found — skipping regression check." >&2
return 0
fi
local prev_run_id
# Get the most recent run that is not the current one (index is append-newest-last)
prev_run_id=$(jq -r --arg rid "$run_id" 'select(.run_id != $rid) | .run_id' "$INDEX_FILE" 2>/dev/null | tail -1)
# Note: tail -1 gives the last non-current entry, which is the most recent previous run
if [[ -z "$prev_run_id" ]]; then
echo "[archeflow-memory] No previous run found — skipping regression check." >&2
return 0
fi
local prev_events=".archeflow/events/${prev_run_id}.jsonl"
if [[ ! -f "$prev_events" ]]; then
echo "[archeflow-memory] Previous run events not found: $prev_events" >&2
return 0
fi
# Extract resolved findings from previous run (fix.applied events)
local resolved_findings
resolved_findings=$(jq -r 'select(.type == "fix.applied") | .data.finding // empty' "$prev_events" 2>/dev/null || true)
if [[ -z "$resolved_findings" ]]; then
echo "[archeflow-memory] No resolved findings in previous run — nothing to regress." >&2
return 0
fi
# Extract current run findings from review.verdict events
local current_findings
current_findings=$(jq -r '
select(.type == "review.verdict") |
.data.findings[]? | .description // empty
' "$events_file" 2>/dev/null || true)
if [[ -z "$current_findings" ]]; then
echo "[archeflow-memory] No findings in current run — no regressions." >&2
return 0
fi
# Compare: for each resolved finding, check if it reappeared
local regressions=0
while IFS= read -r resolved; do
[[ -z "$resolved" ]] && continue
while IFS= read -r current; do
[[ -z "$current" ]] && continue
local overlap
overlap=$(keyword_overlap "$resolved" "$current")
if [[ "$overlap" -ge 50 ]]; then
echo "REGRESSION: \"$resolved\" (fixed in $prev_run_id) reappeared as \"$current\""
regressions=$((regressions + 1))
break
fi
done <<< "$current_findings"
done <<< "$resolved_findings"
if [[ "$regressions" -gt 0 ]]; then
echo "[archeflow-memory] $regressions regression(s) detected from run $prev_run_id." >&2
return 1
else
echo "[archeflow-memory] No regressions detected." >&2
return 0
fi
}
cmd_add() {
local type="${1:-preference}"
local desc="${2:-}"
@@ -474,17 +557,17 @@ cmd_forget() {
ensure_dir
# Check if the lesson exists
if ! jq -e "select(.id == \"$target_id\")" "$LESSONS_FILE" > /dev/null 2>&1; then
if ! jq -e --arg tid "$target_id" 'select(.id == $tid)' "$LESSONS_FILE" > /dev/null 2>&1; then
echo "Error: lesson $target_id not found." >&2
exit 1
fi
# Archive the lesson
jq -c "select(.id == \"$target_id\")" "$LESSONS_FILE" >> "$ARCHIVE_FILE"
jq -c --arg tid "$target_id" 'select(.id == $tid)' "$LESSONS_FILE" >> "$ARCHIVE_FILE"
# Remove from lessons
local tmp_file="${LESSONS_FILE}.tmp"
jq -c "select(.id != \"$target_id\")" "$LESSONS_FILE" > "$tmp_file"
jq -c --arg tid "$target_id" 'select(.id != $tid)' "$LESSONS_FILE" > "$tmp_file"
mv "$tmp_file" "$LESSONS_FILE"
echo "[archeflow-memory] Forgot lesson $target_id (moved to archive)" >&2
@@ -503,6 +586,7 @@ if [[ $# -lt 1 ]]; then
echo " decay Apply decay to all lessons" >&2
echo " forget <id> Archive a lesson by ID" >&2
echo " audit-check <run_id> Check lesson effectiveness for a run" >&2
echo " regression-check <events.jsonl> Detect regressions from previously fixed findings" >&2
exit 1
fi
@@ -535,6 +619,10 @@ case "$COMMAND" in
[[ $# -lt 1 ]] && { echo "Usage: $0 audit-check <run_id>" >&2; exit 1; }
cmd_audit_check "$1"
;;
regression-check)
[[ $# -lt 1 ]] && { echo "Usage: $0 regression-check <events.jsonl>" >&2; exit 1; }
cmd_regression_check "$1"
;;
*)
echo "Unknown command: $COMMAND" >&2
exit 1

View File

@@ -1,26 +1,73 @@
#!/usr/bin/env bash
# archeflow-rollback.sh — Auto-revert a merge that fails post-merge tests.
# archeflow-rollback.sh — Auto-revert a merge that fails post-merge tests,
# or roll back to a specific PDCA phase boundary.
#
# Usage: archeflow-rollback.sh <run_id> [--test-cmd <cmd>]
# Usage:
# archeflow-rollback.sh <run_id> [--test-cmd <cmd>] # Post-merge test + revert
# archeflow-rollback.sh <run_id> --to <phase> # Roll back to phase boundary
#
# If --test-cmd not provided, reads test_command from .archeflow/config.yaml.
# Returns 0 if tests pass, 1 if tests fail (merge reverted).
# --to <phase>: Roll back to the given phase boundary (plan, do, or check).
# Delegates to archeflow-git.sh rollback and emits a decision event.
#
# If --test-cmd not provided (and --to not used), reads test_command from .archeflow/config.yaml.
# Returns 0 if tests pass (or rollback succeeds), 1 if tests fail (merge reverted).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
RUN_ID="${1:?Usage: archeflow-rollback.sh <run_id> [--test-cmd <cmd>]}"
RUN_ID="${1:?Usage: archeflow-rollback.sh <run_id> [--test-cmd <cmd>] [--to <phase>]}"
shift
# Parse optional --test-cmd
# Parse options
TEST_CMD=""
TARGET_PHASE=""
while [[ $# -gt 0 ]]; do
case "$1" in
--test-cmd) TEST_CMD="$2"; shift 2 ;;
--to) TARGET_PHASE="$2"; shift 2 ;;
*) echo "Unknown option: $1" >&2; exit 2 ;;
esac
done
# Mutual exclusivity check
if [[ -n "$TARGET_PHASE" && -n "$TEST_CMD" ]]; then
echo "ERROR: --to and --test-cmd are mutually exclusive." >&2
exit 2
fi
# --- Phase rollback mode ---
if [[ -n "$TARGET_PHASE" ]]; then
# Validate phase name
case "$TARGET_PHASE" in
plan|do|check) ;;
*)
echo "ERROR: Invalid phase '$TARGET_PHASE'. Must be one of: plan, do, check" >&2
exit 2
;;
esac
echo "Rolling back run $RUN_ID to phase boundary: $TARGET_PHASE"
# Delegate to archeflow-git.sh
if [[ ! -x "$SCRIPT_DIR/archeflow-git.sh" ]]; then
echo "ERROR: archeflow-git.sh not found or not executable" >&2
exit 1
fi
"$SCRIPT_DIR/archeflow-git.sh" rollback "$RUN_ID" --to "$TARGET_PHASE"
# Emit decision event
if [[ -x "$SCRIPT_DIR/archeflow-event.sh" ]]; then
"$SCRIPT_DIR/archeflow-event.sh" "$RUN_ID" decision act "" \
"{\"what\":\"phase_rollback\",\"chosen\":\"rollback_to_${TARGET_PHASE}\",\"rationale\":\"user requested rollback to ${TARGET_PHASE} phase boundary\"}" ""
fi
echo "Rollback to $TARGET_PHASE complete for run $RUN_ID."
exit 0
fi
# --- Post-merge test mode ---
# Read test_command from config if not provided
if [[ -z "$TEST_CMD" ]]; then
if [[ -f ".archeflow/config.yaml" ]]; then

View File

@@ -76,6 +76,108 @@ Use the higher severity. Don't double-count in the verdict.
→ Build cycle feedback (see orchestration skill) and feed to Plan phase
```
## Reviewer Spawning Protocol
This section defines the exact sequence for spawning reviewers in the Check phase.
### Step 1: Guardian First (mandatory)
Guardian always runs first, before any other reviewer. It receives the Maker's git diff and the proposal's risk section only.
**Context for Guardian:**
- `git diff main...<maker-branch>` (the actual code changes)
- Risk section from `plan-creator.md` (if present)
- Do NOT include: Explorer research, full proposal, other reviewer outputs
```
Agent(
description: "Guardian: security and risk review for <task>",
prompt: "You are the GUARDIAN archetype.
Review the diff: <maker's diff>
Proposal risks: <risk section from plan-creator.md>
Assess: security vulnerabilities, reliability risks, breaking changes, dependency risks.
Output: APPROVED or REJECTED with findings in the standardized format.
Each finding: | Location | Severity | Category | Description | Fix |",
model: <resolve_model guardian $WORKFLOW>
)
```
Save output to `.archeflow/artifacts/${RUN_ID}/check-guardian.md`.
### Step 2: A2 Fast-Path Evaluation
After Guardian completes, parse its output before spawning other reviewers:
```bash
CRITICAL_COUNT=$(grep -c "| CRITICAL |" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
WARNING_COUNT=$(grep -c "| WARNING |" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
# A2 fast-path: skip remaining reviewers if Guardian is clean
# Exception: first cycle of thorough workflows always spawns all reviewers
if [[ "$CRITICAL_COUNT" -eq 0 && "$WARNING_COUNT" -eq 0 \
&& "$ESCALATED" != "true" \
&& ! ("$WORKFLOW" == "thorough" && "$CYCLE" -eq 1) ]]; then
echo "Guardian fast-path: 0 CRITICAL, 0 WARNING — skipping remaining reviewers."
# Proceed directly to Act phase
fi
```
### Step 3: Parallel Reviewer Spawning
If A2 does not trigger, spawn remaining reviewers in parallel based on workflow:
| Workflow | Reviewers (after Guardian) |
|----------|--------------------------|
| `fast` | None (Guardian only) |
| `fast` (escalated via A1) | Skeptic + Sage |
| `standard` | Skeptic + Sage |
| `thorough` | Skeptic + Sage + Trickster |
Spawn all applicable reviewers in a single message with multiple Agent calls:
```
# Standard workflow example — spawn Skeptic and Sage in parallel:
Agent(
description: "Skeptic: challenge assumptions for <task>",
prompt: "<Skeptic prompt with Creator's proposal>",
model: <resolve_model skeptic $WORKFLOW>
)
Agent(
description: "Sage: holistic quality review for <task>",
prompt: "<Sage prompt with proposal + diff + implementation summary>",
model: <resolve_model sage $WORKFLOW>
)
```
Each reviewer gets context per the attention filters defined in `archeflow:orchestration`:
- **Skeptic:** Creator's proposal (assumptions section focus)
- **Sage:** Creator's proposal + Maker's diff + implementation summary
- **Trickster:** Maker's diff only
### Step 4: Collect Results
Wait for all spawned reviewers to return. For each:
1. Save output to `.archeflow/artifacts/${RUN_ID}/check-<archetype>.md`
2. Emit `review.verdict` event with findings
3. Record sequence number for DAG parent tracking
### Timeout Handling
Each reviewer has a **5-minute timeout**. If a reviewer does not return within 5 minutes:
1. Emit `agent.complete` with `"error": true, "reason": "timeout"`
2. Log a WARNING — do not block the run
3. Treat the timed-out reviewer as having delivered no findings (neither approved nor rejected)
4. Proceed with available verdicts
If Guardian times out, this is a blocking failure — abort the Check phase and report to the user.
### Re-Check Protocol (Act Phase Fixes)
When the Act phase routes findings back to the Maker and the Maker applies fixes in a subsequent cycle, the Check phase re-runs with the updated diff. Reviewers who previously rejected should focus on whether their specific findings were addressed. The structured feedback from `act-feedback.md` provides the mapping of which findings were routed where.
---
## Why Structured Findings Matter
The standardized format enables:

View File

@@ -89,6 +89,12 @@ Events are optional — if the events dir doesn't exist, skip logging. Never let
---
## Model Configuration
Model assignment per archetype and workflow is configured in `.archeflow/config.yaml` under the `models:` section. The `archeflow:run` skill (section 0c) handles resolution with fallback chain: per-workflow per-archetype > per-workflow default > per-archetype > global default. When spawning agents manually, read the config to select the appropriate model.
---
## Step 1: Plan Phase
Spawn agents sequentially — Creator needs Explorer's findings.
@@ -188,6 +194,8 @@ Agent(
Spawn Guardian **first**. After Guardian completes, check adaptation rule A2 (fast-path). If A2 triggers (0 CRITICAL, 0 WARNING, non-escalated workflow), skip remaining reviewers and proceed to Act. Otherwise, spawn remaining reviewers **in parallel**.
**Reviewer spawning protocol:** The canonical sequence (Guardian first, A2 evaluation, parallel spawning, timeout handling) is defined in `archeflow:check-phase` under "Reviewer Spawning Protocol". Follow that protocol for the exact spawning order, context per reviewer, and timeout rules.
### Guardian (always runs first)
**Context to include:** Maker's git diff, proposal risk section only.

View File

@@ -89,12 +89,12 @@ Only show if the user explicitly asks or if `progress.dag_on_complete: true` in
When ArcheFlow activates at session start (via the `using-archeflow` skill), show ONE line:
```
archeflow v0.3.0 · 24 skills · writing domain detected
archeflow v0.5.0 · 24 skills · writing domain detected
```
Or for code projects:
```
archeflow v0.3.0 · 24 skills · code domain
archeflow v0.5.0 · 24 skills · code domain
```
If ArcheFlow decides NOT to activate (simple task, single file):

View File

@@ -63,6 +63,45 @@ After emitting `run.start`, record `SEQ_RUN_START=1`.
If `--start-from` is specified, verify that the required prior artifacts exist in `.archeflow/artifacts/${RUN_ID}/` before skipping phases. If missing, abort with an error.
#### 0a. Lib Script Validation
Verify that all required library scripts exist and are executable before proceeding. Fail fast if any dependency is missing.
```bash
# Required lib scripts
REQUIRED_LIBS=(
"archeflow-event.sh"
"archeflow-memory.sh"
"archeflow-git.sh"
"archeflow-rollback.sh"
"archeflow-report.sh"
"archeflow-progress.sh"
)
MISSING=()
for lib in "${REQUIRED_LIBS[@]}"; do
if [[ ! -x "./lib/$lib" ]]; then
MISSING+=("$lib")
fi
done
if [[ ${#MISSING[@]} -gt 0 ]]; then
echo "ERROR: Missing or non-executable lib scripts:" >&2
for m in "${MISSING[@]}"; do
echo " - lib/$m" >&2
done
echo "Ensure ArcheFlow is installed correctly. See README for setup." >&2
exit 1
fi
# Check jq availability (required for event processing and memory)
if ! command -v jq &>/dev/null; then
echo "ERROR: jq is required but not found in PATH." >&2
echo "Install with: apt install jq / brew install jq" >&2
exit 1
fi
```
#### 0b. Memory Injection
Load cross-run memory lessons and inject into agent prompts. Use `--audit` to track which lessons were injected for this run:
@@ -82,6 +121,49 @@ ${MEMORY_LESSONS}"
fi
```
#### 0c. Model Configuration
Read model assignment from `.archeflow/config.yaml` and resolve the model for each archetype based on the current workflow. Per-workflow overrides take precedence over per-archetype overrides, which take precedence over the default.
```bash
CONFIG=".archeflow/config.yaml"
# Read default model
DEFAULT_MODEL=$(grep -A1 '^models:' "$CONFIG" 2>/dev/null | grep 'default:' | sed 's/.*default:\s*//' | tr -d '"' | head -1)
DEFAULT_MODEL="${DEFAULT_MODEL:-sonnet}"
# Resolve model for a given archetype and workflow
# Usage: resolve_model <archetype> <workflow>
resolve_model() {
local arch="$1" wf="$2" model=""
# Check per-workflow per-archetype override
model=$(sed -n "/workflows:/,\$p" "$CONFIG" 2>/dev/null \
| sed -n "/${wf}:/,/^ [a-z]/p" \
| grep -A1 "archetypes:" | grep "${arch}:" \
| sed "s/.*${arch}:\s*//" | tr -d '"' | head -1)
[[ -n "$model" ]] && echo "$model" && return
# Check per-workflow default
model=$(sed -n "/workflows:/,\$p" "$CONFIG" 2>/dev/null \
| sed -n "/${wf}:/,/^ [a-z]/p" \
| grep 'default:' | sed 's/.*default:\s*//' | tr -d '"' | head -1)
[[ -n "$model" ]] && echo "$model" && return
# Check per-archetype override
model=$(sed -n "/^ archetypes:/,/^ [a-z]/p" "$CONFIG" 2>/dev/null \
| grep "${arch}:" | sed "s/.*${arch}:\s*//" | tr -d '"' | head -1)
[[ -n "$model" ]] && echo "$model" && return
# Fall back to default
echo "$DEFAULT_MODEL"
}
# Example: EXPLORER_MODEL=$(resolve_model explorer "$WORKFLOW")
```
Use `resolve_model` when spawning each agent to pass the correct model. The resolved model can be included in the `agent.start` event data for cost tracking.
---
### 1. Plan Phase
@@ -501,6 +583,14 @@ If `CYCLE >= MAX_CYCLES` and issues remain:
./lib/archeflow-event.sh "$RUN_ID" run.complete act "" \
'{"status":"completed","cycles":<N>,"agents_total":<count>,"fixes_total":<count>,"shadows":0,"artifacts":[<list>]}'
# Check for regressions from previously fixed findings
if ./lib/archeflow-memory.sh regression-check ".archeflow/events/${RUN_ID}.jsonl"; then
echo "No regressions detected."
else
echo "WARNING: Regressions detected — previously fixed findings have reappeared."
echo "Review the regression output above and consider addressing them."
fi
# Generate report
./lib/archeflow-report.sh .archeflow/events/${RUN_ID}.jsonl

View File

@@ -11,7 +11,7 @@ Multi-agent orchestration using archetypal roles and PDCA quality cycles.
On activation, print ONE line:
```
archeflow v0.3.0 · 25 skills · <domain> domain
archeflow v0.5.0 · 25 skills · <domain> domain
```
Where `<domain>` is auto-detected: `writing` if `colette.yaml` exists, `research` if paper/thesis files exist, `code` otherwise. Then proceed silently — no further announcement unless `archeflow:run` is invoked.