@mu-crew/mu 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/AGENTS.md +208 -599
  2. package/README.md +125 -329
  3. package/dist/cli.js +108 -78
  4. package/dist/cli.js.map +1 -1
  5. package/dist/extension/mu-pi.js +421 -56
  6. package/dist/extension/mu-pi.js.map +1 -1
  7. package/dist/index.d.ts +36 -10
  8. package/dist/index.js +89 -67
  9. package/dist/index.js.map +1 -1
  10. package/docs/ARCHITECTURE.md +176 -1072
  11. package/docs/ROADMAP.md +88 -169
  12. package/docs/VISION.md +205 -415
  13. package/docs/VOCABULARY.md +204 -466
  14. package/docs/architecture/control-socket.md +133 -0
  15. package/docs/architecture/dag.md +113 -0
  16. package/docs/architecture/mux.md +162 -0
  17. package/docs/architecture/ops-log.md +140 -0
  18. package/docs/architecture/sdk.md +185 -0
  19. package/docs/architecture/sync.md +129 -0
  20. package/docs/architecture/tui.md +146 -0
  21. package/docs/guide/README.md +30 -0
  22. package/docs/guide/backends.md +61 -0
  23. package/docs/guide/cleanup.md +74 -0
  24. package/docs/guide/delegate.md +87 -0
  25. package/docs/guide/dispatch.md +144 -0
  26. package/docs/guide/getting-started.md +180 -0
  27. package/docs/guide/recovery.md +135 -0
  28. package/docs/guide/remote.md +74 -0
  29. package/docs/guide/sql.md +76 -0
  30. package/docs/guide/stop-a-worker.md +64 -0
  31. package/docs/guide/sync.md +78 -0
  32. package/docs/guide/tui.md +98 -0
  33. package/docs/guide/upgrade.md +76 -0
  34. package/docs/history/CHANGELOG-pre-3.md +4866 -0
  35. package/docs/reference/env.md +87 -0
  36. package/docs/reference/naming.md +82 -0
  37. package/docs/specs/2026-09-28-agent-state-from-murmur.md +1 -1
  38. package/docs/specs/2026-09-29-task-substates.md +1 -1
  39. package/docs/specs/2026-10-03-keep-driving-nudge.md +142 -0
  40. package/package.json +2 -1
  41. package/prompts/mu-refute.md +8 -0
  42. package/prompts/mu-research.md +8 -0
  43. package/prompts/mu-review.md +8 -0
  44. package/prompts/mu-rules-audit.md +8 -0
  45. package/prompts/mu-tournament.md +9 -0
  46. package/prompts/ultrathink.md +9 -0
  47. package/skills/mu/SKILL.md +126 -255
  48. package/skills/mu/recipes/adversarial-review.md +83 -0
  49. package/skills/mu/recipes/brief.md +53 -0
  50. package/skills/mu/recipes/codemode-driver.md +54 -0
  51. package/skills/mu/recipes/deep-research.md +52 -0
  52. package/skills/mu/recipes/fan-out.md +36 -0
  53. package/skills/mu/recipes/hypothesis-panel.md +40 -0
  54. package/skills/mu/recipes/long-run.md +20 -0
  55. package/skills/mu/recipes/loop-until-done.md +38 -0
  56. package/skills/mu/recipes/orchestrator-loop.md +87 -0
  57. package/skills/mu/recipes/plan.md +54 -0
  58. package/skills/mu/recipes/recovery.md +26 -0
  59. package/skills/mu/recipes/refute.md +49 -0
  60. package/skills/mu/recipes/remote-workers.md +292 -0
  61. package/skills/mu/recipes/review-panel.md +57 -0
  62. package/skills/mu/recipes/rules-audit.md +70 -0
  63. package/skills/mu/recipes/tournament.md +37 -0
  64. package/skills/mu/recipes/triage.md +38 -0
  65. package/skills/mu/recipes/ultrathink.md +73 -0
  66. package/skills/mu/recipes/watcher.md +16 -0
  67. package/skills/mu/recipes/waves.md +19 -0
  68. package/skills/mu/recipes/worker.md +24 -0
  69. package/docs/HANDOVER.md +0 -486
  70. package/docs/USAGE_GUIDE.md +0 -2738
  71. package/skills/mu/REMOTE_WORKERS.md +0 -617
@@ -14,25 +14,19 @@ not in `--help` do not exist.
14
14
 
15
15
  ## Output + JSON shapes
16
16
 
