@martintrojer/mu 0.3.1 → 0.4.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.
@@ -5,118 +5,110 @@ description: Manage a persistent crew of pi agents in tmux panes coordinated thr
5
5
 
6
6
  # mu — Multi-agent orchestration
7
7
 
8
- `mu` is a CLI for managing a persistent crew of AI agents in tmux
9
- panes coordinated through a task graph. State lives at
10
- `<XDG_STATE_HOME or ~/.local/state>/mu/mu.db` (SQLite).
11
-
12
- **Output:**
13
- - Default: every verb prints a textual card on stdout AND a `Next:`
14
- block of suggested follow-up commands. Read both.
15
- - `--json` (every verb): success → one object on stdout. Collection
16
- reads (`task list`, `workspace commits`, `archive search`, ...)
17
- emit `{items: T[], count: number}`; singletons keep named fields.
18
- Carve-outs: `mu sql --json` is bare-array rows; `mu log --tail`
19
- is NDJSON (one object per line). Errors →
20
- `{error,message,nextSteps,exitCode}` on stderr; validation errors
21
- ALSO carry `usage` (structured `--help`). **`nextSteps` survives
22
- in JSON** `mu task wait --first --json` literally puts the
23
- cherry-pick command in `.nextSteps[0].command`.
24
-
25
- **Trust `mu --help` and `mu <verb> --help` over this skill** if they
26
- disagree. Verbs not in `--help` do not exist.
8
+ `mu` manages long-lived AI agents in tmux panes, coordinated by a
9
+ SQLite task DAG at `<XDG_STATE_HOME or ~/.local/state>/mu/mu.db`.
10
+
11
+ **Trust `mu --help` / `mu <verb> --help` over this skill.** Verbs
12
+ not in `--help` do not exist.
13
+
14
+ ## Output + JSON shapes
15
+
16
+ Default output: textual card on stdout plus a `Next:` block. Read
17
+ both.
18
+
19
+ `--json` exists on every verb:
20
+ - Success: one stdout object.
21
+ - Collection reads (`task list`, `workspace commits`, `archive
22
+ search`, ...): `{items: T[], count: number}`.
23
+ - Singletons keep named fields.
24
+ - `mu sql --json`: bare array rows.
25
+ - `mu log --tail`: NDJSON (one object per line).
26
+ - Errors: `{error,message,nextSteps,exitCode}` on stderr.
27
+ - Validation errors also include structured `usage`.
28
+ - **`nextSteps` survives in JSON**. `mu task wait --first --json`
29
+ puts the cherry-pick command in `.nextSteps[0].command`.
27
30
 
28
31
  ## Vocabulary
29
32
 
30
- - **workstream** — unit of organization; one tmux session
31
- (`mu-<name>`).
32
- - **agent** — a named worker in a tmux pane (you may be one).
33
- - **task** a node in the DAG; mandatory `impact` (1–100) and
34
- `effort_days`. Status: `OPEN`, `IN_PROGRESS`, `CLOSED` (the only
35
- state that satisfies a `--blocked-by` edge), `REJECTED` (terminal
36
- won't-do; still blocks downstream), `DEFERRED` (parked; still
37
- blocks downstream).
38
- - **claim / release** — atomic CAS take/clear of `tasks.owner`.
33
+ - **workstream** — unit of organization; tmux session `mu-<name>`.
34
+ - **agent** — named worker in a tmux pane (you may be one).
35
+ - **task** — DAG node with mandatory `impact` (1–100) and
36
+ `effort_days`. Status: `OPEN`, `IN_PROGRESS`, `CLOSED`
37
+ (satisfies `--blocked-by`), `REJECTED` (terminal won't-do; still
38
+ blocks), `DEFERRED` (parked; still blocks).
39
+ - **claim / release** atomic take/clear of `tasks.owner`.
39
40
  - **free** — mark the *agent* available (`mu agent free`); pane
40
- untouched. Different from release: free is about the agent,
41
- release is about the task.
42
- - **note** — append-only context attached to a task; survives
43
- across sessions.
44
- - **track** — an independent subtree of the DAG (parallel-track
45
- detection; visible in mission control).
46
- - **workspace** — per-agent isolated VCS working copy under
41
+ untouched. **Release is about the task; free is about the agent.**
42
+ - **note** append-only task context; survives sessions.
43
+ - **track** — independent DAG subtree; don't spawn more agents than
44
+ ready tracks.
45
+ - **workspace** — per-agent VCS copy under
47
46
  `<state-dir>/workspaces/<workstream>/<agent>/`.
48
47
 
49
- ## When to reach for mu
50
-
51
- **Use mu for:**
52
- - Multi-phase investigations where context loss across the session
53
- would hurt (benchmark + profile + fix + review + parity).
54
- - Tasks worth gating with review (DAG enforces
55
- `implement → review → address → ship`).
56
- - Parallel read-only/audit work alongside heavier tasks.
57
- - Implementation + reviewer/tester splits with isolated workspaces.
58
- - Work likely to survive context compaction — durable task notes
59
- are the project memory the next agent inherits.
48
+ ## When to use mu
60
49
 
61
- **Do NOT use mu for:**
62
- - Tiny direct edits (5-minute one-file changes).
63
- - One-off local inspection / single shell commands.
64
- - Single-context work where no durable coordination is needed.
50
+ Use mu for multi-phase work, review-gated work (`implement → review
51
+ address ship`), parallel audits, implementation/reviewer splits,
52
+ and anything that must survive context compaction via task notes.
65
53
 
