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:
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-2
@@ -1070,7 +1070,9 @@ The lane card shows a lock badge when the lane **holds** a named lock (its `lane
|
||||
|
||||
## The ship-feature-lane skill (E1)
|
||||
|
||||
The **ship-feature-lane** skill is the ported Shipyard driving skill for autonomous end-to-end feature pipelines in a single CCAM lane. It coordinates the entire development flow: implementation (TDD) → pre-push CI gates + dev preflight → e2e testing → code review → local QC → senior gate authorization → PR push and publication → CI watch → final report.
|
||||
The **ship-feature-lane** skill is the ported Shipyard driving skill for autonomous end-to-end feature pipelines in a single CCAM lane. It coordinates the entire development flow: implementation (TDD) → independent unit tests → pre-push CI gates + dev preflight → e2e testing → code review → local QC → senior gate authorization → PR push and publication → CI watch → final report.
|
||||
|
||||
**Every stage whose job is to judge the work runs in a fresh-context subagent, never in the driving session.** The plan debate (Stage 0b), unit tests (Stage 1b), the e2e run and its triage (Stage 3), code review (Stage 4), browser QC (Stage 6), the senior gate (Stage 7), and a re-triage of CI that stayed red after a fix (Stage 10) are each dispatched with the Agent tool to a subagent that starts with an empty context and receives only artifacts it can verify itself — working directory, lane spec, diff range, commands, and the other agents' reports verbatim, never the driving session's paraphrase of why a finding was fine. The stages the driving session keeps are the ones that *do* rather than judge: intake, implementation, the mechanical gates, publishing, the CI/PR watch, and applying every fix the judges ask for. `subagent_type: fork` is explicitly forbidden for these: a fork inherits the implementing session's context, so it inherits the belief that the code is already correct. The driving session implements and applies fixes; it never grades its own work. Stages 1b/3/4 use the generic `general-purpose`/`Code Reviewer` types (nothing to install); Stages 6/7 use the lane-installed `qc-local`/`senior-gate-reviewer` agents.
|
||||
|
||||
### Installing the skill (once per machine)
|
||||
|
||||
@@ -1094,7 +1096,7 @@ The skill frontloads all clarifying questions once, then runs unattended. The on
|
||||
### Current status: stages 0–8, 10–12, 14 work; stages 9, 13 deferred; stages 6–7 agent-gated
|
||||
|
||||
**Stages implemented now:**
|
||||
- **0-8**: Intake & frontloaded Q&A → plan → implementation → gates+preflight → e2e on feature branch → code review → QC plan → publish PR
|
||||
- **0-8**: Intake & frontloaded Q&A → plan → implementation → independent unit tests (1b) → gates+preflight → e2e on feature branch → code review → QC plan → QC → senior gate → publish PR
|
||||
- **10-12**: CI watch on the PR → report → watch PR until merge (gated fix-loop re-entries on review feedback)
|
||||
- **14**: Done
|
||||
|
||||
|
||||
Reference in New Issue
Block a user