@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.
- package/AGENTS.md +208 -599
- package/README.md +125 -329
- package/dist/cli.js +108 -78
- package/dist/cli.js.map +1 -1
- package/dist/extension/mu-pi.js +421 -56
- package/dist/extension/mu-pi.js.map +1 -1
- package/dist/index.d.ts +36 -10
- package/dist/index.js +89 -67
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +176 -1072
- package/docs/ROADMAP.md +88 -169
- package/docs/VISION.md +205 -415
- package/docs/VOCABULARY.md +204 -466
- package/docs/architecture/control-socket.md +133 -0
- package/docs/architecture/dag.md +113 -0
- package/docs/architecture/mux.md +162 -0
- package/docs/architecture/ops-log.md +140 -0
- package/docs/architecture/sdk.md +185 -0
- package/docs/architecture/sync.md +129 -0
- package/docs/architecture/tui.md +146 -0
- package/docs/guide/README.md +30 -0
- package/docs/guide/backends.md +61 -0
- package/docs/guide/cleanup.md +74 -0
- package/docs/guide/delegate.md +87 -0
- package/docs/guide/dispatch.md +144 -0
- package/docs/guide/getting-started.md +180 -0
- package/docs/guide/recovery.md +135 -0
- package/docs/guide/remote.md +74 -0
- package/docs/guide/sql.md +76 -0
- package/docs/guide/stop-a-worker.md +64 -0
- package/docs/guide/sync.md +78 -0
- package/docs/guide/tui.md +98 -0
- package/docs/guide/upgrade.md +76 -0
- package/docs/history/CHANGELOG-pre-3.md +4866 -0
- package/docs/reference/env.md +87 -0
- package/docs/reference/naming.md +82 -0
- package/docs/specs/2026-09-28-agent-state-from-murmur.md +1 -1
- package/docs/specs/2026-09-29-task-substates.md +1 -1
- package/docs/specs/2026-10-03-keep-driving-nudge.md +142 -0
- package/package.json +2 -1
- package/prompts/mu-refute.md +8 -0
- package/prompts/mu-research.md +8 -0
- package/prompts/mu-review.md +8 -0
- package/prompts/mu-rules-audit.md +8 -0
- package/prompts/mu-tournament.md +9 -0
- package/prompts/ultrathink.md +9 -0
- package/skills/mu/SKILL.md +126 -255
- package/skills/mu/recipes/adversarial-review.md +83 -0
- package/skills/mu/recipes/brief.md +53 -0
- package/skills/mu/recipes/codemode-driver.md +54 -0
- package/skills/mu/recipes/deep-research.md +52 -0
- package/skills/mu/recipes/fan-out.md +36 -0
- package/skills/mu/recipes/hypothesis-panel.md +40 -0
- package/skills/mu/recipes/long-run.md +20 -0
- package/skills/mu/recipes/loop-until-done.md +38 -0
- package/skills/mu/recipes/orchestrator-loop.md +87 -0
- package/skills/mu/recipes/plan.md +54 -0
- package/skills/mu/recipes/recovery.md +26 -0
- package/skills/mu/recipes/refute.md +49 -0
- package/skills/mu/recipes/remote-workers.md +292 -0
- package/skills/mu/recipes/review-panel.md +57 -0
- package/skills/mu/recipes/rules-audit.md +70 -0
- package/skills/mu/recipes/tournament.md +37 -0
- package/skills/mu/recipes/triage.md +38 -0
- package/skills/mu/recipes/ultrathink.md +73 -0
- package/skills/mu/recipes/watcher.md +16 -0
- package/skills/mu/recipes/waves.md +19 -0
- package/skills/mu/recipes/worker.md +24 -0
- package/docs/HANDOVER.md +0 -486
- package/docs/USAGE_GUIDE.md +0 -2738
- package/skills/mu/REMOTE_WORKERS.md +0 -617
package/skills/mu/SKILL.md
CHANGED
|
@@ -14,25 +14,19 @@ not in `--help` do not exist.
|
|
|
14
14
|
|
|
15
15
|
## Output + JSON shapes
|
|
16
16
|
|
|
17
|
-
Default output
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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** —
|
|
31
|
-
|
|
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** —
|
|
34
|
-
|
|
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;
|
|
46
|
-
ready
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 <
|
|
64
|
-
timeout, 6 pane died.
|
|
65
|
-
- For a watcher,
|
|
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
|
|
72
|
-
prompt: add `--approve` to `MU_<CLI>_COMMAND
|
|
73
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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`, `
|
|
128
|
-
`auditor-1`, `planner-1`.
|
|
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
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
|
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
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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`
|
|
305
|
-
|
|
306
|
-
|
|
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,
|
|
311
|
-
IN_PROGRESS tasks revert to OPEN with a `[reaper]` note
|
|
312
|
-
|
|
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
|
-
|
|
347
|
-
|
|
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
|
-
##
|
|
192
|
+
## You are a worker
|
|
350
193
|
|
|
351
|
-
|
|
352
|
-
|
|
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
|
|
359
|
-
activity log. Keep edges within one workstream
|
|
360
|
-
|
|
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.
|