66
- The orchestrator's first decision is whether to reach for mu at all.
54
+ Do **not** use mu for tiny one-file edits, one-off local inspection,
55
+ or single-context work where durable coordination adds ceremony.
67
56
 
68
57
  ## Mental model
69
58
 
70
- ### One workstream = one tmux session
71
-
72
- Named `mu-<workstream>`. Every agent is a pane in that session.
73
- Multiple workstreams = multiple tmux sessions, partitioned in the
74
- DB by `workstream`.
59
+ ### Workstreams, DAGs, tracks
75
60
 
76
- ### The task DAG drives coordination
61
+ One workstream = one tmux session named `mu-<workstream>`. Every
62
+ agent is a pane in that session. DB rows are partitioned by
63
+ `workstream`.
77
64
 
78
65
  One edge type: `blocks`. `mu task block A --by B` means **B blocks
79
- A** (B must close first). Built-in views: `ready`, `blocked`,
80
- `goals`. Bare `mu` shows **parallel tracks** with **automatic
81
- diamond-merge**: goals sharing a prerequisite collapse into one
82
- track. Don't spawn more agents than there are tracks.
83
-
84
- ### Per-agent workspaces stop trampling
85
-
86
- For two agents editing the same project, use `--workspace` on spawn.
87
- Each gets an isolated working copy under
88
- `<state-dir>/workspaces/<workstream>/<agent>/`. Auto-detects
89
- jj/sl/git; `cp -a` for non-VCS. Workspaces are NOT freed when you
90
- close an agent run `mu workspace free <agent>` explicitly. Between
91
- waves, `mu workspace refresh <agent>` rebases the dir onto fresh
92
- main without killing the agent's LLM context; `mu workspace commits
93
- <agent>` lists since-fork commits for cherry-picking.
94
-
95
- **Default rule:** if an agent may edit/build/test/generate
96
- artifacts while another agent is active in the same repo, spawn
97
- with `--workspace`. Reserve the main checkout for orchestration.
98
- Two builds in the same checkout corrupt each other's artifacts.
99
-
100
- ### Name agents by role, not by person
101
-
102
- Use `worker-1`, `worker-2`, `reviewer-1`, `scout-1`, `auditor-1`,
103
- `planner-1`. Smallest unused suffix. Avoid human names —
104
- anthropomorphizing makes coordination prompts ambiguous ("send
105
- follow-up to alice" vs "send to worker-1").
66
+ A**. Built-in views: `ready`, `blocked`, `goals`. Bare `mu` shows
67
+ parallel tracks with automatic diamond-merge: goals sharing a
68
+ prerequisite collapse into one track.
69
+
70
+ ### Workspaces prevent trampling
71
+
72
+ If an agent may edit/build/test/generate artifacts while another
73
+ agent is active in the same repo, spawn with `--workspace`. Keep the
74
+ main checkout for orchestration. Two builds in one checkout corrupt
75
+ each other's artifacts.
76
+
77
+ Workspaces auto-detect jj/sl/git; non-VCS uses `cp -a`. They are
78
+ auto-freed on `mu agent close` **iff clean**: no uncommitted changes
79
+ and no commits since fork. Non-clean close fails with
80
+ `WorkspacePreservedError`; then use `mu workspace free <agent>` or
81
+ `mu agent close <agent> --discard-workspace` (lossy).
82
+
83
+ Between waves:
84
+ - `mu workspace refresh <agent>` rebases onto fresh main without
85
+ killing LLM context.
86
+ - `mu workspace recreate <agent>` = free + create for fresh
87
+ single-purpose workers; `--force` discards dirty edits.
88
+ - `mu workspace commits <agent>` lists since-fork commits for
89
+ cherry-picking.
90
+
91
+ Claim/send warn when a target workspace is ≥10 commits behind main;
92
+ refresh first or pass `--strict-staleness` in scripts.
93
+
94
+ ### Agent names
95
+
96
+ Use roles: `worker-1`, `worker-2`, `reviewer-1`, `scout-1`,
97
+ `auditor-1`, `planner-1`. Smallest unused suffix. Avoid human names.
106
98
 
107
99
  ### Task note contract
108
100
 
109
- Every delegated task should end with a note containing six fields
110
- (omit only the ones genuinely N/A):
101
+ End every delegated task with a note containing the applicable
102
+ fields:
111
103
 
112
- ```
113
- FILES: paths inspected/changed (with line ranges if precise)
114
- COMMANDS: shell commands run + exit codes
104
+ ```text
105
+ FILES: paths inspected/changed (line ranges if precise)
106
+ COMMANDS: commands run + exit codes
115
107
  FINDINGS: what you observed
116
108
  DECISION: what you chose, and why
117
- NEXT: follow-on tasks the next agent should know about
118
- VERIFIED: how you confirmed it works (test names, command output)
119
- ODDITIES: anything weird you saw but didn't act on
109
+ NEXT: follow-on tasks
110
+ VERIFIED: tests/checks/output
111
+ ODDITIES: weird things not acted on
120
112
  ```
121
113
 
122
114
  Then close with grounding:
@@ -125,399 +117,238 @@ Then close with grounding:
125
117
  mu task close <id> -w <ws> --evidence "tests pass: cargo test exit 0"
