Files
Claude-Code-Monitor/docs/superpowers/specs/2026-08-05-agents-port-design.md
nntrivi2001 7606653537 docs(lanes): design E3 — agents port (qc-local + senior-gate-reviewer) (E)
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.
2026-08-05 11:46:28 +07:00

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:

  1. server/data/agent-templates/ship-feature-lane/qc-local.md — the ported browser-QC agent template.
  2. server/data/agent-templates/ship-feature-lane/senior-gate-reviewer.md — the ported publish-gate agent template.
  3. ccam lanes agents install [<id>] — copies both templates into <lane>/.claude/agents/, git-excluded.
  4. 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's SKILL.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 matching secrets.js category). This spec ports the agent's fallback path (no embedded creds → report FAIL with 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.md keeps referencing the playwright-qa-local MCP server name by convention; SKILL.md's Stage 0 already documents the manual-.mcp.json fallback this depends on.
  • review-checks.md reader commandsenior-gate-reviewer.md reads the profile's optional review-checks.md directly with the Read tool (a plain file, no CLI needed), not through a new ccam lanes profile cat command.

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.jsonSKILL.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-lane setup; 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 honest FAIL. 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 becomes ccam lanes sync-base --check <branch>; the stack-specific-checks step reads review-checks.md with 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 from server/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/exclude if not already present (same idempotent read-existing-then-append pattern E2's setupMergeDriver already 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>], same resolveLaneArg pattern as lanes proof-link.

Invariants

  1. CCAM still does not orchestrate. agents install copies static files and returns; nothing about it triggers, gates, or sequences pipeline stages.
  2. 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.
  3. A lane that never runs agents install sees no behavior change — Stage 6/7 remain blocked exactly as today until a session explicitly installs the agents, same "explicit, never automatic" shape as proof-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.