@mu-crew/mu 3.13.3 → 4.0.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 (119) hide show
  1. package/AGENTS.md +73 -35
  2. package/README.md +71 -57
  3. package/dist/chunk-5HECDBK3.js +4482 -0
  4. package/dist/chunk-5HECDBK3.js.map +1 -0
  5. package/dist/chunk-AW2NONYU.js +301 -0
  6. package/dist/chunk-AW2NONYU.js.map +1 -0
  7. package/dist/chunk-GQNHIPJN.js +4060 -0
  8. package/dist/chunk-GQNHIPJN.js.map +1 -0
  9. package/dist/{chunk-3BARPJLY.js → chunk-PZ5GOCWH.js} +16 -2
  10. package/dist/chunk-PZ5GOCWH.js.map +1 -0
  11. package/dist/chunk-S424D5EP.js +13766 -0
  12. package/dist/chunk-S424D5EP.js.map +1 -0
  13. package/dist/{cli-CKOMHBXV.js → cli-GB2CAVVW.js} +6776 -4350
  14. package/dist/cli-GB2CAVVW.js.map +1 -0
  15. package/dist/cli.js +2 -3
  16. package/dist/cli.js.map +1 -1
  17. package/dist/errors-KHOYKD7D.js +65 -0
  18. package/dist/extension/mu-pi.js +1617 -836
  19. package/dist/extension/mu-pi.js.map +1 -1
  20. package/dist/index.d.ts +4015 -2561
  21. package/dist/index.js +614 -297
  22. package/dist/index.js.map +1 -1
  23. package/dist/tui-ALPHYTA2.js +1773 -0
  24. package/dist/tui-ALPHYTA2.js.map +1 -0
  25. package/docs/ARCHITECTURE.md +117 -66
  26. package/docs/VOCABULARY.md +112 -49
  27. package/docs/guide/README.md +3 -3
  28. package/docs/guide/backends.md +8 -4
  29. package/docs/guide/cleanup.md +61 -33
  30. package/docs/guide/delegate.md +141 -66
  31. package/docs/guide/dispatch.md +148 -53
  32. package/docs/guide/getting-started.md +37 -44
  33. package/docs/guide/other-agent-clis.md +102 -0
  34. package/docs/guide/recovery.md +31 -50
  35. package/docs/guide/remote.md +115 -45
  36. package/docs/guide/sql.md +104 -24
  37. package/docs/guide/stop-a-worker.md +30 -37
  38. package/docs/guide/sync.md +11 -3
  39. package/docs/guide/upgrade.md +93 -43
  40. package/docs/reference/env.md +23 -32
  41. package/docs/reference/naming.md +12 -7
  42. package/docs/reference/surface-contract.md +153 -0
  43. package/package.json +33 -11
  44. package/prompts/mu-debug.md +3 -1
  45. package/prompts/mu-refute.md +2 -1
  46. package/prompts/mu-research.md +3 -1
  47. package/prompts/mu-review.md +2 -1
  48. package/prompts/mu-rules-audit.md +5 -4
  49. package/prompts/mu-sweep.md +2 -1
  50. package/prompts/mu-tournament.md +4 -2
  51. package/prompts/mu-until.md +3 -1
  52. package/prompts/ultrathink.md +1 -1
  53. package/skills/mu/SKILL.md +60 -291
  54. package/skills/mu/recipes/adversarial-review.md +12 -103
  55. package/skills/mu/recipes/brief.md +14 -61
  56. package/skills/mu/recipes/course-correct.md +23 -0
  57. package/skills/mu/recipes/findings.md +17 -111
  58. package/skills/mu/recipes/models.md +17 -92
  59. package/skills/mu/recipes/move.md +14 -0
  60. package/skills/mu/recipes/orchestrator-loop.md +20 -119
  61. package/skills/mu/recipes/recovery.md +8 -29
  62. package/skills/mu/recipes/remote-workers.md +16 -318
  63. package/skills/mu/recipes/tasks-or-calls.md +15 -78
  64. package/skills/mu/recipes/test-health.md +19 -77
  65. package/skills/mu/recipes/worker.md +17 -24
  66. package/dist/chunk-45KQLMEL.js +0 -2908
  67. package/dist/chunk-45KQLMEL.js.map +0 -1
  68. package/dist/chunk-G434JKV2.js +0 -641
  69. package/dist/chunk-G434JKV2.js.map +0 -1
  70. package/dist/chunk-KUGUFBWH.js +0 -12527
  71. package/dist/chunk-KUGUFBWH.js.map +0 -1
  72. package/dist/chunk-QITLNZEM.js +0 -87
  73. package/dist/chunk-QITLNZEM.js.map +0 -1
  74. package/dist/chunk-VIEYQMQA.js +0 -393
  75. package/dist/chunk-VIEYQMQA.js.map +0 -1
  76. package/dist/chunk-WI6AWCMK.js +0 -19
  77. package/dist/chunk-WI6AWCMK.js.map +0 -1
  78. package/dist/cli-CKOMHBXV.js.map +0 -1
  79. package/dist/devtools-LS4ZEPWM.js +0 -3772
  80. package/dist/devtools-LS4ZEPWM.js.map +0 -1
  81. package/dist/tui-LFJ5P4Y2.js +0 -40956
  82. package/dist/tui-LFJ5P4Y2.js.map +0 -1
  83. package/dist/tui-sync-worker.js +0 -17
  84. package/dist/tui-sync-worker.js.map +0 -1
  85. package/dist/yank-XDOONQSL.js +0 -13
  86. package/dist/yank-XDOONQSL.js.map +0 -1
  87. package/docs/ROADMAP.md +0 -123
  88. package/docs/VISION.md +0 -298
  89. package/docs/architecture/control-socket.md +0 -142
  90. package/docs/architecture/dag.md +0 -117
  91. package/docs/architecture/mux.md +0 -167
  92. package/docs/architecture/ops-log.md +0 -160
  93. package/docs/architecture/sdk.md +0 -187
  94. package/docs/architecture/sync.md +0 -159
  95. package/docs/architecture/tui.md +0 -165
  96. package/docs/guide/tui.md +0 -98
  97. package/docs/history/CHANGELOG-pre-3.md +0 -4866
  98. package/docs/img/tui-dashboard.png +0 -0
  99. package/docs/specs/2026-09-28-agent-state-from-murmur.md +0 -333
  100. package/docs/specs/2026-09-29-task-substates.md +0 -247
  101. package/docs/specs/2026-10-03-keep-driving-nudge.md +0 -163
  102. package/docs/specs/2026-10-21-fast-and-slow-gates.md +0 -229
  103. package/skills/mu/recipes/backlog-triage.md +0 -45
  104. package/skills/mu/recipes/codemode-driver.md +0 -118
  105. package/skills/mu/recipes/deep-research.md +0 -69
  106. package/skills/mu/recipes/drift-audit.md +0 -75
  107. package/skills/mu/recipes/fan-out.md +0 -42
  108. package/skills/mu/recipes/hypothesis-panel.md +0 -48
  109. package/skills/mu/recipes/long-run.md +0 -32
  110. package/skills/mu/recipes/loop-until-done.md +0 -45
  111. package/skills/mu/recipes/plan.md +0 -67
  112. package/skills/mu/recipes/refute.md +0 -55
  113. package/skills/mu/recipes/review-panel.md +0 -65
  114. package/skills/mu/recipes/rules-audit.md +0 -89
  115. package/skills/mu/recipes/tournament.md +0 -44
  116. package/skills/mu/recipes/ultrathink.md +0 -86
  117. package/skills/mu/recipes/watcher.md +0 -28
  118. package/skills/mu/recipes/waves.md +0 -21
  119. /package/dist/{chunk-3BARPJLY.js.map → errors-KHOYKD7D.js.map} +0 -0