126
118
  ```
127
119
 
128
- This turns the DAG from a coordination tool into a durable project
129
- log. Future agents can `mu task notes <id>` to reconstruct the why
130
- without reading the diff.
120
+ Future agents can reconstruct context via `mu task notes <id>`.
131
121
 
132
122
  ## Orchestrator loop
133
123
 
134
124
  Every turn:
135
125
 
136
- 1. `mu state -w <ws>` — read the card. Agents, IN_PROGRESS, ready,
126
+ 1. `mu state -w <ws>` — read agents, IN_PROGRESS, ready tasks,
137
127
  parallel tracks.
138
- 2. Don't spawn more agents than independent ready tracks.
139
- 3. **Claim before sending — even for one-shot reviewers / scouts.**
140
- `mu task claim <id> -w <ws> --for <agent> --evidence "..."`. No
141
- task = nothing for `mu task wait` to wait on; agent status flips
142
- are too noisy. If the dispatch has no task, `mu task add` first.
143
- 4. Send task-specific instructions: task ID, files/notes to read,
144
- scope guards, the task note contract. End with the loud
145
- `⚠️ FINAL ACTION` block (see lessons below).
146
- 5. Wait for *one* task to close (`--first`), cherry-pick, return
147
- control. Do NOT loop in your own shell — see lessons.
148
- 6. On close, repeat from 1.
149
-
150
- ## Hard-earned dispatch lessons
151
-
152
- Every one of these came from real failure modes. Re-read before
153
- running a wave.
154
-
155
- - **Pipeline cherry-picks; DON'T BARRIER.** This is the single most
156
- important rule. One wait, one cherry-pick, one verify, return
157
- control. Do NOT `mu task wait umbrella_wave_X` and block until
158
- everything in the wave finishes you give up the ability to
159
- react per-finish, and you can't surface partial progress.
160
- Don't loop in a shell script either; that's a barrier with extra
161
- steps.
162
-
163
- ```bash
164
- # YES pipeline (returns the moment one task closes)
165
- closed=$(mu task wait t1 t2 t3 -w ws --any --first --json \
166
- --on-stall exit | jq -r .firing.qualifiedId)
167
- # cherry-pick that worker's commit, verify, return control.
168
- # Next turn: same wait on the smaller set.
169
- ```
170
-
171
- The recipe is also in `mu task wait`'s `nextSteps` — `jq` it out.
172
-
173
- - **Refresh workspaces between waves.** `mu workspace refresh
174
- <agent>` rebases the agent's dir onto fresh main without killing
175
- the LLM context. The `behind` column in `mu workspace list` shows
176
- the cost of skipping it. Worker ships clean code against a stale
177
- parent otherwise; you find out at cherry-pick time.
178
-
179
- - **Cherry-pick worker commits onto main, don't merge.** Stale-parent
180
- worker branches drag in re-reverts of everything they missed.
181
-
182
- - **Bucket fix waves by file cluster, not by severity.** Two workers
183
- editing the same file = cherry-pick conflicts at merge time. mu
184
- doesn't help you here; you have to know the codebase.
185
-
186
- - **End every dispatch prompt with a loud `⚠️ FINAL ACTION: git
187
- commit -am '...' THEN mu task close <id> --evidence '...'`.**
188
- Without the literal reminder, agents commit + report success in
189
- chat without running the typed close, and `mu task wait` hangs.
190
-
191
- - **`--on-stall exit` is the unattended-orchestrator escape.**
192
- Default `mu task wait` warns on a stuck worker and KEEPS POLLING.
193
- In any non-interactive flow (wrapping policies, cron, long
194
- pipelines, multi-step orchestration), pass `--on-stall exit`:
195
- exits 7 (`STALL_DETECTED`) the moment the predicate fires.
196
- Distinct from exit 6 (`REAPER_DETECTED`, dead pane —
197
- re-dispatch); exit 7 is the ambiguous sibling (alive but idle
198
- decide whether to poke, release, or roll over). If both fire in
199
- the same poll, exit 6 wins.
200
-
201
- - **Cross-workstream `mu task wait` is built in.** Pass qualified
202
- refs `<workstream>/<name>` directly; `-w` is dropped when every
203
- ref is qualified, and the per-poll reconcile loops over every
204
- workstream in the set.
205
-
206
- - **Cross-workstream `mu task claim --for` is built in.** When
207
- per-workstream worker pools leave a free worker in workstream A
208
- and a queued task in workstream B, dispatch with `mu task claim X
209
- -w B --for A/worker-1`. The agent stays in A; only the task's
210
- `owner_id` crosses. No need to close + re-spawn (which loses LLM
211
- context) or reach for `mu sql`.
212
-
213
- - **Keep dispatch prompts terse.** Workers have the same skills as
214
- the orchestrator and can `mu task notes <id>` for the full spec.
215
- The prompt only needs: who they are, the task id, the workspace
216
- path, the validate command, and the loud final-action block.
217
-
218
- - **Idle agent ( glyph; alive but assigned, no recent progress)** —
219
- see scrollback via `mu agent show <name> -n N`; recover via
220
- `mu agent send <name> '<retry>'` OR `mu task release <id>` (bare
221
- release auto-flips IN_PROGRESS OPEN; `--reopen` is only for
222
- un-closing CLOSED/REJECTED/DEFERRED). Tunable via
223
- `MU_IDLE_THRESHOLD_MS` (default 5 min).
224
-
225
- ## Parallelisation decision table
226
-
227
- | Situation | Action |
228
- |-----------|--------|
229
- | One ready task / one track | Reuse one existing agent |
230
- | Multiple independent ready tasks | Spawn one agent per ready track; cherry-pick each as it closes (don't barrier) |
231
- | CPU-heavy benchmark in progress | Only parallelise read-only / audit tasks |
232
- | Two agents editing/building/testing same repo | Use `--workspace` |
233
- | Agent only reading docs/source | `--cli pi` (or operator alias) without `--workspace` is OK |
234
- | Agent making code changes | `--workspace` strongly preferred |
235
- | Agent reviewing/testing another agent's patch | Separate `--workspace` (or wait for the patch to merge) |
236
-
237
- ## Universal flags (worth knowing without `--help`)
238
-
239
- - **`-w, --workstream <name>`** explicit > `$MU_SESSION` > current
240
- tmux session minus `mu-` prefix > error. On verbs that take an
241
- entity by id, `-w` is a SCOPE check; on picker verbs (`mu task
242
- next`, `mu agent list`), it picks WHICH.
243
- - **Qualified entity refs** — every verb accepts
244
- `<workstream>/<name>` in addition to bare `<name>`. The qualified
245
- form skips `-w` resolution: `mu task show ws/foo` works from any
246
- shell. Mixing a qualified ref with a non-matching `-w` errors out
247
- (exit 2). When a bare name appears AND no `-w` resolves AND ≥2
248
- workstreams contain that name, mu raises `NameAmbiguousError`
249
- (exit 4) and lists every candidate as a one-paste fix.
250
- - **`--evidence "<text>"`** — on `task close / open / claim /
251
- release`. Recorded verbatim in the auto-emitted event payload.
252
- Use it for grounding ("tests pass: cargo test exit 0").
253
- - **`--json`** — on every verb. Use it whenever you compose mu
254
- output into another command. `nextSteps` survives in JSON.
255
-
256
- ## CLI overview (one line each; trust `mu <verb> --help`)
257
-
258
- - **Workstream**: `init`, `list`, `destroy` (auto-snapshots and
259
- `--archive <label>` to preserve graph atomically), `export`,
260
- `import`.
261
- - **Agents**: `spawn` (`--workspace`, `--role read-only`,
262
- `--command`), `send`, `read`, `show`, `list`, `close`, `free`.
263
- **`mu adopt <pane-id|title>`** registers an orphan pane as a
264
- managed agent.
265
- - **Tasks**: `add`, `list`, `next`, `show`, `tree`, `notes`, `note`,
266
- `claim` (`--for | --self`), `release` (`--reopen` to un-close),
267
- `close` (`--if-ready` = no-op unless every blocker terminal),
268
- `open`, `reject`, `defer`, `block`, `unblock`, `update`,
269
- `reparent`, `wait`, `delete` (two-phase; `--yes` commits).
270
- Edge direction: `block <blocked> --by <blocker>`.
271
- - **Self (in-pane)**: `mu me`, `mu me tasks`, `mu me next`.
272
- - **Workspace**: `create`, `list` (`behind` column), `refresh`
273
- (rebase onto fresh base, agent stays alive), `commits` (since-fork
274
- `<sha> <subject>`; `--json` for piping), `free`, `path`
275
- (`cd $(mu workspace path X)`), `orphans`.
276
- - **Activity log**: `mu log "text"` (write), `mu log -n N` (read),
277
- `mu log --tail` (subscribe). Don't pipe `--tail` for waits — use
278
- `mu task wait`.
279
- - **Snapshots/undo**: every destructive verb auto-snapshots first.
280
- `mu undo --yes` restores the latest (DB only, NOT tmux/workspace
281
- dirs). `mu snapshot list/show/prune/delete`.
282
- - **Archives**: `create <label>`, `list`, `show`, `add <label> -w
283
- <ws> [--destroy]` (idempotent; preserves task graph atomically),
284
- `remove`, `delete`, `search`, `export`. Labels globally unique.
285
- - **Escape hatch + state**: `mu sql "<query>"` for anything not yet
286
- typed. `mu` alone = `mu state --mission`. `mu state` has `--hud`,
287
- `--mission`, `--all`, `--json`. `mu doctor` for health.
128
+ 2. Spawn at most one agent per independent ready track.
129
+ 3. **Claim before sending — even one-shot reviewers/scouts.**
130
+ `mu task claim <id> -w <ws> --for <agent> --evidence "..."`.
131
+ If no task exists, `mu task add` first. Agent status is noisy;
132
+ task ownership is durable and waitable.
133
+ 4. Send terse instructions: task id, files/notes to read, workspace
134
+ path, validation command, scope guards, task note contract.
135
+ 5. End with a loud final-action block:
136
+
137
+ ```text
138
+ ⚠️ FINAL ACTION
139
+ git commit -am '...' THEN
140
+ mu task close <id> -w <ws> --evidence '...'
141
+ ```
142
+
143
+ 6. `mu task wait ... --first --any --json --on-stall exit`.
144
+ 7. Cherry-pick the closed worker's **new** commit(s), verify, return
145
+ control. Do not barrier or loop in shell.
146
+ 8. Repeat from `mu state`.
147
+
148
+ ## Dispatch rules that prevent real failures
149
+
150
+ - **Pipeline cherry-picks; don't barrier.** One wait, one
151
+ cherry-pick, one verify, return control. Do not wait on an
152
+ umbrella task for the whole wave; that hides partial progress.
153
+ - **Use `--on-stall exit` in non-interactive flows.** Default wait
154
+ warns on stalled alive workers and keeps polling. Exit 7 =
155
+ `STALL_DETECTED`; exit 6 = `REAPER_DETECTED` (dead pane) and wins
156
+ if both happen.
157
+ - **Cherry-pick worker commits onto main; don't merge.** Stale
158
+ branches can drag re-reverts.
159
+ - **Cherry-pick only new shas.** `workspace commits` lists since
160
+ fork; track what you've already integrated. Don't replay the whole
161
+ worker range each time.
162
+ - **Bucket fix waves by file cluster, not severity.** Two workers
163
+ editing one file create merge conflicts.
164
+ - **Refresh/recreate workspaces between waves.** The `behind` column
165
+ in `mu workspace list` shows stale-parent risk.
166
+ - **Cross-workstream wait/claim:** pass qualified refs
167
+ `<workstream>/<name>`. For `claim --for A/worker-1` on a task in
168
+ B, the agent stays in A; only task ownership crosses.
169
+ - **Recover idle agents:** `mu agent show <name> -n N`; then send a
170
+ retry or `mu task release <id>` (bare release reopens
171
+ IN_PROGRESS). Idle threshold: `MU_IDLE_THRESHOLD_MS`, default 5m.
172
+ - **Recover wedged tool subprocesses:** `mu agent kick <name>` sends
173
+ SIGINT to the pane TTY foreground process group. Escalate with
174
+ `--signal SIGTERM` / `SIGKILL`. It refuses when the foreground is
175
+ the wrapping CLI; use `mu agent close` then.
176
+ - **Use `mu agent send`; never raw `tmux send-keys <text>`.** mu uses
177
+ bracketed paste so `/`, `?`, `f`, etc. are delivered as text
178
+ instead of agent-TUI keybindings.
179
+ - **Prompt quoting:** single-quote prompts containing `$VAR`,
180
+ `$(...)`, backticks, or `!history`, or use a quoted heredoc.
181
+
182
+ Example wait/cherry-pick skeleton:
183
+
184
+ ```bash
185
+ res=$(mu task wait t1 t2 t3 -w ws --any --first --json \
186
+ --timeout 600 --on-stall exit)
187
+ worker=$(jq -r .firing.owner <<<"$res")
188
+ sha=$(mu workspace commits "$worker" -w ws --json | jq -r '.items[0].sha')
189
+ git cherry-pick "$sha" && npm test
190
+ ```
191
+
192
+ ## Universal flags
193
+
194
+ - `-w, --workstream <name>` resolves explicit > `$MU_SESSION` >
195
+ current tmux session minus `mu-` > error. For entity verbs it is a
196
+ scope check; for pickers it selects which workstream.
197
+ - Qualified refs `<workstream>/<name>` skip `-w`; mismatched `-w`
198
+ errors. Bare ambiguous names raise `NameAmbiguousError` (exit 4)
199
+ with one-paste fixes.
200
+ - `--evidence "text"` on task `claim/close/open/release`; recorded
201
+ verbatim in emitted events.
202
+ - `--json` for composition; `nextSteps` survives.
203
+
204
+ ## CLI overview (only gotchas; use `--help` for full syntax)
205
+
206
+ - **Workstream:** `init`, `list`, `destroy` (auto-snapshot;
207
+ `--archive <label>` preserves graph), `export`, `import`.
208
+ - **Agents:** `spawn` (`--workspace`, `--role read-only`,
209
+ `--command`), `send`, `read`, `show`, `list`, `close`, `free`,
210
+ `kick`, `adopt <pane-id|title>` for orphan panes.
211
+ - **Tasks:** `add`, `list`, `next`, `show`, `tree`, `notes`
212
+ (`--tail`, `--since`, `--since-claim`), `note`, `claim`
213
+ (`--for | --self`), `release` (`--reopen` only for un-closing
214
+ terminal tasks), `close` (`--if-ready` no-ops until blockers
215
+ terminal), `open`, `reject`, `defer`, `block`, `unblock`,
216
+ `update`, `reparent`, `wait`, `delete --yes`. Edge direction:
217
+ `block <blocked> --by <blocker>`.
218
+ - **Self:** `mu me`, `mu me tasks`, `mu me next`.
219
+ - **Workspace:** `create`, `list` (`behind`), `refresh`, `recreate`,
220
+ `commits`, `free`, `path`, `orphans`.
221
+ - **Log:** `mu log "text"`, `mu log -n N`, `mu log --tail`. Use
222
+ `task wait`, not `log --tail`, for waits.
223
+ - **Snapshots:** destructive verbs auto-snapshot. `mu undo --yes`
224
+ restores DB only, not tmux/workspace dirs. No redo; each restore
225
+ takes a pre-restore snapshot.
226
+ - **Archives:** `create`, `list`, `show`, `add <label> -w <ws>
227
+ [--destroy]`, `remove`, `delete`, `search`, `export`. Labels are
228
+ global.
229
+ - **State/TUI:** bare `mu` opens the all-workstream TUI on a TTY;
230
+ agents/scripts use `mu state --json`. `mu state --tui` is
231
+ read-only, yanks commands, `?` shows keys, `/` filters popups,
232
+ `Esc`/`q` back, `q`/`Ctrl-C` quits. Non-TTY bare `mu` (or
233
+ `MU_NO_TUI=1`) prints help.
234
+ - **Escape hatch:** `mu sql "<query>"` for missing typed verbs.
235
+ - **Health:** `mu doctor`.
288
236
 
289
237
  ## `mu task wait` exits
290
238
 
291
- Default target: CLOSED. `--first` = `--any` + prints firing
292
- qualified id and emits `firing` in JSON.
239
+ Default target: CLOSED. `--first` = `--any` plus firing id/object.
293
240
 
294
241
  | Code | Meaning |
295
242
  |------|---------|
296
- | 0 | All targets met (or `--any` and one met) |
243
+ | 0 | All targets met, or `--any` and one met |
297
244
  | 3 | Missing task id |
298
245
  | 5 | Timeout |
299
- | 6 | Reaper flipped a watched task back to OPEN (target=CLOSED only) |
300
- | 7 | Stall (`--on-stall exit`) |
301
-
302
- ## Picking model + thinking effort per agent
303
-
304
- mu doesn't reason about models. Pi speaks `--model sonnet:high` and
305
- `--thinking off|minimal|low|medium|high|xhigh`.
306
-
307
- Three controls, smallest first:
308
- - **Per-spawn**: `mu agent spawn r --command "pi --model opus:high"`
309
- - **Shell default**: `export MU_PI_COMMAND="pi --model sonnet:medium"`
310
- - **Operator aliases**: any `--cli <key>` uppercases to
311
- `$MU_<KEY>_COMMAND` (use underscores). Convention: `pi_mini` /
312
- `pi` / `pi_big`. mu doesn't enforce these.
313
-
314
- Rubric: mini for probing/fan-out; modest for build/edit/refactor;
315
- big for design/review/incident/gnarly debugging. Discover valid
316
- model strings: `pi --list-models [fuzzy-search]`.
246
+ | 6 | Reaper flipped watched task back to OPEN (target=CLOSED only) |
247
+ | 7 | Stall with `--on-stall exit` |
317
248
 
318
- ## The reaper
249
+ ## Models and thinking effort
319
250
 
320
- When an agent's pane dies (or you `mu agent close` mid-task), any
321
- IN_PROGRESS task it owned auto-reverts to OPEN with a `[reaper]`
322
- note plus a `task reap` event in `agent_logs`. You don't have to
323
- manually `task release` after a crash.
324
-
325
- ## Known limitations
326
-
327
- - **Status detection lags with custom `--command` wrappers.**
328
- Agents may show `needs_input` while running commands. Trust
329
- scrollback, task notes, and event log over the status emoji for
330
- monitoring decisions.
331
- - **Workspace patch flow needs explicit apply.** Worker writes in
332
- isolated workspace → review → parity tests in workspace → manual
333
- cherry-pick to main → sanity test. Worth it for any patch that
334
- benefits from review; overkill for a one-line typo fix.
335
- - **Orchestration overhead is real for tiny tasks.** Task create +
336
- claim + send + monitor + notes + close is ~6 verbs of ceremony.
337
- See "When to reach for mu" above.
338
-
339
- ## Common patterns
340
-
341
- The `Next:` block on every verb covers the single-step follow-ups.
342
- These are the **multi-verb composites** that no hint can show.
343
-
344
- ### Plan + spawn a crew
345
-
346
- ```bash
347
- mu workstream init <ws>
348
- mu task add -w <ws> --title "Design X" --impact 70 --effort-days 1
349
- mu task add -w <ws> --title "Build X" --impact 70 --effort-days 5 --blocked-by design_x
350
- mu task add -w <ws> --title "Review X" --impact 60 --effort-days 1 --blocked-by build_x
351
- mu agent spawn worker-1 -w <ws> --workspace
352
- mu agent spawn reviewer-1 -w <ws> --workspace --role read-only
353
- mu -w <ws> # mission control
354
- ```
355
-
356
- IDs auto-derive from titles via slugify.
357
-
358
- ### Pipeline cherry-pick (the canonical fix-wave loop)
251
+ mu doesn't reason about models; pi does. Controls:
359
252
 
360
253
  ```bash
