feat(skills): run every judging stage in a fresh-context subagent

The session that writes the code is the worst judge of it: it believes the
code is correct and remembers the reasoning its tests are meant to challenge.
Split the pipelines along a judge/do boundary — the driving session implements,
runs the mechanical gates, publishes and applies fixes; every stage whose job
is to judge the work is dispatched to a subagent with an EMPTY context.

ship-feature-lane:
- New hard rule: plan debate (0b), unit tests (1b), e2e (3), code review (4),
  browser QC (6) and the senior gate (7) run in fresh-context agents.
  `subagent_type: fork` is forbidden for these — a fork inherits the
  implementing session's context, which is the bias being escaped.
- New Stage 1b: an independent agent writes the unit tests the implementation
  is missing (test files only, no weakening existing tests) and returns
  UNIT-TESTS: PASS/FAIL. A FAIL is fixed in the source, never in the test.
- Stage 3 delegates the e2e run + triage (the poll/timeout discipline moves
  into the agent's brief); Stage 4 delegates the code-review skill run.
- Stages 6/7 keep their agents but may no longer be primed with the driving
  session's context, conclusions or known-issue list.
- Stage 10: CI still red on the same job after a fix goes to a fresh agent —
  calling your own failure a flake twice pushes a real defect past the gate.
- Fix-loop: a re-entry touching non-test source re-runs Stage 1b first.

ship-feature: same boundary for the plan, tests, review and gate phases.

docs/LANES.md updated to match.
This commit is contained in:
2026-08-21 16:59:57 +07:00
parent 16bef7f9a1
commit effdaf4ba8
3 changed files with 71 additions and 20 deletions
+32 -11
View File
@@ -1,6 +1,6 @@
---
name: ship-feature-lane
description: "Autonomous end-to-end feature pipeline for ONE CCAM lane. Invoke inside a lane's working directory with a requirement: `/ship-feature-lane <requirement>`. Frontloads ALL clarifying questions once, then runs unattended: implement (TDD) → pre-push CI gates + dev preflight → e2e on the feature branch → code review → local QC → senior GO/NO-GO gate → push branch + open PR (base `development`) → CI watch → report, then watches the PR (new comments → gated fix-loop; base conflicts → sync development into the branch) until a HUMAN merges it. The PR is only published after all local gates pass and the senior gate says GO — it's finalized when reviewers see it. Declares lane stage at every step via `ccam stage` for the dashboard. Use when the user wants to build/ship/implement a feature in a CCAM lane. NOTE: ticket-filing and post-merge dev-site QC are currently OFF (F's integrations aren't built yet) — this pipeline stops at Stage 14 once dev CI/dev-QC support lands."
description: "Autonomous end-to-end feature pipeline for ONE CCAM lane. Invoke inside a lane's working directory with a requirement: `/ship-feature-lane <requirement>`. Frontloads ALL clarifying questions once, then runs unattended: implement (TDD) → independent unit-test agent → pre-push CI gates + dev preflight → e2e on the feature branch (agent-run) → code review (fresh-context agent) → local QC → senior GO/NO-GO gate → push branch + open PR (base `development`) → CI watch → report, then watches the PR (new comments → gated fix-loop; base conflicts → sync development into the branch) until a HUMAN merges it. The PR is only published after all local gates pass and the senior gate says GO — it's finalized when reviewers see it. Declares lane stage at every step via `ccam stage` for the dashboard. Use when the user wants to build/ship/implement a feature in a CCAM lane. NOTE: ticket-filing and post-merge dev-site QC are currently OFF (F's integrations aren't built yet) — this pipeline stops at Stage 14 once dev CI/dev-QC support lands."
---
# Ship Feature Lane (CCAM lane pipeline)
@@ -41,7 +41,11 @@ Resume from the stage shown. If state says `stage=X status=running`, you were mi
## Hard rules
- **Publish ONLY after the senior-gate-reviewer returns `VERDICT: GO`.** "Publish" = push the feature branch + open/update the PR (Stage 8). Nothing reviewer-visible exists before GO, and nothing else authorizes it.
- **Testing and reviewing run in a FRESH-CONTEXT agent — never in this session.** The session that wrote the code is its worst judge: it already believes the code is correct and it remembers the reasoning the tests are supposed to challenge. Every stage whose job is to *judge* the work — Stage 0b (plan debate), Stage 1b (unit tests), Stage 3 (e2e run + triage), Stage 4 (code review), Stage 6 (browser QC), Stage 7 (senior gate) — is dispatched with the Agent tool to a subagent that starts with an EMPTY context and receives only artifacts it can verify itself: the lane's working directory, the lane spec file, the diff range, the commands to run, and the other agents' reports verbatim. The stages you keep are the ones that *do* rather than judge: intake, implementing, the mechanical gates (Stage 2), publishing (Stage 8), the CI/PR watch (Stages 10–12), and applying every fix the judges ask for. Rules: **never `subagent_type: fork`** for these (a fork inherits this session's context, which defeats the whole point); never "save a round-trip" by doing the pass yourself; never paste your own conclusions ("I already checked X", "this is safe because…") into the brief — hand facts and paths, not verdicts. You implement and you apply fixes; you do not grade your own work.
- Launch them **FOREGROUND** (they gate the pipeline, and their completion re-invokes you, which satisfies the turn-liveness rule).
- Each returns ONE parseable final line (`UNIT-TESTS:` / `E2E:` / `REVIEW:` / `LOCAL-QC:` / `VERDICT:`). Parse that line; never infer a pass from prose.
- **The fix-loop:** any failure in stages 2–7 (gates/preflight, e2e, review, QC, senior gate), any red PR CI that's genuinely yours (Stage 10), and any worth-fixing review comment (Stage 12) → fix on the **feature branch**, and re-run **from Stage 2 through Stage 8** (gates+preflight → e2e → review → QC plan → QC → senior gate → publish/update PR), then the Stage 10 CI watch. Never skip a gate — the full process applies; no shortcuts because "it's just review feedback".
- **Re-entry that changes non-test source re-runs Stage 1b first** (fresh unit-test agent on the new diff), then Stage 2 onward. A re-entry that only touches test files skips 1b — the tests are already what changed.
- **EXCEPTION — test-only re-entry (browser-QC fast-path).** If the re-entry's change is ENTIRELY test files — `git diff --name-only` since the last browser-QC'd commit matches only test paths — the app's runtime behavior/UI is unchanged from the last QC'd pass. Run this EXACT stage set, nothing else:
- **Always run:** Stage 2 (gates + preflight), Stage 7 (senior gate), Stage 8 (publish/update PR), and the Stage 10 tail (CI watch).
- **Run only if e2e spec files are among the changed tests:** Stage 3 (boot + e2e on the feature branch). No e2e specs changed → skip it.
@@ -50,7 +54,7 @@ Resume from the stage shown. If state says `stage=X status=running`, you were mi
- **EXCEPTION — localized re-entry (scoped-e2e fast-path).** On a re-entry whose diff since the last fully-validated commit is SMALL and LOCALIZED — only files inside the feature's own surface, NO migrations, NO contract/generated files, NO shared fixtures/utilities, NO dependency changes — you may shrink Stage 3's e2e to a SCOPED run of the specs covering the touched surface: `ccam lanes hook e2e -- <spec files>` (scoped runs still heartbeat + lock + time-bound like the full suite), and browser QC runs SCOPED to the affected QC-Plan scenarios (tell the qc agent exactly which scenario numbers). Know the trade-off: there is no dev-merged full suite anymore — post-merge dev CI + dev-QC (Stage 13, currently off) are normally the integration net; without them, a localized re-entry after this lands is a real gap until F ships. If in doubt whether the change is localized, it isn't — run the full path.
- **Run long helpers so they can't be killed mid-flight or hang your turn.** `ccam lanes hook ci-gate`, `ccam lanes up`, `ccam lanes hook e2e` legitimately run 3–20+ minutes (builds, tests, Playwright, lock waits). NEVER invoke them with the default Bash timeout (2 min kills them mid-flight and strands the lane half-done): use `run_in_background: true` and poll the output file until done, or set `timeout: 600000` for the shorter gates. If a helper does die mid-run, don't panic: every hook is idempotent — re-run the step (e.g. re-run `ccam lanes up --no-build` to revive a stack).
- **Waiting + polling NEVER use a foreground `sleep`** (the Bash tool blocks it) or `ScheduleWakeup` (that's a `/loop`-only primitive — this pipeline is not a `/loop` session, so it won't sustain your watch). To pace a poll loop or wait out a timer, **background the wait**: run `sleep <secs>` with `run_in_background: true` — you're re-invoked when it exits, and re-invoked the moment a backgrounded Agent or helper finishes, so you never busy-poll for background work. **If you ever can't sustain a wait/loop in this session, set `ccam stage <current> --note "<honest note>"` and STOP — never narrate a watch or loop you are not actually running.**
- **e2e: actively poll — never wait on the completion re-invoke alone.** A hung suite never fires it, stranding the lane at `stage=e2e-feature`. When running `ccam lanes hook e2e` (Stage 3): start it `run_in_background: true` AND background a `sleep 90` beside it. Each wake — finished → parse PASS/FAIL; still running → read the e2e log tail (`ccam lanes logs <id> e2e`), bump the heartbeat, and re-background `sleep 90`, UNLESS it's erroring or has run past ~22 min, in which case kill the e2e task and treat it as FAIL → re-enter Stage 2.
- **e2e: actively poll — never wait on the completion re-invoke alone.** This binds whoever actually runs the hook — normally Stage 3's e2e agent, so pass this paragraph into its brief verbatim; you only follow it yourself for an ad-hoc run. A hung suite never fires the completion re-invoke, stranding the lane at `stage=e2e-feature`. When running `ccam lanes hook e2e`: start it `run_in_background: true` AND background a `sleep 90` beside it. Each wake — finished → parse PASS/FAIL; still running → read the e2e log tail (`ccam lanes logs <id> e2e`), bump the heartbeat, and re-background `sleep 90`, UNLESS it's erroring or has run past ~22 min, in which case kill the e2e task and treat it as FAIL → re-enter Stage 2.
- **Turn-liveness: never let the pipeline die silently.** A "stalled" lane usually died one of two ways: (a) a turn ended with NOTHING pending — no backgrounded wait, no running helper, no background agent — so nothing ever re-invoked the session; or (b) a transient API error (rate-limit, 529/overload, connection refused) killed the turn mid-stage. Rules: while the pipeline is anywhere between Stage 1 and Stage 14 (done), every turn you end MUST leave at least one re-invoker pending (a `run_in_background` helper/sleep or a background agent) — check before ending the turn. And on ANY resume after an error or a human nudge ("continue"), do not ask questions: re-derive position from lane state (Context recovery above) and continue the stage. If you truly cannot leave a re-invoker, set `--note "watch needs re-trigger: <what to do>"` so the dashboard shows it honestly.
- **No retry cap — the phase clock is the signal.** A failing gate/QC/CI/e2e just re-enters the loop (fix on the feature branch, re-run from Stage 2); there is NO automatic block after N attempts. The dashboard shows how long the lane has sat in its current stage, so the human can spot a stuck or endlessly-looping lane and step in. Reserve `--status blocked` for GENUINE blockers you cannot resolve (an ambiguous merge conflict, a hard/unrecoverable error).
- **Commit only on the feature branch.** Never commit on `development`/`main`. Stage only intended files (never `git add .` blindly — this repo collects stray build/QA artifacts).
@@ -71,7 +75,7 @@ Do NOT jump to code. Understand the requirement first.
- `ccam stage plan` — now design a real plan and have it independently challenged before you implement.
- **Investigate (autonomous, thorough).** Read the actual code paths, models, existing tests, and conventions the feature touches — `Explore`/`general-purpose` subagents for breadth, then read the key files yourself for depth. Pin down: integration points, data/migration needs, API/contract impact, reuse opportunities, and risks. Use **systematic-debugging** if the feature is a fix (root-cause first, no symptom patches).
- **Plan.** Produce a concrete implementation plan (the **writing-plans** skill): approach, files to change, the test strategy (which behaviors/edge cases each test will pin), migration/contract impact, and how each acceptance criterion is met.
- **Debate the plan (adversarial review).** Spawn a SEPARATE sub-agent (Agent tool — `Plan` or `general-purpose`) to critique the plan + investigation: missed requirements, wrong assumptions, a simpler approach, unhandled edge cases, acceptance-criteria gaps. Apply the worthwhile critiques (use **receiving-code-review** judgment — verify each point, don't blindly accept or reject). Iterate once or twice until the plan holds up.
- **Debate the plan (adversarial review) — fresh context, never `fork`.** Spawn a SEPARATE sub-agent (Agent tool — `Plan` or `general-purpose`, FOREGROUND) to critique the plan + investigation. Hand it the requirement, the Stage-0 answers and the plan as text plus the paths to read; do NOT hand it your reasoning for why the plan is right — that is exactly what it is there to test. Ask for: missed requirements, wrong assumptions, a simpler approach, unhandled edge cases, acceptance-criteria gaps. Apply the worthwhile critiques (use **receiving-code-review** judgment — verify each point, don't blindly accept or reject). Iterate once or twice until the plan holds up.
- Write the Q&A answers **and the agreed plan** to a lane spec file `docs/superpowers/specs/lane-<slug>.md` (gitignored, or add it to `.gitignore` if this is the first one) — the acceptance contract the senior gate checks against.
### 1 — Implement (TDD, to the plan)
@@ -83,6 +87,18 @@ Do NOT jump to code. Understand the requirement first.
- If your stack generates an API contract/client and the API changed, regenerate it (`ccam lanes hook regen`) so the contract-check gate passes (stacks without a contract gate skip this).
- `ccam stage implementing`
### 1b — Independent unit tests *(fresh-context agent)*
Your TDD tests in Stage 1 were written by the same mind that wrote the code, so they inherit its blind spots. This stage buys a second, uncontaminated set.
- `ccam stage tests --status running` (an alias of `gates` — the map holds; the stage name says these minutes are the independent test pass).
- Launch a fresh-context agent (Agent tool, `subagent_type: general-purpose`, FOREGROUND — **never `fork`**). Hand it ONLY: the lane's working directory, the lane spec path (`docs/superpowers/specs/lane-<slug>.md`), the diff range `git diff origin/development...feat/<slug>`, the repo's unit-test commands, and this brief:
- Read the acceptance criteria and the diff. Write the unit tests the implementation is **missing** — one per real behavior or edge case (happy path, negative/error path, boundary), in the repo's existing test style and location. Test the contract in the spec, not the shape of the implementation.
- Do NOT modify non-test files. Do NOT weaken, skip, or delete an existing test. No coverage padding, no asserting constants or framework internals.
- Run the suite. Commit **test files only**.
- Final line: `UNIT-TESTS: PASS — <n> tests added` (all green) or `UNIT-TESTS: FAIL — <failing test> :: <the defect it exposes>`.
- `FAIL` → a real defect: fix the **source** on the feature branch (root cause — **systematic-debugging**; never edit the agent's test to make it pass unless the test itself is provably wrong, and say so in the evidence), then re-run this stage.
- `PASS` → `ccam stage tests --evidence "<n> independent unit tests added, green"` → Stage 2.
### 2 — Pre-push CI gates + dev preflight (on the feature branch)
- `ccam stage gates --status running` — declare it FIRST. This is also the fix-loop's re-entry point, and the declaration is what moves the lane BACK down the pipeline: detection alone can't (`recordDetection` is forward-only and never overrides a higher declared stage), so a re-entry that skips this line leaves the dashboard showing the stage you already left.
- `ccam lanes hook ci-gate` — runs the profile's CI gate (lint / test / contract checks) against an isolated per-lane test DB. On failure: read the output, fix on the feature branch, commit, re-run. Loop until green.
@@ -93,15 +109,19 @@ The e2e hook doesn't run migrations itself — it tests the already-running stac
- `ccam stage booting --status running` — an alias of `e2e-feature`; the boot below can take minutes and this says which minutes they are.
- `ccam lanes up --qc` — boots with the profile's QC env (mock/stub flags so QC is deterministic, from `QC_BOOT_ENV`), applies the feature branch's own migrations, and reboots the stack. Idempotent; safe to re-run. (The branch was cut from `origin/development`, so this stack IS development + your feature as of the branch point.)
- `ccam stage e2e-feature --status running`, then `ccam lanes hook e2e` — Playwright e2e under the e2e lock against the now-booted stack. **This is the only e2e gate in the flow** — there is no dev-merged suite behind it.
- On failure: fix on the feature branch, commit, re-run from Stage 2.
- **Iterating on a failing spec:** declare `ccam stage e2e-scoped` (alias of `e2e-feature`) so the dashboard shows this is a narrowed run, not the gate, and use scoped runs through the hook — `ccam lanes hook e2e -- <spec file/filter>` — never a bare test-runner invocation in the lane (bare runs skip the cross-lane lock, the hard timeout, and the heartbeat, so the dashboard false-flags STALLED). A scoped green is never the gate; finish with the full suite (unless the localized fast-path applies — see Hard rules).
- `ccam stage e2e-feature --status running`, then launch a fresh-context agent (Agent tool, `subagent_type: general-purpose`, FOREGROUND — **never `fork`**) to RUN and triage the suite. You booted the stack; you do not run or read the suite. Hand it ONLY: the lane's working directory, the feature branch, the acceptance points (lane spec path), and the e2e discipline verbatim — `ccam lanes hook e2e` with `run_in_background: true`, a backgrounded `sleep 90` beside it, `ccam lanes logs <id> e2e` for the tail on each wake, kill-and-FAIL past ~22 min, and NEVER a bare test-runner invocation in the lane (bare runs skip the cross-lane lock, the hard timeout and the heartbeat). Playwright e2e under the e2e lock against the now-booted stack. **This is the only e2e gate in the flow** — there is no dev-merged suite behind it.
- It reports one final line: `E2E: PASS` or `E2E: FAIL — <spec/test> :: <root cause, and whether it looks like a product defect or an infra flake>`.
- On `FAIL`: fix on the feature branch, commit, re-run from Stage 1b (source changed) or Stage 2 (test-only change).
- **Iterating on a failing spec:** declare `ccam stage e2e-scoped` (alias of `e2e-feature`) so the dashboard shows this is a narrowed run, not the gate, and tell the e2e agent to run scoped through the hook — `ccam lanes hook e2e -- <spec file/filter>` (same agent, same discipline; the narrowing is in ITS brief, not in you taking the run back). A scoped green is never the gate; finish with the full suite (unless the localized fast-path applies — see Hard rules).
- On success: `ccam stage e2e-feature-passed --status running`
### 4 — Code review *(no open PR yet — use local diff)*
- Run the **`code-review` skill at effort `high`** on the feature diff vs `origin/development` — this is the deterministic code-review gate, not an ad-hoc read. The PR isn't open yet, so point it at the local diff: `git diff origin/development...feat/<slug>` (and `git log origin/development..feat/<slug>` for commits). ONLY if the `code-review` skill is unavailable, fall back to a manual review of that diff (correctness, security, tests, migration/contract safety). The Stage-6 `qc-local` report covers the user-flow review for the senior gate.
- Apply the fixes worth making on the feature branch; if you change code, re-run **from Stage 2**.
- `ccam stage review`
- `ccam stage review --status running`, then launch a fresh-context reviewer agent (Agent tool, `subagent_type: Code Reviewer` — FOREGROUND, **never `fork`**; a reviewer who already watched you write the code is not a reviewer). Hand it ONLY: the lane's working directory, the lane spec path (requirement + acceptance criteria), the diff commands, and the brief below. Do NOT summarize your own implementation for it, and do NOT pre-empt findings — let it read the diff cold.
- Run the **`code-review` skill at effort `high`** on the feature diff vs `origin/development` — the deterministic gate, not an ad-hoc read. No PR is open yet, so point it at the local diff: `git diff origin/development...feat/<slug>` (and `git log origin/development..feat/<slug>` for commits). ONLY if the `code-review` skill is unavailable in its session, fall back to a manual review of that diff (correctness, security, tests, migration/contract safety, this repo's `CLAUDE.md` + `.claude/rules/` boundaries).
- Final line: `REVIEW: CLEAN` or `REVIEW: FINDINGS — <n>`, with the findings listed above it as `path:line — severity — problem — suggested fix`.
- Triage its findings with **receiving-code-review** judgment (verify each, neither blind agreement nor blind rejection) and apply what's worth applying on the feature branch. Changed source → re-run **from Stage 1b**; changed only tests → **from Stage 2**. Keep the findings + your resolutions — the senior gate reads them.
- The Stage-6 `qc-local` report covers the user-flow review for the senior gate.
- `ccam stage review --evidence "<findings count> findings, resolved"`
### 5 — QC plan *(bound the test scope before any browser QC)*
- Author a **QC Plan** the browser-QC agents (Stage 6 now, and a future Stage 13 once dev-QC exists) will execute against — so QC covers everything that matters and nothing that doesn't (no missed scenarios, no wandering into unrelated areas). Derive it from the acceptance points (lane spec) + the real change surface (`git diff origin/development...feat/<slug>` and `--stat`). Three parts:
@@ -113,12 +133,12 @@ The e2e hook doesn't run migrations itself — it tests the already-running stac
### 6 — Browser QC via the qc-local agent
- **Test-only fast-path:** on a fix-loop re-entry whose change is ENTIRELY test files (see the fix-loop rule), SKIP this stage — the app's runtime UI is unchanged — and record `--evidence "QC skipped: test-only change"`. Otherwise run it:
- `ccam stage qc --status running`, then launch the **qc-local** agent (Agent tool, `subagent_type: qc-local` — FOREGROUND; it gates the pipeline; the Setup section's agents preflight already installed it). Give it: the lane's working directory, the feature slug, the feature title, the acceptance points (lane spec), and the **QC Plan** (lane spec, Stage 5) as the authoritative scope to execute against. It owns the whole local browser QC and proof capture (`ccam lanes proof-link` first, then screenshots land under the proof gallery automatically). It runs against the lane's feature-branch stack from Stage 3. Do NOT drive the browser yourself at this stage.
- `ccam stage qc --status running`, then launch the **qc-local** agent (Agent tool, `subagent_type: qc-local` — FOREGROUND, fresh context, **never `fork`**; it gates the pipeline; the Setup section's agents preflight already installed it). Give it: the lane's working directory, the feature slug, the feature title, the acceptance points (lane spec), and the **QC Plan** (lane spec, Stage 5) as the authoritative scope to execute against — and NOTHING about how you built it. No "the button is at the top-right", no "this part already works", no known-issue list: a QC pass that starts from your mental model only re-checks what you already believed. It owns the whole local browser QC and proof capture (`ccam lanes proof-link` first, then screenshots land under the proof gallery automatically). It runs against the lane's feature-branch stack from Stage 3. Do NOT drive the browser yourself at this stage.
- Parse its last line: `LOCAL-QC: PASS` → continue. `LOCAL-QC: FAIL — <reasons>` → fix on the feature branch → re-run from Stage 2. Keep its report — it is the feature user-flow review for the senior gate.
- **Fold back discoveries:** if its report lists scenarios it found that weren't in the plan (its "Scenarios discovered during QC" section), add them to the `## QC Plan` in-scope list in the lane spec.
### 7 — Senior GO/NO-GO gate *(authorizes the publish)*
- Launch the **senior-gate-reviewer** agent (Agent tool, `subagent_type: senior-gate-reviewer` — installed the same way as `qc-local`, see Stage 6). Give it: the lane's working directory, the requirement + Stage-0 answers (the lane spec file), the feature branch, the Stage-4 code-review findings + resolutions, the Stage-6 `qc-local` report (the user-flow review), and confirmation that gates/e2e/review/QC passed. The agent inspects the local diff with `git diff origin/development...feat/<slug>` — no open PR is required (and none exists yet).
- Launch the **senior-gate-reviewer** agent (Agent tool, `subagent_type: senior-gate-reviewer` — FOREGROUND, fresh context, **never `fork`**; installed the same way as `qc-local`, see Stage 6). Give it: the lane's working directory, the requirement + Stage-0 answers (the lane spec file), the feature branch, the Stage-4 code-review findings + resolutions **as the other agents wrote them** (verbatim/by path — never your paraphrase of why each was fine), the Stage-6 `qc-local` report (the user-flow review), and the raw results of gates/e2e/QC. The agent inspects the local diff with `git diff origin/development...feat/<slug>` — no open PR is required (and none exists yet).
- Parse its final line:
- `VERDICT: GO` → proceed to Stage 8.
- `VERDICT: NO-GO — <fixes>` → `ccam stage gate-blocked --evidence "NO-GO — <reason>"` (an alias of `gate`, so the map holds while the lane's stage name says the gate refused), then fix on the feature branch and re-run **from Stage 2**. No attempt cap — the loop re-enters; the dashboard's time-on-stage surfaces a lane stuck cycling so the human can step in. Set `--status blocked` only for a genuine blocker you can't resolve.
@@ -141,6 +161,7 @@ The e2e hook doesn't run migrations itself — it tests the already-running stac
2. **Your tests / your code implicated** → real failure: fix on the feature branch, re-enter from Stage 2.
3. **Infra/flake signature** (a job with no test failures, OOM/contention on the shared runner, a hung job with no output, or a test that is green locally on the identical tree) → re-run the workflow via `gh run rerun <run-id> --failed` — ONCE. Still red after the rerun → treat it as real (or escalate with the evidence). Never rerun more than twice, and never push an empty commit to re-trigger CI.
4. A **hung** workflow (running way past its normal duration with no output) → `gh run cancel <run-id>` then rerun once.
5. **Still red after your fix, on the same job:** you have now mis-triaged it once — hand the triage to a fresh-context agent (`general-purpose`, FOREGROUND, never `fork`) with the run URL, the failing job's logs and the diff range, and NOT your theory of the cause. Calling your own failure a flake twice is how a real defect gets pushed past the gate.
### 11 — Report
- Post a concise report: PR URL, CI status, what shipped, and that the PR now **awaits a human merge** (this pipeline never merges).
+35 -7
View File
@@ -54,6 +54,11 @@ you dropped back to.
- If the task is a bug rather than a feature: **superpowers:systematic-debugging**
first. Root cause, not symptom — and grep every caller of the function you
are about to change, not just the path the report names.
- Have the plan **challenged by a fresh-context agent** (`Plan` or
`general-purpose`, never `fork`): missed requirements, wrong assumptions, a
simpler approach, unhandled edge cases. Give it the requirement and the plan,
not your reasons for believing the plan. Apply what survives
**superpowers:receiving-code-review** scrutiny.
### implement — smallest coherent diff
- `ccam stage implementing`
@@ -63,18 +68,35 @@ you dropped back to.
### tests — this repo's verification, not a claim
- `ccam stage tests --status running`
- Backend changed → `npm run test:server`. Frontend → `npm run test:client`.
MCP → `npm run mcp:typecheck` + `npm run mcp:build`.
- A UI snapshot diff is reviewed, never blindly regenerated
(`cd client && npx vitest run -u` only after you have read the diff).
- **Dispatch, don't self-grade.** Both halves below run in a **fresh-context
agent** (Agent tool, `subagent_type: general-purpose` — FOREGROUND, and
**never `fork`**: a fork inherits your context, which is the bias you are
trying to escape). Hand it only what it can verify itself — repo path, the
spec/requirement, `git diff` range, the commands — never your own conclusions.
- **Independent unit tests.** It reads the requirement and the diff cold and
writes the tests the implementation is *missing* — happy, negative and
boundary, in the repo's existing style. It may not touch non-test files nor
weaken existing tests. Final line: `UNIT-TESTS: PASS — <n> added` or
`UNIT-TESTS: FAIL — <test> :: <defect>`.
- **Suite run.** Backend changed → `npm run test:server`. Frontend →
`npm run test:client`. MCP → `npm run mcp:typecheck` + `npm run mcp:build`.
A UI snapshot diff is reported for review, **never blindly regenerated**
(`cd client && npx vitest run -u` is yours to run, only after you read the
diff).
- `FAIL` → fix the **source** (root cause), not the agent's test — then re-run
this phase. Rewriting a failing independent test to pass is the one move that
makes this whole phase worthless.
- Record the outcome: `ccam stage tests --evidence "<what passed>"`, or
`--result fail` with what failed. A step you could not run is reported as not
run, never as passed.
### review — a real review pass, not a re-read
- `ccam stage review`
- Run the **code-review** skill on the working diff, or
**superpowers:requesting-code-review** when handing it to an agent.
- `ccam stage review --status running`
- Hand the review to a **fresh-context agent** (`subagent_type: Code Reviewer`,
FOREGROUND, never `fork`) — a reviewer that watched you write the code is not
a reviewer. It runs the **code-review** skill on the working diff
(see also **superpowers:requesting-code-review** for what to hand over).
Final line: `REVIEW: CLEAN` or `REVIEW: FINDINGS — <n>`.
- Apply what is worth applying with **superpowers:receiving-code-review**
judgment: verify each point, neither blind agreement nor blind rejection.
- Changed code in response? Re-run the `tests` phase.
@@ -82,6 +104,12 @@ you dropped back to.
### gate — evidence before the completion claim
- **superpowers:verification-before-completion**. Commands actually run, output
actually read. This is the phase that stops "should work" from shipping.
- For a change of any real size, the gate is a **fresh-context agent** too
(`general-purpose`, FOREGROUND, never `fork`): hand it the requirement, the
diff range and the verification commands — not your evidence — and let it
re-run and re-check them. Final line: `GATE: GO` or `GATE: NO-GO — <what is
missing>`. A one-line fix does not need it; anything you would defend in a
review does.
- `ccam stage gate --evidence "<what was verified>"`
### ship — docs, then the user's call