Files
AgentHub/docs/superpowers/specs/2026-08-04-ship-feature-skill-design.md
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

8.8 KiB
Raw Permalink Blame History

E1 — Ship-feature pipeline template + skill port

Status: approved 2026-08-04. Roadmap it belongs to: docs/superpowers/plans/2026-08-03-shipyard-parity-lanes.md (subsystem E).

Problem

Shipyard's ship-feature/SKILL.md (~/MyDrive/Projects/ResearchAndDevelopment/AgentWorkflow/claude/skills/ship-feature/SKILL.md, 208 lines, 16 stages) is the driving skill that runs a lane end-to-end: intake → TDD implement → gates → e2e → review → QC → senior gate → publish PR → watch → post-merge verify → done. AgentHub has no equivalent yet. E (per the roadmap) is four independent pieces — this spec covers only the first: the pipeline template + the skill text itself. Agents (qc-local, senior-gate-reviewer, ticketer, dev-qc, pr-reviewer) and agenthub lanes sync-base are separate, later tasks; F's integrations (tracker, dev-QC, CI-wait) are later still.

Scope

In scope:

  1. A backend gap the skill text requires to be truthful: agenthub lanes up --qc, backed by a new QC_BOOT_ENV profile declaration.
  2. server/data/pipelines/ship-feature.json — the node/stage definitions the dashboard renders against.
  3. .claude/skills/ship-feature-lane/SKILL.md — the ported skill, every Shipyard bin/… call rewritten to its AgentHub equivalent.

Out of scope (later tasks, referenced by name in the ported skill but not built here):

  • agenthub lanes sync-base (the migration-collision + merge-driver command Stage 2/8/12 call).
  • agenthub lanes mcp sync (F) — Stage 0's MCP preflight becomes a manual check + a message to the human, not an auto-sync call.
  • agenthub lanes integration <name> / .agenthub/profile/integrations.env (F) — tracker/dev_qc/ci_wait are hardcoded off in this port; Stage 9 (ticket) and the dev-QC half of Stage 13 unconditionally skip; Stage 10's CI watch unconditionally uses the gh pr checks fallback the original skill already documents for "helper not configured" (no conditional branch needed — there is nothing to branch on yet).
  • agenthub ci (F, ci-job.sh port) — same reasoning; Stage 10/13's CI-triage logic that depends on it is dropped to the fallback path.
  • The five agents — the skill references them by subagent_type at Stages 6/7/9/13/12(pr-reviewer callout), but none exist yet. This spec's own verification stops where an agent invocation would occur.

Decisions