@@ -2,16 +2,18 @@
2
2
 
3
3
  ## Delegate from pi
4
4
 
5
- `mu link pi` installs the `mu_delegate` and `mu_delegate_cancel` tools
6
- in every pi session. Ask pi in plain words:
5
+ The mu pi package (`pi install npm:@mu-crew/mu`) installs the
6
+ `mu_delegate` and `mu_delegate_cancel` tools in every pi session. Ask pi in plain words:
7
7
 
8
8
  - "Delegate a review of src/x.ts to a helper."
9
9
  - "Have three helpers investigate A, B, and C."
10
10
 
11
- pi calls `mu_delegate`. It spawns a pi agent in the reserved `scratch`
12
- workstream and returns at once with the delegate's name and attach
13
- command. The answer arrives later as a follow-up message; do not poll.
14
- Delegates called in one turn run in parallel.
11
+ pi calls `mu_delegate`. It registers the call as a task (`kind=delegate`,
12
+ see [Every call is a task](#every-call-is-a-task)), spawns a pi agent in
13
+ the reserved `scratch` workstream and returns at once with the task, the
14
+ delegate's name and attach command. The answer arrives later, with
15
+ pi's next settle; do not poll. Delegates called in one turn run in
16
+ parallel.
15
17
 
16
18
  | Option | Meaning |
17
19
  | ------ | ------- |
@@ -19,46 +21,107 @@ Delegates called in one turn run in parallel.
19
21
  | `label` | Names the delegate: `review` gives `delegate-review`. |
20
22
  | `brief` | Ad hoc persona or ground rules, sent first. Not enforced. |
21
23
  | `cwd` | Start directory. Default: the caller's. Must exist. |
22
- | `timeout` | Seconds to wait for the answer (default 3600). After it, the answer does not come back; the follow-up gives the `mu agent wait` command. |
23
- | `workspace` | Own VCS checkout, for delegates that edit files. The follow-up names its path. It isolates repository edits only. |
24
+ | `timeout` | Seconds to wait for the answer (default 3600). After it, the answer does not come back to pi; it still lands on the delegate task, whose report names a wait command. |
25
+ | `workspace` | Own git worktree, for delegates that edit files. The tool result names its path. It isolates repository edits only. |
24
26
  | `cli` | Key for `$MU_<CLI>_COMMAND` (default `pi`). Only keys set in pi's environment exist. |
25
27
  | `model` | pi `--model` value, appended to the cli's command (`sonnet`, `<provider>/<model>:high`, copied from `pi --list-models`). Varies models across a panel. tmux only: herdr refuses a command override. |
26
28
  | `keep` | Keep the pane after it finishes, to talk to it again. |
27
29
  | `record` | `{ task, workstream? }` (or `task: "<ws>/<task>"`): write the answer's verdict onto that task as a note. See [Record a verdict](#record-a-verdict). |
28
-
30
+ | `wave` | A label for one fan-out; `mu delegates tally` counts its verdicts per judged task. |
31
+ | `workstream` | Holds the delegate task and runs the delegate (default `scratch`). |
32
+
33
+ - No tmux or herdr: the same tool runs the delegate as a child pi
34
+ (`mu delegates run <call-id>`), with no pane and no attach command.
35
+ Its report names the session file and, when it fails, the log tail.
36
+ `keep` is dropped. Cancel stops the child. `/reload` lets it finish
37
+ onto its task; quitting pi cancels it.
29
38
  - Watch or steer: run the attach command.
30
- - Stop: `mu_delegate_cancel`, or `mu agent abort <name> -w scratch`.
39
+ - Stop: `mu_delegate_cancel` (a delegate name, a `queued-N` handle or a
40
+ call id), or `mu agent abort <name> -w scratch`. A cancel is recorded:
41
+ the task closes `wontfix` with a report.
31
42
  - The pane closes after a clean finish; died or timed-out panes stay
32
43
  as evidence.
33
- - pi's footer shows how many delegates this session is waiting on, and
34
- `N results pending` for delegates that finished but whose answer has
35
- not reached the conversation yet (queued behind the running turn).
36
- Escape drops those queued answers from pi. The extension then writes
37
- one line per answer into the conversation, without starting a turn,
38
- pointing at a copy under `~/.cache/mu/delegate-answers/` and
39
- at the delegate's own pi session file. An answer that lands after
40
- Escape arrives as usual.
44
+ - The answer reaches the model through the settle wait, never as a
45
+ copy in a pi message. When a delegate finishes, its answer is
46
+ recorded (verdict, report, close); the keep-driving settle wait then
47
+ returns it as a `delegate` event, and the continuation shows that
48
+ call's report (capped at 4000 characters, with the
49
+ `mu task notes <task> -w <ws>` pointer to the rest). A recorded check
50
+ with a verdict shows only its header: the verdict is on its task.
51
+ - A delegate of a `wave` is shown with the rest of the wave: the settle
52
+ keeps waiting while siblings run, then shows ONE summary (counts per
53
+ verdict, a line per call, the answers). A refused call is listed for
54
+ reissue and never waited on. Any other event (a worker closing, a
55
+ dialog) ends that early and is shown after the summary so far.
56
+ - When no settle wait will show an answer (pi is idle, `MU_NUDGE=0`, the
57
+ wait failed), the extension sends one **wake**: a pointer per answer,
58
+ no answer text, that starts a turn. A wake lost from pi's queue (the
59
+ dequeue key, alt+up) is sent once more; lost twice, or dropped by
60
+ Escape, it leaves one line per answer and starts nothing. The report
61
+ stays recorded either way, so the next settle shows it. Escape ends
62
+ only the wait running now: a later answer still wakes an idle pi.
63
+ - `MU_DELEGATE_TRACE=1` logs every wake send and pi lifecycle
64
+ event to `~/.cache/mu/delegate-trace.log`, for finding a lost answer.
41
65
  - Each delegate costs a pane and a pi process. A session runs at most
