cohorte 1.6.0 → 2.0.0

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +84 -2
  2. package/README.md +57 -57
  3. package/bin/cli.js +23 -15
  4. package/core/agents/implementer.template.md +3 -3
  5. package/core/agents/release.md +1 -1
  6. package/core/agents/review.md +3 -3
  7. package/core/commands/{audit.md → cohorte-audit.md} +3 -3
  8. package/core/commands/{brainstorm.md → cohorte-brainstorm.md} +4 -4
  9. package/core/commands/{build.md → cohorte-build.md} +15 -15
  10. package/core/commands/{doctor.md → cohorte-doctor.md} +17 -9
  11. package/core/commands/{fix.md → cohorte-fix.md} +15 -13
  12. package/core/commands/{init-pipeline.md → cohorte-init-pipeline.md} +1 -1
  13. package/core/commands/cohorte-loop.md +110 -0
  14. package/core/commands/{refactor.md → cohorte-refactor.md} +3 -3
  15. package/core/commands/{review.md → cohorte-review.md} +20 -19
  16. package/core/commands/{ship.md → cohorte-ship.md} +5 -5
  17. package/core/commands/{spec.md → cohorte-spec.md} +13 -13
  18. package/core/commands/{update-pipeline.md → cohorte-update-pipeline.md} +11 -6
  19. package/core/hooks/gate.py +101 -6
  20. package/core/templates/brainstorm-return.md +4 -4
  21. package/core/templates/decisions.template.md +1 -1
  22. package/core/templates/design-brief.md +1 -1
  23. package/core/templates/spec.template.md +7 -7
  24. package/core/templates/steps/init-pipeline/01-detect-stack.md +1 -1
  25. package/core/templates/steps/init-pipeline/02-interview-gaps.md +6 -6
  26. package/core/templates/steps/init-pipeline/03-draft-profile.md +1 -1
  27. package/core/templates/steps/init-pipeline/04-write-render.md +16 -12
  28. package/core/templates/steps/init-pipeline/05-report.md +5 -5
  29. package/core/workflows/audit.js +6 -6
  30. package/core/workflows/refactor.js +14 -14
  31. package/core/workflows/review.js +22 -22
  32. package/dashboard/README.md +2 -2
  33. package/dashboard/dist/assets/{index-DYyn4p93.js → index-P1I1JGtj.js} +2 -2
  34. package/dashboard/dist/index.html +1 -1
  35. package/dashboard/server/doctor.js +69 -19
  36. package/dashboard/server/index.js +5 -5
  37. package/dashboard/server/metrics.js +1 -1
  38. package/install.ps1 +23 -14
  39. package/install.sh +24 -14
  40. package/package.json +2 -2
  41. package/profile/PIPELINE.template.md +17 -16
  42. package/profile/SCHEMA.md +89 -77
  43. package/profile/cohorte.config.template.yaml +8 -8
  44. package/scripts/loop-detach.sh +153 -0
  45. package/scripts/loop.sh +75 -27
  46. package/scripts/metrics/collect.mjs +17 -8
  47. package/scripts/new-feature.sh.template +3 -3
  48. package/scripts/preflight.sh +40 -4
  49. package/scripts/remove-feature.sh.template +2 -2
  50. package/scripts/test-dashboard.mjs +34 -7
  51. package/scripts/test-gate.mjs +58 -0
  52. package/scripts/test-loop.mjs +49 -7
  53. package/scripts/test-metrics.mjs +23 -11
  54. package/scripts/test-workflows.mjs +7 -7
  55. package/scripts/validate-core.mjs +45 -23
  56. package/core/commands/drive.md +0 -80
  57. /package/core/commands/{align-ds.md → cohorte-align-ds.md} +0 -0
package/profile/SCHEMA.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PIPELINE.md profile — field reference
2
2
 
