cohorte 1.2.6 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,66 @@
3
3
  Entries are shown by `/update-pipeline` ("What's new") after a core refresh. Keep them short,
4
4
  user-facing, most recent first. One `## <version> — <YYYY-MM-DD>` section per release.
5
5
 
6
+ ## 1.3.1 — 2026-07-30
7
+
8
+ - **`/cycle <feature_id> [max_rounds]`** — a launcher command for the full dev-cycle workflow,
9
+ so you don't have to phrase the request in prose. It resolves `workflows/cycle.js`
10
+ (bundled or global), checks the runtime is available (missing ⇒ it hands you the
11
+ conversational `/build` → `/smoke` → `/review` path instead), sanity-checks the spec is
12
+ frozen, launches the workflow in the background, then relays the verdict: outcome,
13
+ contract re-authorings to eyeball, the `questions` array verbatim, and the next step
14
+ (`/ship` on SHIP-READY, rerun `/cycle` or `/fix` otherwise). Kanban card moves included.
15
+
16
+ ## 1.3.0 — 2026-07-30
17
+
18
+ **Token economy — immediate wins, no workflow needed:**
19
+
20
+ - **Deterministic pre-flight before `/review` and `/smoke`.** A shipped script
21
+ (`pipeline/scripts/preflight.sh`) runs typecheck + lint + tests first; red ⇒ the command
22
+ aborts with the raw last-40 lines and **spawns zero agents** — a reviewer no longer burns
23
+ its whole run rediscovering what `tsc` printed for free. Green runs stamp
24
+ `.claude/preflight.ok`, and `gate.py` enforces it as a **phase gate**: a review/smoke
25
+ dispatch with a missing/stale stamp gets a confirm (`gate.preflight` in the profile).
26
+ - **Quiet commands.** New profile fields (`test_quiet_cmd`/`lint_quiet_cmd` per surface,
27
+ `commands.test_quiet`/`lint_quiet` repo-wide) hold the bridled forms agents actually run
28
+ (`--reporter=dot`, `--quiet`, failures-only); absent ⇒ `<cmd> 2>&1 | tail -40`.
29
+ `/init-pipeline` now asks for them instead of storing a bare `pnpm test`;
30
+ `/update-pipeline` tops up older profiles.
31
+ - **`/review` computes the diff once.** One `git diff --stat`, then full patches staged to
32
+ disk only for the touched surfaces — reviewers read the artifact instead of each
33
+ re-running git.
34
+ - **Conventions baked into rendered agents.** The implementer template gets a
35
+ `<SURFACE_CONVENTIONS>` slice rendered at init; at runtime agents read only the profile's
36
+ machine block. Edit conventions in `PIPELINE.md`, then `/update-pipeline` re-renders.
37
+ - **Capped reports.** Review reports: max 20 findings, one line each, zero code excerpts;
38
+ smoke returns: max 10 ❌ lines. Dispatch prompts now keep every volatile slot (feature id,
39
+ paths, file lists) at the END so repeats hit the prompt-cache prefix.
40
+ - `gate.py` also escalates every `ask` to a hard deny in unattended runs
41
+ (`bypassPermissions`) — nobody is there to answer a prompt.
42
+
43
+ **Workflows (opt-in — conversational commands stay the default and the fallback):**
44
+
45
+ - Four deterministic multi-agent scripts for the Claude Code Workflow runtime
46
+ (≥ 2.1.154, workflows enabled): **`workflows/cycle.js` — the full dev cycle on a frozen
47
+ spec** (contract → parallel build → smoke ∥ review(+cross-check) → fix, looping until
48
+ zero findings + PASS; contract changes handled in-loop by a lead-equivalent agent, human
49
+ decisions returned in a `questions` array at the end; a clean exit ticks the DoD and
50
+ stamps the freshness gate so `/ship` follows directly), `workflows/review.js` (preflight
51
+ gate → one reviewer per touched surface → adversarial cross-check of CRITICAL/security
52
+ findings → verdict only), `workflows/audit.js` (one auditor per domain, concurrent,
53
+ prioritized backlog), `workflows/refactor.js` (big domains only: shared first, parallel
54
+ implementers, per-domain verify + one retry). Mechanical phases route to haiku.
55
+ - New `profile-reader` agent (haiku) — phase 0 of every workflow: returns the
56
+ `PIPELINE.md` machine block as JSON, since workflow scripts have no filesystem access.
57
+ - `/doctor` check 8 reports the workflow prerequisites and which path a session will take;
58
+ the generated `settings.json` allow-list now covers what workflow agents need (quiet
59
+ commands, shipped scripts, `git rev-parse`, retrieval MCP tools) so runs don't stall on
60
+ prompts nobody is watching.
61
+ - Installers (npx CLI, install.sh, install.ps1) ship `core/workflows/` + `preflight.sh` +
62
+ the `profile-reader` agent in both global and bundled modes; CI dry-runs assert it.
63
+ - Dashboard: new headless **Audit** action (`claude -p "/audit"` — starts without a prompt,
64
+ no resume if the session dies) and the workflows state in the project drill-down.
65
+
6
66
  ## 1.2.6 — 2026-07-30
7
67
 
8
68
  - **`npx cohorte install` never installed the `smoke` agent.** It copied only `review.md` and