42
66
  `MU_DELEGATE_MAX` at once (default 16). Further calls are queued, up
43
- to four times the cap: the footer reads `16 delegates running, 4 queued`,
44
- each starts when a slot frees, and `mu_delegate_cancel queued-N`
45
- drops one. A queued call has no pane yet, so quitting pi or `/reload`
46
- drops it; pi warns which ones never started.
67
+ to four times the cap: each starts when a slot frees, and `mu_delegate_cancel queued-N`
68
+ drops one. Past the queue a call is **refused**, not lost: its task
69
+ and brief exist, its state is `refused`, and it does not start on its
70
+ own. Reissue it with `mu_delegate_reissue { call_id }` in its pi
71
+ session once a slot frees: same call, same task, never a second
72
+ verdict. Only that live runtime can start or drain a call, so
73
+ `mu delegates reissue` refuses and names the tool. A refused call is not in murmur's pending
74
+ count. A queued call has no pane yet, so quitting pi or `/reload`
75
+ parks it as `refused` (reissue it); pi warns which ones.
47
76
  - A delegate that stops on an API error (overloaded, connection, auth)
48
77
  keeps its pane. The answer names the error and leaves the choice to
49
- the model: re-issue, or record the check as unverified. The footer
50
- counts it as `1 failed` until the pane is closed.
78
+ the model: re-issue, or record the check as unverified.
51
79
  - Every answer without a final text (API error, empty, timeout, died,
52
- `mu_delegate_cancel`) names the delegate's pi session file and, when
53
- it wrote anything, a copy of its last message so far under
54
- `~/.cache/mu/delegate-answers/` (`*.partial.md`). Quitting pi or
55
- `/reload` lists each running delegate's session file.
56
- - Answers arrive as follow-up messages when pi would otherwise stop,
57
- never mid-turn. To get several at once, set pi's `followUpMode` to
58
- `"all"`.
80
+ `mu_delegate_cancel`) records the delegate's pi session file and,
81
+ when it wrote anything, its last message so far, in the report.
82
+ Quitting pi or `/reload` lists each running delegate's session file.
83
+ A call whose pane is gone fails when the next runtime re-adopts it.
59
84
 
60
85
  `MU_DELEGATE=0` hides the tool ([env vars](../reference/env.md)).
61
86
 