Choice Rationale
--qc boot flag New QC_BOOT_ENV profile declaration (space-separated KEY=value pairs, same shape as Shipyard's), injected into the boot hook's environment only when up is called with qc: true The skill calls lane-up.sh "$N" --qc in Stage 3 to get a deterministic (mocked/stubbed) stack for QC. Without a real flag this line in the ported skill would be false documentation — violates this repo's docs rule (executable, aligned with actual scripts). A profile that never declares QC_BOOT_ENV gets no extra env (dead code doesn't run), same pattern every other A2 declaration in DEFAULTS already follows.
state.sh "$N" init (open a clean feature slot before Stage 0's Q&A) Dropped — replaced by a plain agenthub feature activate <slug> at Stage 1 Task B's activateFeature already archives the outgoing active feature automatically on switch; Shipyard needed a separate init step because it had no DB-backed archive. Porting init as a distinct call would be redundant with what activate already does.
Integration toggles (tracker/dev_qc/ci_wait) Hardcoded off, not a runtime check F doesn't exist yet. The alternative (a stub agenthub lanes integration that always returns off) adds surface area for no behavioral difference today; the skill's own text already documents the "toggle off" behavior for each stage, so hardcoding is truthful, not a shortcut. When F ships, this becomes a follow-up edit to swap hardcoded skips for real checks — an explicit, later, reviewable diff.
Hook names for lane-ci-gate.sh / lane-e2e.sh agenthub lanes hook ci-gate / agenthub lanes hook e2e Both names are already in server/lib/lane-profile.js's HOOKS allowlist, added during A1 specifically "because... the driving skill needs that surface stable" — this spec is that driving skill. No backend change needed for these two.
.harness-lane marker / lane-assign.sh Dropped entirely AgentHub already resolves a lane from cwd (path-boundary prefix match, documented in this repo's CLAUDE.md) — the marker file and the assign step exist in Shipyard only because it has no such resolution.
@@HARNESS_ROOT@@ / @@DEV_QC_MCP@@ / @@TRACKER_MCP@@ placeholders Dropped Install-time templating that doesn't exist in AgentHub; every reference becomes the literal AgentHub command or, for the two MCP placeholders, is deleted along with the (out-of-scope) integrations that used them.

Command mapping

Shipyard AgentHub Status
state.sh "$N" set stage=X status=Y agenthub stage X --status Y exists
state.sh "$N" activate feat/<slug> agenthub feature activate <slug> exists (Task B)
state.sh "$N" init (dropped — see Decisions) n/a
lane-ci-gate.sh "$N" agenthub lanes hook ci-gate exists (hook allowlisted)
lane-up.sh "$N" --qc agenthub lanes up --qc new in this task
lane-e2e.sh "$N" [-- specs] agenthub lanes hook e2e [-- specs] exists (hook allowlisted)
lane-sync-dev.sh … agenthub lanes sync-base … later task (referenced, not built)
lane-mcp-sync.sh "$N" agenthub lanes mcp sync F (referenced as manual fallback)
lane-env.sh "$N" --check X (hardcoded off) F (deferred)
ci-job.sh status|failures|rerun|cancel agenthub ci … F (deferred; skill uses its own gh-only fallback)

Design

--qc boot flag

  • QC_BOOT_ENV added to server/lib/lane-profile.js's DEFAULTS (empty string default — off).
  • POST /:id/up accepts {build, qc} in its body (currently only reads build); qc: true is threaded through to whatever assembles the boot hook's environment (read the actual upLane/hook-invocation code path in server/lib/lane-runtime.js before implementing — this spec names the profile declaration and the route contract, not the exact internal plumbing function).
  • agenthub lanes up [--no-build] [--qc] in bin/agenthub.js — --qc sets {qc: true} in the POST body alongside the existing --no-build → {build: false} handling.
  • QC_BOOT_ENV format: space-separated KEY=value pairs, parsed the same way this file already parses PORTS/LANE_DIRS (space-separated lists) — not a new parsing convention.

Pipeline template

server/data/pipelines/ship-feature.json — one node per skill stage (0 through 15, using the skill's own stage names: intake, plan, implementing, gates, e2e-feature, e2e-feature-passed, review, qc-plan, qc, gate, publishing, pr-open, reported, watching-pr, merged, done), same node-definition shape default.json already uses (label, detect rules matching the stage= values agenthub stage sets). default.json untouched. A lane opts into this template via its pipeline field, same mechanism every other custom template already uses.

Skill

.claude/skills/ship-feature-lane/SKILL.md — the full port. Frontmatter, hard rules, and all 16 stages carried over with the Command mapping table's substitutions applied line-by-line. Every hard-won rule (turn-liveness, no-retry-cap/phase-clock, one-driver-per-MCP, never-push-base, the fix-loop's two fast-path exceptions, cross-lane etiquette) is kept verbatim in spirit, with lane-lock.sh etiquette re-pointed at D's agenthub lock CLI and named locks.

Invariants

  1. AgentHub still does not orchestrate. The skill runs in the session and calls agenthub commands one at a time; nothing in this task adds chaining, gate evaluation, or retry logic to the dashboard itself.
  2. Every command the skill text names must actually exist and behave as documented — the docs-markdown rule (executable examples, aligned with actual scripts) applies to a skill file exactly as it applies to docs/*.md.
  3. A profile that never declares QC_BOOT_ENV sees no behavior change — --qc degrades to a plain boot when the declaration is absent, same as every other optional A2 declaration.

Verify

A real dry run on a scratch repo with a profile, walking Stage 0 through Stage 2 (intake → plan → agenthub lanes hook ci-gate) — the furthest the pipeline can go without the not-yet-built agents. Confirms every agenthub command named in stages 0–2 exists and behaves as documented. agenthub lanes up --qc gets its own unit/integration test verifying QC_BOOT_ENV reaches the boot hook's environment when declared, and is a no-op when absent. Full Stage 0→14 verification is the agents-port task's responsibility, once qc-local/senior-gate-reviewer exist.