3
- `/init-pipeline` fills the `yaml pipeline-profile` block in `PIPELINE.md` (from
3
+ `/cohorte-init-pipeline` fills the `yaml pipeline-profile` block in `PIPELINE.md` (from
4
4
  `PIPELINE.template.md`) plus the prose sections. This documents every field and how the
5
5
  generic pipeline uses it, so a stateless agent can read/regenerate the profile correctly.
6
6
 
@@ -29,12 +29,12 @@ generic pipeline uses it, so a stateless agent can read/regenerate the profile c
29
29
  | `surfaces[].*_cmd` | string | implementer | test/lint/format/typecheck/build commands. |
30
30
  | `surfaces[].test_quiet_cmd` `.lint_quiet_cmd` | string | implementer, preflight, workflows | Bridled variants agents actually run (dot reporter / `--quiet` / failures-only). `""` ⇒ `<cmd> 2>&1 \| tail -40`. See §Output discipline. |
31
31
  | `surfaces[].uses_design` | bool | build, frontend | Whether this surface consumes designs. |
32
- | `contract.enabled` | bool | build | `false` ⇒ skip contract authoring (§2 of /build). |
32
+ | `contract.enabled` | bool | build | `false` ⇒ skip contract authoring (§2 of /cohorte-build). |
33
33
  | `contract.mechanism` | enum | build, lead | `shared-types-zod`/`openapi`/`protobuf`/`json-schema`/`none`. |
34
34
  | `contract.path` `.ext` `.index` | string | build | Where `<feature_id>` contract is authored + barrel. |
35
35
  | `contract.authored_by` | const `lead` | build | Implementers import it read-only, never edit. |
36
36
  | `commands.*` | string | all | Repo-wide install/dev/lint/format/typecheck/test + migrate. |
37
- | `commands.test_quiet` `.lint_quiet` | string | review, audit, workflows | Repo-wide bridled variants — what the `/review` pre-flight runs. Same fallback as the per-surface ones. |
37
+ | `commands.test_quiet` `.lint_quiet` | string | review, audit, workflows | Repo-wide bridled variants — what the `/cohorte-review` pre-flight runs. Same fallback as the per-surface ones. |
38
38
  | `rbac.enabled` | bool | brainstorm, review | Toggle RBAC personas + authz audit. |
39
39
  | `rbac.hierarchy` | list | review | Highest→lowest role list. |
40
40
  | `design.enabled` | bool | build, frontend, align-ds | `false` ⇒ design steps are no-ops. |
@@ -60,14 +60,14 @@ generic pipeline uses it, so a stateless agent can read/regenerate the profile c
60
60
 
61
61
  - **Conventions** — per-surface rules the implementer follows and review audits.
62
62
  - **Testing** — the TDD contract per surface (what a test must cover, DB isolation).
63
- - **Design brief note** — feeds `/spec` §8 and the Claude Design step.
64
- - **Personas** — the `/brainstorm` panel; include one per RBAC role when `rbac.enabled`.
63
+ - **Design brief note** — feeds `/cohorte-spec` §8 and the Claude Design step.
64
+ - **Personas** — the `/cohorte-brainstorm` panel; include one per RBAC role when `rbac.enabled`.
65
65
 
66
66
  ## How the pieces reference this file
67
67
 
68
68
  - **Agents** (`implementer`, `review`, `release`) are told at dispatch: _read `PIPELINE.md`
69
69
  §Commands / §Conventions / §Surfaces first._ They have `Read`, so they load it live.
70
- - **Commands** (`/build`, `/review`, …) parse the `yaml pipeline-profile` block to know how
70
+ - **Commands** (`/cohorte-build`, `/cohorte-review`, …) parse the `yaml pipeline-profile` block to know how
71
71
  many surfaces to dispatch, the contract mechanism, the commands, and the capability flags.
72
72
  - **Hook** (`gate.py`) reads `gate.deny`/`gate.ask`/`gate.ask_on_default_branch`/`gate.default_branch`
73
73
  from a generated `.claude/gate-config.json`. The last two make git + docker free on feature branches
@@ -87,7 +87,7 @@ follow is provider-agnostic: _"prefer the retrieval MCP tools over Grep/Glob + w
87
87
  | `graphify` | persistent tree-sitter knowledge graph over code + docs | as fresh as the last rescan | index step + re-index discipline |
88
88
  | `none` | agents fall back to Grep/Glob/Read | — | — |
89
89
 
90
- **Wiring (done by `/init-pipeline`, or `/update-pipeline` retroactively):**
90
+ **Wiring (done by `/cohorte-init-pipeline`, or `/cohorte-update-pipeline` retroactively):**
91
91
 
92
92
  - `serena` — requires the `serena` CLI (`uv tool install -p 3.13 serena-agent`). For day-to-day CLI
93
93
  use it should also be on PATH (`uv tool update-shell`; uv installs to `~/.local/bin`). Register at
@@ -113,7 +113,7 @@ follow is provider-agnostic: _"prefer the retrieval MCP tools over Grep/Glob + w
113
113
  - Rendered agents get the provider's MCP tools appended to their `tools:` list (e.g. `mcp__serena`
114
114
  grants the whole server); `none` ⇒ nothing appended.
115
115
 
116
- **Serena health check** — run after wiring in `/init-pipeline` AND on every `/update-pipeline`
116
+ **Serena health check** — run after wiring in `/cohorte-init-pipeline` AND on every `/cohorte-update-pipeline`
117
117
  reconcile (wiring that worked once can rot: PATH changes, tool uninstalled, entry hand-edited):
118
118
 
119
119
  1. **CLI resolves:** `command -v serena`. Fails but `~/.local/bin/serena` exists ⇒ PATH repair
@@ -135,7 +135,7 @@ Grep/Read; the health check above is the diagnostic.
135
135
 
136
136
  ## Specialization — when to split one surface into more agents
137
137
 
138
- `/build` dispatches ONE agent per surface, in parallel, so build wall-clock ≈ the **slowest single
138
+ `/cohorte-build` dispatches ONE agent per surface, in parallel, so build wall-clock ≈ the **slowest single
139
139
  surface**. More agents only build faster when they let the *slowest* surface's work run concurrently —
140
140
  and only if the split is safe. The invariant that keeps parallelism safe is **one owner per tree, and
141
141
  the frozen contract as the only cross-surface channel**. So specialization means carving a surface into
@@ -161,8 +161,8 @@ the frozen contract as the only cross-surface channel**. So specialization means
161
161
  Coarse first, specialize on evidence: start with one `frontend` / `backend` surface each; split only a
162
162
  surface that's proven slow and cleanly separable. The evidence lives in
163
163
  the **main checkout's** `.claude/pipeline-metrics.jsonl` (gitignored) — one JSONL line per phase batch
164
- (`ts`/`feature`/`phase`/`seconds`/`surfaces:{key: result}`), appended by `/build`, `/review`
165
- and `/fix`.
164
+ (`ts`/`feature`/`phase`/`seconds`/`surfaces:{key: result}`), appended by `/cohorte-build`, `/cohorte-review`
165
+ and `/cohorte-fix`.
166
166
  **`surfaces` keys are surface keys, nothing else** — run-level facts go in their own top-level
167
167
  fields. Anything put inside `surfaces` is read
168
168
  as a surface: the dashboard renders it as a row in the per-surface table and scores a non-`ok`
@@ -178,8 +178,8 @@ what's SLOW. It deliberately does NOT record tokens: the lead can't reliably rea
178
178
  to log it. For what's EXPENSIVE, use Claude Code's own accounting:
179
179
 
180
180
  - **`/cost`** (built-in, zero setup) — reports per-**subagent** and per-**slash-command** share of your usage
