cohorte 1.6.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -2
- package/README.md +57 -57
- package/bin/cli.js +23 -15
- package/core/agents/implementer.template.md +3 -3
- package/core/agents/release.md +1 -1
- package/core/agents/review.md +3 -3
- package/core/commands/{audit.md → cohorte-audit.md} +3 -3
- package/core/commands/{brainstorm.md → cohorte-brainstorm.md} +4 -4
- package/core/commands/{build.md → cohorte-build.md} +15 -15
- package/core/commands/{doctor.md → cohorte-doctor.md} +17 -9
- package/core/commands/{fix.md → cohorte-fix.md} +15 -13
- package/core/commands/{init-pipeline.md → cohorte-init-pipeline.md} +1 -1
- package/core/commands/cohorte-loop.md +110 -0
- package/core/commands/{refactor.md → cohorte-refactor.md} +3 -3
- package/core/commands/{review.md → cohorte-review.md} +20 -19
- package/core/commands/{ship.md → cohorte-ship.md} +5 -5
- package/core/commands/{spec.md → cohorte-spec.md} +13 -13
- package/core/commands/{update-pipeline.md → cohorte-update-pipeline.md} +11 -6
- package/core/hooks/gate.py +101 -6
- package/core/templates/brainstorm-return.md +4 -4
- package/core/templates/decisions.template.md +1 -1
- package/core/templates/design-brief.md +1 -1
- package/core/templates/spec.template.md +7 -7
- package/core/templates/steps/init-pipeline/01-detect-stack.md +1 -1
- package/core/templates/steps/init-pipeline/02-interview-gaps.md +6 -6
- package/core/templates/steps/init-pipeline/03-draft-profile.md +1 -1
- package/core/templates/steps/init-pipeline/04-write-render.md +16 -12
- package/core/templates/steps/init-pipeline/05-report.md +5 -5
- package/core/workflows/audit.js +6 -6
- package/core/workflows/refactor.js +14 -14
- package/core/workflows/review.js +22 -22
- package/dashboard/README.md +2 -2
- package/dashboard/dist/assets/{index-DYyn4p93.js → index-P1I1JGtj.js} +2 -2
- package/dashboard/dist/index.html +1 -1
- package/dashboard/server/doctor.js +69 -19
- package/dashboard/server/index.js +5 -5
- package/dashboard/server/metrics.js +1 -1
- package/install.ps1 +23 -14
- package/install.sh +24 -14
- package/package.json +2 -2
- package/profile/PIPELINE.template.md +17 -16
- package/profile/SCHEMA.md +89 -77
- package/profile/cohorte.config.template.yaml +8 -8
- package/scripts/loop-detach.sh +153 -0
- package/scripts/loop.sh +110 -29
- package/scripts/metrics/collect.mjs +17 -8
- package/scripts/new-feature.sh.template +3 -3
- package/scripts/preflight.sh +40 -4
- package/scripts/remove-feature.sh.template +2 -2
- package/scripts/test-dashboard.mjs +34 -7
- package/scripts/test-gate.mjs +58 -0
- package/scripts/test-loop.mjs +123 -20
- package/scripts/test-metrics.mjs +23 -11
- package/scripts/test-workflows.mjs +7 -7
- package/scripts/validate-core.mjs +45 -23
- package/core/commands/drive.md +0 -80
- /package/core/commands/{align-ds.md → cohorte-align-ds.md} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,122 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
Entries are shown by `/update-pipeline` ("What's new") after a core refresh. Keep them
|
|
4
|
-
user-facing, most recent first. One `## <version> — <YYYY-MM-DD>` section per release.
|
|
3
|
+
Entries are shown by `/cohorte-update-pipeline` ("What's new") after a core refresh. Keep them
|
|
4
|
+
short, user-facing, most recent first. One `## <version> — <YYYY-MM-DD>` section per release.
|
|
5
|
+
|
|
6
|
+
> Sections below 2.0.0 name commands **as they were at the time** (`/build`, `/drive`, `/loop`).
|
|
7
|
+
> They are history and are deliberately not rewritten — every command gained a `cohorte-` prefix
|
|
8
|
+
> in 2.0.0.
|
|
9
|
+
|
|
10
|
+
## 2.0.1 — 2026-08-03
|
|
11
|
+
|
|
12
|
+
Three fixes, one failure: an autonomous `/cohorte-loop` run that built 1 surface of 3, stamped
|
|
13
|
+
itself green, and then hung asking a human to approve its own pre-flight. All in `loop.sh` — no
|
|
14
|
+
repo files change, so `npx cohorte@latest update --global` (or `update`) is the whole migration.
|
|
15
|
+
|
|
16
|
+
- **Child sessions now run in `bypassPermissions`, not `acceptEdits`.** `acceptEdits` auto-approves
|
|
17
|
+
Write/Edit and *nothing else*, so the first `Bash` call no `allow` prefix in `settings.json`
|
|
18
|
+
covers raises a permission prompt — and a `claude -p` child has nobody to answer it. It stalls,
|
|
19
|
+
prints prose asking you to approve, and **exits 0**, which the driver scores as a clean phase.
|
|
20
|
+
That is the whole content of one observed run: the review child blocked on invoking
|
|
21
|
+
`preflight.sh` and the loop logged `▶ /cohorte-review … ok`. It is also backwards from what the
|
|
22
|
+
gate is built for — `hooks/gate.py` escalates every `ask` match to a hard **deny** under
|
|
23
|
+
`bypassPermissions` precisely because an unattended run cannot confirm. So the dangerous commands
|
|
24
|
+
from PIPELINE.md `gate` stay blocked deterministically, while typecheck/lint/tests/`git diff` stop
|
|
25
|
+
needing a human. `CLAUDE_FLAGS` still overrides it for a watched run.
|
|
26
|
+
|
|
27
|
+
- **A build phase that reported nothing is no longer treated as a build that found nothing.** The
|
|
28
|
+
driver checked `dead[]` in `specs/reports/<id>.build.json` but accepted the file being **absent** —
|
|
29
|
+
and a phase cut short never reaches the step that writes it, so there was no file to grep and no
|
|
30
|
+
surface to name while the child still exited 0. A 3-surface build that lost 2 of them mid-write
|
|
31
|
+
stamped `<id>.built` and sent reviewers at the result. A missing `build.json` after a build now
|
|
32
|
+
aborts as **exit 2**, naming the cause, and leaves no stamp so a re-run rebuilds.
|
|
33
|
+
|
|
34
|
+
- **`CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0` is exported for every child.** Print mode otherwise
|
|
35
|
+
*terminates* still-running background tasks at its ceiling ("Background tasks still running after
|
|
36
|
+
600s; terminating") — which is 25–40 min short of a real implementer batch, and killed the two
|
|
37
|
+
surfaces above mid-write. The phase is bounded by its own completion (and by the `caffeinate`
|
|
38
|
+
assertion the driver already holds), not by a stopwatch that fires inside the longest phase.
|
|
39
|
+
|
|
40
|
+
`test-loop.mjs` pins all three, including the fixture bug that hid the second one: its `ready`
|
|
41
|
+
build wrote no `build.json` either.
|
|
42
|
+
|
|
43
|
+
## 2.0.0 — 2026-08-03
|
|
44
|
+
|
|
45
|
+
> **Breaking: every command is renamed.** `/build` → `/cohorte-build`, `/review` →
|
|
46
|
+
> `/cohorte-review`, and so on for all 13. The driver, `/loop` → `/drive` in 1.6.0, is now
|
|
47
|
+
> **`/cohorte-loop`**. Re-run `npx cohorte@latest update --global` (or `update`): the update
|
|
48
|
+
> **deletes** the 13 unprefixed command files from your install rather than leaving them as
|
|
49
|
+
> decoys. Nothing inside your repo needs editing — `/build` in a spec or PIPELINE.md is prose,
|
|
50
|
+
> not a call site. Muscle memory is the only migration cost.
|
|
51
|
+
|
|
52
|
+
- **Every command now carries a `cohorte-` prefix, ending command shadowing for good.** A command
|
|
53
|
+
whose name collides with a Claude Code built-in is not overridden, it is **shadowed**: the
|
|
54
|
+
built-in answers the slash, our file is never read, and the session confidently reports on a run
|
|
55
|
+
that never happened. `/loop` did exactly that and went unnoticed until a user found the driver had
|
|
56
|
+
never started; `/doctor` was sitting on a watchlist waiting to do the same. 1.6.0 renamed one
|
|
57
|
+
name; this replaces the whole approach. `validate-core` now enforces the prefix structurally
|
|
58
|
+
instead of maintaining a blocklist that could only ever forbid the collisions we already knew
|
|
59
|
+
about. Telemetry **phase** names (`build`, `review`, `fix`, …) stay unprefixed — they are a wire
|
|
60
|
+
contract with the collector, and the retired bare command names are kept in the metrics
|
|
61
|
+
collector's retired list so months of existing transcripts stay attributed instead of silently
|
|
62
|
+
reclassifying to `(chat)`.
|
|
63
|
+
|
|
64
|
+
- **`/cohorte-loop` can now run for hours.** It previously ran the driver as one foreground Bash
|
|
65
|
+
call, which cannot work: a single call is capped at **600 s** and a build is 25–40 min, so it was
|
|
66
|
+
killed mid-`/cohorte-build`. Backgrounding it was worse — a backgrounded Bash call is **not
|
|
67
|
+
detached**, so the driver stayed in the calling session's process group and every Claude Code
|
|
68
|
+
restart, crash or laptop sleep took `loop.sh` and its `claude -p` children down with it, mid-write.
|
|
69
|
+
Observed on a real run: four teardowns in 45 minutes, each aborting both surface implementers and
|
|
70
|
+
leaving a half-built tree that read as `dead`. New `loop-detach.sh` puts the driver in its own
|
|
71
|
+
`screen` session so it outlives the launching process entirely, and `/cohorte-loop` polls a small
|
|
72
|
+
status file in ~9-minute waits. The driver's exit code — which the report table is keyed on —
|
|
73
|
+
survives as `__EXIT__ <code>` in that file.
|
|
74
|
+
|
|
75
|
+
- **`loop.sh` holds the machine awake for its whole run.** It re-execs itself under
|
|
76
|
+
`caffeinate -ims` on macOS, `systemd-inhibit` on Linux, because system sleep aborts every
|
|
77
|
+
in-flight `claude -p` request and the abort is byte-identical to "the agent returned nothing" —
|
|
78
|
+
the `dead` family the driver exists to catch. The inhibitor is **probed before the `exec`**, since
|
|
79
|
+
`exec` replaces the shell: one that exists but is refused (`systemd-inhibit` answers `Failed to
|
|
80
|
+
inhibit: Access denied` in a container, in CI, or in any seatless session) would otherwise make its
|
|
81
|
+
own failure the driver's exit code and the run would never start — GitHub's Linux runners turned
|
|
82
|
+
all 24 loop tests red exactly that way. Absent or refused both fall through to a no-op; an unheld
|
|
83
|
+
power assertion is a degraded run, not a failed one, and `test-loop.mjs` now pins both directions.
|
|
84
|
+
**This cannot prevent lid-close sleep** — no userspace assertion can on any platform; keep the
|
|
85
|
+
lid open or use clamshell mode.
|
|
86
|
+
|
|
87
|
+
- **Platform tiers, stated rather than assumed.** Detaching uses `screen` (macOS + Linux), else
|
|
88
|
+
`setsid` (Linux) — both escape the caller's process group, which is what actually matters. Git
|
|
89
|
+
Bash on Windows has neither, so it falls back to `nohup`, which ignores `SIGHUP` but does **not**
|
|
90
|
+
survive a teardown; `loop-detach.sh` prints that warning rather than degrading silently, and
|
|
91
|
+
points at running `loop.sh` from your own terminal instead. See the platform table in
|
|
92
|
+
`docs/reference/scripts.md`.
|
|
93
|
+
|
|
94
|
+
- **Fixed — the preflight stamp is keyed on the code, not on HEAD, and is never versioned.** The
|
|
95
|
+
stamp recorded the HEAD sha, which is the wrong key in both directions: the reviewed tree is
|
|
96
|
+
normally *dirty*, so committing the very code the preflight verified made the gate ask on a clean
|
|
97
|
+
tree, while an implementer editing files between preflight and dispatch invalidated nothing. Worse,
|
|
98
|
+
`.claude/preflight.ok` was never gitignored — once a release agent staged `.claude/`, the stamp
|
|
99
|
+
went into git describing the tree *before* its own commit, so it could never match again: every
|
|
100
|
+
review dispatch in that repo asked "HEAD moved" forever, and every new clone or worktree inherited
|
|
101
|
+
a green it never earned. The stamp is now `<epoch> <sha> <tree digest>`, where the digest is the
|
|
102
|
+
git tree id of the working tree (`.claude` and `specs` excluded, so the pipeline's own report,
|
|
103
|
+
metrics and DoD writes don't invalidate it), computed in a throwaway index that never touches
|
|
104
|
+
yours. Pre-2.0.0 two-field stamps still fall back to the HEAD comparison. `/cohorte-doctor` check 3
|
|
105
|
+
now fails hard on a tracked stamp, `/cohorte-update-pipeline` untracks it and fixes `.gitignore`
|
|
106
|
+
(§Reconcile step 8), and `test-gate.mjs` pins all of it — including "commit the verified code ⇒
|
|
107
|
+
still green" and "one edit ⇒ red".
|
|
108
|
+
|
|
109
|
+
- **`/cohorte-review` and `/cohorte-fix` now spell out the metrics path instead of delegating it.**
|
|
110
|
+
Both said "append a line to `pipeline-metrics.jsonl`" and pointed at `/cohorte-build` §4 for where
|
|
111
|
+
that file lives — a lead running from a feature worktree resolves the bare name against its own
|
|
112
|
+
cwd and strands the batch in a sink that dies at teardown. Both now carry the resolved
|
|
113
|
+
`$(dirname "$(git rev-parse --git-common-dir)")` form inline.
|
|
114
|
+
|
|
115
|
+
- **Fixed — the dashboard's command allowlist had drifted from its own error message.** The
|
|
116
|
+
server accepted the bare `/audit`/`/init-pipeline`/`/update-pipeline` while the UI sent (and the
|
|
117
|
+
error text advertised) the prefixed names, so the run button would have 400'd on the only
|
|
118
|
+
commands that exist. The test suite checked *rejection* only, which is why it passed; it now pins
|
|
119
|
+
both directions.
|
|
5
120
|
|
|
6
121
|
## 1.6.0 — 2026-08-01
|
|
7
122
|
|
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
A **portable, stack-agnostic multi-agent pipeline** for Claude Code. Install it once globally,
|
|
17
|
-
then one command per project (`/init-pipeline`) adapts it to that project's stack.
|
|
17
|
+
then one command per project (`/cohorte-init-pipeline`) adapts it to that project's stack.
|
|
18
18
|
|
|
19
19
|
- **The dev pipeline** — a human **lead** drives feature work through gated commands, dispatching
|
|
20
20
|
**stateless agents** that only communicate through a frozen contract:
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
/brainstorm → /spec → (design) → /build <id> → /review → (/fix) → /ship
|
|
23
|
+
/cohorte-brainstorm → /cohorte-spec → (design) → /cohorte-build <id> → /cohorte-review → (/cohorte-fix) → /cohorte-ship
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## How it works — three layers
|
|
@@ -28,7 +28,7 @@ then one command per project (`/init-pipeline`) adapts it to that project's stac
|
|
|
28
28
|
| Layer | What it holds | Lives in | Scope |
|
|
29
29
|
| --- | --- | --- | --- |
|
|
30
30
|
| **Generic core** | the workflow doctrine: commands, fixed agents, templates, hooks — zero project facts | `~/.claude` (global) — or vendored in a repo's `.claude/` (bundled) | identical everywhere, installed once |
|
|
31
|
-
| **Project profile** | stack, surfaces, commands, conventions, gates | `PIPELINE.md` + rendered surface agents + `gate-config.json`, **committed in each repo** | generated per project by `/init-pipeline` |
|
|
31
|
+
| **Project profile** | stack, surfaces, commands, conventions, gates | `PIPELINE.md` + rendered surface agents + `gate-config.json`, **committed in each repo** | generated per project by `/cohorte-init-pipeline` |
|
|
32
32
|
| **User config** | kanban board links + shared Obsidian vault path | `~/.claude/cohorte.config.yaml` | personal, project-independent |
|
|
33
33
|
|
|
34
34
|
The core never hardcodes stack facts. Two mechanisms keep it generic:
|
|
@@ -37,7 +37,7 @@ The core never hardcodes stack facts. Two mechanisms keep it generic:
|
|
|
37
37
|
`~/.claude/cohorte.config.yaml` (kanban board links + shared vault) at run time — an agent's
|
|
38
38
|
_first action_ is to read its config.
|
|
39
39
|
2. **Render-at-init** — things that must be in agent frontmatter (name, `tools:`, surface ownership)
|
|
40
|
-
are rendered per **surface** by `/init-pipeline` from `implementer.template.md`.
|
|
40
|
+
are rendered per **surface** by `/cohorte-init-pipeline` from `implementer.template.md`.
|
|
41
41
|
|
|
42
42
|
## Prerequisites
|
|
43
43
|
|
|
@@ -48,10 +48,10 @@ Only one hard requirement — the rest is optional and independent:
|
|
|
48
48
|
provider. Install it separately (`uv tool install -p 3.13 serena-agent && uv tool update-shell`); the
|
|
49
49
|
`npx` install neither needs nor touches it, so the order between the two is irrelevant. Without Serena
|
|
50
50
|
the pipeline still runs — agents just fall back to Grep/Read. Having it installed **before**
|
|
51
|
-
`/init-pipeline` lets init wire it in one pass (otherwise `/update-pipeline` wires it later).
|
|
51
|
+
`/cohorte-init-pipeline` lets init wire it in one pass (otherwise `/cohorte-update-pipeline` wires it later).
|
|
52
52
|
- **On a new machine cloning a repo that's already pipeline-ised:** the Serena registration is committed
|
|
53
53
|
in the repo's `.mcp.json` (project scope, portable) — you don't re-wire. Just install the Serena CLI,
|
|
54
|
-
restart the session, and run `/doctor` to confirm it connects.
|
|
54
|
+
restart the session, and run `/cohorte-doctor` to confirm it connects.
|
|
55
55
|
|
|
56
56
|
## Install
|
|
57
57
|
|
|
@@ -66,11 +66,11 @@ own `gate-config.json`:
|
|
|
66
66
|
npx cohorte install --global
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
The per-project part is NOT the core — it's the **profile** `/init-pipeline` generates and you
|
|
69
|
+
The per-project part is NOT the core — it's the **profile** `/cohorte-init-pipeline` generates and you
|
|
70
70
|
commit: `PIPELINE.md`, the rendered surface agents, `gate-config.json`, `settings.json`, `specs/`.
|
|
71
71
|
**That's what makes team work possible in global mode**: everything project-specific travels with the
|
|
72
72
|
repo; each teammate just runs the same global one-liner once, guided by the committed
|
|
73
|
-
`.claude/pipeline.json` pointer (core version + install command) that `/init-pipeline` writes.
|
|
73
|
+
`.claude/pipeline.json` pointer (core version + install command) that `/cohorte-init-pipeline` writes.
|
|
74
74
|
|
|
75
75
|
<details>
|
|
76
76
|
<summary><strong>Alternative: per-project (bundled)</strong> — vendor the core into the repo itself.</summary>
|
|
@@ -109,13 +109,13 @@ published semver. Both land in `.claude/pipeline/VERSION` and the `pipeline.json
|
|
|
109
109
|
</details>
|
|
110
110
|
|
|
111
111
|
> **After installing (or updating): restart Claude Code / start a new session.** Slash commands and
|
|
112
|
-
> agents are scanned at session start — in an already-open session the new `/init-pipeline`,
|
|
113
|
-
> `/build`, etc. won't appear until you reload. This is the #1 "the install didn't work" trap.
|
|
112
|
+
> agents are scanned at session start — in an already-open session the new `/cohorte-init-pipeline`,
|
|
113
|
+
> `/cohorte-build`, etc. won't appear until you reload. This is the #1 "the install didn't work" trap.
|
|
114
114
|
|
|
115
115
|
Then, in Claude Code (from any repo, once the core is installed either way):
|
|
116
116
|
|
|
117
117
|
```
|
|
118
|
-
/init-pipeline
|
|
118
|
+
/cohorte-init-pipeline
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
It **detects** your stack (package manager, workspaces, frameworks, test runners, linters, git remote,
|
|
@@ -132,9 +132,9 @@ design system), **interviews** you for the gaps, and **generates**:
|
|
|
132
132
|
profile's `retrieval.provider`)
|
|
133
133
|
- `scripts/new-feature.sh` + `remove-feature.sh` — parallel worktree isolation (if you enable it)
|
|
134
134
|
- `specs/_template.md` (and, on first decision, `specs/_decisions.md` — the project's one-line-per-decision
|
|
135
|
-
journal, read by `/brainstorm`, `/spec` and `/audit` so features stop re-litigating settled ground)
|
|
135
|
+
journal, read by `/cohorte-brainstorm`, `/cohorte-spec` and `/cohorte-audit` so features stop re-litigating settled ground)
|
|
136
136
|
|
|
137
|
-
Sanity-check `PIPELINE.md`, commit it, and run `/brainstorm`.
|
|
137
|
+
Sanity-check `PIPELINE.md`, commit it, and run `/cohorte-brainstorm`.
|
|
138
138
|
|
|
139
139
|
## Update
|
|
140
140
|
|
|
@@ -149,12 +149,12 @@ The installer refreshes the generic core (commands, hook, templates) **without**
|
|
|
149
149
|
`PIPELINE.md`, rendered agents, `gate-config.json`, `settings.json`, or your filled
|
|
150
150
|
`~/.claude/cohorte.config.yaml`.
|
|
151
151
|
|
|
152
|
-
From inside Claude Code, prefer **`/update-pipeline`**: it runs the right update invocation for your
|
|
152
|
+
From inside Claude Code, prefer **`/cohorte-update-pipeline`**: it runs the right update invocation for your
|
|
153
153
|
install scope, reports `old → new` — and then **reconciles the repo's generated files to the new
|
|
154
154
|
core**: new profile fields are added at their defaults (you're only asked for genuinely new
|
|
155
155
|
decisions), surface agents are re-rendered, settings are patched additively, new capabilities get
|
|
156
|
-
wired. **`/init-pipeline` is one-time per project** — after init, `/update-pipeline` is the only
|
|
157
|
-
maintenance command you ever run (`/build` auto-grows surfaces as specs need them).
|
|
156
|
+
wired. **`/cohorte-init-pipeline` is one-time per project** — after init, `/cohorte-update-pipeline` is the only
|
|
157
|
+
maintenance command you ever run (`/cohorte-build` auto-grows surfaces as specs need them).
|
|
158
158
|
|
|
159
159
|
## Dashboard — a local web cockpit
|
|
160
160
|
|
|
@@ -167,7 +167,7 @@ npx cohorte dashboard --port=4400 --open # custom port, open the browser
|
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
**Bound to `127.0.0.1` by default** — the dashboard's actions execute code (install/update/reset,
|
|
170
|
-
and `/init-pipeline`·`/update-pipeline`·`/audit` via headless Claude), so it must stay on loopback. Each user
|
|
170
|
+
and `/cohorte-init-pipeline`·`/cohorte-update-pipeline`·`/cohorte-audit` via headless Claude), so it must stay on loopback. Each user
|
|
171
171
|
runs their own agent and drives only their own machine. `--host=0.0.0.0` exposes it to the network
|
|
172
172
|
(it prints a security warning) — only on a trusted network, since anyone who reaches the port can run
|
|
173
173
|
those actions.
|
|
@@ -175,7 +175,7 @@ those actions.
|
|
|
175
175
|
- **Fleet overview** — the global core version vs npm latest, plus every tracked project's freshness
|
|
176
176
|
and health at a glance. Add a project by absolute path or with the **folder picker** (Browse…); the
|
|
177
177
|
set is remembered in `~/.claude/cohorte-dashboard.json`.
|
|
178
|
-
- **Per-project drill-down** — Freshness (installed core vs npm), `/doctor` rendered as a live
|
|
178
|
+
- **Per-project drill-down** — Freshness (installed core vs npm), `/cohorte-doctor` rendered as a live
|
|
179
179
|
✅/⚠️/❌ checklist (each failure with its fix), the **Surfaces ↔ agents** map from `PIPELINE.md`,
|
|
180
180
|
and one board: a **Kanban** if the project has a linked Obsidian board (columns + cards from the
|
|
181
181
|
vault, with clickable PR links + live open/merged/closed status and a ship-date-sorted Shipped
|
|
@@ -191,7 +191,7 @@ those actions.
|
|
|
191
191
|
**workflows** state (scripts + profile-reader installed, which path a session will take).
|
|
192
192
|
|
|
193
193
|
Runtime is **dependency-free** — node's built-in `http` server serves a prebuilt React app (the app
|
|
194
|
-
source lives in `dashboard/app/`, built to `dashboard/dist/` at publish time). The `/doctor` checks
|
|
194
|
+
source lives in `dashboard/app/`, built to `dashboard/dist/` at publish time). The `/cohorte-doctor` checks
|
|
195
195
|
are reimplemented in JS, so the dashboard needs no Claude session to compute state. See
|
|
196
196
|
[`dashboard/README.md`](dashboard/README.md) for the architecture.
|
|
197
197
|
|
|
@@ -214,29 +214,29 @@ it in `.claude/pipeline/VERSION` and bundled repos in their committed `pipeline.
|
|
|
214
214
|
|
|
215
215
|
| Command | Role |
|
|
216
216
|
| -------------------- | ------------------------------------------------------------------------------------- |
|
|
217
|
-
| `/init-pipeline` | Detect stack → interview → generate the profile + agents. Run once per project. |
|
|
218
|
-
| `/brainstorm` | Interactive persona panel that pressure-tests a feature idea. |
|
|
219
|
-
| `/spec` | Freeze the feature spec + contract into `specs/<id>.md` (UI features also get a standalone design brief at `specs/design/<id>.md`). Also applies review returns. |
|
|
220
|
-
| `/build <id>` | Readiness gate on the frozen spec, then the lead authors the contract and dispatches one implementer per surface in parallel. |
|
|
221
|
-
| `/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
|
-
| `/fix <id>` | Apply a review report: remediation into the spec, re-dispatch only the surfaces with findings. |
|
|
223
|
-
| `/
|
|
224
|
-
| `/ship <id>` | Release agent commits, pushes, opens the PR; watches CI; proposes worktree teardown. |
|
|
225
|
-
| `/audit [path]` | Prioritized refactor backlog for existing code. |
|
|
226
|
-
| `/refactor <domain>` | Apply the backlog for one surface, TDD-first. |
|
|
227
|
-
| `/align-ds` | Align the code UI kit to the design system (no-op if none configured). |
|
|
228
|
-
| `/update-pipeline` | Refresh the installed core (global or bundled) to the latest published version. |
|
|
229
|
-
| `/doctor` | Diagnose the installation (core, agents↔surfaces, hooks, gate, retrieval, worktrees). |
|
|
217
|
+
| `/cohorte-init-pipeline` | Detect stack → interview → generate the profile + agents. Run once per project. |
|
|
218
|
+
| `/cohorte-brainstorm` | Interactive persona panel that pressure-tests a feature idea. |
|
|
219
|
+
| `/cohorte-spec` | Freeze the feature spec + contract into `specs/<id>.md` (UI features also get a standalone design brief at `specs/design/<id>.md`). Also applies review returns. |
|
|
220
|
+
| `/cohorte-build <id>` | Readiness gate on the frozen spec, then the lead authors the contract and dispatches one implementer per surface in parallel. |
|
|
221
|
+
| `/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
|
+
| `/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
|
+
| `/cohorte-ship <id>` | Release agent commits, pushes, opens the PR; watches CI; proposes worktree teardown. |
|
|
225
|
+
| `/cohorte-audit [path]` | Prioritized refactor backlog for existing code. |
|
|
226
|
+
| `/cohorte-refactor <domain>` | Apply the backlog for one surface, TDD-first. |
|
|
227
|
+
| `/cohorte-align-ds` | Align the code UI kit to the design system (no-op if none configured). |
|
|
228
|
+
| `/cohorte-update-pipeline` | Refresh the installed core (global or bundled) to the latest published version. |
|
|
229
|
+
| `/cohorte-doctor` | Diagnose the installation (core, agents↔surfaces, hooks, gate, retrieval, worktrees). |
|
|
230
230
|
|
|
231
231
|
### Run the loop cheaply — `/clear` between stages
|
|
232
232
|
|
|
233
233
|
Every command reloads all the state it needs **from disk** — the frozen spec, the contract, the diff, the
|
|
234
|
-
Remediation checkboxes, the freshness stamp, and the last `/review` report (staged to a gitignored
|
|
234
|
+
Remediation checkboxes, the freshness stamp, and the last `/cohorte-review` report (staged to a gitignored
|
|
235
235
|
`specs/reports/<id>.md`). Nothing essential lives in the conversation. So the loop is **`/clear`-safe at
|
|
236
236
|
every boundary**:
|
|
237
237
|
|
|
238
238
|
```
|
|
239
|
-
/spec → /clear → /build → /clear → /review → /clear → /fix → /clear → /review → /ship
|
|
239
|
+
/cohorte-spec → /clear → /cohorte-build → /clear → /cohorte-review → /clear → /cohorte-fix → /clear → /cohorte-review → /cohorte-ship
|
|
240
240
|
```
|
|
241
241
|
|
|
242
242
|
`/clear`-ing between stages sheds the accumulated main-thread context, which is the single biggest token
|
|
@@ -244,26 +244,26 @@ lever: long sessions (>150k) are expensive even when cached. Each command tells
|
|
|
244
244
|
safe to clear. If you'd rather stay in one session, `/compact` mid-task does the lighter version. (Claude
|
|
245
245
|
can't fire `/clear` itself — it's a client-side command; the pipeline just makes it always safe to type.)
|
|
246
246
|
|
|
247
|
-
### Let it run itself — `/
|
|
247
|
+
### Let it run itself — `/cohorte-loop`
|
|
248
248
|
|
|
249
249
|
```
|
|
250
|
-
/
|
|
251
|
-
/
|
|
252
|
-
/
|
|
253
|
-
/
|
|
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
254
|
```
|
|
255
255
|
|
|
256
|
-
It stops when `/review` reports **zero blocking findings** (a CRITICAL or a security issue — a LOW
|
|
256
|
+
It stops when `/cohorte-review` reports **zero blocking findings** (a CRITICAL or a security issue — a LOW
|
|
257
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 `/build`'s
|
|
259
|
-
readiness gate says the frozen spec **cannot be built** — that one needs `/spec`, not passes. **Each
|
|
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
260
|
fix pass is committed** (`loop(<id>): fix pass <i>`) — that's your way back after N autonomous passes —
|
|
261
261
|
and **no fix runs on the last pass**, since fixing without a review behind it leaves unaudited code.
|
|
262
262
|
|
|
263
263
|
**It's resumable.** Before each phase the driver stamps `status: in-progress` + `loop_pass` +
|
|
264
264
|
`loop_phase` into the spec's front-matter (plain `awk`, zero tokens), and a terminal `in-review` or
|
|
265
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, `/doctor` and the dashboard where the loop got to.
|
|
266
|
+
itself tells you, `/cohorte-doctor` and the dashboard where the loop got to.
|
|
267
267
|
|
|
268
268
|
**The loop does not run in your session.** Each phase is a separate `claude -p` child with its own
|
|
269
269
|
fresh context, driven by `pipeline/scripts/loop.sh`; all of their output goes to
|
|
@@ -271,7 +271,7 @@ fresh context, driven by `pipeline/scripts/loop.sh`; all of their output goes to
|
|
|
271
271
|
line per phase and a three-line summary. That's the whole design: a slash command can't `/clear`
|
|
272
272
|
itself, so a conversational loop would pile the diff plus N review reports plus N contracts into a
|
|
273
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 `/review` now writes on every run; no
|
|
274
|
+
machine contract is `specs/reports/<id>.verdict.json`, which `/cohorte-review` now writes on every run; no
|
|
275
275
|
prose is ever parsed.
|
|
276
276
|
|
|
277
277
|
### Run features in parallel — one session per feature
|
|
@@ -279,16 +279,16 @@ prose is ever parsed.
|
|
|
279
279
|
With `isolation.enabled`, every feature already gets its own worktree, ports, and database
|
|
280
280
|
(`scripts/new-feature.sh <id>` — slots tracked in `.worktrees/slots.tsv`). That isolation is exactly
|
|
281
281
|
what makes **parallel features** safe, and it's the real throughput multiplier when you're rate-limited:
|
|
282
|
-
while feature A's `/build` runs its agents (minutes of wall-clock you'd otherwise spend waiting), a
|
|
283
|
-
second Claude Code session can `/spec` or `/review` feature B.
|
|
282
|
+
while feature A's `/cohorte-build` runs its agents (minutes of wall-clock you'd otherwise spend waiting), a
|
|
283
|
+
second Claude Code session can `/cohorte-spec` or `/cohorte-review` feature B.
|
|
284
284
|
|
|
285
285
|
The pattern:
|
|
286
286
|
|
|
287
287
|
```
|
|
288
|
-
session 1 (main checkout): /spec feat-a → /build feat-a (agents run…)
|
|
289
|
-
session 2 (main checkout): /spec feat-b → /build feat-b (agents run…)
|
|
290
|
-
session 1: /review feat-a → /ship feat-a
|
|
291
|
-
session 2: /review feat-b → …
|
|
288
|
+
session 1 (main checkout): /cohorte-spec feat-a → /cohorte-build feat-a (agents run…)
|
|
289
|
+
session 2 (main checkout): /cohorte-spec feat-b → /cohorte-build feat-b (agents run…)
|
|
290
|
+
session 1: /cohorte-review feat-a → /cohorte-ship feat-a
|
|
291
|
+
session 2: /cohorte-review feat-b → …
|
|
292
292
|
```
|
|
293
293
|
|
|
294
294
|
Rules that make it safe:
|
|
@@ -301,10 +301,10 @@ Rules that make it safe:
|
|
|
301
301
|
- **The contract package is the one shared tree.** Two features editing
|
|
302
302
|
`<contract.path>/<their-own-id>.<ext>` never conflict (one file per feature); merge order only
|
|
303
303
|
matters if a later feature *imports* an earlier one's contract — ship the dependency first.
|
|
304
|
-
- `/ship` one at a time: it commits from the feature's branch and the freshness gate keeps a stale
|
|
304
|
+
- `/cohorte-ship` one at a time: it commits from the feature's branch and the freshness gate keeps a stale
|
|
305
305
|
verdict from shipping; after each merge, rebase the other live worktrees (`git rebase main`) so
|
|
306
306
|
their eventual reviews diff against reality.
|
|
307
|
-
- `/doctor` check 6 shows the live slot table (feature ↔ worktree ↔ ports) when you lose track.
|
|
307
|
+
- `/cohorte-doctor` check 6 shows the live slot table (feature ↔ worktree ↔ ports) when you lose track.
|
|
308
308
|
|
|
309
309
|
### Workflows — deterministic multi-agent runs (opt-in)
|
|
310
310
|
|
|
@@ -323,7 +323,7 @@ The essentials:
|
|
|
323
323
|
- **The conversational commands stay the default path** — and the fallback when workflows are
|
|
324
324
|
disabled or the client is too old. A workflow runs only when you explicitly ask for it
|
|
325
325
|
("run the review workflow").
|
|
326
|
-
- **Prerequisite: Claude Code ≥ 2.1.154** with workflows enabled. `/doctor` (check 8) tells you
|
|
326
|
+
- **Prerequisite: Claude Code ≥ 2.1.154** with workflows enabled. `/cohorte-doctor` (check 8) tells you
|
|
327
327
|
which path your session will take and why.
|
|
328
328
|
- **No input mid-run — questions at the edges.** A workflow runs to completion without asking
|
|
329
329
|
anything: whatever would have been a mid-run question lands in the result at the end. The
|
|
@@ -339,9 +339,9 @@ Details: `profile/SCHEMA.md` §Workflows.
|
|
|
339
339
|
|
|
340
340
|
Cohorte can send **anonymous** usage pings (core version, OS, phase name, duration, per-surface
|
|
341
341
|
result counts, and a *hash* of the feature id — never repo names, paths, code, or IPs). It is
|
|
342
|
-
**strictly opt-in**: `/init-pipeline` asks once per machine, the default is No, and both answers are
|
|
342
|
+
**strictly opt-in**: `/cohorte-init-pipeline` asks once per machine, the default is No, and both answers are
|
|
343
343
|
recorded so you're never re-asked. Withdraw anytime (`telemetry.enabled: false` in
|
|
344
|
-
`~/.claude/cohorte.config.yaml`); erase your history anytime (`/doctor` prints your `install_id`,
|
|
344
|
+
`~/.claude/cohorte.config.yaml`); erase your history anytime (`/cohorte-doctor` prints your `install_id`,
|
|
345
345
|
the collector's `DELETE /v1/install/<id>` drops it). Full spec + GDPR details:
|
|
346
346
|
`profile/SCHEMA.md` §Telemetry (including the collector API contract).
|
|
347
347
|
|
|
@@ -363,12 +363,12 @@ install.sh # script installer (fresh + --update) for no-Node enviro
|
|
|
363
363
|
install.ps1 # same installer for Windows PowerShell (fresh + -Update)
|
|
364
364
|
core/ # copied verbatim into ~/.claude (global) or <project>/.claude (bundled)
|
|
365
365
|
agents/ # implementer.template.md (rendered per surface) + review / release / profile-reader
|
|
366
|
-
commands/ # init-pipeline + the pipeline commands + /update-pipeline
|
|
366
|
+
commands/ # init-pipeline + the pipeline commands + /cohorte-update-pipeline
|
|
367
367
|
hooks/ # gate.py (destructive-command gate; branch-aware; preflight phase gate)
|
|
368
368
|
templates/ # handoff / brainstorm-return / design-brief / review-feedback / pr-body / spec
|
|
369
369
|
workflows/ # opt-in Workflow-runtime scripts: review.js / audit.js / refactor.js
|
|
370
370
|
profile/
|
|
371
|
-
PIPELINE.template.md # the profile skeleton /init-pipeline fills
|
|
371
|
+
PIPELINE.template.md # the profile skeleton /cohorte-init-pipeline fills
|
|
372
372
|
SCHEMA.md # field reference
|
|
373
373
|
cohorte.config.template.yaml # seeds ~/.claude/cohorte.config.yaml (kanban)
|
|
374
374
|
scripts/ # worktree-isolation templates + shipped preflight/kanban/telemetry scripts
|
package/bin/cli.js
CHANGED
|
@@ -45,7 +45,7 @@ Commands:
|
|
|
45
45
|
update Refresh the stack-agnostic core only. PIPELINE.md, rendered surface
|
|
46
46
|
agents, gate-config.json, settings.json and your filled
|
|
47
47
|
~/.claude/cohorte.config.yaml are never touched.
|
|
48
|
-
dashboard Serve a local web cockpit for the pipeline (freshness, /doctor
|
|
48
|
+
dashboard Serve a local web cockpit for the pipeline (freshness, /cohorte-doctor
|
|
49
49
|
health, specs board, install/update actions). Binds 127.0.0.1:4317
|
|
50
50
|
by default (loopback only — its actions execute code). --host=ADDR
|
|
51
51
|
to expose (e.g. --host=0.0.0.0, prints a security warning). --open
|
|
@@ -163,7 +163,7 @@ function copyCore() {
|
|
|
163
163
|
// every caller chains them with `|| true`, the result was silent: no kanban card
|
|
164
164
|
// moves, no telemetry pings, no error. The shell installers named them explicitly
|
|
165
165
|
// and this port drifted. The rule below needs no list to keep in sync: a `<x>.sh`
|
|
166
|
-
// with an `<x>.sh.template` sibling is rendered per-project by /init-pipeline, so
|
|
166
|
+
// with an `<x>.sh.template` sibling is rendered per-project by /cohorte-init-pipeline, so
|
|
167
167
|
// only the template ships; every other `.sh` is a shipped executable.
|
|
168
168
|
const scriptFiles = fs.readdirSync(path.join(src, 'scripts'));
|
|
169
169
|
for (const f of scriptFiles) {
|
|
@@ -178,7 +178,7 @@ function copyCore() {
|
|
|
178
178
|
}
|
|
179
179
|
fs.copyFileSync(path.join(src, 'core', 'agents', 'implementer.template.md'),
|
|
180
180
|
path.join(pipelineDir, 'implementer.template.md'));
|
|
181
|
-
// /doctor reads this to tell the human what they're missing; the shell installers
|
|
181
|
+
// /cohorte-doctor reads this to tell the human what they're missing; the shell installers
|
|
182
182
|
// have always copied it, this port never did.
|
|
183
183
|
const changelog = path.join(src, 'CHANGELOG.md');
|
|
184
184
|
if (fs.existsSync(changelog)) fs.copyFileSync(changelog, path.join(pipelineDir, 'CHANGELOG.md'));
|
|
@@ -211,7 +211,7 @@ function scrubTddGate() {
|
|
|
211
211
|
// the fixed (non-rendered) agents: the dev review/release pipeline agents
|
|
212
212
|
function copyFixedAgents() {
|
|
213
213
|
fs.mkdirSync(path.join(dest, 'agents'), { recursive: true });
|
|
214
|
-
// Every agent in core/agents/ EXCEPT the *.template.md ones, which /init-pipeline renders
|
|
214
|
+
// Every agent in core/agents/ EXCEPT the *.template.md ones, which /cohorte-init-pipeline renders
|
|
215
215
|
// per-surface. Until 1.2.6 this was a hardcoded ['review.md', 'release.md'] that never grew
|
|
216
216
|
// the agents the shell installers copy, so `npx cohorte install` shipped a command with no
|
|
217
217
|
// agent to dispatch — the run reported the command as not installed.
|
|
@@ -235,6 +235,14 @@ function copyFixedAgents() {
|
|
|
235
235
|
// 1.6.0 renamed /loop → /drive: Claude Code's own built-in /loop shadowed ours, so a leftover
|
|
236
236
|
// commands/loop.md is a command the user can never reach — scrub it rather than leave a decoy.
|
|
237
237
|
fs.rmSync(path.join(dest, 'commands', 'loop.md'), { force: true });
|
|
238
|
+
// 2.0.0 prefixed every command with `cohorte-`, which ends the shadowing problem for good.
|
|
239
|
+
// Copy-over never deletes, so all 13 bare names would survive an upgrade as decoys — and a
|
|
240
|
+
// stale /build is the worst kind: it still dispatches implementers, from a 1.x command file
|
|
241
|
+
// that knows nothing of this core's contract. /drive goes too (it became /cohorte-loop).
|
|
242
|
+
for (const c of ['align-ds', 'audit', 'brainstorm', 'build', 'doctor', 'drive', 'fix',
|
|
243
|
+
'init-pipeline', 'refactor', 'review', 'ship', 'spec', 'update-pipeline']) {
|
|
244
|
+
fs.rmSync(path.join(dest, 'commands', `${c}.md`), { force: true });
|
|
245
|
+
}
|
|
238
246
|
scrubResearchQuestionnaire();
|
|
239
247
|
}
|
|
240
248
|
|
|
@@ -279,10 +287,10 @@ function setCfg(text, cfgKey, value) {
|
|
|
279
287
|
}
|
|
280
288
|
|
|
281
289
|
// Fill the seeded config from a short TTY interview (shared Obsidian vault for the kanban mirror).
|
|
282
|
-
// Kanban is per-project, so it is wired later by /init-pipeline — not asked here.
|
|
290
|
+
// Kanban is per-project, so it is wired later by /cohorte-init-pipeline — not asked here.
|
|
283
291
|
async function promptConfig(text) {
|
|
284
292
|
console.log('\n Quick setup (Enter to skip — you can also wire this later via');
|
|
285
|
-
console.log(' /init-pipeline or /update-pipeline):');
|
|
293
|
+
console.log(' /cohorte-init-pipeline or /cohorte-update-pipeline):');
|
|
286
294
|
const vault = await ask(' · absolute path to your shared Obsidian vault (for the kanban mirror): ');
|
|
287
295
|
if (vault) text = setCfg(text, 'vault_path', `"${vault}"`);
|
|
288
296
|
return text;
|
|
@@ -299,7 +307,7 @@ async function seedConfig() {
|
|
|
299
307
|
if (fs.existsSync(cfg)) { console.log(` · kept your existing ${cfg}`); return; }
|
|
300
308
|
if (legacy) {
|
|
301
309
|
console.log(` · found legacy ${legacy} — kept as-is (still read as a fallback).`);
|
|
302
|
-
console.log(' Run /update-pipeline to migrate it into cohorte.config.yaml + wire the kanban.');
|
|
310
|
+
console.log(' Run /cohorte-update-pipeline to migrate it into cohorte.config.yaml + wire the kanban.');
|
|
303
311
|
return;
|
|
304
312
|
}
|
|
305
313
|
fs.mkdirSync(path.dirname(cfg), { recursive: true });
|
|
@@ -310,7 +318,7 @@ async function seedConfig() {
|
|
|
310
318
|
console.log(` · seeded ${cfg} from your answers`);
|
|
311
319
|
} else {
|
|
312
320
|
fs.writeFileSync(cfg, text);
|
|
313
|
-
console.log(` · seeded ${cfg} (disabled defaults — enable via /init-pipeline or /update-pipeline)`);
|
|
321
|
+
console.log(` · seeded ${cfg} (disabled defaults — enable via /cohorte-init-pipeline or /cohorte-update-pipeline)`);
|
|
314
322
|
}
|
|
315
323
|
}
|
|
316
324
|
|
|
@@ -391,21 +399,21 @@ if (scope === 'global') {
|
|
|
391
399
|
✓ pipeline core installed globally into ${dest} (version ${VERSION})
|
|
392
400
|
gate hook: ${hookState} (reads each repo's .claude/gate-config.json; silent where absent)
|
|
393
401
|
|
|
394
|
-
The commands (/init-pipeline, /brainstorm, /build …) and the review/release agents are now
|
|
402
|
+
The commands (/cohorte-init-pipeline, /cohorte-brainstorm, /cohorte-build …) and the review/release agents are now
|
|
395
403
|
available in EVERY project on this machine — nothing is copied per repo.
|
|
396
404
|
|
|
397
405
|
Per repo:
|
|
398
406
|
1. Open the project in Claude Code.
|
|
399
|
-
2. Run /init-pipeline — it generates PIPELINE.md, renders the surface agents, writes
|
|
407
|
+
2. Run /cohorte-init-pipeline — it generates PIPELINE.md, renders the surface agents, writes
|
|
400
408
|
.claude/gate-config.json, and drops a committed .claude/pipeline.json pointer so
|
|
401
409
|
teammates know to install the global core (${REPO_URL}).
|
|
402
|
-
3. Commit PIPELINE.md + .claude/, then /brainstorm to start a feature.
|
|
410
|
+
3. Commit PIPELINE.md + .claude/, then /cohorte-brainstorm to start a feature.
|
|
403
411
|
|
|
404
412
|
Update later with: npx cohorte@latest update --global
|
|
405
413
|
|
|
406
414
|
Global kanban config, user-scoped — optional:
|
|
407
415
|
· One consolidated file: ${path.join(globalDir, 'cohorte.config.yaml')}
|
|
408
|
-
· Don't hand-edit it — /init-pipeline (new project) and /update-pipeline (existing) wire it
|
|
416
|
+
· Don't hand-edit it — /cohorte-init-pipeline (new project) and /cohorte-update-pipeline (existing) wire it
|
|
409
417
|
for you: creating + syncing an Obsidian kanban board of the pipeline in your shared vault.`);
|
|
410
418
|
} else if (mode === 'install') {
|
|
411
419
|
console.log(`→ installing pipeline core into ${dest}`);
|
|
@@ -422,9 +430,9 @@ Global kanban config, user-scoped — optional:
|
|
|
422
430
|
|
|
423
431
|
Next:
|
|
424
432
|
1. Open the project in Claude Code.
|
|
425
|
-
2. Run /init-pipeline — it detects your stack, asks the gaps, and generates
|
|
433
|
+
2. Run /cohorte-init-pipeline — it detects your stack, asks the gaps, and generates
|
|
426
434
|
PIPELINE.md + renders one implementer agent per surface.
|
|
427
|
-
3. Commit PIPELINE.md, then /brainstorm to start a feature.
|
|
435
|
+
3. Commit PIPELINE.md, then /cohorte-brainstorm to start a feature.
|
|
428
436
|
|
|
429
437
|
Update later with: npx cohorte@latest update
|
|
430
438
|
Prefer one shared core across all your repos? Re-run with --global.`);
|
|
@@ -436,6 +444,6 @@ Prefer one shared core across all your repos? Re-run with --global.`);
|
|
|
436
444
|
bumpPointerVersion(path.join(dest, 'pipeline.json'));
|
|
437
445
|
console.log(`
|
|
438
446
|
✓ core refreshed to ${VERSION}. Your PIPELINE.md, rendered surface agents, gate-config.json and
|
|
439
|
-
settings.json were left as-is. Re-run /init-pipeline if your stack changed.`);
|
|
447
|
+
settings.json were left as-is. Re-run /cohorte-init-pipeline if your stack changed.`);
|
|
440
448
|
}
|
|
441
449
|
})();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: <SURFACE_AGENT>
|
|
3
|
-
description: Implements the <SURFACE_LABEL> surface (<SURFACE_PATH>) for one feature, strictly from the frozen spec + contract, test-first TDD. Dispatched by /build. Touches only its own surface.
|
|
3
|
+
description: Implements the <SURFACE_LABEL> surface (<SURFACE_PATH>) for one feature, strictly from the frozen spec + contract, test-first TDD. Dispatched by /cohorte-build. Touches only its own surface.
|
|
4
4
|
tools: <SURFACE_TOOLS>
|
|
5
5
|
model: <SURFACE_MODEL>
|
|
6
6
|
---
|
|
@@ -14,7 +14,7 @@ shared surface is the frozen contract and the spec.
|
|
|
14
14
|
> (§Conventions/§Testing): your slice of them is baked into this file below (§Your conventions),
|
|
15
15
|
> rendered from the profile — re-reading the prose every dispatch is exactly the cost the bake
|
|
16
16
|
> removes. If the baked slice visibly contradicts `PIPELINE.md`, say so in your handoff: the profile
|
|
17
|
-
> wins, and this agent file needs a re-render (`/update-pipeline`).
|
|
17
|
+
> wins, and this agent file needs a re-render (`/cohorte-update-pipeline`).
|
|
18
18
|
|
|
19
19
|
## You own
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ shared surface is the frozen contract and the spec.
|
|
|
22
22
|
|
|
23
23
|
## Your conventions (baked from `PIPELINE.md` at render time)
|
|
24
24
|
|
|
25
|
-
<!-- Rendered by /init-pipeline (and refreshed by /update-pipeline's reconcile) from
|
|
25
|
+
<!-- Rendered by /cohorte-init-pipeline (and refreshed by /cohorte-update-pipeline's reconcile) from
|
|
26
26
|
§Conventions `### Shared` + `### Surface: <your key>` + your §Testing lines.
|
|
27
27
|
Edit conventions in PIPELINE.md, never here — this block is regenerated. -->
|
|
28
28
|
|
package/core/agents/release.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release
|
|
3
|
-
description: Commits, pushes, and opens the PR for a SHIP-verified feature. Dispatched by /ship at the SHIP gate. Drafts the conventional commit + PR body from the spec and diff. Never edits source.
|
|
3
|
+
description: Commits, pushes, and opens the PR for a SHIP-verified feature. Dispatched by /cohorte-ship at the SHIP gate. Drafts the conventional commit + PR body from the spec and diff. Never edits source.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
package/core/agents/review.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
|
-
description: Read-only reviewer. Compares the implementation against the frozen spec, then audits code quality, security, and (if the profile declares it) mobile-first. Emits the REVIEW REPORT. Dispatched by /review — one per touched surface on multi-surface diffs. Cannot modify anything.
|
|
3
|
+
description: Read-only reviewer. Compares the implementation against the frozen spec, then audits code quality, security, and (if the profile declares it) mobile-first. Emits the REVIEW REPORT. Dispatched by /cohorte-review — one per touched surface on multi-surface diffs. Cannot modify anything.
|
|
4
4
|
tools: Read, Grep, Glob, mcp__serena
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -66,7 +66,7 @@ Concrete, high-signal traps to grep for per language. A surface's language comes
|
|
|
66
66
|
- **SQL / migrations** — `UPDATE`/`DELETE` with no `WHERE`; N+1 (a query inside a loop that a JOIN
|
|
67
67
|
would collapse); foreign-key columns joined/filtered without an index.
|
|
68
68
|
|
|
69
|
-
## Audit mode (no feature spec — codebase refactor, dispatched by `/audit`)
|
|
69
|
+
## Audit mode (no feature spec — codebase refactor, dispatched by `/cohorte-audit`)
|
|
70
70
|
|
|
71
71
|
When given a **path/domain instead of a feature spec**, skip step 1 and audit the target against
|
|
72
72
|
`PIPELINE.md` §Conventions as the rulebook: conventions per surface, TDD coverage (list every
|
|
@@ -86,7 +86,7 @@ domain** (same finding-line shape) instead of a SHIP/REVISE/BLOCK verdict.
|
|
|
86
86
|
A finding is **deferred** when it is genuinely true and genuinely **out of this feature's scope**:
|
|
87
87
|
pre-existing code the staged diff did not touch, adjacent debt the spec never claims to fix, a
|
|
88
88
|
convention violation that predates this work. Deferring is not softening — it is naming the right
|
|
89
|
-
owner. The lead routes deferred findings to `specs/refactor-backlog.md` (they feed `/refactor`), so
|
|
89
|
+
owner. The lead routes deferred findings to `specs/refactor-backlog.md` (they feed `/cohorte-refactor`), so
|
|
90
90
|
they are **never lost and never cost a fix loop**.
|
|
91
91
|
|
|
92
92
|
- **Deferred findings are separate from your findings list** and count in **no** severity row: the
|
|
@@ -5,7 +5,7 @@ argument-hint: [path or domain, default = whole repo]
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
You are the **lead**. Audit **$ARGUMENTS** (default: whole repo) to drive it to a clean base. Read +
|
|
8
|
-
analyze only — no fixes (those go through `/refactor`).
|
|
8
|
+
analyze only — no fixes (those go through `/cohorte-refactor`).
|
|
9
9
|
|
|
10
10
|
> Read `PIPELINE.md` §`commands` (the mechanical gates), `surfaces`, and §Conventions — plus
|
|
11
11
|
> `specs/_decisions.md` §Live if it exists (SCHEMA.md §Decisions): those standing decisions are part
|
|
@@ -44,8 +44,8 @@ Merge mechanical + convention findings into one prioritized backlog and **write
|
|
|
44
44
|
|
|
45
45
|
**Carry over the deferred items** before overwriting: `grep -n 'deferred:' specs/refactor-backlog.md`
|
|
46
46
|
and re-emit every **open** (`- [ ]`) match verbatim under its domain, tag included. Those lines were
|
|
47
|
-
put there by `/review` §3.5 — a real finding a feature deliberately did not own — and an audit that
|
|
47
|
+
put there by `/cohorte-review` §3.5 — a real finding a feature deliberately did not own — and an audit that
|
|
48
48
|
blindly overwrites the file is the one way they silently disappear. Already-ticked (`- [x]`) ones are
|
|
49
49
|
done: drop them.
|
|
50
50
|
Print a short summary (counts per domain + top items). Tell the human: refactor a domain with
|
|
51
|
-
`/refactor <domain>`.
|
|
51
|
+
`/cohorte-refactor <domain>`.
|