refactor(lanes): drop the workflow skills and Superpowers link; pipelines go dormant
The plugin stops shipping its workflow layer: - skills/ship-feature and skills/ship-feature-lane, the 18 stage/ship slash commands (plugin.json keeps agenthub-doctor/update/open), and all four agents/ (qc-local, senior-gate-reviewer, backend-reviewer, frontend-reviewer). - CLI `agenthub skills install`, `agenthub lanes agents install`, `agenthub ship-full|ship-quick`; routes POST /api/skills/install and POST /api/lanes/:id/agents/install; the Settings button, the lane Tools menu item and the Add-lane setup step that called them. - The Superpowers auto-install: server/lib/skill-plugins.js, the bootstrap's autoInstallSkillPlugins / skillPluginsSettled gate and the doctor row. Pipelines are kept but dormant: server/data/pipelines/ is deleted, so no template ships. `default` resolves to EMPTY_PIPELINE (no nodes, progress 0), createLane still accepts it, POST /api/lanes/:id/stage answers 400 ENOPIPELINE, and the Workspace hides the stage timer, pickers, PipelineMap and strip stage chip for a lane with no nodes. A template dropped into DASHBOARD_PIPELINES_DIR turns it all back on. The server suite loads its templates from server/__tests__/fixtures/pipelines/. Docs: CLAUDE.md (marker, retired rules), README(.vi), INSTALL, ARCHITECTURE, docs/LANES|PLUGINS|CLI|API, agenthub-introduction.html.
This commit is contained in:
@@ -1,225 +0,0 @@
|
||||
---
|
||||
name: ship-feature-lane
|
||||
description: "Autonomous end-to-end feature pipeline for ONE AgentHub lane. Invoke inside a lane's working directory with a requirement: `/ship-feature-lane <requirement>`. Brainstorms with the user and frontloads ALL clarifying questions once (`AskUserQuestion`), stops for their approval of the plan, 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 → the user's acceptance → 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, the senior gate says GO and the user accepts — it's finalized when reviewers see it. A NO-GO loops back to the gates, or to replanning when the approach itself was wrong. Declares lane stage at every step via `agenthub stage` for the dashboard. Use when the user wants to build/ship/implement a feature in a AgentHub lane. NOTE: ticket-filing (Stage 9) and post-merge dev-site QC (Stage 13's second half) are currently OFF (F's integrations aren't built yet) — Stage 13's CI-wait half now runs via agenthub lanes ci status."
|
||||
---
|
||||
|
||||
# Ship Feature Lane (AgentHub lane pipeline)
|
||||
|
||||
You are running the autonomous feature pipeline for **one AgentHub lane**. The human's interactive touchpoints are exactly three — **Stage 0 (frontloaded Q&A)**, **Stage 0b (approving the plan)** and **Stage 7 (accepting the work before the PR is published)** — plus **merging the PR on GitHub**; everything between them runs to completion or to a `blocked` escalation, reporting progress through `agenthub stage` (which the dashboard renders). Those three are not optional politeness: they are the points where being wrong is cheapest to fix (before a plan), and where being wrong becomes public (before a PR).
|
||||
|
||||
## Current status
|
||||
|
||||
**Stages currently hardcoded skipped** (pending F's integrations):
|
||||
- **9 (Ticket)**: Ticket-filing integration not yet built — this stage is skipped entirely.
|
||||
|
||||
**Partially wired:**
|
||||
- **13 (Post-merge verification)**: CI-wait half now runs for real via `agenthub lanes ci status`. The dev-QC half (QCing the deployed site) is still unavailable — Stage 13 always ends noting that gap even when CI-wait passes clean.
|
||||
|
||||
## Setup — do this first, every run
|
||||
|
||||
```bash
|
||||
LANE_DIR="$(pwd)" # the lane clone IS your cwd — AgentHub resolves the lane from this, never a hardcoded path
|
||||
```
|
||||
- AgentHub resolves your lane from `cwd` automatically (longest path-boundary prefix match) — there is no marker file to check and no separate assign step. If `agenthub stage` or `agenthub feature activate` ever fails with "no lane found", you are not inside a lane's working directory; stop and tell the human.
|
||||
- **Pipeline template is this skill's contract, not whatever the lane started on.** Before your first `agenthub stage` call, run `agenthub lanes pipeline ship-feature` (no id needed — resolves from `cwd` like `agenthub stage`; idempotent, a no-op if already set) so every stage below resolves against the 16-node `ship-feature` map. The human is never expected to pick this in Add Lane or anywhere else — you force it to match the skill actually running.
|
||||
- All stage updates go through `agenthub stage <stage> [--status <s>] [--evidence "..."]` — **call it at the start of every stage** (this is also the heartbeat, visible on the dashboard).
|
||||
- **Integration toggles: check, don't assume.** `agenthub lanes integration tracker`, `agenthub lanes integration dev_qc`, `agenthub lanes integration ci_wait` each exit 0 (on) or 1 (off), reading the profile's `integrations.env`. No agent exists yet to actually FILE a ticket or run dev-QC even when a toggle reads on (`ticketer`/`dev-qc` are a later task) — so regardless of the check's result, Stage 9 (ticket) stays skipped, Stage 13's dev-QC and dev-CI-wait halves stay skipped, and Stage 10's CI watch keeps using the plain `gh pr checks` path (`agenthub ci` doesn't exist yet). Check the toggle where noted below anyway, so the evidence you record is honest about whether the PROFILE wants the integration on, distinct from whether AgentHub can act on it yet.
|
||||
- **Heartbeat during long stages.** Implementing (Stage 1), CI waits (Stage 10), and the watch/post-merge polls (Stages 12–13) can run many minutes between stage transitions — bump the heartbeat with `agenthub stage <same-stage>` after each commit and on each poll iteration, so the dashboard doesn't false-flag a working lane as stalled.
|
||||
- Profile hooks (`bootstrap`/`boot`/`migrate`/`seed`/`ci-gate`/`e2e`/`health`/`regen`) run through `agenthub lanes hook <name> [args…]` and `agenthub lanes up`/`down`. Use them; don't reinvent their logic.
|
||||
- **NEVER merge or rebase branches manually.** The ONLY merge that ever happens in this flow is `origin/development` INTO the feature branch, and only through `agenthub lanes sync-base` (fetches fresh, pre-checks migration collisions, auto-regenerates generated files — see the note on this command in Stage 2; it is a LATER task, referenced here by its intended contract). There is no other direction: never merge a feature branch into anything locally, never commit on `development`, and never touch `main`.
|
||||
- **NEVER push `origin/development` or `origin/main` (HARD).** `development` moves ONLY when a human merges a PR on GitHub. The only branch you ever push is your own `feat/<slug>` — and only after the senior gate's GO (Stage 8). If you ever find yourself typing `git push` with `development` or `main` on the line: STOP, `agenthub stage <current> --status blocked`.
|
||||
|
||||
## Context recovery — after conversation compaction
|
||||
|
||||
Long pipelines outlive the context window. When context is compacted (summarized), re-derive these before continuing:
|
||||
|
||||
```bash
|
||||
LANE_DIR="$(pwd)" # lane = cwd, resolved fresh
|
||||
```
|
||||
|
||||
Then check your current position:
|
||||
- **Lane state**: `agenthub feature show <slug>` (or `agenthub lanes` for the lane's own row) — shows current stage, status, feature title, branch, gate decision, PR URL, notes.
|
||||
- **Git branch**: `git rev-parse --abbrev-ref HEAD` — which branch you're on.
|
||||
- **Feature slug**: from the branch name (`feat/X` → `X`), or from `agenthub feature list` (the lane's currently-active feature is marked `▶`).
|
||||
|
||||
Resume from the stage shown. If state says `stage=X status=running`, you were mid-stage X when context compacted — re-run that stage from the top (all `agenthub` commands are idempotent).
|
||||
- **MCP preflight (fail fast):** if this is the lane's first run, or a required Playwright MCP's `browser_*` tools aren't available in this session, run `agenthub lanes mcp sync` — it relocates the source repo's already-configured MCP servers into this lane's `.mcp.json`. If the source repo has none configured (`ENOMCPCONFIG`), tell the human to configure `.mcp.json` manually for the source repo first. Either way, restart the session after syncing so the new config loads — `playwright` and a local-QC MCP are always required for Stage 3/6. Catching this at Stage 0 costs a minute; catching it at Stage 13 strands a merged feature unverified.
|
||||
- **Agents preflight:** if this is the lane's first run through this pipeline, run `agenthub lanes agents install` once — it writes the `qc-local` and `senior-gate-reviewer` agent definitions into the lane's own `.claude/agents/` (idempotent; re-running just overwrites with the current definitions). That copy is what makes the bare `subagent_type: qc-local` resolve inside the lane. If the install isn't possible (not a git repo, or the CLI is unavailable), the `agenthub` plugin ships the same two agents, addressed as `agenthub:qc-local` / `agenthub:senior-gate-reviewer` — use those names instead. Only if NEITHER exists are Stages 6/7 unable to launch.
|
||||
|
||||
## Hard rules
|
||||
|
||||
- **Publish ONLY after the senior-gate-reviewer returns `VERDICT: GO` AND the human accepts it (Stage 7).** "Publish" = push the feature branch + open/update the PR (Stage 8). Nothing reviewer-visible exists before both, 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.
|
||||
- **Always SKIP** (runtime UI unchanged): Stage 5 (QC plan), Stage 6 (qc-local). Record `--evidence "QC skipped: test-only change"`.
|
||||
- If the diff contains ANY non-test file → this fast-path does NOT apply; take the full path above. The first pass (not a re-entry) always runs full QC.
|
||||
- **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: `agenthub 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.** `agenthub lanes hook ci-gate`, `agenthub lanes up`, `agenthub 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 `agenthub 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 `agenthub 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.** 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 `agenthub 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 (`agenthub 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. The ONE legitimate exception is a turn that ends on an `AskUserQuestion` at a scheduled touchpoint (Stage 0, 0b, 7): the human's answer is the re-invoker, and a pipeline waiting on a question it actually asked is not a stalled one. 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).
|
||||
- Keep the lane's state truthful: on any stop, set an accurate `agenthub stage <stage> --status <status> --note "<why>"`.
|
||||
- **Quality bar (applies to every code change, including fix-loop re-entries and follow-up PRs).** Tests are sharp and meaningful — each pins a real behavior/edge case (happy + negative + boundary), none trivial, redundant, or coverage-padding. Comments are minimal — only the non-obvious *why*, matching the surrounding density; never narrate the *what*. Investigate before fixing (root cause, not symptom — use **systematic-debugging**). Prefer reusing/extending existing code over duplicating it.
|
||||
- **One driver per MCP browser server.** Each MCP server owns ONE browser; two agents driving the SAME server interleave clicks in one tab. The local-QC MCP → the qc-local agent (Stage 6) only; the general `playwright` MCP → the main session for ad-hoc checks only (never while qc-local runs). Parallel agents on DIFFERENT servers are safe by design; a second concurrent driver on the SAME server is never OK.
|
||||
- **Cross-lane etiquette (locks + siblings).** Lanes share one machine and one dev site. Waiting on a cross-lane serializer (`agenthub lock acquire <name>`, e.g. around a shared build/e2e step) is NORMAL — it heartbeats while it waits, so you won't look stalled. NEVER free a lock by killing another lane's session or processes, deleting the lock's directory by hand, or shrinking `LOCK_MAX_HOLD`; a dead holder's lock auto-expires on its own. If a lock wait times out: re-try with a longer `--timeout`, or set `--status blocked` with a note and report. Touch ONLY your own lane's clone, state, and locks you hold.
|
||||
|
||||
## Stages
|
||||
|
||||
### 0 — Intake & frontloaded Q&A *(the only interactive part)*
|
||||
Do NOT jump to code. Understand the requirement first.
|
||||
|
||||
- **Restate + quick scan.** Restate the requirement. Do a fast targeted scan of the relevant code (use the `Explore` agent for breadth) so your questions are grounded in what actually exists.
|
||||
- **The brainstorm is mandatory, not conditional.** Run the **superpowers:brainstorming** skill here on every run — not only "if the requirement is fuzzy". A one-line requirement always leaves scope, edge cases and acceptance criteria unstated, and this stage is the only place left to find that out cheaply.
|
||||
- **Ask only what the repo cannot answer.** Read first, ask second: a question whose answer is in the code, the tests, `CLAUDE.md` or the existing UI spends the human's one interactive round on something you could have looked up. What belongs to them is intent — scope, priorities, trade-offs, what "done" means — never facts.
|
||||
- **Frontloaded Q&A — asked with `AskUserQuestion`, and you WAIT for the answers.** Put the questions to the human with the `AskUserQuestion` tool (batched, up to 4 per round, each with real options — the way plan mode asks), not as prose they may not answer. Ask **every** clarifying question in ONE batch: acceptance criteria, scope / non-goals, UI/UX specifics, data shapes, edge cases, which existing flows it touches. You may not answer them on the human's behalf and you may not go on to Stage 0b until they are answered — deciding for them here is what makes a whole autonomous pipeline build the wrong feature. Only if the human explicitly says to decide yourself do you proceed, and then you write the assumptions into the lane spec. **Sibling-surface check (mandatory):** if your scan shows the app has N parallel surfaces of the pattern the requirement touches (e.g. several foldered areas, several list pages sharing a component) and the requirement names fewer than N, explicitly ask "this exists in [all N places] — apply to all, or only [the named ones]?" A missed sibling here costs a full second pipeline pass when a reviewer catches it on the PR. Then activate a clean feature slot for this run: `agenthub feature activate <slug> --title "<short title>"` — Task B's `activate` archives whatever feature was previously active on this lane automatically, so this run's dashboard state starts clean without a separate "init" step. Then mark intake: `agenthub stage intake --status running`. After this the human is asked exactly twice more — to approve the plan (Stage 0b) and to accept the work before the PR is published (Stage 7) — plus any `blocked` escalation. Nothing else is interactive.
|
||||
|
||||
### 0b — Investigate & plan *(autonomous)*
|
||||
- `agenthub 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) — 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.
|
||||
- **STOP — the human approves the plan before any code exists.** This is the second of the three scheduled interactive touchpoints. Show them the plan: what changes, which files, what is deliberately out of scope, the test strategy, and how each acceptance criterion is met — plus the lane spec path. Ask with `AskUserQuestion`: approve / revise / change approach. "Revise" means edit the plan and the lane spec and ask again. **Stage 1 does not start without an approval in this turn** — an adversarial agent agreeing with your plan is not the human agreeing with it. Announce "Plan approved — going autonomous now" and only then continue.
|
||||
- A later stage that turns out to need a materially different approach comes BACK here for a fresh plan and a fresh approval, rather than drifting under the old one.
|
||||
|
||||
### 1 — Implement (TDD, to the plan)
|
||||
- Choose a **single-segment slug** for the feature — lowercase, hyphens, NO slashes. Cut the feature branch from **development** (the PR base): `git fetch origin && git checkout -b feat/<slug> origin/development`.
|
||||
- If Stage 0 activated a placeholder slug different from the final chosen one, reconcile: `agenthub feature activate <slug>` — it echoes back the canonicalized slug it actually stored; use THAT for the branch and every later reference.
|
||||
- Implement the agreed plan with the **test-driven-development** skill: failing test → minimal code → green → commit. Frequent small commits.
|
||||
- **Tests must be sharp and meaningful.** Each test pins a real behavior or edge case from the plan / acceptance criteria — cover the happy path, the negative/error path, and boundaries. NO trivial or redundant tests: don't assert constants or framework internals, don't re-test the same path twice, don't pad for coverage. A few precise tests that would actually catch a regression beat many shallow ones.
|
||||
- **Comment only when it earns its place.** Match the surrounding code's comment density. Comment the non-obvious *why* (intent, invariants, gotchas, links to context) — never narrate the *what* the code already says. Delete redundant/boilerplate/restating comments rather than adding them.
|
||||
- If your stack generates an API contract/client and the API changed, regenerate it (`agenthub lanes hook regen`) so the contract-check gate passes (stacks without a contract gate skip this).
|
||||
- `agenthub 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.
|
||||
|
||||
- `agenthub 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` → `agenthub stage tests --evidence "<n> independent unit tests added, green"` → Stage 2.
|
||||
|
||||
### 2 — Pre-push CI gates + dev preflight (on the feature branch)
|
||||
- `agenthub 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.
|
||||
- `agenthub 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.
|
||||
- `agenthub lanes sync-base --check feat/<slug>` — the dev preflight: fetches and checks the branch against the CURRENT `origin/development` without merging anything. Exit 5 on a migration-number collision: declare `agenthub stage migration-collision --status running` (an alias of `gates` — the map stays put, the lane's stage names WHY it is sitting there), rename the printed file to the suggested number on the feature branch (`git mv`, update any in-file references), then re-run Stage 2. Exit 0 with `DEV_DELTA:`/`DEV_OVERLAP:` output otherwise — informational, you do NOT sync the branch for it (GitHub merges non-conflicting histories fine); a large overlapping delta is a heads-up that post-merge behavior may differ from what you test locally.
|
||||
|
||||
### 3 — E2E on the feature branch
|
||||
The e2e hook doesn't run migrations itself — it tests the already-running stack. To exercise the feature's code and any new schema, boot the lane stack with the feature branch first:
|
||||
|
||||
- `agenthub stage booting --status running` — an alias of `e2e-feature`; the boot below can take minutes and this says which minutes they are.
|
||||
- `agenthub 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.)
|
||||
- `agenthub 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 — `agenthub lanes hook e2e` with `run_in_background: true`, a backgrounded `sleep 90` beside it, `agenthub 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 `agenthub 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 — `agenthub 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: `agenthub stage e2e-feature-passed --status running`
|
||||
|
||||
### 4 — Code review *(no open PR yet — use local diff)*
|
||||
- `agenthub 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 **Claude Code's own `code-review` skill** (the official plugin's `/code-review`) **at effort `high`** on the feature diff vs `origin/development` — the deterministic gate, not an ad-hoc read, and not a reviewer summarizing the diff in its own words. 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`.
|
||||
- **Scale the pass to the diff.** A handful of lines in one layer gets the `code-review` pass alone — three agents re-reading a 20-line change buys one opinion at three times the tokens, and this stage re-runs on every fix-loop lap. Add the domain reviewer(s) once the change has seams: multiple files in a layer, a route/schema/migration/hook touched, or anything you would want a second reader on.
|
||||
- **Domain reviewers, in parallel with the above (same message, separate Agent calls).** Check `git diff --name-only origin/development...feat/<slug>` for touched layers and launch every matching one — FOREGROUND, fresh context, **never `fork`**, addressed as `agenthub:backend-reviewer` / `agenthub:frontend-reviewer` (plugin-qualified — no lane install needed, unlike `qc-local`/`senior-gate-reviewer`):
|
||||
- Any path under `server/` → `agenthub:backend-reviewer`.
|
||||
- Any path under `client/` → `agenthub:frontend-reviewer`.
|
||||
- Neither touched (root/`skills/`/`agents/`/`scripts/`/docs-only change) → skip both; the generic Code Reviewer above is the only gate.
|
||||
- Hand each ONLY the lane's working directory and the diff range `git diff origin/development...feat/<slug>` — each scopes itself to its own domain's files even though the diff range is the same for both.
|
||||
- Each ends with its own parseable line: `BACKEND-REVIEW:` / `FRONTEND-REVIEW:` — `CLEAN` or `FINDINGS — <n>`.
|
||||
- Triage ALL findings — the generic review plus every domain reviewer that ran — together with **receiving-code-review** judgment (verify each, neither blind agreement nor blind rejection) and apply what's worth applying on the feature branch. A finding you reject is answered with a reason, never with silence. Changed source → re-run **from Stage 1b**; changed only tests → **from Stage 2**. Either way the re-entry passes through THIS stage again: review ends when a pass over the current diff comes back clean (or with only findings you explicitly and defensibly rejected), not when one pass has been performed. 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.
|
||||
- `agenthub stage review --evidence "<total findings count across all reviewers that ran> 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:
|
||||
- **In-scope scenarios** (numbered): each acceptance point with positive AND negative cases; adjacent flows sharing routes/components/data with the change; required **state coverage** (reload on each stateful screen touched, one logout→re-login, back/forth nav); and the required **UI/UX layout checks** for every form/screen the feature touches (narrow AND short viewport, expandables open so content exceeds the viewport, fixed chrome not clipped, every control labelled, section headers more prominent than field labels).
|
||||
- **Out-of-scope** (explicit): areas NOT to test because the change cannot affect them — this is what stops QC from over-testing.
|
||||
- **Smoke set**: login + main nav + ≥3 unaffected major areas.
|
||||
- Append it to the lane spec under a `## QC Plan` heading (`docs/superpowers/specs/lane-<slug>.md`) — the same file the senior gate reads. You are the **single writer** of this section; the QC agent only *proposes* additions in its report and you fold them in (Stage 6). This keeps the plan race-free yet living.
|
||||
- `agenthub stage qc-plan --status running`
|
||||
|
||||
### 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:
|
||||
- `agenthub stage qc --status running`, then launch the **qc-local** agent (Agent tool, `subagent_type: qc-local`, or `agenthub:qc-local` if the lane copy isn't installed — FOREGROUND, fresh context, **never `fork`**; it gates the pipeline; the Setup section's agents preflight covers both names). 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 (`agenthub 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`, or `agenthub:senior-gate-reviewer` if the lane copy isn't installed — 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` → the agent gate is satisfied; now the human's.
|
||||
- `VERDICT: NO-GO — <fixes>` → `agenthub 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 **re-enter by the SIZE of what is wrong**, not always at the same place:
|
||||
- A defect, a missed case, a wrong detail → fix on the feature branch and re-run **from Stage 2** (or Stage 1b if non-test source changed).
|
||||
- Wrong approach, wrong scope, or a requirement that turns out to mean something else → back to **Stage 0b**: replan, and take the new plan through its approval stop again before any further code.
|
||||
- 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. Two NO-GOs on the same root issue means the loop is not converging: stop and ask the human instead of a third lap.
|
||||
- **Then ask the human to accept, before anything reviewer-visible exists.** Publishing is outward-facing and irreversible in the social sense — a PR reviewers have seen cannot be un-seen. Present: what was built, what was verified and how (gates/e2e/QC with their real outcomes), what the reviews found and what you did about it, and anything you could not run. Ask with `AskUserQuestion`: publish the PR / send back for fixes / rethink the approach. `VERDICT: GO` is the agent's opinion about evidence; it is not the human's decision to publish. Not accepted → re-enter exactly as for a NO-GO above.
|
||||
- `agenthub stage gate --evidence "GO; human accepted"` (or `NO-GO — <reason>`)
|
||||
|
||||
### 8 — Publish: push branch + open/update PR *(GATED — only on GO)*
|
||||
- `agenthub stage publishing --status running`
|
||||
- `agenthub stage push-revalidate` (alias of `pr-open`) — then re-run the preflight: `agenthub lanes sync-base --check feat/<slug>` — development may have moved while you were in QC. A migration collision here (exit 5) sends you back to Stage 2 with the rename; a clean result (exit 0) proceeds to the push.
|
||||
- `git push -u origin feat/<slug>` — first push of the feature branch to remote. All gates have passed before this point; the PR is finalized before reviewers see it.
|
||||
- Open or update the PR **based on and targeting `development`**: `gh pr create --base development --fill` (or `gh pr edit` / the push itself if a prior run already created it). Capture the URL.
|
||||
- `agenthub stage pr-open --evidence "<pr-url>"` — the dashboard shows the PR link from here (via `--evidence` in `agenthub feature show`/`agenthub lanes`).
|
||||
|
||||
### 9 — Ticket *(currently SKIPPED — tracker integration is off)*
|
||||
- Tracker integration is hardcoded off (see Setup). Do nothing here; do not attempt to file a ticket. When F ships `agenthub lanes integration tracker`, this stage gets a real implementation. (Check `agenthub lanes integration tracker` in the heartbeat: even when on, no ticketer agent exists yet to act on it.)
|
||||
|
||||
### 10 — CI watch on the PR *(non-blocking)*
|
||||
- Check the PR's CI with `gh pr checks` / `gh`. Green → continue to the report + watch — never idle waiting for green.
|
||||
- **Red CI → triage before the fix-loop** (shared CI flakes under multi-lane load; treating every red as your defect wastes cycles):
|
||||
1. Read WHICH job/tests failed with `gh` (there is no `agenthub ci` yet — F builds that; use `gh run view`/`gh pr checks --watch` directly).
|
||||
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).
|
||||
- `agenthub stage reported --status running`
|
||||
- Do **NOT** clear or reset the lane's feature state. Cleanup is the human's call, from the dashboard — they may still be manually testing.
|
||||
|
||||
### 12 — Watch the PR *(until a human merges or closes it)*
|
||||
- `agenthub stage watching-pr --note "watching PR for comments + base conflicts + the merge"`
|
||||
- Loop every ~5 minutes, paced by a **backgrounded** wait so the turn isn't pinned (see the waiting-primitive rule above): run `sleep 300` with `run_in_background: true` — you're re-invoked when it elapses. Each iteration:
|
||||
- Check PR state: `gh pr view <pr_url> --json state,mergeable -q '.state + " " + (.mergeable|tostring)'`, and bump the heartbeat (`agenthub stage watching-pr`).
|
||||
- `MERGED` → a human merged it: go to **Stage 13** (post-merge verification).
|
||||
- `CLOSED` (unmerged) → the human rejected/abandoned it: `agenthub stage done --status passed --note "PR closed unmerged by human"` → STOP.
|
||||
- `CONFLICTING` → the feature branch conflicts with `development`. **Base guard first:** check the PR's actual base — `gh pr view <pr_url> --json baseRefName -q .baseRefName`. If it is NOT `development` (the base drifted — a human retargeted the PR, or it predates this pipeline), do NOT auto-merge anything: `--status blocked --note "PR base is not development — human decision"` and STOP. If the base IS `development`, declare `agenthub stage sync-conflict --status running` (an alias of `gates`, which is also where the re-entry below lands — one declaration, honest about both) and resolve it as real work:
|
||||
- `agenthub lanes sync-base feat/<slug>` (merges the latest `origin/development` INTO the feature branch — the only sanctioned merge). A migration-number collision (exit 5) means nothing was merged — rename the printed file on the feature branch, re-run Stage 2, then retry this step.
|
||||
- **Exit 4 — merge conflict, left in place on purpose.** Resolve every conflict thoughtfully on the feature branch — keep `development`'s behavior for code unrelated to this feature, preserve the feature's intent where they overlap; when genuinely ambiguous, STOP and escalate (`--status blocked`, note the files) rather than guess. Never hand-merge a generated contract/client file listed in the profile's `GENERATED_MERGE_PATHS` — the keep-ours driver + regen own them. `git add` ONLY the conflicted files, `git commit --no-edit`, then `agenthub lanes sync-base --continue feat/<slug>` (folds any regenerated artifacts into a follow-up commit).
|
||||
- Re-enter the pipeline **from Stage 2 through Stage 8** (the push updates the PR), then return here and keep watching.
|
||||
- For each new PR comment (list with `gh pr view <pr_url> --json comments`, tracking which you've already handled by comment id in your own notes), triage AND **always reply on its thread** (every comment gets a response — no silent handling, so reviewers see it was considered):
|
||||
- **Worth fixing** (reviewer-requested change, real bug, test/doc gap): this is a NEW CHANGE — `agenthub stage pr-comment-fix --status running` (alias of `watching-pr`, so the lane reads as *acting on a comment* rather than idly polling), then apply it on the feature branch and re-enter the pipeline **from Stage 2 through Stage 8** (+ Stage 10 CI watch). The full process applies; no shortcuts because "it's just review feedback". **After the fix is pushed, reply to the comment** confirming resolution — what changed + the commit/PR ref — by writing the reply to a file and posting `gh pr comment <pr_url> --body-file <path>` referencing the comment. **Never inline `--body "..."`** — bodies carry backticks/`file:line`/`$(...)` that bash reads as command substitution inside double quotes, which corrupts the comment and trips an approval prompt. Then come back here and keep watching.
|
||||
- **Question / discussion**: answer it via `gh pr comment <pr_url> --body-file <path>` (same file-not-inline rule) — no code change.
|
||||
- **Not worth fixing** (out of scope, working as intended, deferred): **reply with the reasoning** so the reviewer knows why it wasn't actioned (don't just skip it).
|
||||
- **Sign every reply** with a distinct attribution — end each posted body, on its own line, with: `— 🤖 ship-feature-lane pipeline`.
|
||||
- Nothing new → background another `sleep 300` (`run_in_background: true`) and end the turn; you'll be re-invoked for the next poll. A PR can sit for days — that's fine.
|
||||
|
||||
### 13 — Post-merge verification *(CI-wait works; dev-QC still unavailable)*
|
||||
- `agenthub stage merged --status running --note "watching development CI post-merge"`
|
||||
- Get the merge commit: `gh pr view <pr_url> --json mergeCommit -q .mergeCommit.oid`.
|
||||
- Loop every ~5 minutes, paced by a **backgrounded** wait (same shape as Stage 12): `sleep 300` with `run_in_background: true`. Each iteration, bump the heartbeat and check:
|
||||
- `agenthub lanes ci status <mergeSha>` — exit `3` (pending) → keep waiting, background another `sleep 300`, end the turn.
|
||||
- Exit `1` (failure) → triage exactly like Stage 10 (read the failing job via `gh run view <run-id>` — the run id is embedded in each failing check's `url` in the command's JSON output; distinguish real failure from shared-runner flake the same way). A real failure on `development` post-merge is a regression the fix-loop doesn't reach (the PR is already merged) — `agenthub stage merged --status blocked --note "<job> red on development after merge — human decision"` and STOP; this is not something the pipeline auto-fixes on a shared branch.
|
||||
- Exit `0` (success) → CI-wait passed. Dev-QC (QCing the deployed site) is a separate, not-yet-built integration — `agenthub stage merged --status passed --note "CI green on development; dev-QC unavailable (separate task)"` and proceed to Stage 14.
|
||||
- If `agenthub lanes integration ci_wait` reads off for this profile, skip the loop entirely and go straight to Stage 14 with `--note "ci_wait integration off for this profile"` — the toggle means the profile doesn't want this check, not that the command is unavailable.
|
||||
|
||||
### 14 — Done
|
||||
- Post the final report: PR merged, that dev-QC (deployed-site QC) is unavailable pending F; CI-wait already ran in Stage 13.
|
||||
- `agenthub stage done --status passed --note "merged; dev-QC unavailable (F not built)"` → STOP (leave the lane for the human to clear from the dashboard whenever).
|
||||
|
||||
## Escalation
|
||||
Whenever you STOP early (an ambiguous merge conflict, an unexpected/unrecoverable failure, a missing agent this skill depends on), set `agenthub stage <current> --status blocked --note "<what the human must decide>"` — the dashboard surfaces it. Then summarize for the human and wait.
|
||||
@@ -1,321 +0,0 @@
|
||||
---
|
||||
name: ship-feature
|
||||
description: Implement a feature safely end-to-end in this repository. Use when adding or changing functionality across backend, frontend, or MCP with required verification and documentation updates. Drives the Superpowers workflow skills and declares each phase with `agenthub stage` so the dashboard's pipeline map follows along. Brainstorms WITH the user at intake, stops for their approval of the plan before any code, reviews with Claude Code's own `code-review` plus only the domain reviewers the diff actually needs, and stops again at the gate for their acceptance — a NO-GO loops back to implement or plan rather than shipping.
|
||||
---
|
||||
|
||||
# Ship Feature
|
||||
|
||||
Use this workflow for medium or large implementation tasks. It does not restate
|
||||
how to plan, test, or review — the Superpowers skills own that. What lives here
|
||||
is the phase order, this repository's own rules, and the stage declaration at
|
||||
each boundary.
|
||||
|
||||
For a feature inside a AgentHub **lane**, use `ship-feature-lane` instead: it adds
|
||||
the branch/e2e/QC/senior-gate/PR half this skill deliberately leaves out.
|
||||
|
||||
## Declaring the stage
|
||||
|
||||
Each phase below starts with `agenthub stage <node>`, which is what puts the phase
|
||||
on the lane's pipeline map. The nodes are the `default` template's:
|
||||
`intake → plan → implement → tests → review → gate → ship → done`.
|
||||
|
||||
Set the template yourself, don't rely on how the lane was created: before your
|
||||
first `agenthub stage` call, run `agenthub lanes pipeline default` (no id needed —
|
||||
resolves from `cwd`; a no-op if the lane is already on it). This is what makes
|
||||
the choice invisible to the human — whichever of `ship-feature` or
|
||||
`ship-feature-lane` actually runs is what decides the template, not a picker
|
||||
they have to get right in advance.
|
||||
|
||||
`agenthub stage` needs a lane owning the current directory. If it reports no lane,
|
||||
this repo was never adopted (`agenthub lanes add --cwd $(pwd)` fixes it) — carry on
|
||||
with the workflow and skip the stage calls; they are reporting, not control
|
||||
flow. Never skip a phase because its stage call failed.
|
||||
|
||||
Declaring beats detection. The dashboard also *infers* these stages from the
|
||||
Superpowers skill invocations below, but an inference never renders `done` and
|
||||
never overrides a declaration — and detection cannot move a lane BACKWARD past
|
||||
a declared stage, so a rework loop is invisible unless you re-declare the phase
|
||||
you dropped back to.
|
||||
|
||||
## Waiting for an agent or a long command
|
||||
|
||||
A phase that dispatches a foreground agent (tests, review, gate) or runs a long
|
||||
command is **already** wired to wake you: you are re-invoked the moment a
|
||||
backgrounded Agent or helper finishes. So:
|
||||
|
||||
- Do not poll for it, and do not invent a timer. **`ScheduleWakeup` is a
|
||||
`/loop`-only primitive** — this pipeline is not a `/loop` session, so it
|
||||
neither paces nor sustains anything here, and in `auto` permission mode it can
|
||||
simply be refused (the safety classifier is a model call, which fails when
|
||||
that model is briefly unavailable). Never let a phase's progress depend on it.
|
||||
- Need to pace a wait anyway (a CI run, an external queue)? Background the wait:
|
||||
`sleep <secs>` with `run_in_background: true`.
|
||||
- Never narrate a wait you are not actually running. If you cannot sustain one,
|
||||
say so plainly and stop.
|
||||
|
||||
## The shape of a run
|
||||
|
||||
Forward: `intake → plan → implement → tests → review → gate → ship → done`.
|
||||
Two back-edges, and they are the point of the pipeline, not its failure mode:
|
||||
|
||||
- **`tests`/`review` → `implement`** — a failure or a finding sends you to the
|
||||
code, then forward through `tests` and `review` again.
|
||||
- **`gate` → `plan`** — a NO-GO about the APPROACH (wrong scope, wrong shape,
|
||||
the requirement meant something else) replans and re-earns the user's
|
||||
approval. A NO-GO about a DEFECT goes to `implement` instead.
|
||||
|
||||
Going back is a declaration: re-run `agenthub stage <node>` for the node you
|
||||
dropped to. Detection cannot move a lane backward on its own, so a silent
|
||||
rework leaves the dashboard showing a stage you already left, and the nodes
|
||||
ahead keep the previous pass's evidence.
|
||||
|
||||
## Right-size the run before you start it
|
||||
|
||||
This pipeline is not free: every phase that dispatches an agent costs a model
|
||||
call and minutes of wall clock, and the fix-loop pays it again on each lap.
|
||||
Match its weight to the work, and say in one line which weight you picked.
|
||||
|
||||
| Work | What runs |
|
||||
|---|---|
|
||||
| **Trivial** — typo, rename, one-line fix, a question | Not this skill. Do it, run the touched suite, say what you did. |
|
||||
| **Small** — one layer, a few files, no new interface | `intake` questions → `implement` → `tests` → `review` with `code-review` alone → `gate` (the user's acceptance IS the gate). Skip the plan-debate agent, the independent-test agent and the gate agent. |
|
||||
| **Medium / large** — multi-file, new route/schema/interface, cross-layer, or anything you would defend in a review | Every phase below, in full. |
|
||||
|
||||
Sizing is a claim you make out loud, not a shortcut you take quietly. When
|
||||
torn, take the heavier one. A small task that grows re-sizes upward mid-run —
|
||||
re-declare the phase you re-enter and pick up the skipped agents from there.
|
||||
|
||||
## Dispatching a judgement (used by `tests`, `review`, `gate`)
|
||||
|
||||
One contract, written once, so the phases below don't each re-argue it:
|
||||
|
||||
- **Fresh context, FOREGROUND, never `fork`.** A fork inherits your context —
|
||||
precisely the bias the dispatch exists to escape. Foreground because the phase
|
||||
gates on the answer, and the agent's completion is what re-invokes you.
|
||||
- **Hand only what the agent can verify for itself**: the repo path, the
|
||||
requirement/plan, the `git diff` range, the commands to run. Never your
|
||||
conclusions — "I already checked X", "this is safe because…" — those are the
|
||||
very claims it is there to test.
|
||||
- **One parseable final line** is the verdict (`UNIT-TESTS:`, `REVIEW:`,
|
||||
`BACKEND-REVIEW:`, `FRONTEND-REVIEW:`, `GATE:`). Read that line; never infer a
|
||||
pass from prose around it.
|
||||
- **Never dispatch what a command answers.** Running a suite, reading a log,
|
||||
grepping a path — do it yourself. An agent is for judgement, not for typing.
|
||||
- Agents for the same phase go out in **one message** so they run concurrently.
|
||||
|
||||
## Resuming after a compaction
|
||||
|
||||
A long run outlives the context window. Re-derive your position, don't guess it:
|
||||
|
||||
- `agenthub lanes` — the lane's declared stage, status and notes.
|
||||
- `git status` + `git diff --stat <base>...` — what is actually built.
|
||||
- The plan file — what was actually approved.
|
||||
|
||||
Resume at the declared stage and re-run it from the top; every `agenthub`
|
||||
command is idempotent. **A phase whose evidence you cannot find did not
|
||||
happen** — re-run it rather than assuming a past self did.
|
||||
|
||||
## Phases
|
||||
|
||||
### intake — brainstorm WITH the user, always
|
||||
- `agenthub stage intake --status running`
|
||||
- Restate the requirement and its success criteria.
|
||||
- Explore the impacted modules: `Explore` agent for breadth, then read the key
|
||||
files yourself. Identify which layers are hit (server / client / docs /
|
||||
scripts) — `repo-onboarding` if the area is unfamiliar.
|
||||
- **superpowers:brainstorming is MANDATORY here, not a fallback for a fuzzy
|
||||
requirement.** Run it before any plan exists. Skipping it because the ask
|
||||
"seems clear" is the single most common way this pipeline builds the wrong
|
||||
thing: a requirement typed in one line always leaves scope, edge cases and
|
||||
acceptance criteria unstated.
|
||||
- **Ask only what the repo cannot answer.** Read first, ask second: a question
|
||||
whose answer is in the code, the tests, `CLAUDE.md` or the existing UI costs
|
||||
the user's time and earns you a worse answer than reading would. What belongs
|
||||
to the user is intent — scope, priorities, trade-offs, what "done" means —
|
||||
never facts you could have looked up.
|
||||
- **Ask the user, and wait for the answer.** Put the open questions to them with
|
||||
`AskUserQuestion` — batched in one round (up to 4 at a time), each with real
|
||||
options, exactly the way plan mode asks. Questions that change what you build:
|
||||
scope boundaries, which surfaces are in/out, behavior on the edge cases you
|
||||
found, what "done" means. You may not answer them on the user's behalf, and
|
||||
you may not move to `plan` until they are answered. Answering yourself and
|
||||
proceeding IS the bug this phase exists to prevent.
|
||||
- The one exception: the user explicitly said to skip the questions and decide
|
||||
yourself ("cứ làm đi", "no questions", "you decide"). Then state the
|
||||
assumptions you are proceeding under, in writing, and go on.
|
||||
- **Leave when:** the user's answers are in hand (or their explicit "decide
|
||||
yourself" is), and you can state the scope, the non-goals and what "done"
|
||||
means in your own words without a guess in any of them.
|
||||
|
||||
### plan — a written plan, challenged, then APPROVED by the user
|
||||
- `agenthub stage plan`
|
||||
- **superpowers:writing-plans**: approach, files to change, the test strategy
|
||||
(which behavior each test pins), and how each success criterion is met.
|
||||
- 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.
|
||||
- **STOP. The plan is presented to the user and implementation does not start
|
||||
until they approve it in this turn.** Show the plan (or its path plus a short
|
||||
summary: what changes, which files, what is deliberately out of scope, how it
|
||||
will be verified) and ask with `AskUserQuestion` — approve / revise / change
|
||||
approach. "Revise" means edit the plan and ask again; the loop is the point.
|
||||
Writing a plan and immediately implementing it is exactly the behavior this
|
||||
phase forbids, however obvious the plan looks to you.
|
||||
- Approval covers the plan as presented. Work that turns out to need a
|
||||
materially different approach comes BACK here (`agenthub stage plan` again)
|
||||
for a fresh approval, rather than drifting under the old one.
|
||||
- **Leave when:** a written plan exists, it survived the challenge, and the user
|
||||
approved THIS version of it in this turn.
|
||||
|
||||
### implement — smallest coherent diff
|
||||
- `agenthub stage implementing`
|
||||
- Entered only from an **approved** plan (or from a gate NO-GO sending work
|
||||
back here). No approval in this turn → you are still in `plan`.
|
||||
- **superpowers:test-driven-development**: failing test → minimal code → green.
|
||||
- Smallest diff that satisfies the requirement. Every changed line traces to it.
|
||||
- **file-headers** applies to every source file you create or edit.
|
||||
- Work the approved plan task by task, in its order. Before leaving this phase,
|
||||
re-read the plan's acceptance criteria and check each one against what you
|
||||
actually built — that list, not your memory of it, is what `gate` will ask
|
||||
about.
|
||||
- **The plan turning out wrong is a result, not a detour.** If implementing
|
||||
shows the approach cannot work, or the requirement means something else, stop
|
||||
and go back to `plan` (re-declare it, present the new plan, get it approved
|
||||
again). Quietly building a different thing than the one approved is the
|
||||
failure this phase has to avoid.
|
||||
- Long implementation? Re-declare `agenthub stage implementing` as you go — it
|
||||
doubles as the heartbeat, so the dashboard doesn't read a working lane as
|
||||
stalled.
|
||||
- **Leave when:** every plan task is done, every acceptance criterion has
|
||||
something concrete behind it, and the diff contains nothing that traces to
|
||||
neither.
|
||||
|
||||
### tests — this repo's verification, not a claim
|
||||
- `agenthub stage tests --status running`
|
||||
- **Dispatch the judgement, run the commands yourself.** Only work that needs an
|
||||
unbiased pair of eyes is worth an agent; a deterministic command is not.
|
||||
- **Independent unit tests → a fresh-context agent** (`general-purpose`; see
|
||||
*Dispatching a judgement*). 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 → plain Bash, here.** Run the suite(s) the diff actually needs:
|
||||
backend changed → `npm run test:server`; frontend changed →
|
||||
`npm run test:client`; both → both. A docs-only change needs neither, and
|
||||
running the other layer's suite proves nothing about this diff. Nothing is judged, so nothing is
|
||||
delegated: an agent for this buys a second model's tokens to read output you
|
||||
can read for free. 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: `agenthub 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.
|
||||
- **Leave when:** the suites the diff needs are green in output you actually
|
||||
read, and the independent-test agent (when the size called for one) returned
|
||||
`PASS`.
|
||||
|
||||
### review — the native review, plus the domains this diff actually touched
|
||||
- `agenthub stage review --status running`
|
||||
- **Read the diff first, then decide who reviews it.** `git diff --name-only`
|
||||
against the base this task started from is what picks the reviewers. Spawning
|
||||
a fixed set regardless of what changed wastes a pass on files nobody touched,
|
||||
and worse, reads as coverage that never happened.
|
||||
- **Scale the pass to the diff.** A handful of lines in one layer gets the
|
||||
`code-review` pass alone — three agents re-reading a 20-line change costs
|
||||
three times the tokens for one opinion. Add the domain reviewer(s) once the
|
||||
change is big enough to have seams: multiple files in a layer, a route or
|
||||
schema or hook touched, or anything you would want a second reader on.
|
||||
- **Always: Claude Code's own `code-review` skill** (`/code-review`, on the
|
||||
working diff — it is also what the `review` node declares). Not optional, and
|
||||
not replaced by an agent reviewing "in its own words": run it in a
|
||||
fresh-context `Code Reviewer` agent whose job is to invoke that skill and
|
||||
report what it found (a reviewer that watched you write the code is not a
|
||||
reviewer). See **superpowers:requesting-code-review** for what to hand over.
|
||||
Final line: `REVIEW: CLEAN` or `REVIEW: FINDINGS — <n>`.
|
||||
- **Domain reviewers, conditional on the touched layers**, in the same message
|
||||
as the above so they run concurrently:
|
||||
- Any path under `server/` (routes, lib, hooks, db, CLI-facing code) →
|
||||
`agenthub:backend-reviewer`. No backend path changed → do not launch it.
|
||||
- Any path under `client/` (components, pages, i18n, styles) →
|
||||
`agenthub:frontend-reviewer`. No frontend path changed → do not launch it.
|
||||
- Both touched → both, in the same message so they run concurrently.
|
||||
- Neither touched (docs-only, scripts-only, config-only) → neither; the
|
||||
`code-review` pass above is the whole review.
|
||||
- Hand each ONLY the repo path and the working diff — each scopes itself to
|
||||
its own domain's files. Each ends with its own parseable line:
|
||||
`BACKEND-REVIEW:` / `FRONTEND-REVIEW:` — `CLEAN` or `FINDINGS — <n>`.
|
||||
- Apply what is worth applying — `code-review` plus every domain reviewer that
|
||||
ran — with **superpowers:receiving-code-review** judgment: verify each point,
|
||||
neither blind agreement nor blind rejection. A point you reject is answered
|
||||
with a reason, not silence.
|
||||
- **Changed code in response? Re-run `tests`, then re-run THIS phase.** Review
|
||||
is a loop, not a checkpoint: it ends when a pass over the current diff comes
|
||||
back clean (or with only findings you have explicitly and defensibly
|
||||
rejected), not when one pass has been performed.
|
||||
- Record it: `agenthub stage review --evidence "<n> findings across <who ran>,
|
||||
resolved"`.
|
||||
- **Leave when:** the latest pass over the CURRENT diff is clean or
|
||||
argued-through — not when a pass has merely happened.
|
||||
|
||||
### gate — evidence, then the user's acceptance
|
||||
- **superpowers:verification-before-completion**. Commands actually run, output
|
||||
actually read. This is the phase that stops "should work" from shipping.
|
||||
- At medium/large size the gate is a **fresh-context agent** too
|
||||
(`general-purpose`): 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>`. At small
|
||||
size skip it; the user's acceptance below is the gate.
|
||||
- **The gate is not yours to wave through. Ask the user.** Present, in a few
|
||||
lines: what was built, what was verified and how (the commands and their real
|
||||
outcome), what review found and what you did about it, and anything you could
|
||||
not run. Then ask with `AskUserQuestion`: accept / send back for fixes /
|
||||
rethink the approach. Silence is not acceptance, and neither is `GATE: GO` —
|
||||
the agent gate checks the evidence, the user decides whether this is what they
|
||||
wanted.
|
||||
- **NO-GO, or the user does not accept → go BACK, do not proceed.** Pick the
|
||||
node by the size of what is wrong, and re-declare it so the dashboard follows
|
||||
the rework (a declaration on an earlier node clears the nodes ahead of it —
|
||||
that is what makes a loop visible instead of leaving stale `done` evidence):
|
||||
- A defect, a missed case, a wrong detail → `agenthub stage implementing`, fix
|
||||
at the root cause, then forward through `tests` and `review` again.
|
||||
- Wrong approach, wrong scope, a requirement that turns out to mean something
|
||||
else → `agenthub stage plan`, replan, and get the plan approved again (the
|
||||
`plan` phase's approval step applies in full, every time through).
|
||||
- Either way the phases after it run again. Never carry a NO-GO forward into
|
||||
`ship` with a note about it.
|
||||
- Only once the user has accepted: `agenthub stage gate --evidence "<what was
|
||||
verified, and that the user accepted it>"`
|
||||
- **Leave when:** the verification really ran, its output was really read, and
|
||||
the user said yes. Two of three is a NO-GO.
|
||||
|
||||
### ship — docs, then the user's call
|
||||
- `agenthub stage ship`
|
||||
- **update-project-docs** — mandatory for any change to behavior, config,
|
||||
interfaces, events, schema, CLI commands, or features. Not optional, not
|
||||
deferred, not "if asked".
|
||||
- Commit / push / PR **only when the user asks in this turn**. Finishing an
|
||||
implementation is not authorization to commit.
|
||||
- **Leave when:** the docs that the change made wrong are right again, and you
|
||||
have reported plainly what shipped, what was verified, and what you skipped.
|
||||
- `agenthub stage done --status passed --evidence "<what shipped>"`
|
||||
|
||||
## This repository's own rules
|
||||
|
||||
Not restated here. `CLAUDE.md` is loaded in every session and already binds
|
||||
them — backward-compatible API/WebSocket contracts, fail-safe hooks,
|
||||
migration-safe schema changes, the destructive-lane and git-argv guards, and
|
||||
the lane boundaries (the console never writes a stage; the runtime never writes
|
||||
`stage`/`status`/`notes`). A second copy here would only drift out of sync with
|
||||
the first. Read `CLAUDE.md` and `.claude/rules/` for the area you are touching.
|
||||
|
||||
## References
|
||||
- Checklist template: `references/feature-checklist.md`
|
||||
@@ -1,21 +0,0 @@
|
||||
# Feature Checklist
|
||||
|
||||
- Scope
|
||||
- Problem and success criteria are explicit.
|
||||
- Impacted layers identified (server/client/docs/scripts).
|
||||
|
||||
- Implementation
|
||||
- Input validation and error handling are explicit.
|
||||
- Existing behavior preserved where not in scope.
|
||||
- Safety controls preserved.
|
||||
|
||||
- Verification
|
||||
- Backend: `npm run test:server` when backend changed.
|
||||
- Frontend: `npm run test:client` when UI changed.
|
||||
|
||||
- Documentation
|
||||
- `README.md`, `ARCHITECTURE.md`, `SETUP.md`, `INSTALL.md` updated as needed.
|
||||
- Commands in docs match `package.json`.
|
||||
|
||||
- Delivery
|
||||
- Known risks and unrun checks are clearly stated.
|
||||
Reference in New Issue
Block a user