181
- over the last 24 h / 7 d (e.g. _"Top subagents: frontend 7 %, backend 4 % · Top skills: /build 1 %,
182
- /review 1 %"_). That IS the per-phase ledger — approximate (share-of-total, machine-local, not exact
181
+ over the last 24 h / 7 d (e.g. _"Top subagents: frontend 7 %, backend 4 % · Top skills: /cohorte-build 1 %,
182
+ /cohorte-review 1 %"_). That IS the per-phase ledger — approximate (share-of-total, machine-local, not exact
183
183
  tokens). Read it to see which surface/command actually dominates the bill before you tune a `model` tier.
184
184
  - **OpenTelemetry** (exact numbers + dashboards) — add an `env` block to `~/.claude/settings.json`:
185
185
  `{"env":{"CLAUDE_CODE_ENABLE_TELEMETRY":"1","OTEL_METRICS_EXPORTER":"otlp","OTEL_EXPORTER_OTLP_PROTOCOL":"http/protobuf","OTEL_EXPORTER_OTLP_ENDPOINT":"http://localhost:4318"}}`
@@ -207,35 +207,35 @@ context. The profile therefore stores **two forms of each noisy command**:
207
207
  (`--reporter=dot`, `--quiet`, `-q`, `--silent`, framework equivalent) so a green run costs lines,
208
208
  not pages, and a red run prints only the failures.
209
209
 
210
- Rules for every consumer (implementers, preflight, `/audit` gates, workflow agents):
210
+ Rules for every consumer (implementers, preflight, `/cohorte-audit` gates, workflow agents):
211
211
 
212
212
  1. Run the quiet variant when set.
213
213
  2. Quiet variant empty/absent (older profile) ⇒ run `<full cmd> 2>&1 | tail -40` — never the bare
214
214
  command into your context.
215
215
  3. Need the full log? Redirect it to a file and grep it; never print it.
216
216
 
217
- `/init-pipeline` **asks** for these variants (detected defaults offered first) instead of silently
218
- storing a bare `pnpm test` as the thing agents execute; `/update-pipeline` tops up older profiles.
217
+ `/cohorte-init-pipeline` **asks** for these variants (detected defaults offered first) instead of silently
218
+ storing a bare `pnpm test` as the thing agents execute; `/cohorte-update-pipeline` tops up older profiles.
219
219
 
220
220
  ## Spec status — the lifecycle state machine (and the loop's resume state)
221
221
 
222
222
  A spec's front-matter `status` is not a label, it is the pipeline's **state**: every command routes on
223
- it, the dashboard boards on it, the kanban backfill maps it to a column, and `/drive --resume` reads it
223
+ it, the dashboard boards on it, the kanban backfill maps it to a column, and `/cohorte-loop --resume` reads it
224
224
  back to continue an interrupted autonomous run. Six states, and exactly one writer each:
225
225
 
226
226
  | status | meaning | written by | who may build it |
227
227
  | --- | --- | --- | --- |
228
- | `draft` | the interview is open, nothing is frozen | `/spec` Mode A | no |
229
- | `frozen` | the contract is frozen — the handoff to `/build` | `/spec` Mode A freeze | yes |
230
- | `in-progress` | a `/drive` is driving this spec right now (or died doing it) | `scripts/loop.sh`, before each phase | yes |
231
- | `in-review` | reviewed / awaiting the next round or `/ship` | `/spec` Mode B, `/fix`, `loop.sh` on a clean exit | yes |
228
+ | `draft` | the interview is open, nothing is frozen | `/cohorte-spec` Mode A | no |
229
+ | `frozen` | the contract is frozen — the handoff to `/cohorte-build` | `/cohorte-spec` Mode A freeze | yes |
230
+ | `in-progress` | a `/cohorte-loop` is driving this spec right now (or died doing it) | `scripts/loop.sh`, before each phase | yes |
231
+ | `in-review` | reviewed / awaiting the next round or `/cohorte-ship` | `/cohorte-spec` Mode B, `/cohorte-fix`, `loop.sh` on a clean exit | yes |
232
232
  | `blocked` | a loop gave up here (ceiling, non-convergent, no verdict, not implementable) | `loop.sh` on any non-zero exit | yes, with the reason named |
233
- | `shipped` | the PR is open; the status flip is part of the release commit | `/ship` | no |
233
+ | `shipped` | the PR is open; the status flip is part of the release commit | `/cohorte-ship` | no |
234
234
 
235
235
  **The resume contract.** Before every phase, `loop.sh` stamps `status: in-progress` plus `loop_pass`
236
236
  (the review pass it is on) and `loop_phase` (`build`/`review`/`fix`) into the spec — deterministically,
237
237
  with `awk`, spending **no tokens** on state it will need later. On exit it stamps a terminal status:
238
- `in-review` + `loop_phase: done` when clean, `blocked` otherwise. `/drive <id> --resume` then continues
238
+ `in-review` + `loop_phase: done` when clean, `blocked` otherwise. `/cohorte-loop <id> --resume` then continues
239
239
  at the recorded pass instead of pass 1, so a session killed at pass 3 of 5 does not re-pay passes 1–2.
240
240
  The build is still skipped or redone by the build stamp alone (`specs/reports/<id>.built`, written only
241
241
  after a build that finished), so an interrupted *build* correctly rebuilds.
@@ -244,10 +244,10 @@ Corollaries worth knowing:
244
244
 
245
245
  - A spec with no front-matter makes every stamp a **silent no-op** — the state is bookkeeping, and the
246
246
  loop must never die over a status line.
247
- - Child commands write `status` too (`/fix` sets `in-review`); re-stamping before each phase is what
247
+ - Child commands write `status` too (`/cohorte-fix` sets `in-review`); re-stamping before each phase is what
248
248
  keeps `in-progress` true for the duration of the run rather than for its first phase.
249
- - `blocked` is not a failure to hide: it is the resumable state. `/build` accepts it, names it, and
250
- routes by the spec's `## Remediation` (open items ⇒ `/fix`).
249
+ - `blocked` is not a failure to hide: it is the resumable state. `/cohorte-build` accepts it, names it, and
250
+ routes by the spec's `## Remediation` (open items ⇒ `/cohorte-fix`).
251
251
 
252
252
  ## Dead agents — silence is not a green light
253
253
 
@@ -258,9 +258,9 @@ integrates anything, because the default reading of silence is the most dangerou
258
258
 
259
259
  | phase | what a dead agent looks like | what the phase must do |
260
260
  | --- | --- | --- |
261
- | `/build` | a surface with no handoff | retry it **once** alone (byte-identical prompt), then mark it `dead`, verify the tree with that surface's own quiet commands, never call the batch ok |
262
- | `/review` | a reviewer with no report ⇒ **zero findings** | retry once, then list the surface in `unreviewed` and refuse to score `SHIP` |
263
- | `/fix` | a re-dispatched agent with no handoff | retry once, then leave **every** one of its items `- [ ]` — a dead agent never ticks a box |
261
+ | `/cohorte-build` | a surface with no handoff | retry it **once** alone (byte-identical prompt), then mark it `dead`, verify the tree with that surface's own quiet commands, never call the batch ok |
262
+ | `/cohorte-review` | a reviewer with no report ⇒ **zero findings** | retry once, then list the surface in `unreviewed` and refuse to score `SHIP` |
263
+ | `/cohorte-fix` | a re-dispatched agent with no handoff | retry once, then leave **every** one of its items `- [ ]` — a dead agent never ticks a box |
264
264
  | workflows | `agent()` resolves to `null` | already enforced (`review.js` `unreviewedSurfaces`) — the doctrine started here |
265
265
 
266
266
  Non-negotiables, in every phase:
@@ -269,8 +269,8 @@ Non-negotiables, in every phase:
269
269
  already on disk — so recovery costs one agent, never a rebuild. Never retry an agent that answered.
270
270
  - **Never speak for a dead agent.** You did not see its work: report what the *tree* says (quiet
271
271
  commands, redirected to a file, grepped), not what a handoff would have said.
272
- - **Never let it reach a driver as clean.** `/build` writes `dead[]` into
273
- `specs/reports/<id>.build.json`, `/review` writes `unreviewed[]` into the verdict; `scripts/loop.sh`
272
+ - **Never let it reach a driver as clean.** `/cohorte-build` writes `dead[]` into
273
+ `specs/reports/<id>.build.json`, `/cohorte-review` writes `unreviewed[]` into the verdict; `scripts/loop.sh`
274
274
  aborts on either with **exit 2** *before* it reads `blocking`, since a dead reviewer makes
275
275
  `blocking == 0` a statement about code nobody read.
276
276
  - **`unreviewed` is separate from `blocking` on purpose.** Faking a count in `blocking` to force a
@@ -281,7 +281,7 @@ Non-negotiables, in every phase:
281
281
 
282
282
  ## Readiness — the gate between a frozen spec and N implementers
283
283
 
284
- `/build` §1.6 scores the frozen spec on **implementability** before authoring the contract and before
284
+ `/cohorte-build` §1.6 scores the frozen spec on **implementability** before authoring the contract and before
285
285
  dispatching anything, and writes `specs/reports/<id>.readiness.json`
286
286
  (`verdict`: `READY` · `RESERVATIONS` · `NOT-READY`, plus `gaps[]`). It costs **zero extra agents** — the
287
287
  lead already holds the spec, the profile and the reconciled surface list — which is the whole economics
@@ -290,7 +290,7 @@ of the step: a spec that cannot be built does not get cheaper by being built on
290
290
  - Five checks: contract completeness · surface coverage · dependencies exist · residual ambiguity ·
291
291
  the design gate. Each maps to `NOT-READY` (a surface would have to invent the answer) or
292
292
  `RESERVATIONS` (a surface can proceed on a stated assumption).
293
- - **`NOT-READY` aborts the build with no agent spawned** and sends the human to `/spec`.
293
+ - **`NOT-READY` aborts the build with no agent spawned** and sends the human to `/cohorte-spec`.
294
294
  `scripts/loop.sh` reads the same file and exits **4** (`not implementable`) — the one loop outcome
295
295
  that more passes cannot fix.
296
296
  - **`RESERVATIONS` never blocks.** Each gap is inlined verbatim into the dispatch of the surface it
@@ -299,7 +299,7 @@ of the step: a spec that cannot be built does not get cheaper by being built on
299
299
 
300
300
  ## Deferred findings — real, but not this feature's problem
301
301
 
302
- `/review` ends on "zero blocking findings", so everything non-blocking used to be discarded with the
302
+ `/cohorte-review` ends on "zero blocking findings", so everything non-blocking used to be discarded with the
303
303
  report. A **deferred** finding is one the reviewer judges true and **out of this feature's scope**
304
304
  (pre-existing code the staged diff never touched, adjacent debt the spec never claims to fix). The
305
305
  review agent returns them in their own `## Deferred` section — never in `findings` — each carrying its
@@ -310,51 +310,55 @@ own out-of-scope reason.
310
310
  something that cannot change the outcome.
311
311
  - **Not deferrable, ever:** anything the diff touched or introduced, any spec violation, any security
312
312
  issue on a path this feature adds, calls or modifies.
313
- - `/review` §3.5 routes them, **on every verdict**, into `specs/refactor-backlog.md` under the
313
+ - `/cohorte-review` §3.5 routes them, **on every verdict**, into `specs/refactor-backlog.md` under the
314
314
  `## <domain>` heading of the owning surface, tagged `deferred:<feature_id>` — the same grouping
315
- `/audit` writes, so `/refactor <domain>` picks them up with no extra plumbing. Never into the spec's
316
- `## Remediation`, which is what `/fix` re-dispatches.
317
- - `/audit` **carries open `deferred:` items over** when it rewrites the backlog; overwriting them away
315
+ `/cohorte-audit` writes, so `/cohorte-refactor <domain>` picks them up with no extra plumbing. Never into the spec's
316
+ `## Remediation`, which is what `/cohorte-fix` re-dispatches.
317
+ - `/cohorte-audit` **carries open `deferred:` items over** when it rewrites the backlog; overwriting them away
318
318
  is the one way they silently vanish.
319
- - The verdict JSON carries `deferred: <n>` (informational, outside `blocking`), so `/drive` can name
319
+ - The verdict JSON carries `deferred: <n>` (informational, outside `blocking`), so `/cohorte-loop` can name
320
320
  them in its closing line without reading a report.
321
321
 
322
322
  ## Decisions — the transverse decision journal
323
323
 
324
324
  `PIPELINE.md` is a **stack profile** (surfaces, commands, conventions); it says nothing about what this
325
- project has *decided*. Without somewhere for those, every `/spec` re-discovers or contradicts them.
325
+ project has *decided*. Without somewhere for those, every `/cohorte-spec` re-discovers or contradicts them.
326
326
  `specs/_decisions.md` (from `core/templates/decisions.template.md`) is that place, deliberately small:
327
327
 
328
328
  - **Append-only, one line per decision, ≤ ~160 chars:**
329
329
  `- <YYYY-MM-DD> · <area> · <decision> — because <reason> · <feature_id>`. Reversal never edits a line:
330
330
  append a superseding one (`· supersedes <date> <area>`) and move the old one to `## Superseded`. When
331
331
  `## Live` passes ~100 lines, sweep the superseded ones down.
332
- - **Written by** `/spec` at freeze (the decisions that outlive the feature — typically 0–3 lines, and
333
- zero is a normal outcome) and `/build` §1.5 when it adds or splits a surface.
334
- - **Read by the deciding stages only** — `/brainstorm` (so the panel argues about the idea, not about
335
- settled ground), `/spec` (so a new spec does not silently un-decide something), `/audit` (standing
332
+ - **Written by** `/cohorte-spec` at freeze (the decisions that outlive the feature — typically 0–3 lines, and
333
+ zero is a normal outcome) and `/cohorte-build` §1.5 when it adds or splits a surface.
334
+ - **Read by the deciding stages only** — `/cohorte-brainstorm` (so the panel argues about the idea, not about
335
+ settled ground), `/cohorte-spec` (so a new spec does not silently un-decide something), `/cohorte-audit` (standing
336
336
  decisions are part of the rulebook it audits against).
337
337
  - **Never read by implementers or reviewers.** They work from the frozen contract, which already tells
338
338
  them what to do; shipping them the rationale would cost `surfaces × dispatches` tokens per feature
339
339
  for a fact they cannot act on. This is what keeps the journal cheap enough to be worth having.
340
- - The `_` prefix is load-bearing: `/doctor`, the dashboard spec scanner and the kanban backfill all skip
340
+ - The `_` prefix is load-bearing: `/cohorte-doctor`, the dashboard spec scanner and the kanban backfill all skip
341
341
  `specs/_*.md`, so the journal is never mistaken for a spec (no phantom card, no bogus stage).
342
342
 
343
343
  ## Preflight — the deterministic phase gate
344
344
 
345
- `/review` starts by running `pipeline/scripts/preflight.sh` — a plain shell script (no
345
+ `/cohorte-review` starts by running `pipeline/scripts/preflight.sh` — a plain shell script (no
346
346
  agent) that executes the profile's mechanical checks in order (typecheck → lint → tests, quiet
347
347
  variants) with all output redirected to `specs/reports/<id>.preflight.txt`:
348
348
 
349
349
  - **Any check red** ⇒ the script prints the last 40 lines raw and exits 1. The command **aborts
350
350
  there: zero agents are spawned.** A reviewer dispatched onto code that doesn't compile burns its
351
351
  whole run rediscovering what `tsc` already printed for free — the failure goes straight to the
352
- human (or `/fix`) instead.
353
- - **All green** ⇒ the script stamps `.claude/preflight.ok` (`<epoch> <HEAD sha>`).
352
+ human (or `/cohorte-fix`) instead.
353
+ - **All green** ⇒ the script stamps `.claude/preflight.ok` (`<epoch> <HEAD sha> <tree digest>` —
354
+ local and **gitignored**; a versioned stamp describes the tree *before* its own commit and rides
355
+ into every clone and worktree, which breaks the gate both ways).
354
356
 
355
357
  `hooks/gate.py` enforces the stamp as a **phase gate** (the `preflight` block of `gate-config.json`,
356
358
  generated from `gate.preflight`): a Task dispatch of a listed `subagent_type` (default
357
- `review`) with a missing/stale stamp — older than `max_age_minutes`, or HEAD moved — gets an
359
+ `review`) with a missing/stale stamp — older than `max_age_minutes`, or the digest no longer
360
+ matches the working tree (`.claude` and `specs` excluded, so the pipeline's own writes and a
361
+ commit of already-verified code do not invalidate it) — gets an
358
362
  "ask", so a lead can't accidentally skip the gate but a human can consciously override it. The gate
359
363
  hook fires for **every** agent in the session, including subagents spawned by the Workflow runtime
360
364
  (they run in `acceptEdits` whatever the session mode — Write/Edit auto-approved — but Bash and Task
@@ -363,7 +367,7 @@ hard deny, because nobody is there to answer a prompt.
363
367
 
364
368
  ## Rendering / reconciling a surface agent (shared procedure)
365
369
 
366
- Both `/init-pipeline` (initial render) and `/build` (auto-reconcile when a spec needs a new agent) use
370
+ Both `/cohorte-init-pipeline` (initial render) and `/cohorte-build` (auto-reconcile when a spec needs a new agent) use
367
371
  this exact procedure so a surface is always defined the same way. To add surface `S`:
368
372
 
369
373
  1. **Add the `surfaces[]` entry** to `PIPELINE.md`: `key`, `path` (the disjoint tree it exclusively
@@ -382,7 +386,7 @@ this exact procedure so a surface is always defined the same way. To add surface
382
386
  **baked at render time**: `PIPELINE.md` §Conventions `### Shared` + this surface's
383
387
  `### Surface: <key>` stanza + its §Testing lines, verbatim. At runtime the agent then reads only
384
388
  the profile's machine block (the fenced `yaml pipeline-profile`) — never the prose sections. The
385
- bake stays honest because §Conventions edits go through `/update-pipeline`, whose reconcile
389
+ bake stays honest because §Conventions edits go through `/cohorte-update-pipeline`, whose reconcile
386
390
  re-renders every agent (step 2 below); hand-edit the prose without re-rendering and the baked
387
391
  slice goes stale — that's the trade for not re-reading the prose on every dispatch. For a `uses_design` surface, fill them **link-based** (never with a
388
392
  stored `design_project` id — that goes stale on a DS rebuild):
@@ -410,7 +414,7 @@ conventions. Never leave an agent file with no matching `surfaces[]` entry (orph
410
414
 
411
415
  ## Reconcile — bringing generated files up to the current core
412
416
 
413
- `/init-pipeline` is **one-time per project**. Afterwards, `/update-pipeline` runs this procedure so a
417
+ `/cohorte-init-pipeline` is **one-time per project**. Afterwards, `/cohorte-update-pipeline` runs this procedure so a
414
418
  core upgrade never requires re-running init — new pipeline features flow into the repo's generated
415
419
  files automatically. It works because every generated artifact is a **deterministic function of
416
420
  (current template × the profile's data)**; nothing needs re-detecting or re-interviewing.
@@ -428,7 +432,7 @@ files automatically. It works because every generated artifact is a **determinis
428
432
  init spec (missing `allow` entries, hooks per install mode) — add what's missing, never remove or
429
433
  rewrite existing/custom keys.
430
434
  4. **Capability wiring.** If a top-up added a capability needing external setup (e.g. a `retrieval`
431
- provider whose MCP server isn't registered yet), run its wiring step from `/init-pipeline` Phase 4.
435
+ provider whose MCP server isn't registered yet), run its wiring step from `/cohorte-init-pipeline` Phase 4.
432
436
  Even when nothing new was added, re-run the provider's health check (§Code retrieval) — wiring
433
437
  rots (PATH changes, uninstalls, hand-edits) — and repair whatever fails.
434
438
  5. **Global config seed.** If `~/.claude/cohorte.config.yaml` is absent, seed it from the template
@@ -446,20 +450,28 @@ files automatically. It works because every generated artifact is a **determinis
446
450
  demand when a driver needs them); it just keeps a new spec's front-matter honest about the states
447
451
  the pipeline can put it in.
448
452
 
449
- Re-running `/init-pipeline` remains possible (it reconciles too) but is only *needed* when the stack
450
- itself changes in ways `/build` §1.5 can't auto-grow (e.g. package manager or contract mechanism swap).
453
+ 8. **Local-artifact hygiene.** The pipeline's own runtime files must stay out of git:
454
+ `.claude/preflight.ok`, `.claude/pipeline-metrics.jsonl`, `specs/reports/`. Add any missing entry to
455
+ `.gitignore`, and **untrack** what a pre-2.0.0 install let slip in —
456
+ `git rm --cached --ignore-unmatch .claude/preflight.ok` (repeat per stray path). The stamp is the
457
+ one that actively breaks: it records the tree it verified, the commit carrying it moves HEAD past
458
+ that tree, and the committed copy lands in every clone and worktree — so the phase gate ends up
459
+ blocking clean trees and greening unchecked ones. Report what was untracked; the human commits it.
460
+
461
+ Re-running `/cohorte-init-pipeline` remains possible (it reconciles too) but is only *needed* when the stack
462
+ itself changes in ways `/cohorte-build` §1.5 can't auto-grow (e.g. package manager or contract mechanism swap).
451
463
 
452
464
  ## Workflows — deterministic multi-agent runs (opt-in)
453
465
 
454
466
  Three phases have a **workflow variant** — a deterministic orchestration script the Claude Code
455
467
  Workflow runtime executes instead of the lead reasoning out the fan-out turn by turn:
456
468
  `<core>/workflows/review.js`, `audit.js`, `refactor.js` (installed to `.claude/workflows/` bundled or
457
- `~/.claude/workflows/` global). The conversational commands (`/review`, `/audit`, `/refactor`)
469
+ `~/.claude/workflows/` global). The conversational commands (`/cohorte-review`, `/cohorte-audit`, `/cohorte-refactor`)
458
470
  **remain the default path and the fallback** — a workflow runs only when the human explicitly asks
459
471
  for it ("run the review workflow"), and requires Claude Code ≥ **2.1.154** with workflows
460
472
  enabled.
461
- `/doctor` reports which path a session will take. The interactive commands (`/init-pipeline`,
462
- `/brainstorm`, `/spec`) and the dispatch-only ones (`/build`, `/ship`) have **no** workflow variant on
473
+ `/cohorte-doctor` reports which path a session will take. The interactive commands (`/cohorte-init-pipeline`,
474
+ `/cohorte-brainstorm`, `/cohorte-spec`) and the dispatch-only ones (`/cohorte-build`, `/cohorte-ship`) have **no** workflow variant on
463
475
  purpose: they're interviews or already a single parallel dispatch — a script adds nothing.
464
476
 
465
477
  Shared design, all four scripts:
@@ -488,13 +500,13 @@ Shared design, all four scripts:
488
500
  - **`audit.js`** — one auditor per domain (each surface + `shared`), concurrency capped by the
489
501
  runtime (~16), merged into the prioritized `specs/refactor-backlog.md`.
490
502
  - **`refactor.js`** — big domains only (it skips domains with a handful of open items — the
491
- conversational `/refactor` is cheaper there): `shared` first and alone, then the other domains'
503
+ conversational `/cohorte-refactor` is cheaper there): `shared` first and alone, then the other domains'
492
504
  implementers in parallel, each verified per-domain.
493
505
  - **No input mid-run.** A workflow runs to completion without questions; anything interactive
494
506
  (contract changes, human decisions) belongs to the conversational path. The gate hook still
495
507
  fires on workflow subagents (see
496
508
  §Preflight) — in unattended runs its asks become denies.
497
- - **Permissions:** `/init-pipeline` and `/update-pipeline` extend the generated `settings.json`
509
+ - **Permissions:** `/cohorte-init-pipeline` and `/cohorte-update-pipeline` extend the generated `settings.json`
498
510
  `allow` list with what workflow agents need (the quiet commands, the shipped
499
511
  `pipeline/scripts/*.sh`, read-only git incl. `git rev-parse`, and the retrieval provider's MCP
500
512
  tools) so a run never stalls mid-workflow on a permission prompt nobody is watching.
@@ -517,11 +529,11 @@ present else `kanban.columns`. Not found ⇒ kanban off for this project.
517
529
  **Card format.** A card is a Kanban list item under a `## <column>` heading:
518
530
  `- [ ] <human title> #<feature_id>`. The `#<feature_id>` tag is the join key between a card and its
519
531
  `specs/<feature_id>.md`; it is how every stage finds *its* card (Grep the board for `#<id>`). Free-text
520
- notes a human writes as sub-bullets under an Ideas card are seed context for `/brainstorm`. Never touch
532
+ notes a human writes as sub-bullets under an Ideas card are seed context for `/cohorte-brainstorm`. Never touch
521
533
  the trailing `%% kanban:settings … %%` block or the `kanban-plugin: board` front-matter.
522
534
 
523
- Once shipped, `/ship` appends the **PR number** to the card — `- [ ] <title> #<feature_id> — PR #<num>`.
524
- The bare `#<num>` is what the dashboard renders as a clickable link to the GitHub PR, so `/ship` always
535
+ Once shipped, `/cohorte-ship` appends the **PR number** to the card — `- [ ] <title> #<feature_id> — PR #<num>`.
536
+ The bare `#<num>` is what the dashboard renders as a clickable link to the GitHub PR, so `/cohorte-ship` always
525
537
  writes it when a PR was actually created.
526
538
 
527
539
  **Move a card (the core op).** Use the shipped script — it does the whole op outside the agent's
@@ -540,15 +552,15 @@ card created in the target column if missing.
540
552
  | Pipeline moment | Column |
541
553
  | --------------------------------------- | --------------- |
542
554
  | human drops a raw idea (manual) | `ideas` |
543
- | `/brainstorm` picks it up | `brainstorm` |
544
- | `/spec` opens (draft) | `spec` |
545
- | `/spec` freezes (`status: frozen`) | `ready` |
546
- | `/build` | `building` |
547
- | `/review` | `review` |
548
- | `/fix` | `fix` |
549
- | a `/drive` is driving it (`in-progress`) | the current phase's column |
550
- | a `/drive` gave up (`blocked`) | `fix` |
551
- | `/ship` starts | `ship` |
555
+ | `/cohorte-brainstorm` picks it up | `brainstorm` |
556
+ | `/cohorte-spec` opens (draft) | `spec` |
557
+ | `/cohorte-spec` freezes (`status: frozen`) | `ready` |
558
+ | `/cohorte-build` | `building` |
559
+ | `/cohorte-review` | `review` |
560
+ | `/cohorte-fix` | `fix` |
561
+ | a `/cohorte-loop` is driving it (`in-progress`) | the current phase's column |
562
+ | a `/cohorte-loop` gave up (`blocked`) | `fix` |
563
+ | `/cohorte-ship` starts | `ship` |
552
564
  | PR opened (`status: shipped`) | `shipped` (+ `PR #<num>` on the card) |
553
565
 
554
566
  **Backfill / sync from specs (reconcile).** `specs/*.md` is the source of truth. For each spec, read its
@@ -568,12 +580,12 @@ per configured column in pipeline order, and the closing `%% kanban:settings %%`
568
580
  ## Telemetry — anonymous usage stats, strictly opt-in (GDPR-first)
569
581
 
570
582
  Cohorte can send the maintainers anonymous usage pings so the pipeline improves where it's actually
571
- slow. **Nothing is ever sent without explicit consent**: `/init-pipeline` (and `/update-pipeline` on
583
+ slow. **Nothing is ever sent without explicit consent**: `/cohorte-init-pipeline` (and `/cohorte-update-pipeline` on
572
584
  pre-telemetry installs) ask ONE question, once per machine, default **No**, and record the answer in
573
585
  `~/.claude/cohorte.config.yaml` §`telemetry` (`enabled`, `install_id`, `consent_date`). The sender —
574
586
  `pipeline/scripts/telemetry-send.sh` — is a silent no-op unless `enabled: true` AND `install_id` AND
575
587
  `endpoint` are all set, times out at 2s, and never fails the pipeline. Callers chain it with
576
- `|| true`, so a **missing** script is equally silent: `/doctor` check 1 verifies `pipeline/scripts/`
588
+ `|| true`, so a **missing** script is equally silent: `/cohorte-doctor` check 1 verifies `pipeline/scripts/`
577
589
  is fully populated.
578
590
 
579
591
  **Which commands ping** — the six that make up the feature funnel, and only those. The point is to
@@ -593,8 +605,8 @@ see where features stall, so every stage of `idea → PR` reports and nothing el
593
605
  > forms are valid — but read the `fix` column knowing which path produced it.
594
606
 
595
607
  `seconds: 0` marks a phase whose duration is human thinking time, not pipeline wall-clock — the
596
- funnel signal there is the event, not how long it took. `/doctor`, `/audit`, `/refactor`,
597
- `/align-ds`, `/init-pipeline` and `/update-pipeline` **never** ping: they sit outside the funnel, and
608
+ funnel signal there is the event, not how long it took. `/cohorte-doctor`, `/cohorte-audit`, `/cohorte-refactor`,
609
+ `/cohorte-align-ds`, `/cohorte-init-pipeline` and `/cohorte-update-pipeline` **never** ping: they sit outside the funnel, and
598
610
  keeping them out is what holds the collected set to what the consent text describes.
599
611
 
600
612
  **What one event contains** (strict allowlist, ~200 bytes):
@@ -614,7 +626,7 @@ work without revealing what is being built.
614
626
  - **Consent** — opt-in only, recorded with a date; "No" is also recorded so nothing re-asks.
615
627
  - **Withdrawal** — set `telemetry.enabled: false` in `~/.claude/cohorte.config.yaml`; effective on
616
628
  the next phase, no restart.
617
- - **Erasure** — `/doctor` prints your `install_id`; send
629
+ - **Erasure** — `/cohorte-doctor` prints your `install_id`; send
618
630
  `curl -X DELETE <endpoint-origin>/v1/install/<install_id>` and the collector drops every event
619
631
  for that id (the deployed collector implements this and stores no IPs).
620
632
  - **Access/portability** — events are keyed by your `install_id`; ask the operator for an export.
@@ -2,7 +2,7 @@
2
2
  # pipeline capabilities. One machine, every project. NOT tied to any project's PIPELINE.md.
3
3
  #
4
4
  # Seeded once by the installer (npx cohorte install) and never clobbered on update. Wired
5
- # interactively by /init-pipeline (new project) and /update-pipeline (existing project) —
5
+ # interactively by /cohorte-init-pipeline (new project) and /cohorte-update-pipeline (existing project) —
6
6
  # you should never need to hand-edit it.
7
7
  #
8
8
  # The `# cfg:<key>` markers below are anchors the installer's interactive prompts write to;
@@ -12,12 +12,12 @@ enabled: true # cfg:enabled — master switch; false disables ev
12
12
 
13
13
  # ── telemetry (anonymous usage stats — OPT-IN, GDPR-first) ──────────────────
14
14
  # Strictly opt-in: nothing is ever sent unless YOU said yes to the consent question
15
- # (/init-pipeline or /update-pipeline ask once per machine; they record your answer here).
15
+ # (/cohorte-init-pipeline or /cohorte-update-pipeline ask once per machine; they record your answer here).
16
16
  # What is sent when enabled: core version, OS, phase name, wall-clock seconds, per-surface
17
17
  # result counts, and a SHA-256 HASH of the feature id — never repo names, paths, code, spec
18
- # content, emails, or IPs. One ping per pipeline phase, /brainstorm through /ship; setup and
19
- # maintenance commands (/doctor, /init-pipeline, /update-pipeline, /audit, /refactor,
20
- # /align-ds) never ping. Sent fire-and-forget (2s timeout, silent on failure) by
18
+ # content, emails, or IPs. One ping per pipeline phase, /cohorte-brainstorm through /cohorte-ship; setup and
19
+ # maintenance commands (/cohorte-doctor, /cohorte-init-pipeline, /cohorte-update-pipeline, /cohorte-audit, /cohorte-refactor,
20
+ # /cohorte-align-ds) never ping. Sent fire-and-forget (2s timeout, silent on failure) by
21
21
  # pipeline/scripts/telemetry-send.sh. Withdraw anytime: set enabled: false. Erase your history:
22
22
  # see SCHEMA.md §Telemetry (DELETE by install_id).
23
23
  telemetry:
@@ -33,9 +33,9 @@ obsidian:
33
33
  vault_path: "" # cfg:vault_path
34
34
 
35
35
  # ── kanban (dev pipeline mirror) ─────────────────────────────────────────────
36
- # Mirrors /brainstorm…/ship onto an Obsidian Kanban board — one board per project. The
36
+ # Mirrors /cohorte-brainstorm…/cohorte-ship onto an Obsidian Kanban board — one board per project. The
37
37
  # board path points at your PERSONAL vault, so it is machine-specific and lives here (never
38
- # committed in a repo's PIPELINE.md). /init-pipeline + /update-pipeline write `boards` for you.
38
+ # committed in a repo's PIPELINE.md). /cohorte-init-pipeline + /cohorte-update-pipeline write `boards` for you.
39
39
  # See SCHEMA.md §Kanban.
40
40
  kanban:
41
41
  enabled: false # cfg:kanban_enabled — master switch for the kanban mirror
@@ -52,7 +52,7 @@ kanban:
52
52
  ship: "Ship"
53
53
  shipped: "Shipped"
54
54
  # One entry per project, keyed by the project's PIPELINE.md `name` (e.g. SAMO). `board` is a
55
- # path RELATIVE to obsidian.vault_path. Written by /init-pipeline + /update-pipeline.
55
+ # path RELATIVE to obsidian.vault_path. Written by /cohorte-init-pipeline + /cohorte-update-pipeline.
56
56
  boards: {}
57
57
  # SAMO:
58
58
  # board: "Samo/Tasks.md"