87
+ ### Every call is a task
88
+
89
+ Each `mu_delegate` call creates, in one transaction, a task of
90
+ `kind=delegate` in `scratch` (or the `workstream` you name) with the
91
+ prompt as its brief, plus a call row keyed by a session-qualified
92
+ `call_id` (`pi:<session>:<n>`). The tool result names both:
93
+ `{ task, state, call_id }`. A repeat of the same call id with the same
94
+ request is a no-op; a changed request under it is refused (exit 4).
95
+
96
+ | State | Meaning |
97
+ | ----- | ------- |
98
+ | `queued` | waits for a slot (the task is parked, so it never reaches `mu task next`) |
99
+ | `starting`, `running` | the pane is coming up, then working |
100
+ | `recording` | the answer is being written |
101
+ | `done` | verdict, report and close are all on record |
102
+ | `failed` | no answer, or the record failed: the task is closed `rejected`, the answer kept as its report, the pane kept |
103
+ | `refused` | past the queue; parked; reissue it |
104
+ | `cancelled` | closed `wontfix` with a report |
105
+
106
+ ```bash
107
+ mu delegates list --caller pi:<session> # every call and its state
108
+ mu delegates list --all --wave review-1 # one wave
109
+ mu delegates tally -w scratch --wave review-1 # CONFIRMED/REFUTED/UNVERIFIED per judged task
110
+ mu task notes <task> -w scratch # its brief, and its report: the full answer
111
+ ```
112
+
113
+ The answer is the delegate task's `report`, whole; the settle shows it
114
+ from there, so a lost wake (Escape, compaction, `/reload`) loses
115
+ nothing: the next runtime of the same pi session (after `/reload`, or
116
+ `pi -c` after quitting) re-adopts its `running` pane calls and records
117
+ the answer, a delegate that finished meanwhile included. `tally`
118
+ counts one result per call: a done answer by the label of its first
119
+ `VERDICT:` line (none: UNVERIFIED), a failed or cancelled call as
120
+ UNVERIFIED, queued, running and refused ones as pending. So a plain
121
+ research call (an answer with no `VERDICT:` line) tallies UNVERIFIED
122
+ and closes `answered with no VERDICT line`: the answer arrived, it
123
+ just carries no label.
124
+
62
125
  ### Record a verdict
63
126
 
64
127
  For a refuter or check, pass `record` so the verdict lands on the task
@@ -66,61 +129,70 @@ it judged. The task must exist (`mu task show`), else the call fails
66
129
  and nothing spawns. When the answer arrives, the tool runs
67
130
  `mu task note <task> -w <ws> --author <delegate>` once:
68
131
 
69
- - Done: `REFUTER <label> (<delegate>, <elapsed>):`, then the last
70
- `VERDICT:` line and every `EVIDENCE:` line after it. Without a
71
- VERDICT line, the answer's last 1500 chars after `NO VERDICT LINE:`.
72
- Capped at 4000 chars.
132
+ - Done: `REFUTER <label> (<delegate>, <elapsed>):`, then the first
133
+ verdict line (`VERDICT:` at the start of a line, behind at most one
134
+ role word such as `REFUTER:`) and everything after it, a multi-line
135
+ `EVIDENCE:` body included, uncapped. Later `VERDICT:` lines are
136
+ evidence text, kept verbatim. Without a verdict line, the whole answer after
137
+ `NO VERDICT LINE:`.
73
138
  - Timeout, died, empty, error, or cancelled:
74
139
  `REFUTER <label>: no verdict (<outcome>)`.
75
140
 
76
- The follow-up still carries the full answer and ends with
77
- `Recorded on <ws>/<task> as a note.`, or the reason recording failed.
141
+ The note, the delegate task's report and its close are written together,
142
+ in that order, in one op group (`mu delegates finish`); the delegate
143
+ task is closed before its pane. If the record fails the call is
144
+ `failed`, never `done`, and the answer is kept as the report.
145
+
146
+ The settle then shows the verdict and where the report is. A call whose
147
+ record failed is shown with its whole report and the reason, so you can
148
+ record it yourself.
78
149
 
79
150
  ## Delegate without pi
80
151
 
81
- From a script or other shell, run what the tool runs:
152
+ From a script or another shell, spawn a helper bound to a task and wait
153
+ for the run it starts:
82
154
 
83
155
  ```bash
84
- mu agent spawn helper-1 -w scratch
85
- runs=$(mu agent send helper-1 -w scratch --fresh --json 'Investigate why foo.spec.ts fails. Report the cause.' | jq .runs)
86
- mu agent wait helper-1 -w scratch --after-runs "$runs" --json
156
+ mu task add check_foo -w scratch -t 'Why does foo.spec.ts fail?' --note 'Investigate why foo.spec.ts fails. Report the cause.'
157
+ mu agent spawn helper-1 -w scratch --task check_foo --send 'Do task check_foo. Read: mu task notes check_foo -w scratch'
158
+ mu wait agent:scratch/helper-1
87
159
  ```
88
160
 
89
- `--after-runs` waits for the first run past the count the send
90
- reported, so a run that settles before the wait starts still counts.
91
-
92
- Use `--fresh`: a plain send to a reused agent carries the previous
93
- task's context.
161
+ The send's `next` names the exact ref (`agent:scratch/helper-1@<runs>#<inc>`),
162
+ so a run that settles before the wait starts still counts, and a
163
+ restarted pi is refused rather than read. The result's
164
+ `data.snapshots[].lastText` is the answer (its tail if long; the whole
165
+ text is in `sessionFile`), and `data.firing.kind` says how the run ended:
166
+ `settled`, `input` (it stopped to ask), `dead` (exit 6) or `heartbeat`.
167
+ Non-pi agents have no `lastText`; read the pane with
168
+ `mu agent read helper-1 -w scratch -n 80`.
94
169
 
