Files
AgentHub/docs/superpowers/specs/2026-08-05-agents-port-design.md
T
nntrivi2001 17d56d0e01 refactor!: rebrand CCAM to AgentHub
Clean break, no compatibility alias. Renames the product name, the CLI
binary (`ccam` -> `agenthub`), the env var prefix (`CCAM_` ->
`AGENTHUB_`), the Prometheus metric namespace (`ccam_*` ->
`agenthub_*`), the tmux session prefix (`ccam-lane-<id>` ->
`agenthub-lane-<id>`), the per-repo runtime profile directory
(`.ccam/profile` -> `.agenthub/profile`), the lanes state root
(`~/.claude/ccam-lanes` -> `~/.claude/agenthub-lanes`), the bundled
plugins (`plugins/ccam*` -> `plugins/agenthub*`) and their slash
commands (`/ccam-doctor` -> `/agenthub-doctor`, `/ccam:*` ->
`/agenthub:*`).

Because there is no alias, an existing install has to be updated by
hand: rename its `.ccam/profile` directory and any `CCAM_*` variables,
and reinstall the plugin under its new name.

Two other name families are deliberately left alone here, since they are
not just strings: the `Claude-Code-Monitor` repository/marketplace name,
and the `agent-dashboard` npm package plus its `~/.claude/agent-dashboard`
runtime directory, which holds the live database and needs a migration
rather than a rename.

Verified: server 1406/1406, client 459/459, `grep -i ccam` clean across
tracked files, `openapi.yaml` regenerated (95 paths, unchanged count).
2026-09-07 12:09:15 +07:00

9.6 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. agenthub 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 AgentHub 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 AgentHub 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 (agenthub 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 command — senior-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 agenthub 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 agenthub-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. AgentHub'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 AgentHub heartbeat primitive exists for a subagent to call anyway (this repo's own rule: only agenthub 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 AgentHub 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) → agenthub 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 — AgentHub resolves a lane from cwd directly.
Install command semantics agenthub 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 AgentHub Status
lane-agents-install.sh <N> agenthub 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) agenthub lanes sync-base --check <branch> exists (E2)
lane-up.sh "$N" --no-build (revive a down stack) agenthub lanes up --no-build exists (E1 runtime, pre-existing flag)
profile-cat.sh review-checks.md Read tool on <lane>/.agenthub/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-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 agenthub 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.

agenthub 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 AgentHub-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: agenthub lanes agents install [<id>], same resolveLaneArg pattern as lanes proof-link.

Invariants

  1. AgentHub 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.