@martintrojer/mu 0.3.2 → 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,123 +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
48
+ ## When to use mu
50
49
 
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.
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.
60
53
 
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.
65
-
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 auto-freed when
90
- you close an agent **iff the workspace is clean** (no uncommitted
91
- changes AND no commits since fork); a non-clean workspace blocks
92
- `mu agent close` with `WorkspacePreservedError` and forces an
93
- explicit `mu workspace free <agent>` (or
94
- `mu agent close <agent> --discard-workspace` for the lossy override).
95
- Between
96
- waves, `mu workspace refresh <agent>` rebases the dir onto fresh
97
- main without killing the agent's LLM context; `mu workspace commits
98
- <agent>` lists since-fork commits for cherry-picking.
99
-
100
- **Default rule:** if an agent may edit/build/test/generate
101
- artifacts while another agent is active in the same repo, spawn
102
- with `--workspace`. Reserve the main checkout for orchestration.
103
- Two builds in the same checkout corrupt each other's artifacts.
104
-
105
- ### Name agents by role, not by person
106
-
107
- Use `worker-1`, `worker-2`, `reviewer-1`, `scout-1`, `auditor-1`,
108
- `planner-1`. Smallest unused suffix. Avoid human names —
109
- anthropomorphizing makes coordination prompts ambiguous ("send
110
- 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.
111
98
 
112
99
  ### Task note contract
113
100
 
114
- Every delegated task should end with a note containing six fields
115
- (omit only the ones genuinely N/A):
101
+ End every delegated task with a note containing the applicable
102
+ fields:
116
103
 
117
- ```
118
- FILES: paths inspected/changed (with line ranges if precise)
119
- COMMANDS: shell commands run + exit codes
104
+ ```text
105
+ FILES: paths inspected/changed (line ranges if precise)
106
+ COMMANDS: commands run + exit codes
120
107
  FINDINGS: what you observed
121
108
  DECISION: what you chose, and why
122
- NEXT: follow-on tasks the next agent should know about
123
- VERIFIED: how you confirmed it works (test names, command output)
124
- 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
125
112
  ```
126
113
 
127
114
  Then close with grounding:
@@ -130,421 +117,238 @@ Then close with grounding:
130
117
  mu task close <id> -w <ws> --evidence "tests pass: cargo test exit 0"