95
- `mu agent wait` fires when the agent leaves busy (including to
96
- `needs_input`), never on an already idle agent unless it finished a run
97
- past `--after-runs`. For pi, the `--json`
98
- row carries:
170
+ Use a fresh agent or `send --fresh`: a plain send to a reused agent
171
+ carries the previous task's context.
99
172
 
100
- - `outcome`: `done`, `empty`, `error`, `died`, `blocked`, `timeout`, or
101
- `pending`. `error` means the run stopped on an API error after pi's
102
- own retries; `lastError` holds the message and the pane is kept.
103
- `blocked` means pi is waiting on an extension dialog (`blocked` holds
104
- its kind and title); the run is not finished.
105
- - `lastText`: the final message, capped at 64 KiB.
106
- - `sessionFile`: the agent's pi session file, holding the full
107
- transcript (absent for an ephemeral pi or an older extension).
173
+ ### With no multiplexer
108
174
 
109
- Exit codes: `0` met, `5` timeout, `6` pane died, `7` blocked on a dialog. Non-pi agents have no
110
- `lastText`; read the pane with `mu agent read helper-1 -w scratch -n 80`.
175
+ `mu delegates run <call-id>` runs one registered call in a child
176
+ `pi --mode rpc` in the foreground: no tmux, no herdr, no pane. Register
177
+ the call first (`mu delegates register <call-id> --caller <id> --text -`),
178
+ then run it; it sends once, waits, records the verdict, report and close
179
+ on the call's task, and prints the child's log and session paths.
180
+ SIGINT cancels. `mu_delegate` does this by itself when no tmux or
181
+ herdr is installed (see above).
111
182
 
112
183
  ## Keep a helper
113
184
 
114
185
  Pass `keep: true`, or spawn a named agent in `scratch`. It is created
115
186
  on first spawn, needs no tasks, and cannot be `init`ed. Its `mu-scratch`
116
187
  session stays open after the last agent closes; remove it with
117
- `mu workstream teardown scratch --yes`.
188
+ `mu workstream teardown scratch` (preview), then `--if <rev>`.
118
189
 
119
190
  ```bash
120
191
  mu agent spawn helper -w scratch
121
192
  mu agent send helper -w scratch 'Watch CI on PR 1234 and tell me when it is green'
122
193
  mu agent read helper -w scratch -n 50
123
- mu agent close helper -w scratch
194
+ mu agent close helper -w scratch # preview; prints rev=<n>
195
+ mu agent close helper -w scratch --if <n> # close it
124
196
  ```
125
197
 
126
198
  A watcher's chat context does not survive compaction. Log each tick
@@ -146,7 +218,7 @@ pane.
146
218
  | Steer mid-run | no | `mu agent send`; stop with `mu agent abort` |
147
219
  | Keep talking after it answers | no | yes, with `keep: true` |
148
220
  | Transcript | collapses into a result | a normal pi session log |
149
- | If the work grows | re-brief a new agent | same task DAG and workspaces |
221
+ | If the work grows | re-brief a new agent | same task DAG and worktrees |
150
222
  | Cost | light | one pane and one pi process |
151
223
 
152
224
  For many tiny calls, a hidden subagent is lighter. mu bets that seeing
@@ -155,13 +227,16 @@ and steering agent work is worth a pane.
155
227
  ## When to stop delegating
156
228
 
157
229
  Use delegates when you only need the answer: reviewing someone's PR or
158
- a doc, a fact-check, a go/no-go. Nothing they find lands in the ops
159
- log, which is permanent and syncs to every machine.
230
+ a doc, a fact-check, a go/no-go. Findings stay in the answers and
231
+ never enter your workstream's task graph. Each call's prompt and
232
+ answer are a `scratch` task, which is in the ops log and syncs like any
233
+ task; `mu workstream teardown scratch` hides them and `mu db forget
234
+ scratch` deletes them.
160
235
 
161
236
  Move to a workstream when the findings become work agents will fix, or
162
237
  the job has dependencies or several stages: see
163
238
  [Getting started](getting-started.md) and
164
- [How to dispatch work](dispatch.md). There, `mu task wait` keys on the
239
+ [How to dispatch work](dispatch.md). There, `mu wait` keys on the
165
240
  task and has `--on-stall`. The agent-facing rules for both are in
166
241
  [recipes/findings.md](../../skills/mu/recipes/findings.md) and
167
242
  [recipes/tasks-or-calls.md](../../skills/mu/recipes/tasks-or-calls.md).
@@ -2,9 +2,7 @@
2
2
 
3
3
  This guide assumes you finished [Getting started](getting-started.md).
4
4
  The agent-facing loop and its traps are in
5
- [recipes/orchestrator-loop.md](../../skills/mu/recipes/orchestrator-loop.md). For several workers in
6
- one repo, see [waves](../../skills/mu/recipes/waves.md); for runs that
7
- last hours, see [long runs](../../skills/mu/recipes/long-run.md).
5
+ [recipes/orchestrator-loop.md](../../skills/mu/recipes/orchestrator-loop.md).
8
6
 
9
7
  ## Claim before you send
10
8
 
@@ -15,14 +13,14 @@ one-shot reviewer:
15
13
  mu task claim build -w auth --for worker-1
