Scopes the third of E's remaining pieces to the two agents the current skill text actually invokes (Stage 6/7). ticketer/dev-qc (F-gated) and pr-reviewer (unreferenced) stay out of scope; per-lane credential embedding is deferred pending a seed-account system this repo doesn't have yet.
9.5 KiB
E3 — Agents port: qc-local + senior-gate-reviewer
Status: approved 2026-08-05. Roadmap it belongs to:
docs/superpowers/plans/2026-08-03-shipyard-parity-lanes.md (subsystem E).
Problem
.claude/skills/ship-feature-lane/SKILL.md's Stage 6 (browser QC) and Stage 7 (senior GO/NO-GO gate) invoke the qc-local and senior-gate-reviewer subagents by subagent_type, but neither exists in this repo — a lane reaching either stage is currently marked blocked. Shipyard's source (~/MyDrive/Projects/ResearchAndDevelopment/AgentWorkflow/claude/agents/{qc-local,senior-gate-reviewer}.md) is the reference. The roadmap names five agents for E ("Agents"); this spec ports the two the current skill text actually invokes.
Scope
In scope:
server/data/agent-templates/ship-feature-lane/qc-local.md— the ported browser-QC agent template.server/data/agent-templates/ship-feature-lane/senior-gate-reviewer.md— the ported publish-gate agent template.ccam lanes agents install [<id>]— copies both templates into<lane>/.claude/agents/, git-excluded.docs/LANES.md+ roadmap progress line.
Out of scope (later, when their dependencies exist):
ticketer.md,dev-qc.md— both are invoked only by Stages 9 and 13, which are hardcoded-skipped pending F's tracker/dev-QC integrations. Porting them now would ship agent files nothing calls.pr-reviewer.md— not referenced anywhere in this repo'sSKILL.md(the CCAM port dropped the reference during E1; confirmed by grep). Nothing to unblock.- Per-lane embedded credentials — Shipyard's installer injects a real QA account's email/password directly into
qc-local.md's prompt text, sourced from a per-lane seeded account (.harness-qa.env) that has no CCAM equivalent (no seed-account system, no matchingsecrets.jscategory). This spec ports the agent's fallback path (no embedded creds → reportFAILwith a clear reason) rather than inventing a seed-account system to unblock a credentials feature nobody asked for yet. - MCP auto-provisioning (
ccam lanes mcp sync) — F, not built.qc-local.mdkeeps referencing theplaywright-qa-localMCP server name by convention;SKILL.md's Stage 0 already documents the manual-.mcp.jsonfallback this depends on. review-checks.mdreader command —senior-gate-reviewer.mdreads the profile's optionalreview-checks.mddirectly with the Read tool (a plain file, no CLI needed), not through a newccam lanes profile catcommand.
Decisions
| Choice | Rationale | |
|---|---|---|
| Template location | server/data/agent-templates/ship-feature-lane/*.md |
Parallel to server/data/pipelines/*.json (E1's pattern) — data files, not source. Not ccam-lanes/.claude/agents/, which already holds this repo's own dev-facing agents (backend-reviewer, frontend-reviewer, mcp-reviewer); mixing a lane's runtime-installed agents into that directory would be a name-collision risk and conflate two different agent populations. |
Heartbeat calls (state.sh set between QC scenarios) |
Dropped entirely | Shipyard dispatches these agents as a separate background-capable process, so a stalled multi-minute run needs an explicit touch to avoid a false "stalled" flag. CCAM's qc-local/senior-gate-reviewer run as a synchronous Agent-tool call inside the driving session's own turn — the turn is blocked on the subagent's return, so the session is already "alive" by definition for the whole run. No CCAM heartbeat primitive exists for a subagent to call anyway (this repo's own rule: only ccam stage writes progress, and these agents must never call it). |
Auto pre-seed login (lane-qa-login.sh, lane-reset.sh) |
Dropped; qc-local.md's login fallback becomes an honest failure, not a script call |
CCAM has no seeded-QA-account system these scripts assumed. Calling a command that doesn't exist would be the same "docs must be executable" violation E1's Decisions table already ruled against for hardcoded-off integrations — this spec's version reports LOCAL-QC: FAIL — login required, no seed-account mechanism configured instead. |
lane-sync-dev.sh --check reference (senior-gate-reviewer's merge-safety check) |
→ ccam lanes sync-base --check <branch> |
Direct 1:1 mapping — E2 already built and shipped this command with the exact contract (exit 5 collision, DEV_DELTA/DEV_OVERLAP output) the agent's text already describes. |
@@HARNESS_ROOT@@ / .harness-lane |
Dropped | Same reasoning as E1's skill port — CCAM resolves a lane from cwd directly. |
| Install command semantics | ccam lanes agents install [<id>], idempotent (overwrite-on-reinstall, not merge) |
Matches the "explicit, never automatic" shape this repo already uses for proof-link and the E2 merge-driver setup — a session calls it when it wants updated templates, the dashboard never calls it for them. |
.claude/agents/ git-exclusion |
Appended to <lane>/.git/info/exclude (clone-local, not the tracked .gitignore) |
Same mechanism write_lane_markers used in Shipyard and the same file this repo's proof-link machinery already touches — a lane-runtime concern never becomes a change to the app repo's own tracked ignore rules. |
Command mapping
| Shipyard | CCAM | Status |
|---|---|---|
lane-agents-install.sh <N> |
ccam lanes agents install [<id>] |
new in this task |
state.sh "$N" set (mid-run heartbeat) |
dropped — see Decisions | n/a |
lane-qa-login.sh "$N" local |
dropped — see Decisions | n/a |
lane-reset.sh "$N" (reseed on login failure) |
dropped — see Decisions | n/a |
lane-sync-dev.sh "$N" --check <branch> (senior-gate-reviewer's merge-safety check) |
ccam lanes sync-base --check <branch> |
exists (E2) |
lane-up.sh "$N" --no-build (revive a down stack) |
ccam lanes up --no-build |
exists (E1 runtime, pre-existing flag) |
profile-cat.sh review-checks.md |
Read tool on <lane>/.ccam/profile/review-checks.md directly |
no command needed |
"$HARNESS/bin/lane-mcp-sync.sh" (implied MCP setup) |
manual .mcp.json — SKILL.md Stage 0 already documents this fallback |
F (deferred) |
Design
Agent templates
Both files are near-verbatim ports of the Shipyard source with the Command-mapping substitutions applied and the out-of-scope credential/heartbeat/login sections rewritten per the Decisions table:
qc-local.md— frontmatter (name,description,model: opus,color: green) unchanged in shape. Body: drops the heartbeat loop and the@@HARNESS_ROOT@@/.harness-lanesetup; the "Account / login" section keeps the "if a credentials block is embedded at the top of this agent, use it" path (future-proofed for when a seed-account system exists) but replaces the auto-login-script fallback with an honestFAIL. Proof convention (proof/<feature-slug>/qc-local/<NN>-<what>.png) is unchanged — it already matches this repo's proof gallery (C) verbatim.senior-gate-reviewer.md— frontmatter unchanged (model: opus,color: red). Body: the merge-safety check's command becomesccam lanes sync-base --check <branch>; the stack-specific-checks step readsreview-checks.mdwith the Read tool if present, otherwise falls back to "derive the equivalents yourself" exactly as the original already instructs when that file is empty. Nothing else changes — this agent never touched credentials or heartbeats to begin with.
ccam lanes agents install
POST /api/lanes/:id/agents/install— reads both templates fromserver/data/agent-templates/ship-feature-lane/, writes them to<lane>/.claude/agents/{qc-local.md,senior-gate-reviewer.md}(creating the directory if needed), appends.claude/agents/to<lane>/.git/info/excludeif not already present (same idempotent read-existing-then-append pattern E2'ssetupMergeDriveralready established for.git/info/attributes). Returns{installed: ["qc-local.md", "senior-gate-reviewer.md"]}.- No templating/placeholder substitution needed at install time — both files are already CCAM-final text (all substitutions happened once, at port time, into the template files themselves). This is a deliberate simplification from Shipyard's Python templating step, which existed only to inject per-lane credentials and MCP names this scope doesn't have.
- CLI:
ccam lanes agents install [<id>], sameresolveLaneArgpattern aslanes proof-link.
Invariants
- CCAM still does not orchestrate.
agents installcopies static files and returns; nothing about it triggers, gates, or sequences pipeline stages. - Neither agent ever writes
stage/status/notes. Both already say so explicitly in their own prompt text (ported verbatim); this spec doesn't change that boundary. - A lane that never runs
agents installsees no behavior change — Stage 6/7 remainblockedexactly as today until a session explicitly installs the agents, same "explicit, never automatic" shape asproof-link.
Verify
Unit tests for the install route/CLI (template files land at the right path, git-exclude line is appended idempotently on a second call, a lane with no .git directory yet fails cleanly) — no new git-internals risk here (this is plain file I/O, not the git-worktree subtlety E2 had to test for). A manual read-through of both ported agent files against their Shipyard originals, confirming every @@HARNESS_ROOT@@/.harness-lane/removed-script reference is actually gone (not just the ones this spec called out) is part of the implementation task, not a unit test — prose files don't have an automated "no dead references" check beyond that read.