@mu-crew/mu 1.6.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/docs/VISION.md ADDED
@@ -0,0 +1,487 @@
1
+ # VISION: A persistent crew of agents
2
+
3
+ > Terminology used in this doc is canonical. See
4
+ > [VOCABULARY.md](VOCABULARY.md) for definitions of *workstream*,
5
+ > *agent*, *task DAG*, *crew*, *track*, *claim*, *free*, *workspace*,
6
+ > and the rest.
7
+
8
+ ## What This Is
9
+
10
+ mu is a small, durable **control plane** for a persistent crew of AI
11
+ agents in multiplexer panes. Agents have names, roles, and status; they live
12
+ across sessions; they work on a built-in task graph with VCS
13
+ workspace isolation; humans and other agents drive them through one
14
+ CLI. State lives in one SQLite file; every mu feature is a typed verb
15
+ over that state or a reconciled view of reality.
16
+
17
+ ```bash
18
+ mu agent spawn worker-1 --tab Backend --workspace
19
+ mu agent spawn reviewer-1 --tab Review --workspace --role read-only
20
+ mu task add --title "Build auth" --impact 80 --effort-days 3
21
+ mu task claim build_auth --for worker-1 --evidence "have implementation plan"
22
+ mu agent send worker-1 "Implement build_auth per the description"
23
+ mu state # canonical state card
24
+ mu log --tail # subscribe to every state change
25
+ ```
26
+
27
+ That's the whole product. Everything else makes those few lines work,
28
+ recover from failure, and scale to dozens of agents and hundreds of
29
+ tasks.
30
+
31
+ ---
32
+
33
+ ## Why It Exists
34
+
35
+ Existing tools force a choice:
36
+
37
+ - **Pi-subagents** is great for one-shot focused delegation but the
38
+ children it spawns are short-lived, pi-only, and not driveable from
39
+ outside their parent pi session.
40
+ - **Tmux-orchestration tools** spawn agents in panes but leave
41
+ coordination to chat transcripts or filesystem conventions.
42
+ - **Task trackers** (GitHub Issues, Linear, even tg) model the work but
43
+ don't run the agents.
44
+ - **Bigger orchestration platforms** carry the coordination state but
45
+ have accumulated breadth that costs more in maintenance than it
46
+ pays for. See
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
+ ```
57
+
58
+ ---
59
+
60
+ ## Design Principles
61
+
62
+ ### 1. The CLI is the product
63
+
64
+ The pi extension is a UX skin. Everything mu does must work from a
65
+ shell with no pi anywhere. A feature that requires the extension
66
+ doesn't ship.
67
+
68
+ ### 2. One DB is canonical
69
+
70
+ All state lives in `~/.local/state/mu/mu.db`. SQLite WAL; multiple
71
+ processes share it safely. The DB is the source of truth; in-memory
72
+ state is a cache. The extension and the CLI go through the same DB,
73
+ so they never diverge.
74
+
75
+ ### 2b. One log records every change
76
+
77
+ There is exactly **one** record of change: the `ops` table, written by
78
+ SQLite triggers inside the same transaction as the mutation they
79
+ record. Same file, same transaction — so capture cannot be forgotten
80
+ and cannot drift from the data, even on power loss.
81
+
82
+ **Sync, undo, rebuild, and history are all queries or replays over
83
+ that one log.**
84
+
85
+ The tables stay canonical for **reads** — this is not an event-sourced
86
+ system that replays to answer a query. Ops are the durable change
87
+ record; the tables are the materialized view; triggers keep them in
88
+ lockstep. `mu doctor` rebuilds into a temp DB and diffs, so the
89
+ lockstep is verified rather than assumed.
90
+
91
+ The cost: a capture bug is not "sync is broken", it is "undo and
92
+ rebuild are also broken". The drift check is load-bearing.
93
+
94
+ ### 2c. Local-first, transport-agnostic
95
+
96
+ Every machine keeps its own complete DB. Machines exchange
97
+ append-only JSONL **segments** — one per machine, single-writer, so no
98
+ file is ever contended and any file-mover (Syncthing, rsync, scp,
99
+ git, a USB stick) is adequate transport. mu reads and writes files;
100
+ **the user owns transport**. mu has no network code, no daemon, and
101
+ no membership config — peers are discovered from the segment files
102
+ present.
103
+
104
+ ### 3. Reality wins reconciliation
105
+
106
+ `mu agent list` queries the mux, prunes ghosts, surfaces orphans. The DB
107
+ records what we last observed, not what we wish were true. If
108
+ worker-1's pane crashed, the next `mu agent list` notices.
109
+
110
+ ### 4. Agents are dumb workers; the task graph is the brain
111
+
112
+ The **task DAG is the central organizing primitive**, not a sidecar
113
+ feature. Tasks have mandatory `impact` and `effort_days`; edges are
114
+ `blocks` relationships; `ready`/`blocked`/`goals` are SQL views; the
115
+ parallel-track detector runs union-find with automatic diamond-merge
116
+ so two agents never collide on a shared dependency.
117
+
118
+ "What should this agent do next?" and "can we parallelize?" are
119
+ deterministic queries against the graph, not LLM judgment calls. The
120
+ LLM decides *what to type to the agent*; the graph decides *which
121
+ agent gets which task*.
122
+
123
+ ### 5. One workstream per mux session
124
+
125
+ A mu workstream is a **mux session** — a tmux session on the tmux
126
+ backend, a herdr workspace on the herdr backend. All its agents are
127
+ panes/windows inside that session. `tmux a -t mu-<workstream>` shows
128
+ the whole crew live. Multiple workstreams on one machine are multiple
129
+ isolated mux sessions, partitioned in the DB by `session_id`. Detach
130
+ and reattach as you would any tmux session — the crew survives.
131
+
132
+ The multiplexer is a **backend**, chosen by detection
133
+ (`MU_MUX` → `HERDR_ENV` → `$TMUX` → `PATH`), the same shape as the
134
+ VCS backend. Everything backend-specific — topology, the send
135
+ protocol, scrollback capture, pane-id validation, identity fallback —
136
+ lives behind `MuxBackend` in `src/mux/`. Two implementations, not an
137
+ anticipatory abstraction: a third earns its way in on its own
138
+ friction evidence.
139
+
140
+ ### 6. Pi-first, and what the mux knows
141
+
142
+ Mu's own status detection (`busy` / `needs_input` / `needs_permission`)
143
+ is pi-only, plus a Braille-spinner fallback that catches most TUI
144
+ wrappers. `--cli <name>` accepts other strings, but on the tmux
145
+ backend no other CLI ships with a detector, so an unrecognized pane
146
+ tends to read `needs_input`.
147
+
148
+ A mux that classifies panes itself changes this. The herdr backend
149
+ reports agent state natively across the agent kinds it knows, so on
150
+ that backend mu takes the mux's word and skips scrollback scraping
151
+ entirely. Detection is a property of the **mux backend**, not a fixed
152
+ property of mu.
153
+
154
+ `--cli` and `MU_<UPPER_CLI>_COMMAND` stay useful for swapping the pi
155
+ binary: set `MU_PI_COMMAND=<name>` once and every spawn picks it up.
156
+ Multi-word commands work: `MU_PI_COMMAND="pi-alt --some-flag"`.
157
+
158
+ Multi-CLI support (claude / codex with real detection) is not
159
+ planned. The substrate is ready if it earns promotion per the
160
+ [ROADMAP](ROADMAP.md) criteria: spawn accepts arbitrary commands and
161
+ the schema's `cli` column is TEXT.
162
+
163
+ ### 7. TypeScript on Node
164
+
165
+ Mu is TypeScript on Node, with a small set of well-established
166
+ npm deps (`commander`, `better-sqlite3`, `cli-table3`, `picocolors`,
167
+ `execa`). No native code we maintain, no build matrix. Anyone
168
+ reading `package.json` should recognize every name.
169
+
170
+ The choice earns its keep on four axes:
171
+
172
+ - **The type system pays.** The `AgentNotFoundError` /
173
+ `TaskNotFoundError` / `TaskNotInWorkstreamError` / `CycleError`
174
+ hierarchy maps to exit codes via `handle()`; the
175
+ `assertXInWorkstream` family stays type-safe across every
176
+ namespace; `noUncheckedIndexedAccess` has caught real bugs. Go
177
+ loses the discriminated unions, Python's checker is too weak,
178
+ Rust costs 2–3× the LOC.
179
+ - **JSON-first surface fits TS.** Every read verb's `--json` output
180
+ is `JSON.stringify(value)` straight from a typed shape.
181
+ - **`better-sqlite3` fits the shape.** Synchronous
182
+ request/response matches the CLI invocation model; WAL correct out
183
+ of the box; `db.transaction()` is the right shape.
184
+ - **Iteration speed.** ~60 typed verbs / 10 tables / ~2900 tests
185
+ (`npm run test`) in ~95k LOC src+tests (`wc -l` over `src/` and
186
+ `test/`), with multiple substantive changes per day. That cadence
187
+ in an equivalent Rust codebase would be 2–3× slower.
188
+
189
+ **Where it's weak: cold start.** Node's V8 init is ~30–50ms even
190
+ after tsup bundles (Rust ~5ms, Go ~10–15ms). That would matter if
191
+ mu were called in tight loops, but the docs steer operators away
192
+ from polling toward `mu log --tail`. If that stops being true, Rust
193
+ is the natural port target.
194
+
195
+ **Native dep:** `better-sqlite3` requires prebuilds or a C++
196
+ toolchain. Prebuilds cover darwin-arm64/x64, linux-x64/arm64,
197
+ win32-x64 — every dev workstation we care about. Acceptable.
198
+
199
+ ### 8. Schema-first; typed verbs over read views; SQL as escape hatch
200
+
201
+ The product surface is:
202
+
203
+ - **Read views** (the `ready` / `blocked` / `goals` SQL views; `mu
204
+ state` as the curated state card) for inspection.
205
+ - **Typed verbs** that map cleanly to resource transitions for action
206
+ (`task add`, `task claim`, `task close`, `agent spawn --workspace`,
207
+ `workstream init`, `workstream destroy`, ...).
208
+ - **`--json` on every read verb** so scripts pipe through `jq`
209
+ instead of parsing tables.
210
+ - **`mu sql`** as the explicit escape hatch underneath.
211
+
212
+ There is no DSL, no plugin system, no workflow engine, no
213
+ `defineOperation` registry generating verbs from declarations. The
214
+ commander wiring in `src/cli.ts` is the single source of truth for
215
+ the verb surface. Adding a new verb is one SDK function plus one
216
+ commander block.
217
+
218
+ ### 9. Observed vs claimed
219
+
220
+ When a verb mutates state, the audit trail records what the caller
221
+ said it relied on. `mu task close design --evidence "tests pass:
222
+ npm test exit 0"` lands in the ops log as
223
+ `task status design (IN_PROGRESS → CLOSED) evidence="..."`. The verb
224
+ still trusts the caller — mu doesn't run tests for you — but the
225
+ grounding for every state change is searchable via `mu log`.
226
+
227
+ ### 10. Get out of the model's way
228
+
229
+ Mu coordinates agents; it does not reason about them. Specifically,
230
+ mu does not own:
231
+
232
+ - **Model selection.** No tier abstraction, no provider matrix, no
233
+ vendor-name mapping. Pi already speaks `--model sonnet:high` and
234
+ `--provider openai`. Inventing tier names would mean owning a
235
+ vendor matrix that goes stale every quarter.
236
+ - **Effort / thinking levels.** Pi has
237
+ `--thinking off|minimal|low|medium|high|xhigh`. Mu doesn't wrap
238
+ it, doesn't normalise it, doesn't second-guess it. Pass-through
239
+ via `--command` or the `MU_<UPPER_CLI>_COMMAND` env var, full stop.
240
+ - **Prompt engineering.** Mu has no system-prompt templating, no
241
+ role injection beyond the agent name and `--role`, no "agent
242
+ template" registry. The system prompt is whatever you put in the
243
+ spawn command and the first message you send.
244
+ - **Tool routing decisions.** Pi (and any other CLI you spawn) owns
245
+ tool allowlists, MCP servers, extensions. Mu doesn't proxy or
246
+ inspect them.
247
+ - **Output interpretation.** Mu reads pane contents to detect
248
+ `busy / needs_input / idle / done` (a 4-state classification).
249
+ It does not parse model output for facts, claims, or tool calls.
250
+ The `--evidence` payload is whatever the agent says it is; mu
251
+ records it without interpretation.
252
+
253
+ The full mechanism is one function: `--cli <key>` uppercases the
254
+ key and looks up `$MU_<KEY>_COMMAND`. That's mu's entire vendor
255
+ surface. The operator pattern when you want different models per
256
+ role is just convention on top:
257
+
258
+ ```bash
259
+ export MU_PI_MINI_COMMAND="pi --model haiku:off" # → --cli pi_mini
260
+ export MU_PI_BIG_COMMAND="pi --model opus:high" # → --cli pi_big
261
+
262
+ mu agent spawn worker-1 --cli pi_mini
263
+ mu agent spawn reviewer-1 --cli pi_big
264
+ ```
265
+
266
+ Your shell rc owns the mapping. The names `pi_mini` / `pi_big` are
267
+ operator convention — mu doesn't know about "tiers," it just looks
268
+ up whatever env var the uppercased key produces. Swap the whole
269
+ matrix in one line; per-machine, per-workstream, per project —
270
+ wherever you set the env. The substrate stays small; the
271
+ orchestrator stays in charge.
272
+
273
+ ---
274
+
275
+ ## What It Enables
276
+
277
+ - **Persistent crews in one place** — Spawn worker-1/worker-2/reviewer-1
278
+ once, send them work all day. `tmux a -t mu-<workstream>` shows
279
+ the whole crew: each agent in its own pane, observable, detachable.
280
+ - **Graph-driven coordination** — The task DAG answers "what's ready?",
281
+ "what blocks what?", "what can be parallelized?" with SQL queries
282
+ and union-find, not LLM guesses. Task notes accumulate durable
283
+ context that outlives any single agent or session.
284
+ - **Deterministic parallelization** — Diamond patterns (shared
285
+ prerequisites) get merged automatically so two agents never collide
286
+ on a shared dependency. The orchestrator follows the algorithm; it
287
+ doesn't have to be smart enough to spot the trap.
288
+ - **VCS workspace isolation** — Each agent gets its own jj workspace,
289
+ sl clone, git worktree, or `cp -a` snapshot, auto-detected.
290
+ `mu agent spawn --workspace` creates and mounts; `mu agent close`
291
+ auto-frees. Two parallel agents in the same project never trample
292
+ each other's working tree.
293
+ - **Async coordination via `mu log`** — Every state-changing verb
294
+ writes an op. Subscribers `mu log --tail` instead of polling.
295
+ Wakeups without a daemon.
296
+ - **Audit trail with grounding** — `--evidence` on lifecycle verbs
297
+ records what the caller observed, searchable via `mu log`.
298
+ - **Crash recovery** — Reconciliation prunes ghost agents; the reaper
299
+ reverts their IN_PROGRESS tasks to OPEN with an explanatory note;
300
+ no manual cleanup.
301
+ - **Human-driveable** — Anything mu can do, you can do from a shell.
302
+ Debug, recover, script, cron.
303
+
304
+ ---
305
+
306
+ ## What It Is NOT
307
+
308
+ - **Not an orchestrator.** mu provides primitives. The orchestration
309
+ *policy* (when to spawn, what to assign, when to free) is yours —
310
+ expressed as bash scripts, jq pipelines over `--json` output, or
311
+ driven by an LLM through the bundled skill. There is no JS DSL,
312
+ no workflow engine, no `mu run script.ts`. <!-- doc-cli-drift:skip --> (See
313
+ [§ What looking at a prior multi-agent runtime taught us](#what-looking-at-a-prior-multi-agent-runtime-taught-us).)
314
+ - **Not a build tool.** mu doesn't compile, test, or deploy your code.
315
+ It runs agents that do those things.
316
+ - **Not a chat protocol.** Agents communicate through the work graph
317
+ (notes, claim, status) and the **ops log** read through `mu log`.
318
+ - **Not a replacement for pi-subagents.** Different problem (persistent
319
+ crew vs one-shot focused delegation). Install both; they share the
320
+ agent-frontmatter format.
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.)
328
+ - **DB-undoable, not substrate-undoable.** `mu undo <group> --yes`
329
+ emits inverse ops for one action and restores the rows. It does not
330
+ replay killed mux panes or recreate freed workspace directories;
331
+ after an undo, reconciliation reports ghosts/orphans and the caller
332
+ decides what to re-spawn or adopt.
333
+
334
+ ---
335
+
336
+ ## Key Constraints
337
+
338
+ 1. **A multiplexer is required.** The substrate is mux panes — tmux or
339
+ herdr. No multiplexer, no agents. `mu doctor` reports the resolved
340
+ backend and its version; verbs that touch the agent layer fail with
341
+ exit 5 when none is reachable.
342
+
343
+ 2. **Local-first persistence.** SQLite file at
344
+ `~/.local/state/mu/mu.db`. Cross-machine state moves as
345
+ append-only JSONL segments in a shared folder; you own transport.
346
+
347
+ 3. **Pi-first.** mu's own status detection targets pi. `--cli pi` is
348
+ the meaningful default; `--cli` accepts other strings as a key for
349
+ the `MU_<UPPER_CLI>_COMMAND` env var resolver. On tmux no other CLI
350
+ has a detector; on a backend that classifies panes itself (herdr),
351
+ mu defers to it. Either way we optimize for
352
+ false-negative-then-poll over false-positive-then-act.
353
+
354
+ 4. **Send is delivered, not acknowledged.** `mu agent send` gets the
355
+ text into the pane and warns loudly when it cannot confirm
356
+ submission, but the AGENT never acknowledges receipt.
357
+ Orchestrators poll status or subscribe to
358
+ `mu log --tail` for confirmation. This is by design — the
359
+ alternative requires a protocol every CLI would have to speak.
360
+
361
+ 5. **Recursion is opt-in.** Default `maxSubagentDepth: 0`. Children
362
+ get the `mu` binary on PATH but the bundled skill says "you are
363
+ not the orchestrator."
364
+
365
+ 6. **Subscriptions are polling-based.** `mu log --tail` polls
366
+ SQLite once per second. SQLite handles the concurrency; latency
367
+ is bounded by the poll interval. Real subscription mechanisms
368
+ (SQLite hooks, fs.watch) are a future ask if anyone hits the
369
+ latency cliff.
370
+
371
+ 7. **Every invocation is short-lived — except for two named
372
+ interactive readers.** mu is a CLI: each verb starts, mutates
373
+ or reads, prints, and exits. There is no daemon, no resident
374
+ state outside SQLite, no background process. Two verbs are
375
+ exempt, narrowly, because they are interactive *readers* rather
376
+ than background workers:
377
+
378
+ - `mu log --tail` — polls SQLite once per second; emits NDJSON
379
+ until SIGINT or the parent closes stdin.
380
+ - the TUI dashboard — rendered by `mu state --tui` explicitly or
381
+ by bare `mu` when stdout is attached to a TTY, until the user
382
+ quits with `q`/`Ctrl-C`. Plain `mu state` keeps the static-card
383
+ behaviour; non-TTY bare `mu` prints help instead of entering Ink.
384
+
385
+ Both share the same shape, and the shape is the predicate that
386
+ bounds the exception:
387
+
388
+ - **Interactive, not a daemon.** The process is owned by a
389
+ human (or a parent script) and dies the moment that owner
390
+ ends it. Nothing keeps it alive across sessions; nothing
391
+ restarts it.
392
+ - **Read-only against SQLite.** Neither verb writes. The TUI's
393
+ act-intents (claim, close, send, ...) yank the canonical
394
+ `mu <verb>` command into the clipboard and exit the
395
+ dashboard; every mutation still lands through a fresh
396
+ short-lived CLI invocation.
397
+ - **No resources beyond stdout, stdin, and a poll timer.** No
398
+ sockets, no file watches, no subscriptions to external
399
+ services, no spawned subprocesses, no inter-process state
400
+ beyond the SQLite reads any other CLI invocation already
401
+ does.
402
+ - **Human-TTY gated, with static/script fallbacks.** The TUI mode
403
+ activates when `--tui` is passed to `mu state` or when bare `mu`
404
+ sees `process.stdout.isTTY === true`. Default `mu state` prints
405
+ the static card. Non-interactive callers (pipes, CI, `--json`, or
406
+ `MU_NO_TUI=1`) never enter the TUI.
407
+
408
+ This is not a precedent for any other long-lived process. The
409
+ anti-feature pledges in [ROADMAP.md](ROADMAP.md) remain in force;
410
+ a third member of this exception class needs its own promotion.
411
+
412
+ ---
413
+
414
+ ## What looking at a prior multi-agent runtime taught us
415
+
416
+ A five-role council critique of a prior internal multi-agent runtime
417
+ — mu's design ancestor — converged on a sharp central claim:
418
+
419
+ > [The runtime] is not justified as a better general coding harness.
420
+ > [The runtime] is justified only when it becomes a durable
421
+ > coordination/control plane for work that outgrows a thin harness
422
+ > plus manually managed tmux.
423
+
424
+ And a sharper recommendation for what such a control plane should
425
+ look like:
426
+
427
+ > A minimal defensible core would be: durable sessions/transcripts;
428
+ > agent registry; task records / task graph; workspace and checkout
429
+ > ownership/leases; event log; wakeups/timers; human approvals/input;
430
+ > typed control API; read-only views/state cards; recovery/orphan
431
+ > detection.
432
+ >
433
+ > Everything else — chat, docs, IDE assist, incident-triage,
434
+ > mobile-agent, end-to-end workflows, memory policy, rich
435
+ > dashboards, workflow DSLs — should be optional layers that prove
436
+ > they strengthen the supervision loop.
437
+
438
+ Nine of the ten items in that minimal core ship in mu; almost every
439
+ item the council criticised is something mu does not have.
440
+
441
+ ### The council's criticisms → mu's design choices
442
+
443
+ | Council critique of the prior runtime | mu's stance |
444
+ | ------------------------------------------------------------- | -------------------------------------------------------------------------- |
445
+ | "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. |
446
+ | "Workflow DSL is mostly liability" | Rejected outright. No `mu run`/`eval`/`repl`. <!-- doc-cli-drift:skip --> `--json` + bash + jq cover the scripting story. |
447
+ | "defineOperation/verb-registry adds entropy without consumers" | Rejected. The commander wiring in `src/cli.ts` is the verb surface; one place. |
448
+ | "Plugin sprawl with hidden state and lifecycle bugs" | No plugins. Adding behaviour is a typed verb in `src/cli.ts`. |
449
+ | "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. |
450
+ | "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. |
451
+ | "Distinguish observed from claimed state" | `--evidence` on lifecycle verbs (first inch). The verb still trusts the caller; the audit trail records grounding. |
452
+ | "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). |
453
+ | "Reads must distinguish provenance (process telemetry vs agent self-report)" | event `source` field attributes events to actor (claiming agent / decider / 'system'). |
454
+ | "State must be authoritative and recoverable, not just durable" | Reconciliation runs on read paths; reaper recovers stuck IN_PROGRESS automatically. |
455
+
456
+ ### What this validates
457
+
458
+ 1. **The anti-feature pledges hold.** No DSL, no plugins,
459
+ no daemon, no config file, no web UI. Each is a failure mode the
460
+ prior runtime exhibited and mu chose not to inherit.
461
+
462
+ 2. **"Pi+tmux is the benchmark" is the right comparison.** mu only
463
+ earns its complexity above the threshold where coordination
464
+ itself is the work — multiple agents, multiple checkouts, delayed
465
+ wakeups, recovery, approvals. Below that, a thin harness with
466
+ manual tmux is more transparent.
467
+
468
+ 3. **Schema-first + typed verbs + state cards is the right model UX
469
+ shape** — independent reasoning from operators, engineers,
470
+ architects, and model-UX specialists converges on it.
471
+
472
+ ### What this still flags as gaps
473
+
474
+ The critique cuts mu too:
475
+
476
+ - **Wakeups are polling-based.** `mu log --tail` polls every 1s.
477
+ Real subscriptions (SQLite update hooks) are deferred.
478
+ - **`--evidence` is grounding, not verification.** mu doesn't run the
479
+ tests. A future `--verify-by` mode that runs a command and records
480
+ its exit could deepen this; not built yet.
481
+ - **No idempotency keys on mutations.** Most ops are idempotent by
482
+ happenstance; not declared as part of the API contract.
483
+ - **No dry-run on most mutations.** `workstream destroy`, `task delete`, and `undo` have it; most other mutating verbs apply immediately.
484
+ - **No capability model.** The `role` field is stored on agent rows
485
+ but unused. No "reviewer-1 cannot delete tasks" enforcement.
486
+
487
+ Each is a known gap with a clear shape; none has earned promotion.