@mu-crew/mu 3.2.1 → 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 (50) hide show
  1. package/AGENTS.md +10 -5
  2. package/README.md +49 -2
  3. package/dist/cli.js +108 -78
  4. package/dist/cli.js.map +1 -1
  5. package/dist/extension/mu-pi.js +244 -12
  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 +1 -0
  11. package/docs/VOCABULARY.md +2 -0
  12. package/docs/architecture/control-socket.md +17 -3
  13. package/docs/architecture/mux.md +3 -4
  14. package/docs/guide/README.md +5 -0
  15. package/docs/guide/dispatch.md +11 -4
  16. package/docs/guide/getting-started.md +3 -0
  17. package/docs/guide/recovery.md +3 -1
  18. package/docs/guide/remote.md +1 -1
  19. package/docs/history/CHANGELOG-pre-3.md +1 -1
  20. package/docs/reference/env.md +1 -1
  21. package/docs/specs/2026-10-03-keep-driving-nudge.md +142 -0
  22. package/package.json +2 -1
  23. package/prompts/mu-refute.md +8 -0
  24. package/prompts/mu-research.md +8 -0
  25. package/prompts/mu-review.md +8 -0
  26. package/prompts/mu-rules-audit.md +8 -0
  27. package/prompts/mu-tournament.md +9 -0
  28. package/prompts/ultrathink.md +9 -0
  29. package/skills/mu/SKILL.md +71 -131
  30. package/skills/mu/recipes/adversarial-review.md +83 -0
  31. package/skills/mu/recipes/brief.md +53 -0
  32. package/skills/mu/recipes/codemode-driver.md +54 -0
  33. package/skills/mu/recipes/deep-research.md +52 -0
  34. package/skills/mu/recipes/fan-out.md +36 -0
  35. package/skills/mu/recipes/hypothesis-panel.md +40 -0
  36. package/skills/mu/recipes/long-run.md +20 -0
  37. package/skills/mu/recipes/loop-until-done.md +38 -0
  38. package/skills/mu/recipes/orchestrator-loop.md +87 -0
  39. package/skills/mu/recipes/plan.md +54 -0
  40. package/skills/mu/recipes/recovery.md +26 -0
  41. package/skills/mu/recipes/refute.md +49 -0
  42. package/skills/mu/recipes/review-panel.md +57 -0
  43. package/skills/mu/recipes/rules-audit.md +70 -0
  44. package/skills/mu/recipes/tournament.md +37 -0
  45. package/skills/mu/recipes/triage.md +38 -0
  46. package/skills/mu/recipes/ultrathink.md +73 -0
  47. package/skills/mu/recipes/watcher.md +16 -0
  48. package/skills/mu/recipes/waves.md +19 -0
  49. package/skills/mu/recipes/worker.md +24 -0
  50. /package/skills/mu/{REMOTE_WORKERS.md → recipes/remote-workers.md} +0 -0
@@ -55,9 +55,7 @@ auto-created), `send --fresh`, then `mu agent wait --json` (`lastText`).
55
55
 
56
56
  - `mu agent wait <names...> --first` waits for busy → idle instead of a
57
57
  `sleep` loop; exit 0 met, 5 timeout, 6 pane died.
58
- - For a watcher, persist last-seen state in a log ledger: write `mu log -w
59
- scratch --kind pr-state 'pr=1234 sha=abc ci=red'`, then read `mu log -w
60
- scratch --kind pr-state -n 1 --json`. Act only on change.
58
+ - For a watcher (PR, CI, a log), follow [recipes/watcher.md](recipes/watcher.md).
61
59
  - One agent per independent unit; `--workspace` for any helper that may edit,
62
60
  build, or test the shared repo.
63
61
 
@@ -89,16 +87,10 @@ keeps LLM context. Claim and send warn at ≥10 commits behind
89
87
 
90
88
  ### Remote agents
91
89
 
