@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/docs/VISION.md
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
# VISION: A persistent crew of agents
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> [VOCABULARY.md](VOCABULARY.md) for definitions of *workstream*,
|
|
5
|
-
> *agent*, *task DAG*, *crew*, *track*, *claim*, *free*, *workspace*,
|
|
6
|
-
> and the rest.
|
|
3
|
+
Terms are defined in [VOCABULARY.md](VOCABULARY.md).
|
|
7
4
|
|
|
8
|
-
## What
|
|
5
|
+
## What mu is
|
|
9
6
|
|
|
10
|
-
mu is a small, durable
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
over that state or a reconciled view of reality.
|
|
7
|
+
mu is a small, durable control plane for a persistent crew of AI agents
|
|
8
|
+
in multiplexer panes. Agents have names and roles, outlive sessions, and
|
|
9
|
+
work on a built-in task graph, each in its own VCS workspace. Humans and
|
|
10
|
+
agents drive them through one CLI. State lives in one SQLite file. Every
|
|
11
|
+
feature is a typed verb over that state or a reconciled view of reality.
|
|
16
12
|
|
|
17
13
|
```bash
|
|
18
14
|
mu agent spawn worker-1 --tab Backend --workspace
|
|
@@ -24,233 +20,178 @@ mu state # canonical state card
|
|
|
24
20
|
mu log --tail # subscribe to every state change
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
tasks.
|
|
23
|
+
Everything else makes those lines recover from failure and scale to
|
|
24
|
+
dozens of agents and hundreds of tasks.
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Why It Exists
|
|
26
|
+
## Why it exists
|
|
34
27
|
|
|
35
28
|
Existing tools force a choice:
|
|
36
29
|
|
|
37
30
|
- **Hidden subagents** (pi-subagents, the Claude Code and Codex task
|
|
38
|
-
tools)
|
|
39
|
-
|
|
40
|
-
- **
|
|
31
|
+
tools) hand one-shot work to a child you cannot see, steer, or keep
|
|
32
|
+
talking to. Its transcript collapses into a result.
|
|
33
|
+
- **tmux orchestration tools** spawn agents in panes but leave
|
|
41
34
|
coordination to chat transcripts or filesystem conventions.
|
|
42
|
-
- **Task trackers** (GitHub Issues, Linear
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
[§ What looking at a prior multi-agent runtime taught us](#what-looking-at-a-prior-multi-agent-runtime-taught-us).
|
|
48
|
-
|
|
49
|
-
mu unifies the first three without becoming the fourth: persistent
|
|
50
|
-
pi agents, a structured work graph, per-agent VCS isolation, one
|
|
51
|
-
CLI, one SQLite file. "What should this agent do next?" becomes:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
mu task next # top ready task by ROI
|
|
55
|
-
mu state # full picture as a JSON state card
|
|
56
|
-
```
|
|
35
|
+
- **Task trackers** (GitHub Issues, Linear) model the work but do not
|
|
36
|
+
run the agents.
|
|
37
|
+
- **Large orchestration platforms** hold the coordination state but
|
|
38
|
+
carry breadth that costs more to maintain than it returns. See
|
|
39
|
+
[What a prior runtime taught us](#what-a-prior-runtime-taught-us).
|
|
57
40
|
|
|
58
|
-
|
|
41
|
+
mu joins the first three without becoming the fourth.
|
|
59
42
|
|
|
60
|
-
## Design
|
|
43
|
+
## Design principles
|
|
61
44
|
|
|
62
45
|
### 1. The CLI is the product
|
|
63
46
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
Everything mu does works from a shell with no pi extension loaded. A
|
|
48
|
+
feature that needs the extension does not ship. The pi extension
|
|
49
|
+
(`mu link pi`) serves the control socket and the `mu_delegate` tool, and
|
|
50
|
+
three rules keep it thin:
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
1. **The DB is canonical.** The extension reads and writes through the
|
|
53
|
+
same modules as the CLI. It keeps no state of its own.
|
|
54
|
+
2. **Every operation works from the CLI.** No extension tool has logic
|
|
55
|
+
the CLI lacks.
|
|
56
|
+
3. **The skill teaches the CLI.** A pi session without the extension
|
|
57
|
+
still gets a working mu from [skills/mu/SKILL.md](../skills/mu/SKILL.md).
|
|
58
|
+
|
|
59
|
+
Delegation is CLI: `mu agent spawn -w scratch`, `mu agent send`, and
|
|
60
|
+
`mu agent wait --json`. `mu_delegate` only adds the callback that puts
|
|
61
|
+
the answer into the parent conversation.
|
|
72
62
|
|
|
73
63
|
### 2. One DB is canonical
|
|
74
64
|
|
|
75
|
-
All state lives in `~/.local/state/mu/mu.db
|
|
76
|
-
processes
|
|
77
|
-
|
|
78
|
-
so they never diverge.
|
|
65
|
+
All state lives in `~/.local/state/mu/mu.db` (SQLite WAL, safe for
|
|
66
|
+
concurrent processes). In-memory state is a cache. The extension and the
|
|
67
|
+
CLI share the DB, so they cannot diverge.
|
|
79
68
|
|
|
80
69
|
### 2b. One log records every change
|
|
81
70
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
**Sync, undo, rebuild, and history are all queries or replays over
|
|
88
|
-
that one log.**
|
|
71
|
+
The `ops` table is the only change record. SQLite triggers write it in
|
|
72
|
+
the same transaction as the mutation, so capture cannot be forgotten or
|
|
73
|
+
drift from the data. Sync, undo, rebuild, and history are queries or
|
|
74
|
+
replays over that log.
|
|
89
75
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
The cost: a capture bug is not "sync is broken", it is "undo and
|
|
97
|
-
rebuild are also broken". The drift check is load-bearing.
|
|
76
|
+
Reads still go to the tables. mu is not event-sourced: the tables are
|
|
77
|
+
the materialized view and triggers keep them in step with the ops.
|
|
78
|
+
`mu doctor` rebuilds into a temp DB and diffs, so that is verified, not
|
|
79
|
+
assumed. A capture bug therefore breaks sync, undo, and rebuild at once,
|
|
80
|
+
which is why the drift check is load-bearing.
|
|
98
81
|
|
|
99
82
|
### 2c. Local-first, transport-agnostic
|
|
100
83
|
|
|
101
|
-
Every machine keeps
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
present.
|
|
84
|
+
Every machine keeps a complete DB. Machines exchange append-only JSONL
|
|
85
|
+
segments, one per machine with a single writer, so no file is contended
|
|
86
|
+
and any file mover works (Syncthing, rsync, scp, git, a USB stick). mu
|
|
87
|
+
reads and writes files. The user owns transport. mu has no network
|
|
88
|
+
code, no daemon, and no membership config: peers are found from the
|
|
89
|
+
segment files present.
|
|
108
90
|
|
|
109
91
|
### 3. Reality wins reconciliation
|
|
110
92
|
|
|
111
|
-
`mu agent list` queries the mux, prunes ghosts, surfaces orphans.
|
|
112
|
-
records what
|
|
113
|
-
worker-1's pane crashed, the next `mu agent list` notices.
|
|
93
|
+
`mu agent list` queries the mux, prunes ghosts, and surfaces orphans.
|
|
94
|
+
The DB records what mu last observed.
|
|
114
95
|
|
|
115
96
|
### 4. Agents are dumb workers; the task graph is the brain
|
|
116
97
|
|
|
117
|
-
The
|
|
118
|
-
|
|
119
|
-
`
|
|
120
|
-
|
|
121
|
-
so two agents never collide on a shared dependency.
|
|
98
|
+
The task DAG is the center of mu, not a sidecar. Tasks require `impact`
|
|
99
|
+
and `effort_days`. Edges are `blocks` relations. `ready`, `blocked`, and
|
|
100
|
+
`goals` are SQL views. The parallel-track detector runs union-find and
|
|
101
|
+
merges diamonds, so two agents never collide on a shared dependency.
|
|
122
102
|
|
|
123
|
-
"What
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
agent gets which task*.
|
|
103
|
+
"What next?" and "can we parallelize?" are deterministic queries. The
|
|
104
|
+
LLM decides what to type to an agent. The graph decides which agent gets
|
|
105
|
+
which task.
|
|
127
106
|
|
|
128
107
|
### 5. One workstream per mux session
|
|
129
108
|
|
|
130
|
-
A
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
lives behind `MuxBackend` in `src/mux/`. Two implementations, not an
|
|
142
|
-
anticipatory abstraction: a third earns its way in on its own
|
|
143
|
-
friction evidence.
|
|
109
|
+
A workstream is a mux session: a tmux session on tmux, a herdr workspace
|
|
110
|
+
on herdr. Its agents are panes in that session, so
|
|
111
|
+
`tmux a -t mu-<workstream>` shows the whole crew. Workstreams on one
|
|
112
|
+
machine are separate sessions, partitioned in the DB by `session_id`.
|
|
113
|
+
The crew survives detach and reattach.
|
|
114
|
+
|
|
115
|
+
The multiplexer is a backend chosen by detection
|
|
116
|
+
(`MU_MUX` → `HERDR_ENV` → `$TMUX` → `PATH`), like the VCS backend.
|
|
117
|
+
Topology, the paste protocol, scrollback capture, pane-id validation,
|
|
118
|
+
and identity fallback live behind `MuxBackend` in `src/mux/`. There are
|
|
119
|
+
two implementations. A third needs its own friction evidence.
|
|
144
120
|
|
|
145
121
|
### 6. Pi-first, with reported agent state
|
|
146
122
|
|
|
147
|
-
mu
|
|
148
|
-
state through the mux. On tmux, murmur's pi extension reports state from
|
|
149
|
-
inside the agent process; without murmur, state is `unknown` with a reason.
|
|
123
|
+
mu never infers agent state from pane text. Each state source reports it:
|
|
150
124
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
125
|
+
| Agent | Send, abort, wait | State |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| pi (any backend, local or remote over `ssh -L`) | control socket, exact | control socket |
|
|
128
|
+
| other CLI on herdr | mux | herdr |
|
|
129
|
+
| other CLI on tmux | mux (bracketed paste) | murmur |
|
|
154
130
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
131
|
+
With no source, state is `unknown` with a reason. A pi agent whose
|
|
132
|
+
socket does not answer fails loudly; mu never falls back to pasting.
|
|
133
|
+
murmur is optional for pi agents.
|
|
134
|
+
|
|
135
|
+
`MU_PI_COMMAND="pi-alt --some-flag"` swaps the pi command for every
|
|
136
|
+
spawn. First-class support for other CLIs is not planned. It can earn promotion
|
|
137
|
+
under the [ROADMAP](ROADMAP.md) criteria: spawn accepts any command and
|
|
138
|
+
`agents.cli` is TEXT.
|
|
159
139
|
|
|
160
140
|
### 7. TypeScript on Node
|
|
161
141
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
The
|
|
168
|
-
|
|
169
|
-
-
|
|
170
|
-
`
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
- **
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
is
|
|
191
|
-
|
|
192
|
-
**Native dep:** `better-sqlite3` requires prebuilds or a C++
|
|
193
|
-
toolchain. Prebuilds cover darwin-arm64/x64, linux-x64/arm64,
|
|
194
|
-
win32-x64 — every dev workstation we care about. Acceptable.
|
|
195
|
-
|
|
196
|
-
### 8. Schema-first; typed verbs over read views; SQL as escape hatch
|
|
197
|
-
|
|
198
|
-
The product surface is:
|
|
199
|
-
|
|
200
|
-
- **Read views** (the `ready` / `blocked` / `goals` SQL views; `mu
|
|
201
|
-
state` as the curated state card) for inspection.
|
|
202
|
-
- **Typed verbs** that map cleanly to resource transitions for action
|
|
203
|
-
(`task add`, `task claim`, `task close`, `agent spawn --workspace`,
|
|
204
|
-
`workstream init`, `workstream destroy`, ...).
|
|
205
|
-
- **`--json` on every read verb** so scripts pipe through `jq`
|
|
206
|
-
instead of parsing tables.
|
|
207
|
-
- **`mu sql`** as the explicit escape hatch underneath.
|
|
208
|
-
|
|
209
|
-
There is no DSL, no plugin system, no workflow engine, no
|
|
210
|
-
`defineOperation` registry generating verbs from declarations. The
|
|
211
|
-
commander wiring in `src/cli.ts` is the single source of truth for
|
|
212
|
-
the verb surface. Adding a new verb is one SDK function plus one
|
|
213
|
-
commander block.
|
|
142
|
+
mu uses a few well-known npm dependencies (`commander`,
|
|
143
|
+
`better-sqlite3`, `cli-table3`, `picocolors`, `execa`, and `ink` for the
|
|
144
|
+
TUI). There is no native code to maintain and no build matrix.
|
|
145
|
+
|
|
146
|
+
- **Types pay.** The typed error classes map to exit codes in
|
|
147
|
+
`handle()`. The `assertXInWorkstream` family stays type-safe across
|
|
148
|
+
namespaces. `noUncheckedIndexedAccess` has caught real bugs.
|
|
149
|
+
- **`better-sqlite3` fits.** Synchronous calls match a short-lived CLI,
|
|
150
|
+
and `db.transaction()` is the right shape.
|
|
151
|
+
- **Iteration is fast.** Several substantive changes a day land in
|
|
152
|
+
about 99k lines of `src/` and `test/`.
|
|
153
|
+
|
|
154
|
+
The weak spot is cold start: Node takes 30–50 ms to boot, which matters
|
|
155
|
+
only in tight loops. If that changes, Rust is the port target.
|
|
156
|
+
`better-sqlite3` needs prebuilds (darwin-arm64/x64, linux-x64/arm64,
|
|
157
|
+
win32-x64) or a C++ toolchain.
|
|
158
|
+
|
|
159
|
+
### 8. Schema-first: typed verbs over read views, SQL as escape hatch
|
|
160
|
+
|
|
161
|
+
- **Read views**: the `ready`, `blocked`, and `goals` views, and
|
|
162
|
+
`mu state` as the state card.
|
|
163
|
+
- **Typed verbs** that map to resource transitions (`task claim`,
|
|
164
|
+
`task close`, `agent spawn --workspace`, `workstream destroy`).
|
|
165
|
+
- **`--json` on every read verb**, so scripts use `jq`, not table parsing.
|
|
166
|
+
- **`mu sql`** underneath, as the explicit escape hatch.
|
|
167
|
+
|
|
168
|
+
There is no DSL, no plugin system, no workflow engine, and no verb
|
|
169
|
+
registry. The commander wiring in `src/cli.ts` is the verb surface. A new
|
|
170
|
+
verb is one SDK function plus one commander block.
|
|
214
171
|
|
|
215
172
|
### 9. Observed vs claimed
|
|
216
173
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
still trusts the caller — mu doesn't run tests for you — but the
|
|
222
|
-
grounding for every state change is searchable via `mu log`.
|
|
174
|
+
A mutating verb records what the caller said it relied on.
|
|
175
|
+
`mu task close design --evidence "npm test exit 0"` lands in the ops log
|
|
176
|
+
with the evidence. mu does not run the tests, but `mu log` can search
|
|
177
|
+
the grounding for every change.
|
|
223
178
|
|
|
224
179
|
### 10. Get out of the model's way
|
|
225
180
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
- **
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
spawn command and the first message you send.
|
|
241
|
-
- **Tool routing decisions.** Pi (and any other CLI you spawn) owns
|
|
242
|
-
tool allowlists, MCP servers, extensions. Mu doesn't proxy or
|
|
243
|
-
inspect them.
|
|
244
|
-
- **Output interpretation.** Mu does not parse pane contents for agent
|
|
245
|
-
state, facts, claims, or tool calls. murmur or herdr reports runtime
|
|
246
|
-
agent state.
|
|
247
|
-
The `--evidence` payload is whatever the agent says it is; mu
|
|
248
|
-
records it without interpretation.
|
|
249
|
-
|
|
250
|
-
The full mechanism is one function: `--cli <key>` uppercases the
|
|
251
|
-
key and looks up `$MU_<KEY>_COMMAND`. That's mu's entire vendor
|
|
252
|
-
surface. The operator pattern when you want different models per
|
|
253
|
-
role is just convention on top:
|
|
181
|
+
mu coordinates agents and does not reason about them. It does not own:
|
|
182
|
+
|
|
183
|
+
- **Model selection or thinking levels.** No tiers, no provider matrix.
|
|
184
|
+
pi already takes `--model` and `--thinking`. Pass them through the
|
|
185
|
+
spawn command.
|
|
186
|
+
- **Prompts.** No system-prompt templates and no role registry. The
|
|
187
|
+
prompt is the spawn command plus the first message.
|
|
188
|
+
- **Tool routing.** The agent CLI owns tool allowlists, MCP servers, and
|
|
189
|
+
extensions.
|
|
190
|
+
- **Output interpretation.** mu does not parse panes for state, facts,
|
|
191
|
+
or tool calls. `--evidence` is recorded as given.
|
|
192
|
+
|
|
193
|
+
The whole vendor surface is one lookup: `--cli <key>` reads
|
|
194
|
+
`$MU_<KEY>_COMMAND`. Per-role models are a convention in your shell rc:
|
|
254
195
|
|
|
255
196
|
```bash
|
|
256
197
|
export MU_PI_MINI_COMMAND="pi --model haiku:off" # → --cli pi_mini
|
|
@@ -260,227 +201,76 @@ mu agent spawn worker-1 --cli pi_mini
|
|
|
260
201
|
mu agent spawn reviewer-1 --cli pi_big
|
|
261
202
|
```
|
|
262
203
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
and
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
`mu agent spawn --workspace` creates and mounts; `mu agent close`
|
|
288
|
-
auto-frees. Two parallel agents in the same project never trample
|
|
289
|
-
each other's working tree.
|
|
290
|
-
- **Async coordination via `mu log`** — Every state-changing verb
|
|
291
|
-
writes an op. Subscribers `mu log --tail` instead of polling.
|
|
292
|
-
Wakeups without a daemon.
|
|
293
|
-
- **Audit trail with grounding** — `--evidence` on lifecycle verbs
|
|
294
|
-
records what the caller observed, searchable via `mu log`.
|
|
295
|
-
- **Crash recovery** — Reconciliation prunes ghost agents; the reaper
|
|
296
|
-
reverts their IN_PROGRESS tasks to OPEN with an explanatory note;
|
|
297
|
-
no manual cleanup.
|
|
298
|
-
- **Human-driveable** — Anything mu can do, you can do from a shell.
|
|
299
|
-
Debug, recover, script, cron.
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## What It Is NOT
|
|
304
|
-
|
|
305
|
-
- **Not an orchestrator.** mu provides primitives. The orchestration
|
|
306
|
-
*policy* (when to spawn, what to assign, when to free) is yours —
|
|
307
|
-
expressed as bash scripts, jq pipelines over `--json` output, or
|
|
308
|
-
driven by an LLM through the bundled skill. There is no JS DSL,
|
|
309
|
-
no workflow engine, no `mu run script.ts`. <!-- doc-cli-drift:skip --> (See
|
|
310
|
-
[§ What looking at a prior multi-agent runtime taught us](#what-looking-at-a-prior-multi-agent-runtime-taught-us).)
|
|
311
|
-
- **Not a build tool.** mu doesn't compile, test, or deploy your code.
|
|
312
|
-
It runs agents that do those things.
|
|
313
|
-
- **Not a chat protocol.** Agents communicate through the work graph
|
|
314
|
-
(notes, claim, status) and the **ops log** read through `mu log`.
|
|
315
|
-
- **Not a hidden-subagent runner.** A one-shot **delegate** is an
|
|
316
|
-
ordinary agent in a visible pane: attach, steer, abort, or keep
|
|
317
|
-
talking to it. The cost is one pane and one pi process per delegate;
|
|
318
|
-
a hidden subagent is lighter for many tiny calls. mu bets that
|
|
319
|
-
visibility and steering are worth that for agent work. No agent
|
|
320
|
-
types: the brief is ad-hoc text.
|
|
321
|
-
- **Not a hosted service.** Local-first SQLite. Zero ops, no accounts.
|
|
322
|
-
Your machine is the deployment.
|
|
323
|
-
- **Not a verifier.** The verbs trust the caller. `task close
|
|
324
|
-
--evidence "tests pass"` records the claim; mu doesn't run the
|
|
325
|
-
tests. Verification is the caller's job. (mu may grow optional
|
|
326
|
-
verifying-runners later if friction surfaces; today it's an
|
|
327
|
-
audit-trail discipline, not enforcement.)
|
|
204
|
+
## What it enables
|
|
205
|
+
|
|
206
|
+
- **Visible crews.** Spawn agents once and send them work all day. Each
|
|
207
|
+
sits in a pane you can attach to.
|
|
208
|
+
- **Isolation.** Each agent gets a jj workspace, sl clone, git worktree,
|
|
209
|
+
or `cp -a` copy, detected automatically and freed by `mu agent close`.
|
|
210
|
+
- **Wakeups without a daemon.** `mu log --tail` and event-driven
|
|
211
|
+
`mu agent wait` replace polling.
|
|
212
|
+
- **Crash recovery.** The reaper reopens a dead agent's IN_PROGRESS
|
|
213
|
+
tasks with a note.
|
|
214
|
+
|
|
215
|
+
## What it is not
|
|
216
|
+
|
|
217
|
+
- **Not an orchestrator.** mu provides primitives. The policy (when to
|
|
218
|
+
spawn, what to assign, when to free) is yours: bash, `jq` over
|
|
219
|
+
`--json`, or an LLM following the bundled skill. There is no workflow
|
|
220
|
+
engine and no `mu run script.ts`. <!-- doc-cli-drift:skip -->
|
|
221
|
+
- **Not a chat protocol.** Agents communicate through notes, claims, and
|
|
222
|
+
the ops log.
|
|
223
|
+
- **Not a hidden-subagent runner.** A delegate is an ordinary agent in a
|
|
224
|
+
visible pane: attach, steer, abort, or keep talking to it. It costs one
|
|
225
|
+
pane and one pi process. A hidden subagent is lighter for many tiny
|
|
226
|
+
calls. mu bets that visibility and steering are worth the cost. There
|
|
227
|
+
are no agent types: the brief is plain text.
|
|
328
228
|
- **DB-undoable, not substrate-undoable.** `mu undo <group> --yes`
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
- `mu log --tail` — polls SQLite once per second; emits NDJSON
|
|
378
|
-
until SIGINT or the parent closes stdin.
|
|
379
|
-
- the TUI dashboard — rendered by `mu state --tui` explicitly or
|
|
380
|
-
by bare `mu` when stdout is attached to a TTY, until the user
|
|
381
|
-
quits with `q`/`Ctrl-C`. Plain `mu state` keeps the static-card
|
|
382
|
-
behaviour; non-TTY bare `mu` prints help instead of entering Ink.
|
|
383
|
-
|
|
384
|
-
Both share the same shape, and the shape is the predicate that
|
|
385
|
-
bounds the exception:
|
|
386
|
-
|
|
387
|
-
- **Interactive, not a daemon.** The process is owned by a
|
|
388
|
-
human (or a parent script) and dies the moment that owner
|
|
389
|
-
ends it. Nothing keeps it alive across sessions; nothing
|
|
390
|
-
restarts it.
|
|
391
|
-
- **Read-only against SQLite.** Neither verb writes. The TUI's
|
|
392
|
-
act-intents (claim, close, send, ...) yank the canonical
|
|
393
|
-
`mu <verb>` command into the clipboard and exit the
|
|
394
|
-
dashboard; every mutation still lands through a fresh
|
|
395
|
-
short-lived CLI invocation.
|
|
396
|
-
- **No resources beyond stdout, stdin, and a poll timer.** No
|
|
397
|
-
sockets, no file watches, no subscriptions to external
|
|
398
|
-
services, no spawned subprocesses, no inter-process state
|
|
399
|
-
beyond the SQLite reads any other CLI invocation already
|
|
400
|
-
does.
|
|
401
|
-
- **Human-TTY gated, with static/script fallbacks.** The TUI mode
|
|
402
|
-
activates when `--tui` is passed to `mu state` or when bare `mu`
|
|
403
|
-
sees `process.stdout.isTTY === true`. Default `mu state` prints
|
|
404
|
-
the static card. Non-interactive callers (pipes, CI, `--json`, or
|
|
405
|
-
`MU_NO_TUI=1`) never enter the TUI.
|
|
406
|
-
|
|
407
|
-
This is not a precedent for any other long-lived process. The
|
|
408
|
-
anti-feature pledges in [ROADMAP.md](ROADMAP.md) remain in force;
|
|
409
|
-
a third member of this exception class needs its own promotion.
|
|
410
|
-
|
|
411
|
-
---
|
|
412
|
-
|
|
413
|
-
## What looking at a prior multi-agent runtime taught us
|
|
414
|
-
|
|
415
|
-
A five-role council critique of a prior internal multi-agent runtime
|
|
416
|
-
— mu's design ancestor — converged on a sharp central claim:
|
|
417
|
-
|
|
418
|
-
> [The runtime] is not justified as a better general coding harness.
|
|
419
|
-
> [The runtime] is justified only when it becomes a durable
|
|
420
|
-
> coordination/control plane for work that outgrows a thin harness
|
|
421
|
-
> plus manually managed tmux.
|
|
422
|
-
|
|
423
|
-
And a sharper recommendation for what such a control plane should
|
|
424
|
-
look like:
|
|
425
|
-
|
|
426
|
-
> A minimal defensible core would be: durable sessions/transcripts;
|
|
427
|
-
> agent registry; task records / task graph; workspace and checkout
|
|
428
|
-
> ownership/leases; event log; wakeups/timers; human approvals/input;
|
|
429
|
-
> typed control API; read-only views/state cards; recovery/orphan
|
|
430
|
-
> detection.
|
|
431
|
-
>
|
|
432
|
-
> Everything else — chat, docs, IDE assist, incident-triage,
|
|
433
|
-
> mobile-agent, end-to-end workflows, memory policy, rich
|
|
434
|
-
> dashboards, workflow DSLs — should be optional layers that prove
|
|
435
|
-
> they strengthen the supervision loop.
|
|
436
|
-
|
|
437
|
-
Nine of the ten items in that minimal core ship in mu; almost every
|
|
438
|
-
item the council criticised is something mu does not have.
|
|
439
|
-
|
|
440
|
-
### The council's criticisms → mu's design choices
|
|
441
|
-
|
|
442
|
-
| Council critique of the prior runtime | mu's stance |
|
|
443
|
-
| ------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
444
|
-
| "Sprawling product identities (TUI + web + Thrift + plugin host + workflow engine + chat + docs + memory + ...)" | One CLI, one SQLite file, no plugins, no web UI, no Thrift, no chat/docs integrations. |
|
|
445
|
-
| "Workflow DSL is mostly liability" | Rejected outright. No `mu run`/`eval`/`repl`. <!-- doc-cli-drift:skip --> `--json` + bash + jq cover the scripting story. |
|
|
446
|
-
| "defineOperation/verb-registry adds entropy without consumers" | Rejected. The commander wiring in `src/cli.ts` is the verb surface; one place. |
|
|
447
|
-
| "Plugin sprawl with hidden state and lifecycle bugs" | No plugins. Adding behaviour is a typed verb in `src/cli.ts`. |
|
|
448
|
-
| "CLI verbs as a primary model surface vs. typed mutations" | mu's verbs *are* the typed mutations. CLI is a thin wrapper over a typed SDK with idempotency, validation, exit-code-mapped errors. |
|
|
449
|
-
| "Raw SQL as the only inspection surface is too low-level" | `mu state` is the canonical state card. `--json` everywhere. `mu sql` is the escape hatch beneath, not the cockpit. |
|
|
450
|
-
| "Distinguish observed from claimed state" | `--evidence` on lifecycle verbs (first inch). The verb still trusts the caller; the audit trail records grounding. |
|
|
451
|
-
| "Approval primitives belong in the core" | Not in mu: dogfood across 200+ tasks produced zero calls for them. Anti-anticipatory pruning per "no traits with zero implementors". May earn promotion when a real implementor surfaces (e.g. an unattended pi-orchestrator running mu). |
|
|
452
|
-
| "Reads must distinguish provenance (process telemetry vs agent self-report)" | event `source` field attributes events to actor (claiming agent / decider / 'system'). |
|
|
453
|
-
| "State must be authoritative and recoverable, not just durable" | Reconciliation runs on read paths; reaper recovers stuck IN_PROGRESS automatically. |
|
|
454
|
-
|
|
455
|
-
### What this validates
|
|
456
|
-
|
|
457
|
-
1. **The anti-feature pledges hold.** No DSL, no plugins,
|
|
458
|
-
no daemon, no config file, no web UI. Each is a failure mode the
|
|
459
|
-
prior runtime exhibited and mu chose not to inherit.
|
|
460
|
-
|
|
461
|
-
2. **"Pi+tmux is the benchmark" is the right comparison.** mu only
|
|
462
|
-
earns its complexity above the threshold where coordination
|
|
463
|
-
itself is the work — multiple agents, multiple checkouts, delayed
|
|
464
|
-
wakeups, recovery, approvals. Below that, a thin harness with
|
|
465
|
-
manual tmux is more transparent.
|
|
466
|
-
|
|
467
|
-
3. **Schema-first + typed verbs + state cards is the right model UX
|
|
468
|
-
shape** — independent reasoning from operators, engineers,
|
|
469
|
-
architects, and model-UX specialists converges on it.
|
|
470
|
-
|
|
471
|
-
### What this still flags as gaps
|
|
472
|
-
|
|
473
|
-
The critique cuts mu too:
|
|
474
|
-
|
|
475
|
-
- **Wakeups are polling-based.** `mu log --tail` polls every 1s.
|
|
476
|
-
Real subscriptions (SQLite update hooks) are deferred.
|
|
477
|
-
- **`--evidence` is grounding, not verification.** mu doesn't run the
|
|
478
|
-
tests. A future `--verify-by` mode that runs a command and records
|
|
479
|
-
its exit could deepen this; not built yet.
|
|
480
|
-
- **No idempotency keys on mutations.** Most ops are idempotent by
|
|
481
|
-
happenstance; not declared as part of the API contract.
|
|
482
|
-
- **No dry-run on most mutations.** `workstream destroy`, `task delete`, and `undo` have it; most other mutating verbs apply immediately.
|
|
483
|
-
- **No capability model.** The `role` field is stored on agent rows
|
|
484
|
-
but unused. No "reviewer-1 cannot delete tasks" enforcement.
|
|
485
|
-
|
|
486
|
-
Each is a known gap with a clear shape; none has earned promotion.
|
|
229
|
+
restores rows. It does not revive killed panes or freed workspace
|
|
230
|
+
directories. Reconciliation then reports ghosts and orphans.
|
|
231
|
+
|
|
232
|
+
## Key constraints
|
|
233
|
+
|
|
234
|
+
1. **A multiplexer is required** (tmux or herdr). `mu doctor` reports
|
|
235
|
+
the backend. Agent verbs exit 5 when none is reachable.
|
|
236
|
+
2. **The agent never acknowledges a send.** For pi, the control socket
|
|
237
|
+
confirms that pi accepted the message. On the mux path, mu confirms
|
|
238
|
+
only that the text reached the pane and warns when it cannot confirm
|
|
239
|
+
submission. Use `mu agent wait` or `mu log --tail` to see the effect.
|
|
240
|
+
3. **Recursion is opt-in.** `mu_delegate` is hidden in agents mu spawned
|
|
241
|
+
(`MU_MANAGED_AGENT`). Agents have `mu` on PATH, but the skill tells
|
|
242
|
+
them they are not the orchestrator.
|
|
243
|
+
4. **Every invocation is short-lived, except two interactive readers.**
|
|
244
|
+
No daemon, no resident state outside SQLite, no background process.
|
|
245
|
+
The exceptions are `mu log --tail` and the TUI (`mu state --tui`, or
|
|
246
|
+
bare `mu` on a TTY). Both are:
|
|
247
|
+
- owned by a human or parent script and gone when it ends;
|
|
248
|
+
- read-only: TUI actions copy the `mu <verb>` command to the
|
|
249
|
+
clipboard and exit, so every write is a fresh CLI call;
|
|
250
|
+
- limited to stdin, stdout, and a poll timer: no sockets, watches, or
|
|
251
|
+
subprocesses;
|
|
252
|
+
- TTY-gated: pipes, CI, `--json`, and `MU_NO_TUI=1` never enter the
|
|
253
|
+
TUI, and plain `mu state` prints the static card.
|
|
254
|
+
|
|
255
|
+
The control socket is not a third exception. The pi process serves it
|
|
256
|
+
and it dies with that process. Any other long-lived process needs its
|
|
257
|
+
own promotion; the [anti-feature pledges](ROADMAP.md#anti-feature-pledges)
|
|
258
|
+
stand.
|
|
259
|
+
|
|
260
|
+
## What a prior runtime taught us
|
|
261
|
+
|
|
262
|
+
A council review of mu's design ancestor, a larger internal multi-agent
|
|
263
|
+
runtime, found it justified only as a durable coordination control
|
|
264
|
+
plane. Its minimal core: sessions, an agent registry, a task graph,
|
|
265
|
+
workspace ownership, an event log, wakeups, human approvals, a typed
|
|
266
|
+
control API, read-only state cards, and orphan recovery. Everything else
|
|
267
|
+
(chat, workflow DSLs, memory, dashboards) had to prove its worth.
|
|
268
|
+
|
|
269
|
+
mu ships nine of the ten. Approvals are missing because 200+ dogfooded
|
|
270
|
+
tasks never needed them. Below the point where coordination is itself
|
|
271
|
+
the work, pi plus manual tmux is more transparent than mu.
|
|
272
|
+
|
|
273
|
+
Known gaps, none promoted yet: `--evidence` grounds but does not verify,
|
|
274
|
+
mutations have no declared idempotency keys, most mutations have no dry
|
|
275
|
+
run (`workstream destroy`, `task delete`, and `undo` do), and the `role`
|
|
276
|
+
field is stored but not enforced.
|