cohorte 2.0.2 → 2.2.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/CHANGELOG.md +148 -0
- package/README.md +41 -32
- package/bin/cli.js +316 -26
- package/core/adapter/render.js +389 -0
- package/core/agents/implementer.template.md +3 -3
- package/core/agents/release.md +7 -4
- package/core/agents/review.md +10 -2
- package/core/commands/cohorte-audit.md +2 -0
- package/core/commands/cohorte-brainstorm.md +3 -6
- package/core/commands/cohorte-build.md +14 -17
- package/core/commands/cohorte-doctor.md +59 -28
- package/core/commands/cohorte-fix.md +2 -3
- package/core/commands/cohorte-init-pipeline.md +7 -8
- package/core/commands/cohorte-refactor.md +5 -2
- package/core/commands/cohorte-review.md +20 -16
- package/core/commands/cohorte-ship.md +44 -9
- package/core/commands/cohorte-spec.md +3 -7
- package/core/commands/cohorte-update-pipeline.md +8 -8
- package/core/hooks/gate.py +203 -16
- package/core/runtimes/claude.json +73 -0
- package/core/runtimes/codex.json +82 -0
- package/core/runtimes/cursor.json +75 -0
- package/core/runtimes/gemini.json +75 -0
- package/core/runtimes/opencode.json +72 -0
- package/core/templates/spec.template.md +1 -3
- package/core/templates/steps/init-pipeline/01-detect-stack.md +7 -3
- package/core/templates/steps/init-pipeline/02-interview-gaps.md +8 -2
- package/core/templates/steps/init-pipeline/04-write-render.md +23 -17
- package/core/templates/steps/init-pipeline/05-report.md +1 -1
- package/dashboard/dist/assets/{index-P1I1JGtj.js → index-D1rsbLat.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/server/doctor.js +156 -69
- package/dashboard/server/index.js +12 -2
- package/dashboard/server/metrics.js +13 -6
- package/dashboard/server/runtime.js +115 -0
- package/dashboard/server/versions.js +12 -1
- package/install.ps1 +23 -2
- package/install.sh +22 -4
- package/package.json +6 -2
- package/profile/PIPELINE.template.md +27 -6
- package/profile/SCHEMA.md +88 -49
- package/scripts/kanban-move.sh +11 -1
- package/scripts/metrics/collect.mjs +5 -3
- package/scripts/preflight.sh +27 -8
- package/scripts/telemetry-send.sh +10 -3
- package/scripts/test-adapter.mjs +368 -0
- package/scripts/test-dashboard.mjs +70 -0
- package/scripts/test-gate.mjs +62 -0
- package/scripts/validate-core.mjs +1 -1
- package/core/commands/cohorte-loop.md +0 -110
- package/scripts/loop-detach.sh +0 -153
- package/scripts/loop.sh +0 -399
- package/scripts/test-loop.mjs +0 -330
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,154 @@ short, user-facing, most recent first. One `## <version> — <YYYY-MM-DD>` secti
|
|
|
7
7
|
> They are history and are deliberately not rewritten — every command gained a `cohorte-` prefix
|
|
8
8
|
> in 2.0.0.
|
|
9
9
|
|
|
10
|
+
## 2.2.0 — 2026-08-12
|
|
11
|
+
|
|
12
|
+
- **The pipeline was Claude Code or nothing.** The doctrine — frozen spec, stateless surfaces, a
|
|
13
|
+
gate you cannot talk your way past — is not Claude-specific, but every artefact that carried it
|
|
14
|
+
was: `.claude/commands/*.md` with Claude frontmatter, `Task` dispatches, a PreToolUse hook. A
|
|
15
|
+
Codex or Cursor user could read the ideas and reimplement nothing.
|
|
16
|
+
|
|
17
|
+
`core/commands/` and `core/agents/` are now **runtime-neutral sources**, and the installer renders
|
|
18
|
+
them per coding agent — as slash commands, TOML commands, or **Codex skills**
|
|
19
|
+
(`.agents/skills/<name>/SKILL.md`, committed with the repo: custom prompts are deprecated *and*
|
|
20
|
+
user-scoped, so a teammate cloning the repo would have got the profile and none of the commands) —
|
|
21
|
+
for **Claude Code, Codex CLI, Cursor, Gemini CLI, OpenCode**
|
|
22
|
+
(`npx cohorte install --runtime=codex,cursor`, or `--all-runtimes`, or nothing and it detects and
|
|
23
|
+
asks). Rendering rewrites the surface — markdown + the frontmatter keys that runtime understands,
|
|
24
|
+
or TOML for Gemini — resolves every path through the tokens `<core>` / `<state>` / `<agents>` /
|
|
25
|
+
`<config>` / `<memory>`, and swaps the argument placeholder (`$ARGUMENTS`, `{{args}}`, or an
|
|
26
|
+
explicit note where the runtime substitutes nothing, as Cursor does).
|
|
27
|
+
|
|
28
|
+
The part that is not cosmetic: the prompts **branch on what the runtime can enforce**, and say so
|
|
29
|
+
in their own text rather than pretending.
|
|
30
|
+
|
|
31
|
+
**The gate really runs on four of the five.** `gate.py` is registered as a blocking hook in each
|
|
32
|
+
runtime's own format — `PreToolUse` in `settings.json` (Claude) and `.codex/hooks.json` (Codex),
|
|
33
|
+
`beforeShellExecution` in `.cursor/hooks.json`, `BeforeTool` in `.gemini/settings.json` — and
|
|
34
|
+
emits that runtime's envelope, selected by `--runtime <id>`. A verdict in the wrong shape is read
|
|
35
|
+
as *allow* by every one of them, so each dialect is covered by `scripts/test-gate.mjs` rather than
|
|
36
|
+
trusted. **Codex and Gemini have no confirmation tier**, so an `ask` verdict is escalated to
|
|
37
|
+
`deny` with the reason attached: the point of that tier is that a human sees the command first,
|
|
38
|
+
and a runtime that cannot ask cannot deliver it — the same rule unattended headless runs already
|
|
39
|
+
used. The phase gate also learned Gemini's shape, where a subagent arrives as a tool of its own
|
|
40
|
+
name rather than as `Task` + `subagent_type`. OpenCode extends via plugins, not hooks, so there
|
|
41
|
+
the commands call `gate.py --check` themselves: same verdicts, but advisory, and
|
|
42
|
+
`/cohorte-doctor` says so instead of reporting ✅.
|
|
43
|
+
|
|
44
|
+
**Subagents are real everywhere**, in four different file formats — markdown + frontmatter for
|
|
45
|
+
Claude, Cursor, Gemini and OpenCode, TOML with the body under `developer_instructions` for Codex.
|
|
46
|
+
Read-only enforcement for the reviewer is derived from the source agent's tool list and re-emitted
|
|
47
|
+
as each runtime spells it (`readonly: true`, `sandbox_mode = "read-only"`); where there is no
|
|
48
|
+
equivalent, the rendered reviewer carries an explicit instruction that read-only is on it, and
|
|
49
|
+
why. Model pins do **not** travel: the profile names Anthropic aliases, which are meaningless
|
|
50
|
+
elsewhere, so agents inherit the runtime's own model selection.
|
|
51
|
+
|
|
52
|
+
**Real subagents are a requirement, not a capability to degrade around.** A sequential-persona
|
|
53
|
+
fallback shipped mid-development and was removed before release: it asked the lead to simulate the
|
|
54
|
+
isolation boundary by discipline — adopt one agent file, do that surface, drop it — which is not
|
|
55
|
+
the same guarantee, and no supported runtime ever took the branch. A runtime declaring
|
|
56
|
+
`subagents: false` is now refused at install with a named error rather than rendered into a
|
|
57
|
+
pipeline whose central promise is silently absent.
|
|
58
|
+
|
|
59
|
+
- **`/cohorte-loop` is removed, on every runtime including Claude Code.** The autonomous
|
|
60
|
+
build→review→fix driver was the one part of the pipeline tied to a single vendor's headless CLI —
|
|
61
|
+
it spawned `claude -p` children through two shell scripts, a detached `screen` session, a
|
|
62
|
+
`caffeinate` assertion and a resume protocol stamped into spec front-matter. That is a lot of
|
|
63
|
+
surface, on the platform-specific end of the codebase, for a phase the human-driven cycle already
|
|
64
|
+
covers at a cost the loop was mostly there to hide.
|
|
65
|
+
|
|
66
|
+
Gone with it: `scripts/loop.sh`, `scripts/loop-detach.sh`, their test suite, and the
|
|
67
|
+
`loop_pass`/`loop_phase` front-matter fields (dropped from the spec template; still *read* by the
|
|
68
|
+
dashboard so a spec left mid-flight by an older core still explains itself). The installer scrubs
|
|
69
|
+
the command and both scripts on upgrade, in every runtime's layout — copy-over never deletes, and
|
|
70
|
+
a surviving command file is a decoy the model can still fire against a core that no longer ships
|
|
71
|
+
its driver.
|
|
72
|
+
|
|
73
|
+
**The file contract stays.** `verdict.json`, `readiness.json` and `build.json` are still written
|
|
74
|
+
on every run, and the `in-progress`/`blocked` spec statuses stay valid: they are what anything
|
|
75
|
+
automating the cycle from outside reads and writes. Removing the built-in driver does not remove
|
|
76
|
+
the ability to drive it — it removes cohorte's opinion about how.
|
|
77
|
+
|
|
78
|
+
Layout: each runtime gets its own rendered core (`.cohorte/<id>/`), because the same template
|
|
79
|
+
resolves differently per capability — but the **project state is shared** (`.cohorte/`:
|
|
80
|
+
gate-config, preflight stamp, metrics), so a repo driven from two agents cannot disagree with
|
|
81
|
+
itself about what is gated or what has been verified. The user config is shared too; the shipped
|
|
82
|
+
scripts probe `~/.claude` then `~/.cohorte`, so one kanban board and one telemetry consent.
|
|
83
|
+
|
|
84
|
+
**Claude Code is unchanged** — same paths, same frontmatter, same hook, and `scripts/test-adapter.mjs`
|
|
85
|
+
asserts that as a regression test alongside the per-runtime output. `install.sh` / `install.ps1`
|
|
86
|
+
now delegate to the Node CLI: there is no shell renderer, and a raw copy would install prompts
|
|
87
|
+
full of unresolved markers that look installed and instruct the model wrongly.
|
|
88
|
+
|
|
89
|
+
- **A config dir with a space in it broke every tool call in the session.** The gate-hook
|
|
90
|
+
registration quoted the script path only on Windows, so a `CLAUDE_CONFIG_DIR` under
|
|
91
|
+
`~/Library/Application Support/…` — where a desktop host naturally puts it — produced
|
|
92
|
+
`python3 /Users/x/Library/Application Support/…/gate.py`. The shell split that, python reported
|
|
93
|
+
`can't open file '/Users/x/Library/Application'`, and *every* Bash and Task call failed —
|
|
94
|
+
including the ones needed to undo it. Quoted on every platform now, in both the global
|
|
95
|
+
registration and the per-runtime one, with a test that installs into a path containing a space
|
|
96
|
+
and asserts the quoting plus that a re-install still reconciles its own entry instead of
|
|
97
|
+
stacking a second.
|
|
98
|
+
|
|
99
|
+
- **`CLAUDE_CONFIG_DIR` was only half honoured.** The runtime registry declares Claude's paths as
|
|
100
|
+
`~/.claude`, and the adapter resolved them from the homedir — so with the variable set, the core
|
|
101
|
+
was written to the real `~/.claude` while the hook was registered in the overridden dir. A
|
|
102
|
+
scratch or CI install silently wrote into the user's actual global core. `resolvePaths` now
|
|
103
|
+
takes a re-rooting override, and the test asserts the core, the commands and the hook all land
|
|
104
|
+
in the override with nothing written to the home default.
|
|
105
|
+
|
|
106
|
+
- **The dashboard reported a healthy non-Claude install as broken.** Every path it checked was
|
|
107
|
+
`.claude/…`, so a repo driven from Cursor came back "no pipeline core installed", "surface with
|
|
108
|
+
no rendered agent", "artifacts not gitignored", "gate.py not registered" — four findings, all
|
|
109
|
+
false. A false red is worse than no check: it sends someone fixing what is not broken. The
|
|
110
|
+
server now resolves paths from `runtimes.json` (`dashboard/server/runtime.js`), reads the gate
|
|
111
|
+
registration in each runtime's own envelope, names artifacts against the right state dir, reads
|
|
112
|
+
the metrics sink from every state dir in play, skips workflows where there is no engine instead
|
|
113
|
+
of reporting them missing, and the reset action backs up every runtime's directory rather than
|
|
114
|
+
leaving the others behind for the fresh install to land beside.
|
|
115
|
+
|
|
116
|
+
- **`SCHEMA.md` is the agents' rulebook, read at run time — and it still hardcoded `.claude`.**
|
|
117
|
+
It ships to `<core>/pipeline/`, so on a non-Claude install it was telling agents to write
|
|
118
|
+
rendered agents and read the gate config in a directory that runtime never looks at. It and
|
|
119
|
+
`PIPELINE.template.md` now use the same `<core>`/`<state>`/`<agents>`/`<config>` tokens as the
|
|
120
|
+
commands, and the installer resolves their capability conditionals like any other prompt.
|
|
121
|
+
|
|
122
|
+
- **The preflight stamp could green code that had changed.** Both sides of the content digest seed
|
|
123
|
+
a throwaway git index from the real one, for its stat cache — but the copy is stamped `now`, and
|
|
124
|
+
git trusts an entry's cached stat data whenever the entry predates the index file. A file edited
|
|
125
|
+
in the same second as the preflight, at an unchanged size, therefore read as clean: the gate let
|
|
126
|
+
a `review` dispatch through onto code the preflight never verified. Both `gate.py` and
|
|
127
|
+
`preflight.sh` now backdate the copy by 5 s, which forces a content check for anything touched
|
|
128
|
+
inside that window and leaves the fast path intact for every older file.
|
|
129
|
+
|
|
130
|
+
## 2.1.0 — 2026-08-09
|
|
131
|
+
|
|
132
|
+
- **A repo that gates merges on a per-feature release note shipped red PRs, and the flow reported
|
|
133
|
+
success.** Changesets' `changeset` job fails any PR that touches product code without a
|
|
134
|
+
`.changeset/*.md`, but that requirement lives in the project's `CLAUDE.md` — which the ship flow
|
|
135
|
+
never reads. So `/cohorte-ship` committed, pushed, opened the PR and moved the kanban card to
|
|
136
|
+
**Shipped** while the PR was unmergeable, red on a job nobody was watching.
|
|
137
|
+
|
|
138
|
+
The profile gains a `release_notes` block (`enabled`, `tool`, `dir`/`filename`,
|
|
139
|
+
`anchor_package`, `language`, `forbid_levels`, `empty_cmd`, `ci_job`, `guidance` — SCHEMA.md
|
|
140
|
+
§Release notes), and `/cohorte-ship` gains **§2b**: the lead writes the note itself, next to the
|
|
141
|
+
`status: shipped` flip, so it lands *inside* the release commit rather than in a second one after
|
|
142
|
+
the PR is already open. The bump level is project policy, not a git ritual — the release agent is
|
|
143
|
+
now explicitly forbidden from authoring or editing a note, and only stages the one it is handed.
|
|
144
|
+
§4 verifies the note is in the commit; §5 routes a red `ci_job` back to §2b instead of through
|
|
145
|
+
`/cohorte-fix`, which would treat a missing note as a code finding.
|
|
146
|
+
|
|
147
|
+
Two things the block encodes that the tool itself does not: `forbid_levels`, for the `0.x` repo
|
|
148
|
+
where a `major` changeset silently jumps to `1.0.0` with no human deciding it, and the rule to
|
|
149
|
+
**ask** rather than guess between two defensible levels — a wrong bump is a published version
|
|
150
|
+
number, not a fixable draft. `empty_cmd` covers the honest no-op, for a PR that must move no
|
|
151
|
+
version at all.
|
|
152
|
+
|
|
153
|
+
- **Existing projects are asked, not defaulted.** `/cohorte-init-pipeline` detects a versioning tool
|
|
154
|
+
or note-enforcing CI job in Phase 1 and asks the anchor package, language and bump policy in Phase
|
|
155
|
+
2; `/cohorte-update-pipeline` treats `release_notes` as a genuine human decision during reconcile
|
|
156
|
+
rather than topping it up blind. No tool found ⇒ `enabled: false`, and §2b is a silent no-op.
|
|
157
|
+
|
|
10
158
|
## 2.0.2 — 2026-08-08
|
|
11
159
|
|
|
12
160
|
- **Kanban cards stopped moving mid-pipeline, and every stage still reported success.** The
|
package/README.md
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
A **portable, stack-agnostic multi-agent pipeline** for
|
|
17
|
-
|
|
16
|
+
A **portable, stack-agnostic multi-agent pipeline** for your coding agent — Claude Code, Codex CLI,
|
|
17
|
+
Cursor, Gemini CLI or OpenCode. Install it once globally, then one command per project
|
|
18
|
+
(`/cohorte-init-pipeline`) adapts it to that project's stack.
|
|
18
19
|
|
|
19
20
|
- **The dev pipeline** — a human **lead** drives feature work through gated commands, dispatching
|
|
20
21
|
**stateless agents** that only communicate through a frozen contract:
|
|
@@ -39,6 +40,44 @@ The core never hardcodes stack facts. Two mechanisms keep it generic:
|
|
|
39
40
|
2. **Render-at-init** — things that must be in agent frontmatter (name, `tools:`, surface ownership)
|
|
40
41
|
are rendered per **surface** by `/cohorte-init-pipeline` from `implementer.template.md`.
|
|
41
42
|
|
|
43
|
+
## Which coding agent — [full matrix →](https://thebidouilleagency.github.io/cohorte/reference/runtimes)
|
|
44
|
+
|
|
45
|
+
The doctrine is one set of source prompts. The installer renders them into whatever your agent
|
|
46
|
+
actually reads, and branches the instructions on what it can actually do:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
npx cohorte install --runtime=codex,cursor # pick explicitly
|
|
50
|
+
npx cohorte install --all-runtimes # every supported one
|
|
51
|
+
npx cohorte install # detects what you have and asks
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| | Commands | Subagents | Gate | Workflows |
|
|
55
|
+
| --- | --- | --- | --- | --- |
|
|
56
|
+
| **Claude Code** | `.claude/commands/*.md` | ✅ `.claude/agents` | ✅ blocking hook, deny + **ask** | ✅ |
|
|
57
|
+
| **Codex CLI** | `.agents/skills/*/SKILL.md` | ✅ `.codex/agents` (TOML) | ✅ blocking hook, deny only | — |
|
|
58
|
+
| **Cursor** | `.cursor/commands/*.md` | ✅ `.cursor/agents` | ✅ blocking hook, deny + **ask** | — |
|
|
59
|
+
| **Gemini CLI** | `.gemini/commands/*.toml` | ✅ `.gemini/agents` | ✅ blocking hook, deny only | — |
|
|
60
|
+
| **OpenCode** | `.opencode/commands/*.md` | ✅ `.opencode/agents` | advisory `--check` | — |
|
|
61
|
+
|
|
62
|
+
The same `gate.py` is registered as a real blocking hook on four of the five — it speaks each
|
|
63
|
+
runtime's envelope (`PreToolUse`, `beforeShellExecution`, `BeforeTool`). Codex and Gemini have **no
|
|
64
|
+
confirmation tier**, so a pattern that would be queried elsewhere is **denied** there rather than
|
|
65
|
+
falling through; the rendered prompts say so. OpenCode extends via plugins rather than hooks, so
|
|
66
|
+
there the commands call `gate.py --check` themselves — same config and verdicts, but advisory.
|
|
67
|
+
|
|
68
|
+
**Real subagents are a requirement, not a capability to degrade around** — the pipeline's isolation
|
|
69
|
+
guarantee is that boundary, so a runtime without them is refused at install rather than rendered
|
|
70
|
+
into a pipeline whose central promise is absent. All five have them.
|
|
71
|
+
`/cohorte-doctor` reports what the runtime you are in can actually enforce.
|
|
72
|
+
|
|
73
|
+
On Codex the commands ship as **skills** (`$cohorte-build`) rather than custom prompts: prompts are
|
|
74
|
+
deprecated and user-scoped, so a teammate cloning the repo would get the profile but none of the
|
|
75
|
+
commands — `.agents/skills/` is committed with it instead.
|
|
76
|
+
|
|
77
|
+
One thing does not travel: model pins. The profile names Anthropic aliases, meaningless elsewhere,
|
|
78
|
+
so agents inherit the runtime's own model. Claude Code remains the reference implementation and its
|
|
79
|
+
install is unchanged.
|
|
80
|
+
|
|
42
81
|
## Prerequisites
|
|
43
82
|
|
|
44
83
|
Only one hard requirement — the rest is optional and independent:
|
|
@@ -220,7 +259,6 @@ it in `.claude/pipeline/VERSION` and bundled repos in their committed `pipeline.
|
|
|
220
259
|
| `/cohorte-build <id>` | Readiness gate on the frozen spec, then the lead authors the contract and dispatches one implementer per surface in parallel. |
|
|
221
260
|
| `/cohorte-review <id>` | Read-only review agents (one per touched surface, parallel) audit the diff vs the spec; out-of-scope findings go to the refactor backlog. |
|
|
222
261
|
| `/cohorte-fix <id>` | Apply a review report: remediation into the spec, re-dispatch only the surfaces with findings. |
|
|
223
|
-
| `/cohorte-loop <id>` | Autonomous `/cohorte-build → /cohorte-review → /cohorte-fix → /cohorte-review …` until no blocking finding is left (see below). |
|
|
224
262
|
| `/cohorte-ship <id>` | Release agent commits, pushes, opens the PR; watches CI; proposes worktree teardown. |
|
|
225
263
|
| `/cohorte-audit [path]` | Prioritized refactor backlog for existing code. |
|
|
226
264
|
| `/cohorte-refactor <domain>` | Apply the backlog for one surface, TDD-first. |
|
|
@@ -244,35 +282,6 @@ lever: long sessions (>150k) are expensive even when cached. Each command tells
|
|
|
244
282
|
safe to clear. If you'd rather stay in one session, `/compact` mid-task does the lighter version. (Claude
|
|
245
283
|
can't fire `/clear` itself — it's a client-side command; the pipeline just makes it always safe to type.)
|
|
246
284
|
|
|
247
|
-
### Let it run itself — `/cohorte-loop`
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
/cohorte-loop feat-x # /cohorte-build, then /cohorte-review ⇄ /cohorte-fix until clean (max 5 passes)
|
|
251
|
-
/cohorte-loop feat-x --no-build # already built — just re-run the /cohorte-review ⇄ /cohorte-fix loop
|
|
252
|
-
/cohorte-loop feat-x --max=8
|
|
253
|
-
/cohorte-loop feat-x --resume # continue a run that died / hit the ceiling, at the pass it reached
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
It stops when `/cohorte-review` reports **zero blocking findings** (a CRITICAL or a security issue — a LOW
|
|
257
|
-
nit never costs a pass), at the pass ceiling, as soon as two consecutive reviews return the same
|
|
258
|
-
blocking findings (the fix is treading water and more passes won't help), or immediately if `/cohorte-build`'s
|
|
259
|
-
readiness gate says the frozen spec **cannot be built** — that one needs `/cohorte-spec`, not passes. **Each
|
|
260
|
-
fix pass is committed** (`loop(<id>): fix pass <i>`) — that's your way back after N autonomous passes —
|
|
261
|
-
and **no fix runs on the last pass**, since fixing without a review behind it leaves unaudited code.
|
|
262
|
-
|
|
263
|
-
**It's resumable.** Before each phase the driver stamps `status: in-progress` + `loop_pass` +
|
|
264
|
-
`loop_phase` into the spec's front-matter (plain `awk`, zero tokens), and a terminal `in-review` or
|
|
265
|
-
`blocked` on exit. So `--resume` continues at pass 3 instead of re-paying passes 1 and 2 — and the spec
|
|
266
|
-
itself tells you, `/cohorte-doctor` and the dashboard where the loop got to.
|
|
267
|
-
|
|
268
|
-
**The loop does not run in your session.** Each phase is a separate `claude -p` child with its own
|
|
269
|
-
fresh context, driven by `pipeline/scripts/loop.sh`; all of their output goes to
|
|
270
|
-
`specs/reports/<id>.loop.log`, which the command is forbidden to read back. Your session sees one
|
|
271
|
-
line per phase and a three-line summary. That's the whole design: a slash command can't `/clear`
|
|
272
|
-
itself, so a conversational loop would pile the diff plus N review reports plus N contracts into a
|
|
273
|
-
history that is re-sent at input price every turn — it would cost more than the loop saves. The
|
|
274
|
-
machine contract is `specs/reports/<id>.verdict.json`, which `/cohorte-review` now writes on every run; no
|
|
275
|
-
prose is ever parsed.
|
|
276
285
|
|
|
277
286
|
### Run features in parallel — one session per feature
|
|
278
287
|
|