131
118
  ```
132
119
 
133
- This turns the DAG from a coordination tool into a durable project
134
- log. Future agents can `mu task notes <id>` to reconstruct the why
135
- without reading the diff.
120
+ Future agents can reconstruct context via `mu task notes <id>`.
136
121
 
137
122
  ## Orchestrator loop
138
123
 
139
124
  Every turn:
140
125
 
141
- 1. `mu state -w <ws>` — read the card. Agents, IN_PROGRESS, ready,
126
+ 1. `mu state -w <ws>` — read agents, IN_PROGRESS, ready tasks,
142
127
  parallel tracks.
143
- 2. Don't spawn more agents than independent ready tracks.
144
- 3. **Claim before sending — even for one-shot reviewers / scouts.**
145
- `mu task claim <id> -w <ws> --for <agent> --evidence "..."`. No
146
- task = nothing for `mu task wait` to wait on; agent status flips
147
- are too noisy. If the dispatch has no task, `mu task add` first.
148
- 4. Send task-specific instructions: task ID, files/notes to read,
149
- scope guards, the task note contract. End with the loud
150
- `⚠️ FINAL ACTION` block (see lessons below).
151
- 5. Wait for *one* task to close (`--first`), cherry-pick, return
152
- control. Do NOT loop in your own shell — see lessons.
153
- 6. On close, repeat from 1.
154
-
155
- ## Hard-earned dispatch lessons
156
-
157
- Every one of these came from real failure modes. Re-read before
158
- running a wave.
159
-
160
- - **Pipeline cherry-picks; DON'T BARRIER.** This is the single most
161
- important rule. One wait, one cherry-pick, one verify, return
162
- control. Do NOT `mu task wait umbrella_wave_X` and block until
163
- everything in the wave finishes you give up the ability to
164
- react per-finish, and you can't surface partial progress.
165
- Don't loop in a shell script either; that's a barrier with extra
166
- steps.
167
-
168
- ```bash
169
- # YES pipeline (returns the moment one task closes)
170
- closed=$(mu task wait t1 t2 t3 -w ws --any --first --json \
171
- --on-stall exit | jq -r .firing.qualifiedId)
172
- # cherry-pick that worker's commit, verify, return control.
173
- # Next turn: same wait on the smaller set.
174
- ```
175
-
176
- The recipe is also in `mu task wait`'s `nextSteps` — `jq` it out.
177
-
178
- - **Refresh workspaces between waves.** `mu workspace refresh
179
- <agent>` rebases the agent's dir onto fresh main without killing
180
- the LLM context. The `behind` column in `mu workspace list` shows
181
- the cost of skipping it. Worker ships clean code against a stale
182
- parent otherwise; you find out at cherry-pick time.
183
-
184
- - **Cherry-pick worker commits onto main, don't merge.** Stale-parent
185
- worker branches drag in re-reverts of everything they missed.
186
-
187
- - **Bucket fix waves by file cluster, not by severity.** Two workers
188
- editing the same file = cherry-pick conflicts at merge time. mu
189
- doesn't help you here; you have to know the codebase.
190
-
191
- - **End every dispatch prompt with a loud `⚠️ FINAL ACTION: git
192
- commit -am '...' THEN mu task close <id> --evidence '...'`.**
193
- Without the literal reminder, agents commit + report success in
194
- chat without running the typed close, and `mu task wait` hangs.
195
-
196
- - **`--on-stall exit` is the unattended-orchestrator escape.**
197
- Default `mu task wait` warns on a stuck worker and KEEPS POLLING.
198
- In any non-interactive flow (wrapping policies, cron, long
199
- pipelines, multi-step orchestration), pass `--on-stall exit`:
200
- exits 7 (`STALL_DETECTED`) the moment the predicate fires.
201
- Distinct from exit 6 (`REAPER_DETECTED`, dead pane —
202
- re-dispatch); exit 7 is the ambiguous sibling (alive but idle
203
- decide whether to poke, release, or roll over). If both fire in
204
- the same poll, exit 6 wins.
205
-
206
- - **Cross-workstream `mu task wait` is built in.** Pass qualified
207
- refs `<workstream>/<name>` directly; `-w` is dropped when every
208
- ref is qualified, and the per-poll reconcile loops over every
209
- workstream in the set.
210
-
211
- - **Cross-workstream `mu task claim --for` is built in.** When
212
- per-workstream worker pools leave a free worker in workstream A
213
- and a queued task in workstream B, dispatch with `mu task claim X
214
- -w B --for A/worker-1`. The agent stays in A; only the task's
215
- `owner_id` crosses. No need to close + re-spawn (which loses LLM
216
- context) or reach for `mu sql`.
217
-
218
- - **Keep dispatch prompts terse.** Workers have the same skills as
219
- the orchestrator and can `mu task notes <id>` for the full spec.
220
- The prompt only needs: who they are, the task id, the workspace
221
- path, the validate command, and the loud final-action block.
222
-
223
- - **Idle agent ( glyph; alive but assigned, no recent progress)** —
224
- see scrollback via `mu agent show <name> -n N`; recover via
225
- `mu agent send <name> '<retry>'` OR `mu task release <id>` (bare
226
- release auto-flips IN_PROGRESS → OPEN; `--reopen` is only for
227
- un-closing CLOSED/REJECTED/DEFERRED). Tunable via
228
- `MU_IDLE_THRESHOLD_MS` (default 5 min).
229
-
230
- - **Wedged on an unbounded tool subprocess (`find /`, busy-wait
231
- loop)** — `mu agent send` queues until the tool returns;
232
- `tmux send-keys C-c` doesn't propagate (the wrapping CLI eats
233
- it as TUI input). Use `mu agent kick <name>` to SIGINT the
234
- foreground process group of the pane's TTY directly from
235
- outside. Default `--signal SIGINT` is graceful; escalate to
236
- `--signal SIGTERM` then `--signal SIGKILL` if the tool
237
- ignores it. Refuses when the foreground IS the wrapping CLI
238
- itself — use `mu agent close` for that.
239
-
240
- ## Parallelisation decision table
241
-
242
- | Situation | Action |
243
- |-----------|--------|
244
- | One ready task / one track | Reuse one existing agent |
245
- | Multiple independent ready tasks | Spawn one agent per ready track; cherry-pick each as it closes (don't barrier) |
246
- | CPU-heavy benchmark in progress | Only parallelise read-only / audit tasks |
247
- | Two agents editing/building/testing same repo | Use `--workspace` |
248
- | Agent only reading docs/source | `--cli pi` (or operator alias) without `--workspace` is OK |
249
- | Agent making code changes | `--workspace` strongly preferred |
250
- | Agent reviewing/testing another agent's patch | Separate `--workspace` (or wait for the patch to merge) |
251
-
252
- ## Universal flags (worth knowing without `--help`)
253
-
254
- - **`-w, --workstream <name>`** — explicit > `$MU_SESSION` > current
255
- tmux session minus `mu-` prefix > error. On verbs that take an
256
- entity by id, `-w` is a SCOPE check; on picker verbs (`mu task
257
- next`, `mu agent list`), it picks WHICH.
258
- - **Qualified entity refs** — every verb accepts
259
- `<workstream>/<name>` in addition to bare `<name>`. The qualified
260
- form skips `-w` resolution: `mu task show ws/foo` works from any
261
- shell. Mixing a qualified ref with a non-matching `-w` errors out
262
- (exit 2). When a bare name appears AND no `-w` resolves AND ≥2
263
- workstreams contain that name, mu raises `NameAmbiguousError`
264
- (exit 4) and lists every candidate as a one-paste fix.
265
- - **`--evidence "<text>"`** — on `task close / open / claim /
266
- release`. Recorded verbatim in the auto-emitted event payload.
267
- Use it for grounding ("tests pass: cargo test exit 0").
268
- - **`--json`** — on every verb. Use it whenever you compose mu
269
- output into another command. `nextSteps` survives in JSON.
270
-
271
- ## CLI overview (one line each; trust `mu <verb> --help`)
272
-
273
- - **Workstream**: `init`, `list`, `destroy` (auto-snapshots and
274
- `--archive <label>` to preserve graph atomically), `export`,
275
- `import`.
276
- - **Agents**: `spawn` (`--workspace`, `--role read-only`,
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`,
277
209
  `--command`), `send`, `read`, `show`, `list`, `close`, `free`,