92
- The PANE is local, the PROCESS is remote (`--command 'ssh <host> -t
93
- "..."'`); `mu agent remote-env` forwards a pi agent's control socket.
94
- **One orchestrator DB**: never run a second mu on the host. You create
95
- the remote workspace yourself (`--workspace` is local-only).
96
-
97
- **Read [REMOTE_WORKERS.md](REMOTE_WORKERS.md) before spawning your first
98
- remote agent, and again before waiting on one.** Poll once per turn with
99
- the claim's one-shot `Next:` command. On a session-capped host, route
100
- long commands and polls through [mule](https://github.com/mu-crew/mule):
101
- a refused bare ssh returns an empty sha that looks like progress.
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.**
102
94
  **`mule` exit 3 is a HANDBACK** to the operator (hardware-key touch):
103
95
  never retry or open `ssh -MNf` yourself.
104
96
 
@@ -124,78 +116,37 @@ ODDITIES: weird things not acted on
124
116
  Then close with grounding:
125
117
  `mu task close <id> -w <ws> --evidence "tests pass: cargo test exit 0"`.
126
118
 
127
- ## Orchestrator loop
128
-
129
- Every turn:
130
-
131
- 1. `mu state -w <ws>` — read agents, IN_PROGRESS, ready tasks,
132
- parallel tracks.
133
- 2. Spawn at most one agent per independent ready track.
134
- 3. **Claim before sending — even one-shot reviewers/scouts.**
135
- `mu task claim <id> -w <ws> --for <agent> --evidence "..."`.
136
- If no task exists, `mu task add` first (`--note 'REPRO: ...'` when
137
- the title is not enough). Ownership is durable and waitable; agent
138
- state is not.
139
- 4. Send each new task with `mu agent send <w> --fresh '...'` (new
140
- session + prompt in one step; refuses while busy): task id,
141
- files/notes to read, workspace path, validation command, scope
142
- guards, task note contract. Follow the `Next:` block; it picks
143
- `--fresh` vs `--steer` for you.
144
- 5. End with a loud final-action block:
145
-
146
- ```text
147
- ⚠️ FINAL ACTION
148
- git commit -am '...' THEN
149
- mu task close <id> -w <ws> --evidence '...'
150
- ```
151
-
152
- 6. `mu task wait ... --first --on-stall exit --json`.
153
- 7. Cherry-pick the closed worker's **new** commit(s), verify the MERGE
154
- (see below), return control. Do not barrier or loop in shell.
155
- Only `CLOSED/done` ships; other closes: read the reason note.
156
- 8. Repeat from `mu state`.
157
-
158
- ## Dispatch rules that prevent real failures
159
-
160
- - **Pipeline; don't barrier.** Wait for one task, cherry-pick only its
161
- new commits, verify, return control. An umbrella wait hides progress;
162
- merging stale branches can restore reverted code.
163
- - **Verify the merge, not the worker's rerun.** Only the combination
164
- with moved main is new; that found three breaks rerunning found none
165
- of. Run a remote merge gate on the host (see REMOTE_WORKERS.md).
166
- - **Push only from a green gate.** Make `git push` the last line under
167
- `set -e`. Check the gate runs what it claims: an env-gated randomized
168
- test once passed with zero cases.
169
- - **Dispatch from current main.** Reset the worker's worktree to main
170
- before each task.
171
- - **Accept evidence, not close notes.** Re-run the key measurement from
172
- a clean checkout; close notes have claimed unpushed commits.
173
- - **Freeze only what conflicts.** Give idle workers tasks that avoid
174
- shared files; a blanket freeze idled four of five workers for a day.
175
- - **Fix done before a long run.** Put the completion criterion (checks,
176
- agreeing runs, allowed variance) in the task note first.
177
- - **Split long proofs into independent units**, sharded and parallel,
178
- so one flake restarts only its unit.
179
- - Bucket waves by file cluster, not severity; two agents editing one file
180
- conflict. Refresh workspaces between waves.
181
- - Cross-workstream wait and claim use qualified refs; only task
182
- ownership crosses.
183
- - For an idle worker, read the pane, then answer, retry, or release its
184
- task. `MU_IDLE_THRESHOLD_MS` defaults to 5m.
185
- - **Never chain `/new` and a prompt as two sends to a pi agent:** the prompt
186
- can land mid-reset and vanish (it did, twice). `--fresh` does both inside pi.
187
- - **Stop a worker:** `mu agent abort <w>` first for pi (exact, local or
188
- remote, keeps context, waits for idle; exit 5 = still busy; queued
189
- follow-ups return to the editor unsent). Then `mu agent kick` (pi
190
- unresponsive, or non-pi; local panes only), then `mu agent close`.
191
- - Use `mu agent send`, not raw mux input. Single-quote prompts containing shell
192
- expansions, or use a quoted heredoc.
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`.
193
146
 
194
147
  ## CLI gotchas
195
148
 
196
- - **`workstream teardown`** is dry-run without `--yes`. It writes
197
- TOMBSTONE ops, so `mu undo <group> --yes` reverses it; the log is the
198
- backup. `workstream list --torn-down` lists group ids to undo.
149
+ - **`workstream teardown`** is dry-run without `--yes`.
199
150
  - **`task close --if-ready`** no-ops until every blocker is CLOSED; bare
200
151
  `task release` reopens IN_PROGRESS.
201
152
  - **`task close --as rejected|wontfix --why ...`** (declined | valid, not worth it) unblocks dependents (listed in
@@ -204,32 +155,12 @@ Every turn:
204
155
  IN_PROGRESS — `task release` first.
205
156
  - **For waits use `task wait`, not `log --tail`.** `--kind` is the operator's
206
157
  log-ledger channel; `--intent` is what mu recorded.
207
- - **`mu undo`** bare lists groups; `<group>` previews; `<group> --yes`
208
- emits inverse ops for that group only (redo = undo the undo). Exit 4
209
- if a later action changed the same fields (`--force` discards it).
210
- Rows only: killed panes and freed workspace dirs do not come back.
211
- - **`mu rebuild <file>`** writes a new DB from the ops log, without
212
- agents or workspaces; re-spawn after the swap. Recovery is
213
- `mu rebuild`, not `mu db backup`.
214
158
  - **`mu sql`** skips ambient sync.
215
- - **Sync:** set `MU_SYNC_DIR` on each machine to a shared folder
216
- (Syncthing). Every command flushes and ingests ops, merged per field.
217
- mu never runs ssh or rsync; `mu sync` prints the line.
218
- `--repair <peer>` is always safe. **Never put `MU_DB_PATH` inside
219
- `MU_SYNC_DIR`**: it corrupts the DB. Agents, workspaces, and task
220
- ownership never travel.
221
- - **`mu doctor --deep` DRIFT** (exit 5) is a capture bug: back up and
222
- report it. Do not rebuild; the live rows may hold work the log missed.
223
- The `disk` section is report-only: an orphan dir may hold the only copy
224
- of uncommitted work, so mu prints cleanup commands and runs none.
225
-
226
- ## `mu task wait`
227
-
228
- Use `--first --on-stall exit`: `--first` populates `.firing`, and
229
- `--on-stall exit` stops an unattended wait when a worker needs attention.
230
- Exit 6 is a dead pane; exit 7 is an owner in `needs_input`. Read that
231
- pane (`mu agent read <owner>`) and answer: the worker may be waiting on
232
- you. Questions are cheaper than rework.
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).
233
164
 
234
165
  ## Models and thinking effort
235
166
 
@@ -258,31 +189,10 @@ says why. Before a high-stakes decision, read the pane
258
189
  (`mu agent read worker-1 -n 100`), `mu log -w <ws> --tail`, and
259
190
  `mu task notes <id>`.
260
191
 
261
- ## In-pane worker loop
262
-
263
- `$MU_AGENT_NAME` (injected at spawn) resolves identity; adopted panes
264
- fall back to the pane title. In a worker pane, bare `mu task claim <id>`
265
- works. In the unregistered orchestrator pane it errors; use `--self`,
266
- `--for <worker>`, or `mu agent adopt <pane>`.
267
-
268
- ```bash
269
- mu me
270
- mu me next
271
- mu task show <id>; mu task notes <id>
272
- mu task claim <id> --evidence "starting; read notes"
273
- mu task note <id> "FILES: ...\nDECISION: ...\nVERIFIED: ..."
274
- mu task close <id> --evidence "tests pass: ..." # LAST action
275
- ```
276
-
277
- Skipping close makes the orchestrator's wait hang. Won't do it:
278
- `close --as wontfix --why "..."`.
192
+ ## You are a worker
279
193
 
280
- ## Follow-on prompts
281
-
282
- A plain `mu agent send` appends to prior context; use it to steer or
283
- answer. Unrelated work to pi: `mu agent send worker-1 --fresh 'Claim
284
- task_x...'`. claude-code/codex: send `/new` (codex: `/clear`), then the
285
- 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.
286
196
 
287
197
  ## Guardrails
288
198
 
@@ -290,6 +200,36 @@ Task ownership outranks agent state. Coordinate through task notes and
290
200
  the activity log. Keep edges within one workstream and reserve the `mu_`
291
201
  task-id prefix. Give workers bounded paths and commands.
292
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 |
232
+
293
233
  ## See also
294
234
 
295
235
  - `mu --help`, `mu <verb> --help` — canonical CLI reference.
@@ -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.
@@ -0,0 +1,54 @@
1
+ # Codemode driver
2
+
3
+ Use when a pi orchestrator with the `codemode` tool runs a recipe with
4
+ many parallel units, and one tool call per spawn, send, and wait is
5
+ slow. A script can issue those calls in parallel. It stays a driver:
6
+ the plan, the state, and the results live in the DB.
7
+
8
+ ## The rule
9
+
10
+ **Delete the script mid-run and nothing is lost.** That holds when:
11
+
12
+ - The script calls only `mu` verbs, through `tools.bash`. It reads
13
+ state with `mu state --json` / `mu task notes`, never from its own
14
+ variables across calls.
15
+ - Every task it dispatches exists in the DAG before the script starts.
16
+ The script adds no tasks the orchestrator has not planned, except the
17
+ ones a recipe step names (the next round, a `fix_` task).
18
+ - `store()` / `load()` hold nothing a re-run needs. The DAG is the
19
+ cursor.
20
+ - The script's source goes into the log before it runs:
21
+ `mu log -w <ws> --kind driver '<what it does, which tasks>'`.
22
+
23
+ ## Shape
24
+
25
+ ```js
26
+ // @options: {"timeout_ms": 1800000}
27
+ const ws = "audit";
28
+ const sh = async (c) => {
29
+ const r = await tools.bash({ command: c });
30
+ if (r.exit_code !== 0) throw new Error(`${c}: ${r.output}`);
31
+ return r.output;
32
+ };
33
+ const ready = JSON.parse(await sh(`mu task next -w ${ws} -n 0 --json`)).items;
34
+ await Promise.allSettled(ready.slice(0, 4).map(async (t, i) => {
35
+ const w = `worker-${i + 1}`;
36
+ await sh(`mu task claim ${t.name} -w ${ws} --for ${w} --evidence 'driver dispatch'`);
37
+ await sh(`mu agent send ${w} -w ${ws} --fresh 'Work on ${t.name}. Read: mu task notes ${t.name} -w ${ws}'`);
38
+ }));
39
+ const wait = await tools.bash({ command: `mu task wait -w ${ws} ${ready.slice(0, 4).map((t) => t.name).join(" ")} --first --on-stall exit --json` });
40
+ return wait.output;
41
+ ```
42
+
43
+ Check field names against `--json` output before relying on them; the
44
+ script above is a shape, not an API.
45
+
46
+ ## Traps
47
+
48
+ - **One wave per script.** A script that loops forever hides progress
49
+ from you and from the human. Dispatch, wait for the first close,
50
+ return; merge and verify outside the script, then run it again.
51
+ - **A script timeout cancels the waits, not the workers.** Workers keep
52
+ running and their tasks stay claimed. Re-read `mu state` and carry on.
53
+ - **Exit codes are data.** `mu task wait` exit 7 means a worker needs
54
+ you; return it to the model instead of retrying.
@@ -0,0 +1,52 @@
1
+ # Deep research
2
+
3
+ Use when a question needs more sources than one context can read and
4
+ checking them against each other: how a library or protocol behaves,
5
+ what changed between versions, how competitors solve a problem, whether
6
+ a claim in a draft holds. This is [refute](refute.md) applied to
7
+ sources. Workers need a web search tool (pi's `brave_search`, or
8
+ `curl` on docs) or the code they research.
9
+
10
+ ## Steps
11
+
12
+ 1. **Write the question and the bar** on an umbrella task: the exact
13
+ question, what a good answer contains (a recommendation, a
14
+ comparison table, a yes/no with conditions), and how fresh sources
15
+ must be.
16
+ 2. **Split by angle**, one search task per angle: official docs,
17
+ changelogs and release notes, issue trackers, independent write-ups,
18
+ the code itself. Each searcher reads, fetches, and writes claims to
19
+ its note, one per line:
20
+
21
+ ```text
22
+ CLAIM: c4 "Node 22 enables the permission model by default" SOURCE: <url> QUOTE: "<exact words>"
23
+ ```
24
+
25
+ A claim without a source and a quote is not a claim. Searchers can
26
+ run on a cheap model.
27
+ 3. **Dedupe claims** in one task: merge the same fact from several
28
+ sources (keep every source), and flag claims that contradict each
29
+ other.
30
+ 4. **One check task per claim** that the answer depends on. The checker
31
+ gets the claim and its sources, not the searcher's reasoning, fetches
32
+ the source itself, and tries to break the claim: is the quote there,
33
+ does it say that, is it current, does another source disagree? It
34
+ ends with `VERDICT: c4 CONFIRMED | REFUTED | UNVERIFIED <evidence>`.
35
+ For contradicted claims, one checker per side.
36
+ 5. **Synthesize** in a task blocked by every check: answer the question
37
+ from confirmed claims only, each with its source URL. List
38
+ unverified claims separately. Note what the sources disagree on and
39
+ which side the evidence favours.
40
+
41
+ Done when every claim the answer uses has a `CONFIRMED` verdict line,
42
+ every sentence of fact in the report cites a URL, and the report meets
43
+ the bar from step 1.
44
+
45
+ ## Traps
46
+
47
+ - **A fetch failure is UNVERIFIED, not REFUTED.** Rate limits and
48
+ paywalls block checkers; say so, do not drop the claim silently.
49
+ - **Secondary sources copy each other.** Three blog posts repeating one
50
+ changelog are one source. Prefer the primary source in the dedupe.
51
+ - **Version drift.** A claim true for v2 can be false for v3. Checkers
52
+ confirm the version the question asks about.
@@ -0,0 +1,36 @@
1
+ # Fan-out
2
+
3
+ Use when the same treatment applies to many units: files, call sites,
4
+ failing tests, findings, modules. One context holding 50 units drops
5
+ some and calls the job done; one task per unit cannot.
6
+
7
+ ## Steps
8
+
9
+ 1. **Enumerate first, as its own task.** A scout lists the units and
10
+ writes them to the umbrella's note, one per line. The list is done
11
+ when it matches a command the scout ran (`rg -l`, a test listing),
12
+ not when it looks complete. Record the command and the count.
13
+ 2. **One task per unit**, blocked into an umbrella:
14
+
15
+ ```bash
16
+ mu task add sweep -w <ws> -t "Sweep: <goal>" -i 60 -e 1 --note 'UNITS: 37 (rg -l ... | wc -l)'
17
+ mu task add sweep_auth_ts -w <ws> -t "Sweep src/auth.ts" -i 50 -e 0.2
18
+ mu task block sweep -w <ws> --by sweep_auth_ts
19
+ ```
20
+
21
+ Put the shared brief and acceptance criteria on the umbrella; each
22
+ unit task's note holds only what differs.
23
+ 3. **Cap concurrency.** Spawn at most one agent per ready track, and no
24
+ more than the machine can build and test at once. Tell workers to
25
+ avoid repo-wide commands so more can run.
26
+ 4. **Pipeline.** Dispatch, wait `--first`, merge, dispatch the next unit
27
+ to the freed worker with `--fresh`. Units that touch the same files
28
+ go on one track (see [waves](waves.md)).
29
+ 5. **Review per unit** when a wrong unit is costly: add a review task
30
+ per unit ([adversarial-review](adversarial-review.md)).
31
+ 6. **Synthesize** when the output is a report, not commits: a final
32
+ task blocked by every unit reads their notes and writes one result.
33
+ It reads notes, not transcripts.
34
+
35
+ Done when `mu task close sweep --if-ready` closes the umbrella: every
36
+ unit is closed, and the closed count matches the step 1 count.
@@ -0,0 +1,40 @@
1
+ # Hypothesis panel
2
+
3
+ Use for root-cause work: a flaky test, an intermittent bug, a metric
4
+ that moved. One agent that forms a theory then tests its own theory
5
+ finds evidence for it. Separate agents, each given different evidence,
6
+ form independent theories; separate agents then try to kill them.
7
+
8
+ ## Steps
9
+
10
+ 1. **Write the symptom** on the umbrella: what happens, how often, the
11
+ repro command, and what would count as fixed.
12
+ 2. **One hypothesis task per evidence source**: logs, the code path,
13
+ recent commits, data, environment. Each agent sees only its source,
14
+ so the theories do not anchor on each other. Each ends with:
15
+
16
+ ```text
17
+ HYPOTHESIS: h2 <cause>
18
+ PREDICTS: <an observation that is true if h2 is the cause, false otherwise>
19
+ ```
20
+
21
+ 3. **One test task per hypothesis**, in its own workspace. The tester
22
+ builds the experiment that would kill the hypothesis (force the race,
23
+ revert the commit, feed the data) and reports
24
+ `VERDICT: h2 SURVIVES | KILLED <evidence>`.
25
+ 4. **If one survives**, add a fix task for it, then a review task
26
+ ([adversarial-review](adversarial-review.md)). The fix is accepted
27
+ only if the step 1 repro stops reproducing.
28
+ 5. **If none survives**, start another round
29
+ ([loop-until-done](loop-until-done.md)): the new hypothesis tasks get
30
+ the killed hypotheses and their evidence as input.
31
+
32
+ Done when a fix closed `ACCEPT` and the repro from step 1 no longer
33
+ reproduces at the rate step 1 recorded.
34
+
35
+ ## Traps
36
+
37
+ - **Two survivors** usually means the experiments were too weak. Design
38
+ one experiment that separates them before you fix either.
39
+ - **Flaky repros need counts.** "Passed once" proves nothing for a 1 in
40
+ 50 failure. Put the run count in step 1.
@@ -0,0 +1,20 @@
1
+ # Long runs
2
+
3
+ Use when a task or proof runs for hours, crosses context compaction,
4
+ or may hit flakes.
5
+
6
+ 1. **Fix done first.** Before dispatch, write the completion criterion
7
+ into the task note: the checks, how many runs must agree, the
8
+ allowed variance. A worker that finds the bar in the note stops at
9
+ the bar, not at the first green.
10
+ 2. **Split into independent units.** Shard a long proof into tasks
11
+ that run in parallel, so one flake restarts only its unit. Each unit
12
+ carries its own criterion.
13
+ 3. **Keep state in the DB.** Progress lives in task notes, not in the
14
+ orchestrator's context. After a compaction, `mu state` and
15
+ `mu task notes <id>` are the whole picture.
16
+ 4. **Accept evidence, not close notes.** Re-run the key measurement
17
+ from a clean checkout before you count a unit as done.
18
+
19
+ Done when every unit is `CLOSED/done` and the criterion from step 1
20
+ holds on the merged tree.
@@ -0,0 +1,38 @@
1
+ # Loop until done
2
+
3
+ Use when the amount of work is unknown: fix type errors until clean,
4
+ find flaky tests until none are new, search until nothing new turns up.
5
+ A fixed number of passes stops too early or runs too long; a stop rule
6
+ written down first does neither.
7
+
8
+ ## Steps
9
+
10
+ 1. **Write the stop rule** on the umbrella before the first round. It
11
+ names a command and a condition, plus a no-progress rule:
12
+
13
+ ```text
14
+ STOP: `npx tsc --noEmit` exits 0
15
+ NO-PROGRESS: two rounds in a row reduce the error count by zero
16
+ ```
17
+
18
+ 2. **Each round is a task**, blocked by the previous one:
19
+ `round_1`, `round_2`, .... Add the next round only when the current
20
+ one closes; never pre-create rounds.
21
+ 3. **Each round ends with its measurement** in the note:
22
+ `MEASURE: 14 errors (was 31)`, or `NEW: 0 flaky tests`.
23
+ 4. **After each round, check the rule** yourself, from the measurement
24
+ command, not from the worker's note.
25
+ - Rule met: close the umbrella.
26
+ - No progress: stop the loop and decide. Change the approach, split
27
+ the work, or park the umbrella with
28
+ `mu task park <umbrella> --why '<what is stuck>'` and tell the human.
29
+ - Otherwise: add the next round and dispatch it.
30
+
31
+ Done when the stop rule holds on the merged tree, run by you.
32
+
33
+ ## Traps
34
+
35
+ - **A round that only reports is not progress.** Each round must change
36
+ something (fix, new search slice) or produce a new measurement.
37
+ - **Moving goalposts.** Edit the stop rule only with a note saying why;
38
+ the old rule stays in the history.