| name | proceed |
| description | End-to-end AIF pipeline that takes a requirement from spec through to deployed. Takes a REQ number as argument and runs validate → fix → architect → fix → implement → verify (reflect + review) → create PR → wrapup (merge, deploy, knowledge capture). Use when the user says "proceed", "proceed with REQ-xxx", "run the pipeline", "take REQ-xxx to completion", "implement REQ-xxx end to end", or wants to advance a drafted requirement all the way through to deployment in one shot. |
Proceed — Full AIF Pipeline
You are an autonomous AIF orchestrator. Given a requirement number (REQ-xxx), you drive it from validated spec all the way to a pull request — validating at each gate, fixing issues automatically, and only pausing when you're stuck or need human input.
Shape of the run
flowchart LR
P0[Phase 0<br/>manifest + draft PR] --> P13[Phases 1-3<br/>validate spec →<br/>architect → validate plan]
P13 --> P4[Phase 4<br/>implement tasks,<br/>parallel by tier]
P4 --> P5[Phase 5<br/>verify: reflect +<br/>review bench]
P5 --> G1{findings<br/>clean?}
G1 -- no --> P4
G1 -- yes --> P68[Phases 6-8<br/>PR ready → trial-merge<br/>gate → merge → wrapup]
P68 --> G2{trial-merge<br/>conflict?}
G2 -- yes --> HALT[blocked — human<br/>resolves, then resume]
G2 -- no --> DONE[merged + wrapped up]
Execution Mode
This skill supports two modes:
- Main conversation mode (default): Dispatches formal agents (defined in
~/.claude/agents/) for parallelism at Phase 4 (task implementation) and Phase 5 (verify). Use this mode when running /proceed directly.
- Subagent mode (when running as a
pipeline-runner agent inside /sprint): Execute ALL phases sequentially in-context. Do NOT dispatch sub-agents. At Phase 4, implement tasks one at a time. At Phase 5, run the reflector + reviewer checklists sequentially in your own context using the criteria from the agent definitions. Subagents cannot spawn other subagents.
You are in subagent mode if you were explicitly told so in your launch prompt.
Autonomous Execution Contract
/proceed is an autonomous orchestrator. It is designed to run end-to-end without human input. The skill has exactly three legitimate halt points; every other instruction below is a log step, not a pause:
- Validation fails 3 times at any gate (Phase 1 or Phase 3) — surface blockers.
- Reflector surfaces user-facing questions (Phase 5, Step C item 4) — surface as a numbered list and wait.
- Merge conflicts during rebase (Phase 8 / wrapup) — surface conflicts and wait.
For everything else — including every End-of-phase log block below, every agent dispatch, every commit, every PR creation, every CI wait — you continue immediately to the next step without asking the user. Prompt only for tool-level permissions on truly destructive operations (these are governed by .claude/settings.json, not this skill).
Writing logs vs asking questions: when the skill says "report X" or "log Y", emit a one-line status line to the conversation and continue. Do NOT phrase it as a question or wait for acknowledgment. A bad example: "Spec validated — shall I proceed to Phase 2?" A good example: "Spec validated. Moving to Phase 2."
Ethos
!sh .aif/partials/ethos-include.sh 2>/dev/null || sh ~/.claude/skills/partials/ethos-include.sh
Arguments
The user provides a requirement ID, e.g., /proceed REQ-023 or /proceed 23.
- Normalize to
REQ-xxx format (zero-pad to 3 digits if needed)
- Locate the spec at
.aif/specs/REQ-xxx-*/requirement.md
- If the spec doesn't exist, stop and tell the user to run
/spec first
Repository Configuration (single-repo vs cross-repo)
Some requirements touch one repo; others (e.g., a feature that simultaneously changes a mobile app, an API, and a web frontend) touch multiple repos. /proceed supports both.
"Primary" is per-REQ, not a fixed role. The primary repo for a given REQ is simply the repo where you invoked /proceed from — that repo's .aif/ holds the spec, tasks, and pipeline-state.json for this REQ. A different REQ can originate in a different repo; that REQ's primary is the other repo. Every repo that might host a REQ needs its own .aif/ structure (from /init) and its own .aif/config.yml so it can act as primary when a REQ starts there.
Single-repo mode (the invoking repo's config has no siblings, or no config at all): existing behavior — one worktree, one PR, one merge. All phases run against the invoking repo. Used for work that's scoped to one repo.
Cross-repo mode (the invoking repo's config lists siblings): the invoking repo is primary for this REQ. Sibling repos are registered by id → path. /proceed creates a worktree in each touched repo, routes tasks by their repo: frontmatter field, opens one PR per repo, and merges in merge_order.
Config schema (.aif/config.yml, present in every repo that can originate a REQ):
repos:
# Self — mark the current repo as primary. Path is implicit (it's this repo).
# Each repo's config marks ITSELF as primary. The configs across repos end
# up being mirror images of each other; that's expected and correct.
web:
primary: true
# Siblings — other repos this one might coordinate with. Path is relative
# to THIS repo's root, or absolute. Every sibling must be cloned locally.
api:
path: ../api
mobile:
path: ../mobile
# Merge order for Phase 8 when this repo is primary. If omitted, defaults to
# the order repos appear above. Only touched repos (those with tasks in the
# current REQ) are merged; untouched ones are skipped.
merge_order:
- api
- web
- mobile
Rules:
- In each repo's own config, exactly one entry — that repo itself — has
primary: true. Sibling entries describe other repos.
- Every repo that can originate a REQ needs
/init run in it AND its own .aif/config.yml. Repos that will only ever participate as siblings (never originate REQs) technically don't need a config, but it's cheap insurance — configure them anyway so any of them can host a REQ later.
- Task frontmatter must include a
repo: field naming one of the invoking repo's configured repo ids. A task without repo: defaults to the invoking (primary-for-this-REQ) repo.
- "Touched repos" for a REQ = the set of distinct
repo: values across its tasks.
- If the invoking repo's config has only itself (no siblings), or the file is absent, behave as single-repo.
- Sibling repo paths must exist and be git repositories. Fail fast in Step 0 if any are missing.
Terminology used below:
- Primary repo — for this REQ, the repo
/proceed was invoked from. Hosts .aif/, spec, state file. Always participates.
- Touched repo — any repo (primary or sibling) that has at least one task in this REQ.
- Repo worktree —
<repo-path>/.worktrees/REQ-xxx for each touched repo, on branch feat/REQ-xxx-short-description (same branch name across repos).
The Pipeline
Execute these phases in order. Each phase has a validation gate — if validation fails, fix the issues and re-validate. Loop up to 3 times per gate; if still failing after 3 attempts, stop and present the remaining issues to the user.
Pipeline State Tracking
CRITICAL: You MUST maintain a state file to track pipeline progress. This prevents phases from being skipped during long-running pipelines.
State file location: .aif/specs/REQ-xxx-*/pipeline-state.json
Schema:
{
"req": "REQ-xxx",
"branch": "feat/REQ-xxx-short-description",
"startedAt": "2026-03-27T10:00:00Z",
"completed": false,
"currentPhase": 0,
"completedPhases": [],
"phaseHistory": [
{ "phase": 0, "name": "Create Worktree", "completedAt": "2026-03-27T10:01:00Z" }
],
"repos": {
"web": {
"primary": true,
"path": "/absolute/path/to/web",
"worktree": "/absolute/path/to/web/.worktrees/REQ-xxx",
"branch": "feat/REQ-xxx-short-description",
"touched": true,
"prUrl": null,
"merged": false,
"snapshotBranch": null,
"snapshotPR": null
},
"api": {
"primary": false,
"path": "/absolute/path/to/api",
"worktree": "/absolute/path/to/api/.worktrees/REQ-xxx",
"branch": "feat/REQ-xxx-short-description",
"touched": true,
"prUrl": null,
"merged": false,
"snapshotBranch": null,
"snapshotPR": null
}
},
"mergeOrder": ["api", "web"],
"phase4": {
"currentTask": null,
"completedTasks": [],
"failedTasks": []
}
}
The repos block is the canonical registry for this pipeline run. Every cd/commit/push/PR/merge operation reads the target repo's path or worktree from here — never from cwd inference. touched: true means at least one task targets this repo; untouched repos skip Phases 4–8. mergeOrder is the list of touched repo ids in the order Phase 8 will merge them (primary is always a member).
Single-repo mode: repos contains exactly one entry with primary: true, touched: true, and mergeOrder is [that-one-id]. All phase logic still reads from repos — there is no separate code path.
The phase4 block tracks task-level progress during implementation so that a mid-Phase-4 context compression can resume from the exact task in progress rather than restarting the phase. currentTask holds the TASK-xxx ID being worked on right now; completedTasks holds IDs of tasks whose status is complete and whose commit has landed; failedTasks holds IDs that hit unrecoverable errors and were surfaced to the user. Other phases do not need sub-state.
The snapshotBranch and snapshotPR fields on each repos.<id> entry are deprecated as of REQ-380. The skill no longer writes them; they remain in the schema for read-back compatibility with state files written between REQ-362 and REQ-380. A missing or null value is the expected state on all new runs. Snapshot promotion (the staging → main PR creation that previously ran in Phase 8a) is now handled out-of-band by a per-project workflow on staging-tip CI greenness; consult the project's CI configuration.
Gate Protocol — follow exactly:
- Initialize the state file at the start of Step 0 with
currentPhase: 0, completedPhases: [], completed: false, repos: {...resolved from config...}, mergeOrder: [...], phase4: { currentTask: null, completedTasks: [], failedTasks: [] }
- Before starting any phase: read
pipeline-state.json. Verify currentPhase equals the phase you're about to start AND the previous phase is in completedPhases. If either check fails, STOP — you skipped a phase. Go back and complete it.
- After completing any phase: append the phase number to
completedPhases, append an entry to phaseHistory with the completion timestamp, set currentPhase to the next phase number.
- Phase 4 task-level writes: When starting a task, set
phase4.currentTask to its TASK-xxx ID. When its commit lands (in the task's target-repo worktree), append the ID to phase4.completedTasks and clear currentTask. On unrecoverable failure surfaced to the user, append to phase4.failedTasks instead.
- Worktree paths are immutable post-Step-0: once Step 0 records
repos[<id>].worktree, every subsequent phase (1–8) MUST read the path from state and MUST NOT re-derive it from cwd, the REQ id, or any naming convention. This applies on the happy path, not just on resume. (Step 0 itself reads cwd exactly once — at item 2 of Step 0 — to initialize the registry, then freezes the path into state; the prohibition starts from the moment Step 0 completes.)
5b. Resume from interruption: If the state file already exists when you start, read it and resume from currentPhase. Trust repos as the source of truth for worktree paths. If currentPhase is 4 and phase4.currentTask is non-null, resume that specific task (re-read its file, use repos[<task.repo>].worktree for every git/file operation, re-check whether its commit already landed, continue or restart as appropriate) before moving to the next task in the dependency graph. Never replay tasks already in completedTasks.
- If context has been compressed: re-read
pipeline-state.json before doing anything and treat it as the source of truth for currentPhase, repos, and phase4. Do not rely on memory of which phase, task, or repo you're in.
Each phase below has a one-line Gate reminder. The full protocol above applies to every gate.
Step 0: Resolve Repos + Create Worktrees + Preflight + Load Shared Context (ALWAYS FIRST)
Before doing anything else, resolve the repository set, isolate each touched repo in a git worktree, and prime the shared context so subskills don't re-read the same files:
-
Preflight — verify all prerequisite files exist in the primary repo (stop with a clear message if any are missing):
.aif/context/project-overview.md — run /init if missing
.aif/context/architecture.md — run /init if missing
.aif/context/conventions.md — run /init if missing
.aif/specs/REQ-xxx-*/requirement.md — run /spec if missing
-
Resolve repo registry:
- Read
.aif/config.yml if it exists. If absent or has no repos block, use single-repo mode: the registry is { <cwd-repo-id>: { primary: true, path: <cwd>, touched: true } } where the repo id is the basename of the cwd.
- In cross-repo mode: the primary entry's
path is cwd. Resolve each sibling's path to an absolute path (relative paths are relative to the primary repo root). Verify each path exists and is a git repo (git -C <path> rev-parse --git-dir). If any sibling is missing, stop with a clear error listing the missing repos.
-
Determine touched repos (best-effort at Step 0; confirmed after Phase 2):
- If tasks already exist under
.aif/specs/REQ-xxx-*/tasks/, read each task's repo: field to compute the touched set.
- If tasks don't exist yet (fresh pipeline), assume every configured repo is potentially touched and create worktrees in all of them. Post-Phase-2, untouched repos will be marked
touched: false and their worktrees removed.
- The primary is always touched (even if no primary tasks — it hosts the spec and state file).
-
Determine the integration branch, then fetch it in each touched repo. The base for feature branches is NOT always main (LESSON-036 — sprinted runners that hardcoded main in a staging-first repo paid a mid-pipeline rebase + PR-retarget every time). Detect the repo's branch model; any one signal is sufficient:
.aif/config.yml declares a gcp.staging_project (or otherwise indicates a staging-first deploy), OR
- a
.github/workflows/* enforces a / branch-protection head-ref check, OR
Preflight verified — when you invoke subskills in later phases, they may skip their own prerequisite checks (already validated here) AND they may skip re-reading architecture.md / conventions.md / project-overview.md (already in context). Treat the Step 0 loads as authoritative for the rest of the pipeline.
After completing Step 0: Update pipeline-state.json — add 0 to completedPhases, add Step 0 to phaseHistory, set currentPhase to 1.
Phase 1: Validate the Requirement Spec
Gate: currentPhase must be 1. After completion: append 1, set currentPhase=2.
Run /validate against the REQ spec. APPROVED → mark approved, advance.
NEEDS REVISION → fix FAILs and re-validate (up to 3 loops); remaining
blockers are legitimate halt #1. End-of-phase log: "Spec validated and
approved." Full step list in companion.
Phase 2: Architect & Break Into Tasks
Gate: currentPhase must be 2. After completion: append 2, set currentPhase=3.
Invoke /architect to design the approach and emit task files (each tagged
with repo: in cross-repo mode). Reconcile pipeline-state.json: mark
touched/untouched repos, prune untouched-sibling worktrees, rebuild
mergeOrder, backfill missing repo: to primary. End-of-phase log:
one-paragraph architecture + task-graph + per-repo task counts.
Phase 3: Validate Architecture & Tasks
Gate: currentPhase must be 3. After completion: append 3, set currentPhase=4.
Re-invoke /validate (it auto-detects the architecture+tasks phase). Same
3-loop fix protocol as Phase 1; unresolved blockers are legitimate halt #1.
End-of-phase log: "Architecture and tasks validated."
Phase 4: Implement
Gate: currentPhase must be 4. After completion: append 4, set currentPhase=5.
Precise overlap gate (REQ-483, early / best-effort). Before implementing, git -C <worktree> fetch origin <integrationBranch> (refresh the base — the Step-0 fetch is stale by now), then source partials/trial-merge.sh (two-level fallback) and run aif_trial_merge "<worktree>" origin/<integrationBranch>. On rc=1 (real conflict) with an in-flight REQ ranked ahead in /manifest's verdict → return the blocked terminal now, rather than sinking implementation effort into a branch that must rebase (BR-9). rc=0 (clean — including a footprint overlap that merges clean) does NOT block (BR-7); rc=2/3 (precondition / unfetched ref) is a setup error, not a conflict — surface it, never as blocked. This early gate is best-effort (an overlapping branch may not have code yet); the authoritative gate is Phase 8 pre-merge. If the Step-0 /manifest verdict isn't in context (post-compression), re-run /manifest with MANIFEST_SKIP_FETCH=1 first — a stale/absent verdict must not block.
Execute the task graph across all touched-repo worktrees. Each task runs in
repos[<task.repo>].worktree. Track per-task progress in phase4.currentTask
/ completedTasks / failedTasks so a mid-phase compression resumes exactly.
Main mode dispatches task-implementer agents in dependency tiers (parallel
within a tier); subagent mode runs tasks sequentially in-context. End-of-phase
log: one line per tier with finished TASK-xxx [repo] ✓ and any failures.
Phase 5: Verify (Reflect + Review in Parallel)
Gate: currentPhase must be 5. After completion: append 5, set currentPhase=6.
Goal: Self-assess AND multi-agent review the implementation, then fix all findings in a single consolidated pass.
Gather diffs per repo (prerequisite): for each touched repo, compute the diff inside its worktree (git -C <worktree> diff main...HEAD plus the list of changed files). The reviewers receive per-repo diffs + file lists, plus the cross-repo architecture.md so they can reason about contracts spanning repos.
Optional verify candidate-list pre-pass via aif-read (added by REQ-417): for each touched repo, run an advisory delegate pre-pass before the Step A 6-agent dispatch. The pre-pass produces a per-dimension candidate-findings list (correctness, quality, architecture, test-coverage, security) that is passed only to the 5 reviewer agents — the reflector receives no advisory block (reflector's value is independent self-assessment of Claude's own work, which advisory candidates would compromise).
Before the gate check, create a skill-invocation flag and capture the start time for telemetry (REQ-424 ghost-skip detection):
. .aif/partials/delegate-tools-path.sh 2>/dev/null || . ~/.claude/skills/partials/delegate-tools-path.sh
flag=$("$DELEGATE_TOOLS"/skill-flag.sh create)
trap '"$DELEGATE_TOOLS"/skill-flag.sh clear "$flag" 2>/dev/null || true' EXIT # cleanup on abort
"$DELEGATE_TOOLS"/skill-flag.sh mark "$flag" start_s "$(date -u +%s)"
The telemetry state (start_s, invoked, exit, reason) is persisted to the
flag-file sidecar via skill-flag.sh mark, NOT to shell variables, because
SKILL.md fenced blocks do not share shell state (single-fence-safe telemetry,
REQ-522 BR-4). The resolution block reads it back with skill-flag.sh read.
Gate the pre-pass via the shared predicate (REQ-416 ADR-2 — see partials/delegate-gate.md):
. .aif/partials/delegate-gate.sh 2>/dev/null || . ~/.claude/skills/partials/delegate-gate.sh
. .aif/partials/delegate-tools-path.sh 2>/dev/null || . ~/.claude/skills/partials/delegate-tools-path.sh
aif_delegate_gate_check; gate=$?
"$DELEGATE_TOOLS"/skill-flag.sh mark "$flag" reason "$AIF_DELEGATE_GATE_REASON"
case $gate in
0) ;; # delegated path — see "Delegated pre-pass" below
1) ;; # disabled path (AIF_DISABLE_DELEGATE=1, or not opted in) — see "Fallback" below
2) ;; # unavailable path (aif-read not on PATH) — see "Fallback" below
esac
Delegated pre-pass (per touched repo) — iterate over the touched repos already enumerated by the prerequisite step. The per-repo diff and changed-files list MUST be derived from THAT repo's worktree (NOT a shared / monorepo list): use git -C <repos[<id>].worktree> diff main...HEAD for the diff and git -C <repos[<id>].worktree> diff main...HEAD --name-only for the changed-files list. The validation in step 6 below references the per-repo changed-files list, not a global one.
MANDATORY — no agent discretion. When the gate passes, invoking aif-read for the pre-pass is required for every touched repo, not optional. The only acceptable non-delegated outcome on the gate-pass path is per-repo: aif-read was actually invoked for that repo and exited non-zero (→ the per-repo delegation-failure fall-through, recorded as api-error). Producing the candidate-findings yourself by reading the repo diff directly instead of invoking aif-read — for ANY reason, including "small diff", "few changed files", or "faster to just review it" — is a compliance violation, NOT a fallback. emit-telemetry.sh mechanically rewrites any gate-pass fallback record whose reason is not api-error into a ghost-skip, so a hand-written reason cannot disguise a skipped call — the skip surfaces in check-delegation.sh counts regardless of how the emit is labeled.
- Emit ONE stderr line announcing intent BEFORE invoking the delegate (consistent with
/spec and /analyze):
/proceed Phase 5: delegating verify pre-pass to the delegate (repo=<id>, <N> changed files)
- Capture the repo's diff to a temp file using
mktemp -t aif-verify.XXXXXX (BSD-sed-compatible, no predictable name). Install an EXIT trap to remove the temp file on every exit path so the diff (which may contain sensitive code) does not persist. Do NOT hardcode a predictable path like /tmp/aif-verify-<reqid>.txt — that pattern is a symlink/TOCTOU foothold (LESSON-008).
- Redact credential-shaped strings from the diff in place via the 5-pattern BSD-sed chain established in REQ-415 (covers
sk-…, AKIA…, ghp_…, Bearer …, and [A-Z_]+_(API_KEY|TOKEN)… env-var assignments — the broader [A-Z_]+_(API_KEY|TOKEN) arm subsumes MOONSHOT_API_KEY so no separate pattern is needed):
sed -i.bak -E 's/(sk-[A-Za-z0-9_-]{20,}|AKIA[A-Z0-9]{16}|ghp_[A-Za-z0-9]{36,}|Bearer [A-Za-z0-9._-]{20,}|[A-Z_]+_(API_KEY|TOKEN)[[:space:]]*[=:][[:space:]]*[^[:space:]]+)/[REDACTED]/g' "$TMPFILE" && rm -f "$TMPFILE.bak"
- Invoke the delegate over the redacted diff. Mark
invoked=1 to the flag sidecar immediately before the call (REQ-424 telemetry), and mark the call's exit immediately after it returns — these marks are how the resolution block detects a real call vs a ghost-skip:
. .aif/partials/delegate-tools-path.sh 2>/dev/null || . ~/.claude/skills/partials/delegate-tools-path.sh
"$DELEGATE_TOOLS"/skill-flag.sh mark "$flag" invoked 1
aif-read --no-warn --paths "$TMPFILE" --question "From this diff, produce candidate-findings across: correctness (logic bugs, race conditions, edge cases), quality (naming, duplication, dead code), architecture (layer violations, contract drift), test-coverage (missing tests for changed surfaces), security (input validation, secrets, auth). For each dimension, list 0-5 candidates as: '<file path>:<line range> | <one-line description>'. Reply 'NONE' for dimensions with no candidates. 1000 words max total."
"$DELEGATE_TOOLS"/skill-flag.sh mark "$flag" exit $?
If aif-read exits non-zero, emit one combined stderr line and fall through to the fallback dispatch for this repo (BR-4: one line per invocation — this REPLACES the intent line for this repo; the success/announce line in step 1 is the only emit when delegation succeeds):
Fallback (gate failed, or per-repo delegation-failure fall-through):
Resolve telemetry mode and emit (REQ-424). After the delegated OR fallback path completes for this Phase 5 pre-pass, before continuing to the 6-agent dispatch. Emit telemetry ONLY by sourcing and calling the shared resolver in the SAME fenced block — it derives mode/reason/gate_result/duration_ms from the flag-file sidecar the steps above marked, so no shell variable crosses a fence boundary (REQ-522 BR-4). Never hand-construct a telemetry line:
. .aif/partials/emit-step-telemetry.sh 2>/dev/null || . ~/.claude/skills/partials/emit-step-telemetry.sh
_aif_emit_step_telemetry proceed-phase-5 Phase-5-Verify
In subagent mode (/sprint pipeline-runner): do NOT dispatch the delegate pre-pass. Subagents cannot reliably reach a parent's shell env for aif-read, and the pre-pass would be skipped or fail unpredictably. Skip the entire pre-pass block in subagent mode and run the reviewer checklists as before.
Then continue with Step A — Single-gate parallel dispatch unchanged.
Main conversation mode — parallel agents:
Step A — Single-gate parallel dispatch. This whole step is ONE gate. In cross-repo mode, dispatch 6 agents × N touched repos — all in a single assistant message. In single-repo mode, dispatch 6 agents in a single message as before. Do NOT report findings, do NOT pause, do NOT log progress between agent returns — wait until all have returned, then consolidate in Step B.
The six agents match the dimensions covered by /review (correctness, quality, architecture, test coverage, security) plus the reflector self-assessment:
- reflector agent — provide REQ-xxx, the repo id, the worktree path, changed files, diff, conventions.md, architecture.md. Tell it: "Report findings only. The parent pipeline will apply fixes."
- correctness-reviewer agent — repo id, worktree path, changed files, diff, conventions.md. "Report findings only. Do not apply fixes."
- quality-reviewer agent — same inputs. "Report findings only. Do not apply fixes."
- architecture-reviewer agent — repo id, worktree path, changed files, diff, architecture.md, plus a summary of the other touched repos' changes (so it can flag cross-repo contract breaks). "Report findings only. Do not apply fixes."
- test-auditor agent — repo id, worktree path, changed files, diff, conventions.md. "Audit test coverage only for the diff under review. Report findings only. Do not apply fixes."
- security-auditor agent — repo id, worktree path, changed files, diff, conventions.md. "Audit security posture only for the diff under review. Report findings only. Do not apply fixes."
Subagent mode — sequential inline review:
For each touched repo, run the reflector checklist, then correctness, quality, architecture (with cross-repo context), test-auditor, and security-auditor checklists sequentially in your own context. Use the criteria from the agent definitions in ~/.claude/agents/. Do NOT dispatch sub-agents.
Step B — Consolidate: When all agents return (or all checklists complete in subagent mode), dedupe overlapping findings within each repo and also flag cross-repo issues (e.g., API contract drift between an api repo and its consumer). Produce a single ranked list by severity, tagging each finding with the repo id it applies to.
Step C — Fix in one pass:
- Critical + must-fix Major (bugs, security, convention violations, missing tests): fix immediately in the finding's target repo worktree, run that repo's test suite after each related cluster of fixes, commit inside that worktree with
fix(scope): address verify finding [REQ-xxx].
- Should-fix Minor (code quality, naming): fix unless doing so would be a significant refactor — note those as follow-ups.
- Nit / observation: fix trivial ones inline, skip the rest.
- User-facing questions from reflector: if any, surface them to the user as a numbered list and wait for answers before continuing.
Step D — Re-verify (conditional): Re-run ONLY the 5 reviewer agents (not reflector) if Critical or must-fix Major items were fixed — up to 1 confirmation loop. Skip if only minor fixes were applied. Scope re-verify to the (repo, dimension) pairs that had fixes: e.g., if correctness fixes landed only in the api repo, rerun correctness-reviewer for that repo only. In subagent mode, re-run the corresponding reviewer checklists inline.
End-of-phase log: Emit the combined verify summary across repos — per-repo findings, dedupe count, how many fixed, any deferred. If reflector surfaced user-facing questions, halt here (legitimate halt #2). Otherwise continue to Phase 6.
Phase 6: Create Pull Request(s)
Gate: currentPhase must be 6. After completion: append 6, set currentPhase=7.
Push each touched repo's accumulated commits, then flip the draft PR opened at Step 0
(step 8a) to ready with aif_forge_pr_ready <prNumber> (read prNumber/prUrl from
pipeline-state.json) — do NOT create a new PR (REQ-483). Fallback (LESSON-004):
if repos[<id>].prNumber is absent (a pipeline started before draft-PR-early), create
it now with aif_forge_pr_create --base <integrationBranch> (read integrationBranch from
state; never default to main — LESSON-036). Set the full body via aif_forge_pr_edit,
preserving the aif-footprint block (read the current body, keep that fenced block,
replace only the human sections), and drop the [WIP] title prefix via aif_forge_pr_edit --title.
All PR ops route through partials/forge.sh (source it in the same fence) — never direct gh.
Cross-repo: ready primary's PR last and back-fill sibling bodies. Mark requirement
complete in primary frontmatter; prUrl is already in state from Step 0. Report URLs
grouped by repo in mergeOrder sequence. Full detail in companion.
Phase 7: PR Cleanup & CI
Gate: currentPhase must be 7. After completion: append 7, set currentPhase=8.
Lightweight per-PR sanity check — review already ran in Phase 5, do NOT
re-run /review. For every PR: review diff, catch stray debug/TODO/secret
content, verify cross-repo contract consistency, push fixups in the owning
worktree if needed, wait for gh pr checks to go green. End-of-phase log:
one line per PR, then "All N PRs ready for merge".
Phase 8: Wrapup
Gate: currentPhase must be 8 and 7 must be in completedPhases. After completion: append 8, set "completed": true.
Merge in mergeOrder, run /wrapup from the primary (deploys + knowledge
capture), tear down each touched-repo worktree via the absolute path in
state, set completed: true. Terminal claim MUST be tagged exactly one of
{merged, pr-ready, blocked, failed} — untagged claims are a protocol
violation /sprint rejects. Merge conflicts are legitimate halt #3.
Error Handling
- Test failures during implementation: Stop the current task, diagnose the failure, fix it inside the task's target-repo worktree, and re-run tests before continuing. If you can't fix it after 2 attempts, pause and ask the user.
- Validation stuck after 3 loops: Present the remaining FAIL items and ask the user how to proceed (fix manually, skip validation, or abort).
- Missing context files: If
.aif/context/ files don't exist in the primary repo, stop and tell the user to run /init first. Do not proceed without context files.
- Missing sibling repo: If
.aif/config.yml references a sibling whose path doesn't exist or isn't a git repo, stop at Step 0 and list the missing repos. The user must clone or fix paths before retrying.
- Task with unknown
repo: value: If a task frontmatter names a repo id not in the registry, stop Phase 4 and surface the mismatch — either the config or the task is wrong.
- Merge conflicts: If any feature branch has conflicts with its base branch — during Phase 7 rebase or Phase 8 merge — stop and ask the user how to resolve. In cross-repo mode, state which repo conflicted; earlier repos in
mergeOrder may have already merged (see repos[<id>].merged), so the user can resume mid-sequence rather than re-doing completed merges.
- Partial merge recovery: If the pipeline is interrupted mid-Phase-8, resume by reading
pipeline-state.json — the merge loop walks mergeOrder and skips any repo where merged: true.
Prerequisites
Verified by Phase 0 Preflight — see Step 0 above.
What This Skill Does NOT Do
- It does not create the initial spec — run
/spec first