278
- `kick` (signal a wedged foreground tool subprocess from outside
279
- the pane). **`mu agent adopt <pane-id|title>`** registers an
280
- orphan pane as a managed agent.
281
- - **Tasks**: `add`, `list`, `next`, `show`, `tree`, `notes`
282
- (`--tail N` / `--since <iso>` / `--since-claim` to slice the
283
- timeline; default = every note, oldest first), `note`,
284
- `claim` (`--for | --self`), `release` (`--reopen` to un-close),
285
- `close` (`--if-ready` = no-op unless every blocker terminal),
286
- `open`, `reject`, `defer`, `block`, `unblock`, `update`,
287
- `reparent`, `wait`, `delete` (two-phase; `--yes` commits).
288
- Edge direction: `block <blocked> --by <blocker>`.
289
- - **Self (in-pane)**: `mu me`, `mu me tasks`, `mu me next`.
290
- - **Workspace**: `create`, `list` (`behind` column), `refresh`
291
- (rebase onto fresh base, agent stays alive), `recreate` (free +
292
- create in one shot for between-wave prep; `--force` to discard
293
- dirty edits), `commits` (since-fork `<sha> <subject>`; `--json`
294
- for piping), `free`, `path` (`cd $(mu workspace path X)`),
295
- `orphans`.
296
- - **Activity log**: `mu log "text"` (write), `mu log -n N` (read),
297
- `mu log --tail` (subscribe). Don't pipe `--tail` for waits — use
298
- `mu task wait`.
299
- - **Snapshots/undo**: every destructive verb auto-snapshots first.
300
- `mu undo --yes` restores the latest (DB only, NOT tmux/workspace
301
- dirs). `mu snapshot list/show/prune/delete`.
302
- - **Archives**: `create <label>`, `list`, `show`, `add <label> -w
303
- <ws> [--destroy]` (idempotent; preserves task graph atomically),
304
- `remove`, `delete`, `search`, `export`. Labels globally unique.
305
- - **Escape hatch + state**: `mu sql "<query>"` for anything not yet
306
- typed. `mu` alone = `mu state --mission`. `mu state` has `--hud`,
307
- `--mission`, `--all`, `--json`. `mu doctor` for health.
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`.
308
236
 
309
237
  ## `mu task wait` exits
310
238
 
311
- Default target: CLOSED. `--first` = `--any` + prints firing
312
- qualified id and emits `firing` in JSON.
239
+ Default target: CLOSED. `--first` = `--any` plus firing id/object.
313
240
 
314
241
  | Code | Meaning |
315
242
  |------|---------|
316
- | 0 | All targets met (or `--any` and one met) |
243
+ | 0 | All targets met, or `--any` and one met |
317
244
  | 3 | Missing task id |
318
245
  | 5 | Timeout |
319
- | 6 | Reaper flipped a watched task back to OPEN (target=CLOSED only) |
320
- | 7 | Stall (`--on-stall exit`) |
321
-
322
- ## Picking model + thinking effort per agent
323
-
324
- mu doesn't reason about models. Pi speaks `--model sonnet:high` and
325
- `--thinking off|minimal|low|medium|high|xhigh`.
326
-
327
- Three controls, smallest first:
328
- - **Per-spawn**: `mu agent spawn r --command "pi --model opus:high"`
329
- - **Shell default**: `export MU_PI_COMMAND="pi --model sonnet:medium"`
330
- - **Operator aliases**: any `--cli <key>` uppercases to
331
- `$MU_<KEY>_COMMAND` (use underscores). Convention: `pi_mini` /
332
- `pi` / `pi_big`. mu doesn't enforce these.
246
+ | 6 | Reaper flipped watched task back to OPEN (target=CLOSED only) |
247
+ | 7 | Stall with `--on-stall exit` |
333
248
 
334
- Rubric: mini for probing/fan-out; modest for build/edit/refactor;
335
- big for design/review/incident/gnarly debugging. Discover valid
336
- model strings: `pi --list-models [fuzzy-search]`.
249
+ ## Models and thinking effort
337
250
 
338
- ## The reaper
339
-
340
- When an agent's pane dies (or you `mu agent close` mid-task), any
341
- IN_PROGRESS task it owned auto-reverts to OPEN with a `[reaper]`
342
- note plus a `task reap` event in `agent_logs`. You don't have to
343
- manually `task release` after a crash.
344
-
345
- ## Known limitations
346
-
347
- - **Status detection lags with custom `--command` wrappers.**
348
- Agents may show `needs_input` while running commands. Trust
349
- scrollback, task notes, and event log over the status emoji for
350
- monitoring decisions.
351
- - **Workspace patch flow needs explicit apply.** Worker writes in
352
- isolated workspace → review → parity tests in workspace → manual
353
- cherry-pick to main → sanity test. Worth it for any patch that
354
- benefits from review; overkill for a one-line typo fix.
355
- - **Orchestration overhead is real for tiny tasks.** Task create +
356
- claim + send + monitor + notes + close is ~6 verbs of ceremony.
357
- See "When to reach for mu" above.
358
-
359
- ## Common patterns
360
-
361
- The `Next:` block on every verb covers the single-step follow-ups.
362
- These are the **multi-verb composites** that no hint can show.
363
-
364
- ### Plan + spawn a crew
251
+ mu doesn't reason about models; pi does. Controls:
365
252
 
366
253
  ```bash