16
14
  ```
17
15
 
18
- `mu task wait` watches tasks, and the reaper returns a claimed task to
16
+ `mu wait` watches tasks, and the reaper returns a claimed task to
19
17
  `OPEN` when its pane dies. An unclaimed task gets neither. If no task
20
18
  exists, create one with `mu task add --note '<brief>'`.
21
19
 
22
20
  - `--for` takes a worker name or a qualified `<workstream>/<name>`.
23
21
  The worker stays in its own workstream. Only the ownership crosses.
24
- - Inside a worker's pane, bare `mu task claim <id>` uses the pane
25
- title as the worker name.
22
+ - Inside a worker's pane, bare `mu task claim <id>` claims for
23
+ `$MU_AGENT_NAME`, which spawn injects.
26
24
  - To do the task yourself, use `mu task claim <id> --self`.
27
25
 
28
26
  ## Pick the send mode
@@ -53,23 +51,73 @@ socket. Pick the mode by what the agent is doing:
53
51
  - `/new`, `/reload` and `/compact [instructions]` run inside pi through
54
52
  the socket and report pi's answer (for example `Nothing to compact`).
55
53
  They refuse with exit 4 while pi is busy; `--force` overrides. Any
56
- other slash command exits 2; add `--via mux` to type it into the pane.
54
+ other slash command exits 2.
57
55
  - If the socket does not answer, the send fails with exit 1 and
58
- pastes nothing. `--via mux` pastes into the pane on purpose.
59
-
60
- After a claim, spawn, or wait, the `Next:` block prints the right send.
56
+ pastes nothing.
57
+ - A send's `--json` carries `msgId`, `incarnation` and `delivery`
58
+ (`delivered`, or `unknown` in the error JSON of a send that got no
59
+ reply). Its `next` is ONE line, the exact wait: `mu wait 'agent:<ws>/<a>@<n>#<inc>'`.
60
+ The `#<inc>` pin refuses (exit 4) when the agent restarted: its run is gone, so
61
+ re-send the brief. `--wait` enters that wait at once: one JSON document, the wait's, with the
62
+ send's receipt as `data.sent`. A delivered send (also `spawn --send`, `spawn --task`,
63
+ `send --interrupt`, `task claim --for`) is registered for the caller, so a bare `mu wait`
64
+ finds it with no ref; `mu task claim <id> --for <w> --and-wait` dispatches and waits.
65
+ - A send written to the socket but never answered is checked, not
66
+ repeated: mu asks once for the `msgId` and either reports success
67
+ (`receipt: confirmed-after-timeout`) or exits 1 with `next` the receipt
68
+ check `mu agent check <a> <msgId> -w <ws> --json` (only while the agent the
69
+ send went to is still registered). That verb prints `accepted runs=<n>
70
+ at=<iso>` (0), `not-accepted` (3) or `unreachable` (1). Only `accepted`
71
+ is an answer: **`not-accepted` is not "unsent"**. The extension keeps
72
+ its last 64 ids, so an old send reads `not-accepted` after eviction,
73
+ and a send that is still in flight can too. Look at the pane
74
+ (`mu agent read`) before any resend.
75
+
76
+ After `mu task claim <id> --for <w>`, `next` is the send that hands the task over (`--fresh` for a pi worker).
61
77
  `mu agent spawn --send <text>` spawns and sends the first prompt in one
62
- call; `--next-free` takes the next free name when `<name>` is taken
78
+ call; with `--task <id>` it is one journaled attempt (below); `--next-free` takes the next free name when `<name>` is taken
63
79
  (`worker-1` → `worker-2`; the stem is cut to keep the name within 32
64
80
  chars, and it gives up with exit 4 when no free name is near).
65
81
 
82
+ ### Spawn for a task
83
+
84
+ `mu agent spawn <name> --task <id> --send <text>` spawns, **claims the task
85
+ for the new agent**, sends the text and pins it as the task's `brief` (kept
86
+ when the task has one), as one attempt. Without `--send` it sends the
87
+ task's own `brief` note (with the CLOSE footer, as `mu task auto` does), or
88
+ with no brief one line from its title that points at `mu task notes`. A journal (`spawn_receipts`) is
89
+ written before each step, so the same command never sends a second prompt.
90
+
91
+ - Same command again = replay: it returns the saved delivery
92
+ (`task.replay: true`, same `msgId`). `--attempt <key>` names the attempt
93
+ (default: the task id); a changed text or name under one key exits 4, and
94
+ reopened work needs a new key.
95
+ - Fails **before** the prompt could be written (no ctl, Claude's trust
96
+ dialog, a claim that lost the task, the extension refused): its own pane,
97
+ claim and worktree are rolled back, the key is reusable.
98
+ - Delivery **unknown** (written, no reply; the pane died after the write):
99
+ exit 1, the pane and the claim stay, `task.state` is `unknown`, and a
100
+ replay asks the extension once. Never reaped, never resent. Check it
101
+ with `mu agent check`, read the pane, then decide.
102
+ - A replay after the agent was deleted, or its name reused, reports the
103
+ historical delivery with `task.stale` (`deleted` | `replaced`); the
104
+ replacement is never claimed or sent to.
105
+ - The prompt goes only to the agent the spawn created (also plain
106
+ `spawn --send`): a replaced name, a closed task, or a task someone else
107
+ owns now refuses it (exit 4) with nothing sent.
108
+ - Another mu process running the same attempt exits 4 (`SpawnAttemptBusyError`);
109
+ retry and the replay returns its outcome.
110
+
66
111
  ### Non-pi agents