361
- # Wait for any-of N to close, cherry-pick that one, return.
362
- res=$(mu task wait t1 t2 t3 -w ws --any --first --json \
363
- --timeout 600 --on-stall exit)
364
- firing=$(jq -r .firing.qualifiedId <<<"$res")
365
- sha=$(mu workspace commits $worker -w ws --json \
366
- | jq -r --arg id "${firing#*/}" \
367
- '.items[] | select(.subject | startswith($id+":")) | .sha' | head -1)
368
- git cherry-pick $sha && cargo test --lib
369
- # Next turn: same wait on the smaller set.
254
+ mu agent spawn r --command "pi --model opus:high"
255
+ export MU_PI_COMMAND="pi --model sonnet:medium"
256
+ mu agent spawn a --cli pi_big # uses $MU_PI_BIG_COMMAND
370
257
  ```
371
258
 
372
- ### Umbrella-on-wave-done
259
+ Convention: `pi_mini` / `pi` / `pi_big`. Use mini for probing,
260
+ modest for build/edit/refactor, big for design/review/incidents.
261
+ Discover model strings with `pi --list-models [fuzzy-search]`.
373
262
 
374
- Fire `mu task close umbrella_wave_X --if-ready -w <ws>` after every
375
- cherry-pick in the pipeline loop. No-op while any blocker is
376
- OPEN/IN_PROGRESS; closes when the last terminates. JSON no-op shape
377
- carries `skipped: "not_ready"` + `blockingIds: [...]`.
263
+ ## Reaper and status limits
378
264
 
379
- ### Quote command-rich prompts (avoid `$VAR` expanding in YOUR shell)
265
+ If an agent pane dies, or `mu agent close` kills it mid-task, owned
266
+ IN_PROGRESS tasks revert to OPEN with a `[reaper]` note and `task
267
+ reap` event. No manual release after crashes.
380
268
 
381
- `$VAR`, `$(...)`, backticks, and `!history` in a double-quoted
382
- prompt expand in YOUR shell before mu sees them. Single-quote (or
383
- use a quoted heredoc) to defer expansion to the agent.
269
+ Status detection is heuristic and can lag, especially behind custom
270
+ `--command` wrappers. For high-stakes decisions:
384
271
 
385
272
  ```bash