package/README.md CHANGED
@@ -163,7 +163,7 @@ npx cohorte dashboard --port=4400 --open # custom port, open the browser
163
163
  ```
164
164
 
165
165
  **Bound to `127.0.0.1` by default** — the dashboard's actions execute code (install/update/reset,
166
- and `/init-pipeline`·`/update-pipeline` via headless Claude), so it must stay on loopback. Each user
166
+ and `/init-pipeline`·`/update-pipeline`·`/audit` via headless Claude), so it must stay on loopback. Each user
167
167
  runs their own agent and drives only their own machine. `--host=0.0.0.0` exposes it to the network
168
168
  (it prints a security warning) — only on a trusted network, since anyone who reaches the port can run
169
169
  those actions.
@@ -178,10 +178,13 @@ those actions.
178
178
  column, via `gh`), otherwise a **Specs board** from `specs/*.md` (by `draft · frozen · in-review ·
179
179
  shipped`). The Kanban supersedes the Specs board when both would apply.
180
180
  - **Actions** (stream their output live) — **Update / Install core** (the shared global core, or a
181
- repo's bundled core); **Init-pipeline / Update-pipeline**, which run those Claude Code commands
182
- **headless** (`claude -p`, autonomous — Init skips the interactive interview, so review the result);
183
- and **Reset pipeline**, which backs up then wipes a project's pipeline footprint and reinstalls a
184
- fresh core. Buttons render only when they apply (e.g. Init only when there's no profile).
181
+ repo's bundled core); **Init-pipeline / Update-pipeline / Audit**, which run those Claude Code
182
+ commands **headless** (`claude -p`, autonomous — Init skips the interactive interview, so review
183
+ the result; Audit writes `specs/refactor-backlog.md`; headless runs start without any prompt and
184
+ have **no resume** if the session dies); and **Reset pipeline**, which backs up then wipes a
185
+ project's pipeline footprint and reinstalls a fresh core. Buttons render only when they apply
186
+ (e.g. Init only when there's no profile). The drill-down's health checklist also shows the
187
+ **workflows** state (scripts + profile-reader installed, which path a session will take).
185
188
 
186
189
  Runtime is **dependency-free** — node's built-in `http` server serves a prebuilt React app (the app
187
190
  source lives in `dashboard/app/`, built to `dashboard/dist/` at publish time). The `/doctor` checks
@@ -211,6 +214,7 @@ it in `.claude/pipeline/VERSION` and bundled repos in their committed `pipeline.
211
214
  | `/brainstorm` | Interactive persona panel that pressure-tests a feature idea. |
212
215
  | `/spec` | Freeze the feature spec + contract into `specs/<id>.md` (UI features also get a standalone design brief at `specs/design/<id>.md`). Also applies review returns. |
213
216
  | `/build <id>` | Lead authors the contract, then dispatches one implementer per surface in parallel. |
217
+ | `/cycle <id>` | Launch the full dev-cycle **workflow** on a frozen spec: build → smoke ∥ review → fix until zero findings; deferred questions in the output. Needs workflows enabled (falls back to the conversational path). |
214
218
  | `/smoke <id>` | Run the feature for real: infra up, contract endpoints, UI flows, design conformance. |
215
219
  | `/review <id>` | Read-only review agents (one per touched surface, parallel) audit the diff vs the spec. |
216
220
  | `/fix <id>` | Apply a review/smoke report: remediation into the spec, re-dispatch only the surfaces with findings. |
@@ -269,6 +273,37 @@ Rules that make it safe:
269
273
  their eventual reviews diff against reality.
270
274
  - `/doctor` check 6 shows the live slot table (feature ↔ worktree ↔ ports) when you lose track.
271
275
 
276
+ ### Workflows — deterministic multi-agent runs (opt-in)
277
+
278
+ Three phases also ship as **workflow scripts** for the Claude Code Workflow runtime — the same
279
+ fan-out the commands orchestrate, but driven by a deterministic script instead of the lead reasoning
280
+ it out turn by turn:
281
+
282
+ | Script | What it runs |
283
+ | ----------------------- | ----------------------------------------------------------------------------------------- |
284
+ | `workflows/cycle.js` | **The full dev cycle on a frozen spec**: contract → parallel build → smoke ∥ review(+cross-check) → fix, looping until zero findings + PASS (contract changes handled in-loop by a lead-equivalent agent). Human decisions come back in a `questions` array at the END — empty when `/brainstorm`+`/spec` did their job. Exits SHIP-ready (DoD ticked, freshness stamped) so `/ship` is a straight shot. |
285
+ | `workflows/review.js` | Preflight gate (aborts while red — zero agents), one reviewer per touched surface, adversarial cross-check of CRITICAL/security findings, merged verdict only. |
286
+ | `workflows/audit.js` | One auditor per domain (every surface + shared) concurrently, prioritized `specs/refactor-backlog.md`. |
287
+ | `workflows/refactor.js` | Big domains only: `shared` first and alone, then parallel surface implementers, per-domain verify + one retry. |
288
+
289
+ The essentials:
290
+
291
+ - **The conversational commands stay the default path** — and the fallback when workflows are
292
+ disabled or the client is too old. A workflow runs only when you explicitly ask for it
293
+ ("run the review workflow").
294
+ - **Prerequisite: Claude Code ≥ 2.1.154** with workflows enabled. `/doctor` (check 8) tells you
295
+ which path your session will take and why.
296
+ - **No input mid-run — questions at the edges.** A workflow runs to completion without asking
297
+ anything. `cycle.js` moves the decisions to its boundaries: a readiness gate refuses a non-frozen
298
+ spec up front, and whatever would have been a mid-run question lands in the result's `questions`
299
+ array at the end (spec gaps, hit round-cap) — answer them, rerun the cycle. The destructive-
300
+ command gate still fires inside workflow subagents; in unattended runs its confirms become denies.
301
+ - Phase 0 of every script is the `profile-reader` agent (haiku) — it reads `PIPELINE.md` and hands
302
+ the script the profile as JSON, since workflow scripts have no filesystem access. Mechanical
303
+ phases run on haiku; judgment phases use the same pinned agents as the commands.
304
+
305
+ Details: `profile/SCHEMA.md` §Workflows.
306
+
272
307
  ## Privacy — opt-in telemetry
273
308
 
274
309
  Cohorte can send **anonymous** usage pings (core version, OS, phase name, duration, per-surface
@@ -296,15 +331,16 @@ bin/cli.js # the npm CLI: install / update / dashboard / version (c
296
331
  install.sh # script installer (fresh + --update) for no-Node environments
297
332
  install.ps1 # same installer for Windows PowerShell (fresh + -Update)
298
333
  core/ # copied verbatim into ~/.claude (global) or <project>/.claude (bundled)
299
- agents/ # implementer.template.md (rendered per surface) + review.md + release.md
300
- commands/ # init-pipeline + the workflow commands + /update-pipeline
301
- hooks/ # gate.py (destructive-command gate; branch-aware git/docker free off the default branch)
334
+ agents/ # implementer.template.md (rendered per surface) + review / release / smoke / profile-reader
335
+ commands/ # init-pipeline + the pipeline commands + /update-pipeline
336
+ hooks/ # gate.py (destructive-command gate; branch-aware; preflight phase gate)
302
337
  templates/ # handoff / brainstorm-return / design-brief / review-feedback / pr-body / spec
338
+ workflows/ # opt-in Workflow-runtime scripts: review.js / audit.js / refactor.js
303
339
  profile/
304
340
  PIPELINE.template.md # the profile skeleton /init-pipeline fills
305
341
  SCHEMA.md # field reference
306
342
  cohorte.config.template.yaml # seeds ~/.claude/cohorte.config.yaml (kanban)
307
- scripts/ # new-feature / remove-feature worktree-isolation templates
343
+ scripts/ # worktree-isolation templates + shipped preflight/kanban/telemetry scripts
308
344
  dashboard/ # local web cockpit (npx … dashboard) — see dashboard/README.md
309
345
  server/ # dependency-free node runtime (serves the built app + JSON/stream API)
310
346
  app/ # Vite + React source (built to dashboard/dist/ at publish time)
package/bin/cli.js CHANGED
@@ -92,7 +92,10 @@ fs.mkdirSync(dest, { recursive: true });
92
92
 
93
93
  // --- helpers (mirror install.sh) --------------------------------------------
94
94
  function copyCore() {
95
- for (const d of ['commands', 'hooks', 'templates']) {
95
+ // `workflows` = the deterministic orchestration scripts (review/audit/refactor) the
96
+ // Workflow runtime resolves from .claude/workflows (bundled) or ~/.claude/workflows
97
+ // (global) — same copy rule in both modes, like commands.
98
+ for (const d of ['commands', 'hooks', 'templates', 'workflows']) {
96
99
  fs.cpSync(path.join(src, 'core', d), path.join(dest, d), { recursive: true, force: true });
97
100
  }
98
101
  // 0.1.19 renamed questionnaire-domain-brief.md → research-brief.md; drop the stale copy.
@@ -9,16 +9,25 @@ You are the **<SURFACE_AGENT>** engineer for one feature of **<PROJECT_NAME>**.
9
9
  statelessly, from the spec you are given. You cannot talk to the other surface agents — your only
10
10
  shared surface is the frozen contract and the spec.
11
11
 
12
- > **First action, always:** read `PIPELINE.md` the whole machine block (§`pipeline-profile`; it is the
13
- > shared contract: surfaces, contract, gate). Then in §Conventions read ONLY the `### Shared` stanza and
14
- > your own `### Surface: <your key>` stanza (Grep for your key; the other surfaces' stanzas are another
15
- > agent's rules skip them), plus §Testing. You have no memory; re-read your slice every dispatch —
16
- > but never load the other surfaces' convention prose.
12
+ > **First action, always:** read `PIPELINE.md`'s fenced `yaml pipeline-profile` block ONLY the
13
+ > machine contract (surfaces, contract, commands, gate). Do **not** read the prose sections
14
+ > (§Conventions/§Testing): your slice of them is baked into this file below (§Your conventions),
15
+ > rendered from the profile re-reading the prose every dispatch is exactly the cost the bake
16
+ > removes. If the baked slice visibly contradicts `PIPELINE.md`, say so in your handoff: the profile
17
+ > wins, and this agent file needs a re-render (`/update-pipeline`).
17
18
 
18
19
  ## You own
19
20
 
20
21
  `<SURFACE_PATH>/**` only. Everything under it — and nothing outside it.
21
22
 
23
+ ## Your conventions (baked from `PIPELINE.md` at render time)
24
+
25
+ <!-- Rendered by /init-pipeline (and refreshed by /update-pipeline's reconcile) from
26
+ §Conventions `### Shared` + `### Surface: <your key>` + your §Testing lines.
27
+ Edit conventions in PIPELINE.md, never here — this block is regenerated. -->
28
+
29
+ <SURFACE_CONVENTIONS>
30
+
22
31
  ## You must NEVER
23
32
 
24
33
  - Touch any other surface's tree (see the `surfaces` list in `PIPELINE.md`). That's another agent's.
@@ -53,15 +62,19 @@ tools are unavailable or come up empty.
53
62
  ## How you work — strict TDD (red → green → refactor)
54
63
 
55
64
  1. <SURFACE_TDD_STEP1>
56
- 2. **Write the failing test(s) first** from the frozen contract (your surface's test runner is
57
- `surfaces[].test_cmd` in `PIPELINE.md`). Cover exactly what §Testing prescribes for your surface.
58
- Run the test command and watch it fail (red).
59
- 3. Implement until green, following §Conventions for your surface.
65
+ 2. **Write the failing test(s) first** from the frozen contract. Cover exactly what your baked
66
+ Testing rules (§Your conventions) prescribe. Run the test command and watch it fail (red).
67
+ 3. Implement until green, following your baked conventions.
60
68
  4. Refactor to the conventions. Keep tests green.
61
- 5. **Lint + format before handoff:** run your surface's `lint_cmd` from `PIPELINE.md` and fix every
62
- issue. If the project registers a PostToolUse format hook (see `.claude/settings.json`), your files
63
- are already formatted on every write — skip `format_cmd`; otherwise run it too. Code you hand off
64
- must be lint-clean and formatted.
69
+ 5. **Lint + format before handoff:** run your surface's lint and fix every issue. If the project
70
+ registers a PostToolUse format hook (see `.claude/settings.json`), your files are already
71
+ formatted on every write — skip `format_cmd`; otherwise run it too. Code you hand off must be
72
+ lint-clean and formatted.
73
+
74
+ **Run commands bridled — always.** Your surface's `test_quiet_cmd`/`lint_quiet_cmd` in `PIPELINE.md`
75
+ are the forms you execute (dot reporter / failures-only); when a quiet variant is empty or absent,
76
+ run `<full cmd> 2>&1 | tail -40`. Never print a full runner log into your context — redirect to a
77
+ file and grep it if you need more than the tail.
65
78
 
66
79
  ## Definition of done
67
80
 
@@ -72,7 +85,7 @@ of the contract your surface implements matches the spec exactly. User-facing co
72
85
 
73
86
  Your final message **is** the handoff (read by the lead, not a human chat). Keep it tight — the lead
74
87
  only acts on mismatches, test failures, remediation ticks, and TODOs; never list files one by one
75
- (the lead has `git diff --stat`):
88
+ (the lead has `git diff --stat`), never paste code excerpts (the code is on disk):
76
89
 
77
90
  ```
78
91
  # HANDOFF — <surface> · <feature_id>
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: profile-reader
3
+ description: Reads PIPELINE.md and returns its `yaml pipeline-profile` block as compact JSON. Phase 0 of every cohorte workflow — workflow scripts have no filesystem or shell access, so this agent is how a script learns the profile (surfaces, commands, flags). Mechanical, read-only, no judgment.
4
+ tools: Read, Grep, Glob
5
+ model: haiku
6
+ ---
7
+
8
+ You are the **profile-reader**. One job, purely mechanical: load this project's `PIPELINE.md` and
9
+ return the machine block as JSON. A workflow script (which cannot read files itself) parses your
10
+ return and parameterizes every later phase from it — so fidelity beats brevity, and prose beats
11
+ nothing only when something is wrong.
12
+
13
+ ## How
14
+
15
+ 1. Read `PIPELINE.md` at the repo root — specifically the fenced ` ```yaml pipeline-profile ` block.
16
+ It can be long; read the whole block, nothing after it (the prose sections are not your job).
17
+ 2. Convert the YAML to JSON **faithfully**: every key and value as written, comments dropped,
18
+ nothing invented, nothing "fixed". Keep types honest (`true`/`false` booleans, numbers as
19
+ numbers, `""` stays an empty string). Unfilled template placeholders (values still wrapped in
20
+ `<…>`) pass through as the literal string — the caller decides what to do with them.
21
+ 3. Return **only** the JSON object — no fences, no commentary, no markdown. Your final message is
22
+ parsed by a script.
23
+
24
+ ## Failure shape
25
+
26
+ If `PIPELINE.md` is missing, or the `yaml pipeline-profile` fence is absent or unparseable, return
27
+ exactly one JSON object instead: `{"error": "<one line: what is missing or broken>"}` — never a
28
+ partial profile, never prose.
@@ -85,8 +85,12 @@ domain** (same finding-line shape) instead of a SHIP/REVISE/BLOCK verdict.
85
85
 
86
86
  Every finding must be **self-sufficient for a stateless agent**: `file:line` · severity ·
87
87
  `spec-violation | quality | security` · one concrete suggested fix — it gets appended verbatim to the
88
- spec's `## Remediation`. Your final message **is** the report. Emit nothing outside this shape — no
89
- restated rules, no "verified clean" lists:
88
+ spec's `## Remediation`. Your final message **is** the report. **The shape is capped:** at most
89
+ **20 findings**, ONE line each, **zero code excerpts** (the diff and the source are on disk — a
90
+ `file:line` is enough for a stateless fixer). More than 20? Keep every CRITICAL/HIGH/security
91
+ finding, fill the rest by severity, and close the list with one line:
92
+ `+<n> more MEDIUM/LOW — re-run after the fix loop`. Emit nothing outside this shape — no restated
93
+ rules, no "verified clean" lists:
90
94
 
91
95
  ```
92
96
  # REVIEW REPORT
@@ -104,7 +108,7 @@ Verdict: <SHIP | REVISE | BLOCK>
104
108
  ## Findings
105
109
 
106
110
  - **[<SEVERITY>]** `<file>:<line>` · <spec-violation|quality|security> · <problem> → **Fix:** <concrete change>
107
- (order by severity; "None." if none)
111
+ (order by severity; "None." if none; max 20 lines, one per finding, no code excerpts)
108
112
 
109
113
  ## Notes
110
114
  (ONLY the RBAC / mobile-first assessment when the profile enables them; omit the section otherwise)
@@ -57,5 +57,7 @@ assert on the pieces you need.
57
57
  - **Write the full report to `specs/reports/<id>.md`** (overwrite) — the same gitignored buffer
58
58
  `/review` uses, so a `/fix` after a `/clear` still has the failures.
59
59
  - Tear down what you started (kill the dev server); leave shared infra as you found it.
60
- - **Your return to the lead is ONLY:** the verdict line (`PASS` / `FAIL`), the lines verbatim (if
61
- any), and `Full report: specs/reports/<id>.md`. No logs, no bodies, no screenshots.
60
+ - **Your return to the lead is ONLY:** the verdict line (`PASS` / `FAIL:<n>`), **at most 10
61
+ lines** one line each (`❌ <flow/endpoint> · expected <x> got <y>`), no command output, no code
62
+ or body excerpts; more than 10 ⇒ keep the 10 most severe and add `+<n> more — see the report` —
63
+ and `Full report: specs/reports/<id>.md`. No logs, no bodies, no screenshots.
@@ -8,23 +8,31 @@ You are the **lead**. Audit **$ARGUMENTS** (default: whole repo) to drive it to
8
8
  analyze only — no fixes (those go through `/refactor`).
9
9
 
10
10
  > Read `PIPELINE.md` §`commands` (the mechanical gates), `surfaces`, and §Conventions.
11
+ >
12
+ > **Workflow variant** (opt-in — SCHEMA.md §Workflows): on Claude Code ≥ 2.1.154 with workflows
13
+ > enabled, the human can ask to "run the audit workflow" (`<core>/workflows/audit.js` — one auditor
14
+ > per domain, concurrent). This conversational path stays the default and the fallback.
11
15
 
12
16
  ## 1. Mechanical gates (you run these — Bash)
13
17
 
14
18
  Run the profile's checks **scoped to `$ARGUMENTS`** when a path/domain is given (lint/format/typecheck
15
19
  on that path, tests via that surface's `test_cmd`); repo-wide only for the default whole-repo audit.
16
- Redirect each command's output into `specs/reports/audit-gates.txt` in the same call
17
- (`cmd > specs/reports/audit-gates.txt 2>&1`) so the bulk never sits in your history, then grep it for
18
- the `file:line` of every failure: `commands.format` in check mode (e.g. `prettier --check .` /
19
- `ruff format --check`), `commands.lint`, `commands.typecheck`, `commands.test`.
20
+ Use the quiet variants (`commands.lint_quiet`/`test_quiet`, else the `2>&1 | tail -40` fallback —
21
+ SCHEMA.md §Output discipline) and redirect each command's output into
22
+ `specs/reports/audit-gates.txt` in the same call (`cmd > specs/reports/audit-gates.txt 2>&1`) so the
23
+ bulk never sits in your history, then grep it for the `file:line` of every failure:
24
+ `commands.format` in check mode (e.g. `prettier --check .` / `ruff format --check`),
25
+ `commands.lint`, `commands.typecheck`, `commands.test`.
20
26
 
21
27
  ## 2. Convention + TDD audit (dispatch `review` in audit mode)
22
28
 
23
- Dispatch `review` (read-only): "Audit `$ARGUMENTS` against `PIPELINE.md` (no spec**audit mode**).
24
- Check conventions (§Conventions per surface), TDD coverage (untested entry points / modules per surface),
25
- and if the profile enables them mobile-first + design-system usage. Mechanical findings from the
26
- gates: read `specs/reports/audit-gates.txt`. Emit a prioritized refactor backlog (finding-line format
27
- from your instructions), grouped by domain (one group per surface + shared)."
29
+ Dispatch `review` (read-only; static prompt first, variable slot lastprompt-cache prefix):
30
+ "Audit a target against `PIPELINE.md` (no spec **audit mode**). Check conventions (§Conventions
31
+ per surface), TDD coverage (untested entry points / modules per surface), and if the profile
32
+ enables them — mobile-first + design-system usage. Mechanical findings from the gates: read
33
+ `specs/reports/audit-gates.txt`. Emit a prioritized refactor backlog (capped finding-line format
34
+ from your instructions), grouped by domain (one group per surface + shared). — Target: `$ARGUMENTS`
35
+ (default: whole repo)."
28
36
 
29
37
  ## 3. Write the backlog
30
38
 
@@ -0,0 +1,54 @@
1
+ ---
2
+ model: sonnet
3
+ description: Launch the full dev-cycle workflow (contract → build → smoke ∥ review → fix, until zero findings) for a frozen spec; relay its verdict + deferred questions.
4
+ argument-hint: <feature_id> [max_rounds]
5
+ ---
6
+
7
+ You are the **lead**. Launch the full dev-cycle **workflow** for feature **$ARGUMENTS** — the
8
+ deterministic script does the orchestration (SCHEMA.md §Workflows, `cycle.js`); your job is only to
9
+ start it and relay its result. Do NOT run the phases yourself here — that's the conversational path
10
+ (`/build` → `/smoke` → `/review` → `/fix`), which remains the fallback below.
11
+
12
+ > **Kanban** (SCHEMA.md §Kanban): move card `#<feature_id>` → **Building** at launch. No-op silently
13
+ > if no board.
14
+
15
+ ## 1. Resolve & check (fail fast, before spending anything)
16
+
17
+ - Parse `$ARGUMENTS`: the first token is `<feature_id>`, an optional second numeric token is
18
+ `<max_rounds>` (the workflow defaults to 5).
19
+ - Resolve the script: `.claude/workflows/cycle.js` if it exists, else `~/.claude/workflows/cycle.js`
20
+ (`test -f`). **Missing both** ⇒ the core predates 1.3.0 or is half-copied: tell the human to run
21
+ `/update-pipeline`, and stop.
22
+ - **Workflow runtime available?** If the `Workflow` tool is not in your toolset (Claude Code
23
+ < 2.1.154 or workflows disabled), say so and hand over the conversational path instead:
24
+ `/build <feature_id>` → `/smoke` → `/review` → `/fix` — same phases, interactive. Stop.
25
+ - Quick spec sanity (the workflow re-checks properly — this just saves a doomed launch):
26
+ `grep '^status:' specs/<feature_id>.md` must say `frozen` or `in-review`; otherwise tell the human
27
+ to run `/spec` first, and stop.
28
+
29
+ ## 2. Launch
30
+
31
+ Call the `Workflow` tool: `scriptPath: <resolved cycle.js path>`,
32
+ `args: {"feature": "<feature_id>", "maxRounds": <max_rounds, omit if not given>}`.
33
+ It runs in the background — tell the human it's off and what it will do (build, then smoke ∥ review
34
+ → fix rounds until zero findings + PASS; no questions mid-run), and that `/workflows` shows live
35
+ progress. Then END YOUR TURN — never poll, never sleep; the completion notification re-wakes you.
36
+
37
+ ## 3. Relay the result (when the task notification arrives)
38
+
39
+ The workflow returns only a verdict object — the bulk is already on disk
40
+ (`specs/reports/<feature_id>.md`, spec `## Remediation`). Print, without re-reading any of it into
41
+ context:
42
+
43
+ - `outcome` · rounds used · review verdict · smoke result.
44
+ - `contractChanges` if any — flag them explicitly: the loop re-authored the frozen contract
45
+ lead-style; the human should eyeball those hunks in the diff.
46
+ - **The `questions` array, verbatim** — this is the human's inbox from the run (empty when the spec
47
+ pre-answered everything). Each one is a decision to make, usually by sharpening the spec.
48
+ - The `next` line: **SHIP-READY** ⇒ `/ship <feature_id>` (DoD ticked + freshness stamped — ship is a
49
+ straight shot, its human confirmation stays). **STOPPED** ⇒ answer the questions, then rerun
50
+ `/cycle <feature_id>` (it picks up from the spec's Remediation) or finish conversationally with
51
+ `/fix <feature_id>` + `/review <feature_id>`.
52
+ - **Kanban:** outcome SHIP-READY ⇒ move card → **Review** (the cycle's last verdict is a review);
53
+ otherwise → **Fix**. No-op silently if no board.
54
+ - **Recommend a `/clear`** — everything the next command needs is on disk.
@@ -21,8 +21,8 @@ fix only with the human's go-ahead (or hand them the command).
21
21
  commands' step files are present — `templates/steps/init-pipeline/` non-empty (a router whose
22
22
  `templates/steps/<cmd>/` dir is missing is a partial/stale install ⇒
23
23
  re-run install/update). **Shipped scripts present and executable** in `<core>/pipeline/scripts/`:
24
- `kanban-move.sh`, `telemetry-send.sh`, `new-feature.sh.template`, `remove-feature.sh.template`
25
- — ❌ any missing one. Every caller chains these with `|| true`, so an absent script is a **silent**
24
+ `kanban-move.sh`, `telemetry-send.sh`, `preflight.sh`, `new-feature.sh.template`,
25
+ `remove-feature.sh.template` — ❌ any missing one. Every caller chains these with `|| true`, so an absent script is a **silent**
26
26
  no-op (no kanban card moves, no telemetry ping, no error anywhere) — this check is the only thing
27
27
  that sees it. Also flag ❌ a `VERSION` **newer than** the other `pipeline/` files (compare mtimes):
28
28
  a version bumped without a full re-copy is a half-done update ⇒ re-run install/update.
@@ -34,10 +34,10 @@ fix only with the human's go-ahead (or hand them the command).
34
34
  its `surfaces[].model` — ❌ if missing, mismatched, or a literal `<SURFACE_MODEL>` placeholder
35
35
  (all three silently fall back to inheriting the lead session's model — often Opus — on every
36
36
  dispatch); ⚠️ any `inherit` with the note that it bills at the lead's tier. The generic agents
37
- (`review.md`, `release.md`, `smoke.md` — repo or `~/.claude/agents/`) must each carry their
38
- `model:` line too (sonnet/haiku/sonnet). **Command pins:** every mechanical command file
37
+ (`review.md`, `release.md`, `smoke.md`, `profile-reader.md` — repo or `~/.claude/agents/`) must
38
+ each carry their `model:` line too (sonnet/haiku/sonnet/haiku). **Command pins:** every mechanical command file
39
39
  (`build`, `review`, `fix`, `smoke`, `ship`, `audit`, `refactor`, `doctor`, `align-ds`,
40
- `update-pipeline` — in `.claude/commands/` or `~/.claude/commands/`) carries `model: sonnet` in
40
+ `update-pipeline`, `cycle` — in `.claude/commands/` or `~/.claude/commands/`) carries `model: sonnet` in
41
41
  its frontmatter — ⚠️ if missing (the lead's orchestration turn then bills at the session model,
42
42
  e.g. Opus/Fable). `brainstorm`, `spec`, and `init-pipeline` are intentionally unpinned
43
43
  (interactive — they inherit the session model).
@@ -66,7 +66,23 @@ fix only with the human's go-ahead (or hand them the command).
66
66
  incoherent state: `enabled: true` with no `install_id` or no `consent_date` (sending without
67
67
  recorded consent — fix: set `enabled: false` until the consent question is re-run), or a
68
68
  `telemetry:` block missing entirely on a current core (top up via `/update-pipeline`).
69
- 8. **Specs & metrics.** Every `specs/*.md` front-matter `status` is a valid stage; `shipped` specs
69
+ 8. **Workflows** (the opt-in execution path SCHEMA.md §Workflows; the conversational commands
70
+ stay the default, so failures here are ⚠️ at most, never ❌). Report which path this machine will
71
+ take and why:
72
+ - **Claude Code version** ≥ 2.1.154 (`claude --version 2>/dev/null | head -1`) — older or no CLI
73
+ on PATH ⇒ conversational only.
74
+ - **Scripts present:** `<core>/workflows/review.js` + `audit.js` + `refactor.js` + `cycle.js` —
75
+ missing on a current core ⇒ half-done install, re-run install/update.
76
+ - **Phase-0 agent present:** `<agents dir>/profile-reader.md` (repo `.claude/agents/` bundled or
77
+ `~/.claude/agents/` global) — the workflows abort without it.
78
+ - **Workflows enabled in this session** — the `Workflow` tool is in your own toolset right now;
79
+ absent ⇒ disabled for this session (a setting or an old client), conversational path.
80
+ - **Preflight wiring** (used by both paths): `pipeline/scripts/preflight.sh` executable and
81
+ `gate-config.json` carries the `preflight` block — mismatch ⇒ regenerate from the profile.
82
+ End the check with ONE summary line, e.g.
83
+ `workflows: available (opt-in — ask to "run the review workflow")` or
84
+ `workflows: unavailable (<first failing prerequisite>) — conversational commands (the default)`.
85
+ 9. **Specs & metrics.** Every `specs/*.md` front-matter `status` is a valid stage; `shipped` specs
70
86
  with a live worktree flagged (see 6). `.claude/pipeline-metrics.jsonl` and `specs/reports/` (the
71
87
  `/review`·`/smoke` report buffer that lets a `/fix` survive a `/clear`) are gitignored. Metrics
72
88
  belong to the **main checkout** — a `pipeline-metrics.jsonl` inside a live feature worktree is a
@@ -7,6 +7,11 @@ argument-hint: <domain…> (one or more surface keys, "shared", or "all")
7
7
  You are the **lead**. Refactor domain **$ARGUMENTS** to match `PIPELINE.md`, using the `/audit` backlog.
8
8
 
9
9
  > Read `PIPELINE.md` §`surfaces` (map the domain → a surface + its agent + commands) and §`contract`.
10
+ >
11
+ > **Workflow variant** (opt-in — SCHEMA.md §Workflows): for BIG domains (many open backlog items
12
+ > across several surfaces), on Claude Code ≥ 2.1.154 with workflows enabled, the human can ask to
13
+ > "run the refactor workflow" (`<core>/workflows/refactor.js`). For a handful of items this
14
+ > conversational path is cheaper — and it stays the default and the fallback.
10
15
 
11
16
  ## 1. Gather
12
17
 
@@ -42,9 +47,9 @@ slices import it, so refactor it alone, first.
42
47
 
43
48
  ## 3. Verify & loop
44
49
 
45
- After each agent returns: its surface's `test_cmd`/`lint_cmd`, `commands.typecheck`,
46
- `commands.format --check` (redirect output to a file and grep it — don't print gate output into your
47
- context). Then verify each backlog item cleared by checking its `file:line` directly — do NOT re-run
50
+ After each agent returns: its surface's `test_quiet_cmd`/`lint_quiet_cmd` (else the `tail -40`
51
+ fallback — SCHEMA.md §Output discipline), `commands.typecheck`, `commands.format --check` (redirect
52
+ output to a file and grep it — don't print gate output into your context). Then verify each backlog item cleared by checking its `file:line` directly — do NOT re-run
48
53
  `/audit` per round (that repeats the repo-wide gates + a review dispatch you don't need); one optional
49
54
  final `/audit` once ALL dispatched domains are clean is enough. Check cleared items off in
50
55
  `specs/refactor-backlog.md`. Loop until each dispatched domain is clean. Verification is per-domain
@@ -6,22 +6,46 @@ argument-hint: <feature_id>
6
6
 
7
7
  You are the **lead**. Dispatch the review for feature **$ARGUMENTS**.
8
8
 
9
- > Read `PIPELINE.md` §`vcs.default_branch` (diff base) and the `surfaces`/`contract` fields.
9
+ > Read `PIPELINE.md` §`vcs.default_branch` (diff base) and the `surfaces`/`contract`/`commands` fields.
10
10
  > _Skip the re-read if it's already in your context this session and unmodified since._
11
11
  >
12
12
  > **Kanban** (SCHEMA.md §Kanban): move card `#$ARGUMENTS` → **Review**. No-op silently if no board.
13
+ >
14
+ > **Workflow variant** (opt-in — SCHEMA.md §Workflows): on Claude Code ≥ 2.1.154 with workflows
15
+ > enabled, the human can ask to "run the review workflow" (`<core>/workflows/review.js`) instead.
16
+ > This conversational path stays the default and the fallback; `/doctor` shows which is available.
17
+
18
+ ## 0. Deterministic pre-flight — no agents while red
19
+
20
+ Run the profile's mechanical gates in ONE Bash call via the shipped script
21
+ (`<core>/pipeline/scripts/preflight.sh`, `<core>` = `.claude` bundled / `~/.claude` global — probe
22
+ with `test -x`); note the epoch (`date +%s`) in the same call — §3's metrics line needs it:
23
+
24
+ ```
25
+ <core>/pipeline/scripts/preflight.sh specs/reports/$ARGUMENTS.preflight.txt \
26
+ "<commands.typecheck>" "<commands.lint_quiet, else lint>" "<commands.test_quiet, else test>"
27
+ ```
28
+
29
+ - **Non-zero exit** ⇒ the script already printed the raw last-40 lines. **STOP: relay them verbatim
30
+ and spawn NO agent** — a compiler/test failure needs `/fix` (or the human), not a review that
31
+ rediscovers it at agent prices. This abort is the whole point of the step.
32
+ - **Zero exit** ⇒ it stamped `.claude/preflight.ok`, which the gate hook checks before letting
33
+ `review`/`smoke` dispatches through (SCHEMA.md §Preflight). Continue.
34
+ - Script absent (older core) ⇒ run the three commands yourself, each redirected into
35
+ `specs/reports/$ARGUMENTS.preflight.txt`, aborting on the first failure the same way.
13
36
 
14
37
  ## 1. Gather the inputs for stateless reviewers
15
38
 
16
39
  - Confirm `specs/$ARGUMENTS.md` exists.
17
- - Compute the diff, and let **git do the grouping** (deterministic don't reason it out file by file):
18
- per surface, `git diff <default_branch> --name-only -- <surface.path>` is exactly that surface's changed
19
- files; the **`shared` remainder** (contract file + anything outside every surface) is
20
- `git diff <default_branch> --name-only -- . $(for p in <each surface.path>; do printf ':(exclude)%s ' "$p"; done)`.
21
- Attach the remainder to the most relevant surface's reviewer and say so in its dispatch. A surface whose
22
- `git diff` comes back empty gets no reviewer.
23
- - **Stage the hunks** (reviewers are read-only — no Bash — so a staged diff file is the ONLY way they
24
- can review hunks instead of re-reading whole files). Per touched surface, regenerated every round:
40
+ - **Compute the diff ONCE `--stat` first, patches only for retained surfaces.** One call:
41
+ `git diff <default_branch> --stat > specs/reports/$ARGUMENTS.stat.txt`, then grep that file to
42
+ group the changed paths by `surfaces[].path` prefix (deterministic don't reason it out file by
43
+ file). Paths under no surface (contract file, root config) are the **`shared` remainder**: attach
44
+ them to the most relevant surface's reviewer and say so in its dispatch. A surface with no changed
45
+ paths gets no reviewer — and no `.diff` is ever generated for it.
46
+ - **Stage the hunks once per touched surface** (reviewers are read-only — no Bash — so the staged
47
+ diff file is the ONLY way they can review hunks instead of re-reading whole files, and staging it
48
+ here means N reviewers never re-run git N times). Regenerated every round:
25
49
  `git diff <default_branch> -- <surface.path> > specs/reports/$ARGUMENTS.<surface.key>.diff`
26
50
  (same gitignored buffer dir as the reports). For the surface that carries the shared remainder,
27
51
  append the remainder pathspecs to its command so its `.diff` includes them. Never print a diff into
@@ -40,16 +64,20 @@ prescribed fixes land? — NOT a de-novo audit) and write the same REVIEW REPORT
40
64
  First-round reviews, contract changes, and security findings always get a full reviewer. For each
41
65
  dispatched surface:
42
66
 
43
- > `subagent_type: review` "Review feature `$ARGUMENTS` **scope: the `<surface.key>` surface
44
- > only**. Read `PIPELINE.md` first (its flags + §Conventions/§Testing for `<surface.key>`). Spec:
45
- > `specs/$ARGUMENTS.md` (source of truth). Contract: `<contract.path>/$ARGUMENTS.<ext>`. Diff to
46
- > review: `specs/reports/$ARGUMENTS.<surface.key>.diff` (staged hunks read it FIRST; open a full
47
- > source file only when a finding demands it). Check spec conformance first, then correctness,
48
- > security, conventions, RBAC/mobile-first _if the profile enables them_, and TDD coverage. Emit
49
- > the REVIEW REPORT in the format your agent instructions define every finding self-sufficient
50
- > (`file:line` · severity · type · concrete fix). Changed files (`--stat`): <list>."
67
+ Keep the dispatch prompt **byte-identical across features and rounds** except the variable block,
68
+ which sits at the END so every repeat hits the prompt-cache prefix:
69
+
70
+ > `subagent_type: review` "Review one feature surface against its frozen spec. Read `PIPELINE.md`
71
+ > first (flags + the §Conventions/§Testing slice for your scope). Check spec conformance first, then
72
+ > correctness, security, conventions, RBAC/mobile-first _if the profile enables them_, and TDD
73
+ > coverage. Your dispatch names a staged diff file read it FIRST; open a full source file only when
74
+ > a finding demands it. Emit the REVIEW REPORT in the capped format your agent instructions define —
75
+ > every finding self-sufficient (`file:line` · severity · type · one-line concrete fix), no code
76
+ > excerpts. — Variable slots: feature `$ARGUMENTS` · scope: the `<surface.key>` surface only · spec:
77
+ > `specs/$ARGUMENTS.md` (source of truth) · contract: `<contract.path>/$ARGUMENTS.<ext>` · staged
78
+ > diff: `specs/reports/$ARGUMENTS.<surface.key>.diff` · changed files (`--stat`): <list>."
51
79
 
52
- The staging command in §1 already gave you the wall-clock start (`date +%s` in the same call) — §3's
80
+ §0's preflight call already gave you the wall-clock start (`date +%s` in the same call) — §3's
53
81
  metrics line needs it.
54
82
 
55
83
  ## 3. Merge & relay the verdict