367
- mu workstream init <ws>
368
- mu task add -w <ws> --title "Design X" --impact 70 --effort-days 1
369
- mu task add -w <ws> --title "Build X" --impact 70 --effort-days 5 --blocked-by design_x
370
- mu task add -w <ws> --title "Review X" --impact 60 --effort-days 1 --blocked-by build_x
371
- mu agent spawn worker-1 -w <ws> --workspace
372
- mu agent spawn reviewer-1 -w <ws> --workspace --role read-only
373
- mu -w <ws> # mission control
374
- ```
375
-
376
- IDs auto-derive from titles via slugify.
377
-
378
- ### Pipeline cherry-pick (the canonical fix-wave loop)
379
-
380
- ```bash
381
- # Wait for any-of N to close, cherry-pick that one, return.
382
- res=$(mu task wait t1 t2 t3 -w ws --any --first --json \
383
- --timeout 600 --on-stall exit)
384
- worker=$(jq -r .firing.owner <<<"$res")
385
- # Workers run in fresh single-purpose workspaces, so HEAD is the
386
- # task's commit. Don't filter on subject — workers don't prefix
387
- # subjects with the task-id, and any such filter silently returns
388
- # empty (then `git cherry-pick` fails with "empty commit set").
389
- sha=$(mu workspace commits $worker -w ws --json | jq -r '.items[0].sha')
390
- git cherry-pick $sha && cargo test --lib
391
- # 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
392
257
  ```
393
258
 
394
- ### 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]`.
395
262
 