17
- Default output: textual card on stdout plus a `Next:` block. Read
18
- both. `--json` exists on every verb:
19
- - Success: one stdout object.
20
- - Collection reads (`task list`, `workspace commits`, ...): `{items: T[], count: number}`.
21
- - Singletons keep named fields.
22
- - `mu sql --json`: bare array rows.
23
- - `mu log --tail`: NDJSON (one object per line).
24
- - Errors: `{error,message,nextSteps,exitCode}` on stderr.
25
- - Validation errors also include structured `usage`.
26
- - **`nextSteps` survives in JSON.**
17
+ Default output is a card on stdout plus a `Next:` block. Read both.
18
+ Every verb takes `--json`: one stdout object; collections are
19
+ `{items, count}`; `mu sql --json` is bare rows; `mu log --tail` is
20
+ NDJSON. Errors are `{error,message,nextSteps,exitCode}` on stderr
21
+ (validation errors add `usage`). **`nextSteps` survives in JSON.**
27
22
 
28
23
  ## Vocabulary
29
24
 
30
- - **workstream** — unit of organization; one **mux session** named
31
- `mu-<name>` (a tmux session, or a herdr workspace).
25
+ - **workstream** — one **mux session** `mu-<name>` (tmux session or
26
+ herdr workspace) and one DB partition.
32
27
  - **agent** — named worker in a pane (you may be one).
33
- - **mux** — the multiplexer mu drives: tmux, or herdr. One per
34
- invocation. `mu doctor` names the active one; `MU_MUX` forces it.
35
- Spawn, send, and read work on both. `mu agent kick` is Linux-only on herdr.
28
+ - **mux** — tmux or herdr, one per invocation. `mu doctor` names it;
29
+ `MU_MUX` forces it. `mu agent kick` is Linux-only on herdr.
36
30
  - **control socket (ctl)** — how mu drives a pi agent: the mu pi
37
31
  extension (`mu link pi`) serves exact send, state, wait and abort
38
32
  inside pi's own TUI. `ctl missing|refused` means it does not answer.
@@ -42,8 +36,8 @@ both. `--json` exists on every verb:
42
36
  Any `CLOSED/*` satisfies `--blocked-by`.
43
37
  - **claim / release** — atomic take/clear of `tasks.owner`.
44
38
  - **note** — append-only task context; survives sessions.
45
- - **track** — independent DAG subtree; don't spawn more agents than
46
- ready tracks.
39
+ - **track** — independent DAG subtree; spawn at most one agent per
40
+ ready track.
47
41
  - **workspace** — per-agent VCS copy under
48
42
  `<state-dir>/workspaces/<workstream>/<agent>/`.
49
43
 
@@ -55,82 +49,59 @@ or inspection.
55
49
 
56
50
  ### Off-the-cuff helpers (`scratch`)
57
51
 
58
- The reserved `scratch` workstream holds helpers that need no task DAG; it
59
- auto-creates on spawn. `mu_delegate` (installed by `mu link pi`) is its tool
60
- form for one answer back; the CLI form is spawn + send + `mu agent wait --json`
61
- (`lastText`).
52
+ For one-shot work inside pi, call `mu_delegate` (installed by `mu link pi`).
53
+ Outside pi: spawn into the reserved `scratch` workstream (no task DAG,
54
+ auto-created), `send --fresh`, then `mu agent wait --json` (`lastText`).
62
55
 
63
- - `mu agent wait <name> --first` waits for busy → idle; exit 0 met, 5
64
- timeout, 6 pane died.
65
- - For a watcher, persist last-seen state in a log ledger: write `mu log -w
66
- scratch --kind pr-state 'pr=1234 sha=abc ci=red'`, then read `mu log -w
67
- scratch --kind pr-state -n 1 --json`. Act only on change.
56
+ - `mu agent wait <names...> --first` waits for busy → idle instead of a
57
+ `sleep` loop; exit 0 met, 5 timeout, 6 pane died.
58
+ - For a watcher (PR, CI, a log), follow [recipes/watcher.md](recipes/watcher.md).
68
59
  - One agent per independent unit; `--workspace` for any helper that may edit,
69
60
  build, or test the shared repo.
70
61
 
71
- A helper stuck at `needs_input` right after spawn likely hit pi's project trust
72
- prompt: add `--approve` to `MU_<CLI>_COMMAND` rather than overriding it with
73
- `--command`.
74
-
75
- Move off `scratch` when work gains dependencies or review gates.
62
+ A helper stuck at `needs_input` right after spawn likely hit pi's
63
+ project trust prompt: add `--approve` to `MU_<CLI>_COMMAND`. Move off
64
+ `scratch` when work gains dependencies or review gates.
76
65
 
77
66
  ## Mental model
78
67
 
79
68
  ### Workstreams, DAGs, tracks
80
69
 
81
- One workstream is one mux session and DB partition. Its task DAG has one edge:
82
- `mu task block A --by B` means **B blocks A**. Parallel tracks sharing a
83
- prerequisite collapse, preventing two agents from taking the same dependency.
70
+ The DAG has one edge: `mu task block A --by B` means **B blocks A**.
71
+ Tracks sharing a prerequisite collapse into one, so two agents never
72
+ take the same dependency.
84
73
 
85
74
  ### Workspaces prevent trampling
86
75
 