67
112
 
68
- Agents other than pi have no control socket, so mu pastes the text
69
- into the pane. To start a new session, send `/new` (codex: `/clear`),
70
- then the prompt. If mu prints `warning: ... was NOT submitted`, the
71
- agent has not seen the text. Read the pane before you wait. On a slow
72
- tmux link, raise `MU_SEND_DELAY_MS` (default 500 ms).
113
+ Agents other than pi have no control socket. On herdr, mu sends the
114
+ text with herdr's atomic `agent prompt`. To start a new session, send
115
+ `/new` (codex: `/clear`), then the prompt. If mu prints
116
+ `warning: ... was NOT submitted`, the agent has not seen the text.
117
+ Read the pane before you wait. On tmux, a send to a non-pi agent exits
118
+ 4 (`AgentSendUnsupportedError`): spawn it on herdr (`MU_MUX=herdr`), start
119
+ it with the prompt as an argument, or use pi
120
+ ([other agent CLIs](other-agent-clis.md)).
73
121
 
74
122
  ## Write the brief
75
123
 
@@ -94,55 +142,66 @@ quoted heredoc: `mu agent send worker-1 - <<'EOF'`; see
94
142
  [brief](../../skills/mu/recipes/brief.md#quoting). To see only what the worker wrote after the claim, run
95
143
  `mu task notes build -w auth --since-claim`.
96
144
 
97
- ## Give each worker a workspace
145
+ ## Give each worker a worktree
98
146
 
99
- `mu agent spawn --workspace` creates a jj, sl, or git worktree for the
100
- agent (`cp -a` outside a repo). You cherry-pick from it.
147
+ `mu agent spawn --worktree` creates a git worktree for the agent and starts
148
+ its pane there: the worker's cwd is its worktree. Outside a git repo it
149
+ fails with exit 4. `--from <ref>` picks the starting commit and `--root <repo>`
150
+ the repo; both default to the HEAD of the checkout you run in (a linked one included). You cherry-pick from it.
101
151
 
102
- Refresh the workspace between tasks. The rebase keeps the agent's pi
103
- context:
152
+ Refresh the worktree between tasks. The rebase keeps the agent's pi
153
+ context. Before a `--fresh` send:
104
154
 
105
155
  ```bash
106
- mu workspace refresh worker-1 -w auth
156
+ cwd=$(mu agent list -w auth --json | jq -r '.agents[] | select(.name == "worker-1") | .cwd')
157
+ git -C "$cwd" fetch && git -C "$cwd" rebase origin/HEAD
107
158
  ```
108
159
 
109
- It rebases onto the remote's main (`origin/HEAD`); without a remote,
110
- pass `--from main`. It refuses on a dirty tree. On a conflict it exits 5:
111
- git and sl abort the rebase and leave the workspace as it was, while jj
112
- keeps the rebase with the conflicts committed in place. After you resolve,
113
- run refresh again so mu records the new base. To throw the workspace away
114
- instead, run `mu workspace free worker-1 -w auth`.
115
-
116
- Claim and send warn when the worker's workspace is 10 or more commits
117
- behind main. `--strict-staleness` makes that a refusal (exit 4).
160
+ Use `origin/HEAD` as the base, or local main when you merged locally. On a
161
+ conflict, run `git -C "$cwd" rebase --abort` and tell the human. To throw
162
+ the worktree away instead, preview `mu agent close worker-1 -w auth --discard`
163
+ and apply it with `--if <n>`.
118
164
 
119
165
  ## Wait for the first task to close
120
166
 
121
167
  Wait on every in-flight task and handle the first one that closes:
122
168
 
123
169
  ```bash
124
- mu task wait auth/build auth/docs --first --on-stall exit --json
170
+ mu wait task:auth/build task:auth/docs
125
171
  ```
126
172
 
127
- - `--first` prints the closed ref and fills `firing` in `--json`.
128
- `--any` leaves `firing` null even on success.
129
- - `nextSteps[0]` is the cherry-pick command for the worker's new
130
- commits. If the worker closed without committing, it says so.
131
- - Exit codes: `0` met, `5` timeout, `6` the owner's pane died,
132
- `7` the owner sat in `needs_input` for `--stuck-after` seconds
133
- (default 120, or 5 for a pi worker read over its control socket). Exit 7 is the default; `--on-stall warn` keeps
134
- polling instead.
135
-
136
- Exit 7 has several causes: the worker finished but did not close, it
137
- asked a question, or it hit a prompt. In each case, run the exit's
138
- `Next:` first. For a pi owner, it starts with
139
- `mu agent wait <owner> --after-runs <runs-1> --json`, which prints the
140
- last answer at once. Then it shows `mu agent read <owner>`, for the
141
- dialogs and crashes that only the pane shows.
142
-
143
- Pipeline the work: merge one task, run your tests on the merged tree,
144
- then dispatch the next task. Waiting for a whole wave hides partial
145
- progress.
173
+ `mu wait` prints ONE JSON document, with no `--json` flag. Refs are typed
174
+ (`task:`, `agent:`, `delegate:`); with none, it waits on what you started.
175
+
176
+ - `data.firing` is the event: `closed`, `settled`, `input`, `dead`, `stall`,
177
+ `delegate`, or `heartbeat` on a timeout (`ok:true`, `timedOut`, exit 0).
178
+ - `data.snapshots` are the refs' real states; `data.resume` is the command
179
+ that keeps waiting, with every flag you gave. Run it as printed: it takes
180
+ no other flag (only a matching `-w`). When two watched owners die in one
181
+ wait, only the first fires; follow `resume` to hear the second. A fresh
182
+ `mu wait` with the same refs starts a new anchor and reports the earlier
183
+ death as history.
184
+ - `data.cursor` is what this result consumed per ref (`incarnation`, `runs`);
185
+ the next wait starts after it, so the same event is never reported twice.
186
+ `cursorCut` counts entries dropped to fit the 4 KB result.
187
+ - `close:{applied:false, reason:"no CLOSE block…"}` on a settled worker
188
+ is not a failure: the worker sent no CLOSE block, often because it
189
+ closed its own task. Read the snapshot's task status.
190
+ - `next` is the stored resume while something is still owed, else null.
191
+ - Exit codes: `0` event or timeout, `6` the owner's pane died, `7` the owner
192
+ sat in `needs_input` for `--stuck-after` seconds (default 120, or 5 for a pi
193
+ worker read over its control socket), `130`/`143` SIGINT/SIGTERM (the
194
+ snapshot and `resume` are still printed). `--on-stall warn` flags the stall
195
+ on the snapshot and keeps waiting; `steer` sends the stalled pi worker you
196
+ spawned one fixed reminder and keeps waiting; `release` frees its task and
197
+ ends the wait. `data.action` (and a stderr line) says `sent`, `released`,
198
+ `refused` or `unknown`; both refuse a worker you did not spawn or a task not
199
+ permitted with `mu task auto`. `mu task wait` is the same wait over task
200
+ refs.
201
+ - `--all` waits for every ref; `--until-text <re>` waits for a run's final
202
+ text; `--wave <name>` waits on your delegate wave in any workstream
203
+ (`-w` does not narrow it) and `data.tally` says `6/12 CONFIRMED, ...`;
204
+ a name none of your calls carry is `no such wave` (exit 3).
146
205
 
147
206
  ## Close and park tasks
148
207
 
@@ -153,8 +212,11 @@ mu task park polish -w auth --why "after the release"
153
212
  mu task release build -w auth
154
213
  ```
155
214
 
156
- - Closed substates other than `done` need `--why`. Every `CLOSED`
157
- substate satisfies a blocker.
215
+ - `close` needs `--evidence "<command + result>"` for `done`; the other
216
+ substates need `--why`, which is their evidence. `done` also refuses
217
+ while a blocker is open (exit 4, `mu task tree <id>` lists them); the
218
+ other substates may close over open blockers. Every `CLOSED` substate
219
+ satisfies a blocker.
158
220
  - Deciding a finding (`accept`, or `close --as rejected|wontfix|duplicate`)
159
221
  with a reason under 40 characters and no `VERDICT:` or `REFUTER` note
160
222
  prints a warning. The exit code stays the same. A `REJECTED` or `SUPERSEDED`
@@ -162,7 +224,40 @@ mu task release build -w auth
162
224
  - `--if-ready` closes only when every blocker is closed. Otherwise it
163
225
  lists the open blockers and exits 0.
164
226
  - A parked task leaves the ready set, and its dependents keep waiting.
227
+ - `mu human-needed <reason>` records a parked `human` task for a decision only a
228
+ person can make. It never becomes ready and resolves only by `mu task close`
229
+ (unpark, claim and a CLOSE block are refused).
165
230
  - `release` clears the owner and returns `IN_PROGRESS` to `OPEN`.
166
231
 
232
+ ## Authorise tasks for the executor
233
+
234
+ ```bash
235
+ mu task auto build --cli pi --max 2 -w auth
236
+ mu task auto --blockers-of umbrella --cli pi -w auth
237
+ mu task auto build --off -w auth
238
+ ```
239
+
240
+ Ready is not permission: the executor acts only on an `auto` task, and only on
241
+ the machine that authorised it. `--off` keeps the run counter.
242
+
243
+ ```bash
244
+ mu next --dry -w auth # the plan; no pane, socket or write
245
+ mu next --hold -w auth # dispatch, then wait; recover deaths and API errors
246
+ mu next --workers 2 -w auth # never more than 2 working; a CLOSED task's idle pane is free
247
+ ```
248
+
249
+ `mu next` also recovers. A worker whose pane died is reaped and its task retried as a new
250
+ attempt; a live worker whose run ended in an API error is sent its brief again in place (never
251
+ reaped, never duplicated). Each retry costs one run of the ceiling; a remote worker's tree is never
252
+ touched. At the ceiling, or for anything it will not guess, it reports an `attention` move.
253
+
254
+ `mu next --refute [--refute-cli <key>]` also launches ONE checker per task a worker closed as `done`
255
+ (a delegate call in `scratch`, wave `refute-<ws>`, briefed from the task's pinned brief and its
256
+ report). Its `VERDICT:` is recorded on the task before the call closes; the checker never accepts,
257
+ reopens or closes the work, and a wontfix/rejected close gets none. It needs a caller identity
258
+ (`PI_SESSION_ID` or a managed agent) and a cli that speaks ctl (default: the task's own). A repeat
259
+ `mu next --refute` reads a running checker and records its answer (or its death or timeout as
260
+ UNVERIFIED); `--dry` lists the owed checks. `mu delegates tally --wave refute-<ws>` counts them.
261
+
167
262
  To wait on something outside the repo, such as an upstream release,
168
263
  block on a placeholder task and close it when the thing lands.