396
- Fire `mu task close umbrella_wave_X --if-ready -w <ws>` after every
397
- cherry-pick in the pipeline loop. No-op while any blocker is
398
- OPEN/IN_PROGRESS; closes when the last terminates. JSON no-op shape
399
- carries `skipped: "not_ready"` + `blockingIds: [...]`.
263
+ ## Reaper and status limits
400
264
 
401
- ### 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.
402
268
 
403
- `$VAR`, `$(...)`, backticks, and `!history` in a double-quoted
404
- prompt expand in YOUR shell before mu sees them. Single-quote (or
405
- 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:
406
271
 
407
272
  ```bash
408
- # Bad: $HOME and $(date) expand in YOUR shell.
409
- mu agent send worker-1 "OUT=\"$HOME/foo-$(date)\" run_me"
410
-
411
- # Good: single quotes — expansion deferred.
412
- mu agent send worker-1 'OUT="$HOME/foo-$(date)" run_me'
413
-
414
- # Good: quoted heredoc for multi-line + literal.
415
- mu agent send worker-1 "$(cat <<'EOF'
416
- for f in src/*.rs; do cargo check --manifest-path "$f"; done
417
- EOF
418
- )"
273
+ mu agent read worker-1 -n 100
274
+ mu log -w <ws> --kind event --tail
275
+ mu task notes <id>
419
276
  ```
420
277
 
421
- When in doubt, single-quote.
278
+ ## In-pane worker loop
422
279
 
423
- ### Status is approximate; scrollback + log are authoritative
280
+ `$TMUX_PANE` resolves identity. Pane title set at spawn is the agent
281
+ identity.
424
282
 
425
- The status emoji is a 4-state heuristic from prompt shape. For
426
- high-stakes calls, combine:
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>`.
427
286
 
428
287
  ```bash
429
- mu agent read worker-1 -n 100 # pane scrollback
430
- mu log -w <ws> --kind event --tail # state-change stream
431
- mu task notes <id> # decisions + grounding
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
432
294
  ```
433
295
 
434
- ### Sending follow-on work to an existing agent
435
-
436
- A new prompt is appended to whatever context the agent had. For
437
- **unrelated** work, send `/new` first (pi / claude-code; codex uses
438
- `/clear`) to wipe the LLM's working set — pane scrollback is preserved:
296
+ Skipping close makes the orchestrator's wait hang.
439
297
 
440
- ```bash
441
- mu agent send worker-1 '/new'
442
- sleep 1 # let the CLI swallow the slash command
443
- mu agent send worker-1 "$(cat <<'EOF_PROMPT'
444
- Claim and work on $TASK. Read the task notes before starting...
445
- EOF_PROMPT
446
- )"
447
- ```
298
+ ## Follow-on prompts
448
299
 
449
- ### Recover from a destructive verb
450
-
451
- `mu snapshot list` then `mu undo --yes` (dry-run by default; add
452
- `--to <id>` to pick one). DB only — killed tmux panes and freed
453
- workspace dirs do NOT come back. There is no `mu redo`; each
454
- restore takes a pre-restore snapshot, so a second `mu undo --yes`
455
- rolls forward.
456
-
457
- ## If you ARE the agent (in-pane patterns)
458
-
459
- Verbs auto-resolve via `$TMUX_PANE` — `mu me`, `mu me next`,
460
- `mu task claim` all work without a name argument. The pane title
461
- (set at spawn) IS the agent identity.
462
-
463
- - **Worker**: pane was created by `mu agent spawn` (or promoted via
464
- `mu agent adopt`). Bare `mu task claim <id>` works.
465
- - **Orchestrator**: a top-level pi session NOT in `agents`. Bare
466
- `mu task claim` errors with `ClaimerNotRegisteredError` whose
467
- `errorNextSteps()` lists three options: `--self` (work directly,
468
- owner=NULL), `--for <worker>` (dispatch), or `mu agent adopt <pane>`.
469
-
470
- 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):
471
302
 
472
303
  ```bash