386
- # Bad: $HOME and $(date) expand in YOUR shell.
387
- mu agent send worker-1 "OUT=\"$HOME/foo-$(date)\" run_me"
388
-
389
- # Good: single quotes — expansion deferred.
390
- mu agent send worker-1 'OUT="$HOME/foo-$(date)" run_me'
391
-
392
- # Good: quoted heredoc for multi-line + literal.
393
- mu agent send worker-1 "$(cat <<'EOF'
394
- for f in src/*.rs; do cargo check --manifest-path "$f"; done
395
- EOF
396
- )"
273
+ mu agent read worker-1 -n 100
274
+ mu log -w <ws> --kind event --tail
275
+ mu task notes <id>
397
276
  ```
398
277
 
399
- When in doubt, single-quote.
400
-
401
- ### Status is approximate; scrollback + log are authoritative
402
-
403
- The status emoji is a 4-state heuristic from prompt shape. For
404
- high-stakes calls, combine:
405
-
406
- ```bash
407
- mu agent read worker-1 -n 100 # pane scrollback
408
- mu log -w <ws> --kind event --tail # state-change stream
409
- mu task notes <id> # decisions + grounding
410
- ```
278
+ ## In-pane worker loop
411
279
 
412
- ### Sending follow-on work to an existing agent
280
+ `$TMUX_PANE` resolves identity. Pane title set at spawn is the agent
281
+ identity.
413
282
 
414
- A new prompt is appended to whatever context the agent had. For
415
- **unrelated** work, send `/new` first (pi / claude-code; codex uses
416
- `/clear`) to wipe the LLM's working set pane scrollback is preserved:
283
+ - Worker pane: spawned/adopted by mu; bare `mu task claim <id>` works.
284
+ - Orchestrator pane: not registered; bare `claim` errors with next
285
+ steps: `--self`, `--for <worker>`, or `mu agent adopt <pane>`.
417
286
 
418
287
  ```bash
419
- mu agent send worker-1 '/new'
420
- sleep 1 # let the CLI swallow the slash command
421
- mu agent send worker-1 "$(cat <<'EOF_PROMPT'
422
- Claim and work on $TASK. Read the task notes before starting...
423
- EOF_PROMPT
424
- )"
288
+ mu me
289
+ mu me next
290
+ mu task show <id>; mu task notes <id>
291
+ mu task claim <id> --evidence "starting; read notes"
292
+ mu task note <id> "FILES: ...\nDECISION: ...\nVERIFIED: ..."
293
+ mu task close <id> --evidence "tests pass: ..." # LAST action
425
294
  ```
426
295
 
427
- ### Recover from a destructive verb
428
-
429
- `mu snapshot list` then `mu undo --yes` (dry-run by default; add
430
- `--to <id>` to pick one). DB only — killed tmux panes and freed
431
- workspace dirs do NOT come back. There is no `mu redo`; each
432
- restore takes a pre-restore snapshot, so a second `mu undo --yes`
433
- rolls forward.
296
+ Skipping close makes the orchestrator's wait hang.
434
297
 
435
- ## If you ARE the agent (in-pane patterns)
298
+ ## Follow-on prompts
436
299
 
437
- Verbs auto-resolve via `$TMUX_PANE` `mu me`, `mu me next`,
438
- `mu task claim` all work without a name argument. The pane title
439
- (set at spawn) IS the agent identity.
440
-
441
- - **Worker**: pane was created by `mu agent spawn` (or promoted via
442
- `mu adopt`). Bare `mu task claim <id>` works.
443
- - **Orchestrator**: a top-level pi session NOT in `agents`. Bare
444
- `mu task claim` errors with `ClaimerNotRegisteredError` whose
445
- `errorNextSteps()` lists three options: `--self` (work directly,
446
- owner=NULL), `--for <worker>` (dispatch), or `mu adopt <pane>`.
447
-
448
- Working loop:
300
+ A new `mu agent send` appends to prior LLM context. For unrelated
301
+ work, clear first (`/new` for pi/claude-code; `/clear` for codex):
449
302
 
450
303
  ```bash
451
- mu me # orient
452
- mu me next # find work
453
- mu task show <id>; mu task notes <id> # read context
454
- mu task claim <id> --evidence "..." # claim
455
- mu task note <id> "FILES: ...\nDECISION: ..." # work; drop notes
456
- mu task close <id> --evidence "tests pass: ..." # close — LAST action
304
+ mu agent send worker-1 '/new'
305
+ sleep 1
306
+ mu agent send worker-1 'Claim and work on task_x. Read notes first...'
457
307
  ```
458
308
 
459
- **Close as the LAST action.** Skipping `mu task close` makes the
460
- orchestrator's `mu task wait` hang.
461
-
462
- ## DOs
463
-
464
- - **`mu state -w <ws>` before every action.** State card is the
465
- source of truth.
466
- - **Add a task before assigning work.** "What is worker-1 doing?"
467
- is a graph query, not a memory test.
468
- - **Claim BEFORE sending.** Otherwise ownership is murky.
469
- - **Read existing notes before claiming.**
470
- - **Pass `--evidence` on claim AND close.** Audit trail is only as
471
- useful as what's recorded.
472
- - **Drop notes per the task note contract.**
473
- - **Set `impact` and `effort_days` honestly.** They drive ROI.
474
- - **Don't spawn more agents than independent ready tracks.**
475
- - **Send `/new` before unrelated follow-on work** to a still-spawned
476
- agent.
477
- - **`--workspace` whenever the agent might edit/build/test.**
478
- Default-on.
479
- - **Single-quote prompts with `$VAR`, `$(...)`, backticks.**
480
- - **`mu task wait --first --json` for waits; never `mu log --tail
481
- | awk` and never a shell `while` loop polling status.**
482
- - **`--json` for scripting; `mu sql` for what's not yet typed.**
483
- - **`mu doctor` if anything looks off.**
484
-
485
- ## DON'Ts
486
-
487
- - **Don't barrier on a wave umbrella.** Use `--first --any` and
488
- cherry-pick per-finish. Returning control between picks is the
489
- point.
490
- - **Don't loop in your own shell waiting for "everything to be
491
- done."** That's a barrier with extra steps. Single wait, single
492
- cherry-pick, return.
493
- - **Don't fire-and-forget** after `mu agent send`.
494
- - **Don't trust the status emoji alone for high-stakes calls.**
495
- - **Don't double-quote a `$VAR`-laden prompt** — your shell expands
496
- it. Single-quote or quoted-heredoc.
497
- - **Don't bypass mu with `sqlite3`.** Use `mu sql`.
498
- - **Don't spawn an agent without a workstream.**
499
- - **Don't anthropomorphize agent names.** `worker-1`, not `alice`.
500
- - **Don't poll `mu agent read` in tight loops.** Use `mu log
501
- --tail` for streaming, `mu task wait` for waits.
502
- - **Don't add cross-workstream edges.** Model as one workstream.
503
- - **Don't `mu workstream destroy --yes` without the dry-run.**
504
- - **Don't use the `mu_` task-id prefix.** Reserved.
505
- - **Don't message agents directly.** Coordinate via task notes and
506
- the activity log.
309
+ ## Recover destructive verbs
310
+
311
+ `mu snapshot list`, then `mu undo --yes` (dry-run by default; add
312
+ `--to <id>` to choose one). DB only: killed panes and freed
313
+ workspace dirs do not return.
314
+
315
+ ## DO / DON'T
316
+
317
+ DO:
318
+ - `mu state -w <ws>` before actions.
319
+ - Add a task before assigning work.
320
+ - Claim before sending; read notes before claiming.
321
+ - Pass `--evidence` on claim and close.
322
+ - Drop task notes using the note contract.
323
+ - Set `impact` and `effort_days` honestly.
324
+ - Use `--workspace` whenever an agent may edit/build/test.
325
+ - Send `/new` before unrelated follow-on work.
326
+ - Use `mu task wait --first --json`, never shell polling.
327
+ - Use `mu doctor` when state looks wrong.
328
+
329
+ DON'T:
330
+ - Barrier on a wave umbrella or loop until "everything is done".
331
+ - Fire-and-forget after `mu agent send`.
332
+ - Trust status emoji alone.
333
+ - Double-quote `$VAR`-laden prompts.
334
+ - Bypass mu with `sqlite3`; use `mu sql`.
335
+ - Spawn without a workstream.
336
+ - Anthropomorphize agent names.
337
+ - Poll `mu agent read` in tight loops.
338
+ - Add cross-workstream edges; model as one workstream.
339
+ - `mu workstream destroy --yes` without dry-run.
340
+ - Use the reserved `mu_` task-id prefix.
341
+ - Message agents directly; use task notes and the activity log.
342
+ - Prompt workers to run filesystem-wide `find`, broad `grep -r /`,
343
+ or unbounded loops. Pass paths; if wedged, `mu agent kick`.
507
344
 
508
345
  ## What mu is NOT
509
346
 
510
- - Not a build tool. mu doesn't compile, test, or deploy code.
511
- - Not a chat protocol — agent-to-agent comms is via task notes
512
- (durable, per-task) and the `mu log` activity channel (timeline).
513
- - Not a replacement for `pi-subagents` for one-shot focused
514
- delegation with synthesis, use `pi-subagents`. mu is for
515
- long-lived crews you keep talking to.
347
+ - Not a build tool, deploy tool, or chat protocol.
348
+ - Not a replacement for `pi-subagents`; mu is for long-lived crews.
349
+ - Not a place to add config files, daemons, wrapper layers, codegen,
350
+ template discovery, or a render layer beyond current deps.
516
351
 
517
352
  ## See also
518
353
 
519
- - `mu --help` and `mu <verb> --help` — canonical CLI reference
520
- (always trust `--help` over this skill if they disagree).
521
- - `docs/USAGE_GUIDE.md` — worked examples for every verb.
522
- - `CHANGELOG.md` — release notes.
523
- - `docs/VOCABULARY.md` — canonical terms.
354
+ - `mu --help`, `mu <verb> --help` — canonical CLI reference.