87
- If an agent may edit/build/test while another agent is active in the
88
- same repo, spawn with `--workspace`. Keep the main checkout for
89
- orchestration: two builds in one checkout corrupt each other.
90
-
91
- Workspaces auto-detect jj/sl/git; non-VCS uses `cp -a`. They are
92
- auto-freed on `mu agent close` **iff clean**: no uncommitted changes
93
- and no commits since fork. Non-clean close fails with
94
- `WorkspacePreservedError`; then use `mu workspace free <agent>` or
95
- `mu agent close <agent> --discard-workspace` (lossy).
76
+ If an agent may edit, build, or test while another is active in the same
77
+ repo, spawn with `--workspace`. Two builds in one checkout corrupt each
78
+ other; keep the main checkout for orchestration.
96
79
 
97
- Between waves, `mu workspace refresh <agent>` rebases onto fresh main without
98
- killing LLM context. Claim/send warn at ≥10 commits behind; scripts can make
99
- that a refusal with `--strict-staleness`.
80
+ Workspaces auto-detect jj, sl, or git (else `cp -a`). `mu agent close`
81
+ frees one **only if clean** (no uncommitted changes, no commits since
82
+ fork); otherwise it fails with `WorkspacePreservedError`. Then use
83
+ `mu workspace free <agent>` or `--discard-workspace` (lossy).
84
+ Between waves, `mu workspace refresh <agent>` rebases onto main and
85
+ keeps LLM context. Claim and send warn at ≥10 commits behind
86
+ (`--strict-staleness` refuses).
100
87
 
101
88
  ### Remote agents
102
89
 
