cohorte 2.10.0 → 3.0.0-dev.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.
- package/README.md +7 -0
- package/assets/manifest.json +193 -0
- package/assets/migrations/config/README.md +12 -0
- package/assets/migrations/state/0001_init.sql +154 -0
- package/assets/prompts/README.md +11 -0
- package/assets/prompts/agents/fixer.md +7 -0
- package/assets/prompts/agents/implementer.md +12 -0
- package/assets/prompts/agents/reviewer.md +8 -0
- package/assets/prompts/agents/security-reviewer.md +7 -0
- package/assets/prompts/phases/build.md +5 -0
- package/assets/prompts/phases/review.md +5 -0
- package/assets/prompts/phases/test.md +5 -0
- package/assets/prompts/system.md +11 -0
- package/assets/schemas/agent-output.schema.json +225 -0
- package/assets/schemas/auth-status.schema.json +87 -0
- package/assets/schemas/command-result.schema.json +192 -0
- package/assets/schemas/commands.schema.json +952 -0
- package/assets/schemas/config.schema.json +2259 -0
- package/assets/schemas/doctor-report.schema.json +104 -0
- package/assets/schemas/events.schema.json +8514 -0
- package/assets/schemas/fake-script.schema.json +549 -0
- package/assets/schemas/inspect.schema.json +3133 -0
- package/assets/schemas/manifest.schema.json +79 -0
- package/assets/schemas/ownership.schema.json +52 -0
- package/assets/schemas/policy-verdict.schema.json +282 -0
- package/assets/schemas/project-model.schema.json +783 -0
- package/assets/schemas/project-status.schema.json +217 -0
- package/assets/schemas/reconcile-plan.schema.json +155 -0
- package/assets/schemas/run-diff.schema.json +177 -0
- package/assets/schemas/run-snapshot-manifest.schema.json +2104 -0
- package/assets/schemas/run-state.schema.json +1755 -0
- package/assets/schemas/runtime-capabilities.schema.json +1545 -0
- package/assets/schemas/sandbox-capabilities.schema.json +116 -0
- package/assets/schemas/skill.schema.json +87 -0
- package/assets/schemas/spec.schema.json +202 -0
- package/assets/schemas/tool-catalogue.schema.json +655 -0
- package/assets/schemas/trust-record.schema.json +38 -0
- package/assets/skills/README.md +9 -0
- package/assets/skills/inspect-surface.md +4 -0
- package/dist/agent-host.mjs +50 -0
- package/dist/agent-host.mjs.map +1 -0
- package/dist/bundle-manifest.json +102 -0
- package/dist/chunks/__host-DgGPyco9.mjs +18 -0
- package/dist/chunks/__host-DgGPyco9.mjs.map +1 -0
- package/dist/chunks/approve-Cv135UqI.mjs +19 -0
- package/dist/chunks/approve-Cv135UqI.mjs.map +1 -0
- package/dist/chunks/auth-BT5oVp76.mjs +132 -0
- package/dist/chunks/auth-BT5oVp76.mjs.map +1 -0
- package/dist/chunks/auth-D8rCVY33.mjs +84 -0
- package/dist/chunks/auth-D8rCVY33.mjs.map +1 -0
- package/dist/chunks/brainstorm-CU10T1tm.mjs +7 -0
- package/dist/chunks/brainstorm-CU10T1tm.mjs.map +1 -0
- package/dist/chunks/cancel-KV_cpsqS.mjs +15 -0
- package/dist/chunks/cancel-KV_cpsqS.mjs.map +1 -0
- package/dist/chunks/canonical-C8UxeEmB.mjs +57 -0
- package/dist/chunks/canonical-C8UxeEmB.mjs.map +1 -0
- package/dist/chunks/catalogue-BvwSrM_j.mjs +1549 -0
- package/dist/chunks/catalogue-BvwSrM_j.mjs.map +1 -0
- package/dist/chunks/compose-Cr0hP0qm.mjs +7303 -0
- package/dist/chunks/compose-Cr0hP0qm.mjs.map +1 -0
- package/dist/chunks/config-DefHA2Lw.mjs +96 -0
- package/dist/chunks/config-DefHA2Lw.mjs.map +1 -0
- package/dist/chunks/contract-B0ra2-bm.mjs +295 -0
- package/dist/chunks/contract-B0ra2-bm.mjs.map +1 -0
- package/dist/chunks/contract-vYbwYr0Y.mjs +123 -0
- package/dist/chunks/contract-vYbwYr0Y.mjs.map +1 -0
- package/dist/chunks/deny-ClTxSvHJ.mjs +15 -0
- package/dist/chunks/deny-ClTxSvHJ.mjs.map +1 -0
- package/dist/chunks/diff-Qw0II0sj.mjs +101 -0
- package/dist/chunks/diff-Qw0II0sj.mjs.map +1 -0
- package/dist/chunks/discover-30Ciya_0.mjs +20 -0
- package/dist/chunks/discover-30Ciya_0.mjs.map +1 -0
- package/dist/chunks/doctor-DfCrKpfT.mjs +222 -0
- package/dist/chunks/doctor-DfCrKpfT.mjs.map +1 -0
- package/dist/chunks/fix-D4Tj8RVA.mjs +18 -0
- package/dist/chunks/fix-D4Tj8RVA.mjs.map +1 -0
- package/dist/chunks/gc-BBXlBF5w.mjs +161 -0
- package/dist/chunks/gc-BBXlBF5w.mjs.map +1 -0
- package/dist/chunks/init-Okz4mlhW.mjs +30 -0
- package/dist/chunks/init-Okz4mlhW.mjs.map +1 -0
- package/dist/chunks/inspect-Buby4cQD.mjs +22 -0
- package/dist/chunks/inspect-Buby4cQD.mjs.map +1 -0
- package/dist/chunks/logs-Giq5sUau.mjs +25 -0
- package/dist/chunks/logs-Giq5sUau.mjs.map +1 -0
- package/dist/chunks/migrate-DRoFUg53.mjs +19 -0
- package/dist/chunks/migrate-DRoFUg53.mjs.map +1 -0
- package/dist/chunks/models-Btp6X2YZ.mjs +24 -0
- package/dist/chunks/models-Btp6X2YZ.mjs.map +1 -0
- package/dist/chunks/pause-BASBfKLO.mjs +16 -0
- package/dist/chunks/pause-BASBfKLO.mjs.map +1 -0
- package/dist/chunks/policy-DUIgzF3W.mjs +139 -0
- package/dist/chunks/policy-DUIgzF3W.mjs.map +1 -0
- package/dist/chunks/providers-Dx78imKj.mjs +19 -0
- package/dist/chunks/providers-Dx78imKj.mjs.map +1 -0
- package/dist/chunks/reconcile-BfD785gd.mjs +26 -0
- package/dist/chunks/reconcile-BfD785gd.mjs.map +1 -0
- package/dist/chunks/render-DyZr5Lgi.mjs +53 -0
- package/dist/chunks/render-DyZr5Lgi.mjs.map +1 -0
- package/dist/chunks/resume-GJQRb2Eb.mjs +15 -0
- package/dist/chunks/resume-GJQRb2Eb.mjs.map +1 -0
- package/dist/chunks/retry-CLrUem1H.mjs +15 -0
- package/dist/chunks/retry-CLrUem1H.mjs.map +1 -0
- package/dist/chunks/review-BDdjb6kB.mjs +17 -0
- package/dist/chunks/review-BDdjb6kB.mjs.map +1 -0
- package/dist/chunks/run-CgTWYlcd.mjs +82 -0
- package/dist/chunks/run-CgTWYlcd.mjs.map +1 -0
- package/dist/chunks/run-tool-C3rAv4XF.mjs +26 -0
- package/dist/chunks/run-tool-C3rAv4XF.mjs.map +1 -0
- package/dist/chunks/schema-C9QbUW4H.mjs +578 -0
- package/dist/chunks/schema-C9QbUW4H.mjs.map +1 -0
- package/dist/chunks/send-BdnJ85Nz.mjs +19 -0
- package/dist/chunks/send-BdnJ85Nz.mjs.map +1 -0
- package/dist/chunks/ship-DTuLGoaJ.mjs +19 -0
- package/dist/chunks/ship-DTuLGoaJ.mjs.map +1 -0
- package/dist/chunks/shutdown-BM92Iyv2.mjs +15 -0
- package/dist/chunks/shutdown-BM92Iyv2.mjs.map +1 -0
- package/dist/chunks/skip-DZG5kpcH.mjs +18 -0
- package/dist/chunks/skip-DZG5kpcH.mjs.map +1 -0
- package/dist/chunks/spec-Bq0P3jVh.mjs +20 -0
- package/dist/chunks/spec-Bq0P3jVh.mjs.map +1 -0
- package/dist/chunks/src-CId6kMsY.mjs +1689 -0
- package/dist/chunks/src-CId6kMsY.mjs.map +1 -0
- package/dist/chunks/src-CfAOde7C.mjs +5403 -0
- package/dist/chunks/src-CfAOde7C.mjs.map +1 -0
- package/dist/chunks/src-Cu3TxNob.mjs +783 -0
- package/dist/chunks/src-Cu3TxNob.mjs.map +1 -0
- package/dist/chunks/src-DcU4IXMe.mjs +117 -0
- package/dist/chunks/src-DcU4IXMe.mjs.map +1 -0
- package/dist/chunks/src-JxawBQBn.mjs +446 -0
- package/dist/chunks/src-JxawBQBn.mjs.map +1 -0
- package/dist/chunks/src-s7YRvk0t.mjs +2116 -0
- package/dist/chunks/src-s7YRvk0t.mjs.map +1 -0
- package/dist/chunks/status-SMjiOMYy.mjs +29 -0
- package/dist/chunks/status-SMjiOMYy.mjs.map +1 -0
- package/dist/chunks/tail-BuhT-2PH.mjs +25 -0
- package/dist/chunks/tail-BuhT-2PH.mjs.map +1 -0
- package/dist/chunks/update-BXIppsbi.mjs +16 -0
- package/dist/chunks/update-BXIppsbi.mjs.map +1 -0
- package/dist/cli.mjs +175 -0
- package/dist/cli.mjs.map +1 -0
- package/package.json +17 -32
- package/CHANGELOG.md +0 -1453
- package/bin/cli.js +0 -812
- package/bin/report.js +0 -141
- package/core/adapter/render.js +0 -389
- package/core/agents/implementer.template.md +0 -142
- package/core/agents/profile-reader.md +0 -50
- package/core/agents/release.md +0 -58
- package/core/agents/review.md +0 -179
- package/core/commands/cohorte-align-ds.md +0 -33
- package/core/commands/cohorte-audit.md +0 -58
- package/core/commands/cohorte-brainstorm.md +0 -70
- package/core/commands/cohorte-build.md +0 -219
- package/core/commands/cohorte-doctor.md +0 -170
- package/core/commands/cohorte-fix.md +0 -80
- package/core/commands/cohorte-fleet.md +0 -103
- package/core/commands/cohorte-init-pipeline.md +0 -31
- package/core/commands/cohorte-intake.md +0 -92
- package/core/commands/cohorte-patch.md +0 -118
- package/core/commands/cohorte-refactor.md +0 -59
- package/core/commands/cohorte-retro.md +0 -85
- package/core/commands/cohorte-review.md +0 -270
- package/core/commands/cohorte-ship.md +0 -122
- package/core/commands/cohorte-spec.md +0 -101
- package/core/commands/cohorte-update-pipeline.md +0 -134
- package/core/hooks/gate.py +0 -580
- package/core/runtimes/claude.json +0 -74
- package/core/runtimes/codex.json +0 -83
- package/core/runtimes/cursor.json +0 -76
- package/core/runtimes/gemini.json +0 -76
- package/core/runtimes/opencode.json +0 -73
- package/core/templates/agent-handoff.md +0 -34
- package/core/templates/brainstorm-return.md +0 -36
- package/core/templates/decisions.template.md +0 -42
- package/core/templates/design-brief.md +0 -44
- package/core/templates/patch.template.md +0 -86
- package/core/templates/pr-body.md +0 -25
- package/core/templates/review-feedback.md +0 -38
- package/core/templates/spec.template.md +0 -87
- package/core/templates/steps/init-pipeline/01-detect-stack.md +0 -44
- package/core/templates/steps/init-pipeline/02-interview-gaps.md +0 -55
- package/core/templates/steps/init-pipeline/03-draft-profile.md +0 -10
- package/core/templates/steps/init-pipeline/04-write-render.md +0 -115
- package/core/templates/steps/init-pipeline/05-report.md +0 -12
- package/core/workflows/audit.js +0 -240
- package/core/workflows/loop.js +0 -641
- package/core/workflows/refactor.js +0 -276
- package/core/workflows/review.js +0 -456
- package/install.ps1 +0 -103
- package/install.sh +0 -114
- package/lib/doctor.js +0 -504
- package/lib/runtime.js +0 -134
- package/lib/versions.js +0 -149
- package/lib/yaml.js +0 -129
- package/profile/PIPELINE.template.md +0 -251
- package/profile/SCHEMA.md +0 -698
- package/profile/cohorte.config.template.yaml +0 -43
- package/scripts/assert-gate-hook.mjs +0 -75
- package/scripts/kanban-move.sh +0 -313
- package/scripts/metrics/collect.mjs +0 -531
- package/scripts/metrics/prices.json +0 -42
- package/scripts/new-feature.sh.template +0 -98
- package/scripts/preflight.sh +0 -124
- package/scripts/remove-feature.sh.template +0 -56
- package/scripts/test-adapter.mjs +0 -368
- package/scripts/test-gate.mjs +0 -428
- package/scripts/test-kanban.mjs +0 -304
- package/scripts/test-lib.mjs +0 -310
- package/scripts/test-metrics.mjs +0 -156
- package/scripts/test-workflows.mjs +0 -758
- package/scripts/validate-core.mjs +0 -320
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Triage anything that arrives — a ticket, a client email, a stack trace, a Slack thread — into the pipeline's entry point: a patch handoff or a brainstorm seed.
|
|
3
|
-
argument-hint: [paste the raw material — ticket, email, trace, thread — or empty to be asked]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
You are the **intake triager**. Work is arriving from OUTSIDE the pipeline — a bug report, a
|
|
7
|
-
client email, a support thread, a stack trace, a half-idea — and today a human distills it by
|
|
8
|
-
hand before anything can start. Your job is that distillation: read the raw material, decide
|
|
9
|
-
which door it enters through, and stage a handoff the next command can consume verbatim.
|
|
10
|
-
|
|
11
|
-
> Read `PIPELINE.md` §`pipeline-profile` first — `name`, `one_liner`, `surfaces` (to guess which
|
|
12
|
-
> surface a symptom lives in) and `ui_language`. _Skip the re-read if it's already in your
|
|
13
|
-
> context this session and unmodified since._ Read `specs/_decisions.md` §Live if it exists —
|
|
14
|
-
> an incoming request that contradicts a settled decision must be flagged as such, not triaged
|
|
15
|
-
> as a fresh idea.
|
|
16
|
-
|
|
17
|
-
## 1. Ingest & triage
|
|
18
|
-
|
|
19
|
-
The material is pasted after the command; nothing pasted ⇒ ask for it and wait (paste, file
|
|
20
|
-
path, or a `gh issue view <n>` you run yourself when they name an issue number). Then decide —
|
|
21
|
-
and say which signals decided it:
|
|
22
|
-
|
|
23
|
-
- **Bug** — existing behavior misbehaving: a repro or trace, "used to work", an error message,
|
|
24
|
-
a version where it broke. → §2.
|
|
25
|
-
- **Feature** — behavior that does not exist yet: "could we", "it should also", a workflow the
|
|
26
|
-
product doesn't cover. → §3.
|
|
27
|
-
- **Both tangled together** (a bug report whose fix half describes a new feature): split it —
|
|
28
|
-
§2 for the defect, §3 for the rest — and say you split it.
|
|
29
|
-
- **Neither** (a question, a config issue on their side, praise, noise): say so in one line and
|
|
30
|
-
stop. Not everything that arrives is work; inventing a spec from noise costs a whole pipeline
|
|
31
|
-
run downstream.
|
|
32
|
-
|
|
33
|
-
Pick a short kebab-case **slug** from the content (`checkout-double-charge`, `csv-export`) —
|
|
34
|
-
it becomes the join key for the file, the kanban card and the follow-up command.
|
|
35
|
-
|
|
36
|
-
## 2. Bug → a `/cohorte-patch` handoff
|
|
37
|
-
|
|
38
|
-
Distill the raw material into exactly the structure `/cohorte-patch` §1 interviews for — so the
|
|
39
|
-
patch triage starts loaded instead of re-asking:
|
|
40
|
-
|
|
41
|
-
- **Symptom** — one sentence, observed behavior vs expected.
|
|
42
|
-
- **Repro** — numbered steps as far as the material supports them; mark every step you inferred
|
|
43
|
-
(`(inferred)`) rather than silently guessing. A trace with no steps ⇒ the trace IS the repro
|
|
44
|
-
material, say so.
|
|
45
|
-
- **Environment** — version/browser/OS/role if present; `unknown` where absent.
|
|
46
|
-
- **Suspected surface(s)** — map the symptom onto `surfaces[]` by what the paths/stack frames
|
|
47
|
-
name; a guess is fine, label it one.
|
|
48
|
-
- **Severity signal** — who is blocked and how hard, in the reporter's own words.
|
|
49
|
-
|
|
50
|
-
**Stage it** to `specs/reports/intake-<slug>.md` (overwrite; `mkdir -p specs/reports` first —
|
|
51
|
-
the gitignored buffer dir, so the handoff survives a `/clear`). Then:
|
|
52
|
-
|
|
53
|
-
> **Kanban** (SCHEMA.md §Kanban): run
|
|
54
|
-
> `<core>/pipeline/scripts/kanban-move.sh auto patch-<slug> ideas --title "[patch] <one-line title>"`.
|
|
55
|
-
> The id is **`patch-<slug>`, prefix included, and the title prefix is `[patch]`** — that is the
|
|
56
|
-
> exact join key and the exact title `/cohorte-patch` §1 looks for, so its later move finds THIS
|
|
57
|
-
> card instead of creating a duplicate and stranding this one in Ideas (the failure SCHEMA
|
|
58
|
-
> §Kanban's "tag before you move" exists to prevent). `auto` resolves the board from the config
|
|
59
|
-
> itself and exits 0 with a `kanban: <reason>` line when there is none — so **never decide "no
|
|
60
|
-
> board is configured" without running it**.
|
|
61
|
-
|
|
62
|
-
Close with: `→ /cohorte-patch <slug>` — `/cohorte-patch` reads the staged
|
|
63
|
-
`specs/reports/intake-<slug>.md` when it exists, so the triage starts loaded. Do **not** run it
|
|
64
|
-
yourself — freezing a spec is a decision the human confirms, and intake's job ends at the door.
|
|
65
|
-
|
|
66
|
-
## 3. Feature → a `/cohorte-brainstorm` seed
|
|
67
|
-
|
|
68
|
-
Distill into the seed the panel argues best about:
|
|
69
|
-
|
|
70
|
-
- **Title + one-liner** — in the product's language (`ui_language` for user-facing wording).
|
|
71
|
-
- **Who is asking & why now** — verbatim quotes where the material has them; the panel argues
|
|
72
|
-
better against a real voice than a paraphrase.
|
|
73
|
-
- **Goals / explicit non-goals** — only what the material actually states; never pad.
|
|
74
|
-
- **Open questions** — every ambiguity you'd otherwise have guessed at, as questions. This list
|
|
75
|
-
is the seed's real value: it is the brainstorm's agenda.
|
|
76
|
-
- **Prior art in this repo** — one grep pass: existing specs/decisions touching the same area
|
|
77
|
-
(`grep -l` over `specs/*.md`, redirected — never a file read per name). Contradicts a
|
|
78
|
-
`_decisions.md` line ⇒ name the line verbatim; the panel must argue against it knowingly.
|
|
79
|
-
|
|
80
|
-
**Stage it** to `specs/reports/intake-<slug>.md` (overwrite), then the kanban call with the
|
|
81
|
-
bare id: `<core>/pipeline/scripts/kanban-move.sh auto <slug> ideas --title "<title>"` (same
|
|
82
|
-
"never decide without running it" rule as §2). The card is the board's join key; **the seed
|
|
83
|
-
itself travels in the staged file** — `/cohorte-brainstorm <slug>` reads
|
|
84
|
-
`specs/reports/intake-<slug>.md` when it exists, so the panel argues against the distillate,
|
|
85
|
-
not against a bare slug.
|
|
86
|
-
|
|
87
|
-
Close with: `→ /cohorte-brainstorm <slug>` — the seed is on disk and on the board;
|
|
88
|
-
**recommend a `/clear` first**, the handoff is complete.
|
|
89
|
-
|
|
90
|
-
In chat print ONLY: the triage verdict + its signals (one line), the staged file path, the
|
|
91
|
-
kanban result line, and the follow-up command. Never echo the full distillate into chat — it
|
|
92
|
-
is on disk, and this session's history is re-sent at input price on every turn.
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Triage a bug and freeze a minimal patch spec — the cheap entry into the pipeline for a fix, no brainstorm, no contract.
|
|
3
|
-
argument-hint: [bug description / stack trace / issue text — or empty to pick from the kanban]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
You run the **patch triage** in the main thread — interactive, with the human. This is the bug-fix
|
|
7
|
-
entry point: it produces `specs/patch-<slug>.md` and stops. Everything after it is the normal
|
|
8
|
-
pipeline (`/cohorte-build` → `/cohorte-review` → `/cohorte-fix`* → `/cohorte-ship`), unchanged — the
|
|
9
|
-
patch spec is a spec, so those commands consume it as-is. Splitting it this way is the point: each
|
|
10
|
-
phase is a fresh session with the artifact on disk, instead of one long thread paying for the whole
|
|
11
|
-
cycle at input price on every turn.
|
|
12
|
-
|
|
13
|
-
Bug (may be empty): **$ARGUMENTS**
|
|
14
|
-
|
|
15
|
-
> Read `PIPELINE.md` §`pipeline-profile` first: `surfaces` (paths — this is what you map the bug onto)
|
|
16
|
-
> and `vcs`. _Skip the re-read if it's already in your context this session and unmodified since._
|
|
17
|
-
> Do NOT read `specs/_decisions.md`: a bug fix decides nothing transverse, and the journal is for
|
|
18
|
-
> decisions that outlive a feature.
|
|
19
|
-
>
|
|
20
|
-
> **Kanban** (SCHEMA.md §Kanban): two moves, and their **order is load-bearing** — §1 settles the
|
|
21
|
-
> slug and moves the card to `spec`, §4 moves it to `ready` at freeze. Both are one call to
|
|
22
|
-
> `<core>/pipeline/scripts/kanban-move.sh auto patch-<slug> <stage> [--title "[patch] <human title>"]`.
|
|
23
|
-
> The slug is settled first precisely because the move needs it: a card cannot be joined on an id
|
|
24
|
-
> that doesn't exist yet. `auto` resolves the board from the config itself and exits 0
|
|
25
|
-
> with a `kanban: <reason>` line when there is none — so **never decide "no board is configured"
|
|
26
|
-
> without running it**. Reading the Ideas column at §1 still needs the board path: get it from a
|
|
27
|
-
> `kanban-move.sh` run, or grep the config for `boards[<PIPELINE name>]`.
|
|
28
|
-
|
|
29
|
-
## 1. Get the bug
|
|
30
|
-
|
|
31
|
-
If `$ARGUMENTS` is non-empty, restate it in one line and confirm you've got it — and if it is
|
|
32
|
-
(or names) a slug with a staged `specs/reports/intake-<slug>.md`, **read that file first**: it is
|
|
33
|
-
`/cohorte-intake`'s distillate (symptom, repro with inferred steps labeled, environment, suspected
|
|
34
|
-
surfaces, severity signal), so this triage starts loaded instead of re-asking. Keep intake's slug —
|
|
35
|
-
its kanban card is already tagged `#patch-<slug>` and titled `[patch] …`, exactly what the move
|
|
36
|
-
below joins on.
|
|
37
|
-
|
|
38
|
-
If it is empty: when a board is configured and its **Ideas** column has cards, list them (with any
|
|
39
|
-
sub-bullet notes as context) — **cards titled `[patch]` first**, since those are the ones a human
|
|
40
|
-
filed as bugs — and let the human pick one. Otherwise ask **"What's broken?"**. Either way, wait.
|
|
41
|
-
|
|
42
|
-
Then **settle the id, before anything moves.** Derive `<slug>` (kebab-case, from the symptom —
|
|
43
|
-
`500-on-empty-cart`, not `bug-42`) and confirm it. The `feature_id` is **`patch-<slug>`**, prefix
|
|
44
|
-
included: it is the join key for the kanban card, the spec filename, the branch and every later
|
|
45
|
-
command, so the prefix is part of the id itself, not decoration on the card.
|
|
46
|
-
|
|
47
|
-
**Kanban, in this order:**
|
|
48
|
-
|
|
49
|
-
1. **If the human picked an Ideas card, tag it FIRST.** Ideas cards are free text with no
|
|
50
|
-
`#<feature_id>`, and the move script joins on that tag: move before tagging and it finds nothing,
|
|
51
|
-
creates a second card, and strands the untagged original in Ideas forever. One targeted Edit
|
|
52
|
-
appending ` #patch-<slug>` to that line, located by `grep -n` — never a full board read.
|
|
53
|
-
2. `<core>/pipeline/scripts/kanban-move.sh auto patch-<slug> spec --title "[patch] <human title>"` —
|
|
54
|
-
which moves the (now tagged) card, or creates one under `--title` if the human typed a fresh bug.
|
|
55
|
-
Report what it printed — `moved #…` or `kanban: <reason>` — never a guess about which happened.
|
|
56
|
-
|
|
57
|
-
## 2. Triage — three questions, not an interview
|
|
58
|
-
|
|
59
|
-
`/cohorte-spec` walks a template section by section because a feature has to be *designed*. A bug is
|
|
60
|
-
already specified by reality; your job is to pin it down, not to explore it. Ask only what you
|
|
61
|
-
genuinely cannot infer from the input, batched into ONE message:
|
|
62
|
-
|
|
63
|
-
1. **Repro** — the shortest deterministic path to the symptom. No repro ⇒ ask whether they want you
|
|
64
|
-
to go find one first (a diagnosis session, no spec) or to freeze it as a hypothesis and let the
|
|
65
|
-
implementer confirm. Never invent a repro to fill the section.
|
|
66
|
-
2. **Expected behaviour** — often the whole spec. "It should 404, not 500" is a complete contract.
|
|
67
|
-
3. **Blast radius** — what must NOT change. This becomes §7 Out of scope, and it is what stops a fix
|
|
68
|
-
from becoming a refactor.
|
|
69
|
-
|
|
70
|
-
Then locate it yourself — do not make the human do it. Use the retrieval provider if one is wired,
|
|
71
|
-
else grep for the symptom's strings/identifiers. Read only the files the trail actually names.
|
|
72
|
-
Report the suspected `file:line` in one line and let them confirm or correct it.
|
|
73
|
-
|
|
74
|
-
## 3. Map it onto surfaces — as many as it takes
|
|
75
|
-
|
|
76
|
-
Match the suspected cause and the fix's blast radius against `surfaces[].path`. **A patch is not
|
|
77
|
-
capped at one surface**: a bug that spans an API validator and the form feeding it is one bug with
|
|
78
|
-
one repro, and splitting it into two specs would give each half a contract it doesn't have. List the
|
|
79
|
-
surfaces you're claiming, one line each, with why.
|
|
80
|
-
|
|
81
|
-
**The one escalation that is not a judgment call:** if the fix needs **new** contract surface area —
|
|
82
|
-
a new endpoint, a new shared type, a new field crossing surfaces — stop. That is a feature wearing a
|
|
83
|
-
bug's clothes, and §5 is the only channel that keeps two surfaces in agreement about a shape that
|
|
84
|
-
doesn't exist yet. Say so plainly and send the human to `/cohorte-spec`. Changing an **existing**
|
|
85
|
-
contract entry is fine: describe the delta in §5 and continue.
|
|
86
|
-
|
|
87
|
-
## 4. Freeze the patch spec
|
|
88
|
-
|
|
89
|
-
Write `specs/patch-<slug>.md` from `<core>/templates/patch.template.md` with `status: frozen`, filled
|
|
90
|
-
from §§1–3. **Create the file — do not ask the human to.** Budget: **~60 lines**. A patch spec that
|
|
91
|
-
wants 200 is a feature or a refactor — say which and route it (`/cohorte-spec`, or an item on
|
|
92
|
-
`specs/refactor-backlog.md`).
|
|
93
|
-
|
|
94
|
-
Two sections carry the weight, and both are cheap to get wrong:
|
|
95
|
-
|
|
96
|
-
- **§4 Regression test** — name the test file and what it asserts. It replaces §5 as the thing the
|
|
97
|
-
reviewer checks the diff against, so "add a test" is not enough: say what fails today and why. A
|
|
98
|
-
patch whose test can only be written after the cause is found says exactly that.
|
|
99
|
-
- **§5/§9 keep the feature spec's numbers** (contract delta, acceptance). `review.md` and
|
|
100
|
-
`implementer.template.md` name "contract §5, acceptance §9" verbatim — renumbering them here would
|
|
101
|
-
silently point both agents at the wrong section. The template already does this; don't "fix" it.
|
|
102
|
-
|
|
103
|
-
**Postcondition:** `grep -q '^status: frozen' specs/patch-<slug>.md` — if it fails the freeze didn't
|
|
104
|
-
land; fix it before pointing the human at `/cohorte-build`. Chain the second kanban move onto that
|
|
105
|
-
same Bash call — `kanban-move.sh auto patch-<slug> ready` (the card is already tagged and on the
|
|
106
|
-
board from §1, so this one needs no `--title`) — and report what it printed: `moved #…` or
|
|
107
|
-
`kanban: <reason>`, never a guess.
|
|
108
|
-
|
|
109
|
-
## 5. Hand off
|
|
110
|
-
|
|
111
|
-
Print the spec path, the surfaces, and the branch to cut: `<prefix>patch-<slug>`, where `<prefix>` is
|
|
112
|
-
`vcs.patch_branch_prefix` — falling back to `fix/` on a profile that predates the key. If `isolation.enabled`
|
|
113
|
-
and the fix is big enough to want its own worktree, mention `scripts/new-feature.sh patch-<slug>`;
|
|
114
|
-
most patches don't need it.
|
|
115
|
-
|
|
116
|
-
Then: `/cohorte-build patch-<slug>` — and **recommend a `/clear` first**. The spec is on disk; the
|
|
117
|
-
lead's triage history is re-sent at input price on every turn it survives, and `/cohorte-build`
|
|
118
|
-
re-reads everything it needs.
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
model: sonnet
|
|
3
|
-
description: Apply the refactor backlog for one or more domains via the surface implementer agents (TDD-first, parallel across independent surfaces), then re-verify.
|
|
4
|
-
argument-hint: <domain…> (one or more surface keys, "shared", or "all")
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
You are the **lead**. Refactor domain **$ARGUMENTS** to match `PIPELINE.md`, using the `/cohorte-audit` backlog.
|
|
8
|
-
|
|
9
|
-
> Read `PIPELINE.md` §`surfaces` (map the domain → a surface + its agent + commands) and §`contract`.
|
|
10
|
-
>
|
|
11
|
-
<!-- cohorte:if workflows -->
|
|
12
|
-
> **Workflow variant** (opt-in — SCHEMA.md §Workflows): for BIG domains (many open backlog items
|
|
13
|
-
> across several surfaces), on Claude Code ≥ 2.1.154 with workflows enabled, the human can ask to
|
|
14
|
-
> "run the refactor workflow" (`<core>/workflows/refactor.js`). For a handful of items this
|
|
15
|
-
> conversational path is cheaper — and it stays the default and the fallback.
|
|
16
|
-
<!-- cohorte:endif -->
|
|
17
|
-
|
|
18
|
-
## 1. Gather
|
|
19
|
-
|
|
20
|
-
- Read `specs/refactor-backlog.md`; select the items for `$ARGUMENTS` (`all` = every domain with
|
|
21
|
-
open items).
|
|
22
|
-
- Map each domain to a surface. `shared` = the contract package (`contract.path`), owned by you/lead —
|
|
23
|
-
refactor it directly, don't dispatch.
|
|
24
|
-
|
|
25
|
-
## 2. Dispatch the surface's implementer agent — TDD-first, stateless
|
|
26
|
-
|
|
27
|
-
Spawn the matching `<surface.agent>` with the template below (as `subagent_type: <surface.agent>`).
|
|
28
|
-
Keep it **byte-identical across loop
|
|
29
|
-
rounds** (only the final items slot varies — it sits at the end so repeats hit the prompt cache), and
|
|
30
|
-
never paste a diff — the agent computes its own, scoped to its tree:
|
|
31
|
-
|
|
32
|
-
> "Refactor pass on your surface (no feature spec). Read
|
|
33
|
-
> `PIPELINE.md` first. **Add the missing tests FIRST** (pin current behavior / cover the entry
|
|
34
|
-
> points), watch them pass, **then** refactor to clear each item. Preserve current public behavior
|
|
35
|
-
> unless an item marks it a bug. Migrations stay additive. Need the current state of your tree?
|
|
36
|
-
> Compute it yourself: `git diff <default_branch> -- <surface.path>`. Lint + format before handoff;
|
|
37
|
-
> return the handoff in the format your agent instructions define. Backlog items for YOUR surface
|
|
38
|
-
> (self-contained — clear exactly these, reading only the files they name): <the domain's open
|
|
39
|
-
> `- [ ]` lines verbatim, with exact file paths>."
|
|
40
|
-
|
|
41
|
-
**Parallel when domains are independent:** if the human passed several domains (or `all`), dispatch
|
|
42
|
-
their implementers **concurrently in a single message** — surface trees are disjoint by construction,
|
|
43
|
-
so parallel is safe. Exception: `shared` (the contract package) never joins a parallel batch — the
|
|
44
|
-
slices import it, so refactor it alone, first.
|
|
45
|
-
|
|
46
|
-
- **Preserve current public behavior** unless a finding marks it a bug/convention violation — existing
|
|
47
|
-
code has no contract spec, so don't silently change shapes.
|
|
48
|
-
- Migrations stay **additive**; never `PIPELINE.md` §`gate.deny` commands.
|
|
49
|
-
- Touch only its surface; lint + format before handoff.
|
|
50
|
-
|
|
51
|
-
## 3. Verify & loop
|
|
52
|
-
|
|
53
|
-
After each agent returns: its surface's `test_quiet_cmd`/`lint_quiet_cmd` (else the `tail -40`
|
|
54
|
-
fallback — SCHEMA.md §Output discipline), `commands.typecheck`, `commands.format --check` (redirect
|
|
55
|
-
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
|
|
56
|
-
`/cohorte-audit` per round (that repeats the repo-wide gates + a review dispatch you don't need); one optional
|
|
57
|
-
final `/cohorte-audit` once ALL dispatched domains are clean is enough. Check cleared items off in
|
|
58
|
-
`specs/refactor-backlog.md`. Loop until each dispatched domain is clean. Verification is per-domain
|
|
59
|
-
even when the dispatch was parallel — one failing surface loops alone, the others don't redo work.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Mine the accumulated review findings across features for repeating patterns, and turn the ones the human ratifies into PIPELINE.md §Conventions rules the next build already follows.
|
|
3
|
-
argument-hint: [last <n> | all] (default: every feature with a report on disk)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
You are running the **retrospective**. Every review this pipeline has run left structured
|
|
7
|
-
residue on disk — verdicts, Remediation rounds, deferred backlog items. A finding that shows up
|
|
8
|
-
once is a bug; the same finding shape across features is a **missing rule**, and the pipeline
|
|
9
|
-
has a place for rules the implementers actually read: `PIPELINE.md` §Conventions, baked into
|
|
10
|
-
each surface agent at render time. This command closes that loop: findings → patterns →
|
|
11
|
-
ratified rules → re-rendered agents. The next build then never produces the finding again —
|
|
12
|
-
which is cheaper than any number of review rounds catching it.
|
|
13
|
-
|
|
14
|
-
> Read `PIPELINE.md` §`pipeline-profile` (`surfaces`, and skim the existing §Conventions
|
|
15
|
-
> stanzas — a rule that already exists is a finding about *enforcement*, not a missing rule)
|
|
16
|
-
> and `specs/_decisions.md` §Live. _Skip the re-read if already in context and unmodified._
|
|
17
|
-
|
|
18
|
-
## 1. Collect — mechanical, redirected, no judgment yet
|
|
19
|
-
|
|
20
|
-
Scope: `all` (default), or `last <n>` features by spec mtime. In as few Bash calls as possible,
|
|
21
|
-
**always redirected to `specs/reports/retro-scan.txt` and grepped — never into your context**:
|
|
22
|
-
|
|
23
|
-
- `specs/reports/*.verdict.json` — per feature: `blocking_items` (normalized identities),
|
|
24
|
-
`severity`, per-surface counts. The freshest machine record, one per feature.
|
|
25
|
-
- Every non-`_` spec's `## Remediation` section — the **persistent** history (verdict.json is
|
|
26
|
-
overwritten per round; Remediation accumulates, and collapsed rounds still carry their
|
|
27
|
-
count line). Grep the item lines: `- [x?] <SEVERITY> · <file:line> · <kind> · <fix>`.
|
|
28
|
-
- `specs/refactor-backlog.md` — the `deferred:<id>` tagged items: debt reviews kept finding
|
|
29
|
-
but no feature owned.
|
|
30
|
-
|
|
31
|
-
A repo with fewer than two features' worth of residue ⇒ say the retro has nothing statistical
|
|
32
|
-
to stand on yet, name what exists, and stop — one feature's findings are that feature's story,
|
|
33
|
-
not a pattern.
|
|
34
|
-
|
|
35
|
-
## 2. Patterns — what repeats, with the evidence attached
|
|
36
|
-
|
|
37
|
-
A **pattern** is a finding shape that recurs where recurrence means something:
|
|
38
|
-
|
|
39
|
-
- same `kind` × same surface across **≥ 2 features** (e.g. `security` findings on `backend`
|
|
40
|
-
twice running — the strongest signal there is);
|
|
41
|
-
- the same file/module named by findings from **≥ 2 features** (a hotspot no single fix loop
|
|
42
|
-
owns);
|
|
43
|
-
- the same *fix wording* family recurring (e.g. three "add the authz check" fixes = one
|
|
44
|
-
missing authorization convention);
|
|
45
|
-
- a `deferred:` cluster in one domain — debt the reviews keep re-discovering because no rule
|
|
46
|
-
makes the implementers avoid adding to it.
|
|
47
|
-
|
|
48
|
-
For each pattern, produce: the evidence lines **verbatim** (`<feature> · <severity> · <file> ·
|
|
49
|
-
<problem/fix>`), the count, and ONE drafted convention rule — **rule-shaped**: a sentence an
|
|
50
|
-
implementer can follow and a reviewer can test a diff against, placed under `### Shared` or the
|
|
51
|
-
owning `### Surface: <key>`. Not advice ("be careful with auth") — a rule ("every route under
|
|
52
|
-
`apps/api/src/routes/` calls `authorize()` before its handler; no exceptions without a spec
|
|
53
|
-
§5 note"). Skip any pattern the existing §Conventions already covers — report those separately
|
|
54
|
-
as **enforcement gaps** (the rule exists and reviews keep finding violations: that is input for
|
|
55
|
-
the human, not a new rule).
|
|
56
|
-
|
|
57
|
-
## 3. Ratify — the human picks; nothing lands without them
|
|
58
|
-
|
|
59
|
-
Present a compact table: pattern → evidence count → drafted rule → target stanza. Then **stop
|
|
60
|
-
and ask** which to adopt (all / some / none — none is a fine outcome and says the rulebook fits
|
|
61
|
-
the codebase). Rules are standing law every future dispatch pays tokens to carry: the human
|
|
62
|
-
decides what becomes law, exactly as they freeze specs.
|
|
63
|
-
|
|
64
|
-
## 4. Apply — and keep the baked slices honest
|
|
65
|
-
|
|
66
|
-
For each adopted rule, in this order:
|
|
67
|
-
|
|
68
|
-
1. Append it to `PIPELINE.md` §Conventions under its stanza (create the `### Surface: <key>`
|
|
69
|
-
stanza if absent; keep it rule-shaped, one line each).
|
|
70
|
-
2. **Re-render every affected surface agent** per SCHEMA.md §Rendering step 2 — the
|
|
71
|
-
`<SURFACE_CONVENTIONS>` slice is **baked at render time**, so a §Conventions edit without a
|
|
72
|
-
re-render produces the worst outcome available: reviewers (who read the prose live) enforce
|
|
73
|
-
a rule implementers (who carry the stale bake) have never seen, and every future review
|
|
74
|
-
round re-finds the pattern this retro just paid to close. If you cannot re-render on this
|
|
75
|
-
runtime, say so and route to `/cohorte-update-pipeline` (its reconcile step 2 re-renders) —
|
|
76
|
-
but then the rule is **pending**, and you say that too.
|
|
77
|
-
3. Append ONE line per adopted rule to `specs/_decisions.md` §Live (SCHEMA.md §Decisions):
|
|
78
|
-
`- <date> · conventions · <rule, compressed> — because <kind>×<n> across <features> · retro`.
|
|
79
|
-
A retro rule is a standing decision; the journal is where the next `/cohorte-spec` learns it
|
|
80
|
-
without re-mining the reports.
|
|
81
|
-
|
|
82
|
-
In chat print ONLY: patterns found / adopted / skipped (one line each), enforcement gaps, which
|
|
83
|
-
agents were re-rendered (or the pending route), and the decisions lines appended. The evidence
|
|
84
|
-
stays in `specs/reports/retro-scan.txt`. **Recommend a `/clear`** — everything that matters is
|
|
85
|
-
now in `PIPELINE.md`, the rendered agents, and the journal.
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
model: sonnet
|
|
3
|
-
description: Dispatch the read-only review agent to audit the feature against its frozen spec.
|
|
4
|
-
argument-hint: <feature_id>
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
You are the **lead**. Dispatch the review for feature **$ARGUMENTS**.
|
|
8
|
-
|
|
9
|
-
> Read `PIPELINE.md` §`vcs.default_branch` (diff base) and the `surfaces`/`contract`/`commands` fields.
|
|
10
|
-
> _Skip the re-read if it's already in your context this session and unmodified since._
|
|
11
|
-
>
|
|
12
|
-
> **Kanban** (SCHEMA.md §Kanban): run
|
|
13
|
-
> `<core>/pipeline/scripts/kanban-move.sh auto $ARGUMENTS review`. `auto` resolves the board from the config itself and
|
|
14
|
-
> exits 0 with a `kanban: <reason>` line when there is none — so **never decide "no board is
|
|
15
|
-
> configured" without running it**. _(PR mode — `--pr` below — skips this entirely: an incoming
|
|
16
|
-
> PR is not a pipeline feature and has no card.)_
|
|
17
|
-
>
|
|
18
|
-
<!-- cohorte:if workflows -->
|
|
19
|
-
> **Workflow variant** (opt-in — SCHEMA.md §Workflows): on Claude Code ≥ 2.1.154 with workflows
|
|
20
|
-
> enabled, the human can ask to "run the review workflow" (`<core>/workflows/review.js`) instead.
|
|
21
|
-
> This conversational path stays the default and the fallback; `/cohorte-doctor` shows which is available.
|
|
22
|
-
<!-- cohorte:endif -->
|
|
23
|
-
|
|
24
|
-
## PR mode — review an INCOMING pull request (`--pr <num>` or a PR URL)
|
|
25
|
-
|
|
26
|
-
If `$ARGUMENTS` contains `--pr <num>` (or a GitHub PR URL — extract the number), this is not a
|
|
27
|
-
pipeline feature: it is **someone else's work arriving**, reviewed with the same reviewers and the
|
|
28
|
-
same report format, without pretending it went through the pipeline. What that changes, explicitly:
|
|
29
|
-
**no spec** (nothing to check conformance against — reviewers run in audit mode: conventions +
|
|
30
|
-
correctness + security + TDD coverage only), **no kanban move**, **no verdict.json**, **no DoD
|
|
31
|
-
tick, no freshness stamp, no metrics line** — those certify pipeline features, and this is not one.
|
|
32
|
-
Requires `vcs.host: github` + `gh`; otherwise say so and stop.
|
|
33
|
-
|
|
34
|
-
1. **Fetch into a throwaway worktree — never touch the current checkout.** One Bash call:
|
|
35
|
-
`gh pr view <num> --json title,baseRefName,headRefName,author` (relay the one-line summary), then
|
|
36
|
-
`git fetch -f origin pull/<num>/head:cohorte-pr-<num> <baseRefName> && git worktree add ../<repo>-pr-<num> cohorte-pr-<num>`
|
|
37
|
-
— `-f` so a branch left behind by a crashed earlier run updates instead of failing, and the
|
|
38
|
-
**base ref is fetched too**: the diff below is against `origin/<baseRefName>`, and a stale
|
|
39
|
-
local base blames the PR for every commit it merely hasn't rebased onto yet.
|
|
40
|
-
The human's tree, branch and stamps stay untouched; every later step runs `-C` that worktree.
|
|
41
|
-
2. **Mechanical checks inside the worktree — the commands directly, NEVER `preflight.sh`.** The
|
|
42
|
-
script's whole point is stamping `<state>/preflight.ok` in the MAIN checkout (it resolves
|
|
43
|
-
through `git-common-dir` on purpose), so running it here would overwrite the human's stamp
|
|
44
|
-
with the PR tree's digest — greening pipeline review dispatches of a tree nobody preflighted,
|
|
45
|
-
then blocking them once the worktree is gone. Instead: install dependencies first
|
|
46
|
-
(`commands.install` — a bare `worktree add` has no `node_modules`), then run the profile's
|
|
47
|
-
typecheck/lint-quiet/test-quiet yourself, each appended to the worktree's
|
|
48
|
-
`specs/reports/pr-<num>.preflight.txt`, stopping at the first failure. **Red does NOT get
|
|
49
|
-
reviewers** — same economics as §0 (a reviewer on code that doesn't compile rediscovers what
|
|
50
|
-
`tsc` printed for free) — but unlike §0 it is not an abort: the mechanical failures ARE the
|
|
51
|
-
review (severity CRITICAL, kind `quality`, the failing command + last lines) — jump to
|
|
52
|
-
step 4. An *environmental* failure (install itself failed, a missing service) is reported as
|
|
53
|
-
"not verifiable here", never as a finding against the PR.
|
|
54
|
-
3. **Stage + dispatch — §1's staging procedure and §2's dispatch, minus everything spec-shaped**
|
|
55
|
-
(there is no `specs/<id>.md` to confirm and no small-diff fast path — an unknown author's
|
|
56
|
-
diff always gets a full reviewer), with three substitutions: the diff is
|
|
57
|
-
`git diff origin/<baseRefName>...HEAD` (**three-dot** — only the PR's own commits, not the
|
|
58
|
-
base's drift), staged diffs and file paths are **absolute paths into the worktree**
|
|
59
|
-
(reviewers are stateless — they must not read the main checkout), and the dispatch template's
|
|
60
|
-
spec/contract slots read
|
|
61
|
-
`spec: none (incoming PR — audit mode: PIPELINE.md conventions + quality/security/TDD only,
|
|
62
|
-
skip spec conformance)` · `contract: none`. Roll call + merge per §3 (retry once, `unreviewed`
|
|
63
|
-
forbids a clean verdict), same capped REVIEW REPORT.
|
|
64
|
-
4. **Stage the report to the MAIN checkout's `specs/reports/pr-<num>.md`** (it must outlive the
|
|
65
|
-
worktree), print the verdict + severity table + CRITICAL/security digests in chat. Then —
|
|
66
|
-
**always ask the human first, posting is outward-facing** — offer:
|
|
67
|
-
`gh pr comment <num> --body-file specs/reports/pr-<num>.md` (prefix the body with one line:
|
|
68
|
-
`Automated review — cohorte pipeline (advisory)`). Never post without the explicit go-ahead;
|
|
69
|
-
"no" leaves the report on disk and that is a complete outcome.
|
|
70
|
-
5. **Teardown, always** (also after a red preflight or a dead reviewer):
|
|
71
|
-
`git worktree remove --force ../<repo>-pr-<num> && git branch -D cohorte-pr-<num>`.
|
|
72
|
-
|
|
73
|
-
Everything below this line is the normal pipeline-feature flow.
|
|
74
|
-
|
|
75
|
-
## 0. Deterministic pre-flight — no agents while red
|
|
76
|
-
|
|
77
|
-
Run the profile's mechanical gates in ONE Bash call via the shipped script
|
|
78
|
-
(`<core>/pipeline/scripts/preflight.sh`); note the epoch (`date +%s`) in the same call — §3's
|
|
79
|
-
metrics line needs it:
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
<core>/pipeline/scripts/preflight.sh specs/reports/$ARGUMENTS.preflight.txt \
|
|
83
|
-
"<commands.typecheck>" "<commands.lint_quiet, else lint>" "<commands.test_quiet, else test>"
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- **Non-zero exit** ⇒ the script already printed the raw last-40 lines. **STOP: relay them verbatim
|
|
87
|
-
and spawn NO agent** — a compiler/test failure needs `/cohorte-fix` (or the human), not a review that
|
|
88
|
-
rediscovers it at agent prices. This abort is the whole point of the step. Before stopping, write
|
|
89
|
-
the **aborted verdict** (§3's contract, degraded form) so an automated driver gets a diagnosis
|
|
90
|
-
rather than silence:
|
|
91
|
-
`{"id":"$ARGUMENTS","phase":"review","ts":"<ISO>","aborted":"preflight","verdict":"BLOCK","blocking":null}`
|
|
92
|
-
→ `specs/reports/$ARGUMENTS.verdict.json`. One `printf`, in the same Bash call.
|
|
93
|
-
<!-- cohorte:if hooks -->
|
|
94
|
-
- **Zero exit** ⇒ it stamped `<state>/preflight.ok`, which the gate hook checks before letting
|
|
95
|
-
`review` dispatches through (SCHEMA.md §Preflight). Continue.
|
|
96
|
-
<!-- cohorte:else -->
|
|
97
|
-
- **Zero exit** ⇒ it stamped `<state>/preflight.ok`. Nothing enforces that stamp on this runtime, so
|
|
98
|
-
§2 does not start until you have seen this line: a review of red code is the one failure mode this
|
|
99
|
-
step exists to prevent, and here only you can prevent it (SCHEMA.md §Preflight). Continue.
|
|
100
|
-
<!-- cohorte:endif -->
|
|
101
|
-
- Script absent (older core) ⇒ run the three commands yourself, each redirected into
|
|
102
|
-
`specs/reports/$ARGUMENTS.preflight.txt`, aborting on the first failure the same way.
|
|
103
|
-
|
|
104
|
-
## 1. Gather the inputs for stateless reviewers
|
|
105
|
-
|
|
106
|
-
- Confirm `specs/$ARGUMENTS.md` exists.
|
|
107
|
-
- **Compute the diff ONCE — `--stat` first, patches only for retained surfaces.** One call:
|
|
108
|
-
`git diff <default_branch> --stat > specs/reports/$ARGUMENTS.stat.txt`, then grep that file to
|
|
109
|
-
group the changed paths by `surfaces[].path` prefix (deterministic — don't reason it out file by
|
|
110
|
-
file). Paths under no surface (contract file, root config) are the **`shared` remainder**: attach
|
|
111
|
-
them to the most relevant surface's reviewer and say so in its dispatch. A surface with no changed
|
|
112
|
-
paths gets no reviewer — and no `.diff` is ever generated for it.
|
|
113
|
-
- **Stage the hunks once per touched surface** (reviewers are read-only — no Bash — so the staged
|
|
114
|
-
diff file is the ONLY way they can review hunks instead of re-reading whole files, and staging it
|
|
115
|
-
here means N reviewers never re-run git N times). Regenerated every round:
|
|
116
|
-
`git diff <default_branch> -- <surface.path> > specs/reports/$ARGUMENTS.<surface.key>.diff`
|
|
117
|
-
(same gitignored buffer dir as the reports). For the surface that carries the shared remainder,
|
|
118
|
-
append the remainder pathspecs to its command so its `.diff` includes them. Never print a diff into
|
|
119
|
-
your own context — redirect straight to the file.
|
|
120
|
-
|
|
121
|
-
## 2. Dispatch review agents — one per touched surface, IN PARALLEL
|
|
122
|
-
|
|
123
|
-
Spawn ONE `review` agent per surface that has changed files, in a **single message** (one dispatch
|
|
124
|
-
each, like `/cohorte-build`) so they run concurrently — NEVER serially: review wall-clock must be the
|
|
125
|
-
slowest surface, not the sum. A diff touching a single surface ⇒ a single reviewer.
|
|
126
|
-
|
|
127
|
-
**Small-diff fast path (re-reviews only):** if a surface's staged diff is tiny (≤2 files and ≤~40
|
|
128
|
-
changed lines), touches no contract file, and every open finding it addresses is non-security
|
|
129
|
-
LOW/MEDIUM, skip the dispatch: verify the hunks yourself against the open Remediation items (did the
|
|
130
|
-
prescribed fixes land? — NOT a de-novo audit) and write the same REVIEW REPORT into the §3 flow.
|
|
131
|
-
First-round reviews, contract changes, and security findings always get a full reviewer. For each
|
|
132
|
-
reviewed surface:
|
|
133
|
-
|
|
134
|
-
Keep the dispatch prompt **byte-identical across features and rounds** except the variable block,
|
|
135
|
-
which sits at the END so every repeat hits the prompt-cache prefix:
|
|
136
|
-
|
|
137
|
-
> `subagent_type: review` (or this runtime's equivalent) — "Review one feature surface against its frozen spec. Read `PIPELINE.md`
|
|
138
|
-
> first (flags + the §Conventions/§Testing slice for your scope). Check spec conformance first, then
|
|
139
|
-
> correctness, security, conventions, RBAC/mobile-first _if the profile enables them_, and TDD
|
|
140
|
-
> coverage. Your dispatch names a staged diff file — read it FIRST; open a full source file only when
|
|
141
|
-
> a finding demands it. Emit the REVIEW REPORT in the capped format your agent instructions define —
|
|
142
|
-
> every finding self-sufficient (`file:line` · severity · type · one-line concrete fix), no code
|
|
143
|
-
> excerpts. — Variable slots: feature `$ARGUMENTS` · scope: the `<surface.key>` surface only · spec:
|
|
144
|
-
> `specs/$ARGUMENTS.md` (source of truth) · contract: `<contract.path>/$ARGUMENTS.<ext>` · staged
|
|
145
|
-
> diff: `specs/reports/$ARGUMENTS.<surface.key>.diff` · changed files (`--stat`): <list>."
|
|
146
|
-
|
|
147
|
-
§0's preflight call already gave you the wall-clock start (`date +%s` in the same call) — §3's
|
|
148
|
-
metrics line needs it.
|
|
149
|
-
|
|
150
|
-
## 3. Merge & relay the verdict
|
|
151
|
-
|
|
152
|
-
**Roll call FIRST — a dead reviewer is not a clean surface.** Every surface you dispatched in §2 must
|
|
153
|
-
come back with a REVIEW REPORT. A reviewer that died (rate limit, transport error, exhausted context)
|
|
154
|
-
returns **nothing**, and zero findings from a dead reviewer is byte-identical to zero findings from a
|
|
155
|
-
genuinely clean one — which is how "every reviewer crashed" reads as the strongest possible verdict
|
|
156
|
-
from no evidence at all (SCHEMA.md §Dead agents). So:
|
|
157
|
-
|
|
158
|
-
- **Retry a silent surface ONCE**, byte-identical dispatch. Most deaths are transient, and the staged
|
|
159
|
-
diff is already on disk — the retry costs one agent, not a re-review.
|
|
160
|
-
- **Silent twice ⇒ that surface is `unreviewed`.** Name it in the report under
|
|
161
|
-
`## NOT reviewed (no verdict on these)`, list it in the verdict JSON's `unreviewed`, and **refuse to
|
|
162
|
-
score `SHIP`** — the merged verdict is at least `REVISE`. Absence of evidence is not evidence of
|
|
163
|
-
absence, and it must never reach `/cohorte-ship` or tick a DoD box.
|
|
164
|
-
- **Never re-review the other surfaces** to compensate: their reports are valid and already on disk.
|
|
165
|
-
|
|
166
|
-
Then merge the returned reports into **one** REVIEW REPORT (same template): findings concatenated and
|
|
167
|
-
re-ordered by severity, counts summed, duplicates collapsed, verdict = the worst returned
|
|
168
|
-
(`BLOCK` > `REVISE` > `SHIP`). The `## Deferred` sections merge the same way (dedupe by
|
|
169
|
-
`file` + problem) and stay **out of the severity table and out of the verdict** — see §3.5, which
|
|
170
|
-
routes them. Append ONE metrics line for the batch to the **main checkout's**
|
|
171
|
-
`$(dirname "$(git rev-parse --git-common-dir)")/<state>/pipeline-metrics.jsonl` (rules in
|
|
172
|
-
`/cohorte-build` §4; never a bare relative path — from a worktree that strands the lines): `{"ts":"<ISO>","feature":"$ARGUMENTS","phase":"review","seconds":<wall-clock>,"surfaces":{"<key>":"<verdict>:<finding count>",…}}`.
|
|
173
|
-
**Stage the full report to `specs/reports/$ARGUMENTS.md`** (overwrite) — a gitignored buffer so a
|
|
174
|
-
`/cohorte-fix` after a `/clear` can still read the findings; the `specs/reports/` subfolder is skipped by the
|
|
175
|
-
non-recursive `specs/*.md` glob, so it's never mistaken for a spec (no phantom card, no bogus stage).
|
|
176
|
-
**Write the machine-readable verdict** to `specs/reports/$ARGUMENTS.verdict.json` (overwrite) — on
|
|
177
|
-
**every** run, including the small-diff fast path of §2 and a `SHIP`. This file is the ONLY contract
|
|
178
|
-
between the pipeline and any automated driver, which parses no prose:
|
|
179
|
-
|
|
180
|
-
```json
|
|
181
|
-
{ "id": "$ARGUMENTS", "phase": "review", "ts": "<ISO>", "verdict": "REVISE",
|
|
182
|
-
"findings": 7, "blocking": 2, "security": 1, "deferred": 3, "unreviewed": [],
|
|
183
|
-
"severity": {"CRITICAL": 1, "HIGH": 2, "MEDIUM": 3, "LOW": 1},
|
|
184
|
-
"surfaces": {"backend": {"verdict":"BLOCK","findings":4,"blocking":2}},
|
|
185
|
-
"blocking_items": ["backend|apps/api/src/routes/order.ts|missing authz on post"],
|
|
186
|
-
"fingerprint": "b3f1c2a90d4e5f67" }
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
- **`blocking` = CRITICAL findings + `security` findings, deduplicated** (a finding that is both
|
|
190
|
-
counts once). That is exactly the agent's existing verdict rule restated as a number, so
|
|
191
|
-
`blocking == 0` ⟺ `verdict == SHIP`. HIGH/MEDIUM/LOW quality findings are **not** blocking and
|
|
192
|
-
must never cost a driver an iteration — a *human* routes them in the verdict branch below
|
|
193
|
-
(a `/cohorte-fix` pass, or a deliberate park in the backlog); a driver ignores them.
|
|
194
|
-
- **`blocking_items`** — one normalized string per **distinct** blocking finding (deduplicated —
|
|
195
|
-
two findings sharing surface, file and problem head are one identity), `<surface>|<file>|<problem>`:
|
|
196
|
-
the file path **without the `:line`** (a fix that inserts lines shifts every line below it — a
|
|
197
|
-
line-bearing identity would change every pass and the drift detection would never fire), and the
|
|
198
|
-
**problem**, not the fix, cut to its first 8 words, lowercased, every run of non-alphanumerics
|
|
199
|
-
collapsed to one space. Identity of a finding, not its wording.
|
|
200
|
-
- **`fingerprint`** — computed in the same Bash call, never by hand:
|
|
201
|
-
`printf '%s\n' "<item>" … | LC_ALL=C sort | sha256sum | cut -c1-16` (`shasum -a 256` where there
|
|
202
|
-
is no `sha256sum`). Empty list ⇒ `""`. A driver comparing two consecutive fingerprints detects a
|
|
203
|
-
fix loop that is treading water.
|
|
204
|
-
- **`deferred`** — the count of merged `## Deferred` items §3.5 parked in the backlog. Informational:
|
|
205
|
-
it never enters `blocking`, so it can never cost a driver an iteration.
|
|
206
|
-
- **`unreviewed`** — the surface keys whose reviewer died twice, `[]` on a complete run. It is
|
|
207
|
-
**separate from `blocking` on purpose**: `blocking` counts real findings (CRITICAL + security), and
|
|
208
|
-
faking a number there to force a driver's hand would corrupt the one field the whole contract rests
|
|
209
|
-
on. A non-empty `unreviewed` means "this run does not cover everything" — a driver treats it as no
|
|
210
|
-
usable verdict, never as clean, whatever `blocking` says.
|
|
211
|
-
|
|
212
|
-
## 3.5 Route the deferred findings — the backlog, not the fix loop
|
|
213
|
-
|
|
214
|
-
Do this on **every** run, before the verdict branch below, and whatever the verdict — a deferred
|
|
215
|
-
finding that is only routed on a `SHIP` is a deferred finding lost on every other verdict, which is
|
|
216
|
-
exactly the leak this step closes. Append each merged `## Deferred` item to
|
|
217
|
-
**`specs/refactor-backlog.md`**, under the `## <domain>` heading of the surface that owns its
|
|
218
|
-
`file:line` (create the file and/or heading if absent — same grouping `/cohorte-audit` writes, so
|
|
219
|
-
`/cohorte-refactor <domain>` picks them up with no extra plumbing):
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
- [ ] <SEVERITY> · <file:line> · <quality|security|rule|complexity> · <concrete fix> · deferred:$ARGUMENTS
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
- **Never into the spec's `## Remediation`** — that list is what `/cohorte-fix` re-dispatches, so a
|
|
226
|
-
deferred item there would re-trigger the very fix round it was deferred out of.
|
|
227
|
-
- **Dedupe before appending:** `grep -F` the backlog for the item's `<file>` + the first words of its
|
|
228
|
-
problem; already there (from a prior round or an `/cohorte-audit`) ⇒ skip it, don't stack duplicates round
|
|
229
|
-
after round.
|
|
230
|
-
- Append with `>>` in ONE Bash call; never read the whole backlog into context to rewrite it (it grows
|
|
231
|
-
with every audit the repo has ever run).
|
|
232
|
-
- Report it as **one line** in chat: `deferred: <n> parked in specs/refactor-backlog.md (<domains>)`.
|
|
233
|
-
|
|
234
|
-
In chat print ONLY: the verdict, the severity-count table, a one-line digest of each CRITICAL/security
|
|
235
|
-
finding, and `Full report: specs/reports/$ARGUMENTS.md` — never echo the findings body into chat (it
|
|
236
|
-
would sit in this session's history, re-sent every turn). Then:
|
|
237
|
-
|
|
238
|
-
- **SHIP** → only reachable with `unreviewed` empty (the roll call above forbids it otherwise).
|
|
239
|
-
**Split on what survived — the DoD tick and the freshness stamp are earned by a clean bill, not
|
|
240
|
-
by the verdict alone** (the workflow variant enforces the same rule; certifying surviving
|
|
241
|
-
HIGH/MEDIUM findings for `/cohorte-ship` would ship known defects):
|
|
242
|
-
- **Nothing above LOW survived** — the clean bill. **Tick the DoD**: in `specs/$ARGUMENTS.md`
|
|
243
|
-
§`Acceptance criteria / DoD`, flip each `- [ ]` → `- [x]` for the criteria the pipeline has
|
|
244
|
-
actually verified — spec conformance + `ui_language` copy (this review), tests · lint ·
|
|
245
|
-
typecheck (a green `/cohorte-build`), mobile-first as far as the code shows it (this review).
|
|
246
|
-
**Leave `- [ ]` (and say which) any item no stage actually verified** — nothing in the pipeline
|
|
247
|
-
*runs* the feature, so any criterion that needs the app up (runtime flows, a visual check
|
|
248
|
-
against the design) stays open unless the human says they exercised it by hand and it held.
|
|
249
|
-
Ticking is the lead's job (the reviewer is read-only). **Then stamp the freshness gate** so
|
|
250
|
-
`/cohorte-ship` can refuse to ship code edited after this verdict: compute
|
|
251
|
-
`BASE=$(git merge-base <default_branch> HEAD)` and write into the spec front-matter
|
|
252
|
-
`reviewed_base: $BASE` plus `reviewed_digest: $(git diff $BASE -- . ':(exclude)specs/' | sha256sum | cut -c1-16)`
|
|
253
|
-
(`shasum -a 256` then the first 16 hex chars where there is no `sha256sum` — macOS) — the
|
|
254
|
-
fingerprint of exactly the source you just reviewed (specs excluded, so DoD ticks + the ship
|
|
255
|
-
status flip don't trip it). Park the leftover LOWs through §3.5's exact route (the backlog,
|
|
256
|
-
under their surface's domain heading, tagged `deferred:$ARGUMENTS` — never as open
|
|
257
|
-
`## Remediation` items, which would re-trigger the fix loop). Then tell the human they can
|
|
258
|
-
`/cohorte-ship` — **recommend a `/clear` first**, the handoff is fully on disk.
|
|
259
|
-
- **HIGH or MEDIUM findings survived** — the verdict stays SHIP (they are not blocking), but
|
|
260
|
-
**no DoD tick and no freshness stamp**. Route them: `/cohorte-fix $ARGUMENTS` for what should
|
|
261
|
-
be fixed now; MEDIUMs the human *explicitly* chooses to live with go through §3.5's park
|
|
262
|
-
instead — and once everything left is LOW, apply the clean-bill branch above (tick, stamp,
|
|
263
|
-
ship). The stamp is the pipeline certifying what ships; it is never written over known
|
|
264
|
-
HIGH/MEDIUM defects.
|
|
265
|
-
- **REVISE / BLOCK**, or any CRITICAL/HIGH/security finding → tell the human to run
|
|
266
|
-
**`/cohorte-fix $ARGUMENTS`** — it appends the report to the spec's `## Remediation` and re-dispatches ONLY
|
|
267
|
-
the surfaces with findings. The full path (`/cohorte-spec` Mode B then `/cohorte-build`) remains for findings that
|
|
268
|
-
change the contract in ways that ripple into clean surfaces. _The report is staged to
|
|
269
|
-
`specs/reports/$ARGUMENTS.md`, so you can `/clear` before `/cohorte-fix` — it reads the findings back from
|
|
270
|
-
disk._
|