473
- mu me # orient
474
- mu me next # find work
475
- mu task show <id>; mu task notes <id> # read context
476
- mu task claim <id> --evidence "..." # claim
477
- mu task note <id> "FILES: ...\nDECISION: ..." # work; drop notes
478
- 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...'
479
307
  ```
480
308
 
481
- **Close as the LAST action.** Skipping `mu task close` makes the
482
- orchestrator's `mu task wait` hang.
483
-
484
- ## DOs
485
-
486
- - **`mu state -w <ws>` before every action.** State card is the
487
- source of truth.
488
- - **Add a task before assigning work.** "What is worker-1 doing?"
489
- is a graph query, not a memory test.
490
- - **Claim BEFORE sending.** Otherwise ownership is murky.
491
- - **Read existing notes before claiming.**
492
- - **Pass `--evidence` on claim AND close.** Audit trail is only as
493
- useful as what's recorded.
494
- - **Drop notes per the task note contract.**
495
- - **Set `impact` and `effort_days` honestly.** They drive ROI.
496
- - **Don't spawn more agents than independent ready tracks.**
497
- - **Send `/new` before unrelated follow-on work** to a still-spawned
498
- agent.
499
- - **`--workspace` whenever the agent might edit/build/test.**
500
- Default-on.
501
- - **Single-quote prompts with `$VAR`, `$(...)`, backticks.**
502
- - **`mu task wait --first --json` for waits; never `mu log --tail
503
- | awk` and never a shell `while` loop polling status.**
504
- - **`--json` for scripting; `mu sql` for what's not yet typed.**
505
- - **`mu doctor` if anything looks off.**
506
-
507
- ## DON'Ts
508
-
509
- - **Don't barrier on a wave umbrella.** Use `--first --any` and
510
- cherry-pick per-finish. Returning control between picks is the
511
- point.
512
- - **Don't loop in your own shell waiting for "everything to be
513
- done."** That's a barrier with extra steps. Single wait, single
514
- cherry-pick, return.
515
- - **Don't fire-and-forget** after `mu agent send`.
516
- - **Don't trust the status emoji alone for high-stakes calls.**
517
- - **Don't double-quote a `$VAR`-laden prompt** — your shell expands
518
- it. Single-quote or quoted-heredoc.
519
- - **Don't bypass mu with `sqlite3`.** Use `mu sql`.
520
- - **Don't spawn an agent without a workstream.**
521
- - **Don't anthropomorphize agent names.** `worker-1`, not `alice`.
522
- - **Don't poll `mu agent read` in tight loops.** Use `mu log
523
- --tail` for streaming, `mu task wait` for waits.
524
- - **Don't add cross-workstream edges.** Model as one workstream.
525
- - **Don't `mu workstream destroy --yes` without the dry-run.**
526
- - **Don't use the `mu_` task-id prefix.** Reserved.
527
- - **Don't message agents directly.** Coordinate via task notes and
528
- the activity log.
529
- - **Don't prompt workers to run filesystem-wide `find`, broad
530
- `grep -r /`, or unbounded busy-wait loops.** Pass paths
531
- explicitly or scope to `$WORKSPACE`. If a worker wedges on one,
532
- use `mu agent kick <name>` to SIGINT the foreground tool
533
- from outside the pane.
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`.
534
344
 
535
345
  ## What mu is NOT
536
346
 
537
- - Not a build tool. mu doesn't compile, test, or deploy code.
538
- - Not a chat protocol — agent-to-agent comms is via task notes
539
- (durable, per-task) and the `mu log` activity channel (timeline).
540
- - Not a replacement for `pi-subagents` for one-shot focused
541
- delegation with synthesis, use `pi-subagents`. mu is for
542
- 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.
543
351
 
544
352
  ## See also
545
353
 
546
- - `mu --help` and `mu <verb> --help` — canonical CLI reference
547
- (always trust `--help` over this skill if they disagree).
548
- - `docs/USAGE_GUIDE.md` — worked examples for every verb.
549
- - `CHANGELOG.md` — release notes.
550
- - `docs/VOCABULARY.md` — canonical terms.
354
+ - `mu --help`, `mu <verb> --help` — canonical CLI reference.