103
- Agents can run on another machine: the PANE is local, the PROCESS is
104
- remote (`--command 'ssh <host> -t "..."'`), so `send`, `read`, and the
105
- reaper keep working unchanged. A pi agent's control socket is forwarded
106
- over that ssh (`mu agent remote-env`). **One orchestrator
107
- DB; panes may be remote** — never run a second mu on the host, since
108
- `tasks.owner_id` is an FK into the machine-local `agents` table and a
109
- remote mu could not claim your tasks anyway. You create the remote
110
- workspace yourself (`--workspace` is local-only).
111
-
112
- **Read [REMOTE_WORKERS.md](REMOTE_WORKERS.md) before spawning your first
113
- remote agent, and again before waiting on one; poll once per turn and run
114
- the claim's one-shot `Next:` command.** Three more costly traps:
115
- - **On a session-capped host, route long commands and silent-failure
116
- polls through [mule](https://github.com/mu-crew/mule).** A refused
117
- bare `rev-parse` can return an empty sha that looks like progress;
118
- batch all workers in one `--max-secs`-bounded mule job.
119
- - **`mule` exit 3 is a HANDBACK** — no ssh master, and opening one can
120
- need a human to touch a hardware key. Ask the operator; never retry,
121
- never run `ssh -MNf` yourself, never fall back to `ssh <host> <cmd>`.
122
- - **Exit 4 and 6 mean wait again; 5 means never.** Neither says the work
123
- failed.
90
+ The PANE is local, the PROCESS is remote. **One orchestrator DB**: never
91
+ run a second mu on the host. **Read
92
+ [recipes/remote-workers.md](recipes/remote-workers.md) before spawning
93
+ your first remote agent, and again before waiting on one.**
94
+ **`mule` exit 3 is a HANDBACK** to the operator (hardware-key touch):
95
+ never retry or open `ssh -MNf` yourself.
124
96
 
125
97
  ### Agent names
126
98
 
127
- Use roles: `worker-1`, `worker-2`, `reviewer-1`, `scout-1`,
128
- `auditor-1`, `planner-1`. Smallest unused suffix. Avoid human names.
99
+ Use roles with the smallest unused suffix: `worker-1`, `reviewer-1`,
100
+ `scout-1`, `auditor-1`, `planner-1`. No human names.
129
101
 
130
102
  ### Task note contract
131
103
 
132
- End every delegated task with a note containing the applicable
133
- fields:
104
+ End every delegated task with a note holding the applicable fields:
134
105
 
135
106
  ```text
136
107
  FILES: paths inspected/changed (line ranges if precise)
@@ -143,102 +114,39 @@ ODDITIES: weird things not acted on
143
114
  ```
144
115
 
145
116
  Then close with grounding:
146
-
147
- ```bash
148
- mu task close <id> -w <ws> --evidence "tests pass: cargo test exit 0"
149
- ```
150
-
151
- Future agents can reconstruct context via `mu task notes <id>`.
152
-
153
- ## Orchestrator loop
154
-
155
- Every turn:
156
-
157
- 1. `mu state -w <ws>` — read agents, IN_PROGRESS, ready tasks,
158
- parallel tracks.
159
- 2. Spawn at most one agent per independent ready track.
160
- 3. **Claim before sending — even one-shot reviewers/scouts.**
161
- `mu task claim <id> -w <ws> --for <agent> --evidence "..."`.
162
- If no task exists, `mu task add` first; include initial context with
163
- `--note 'REPRO: ...\nSCOPE: ...'` when the title alone is not
164
- enough. Agent state is runtime observation; task ownership is durable and
165
- waitable.
166
- 4. Send each new task with `mu agent send <w> --fresh '...'` (new
167
- session + prompt in one step; refuses while busy): task id,
168
- files/notes to read, workspace path, validation command, scope
169
- guards, task note contract. Follow the `Next:` block; it picks
170
- `--fresh` vs `--steer` for you.
171
- 5. End with a loud final-action block:
172
-
173
- ```text
174
- ⚠️ FINAL ACTION
175
- git commit -am '...' THEN
176
- mu task close <id> -w <ws> --evidence '...'
177
- ```
178
-
179
- 6. `mu task wait ... --first --on-stall exit --json`.
180
- 7. Cherry-pick the closed worker's **new** commit(s), verify the MERGE
181
- (see below), return control. Do not barrier or loop in shell.
182
- Only `CLOSED/done` ships; other closes: read the reason note.
183
- 8. Repeat from `mu state`.
184
-
185
- ## Dispatch rules that prevent real failures
186
-
187
- - **Pipeline; don't barrier.** Wait for one task, cherry-pick only its new
188
- commits onto main, verify the combined tree, then return control. Waiting on an
189
- umbrella task hides partial progress; merging stale branches can restore
190
- reverted code.
191
- - **Verify the merge, not the worker's rerun.** The worker tested against its
192
- fork point; only the combination with moved main is new. This found three
193
- integration breaks where rerunning worker suites found none. For remote work,
194
- run the merged gate on the host with warm dependencies: 500s × 30 integrations
195
- is four laptop-hours. Keep platform-sensitive checks and the final release gate
196
- local; macOS `ps` once exposed a bug Linux could not.
197
- - **Push only from a green gate.** Script the gate so `git push` is its last
198
- line under `set -e`; a chain that printed a failure and pushed anyway put a red
199
- commit on main. Check the gate runs what it claims: a randomized test gated on
200
- an env var passed with zero cases.
201
- - **Dispatch from current main.** Reset the worker's worktree to main before each
202
- task. Stale bases caused four merges that conflicted or broke tests after
203
- passing in the worker.
204
- - **Accept evidence, not close notes.** Re-run the key measurement from a clean
205
- checkout. Close notes have claimed unpushed commits and reported numbers from
206
- a half-edited clone.
207
- - **Freeze only what conflicts.** While one task owns shared files, give idle
208
- workers tasks that avoid them; a blanket freeze idled four of five workers for
209
- a day.
210
- - **Fix done before a long run.** Put the completion criterion in the task note
211
- first: which checks, how many agreeing runs, what may differ. Without it the
212
- target moves with every run.
213
- - **Split long proofs into independent units**, sharded and in parallel, so a
214
- unit that passes stays passed and one flake restarts only its own unit.
215
- Workers poll background jobs every few minutes, not hourly.
216
- - Bucket waves by file cluster, not severity; two agents editing one file
217
- conflict. Refresh workspaces between waves.
218
- - Cross-workstream wait/claim uses qualified refs. The owner stays in its own
219
- workstream; only task ownership crosses.
220
- - For an idle worker, read the pane to learn why it stopped, then answer,
221
- retry, or release its task. `MU_IDLE_THRESHOLD_MS` defaults to 5m.
222
- - **Never chain `/new` and a prompt as two sends to a pi agent:** the prompt
223
- can land mid-reset and vanish (it did, twice). `--fresh` does both inside pi.
224
- - **Stop a worker:** `mu agent abort <w>` first for pi (exact, local or
225
- remote, keeps context, waits for idle; exit 5 = still busy; queued
226
- follow-ups return to the editor unsent). Then `mu agent kick` (pi
227
- unresponsive, or non-pi; local panes only), then `mu agent close`.
228
- - Use `mu agent send`, not raw mux input. Single-quote prompts containing shell
229
- expansions, or use a quoted heredoc.
117
+ `mu task close <id> -w <ws> --evidence "tests pass: cargo test exit 0"`.
118
+
119
+ ## Orchestrator rules
120
+
121
+ <!-- mu:keep-driving -->
122
+ **While workers run, keep driving.** Your turn ends only when every
123
+ task is closed, or when a decision only a human can make blocks all
124
+ progress (scope, spend, irreversible or external actions, a hardware-key
125
+ handback). A status summary is a log line, not a stopping point: write
126
+ it with `mu log`, then go straight back to `mu task wait`. Ending a
127
+ turn to report progress while workers are busy stalls the whole crew.
128
+ <!-- /mu:keep-driving -->
129
+
130
+ Before you dispatch, read [recipes/orchestrator-loop.md](recipes/orchestrator-loop.md):
131
+ the every-turn loop, waiting, merging, and stopping workers. These
132
+ rules hold even when you skip it:
133
+
134
+ - **Claim before sending**, even one-shot reviewers. Ownership is
135
+ durable and waitable; agent state is not.
136
+ - **Pipeline; don't barrier.** Merge each task as it closes.
137
+ - **Verify the merge, not the worker's rerun.** Only `CLOSED/done` ships.
138
+ - **Push only from a green gate.**
139
+ - **Fix done before a long run**: the completion criterion goes in the
140
+ task note first.
141
+ - **New work to pi is `mu agent send --fresh`.** Never chain `/new` and
142
+ a prompt as two sends: the prompt can land mid-reset and vanish.
143
+ - **`mu task wait --first --on-stall exit`**; exit 7 means read the
144
+ owner's pane and answer it.
145
+ - **Stop a worker gently**: `mu agent abort`, then `kick`, then `close`.
230
146
 
231
147
  ## CLI gotchas
232
148
 
233
- - **`workstream teardown`** is dry-run by default; `--yes` commits. It writes
234
- TOMBSTONE ops, so history survives and `mu undo <group> --yes` reverses the
235
- deletions — do NOT `mu db backup` first, the log IS the backup.
236
- `workstream list --torn-down` replays past teardowns with the group id to
237
- undo, newest first, marking ones already recreated.
238
- - **`agent wait <names...> --first`** blocks until an agent stops working
239
- (busy → anything else) — the task-less counterpart to `mu task wait`, for
240
- helpers that own no task. Use it instead of a `sleep` loop. Exit 0 met,
241
- 5 timeout, 6 pane died.
149
+ - **`workstream teardown`** is dry-run without `--yes`.
242
150
  - **`task close --if-ready`** no-ops until every blocker is CLOSED; bare
243
151
  `task release` reopens IN_PROGRESS.
244
152
  - **`task close --as rejected|wontfix --why ...`** (declined | valid, not worth it) unblocks dependents (listed in
@@ -247,49 +155,12 @@ Every turn:
247
155
  IN_PROGRESS — `task release` first.
248
156
  - **For waits use `task wait`, not `log --tail`.** `--kind` is the operator's
249
157
  log-ledger channel; `--intent` is what mu recorded.
250
- - **`mu undo`** bare lists undoable actions with group ids; `<group>` previews;
251
- `<group> --yes` applies. It emits INVERSE ops for that one group, so it
252
- touches nothing else, and the undo is itself an op — REDO is
253
- `mu undo <that group> --yes`. Refuses with exit 4 if a later action changed
254
- the same fields (`--force` discards that newer work). Rows only: killed panes
255
- and freed workspace dirs do not come back. No snapshots, no `--to`.
256
- - **`mu rebuild <file>`** writes a NEW DB from the ops log. Agents and
257
- workspaces are absent because they have no captured ops; re-spawn after swap.
258
- - **`mu sql`** alone skips ambient sync, preserving no-surprise mutations.
259
- - **`mu db backup`** is a convenient copy; real recovery is `mu rebuild`.
260
- - **Sync (laptop ↔ devserver):** `export MU_SYNC_DIR=$HOME/Sync/mu` on each
261
- machine pointing at a shared folder (Syncthing recommended). Every command
262
- then flushes your ops and ingests peers' — ambient, no daemon — so a bare
263
- `mu task list` on the other box already shows what you added here. Merge is
264
- per-FIELD, so two machines editing different fields of one task both keep
265
- their edit. `mu sync` bare reports peer status plus a copy-pasteable rsync
266
- line; mu never runs ssh/scp/rsync itself. `--from <peer-mu.db>` reads a
267
- peer's ops directly; `--repair <peer>` re-reads from zero and is always safe
268
- (ingest is idempotent).
269
- **NEVER put `MU_DB_PATH` inside `MU_SYNC_DIR`** — it corrupts the DB and
270
- `mu doctor` hard-fails. Agent/workspace state and task OWNERSHIP are
271
- machine-local and never travel.
272
- - **`mu doctor`** runs fast checks; `--deep` rebuilds the log into a temp DB and
273
- diffs it field-by-field. DRIFT means the log and the tables disagree, which
274
- breaks undo and sync at once (exit 5, naming table, key and field). It is a
275
- capture bug, not operator error: back up and report it, do NOT reflexively
276
- rebuild — if capture missed a mutation, the live rows hold the real work.
277
- The `disk` section reconciles state-dir against DB both ways and is
278
- **report-only**: `ws-rows` is a row whose directory is gone (nothing else
279
- reports it), `ws-dirs` blocks the next `--workspace` spawn, and an orphan dir
280
- may hold the only copy of uncommitted work — which is why mu prints the
281
- cleanup command and runs none of them. `--disk` adds per-checkout byte usage.
282
-
283
- ## `mu task wait`
284
-
285
- Use `--first --on-stall exit`: `--first` populates `.firing`, and
286
- `--on-stall exit` prevents unattended waits from polling forever when a worker
287
- needs attention. Exit 6 means a dead pane; exit 7 means the owner sat in
288
- `needs_input`. Read that pane (`mu agent read <owner>`) before acting: the
289
- worker may be waiting on an answer from you, not merely forgetting to close.
290
- Answer it — questions are cheaper than rework. For remote workers, see
291
- [REMOTE_WORKERS.md](REMOTE_WORKERS.md) before choosing timeout or stall
292
- handling.
158
+ - **`mu sql`** skips ambient sync.
159
+ - **Never put `MU_DB_PATH` inside `MU_SYNC_DIR`**: it corrupts the DB.
160
+ - **`mu doctor --deep` DRIFT** (exit 5): back up and report it; do not
161
+ rebuild.
162
+ - Before undo, rebuild, teardown, sync setup, or acting on `doctor`
163
+ cleanup output, read [recipes/recovery.md](recipes/recovery.md).
293
164
 
294
165
  ## Models and thinking effort
295
166
 
@@ -301,63 +172,63 @@ export MU_PI_COMMAND="pi --model sonnet:medium"
301
172
  mu agent spawn a --cli pi_big # uses $MU_PI_BIG_COMMAND
302
173
  ```
303
174
 
304
- Convention: `pi_mini` / `pi` / `pi_big`. Use mini for probing,
305
- modest for build/edit/refactor, big for design/review/incidents.
306
- Discover model strings with `pi --list-models [fuzzy-search]`.
175
+ Convention: `pi_mini` for probing, `pi` for build and refactor,
176
+ `pi_big` for design, review, and incidents. List models with
177
+ `pi --list-models [search]`.
307
178
 
308
179
  ## Reaper and agent state
309
180
 
310
- If an agent pane dies, or `mu agent close` kills it mid-task, owned
311
- IN_PROGRESS tasks revert to OPEN with a `[reaper]` note and `task
312
- reap` op. No manual release after crashes.
313
-
314
- pi agents report state through the control socket; other CLIs through
315
- [murmur](https://github.com/mu-crew/murmur) on tmux or herdr on herdr.
316
- `unknown` means no state source; `mu doctor` says why. pi agents need
317
- no murmur. See [REMOTE_WORKERS.md](REMOTE_WORKERS.md) § mu and murmur.
318
-
319
- For high-stakes decisions:
320
-
321
- ```bash
322
- mu agent read worker-1 -n 100
323
- mu log -w <ws> --tail
324
- mu task notes <id>
325
- ```
326
-
327
- ## In-pane worker loop
328
-
329
- `$MU_AGENT_NAME`, injected at spawn, resolves identity; the pane title
330
- is the fallback that adopted panes need. Env-first means this loop is
331
- identical whichever multiplexer you are in — you never need to know.
332
-
333
- - Worker pane: spawned/adopted by mu; bare `mu task claim <id>` works.
334
- - Orchestrator pane: not registered; bare `claim` errors with next
335
- steps: `--self`, `--for <worker>`, or `mu agent adopt <pane>`.
336
-
337
- ```bash
338
- mu me
339
- mu me next
340
- mu task show <id>; mu task notes <id>
341
- mu task claim <id> --evidence "starting; read notes"
342
- mu task note <id> "FILES: ...\nDECISION: ...\nVERIFIED: ..."
343
- mu task close <id> --evidence "tests pass: ..." # LAST action
344
- ```
181
+ If an agent pane dies, or `mu agent close` kills it mid-task, its
182
+ IN_PROGRESS tasks revert to OPEN with a `[reaper]` note. No manual
183
+ release after crashes.
345
184
 
346
- Skipping close makes the orchestrator's wait hang. Won't do it:
347
- `close --as wontfix --why "..."`.
185
+ pi agents report state through the control socket and need no murmur.
186
+ Other CLIs report through [murmur](https://github.com/mu-crew/murmur) on
187
+ tmux, or herdr on herdr. `unknown` means no state source; `mu doctor`
188
+ says why. Before a high-stakes decision, read the pane
189
+ (`mu agent read worker-1 -n 100`), `mu log -w <ws> --tail`, and
190
+ `mu task notes <id>`.
348
191
 
349
- ## Follow-on prompts
192
+ ## You are a worker
350
193
 
351
- A plain `mu agent send` appends to prior context; use it to steer or
352
- answer. Unrelated work to pi: `mu agent send worker-1 --fresh 'Claim
353
- task_x...'`. claude-code/codex: send `/new` (codex: `/clear`), then the
354
- prompt; a send it cannot confirm prints a `warning:` on stderr.
194
+ If a task was claimed for you, follow [recipes/worker.md](recipes/worker.md).
195
+ Close the task as your last action, or the orchestrator's wait hangs.
355
196
 
356
197
  ## Guardrails
357
198
 
358
- Task ownership outranks runtime agent state. Coordinate through task notes and the
359
- activity log. Keep edges within one workstream, role-name agents, and reserve
360
- the `mu_` task-id prefix. Give workers bounded paths and commands.
199
+ Task ownership outranks agent state. Coordinate through task notes and
200
+ the activity log. Keep edges within one workstream and reserve the `mu_`
201
+ task-id prefix. Give workers bounded paths and commands.
202
+
203
+ ## Recipes
204
+
205
+ Read the recipe before starting the shape it names. For a large or
206
+ risky job that needs several of them, start with
207
+ [ultrathink](recipes/ultrathink.md).
208
+
209
+ | Recipe | Read when |
210
+ | --- | --- |
211
+ | [ultrathink](recipes/ultrathink.md) | a job is too large or risky for one context; composes the rest |
212
+ | [orchestrator-loop](recipes/orchestrator-loop.md) | you dispatch tasks and merge results |
213
+ | [brief](recipes/brief.md) | you write a task note or prompt a worker will read |
214
+ | [plan](recipes/plan.md) | you turn a spec or requirements into a task DAG |
215
+ | [worker](recipes/worker.md) | a task was claimed for you |
216
+ | [recovery](recipes/recovery.md) | undo, rebuild, teardown, sync setup, `doctor` cleanup |
217
+ | [remote-workers](recipes/remote-workers.md) | an agent runs on another machine |
218
+ | [waves](recipes/waves.md) | more than one worker edits the same repo at once |
219
+ | [long-run](recipes/long-run.md) | a task or proof runs for hours, or must survive flakes |
220
+ | [watcher](recipes/watcher.md) | a helper polls a PR, CI, or log for change |
221
+ | [adversarial-review](recipes/adversarial-review.md) | work must be checked by someone other than its author before it counts |
222
+ | [fan-out](recipes/fan-out.md) | the same change or check applies to many units |
223
+ | [refute](recipes/refute.md) | an audit, sweep, or fact-check produces findings |
224
+ | [hypothesis-panel](recipes/hypothesis-panel.md) | a root cause is unknown (flaky test, intermittent bug) |
225
+ | [tournament](recipes/tournament.md) | several answers are possible and the best is a judgement call |
226
+ | [loop-until-done](recipes/loop-until-done.md) | the amount of work is unknown until a check passes |
227
+ | [triage](recipes/triage.md) | a backlog of external items needs classifying and acting on |
228
+ | [deep-research](recipes/deep-research.md) | a question needs many sources read and cross-checked |
229
+ | [review-panel](recipes/review-panel.md) | one diff or PR needs review from several angles |
230
+ | [rules-audit](recipes/rules-audit.md) | a change must follow AGENTS.md rule by rule, or rules keep being restated |
231
+ | [codemode-driver](recipes/codemode-driver.md) | a codemode script would dispatch a wave in parallel |
361
232
 
362
233
  ## See also
363
234
 
@@ -0,0 +1,83 @@
1
+ # Adversarial review
2
+
3
+ Use when a unit of work must be checked by someone other than its
4
+ author before it counts: a fix, a finding, a claim, a plan. The author
5
+ grades its own work generously; a fresh agent told to refute it does
6
+ not. Every other review-shaped recipe builds on this one.
7
+
8
+ The review is a task in the DAG, not a step inside the worker's
9
+ session. Its verdict, its evidence, and every rejection stay in the DB.
10
+
11
+ ## Steps
12
+
13
+ 1. **Write the criteria first.** Before dispatching the work, note on
14
+ the work task what "accepted" means: the requirements, the edge
15
+ cases that need tests, the files that must not change. The reviewer
16
+ judges against this note, not against its own taste.
17
+ 2. **Add the review task, blocked by the work:**
18
+
19
+ ```bash
20
+ mu task add review_x -w <ws> -t "Review x" -i 50 -e 0.5 --blocked-by x \
21
+ --note 'ACCEPTANCE: see x notes. Refute; report gaps, not style.'
22
+ ```
23
+
24
+ 3. **Dispatch the work** as usual. When `x` closes, `review_x` becomes
25
+ ready.
26
+ 4. **Spawn a fresh reviewer.** A new agent, or `--fresh` on an idle one,
27
+ so it has none of the author's reasoning. Use a different model from
28
+ the worker where you can (`--cli pi_big` reviewing `pi`): a second
29
+ model has different blind spots. Give it the worker's workspace path
30
+ and commits read-only by instruction; it edits nothing.
31
+ 5. **Send the reviewer brief** (below), claim `review_x` for it, wait.
32
+ 6. **Act on the verdict:**
33
+ - `ACCEPT`: cherry-pick `x`'s commits and verify the merge.
34
+ - `REJECT`: add `fix_x` (blocked by `review_x`, note = the gaps) and
35
+ `review_x_2` (blocked by `fix_x`). Dispatch `fix_x` to the original
36
+ worker, whose context still holds the work. Repeat from step 4.
37
+ The DAG grows; nothing is rewritten.
38
+ - The `fix_x` brief tells the author to check each gap before fixing
39
+ it: reproduce it, then fix it, or answer it with evidence in the
40
+ note (`GAP 2: not reproducible, <command + output>`). A gap the
41
+ author disputes goes to the next reviewer as a claim to check,
42
+ not as settled.
43
+ 7. **Cap the rounds.** After two rejections on the same unit, stop the
44
+ loop and decide yourself: split the unit, change the criteria, or
45
+ ask the human. A third round of the same argument rarely converges.
46
+
47
+ Done when the latest review task closed with `VERDICT: ACCEPT`, and the
48
+ accepted commits are merged and the merged tree passes the gate.
49
+
50
+ ## Reviewer brief
51
+
52
+ Send this with the task id, the workspace path, and the commit range:
53
+
54
+ ```text
55
+ You are reviewing task <x>. You did not write it. Your job is to find
56
+ where it fails the acceptance criteria in `mu task notes <x>`.
57
+
58
+ - Read the diff (<range>) and the criteria. Run the tests that cover it.
59
+ - Report gaps against the criteria: a requirement not met, an edge case
60
+ without a test, a change outside scope, a claim the evidence does not
61
+ support. Not style, not preferences.
62
+ - Each gap cites a file:line or a command and its output.
63
+ - If you could not check something (tool failed, no access), say
64
+ UNVERIFIED for it. Unverified is not a pass and not a fail.
65
+ - Do not edit files.
66
+
67
+ End with a note in the task note contract, plus one line:
68
+ VERDICT: ACCEPT | REJECT
69
+ Then close: mu task close review_<x> --evidence '<verdict + key check>'
70
+ ```
71
+
72
+ ## Traps
73
+
74
+ - **A reviewer that sees the author's reasoning agrees with it.** Send
75
+ the diff and the criteria, not the worker's transcript or close note.
76
+ - **"Looks good" is not a verdict.** Require the `VERDICT:` line and at
77
+ least one command the reviewer ran. A review with no evidence is a
78
+ rejected review: re-send it.
79
+ - **Reviewers drift into fixing.** A reviewer that edits the code is now
80
+ an author nobody reviews. Keep the fix in `fix_x`.
81
+ - **Review is not merge verification.** An accepted unit can still
82
+ break once merged with moved main. Verify the merge as in
83
+ [orchestrator-loop](orchestrator-loop.md#merging).
@@ -0,0 +1,53 @@
1
+ # Writing a brief
2
+
3
+ Use when you write anything a worker reads: a task note, a `--fresh`
4
+ prompt, a reviewer brief. The worker starts with no context. What is
5
+ not in the brief, or one pointer away, does not exist for it.
6
+
7
+ <!-- Ideas adapted from mattpocock/skills `writing-for-agents` (MIT). -->
8
+
9
+ ## Rules
10
+
11
+ 1. **End on a completion criterion.** The brief says how the worker
12
+ tells done from not done, and the criterion is both checkable and
13
+ exhaustive: "every file in the UNITS list compiles under
14
+ `npm run typecheck`", not "update the call sites". A vague bound
15
+ invites the worker to stop at the first plausible point.
16
+ 2. **Inline what every path needs; point to the rest.** Files, the
17
+ verify command, scope, and the final action go in the brief. Shared
18
+ context goes in one place (an umbrella's note) and the brief points
19
+ at it: `Read: mu task notes sweep -w audit`. Repeating it per task
20
+ copies it into every worker's context and lets the copies drift.
21
+ 3. **State the target, not the ban.** "Edit only files under
22
+ `src/auth/`" works; "don't touch other files" puts other files in
23
+ the worker's head. Keep a prohibition only for a hard guardrail
24
+ with no positive form, and pair it with the positive target.
25
+ 4. **Reuse the recipe words.** *Unit*, *stop rule*, *verdict*,
26
+ *finding*, *umbrella* mean the same thing in every recipe. Use them
27
+ as written; a worker that read one recipe brief reads the next
28
+ faster.
29
+ 5. **Cut the default.** A sentence the worker would obey anyway
30
+ ("be careful", "write clean code") costs attention and changes
31
+ nothing. Delete the whole sentence.
32
+ 6. **Ask for evidence, not reassurance.** The final note names the
33
+ commands run and their exit codes (the task note contract). "Done,
34
+ all good" is not a result.
35
+
36
+ ## Shape
37
+
38
+ ```text
39
+ Task <id> in <ws>. Workspace: <path>.
40
+ Read: mu task notes <id> -w <ws> (and the umbrella's, if any)
41
+
42
+ GOAL: <one sentence>
43
+ FILES: <paths it may change>
44
+ DONE WHEN: <checkable, exhaustive criterion>
45
+ VERIFY: <exact command>
46
+
47
+ ⚠️ FINAL ACTION
48
+ git commit -am '<msg>' THEN
49
+ mu task close <id> -w <ws> --evidence '<command + result>'
50
+ ```
51
+
52
+ Done when a worker with no other context could finish the task from
53
+ the brief and the notes it points at, and could tell when it is done.