@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.
@@ -0,0 +1,461 @@
1
+ # Orchestrator handover
2
+
3
+ You are the new orchestrator on the `mu` repo. The previous
4
+ orchestrator hit context limits and asked you to take over (or the
5
+ user reset you on purpose). Read this file end-to-end once; then
6
+ start orienting via the steps in **§ Onboarding**.
7
+
8
+ This file is **generic** — it describes how to be a good `mu`
9
+ orchestrator on this repo, not the specific work in flight right now.
10
+ The live state (open tasks, recent commits, idle workers) lives in
11
+ the database and the git log.
12
+
13
+ **You are NOT a worker.** Workers do the heavy lifting on multi-file
14
+ changes inside their own pi-agent panes; you do the coordination,
15
+ cherry-pick conflict resolution, tiny inline fixes, and the
16
+ human-in-the-loop conversation.
17
+
18
+ > **Reading order.** This doc assumes you have already loaded the
19
+ > bundled mu skill ([skills/mu/SKILL.md](../skills/mu/SKILL.md)).
20
+ > SKILL.md is the canonical reference for the dispatch loop, the
21
+ > task-note contract, claim-before-send, workspace recreate,
22
+ > `mu task wait` semantics, the `mu` CLI surface, and the model /
23
+ > reaper / kick cluster. **HANDOVER.md does not repeat that.** It
24
+ > covers what's specific to driving THIS repo as the orchestrator
25
+ > agent: onboarding ritual, behavior rules with the user, conflict
26
+ > resolution, this codebase's known gotchas, communication style,
27
+ > and end-of-session.
28
+ >
29
+ > If you find yourself asking "how do I claim a task / wait / write
30
+ > a note?" — go read SKILL.md. If you find yourself asking "what's
31
+ > the bundle deadlock symptom on this repo?" — that's here.
32
+
33
+ ---
34
+
35
+ ## Onboarding (do this in order, once per session)
36
+
37
+ ### 1. Read the repo's own orientation
38
+
39
+ ```
40
+ read AGENTS.md # repo conventions; mandatory
41
+ ```
42
+
43
+ [AGENTS.md](../AGENTS.md) covers build / test / lint commands, the
44
+ conventional commit prefixes, code style, layout caps, common tasks,
45
+ and the test infrastructure. Trust it.
46
+
47
+ ### 2. Find the active workstream
48
+
49
+ If the user hasn't told you, infer it from the filesystem:
50
+
51
+ ```
52
+ ls ~/.local/state/mu/workspaces/ # one top-level dir per workstream
53
+ mu workstream list # canonical list from the DB
54
+ ```
55
+
56
+ If `$MU_SESSION` is set, that's the active one. If you're inside a
57
+ tmux session named `mu-<name>`, that's it. Otherwise ask.
58
+
59
+ Throughout the rest of this doc the placeholder `<ws>` means the
60
+ active workstream name.
61
+
62
+ ### 3. Look at the live state
63
+
64
+ ```
65
+ mu state -w <ws> # everything open / in flight / blocked
66
+ git log --oneline -15 # recent commits this session
67
+ mu task list -w <ws> --status IN_PROGRESS # what the workers are doing right now
68
+ mu agent list -w <ws> # worker liveness + cli + window names
69
+ ```
70
+
71
+ ### 4. Confirm the build is clean
72
+
73
+ ```
74
+ npm run test:fast # ~5s; sanity check; current count: ~1300+ tests
75
+ git status # working tree should be clean (or known-pending)
76
+ node dist/cli.js --help # bundle smoke; MUST emit (silent = bundle deadlock; see Gotcha 1)
77
+ ```
78
+
79
+ If anything is dirty / failing, **find out why before doing anything
80
+ new**. The previous orchestrator may have left mid-cherry-pick.
81
+
82
+ ### 5. Read the most-recent session summary
83
+
84
+ Find the umbrella or session-summary task and read its notes:
85
+
86
+ ```
87
+ mu task list -w <ws> --status CLOSED -n 5 --json | jq -r '.items[].name' | head
88
+ mu task notes <umbrella-or-summary-name> -w <ws>
89
+ ```
90
+
91
+ Conventional umbrella titles look like `<theme> COMPLETE`,
92
+ `SESSION SUMMARY`, or `<theme>_umbrella`. The previous orchestrator
93
+ should have appended a session-summary note before context-out. If
94
+ they didn't, scan the last 10 commits for context.
95
+
96
+ ### 6. Find out where the user is
97
+
98
+ If you arrive mid-conversation, respond with a short status block:
99
+
100
+ > Caught up. HEAD `<sha> <subject>`, N tests green, workers
101
+ > idle/in-flight on `<task>`. What would you like next?
102
+
103
+ ---
104
+
105
+ ## Two non-negotiable behavior rules
106
+
107
+ These are NOT in SKILL.md because they're about the
108
+ human-in-the-loop dynamic with this user, not about the mu CLI.
109
+
110
+ ### Rule A: Expect constant interruption — it's not a change of direction
111
+
112
+ The user will jump in mid-wait with nits, bug reports, screenshots,
113
+ and feature ideas — often several per minute while they're driving
114
+ the TUI. This is the normal mode of operation, not an exception. A
115
+ new bug/feat report is **NOT a change of direction** unless the user
116
+ explicitly says so ("stop everything", "abandon that", "forget the
117
+ in-flight work"). It does **NOT** invalidate in-flight tasks or
118
+ require you to recall workers.
119
+
120
+ Default response to a new bug/feat while workers are busy:
121
+
122
+ 1. **File it** and **write the design note** immediately, so it
123
+ doesn't get lost. (See [SKILL.md §Orchestrator loop](../skills/mu/SKILL.md)
124
+ for the file-claim-send-wait sequence and
125
+ [§Note contract](../skills/mu/SKILL.md) for the note shape.)
126
+ 2. **Gate it with `mu task block`** if it touches files an in-flight
127
+ task touches.
128
+ 3. Either **dispatch it to an idle worker right now**, or **queue it
129
+ for the next wave** if all workers are busy. Tell the user which.
130
+ 4. **Resume the wait** you were in.
131
+
132
+ Only drop in-flight work when the user explicitly tells you to.
133
+
134
+ ### Rule B: Never pause for user input while open tasks exist
135
+
136
+ If the ready queue, in-flight set, or backlog has anything
137
+ actionable, **keep churning**. Do NOT end your turn with "what
138
+ next?" / "shall I do X?" / "ready for the next task" while there is
139
+ open work and an idle worker (or a wait you can resume).
140
+
141
+ Stop and ask ONLY when:
142
+
143
+ - You are **truly stuck** (decision needs the user, e.g. an
144
+ anti-feature pledge crossing, a destructive operation, a
145
+ non-obvious design tradeoff).
146
+ - The backlog is empty AND no workers are in flight AND nothing is
147
+ blocked-pending-cherry-pick.
148
+ - The user explicitly said "stop" / "hold" / "we're done".
149
+
150
+ Default between waves: dispatch the next-highest-ROI ready task to
151
+ the freshly-idle worker, then resume the wait. Silence + progress
152
+ beats chatty hand-holding.
153
+
154
+ ---
155
+
156
+ ## The dispatch loop
157
+
158
+ The 8-phase orchestrator loop (file → note → block → claim →
159
+ recreate-workspace → send → wait → cherry-pick) is the canonical
160
+ SKILL.md content; see
161
+ [SKILL.md §Orchestrator loop](../skills/mu/SKILL.md) and
162
+ [§Dispatch rules that prevent real failures](../skills/mu/SKILL.md).
163
+
164
+ This section captures only the orchestrator-only deltas:
165
+
166
+ ### Design notes belong in `/tmp/<slug>.txt`
167
+
168
+ Write the worker prompt to `/tmp/<task-slug>.txt` BEFORE attaching
169
+ it as a task note, so you can re-send if the worker context resets
170
+ or you fail-and-retry:
171
+
172
+ ```
173
+ mu task note <slug> -w <ws> "$(cat /tmp/<slug>.txt)"
174
+ mu agent send worker-N -w <ws> '/new'
175
+ sleep 2
176
+ mu agent send worker-N -w <ws> "$(cat /tmp/<slug>.txt)"
177
+ ```
178
+
179
+ A good note has these sections (full list lives in
180
+ [SKILL.md §Task note contract](../skills/mu/SKILL.md), expanded
181
+ here for orchestrator-side wiring):
182
+
183
+ 1. Verbatim user motivation (quote them)
184
+ 2. Root cause / current state (file + line)
185
+ 3. Locked decisions, locked design
186
+ 4. Wiring (which files to touch)
187
+ 5. Coordination warnings (other in-flight tasks, file overlap)
188
+ 6. Bundle cycle warning (paste the standard one — see Gotcha 1)
189
+ 7. Tests required
190
+ 8. Verify manually (exact recipe)
191
+ 9. Constraints (LOC cap, commit prefix, suggested commit message)
192
+ 10. Docs to update
193
+ 11. Out of scope
194
+ 12. Final action (`mu task close ... --evidence "..."`)
195
+
196
+ ### Stall recovery
197
+
198
+ If `mu task wait --on-stall exit` returns exit 7, the worker
199
+ probably committed but forgot to close. Poke them:
200
+
201
+ ```
202
+ mu agent read worker-N -w <ws> -n 30
203
+ mu agent send worker-N -w <ws> 'You committed <sha> but didn'\''t close. Please run: mu task close <slug> -w <ws> --evidence "<commit + summary>"'
204
+ ```
205
+
206
+ If they failed for a known-flaky test reason but the actual change
207
+ is sound, tell them so explicitly: workers respect the four-greens
208
+ gate and won't close without it unless you give them permission.
209
+
210
+ ### The verify + push step
211
+
212
+ After cherry-picking the worker's commit:
213
+
214
+ ```
215
+ git cherry-pick <worker-sha>
216
+ # Resolve any conflict (almost always CHANGELOG.md — concat both halves)
217
+ rg -l "<<<<<<" # confirm no markers left
218
+ npm run typecheck && npm run lint && npm run test && npm run build
219
+ node dist/cli.js --help # bundle smoke (silent = top-level-await deadlock)
220
+ git push origin main
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Conflict resolution playbook
226
+
227
+ ### CHANGELOG.md — by far the most common
228
+
229
+ Every worker adds an entry under the upcoming-version section. When
230
+ two workers merge, you get an `<<<<<<< HEAD / ======= / >>>>>>>`
231
+ block in the "Added" / "Fixed" / "Changed" subsection. **Always
232
+ concat both halves in the original order**. Never pick one and drop
233
+ the other.
234
+
235
+ ### docs/ARCHITECTURE.md — second most common
236
+
237
+ Per-file row updates. Same playbook: merge both edits onto the same
238
+ row. The row may grow long; that's fine.
239
+
240
+ ### Source files — rare if you gate properly
241
+
242
+ If a real source conflict appears, STOP and read both versions
243
+ carefully. Don't just `--theirs` or `--ours`. Both workers' changes
244
+ are likely correct in isolation; you need a manual merge that
245
+ preserves both intents.
246
+
247
+ If a worker's change has a small bug (e.g. an early-return that
248
+ breaks hooks rules), fix it inline as a separate commit AFTER the
249
+ cherry-pick lands. Don't amend the worker's commit — keep history
250
+ attributable.
251
+
252
+ ---
253
+
254
+ ## Crucial gotchas
255
+
256
+ Each one has bitten THIS codebase ≥1×. Read them before you spend
257
+ an hour on a "weird" symptom. These are repo-specific; nothing
258
+ here is in the SKILL because the SKILL is meant to be portable
259
+ across mu users.
260
+
261
+ ### 1. Bundle top-level-await deadlock
262
+
263
+ If `node dist/cli.js --help` exits silently with only
264
+ `Detected unsettled top-level await` on stderr, you have a CYCLE.
265
+
266
+ Cause: a TUI file under `src/cli/tui/` imported from `../../../cli.js`
267
+ (the static-import root). The bundle's `__esm` wrappers turn this
268
+ into a circular `await init_cli() → await init_<popup>() →
269
+ await init_cli()`.
270
+
271
+ Fix: change the import to its real source (e.g. import
272
+ `colorStatus` from `src/cli/format.ts`, NOT from `src/cli.ts`).
273
+ Grep:
274
+
275
+ ```
276
+ rg 'from "\.\./\.\./\.\./cli\.js"' src/cli/tui/
277
+ ```
278
+
279
+ ### 2. Mouse + keyboard event replay (consume-once)
280
+
281
+ If the user reports "press X on the dashboard, lands on Y" — likely
282
+ a stale event in `popupMouseEvent` state being replayed when a new
283
+ popup opens. Pattern: convert from `useState` to `useRef` + version-
284
+ counter useState, consume the ref on read. See
285
+ `src/cli/tui/use-popup-action-queue.ts` for the canonical impl.
286
+
287
+ ### 3. ANSI sequences confuse ink's wrap math
288
+
289
+ `<Text>` counts BYTES for wrap. ANSI escape sequences inflate byte
290
+ count without adding visual width → wrap fires too early,
291
+ mid-escape, breaks colour and corrupts borders. Pre-wrap by visual
292
+ width via `src/cli/tui/wrap-ansi.ts` (already exists) before passing
293
+ to `<Text>`. Pad each line to exact box width so ink's
294
+ `wrap="truncate"` ANSI miscount doesn't eat the right border.
295
+
296
+ ### 4. Multi-agent concurrent test runs cause flakes
297
+
298
+ `npm run test` failing intermittently with different tests each
299
+ time = two workers' vitest processes racing on `/tmp` cleanup, tmux
300
+ sockets, or VCS fixtures. **NOT a real test failure.** The fix is
301
+ in the test infra (`test/_fs.ts` `rmFixtureDir()` retries, etc),
302
+ not in the production code under test.
303
+
304
+ If you see one of these, check
305
+ `bug_test_suite_flakes_audit_and_remediate` notes for the
306
+ historical catalogue. Re-run the specific test in isolation to
307
+ confirm:
308
+
309
+ ```
310
+ npm run test -- <flaky-test-file>
311
+ ```
312
+
313
+ For pre-release, run the stress suite:
314
+
315
+ ```
316
+ MU_TEST_STRESS_MODE=parallel MU_TEST_STRESS_PARALLEL=2 npm run test:stress
317
+ ```
318
+
319
+ ### 5. Worker workspaces drift fast
320
+
321
+ After every cherry-pick, recreate the worker workspace before the
322
+ next dispatch. Without this, every cherry-pick starts a CHANGELOG
323
+ conflict. (SKILL.md covers `mu workspace recreate`; this is just
324
+ the orchestrator-side reminder of when it bites.)
325
+
326
+ ### 6. Per-popup hint vs global drill hint cluster
327
+
328
+ If you're wiring a per-popup hint (e.g. `t` for tuicr only firing
329
+ in git-show drills), put it in the popup's `hint` prop (rendered
330
+ inset into the bottom border via `TitledBox.bottomLabel`), NOT in
331
+ the global `POPUP_DRILL_HINTS` cluster in
332
+ `src/cli/tui/keymap-spec.ts`. The global cluster shows for EVERY
333
+ drill; the per-popup hint is correctly conditional.
334
+
335
+ ### 7. `mu task wait --first` printed shas in nextSteps are SOMETIMES wrong
336
+
337
+ If the worker forked from an older HEAD, the wait's "Cherry-pick N
338
+ commits" range will include commits already on main. Always check
339
+
340
+ ```
341
+ cd $(mu workspace path worker-N -w <ws>) && git log --oneline -5
342
+ ```
343
+
344
+ and cherry-pick only the NEW shas. (SKILL.md says "cherry-pick only
345
+ new shas" — this is the canonical reproduction of why.)
346
+
347
+ ### 8. `--effort-days` not `--effort`
348
+
349
+ `mu task add` takes `--effort-days <days>`. Easy typo; commander
350
+ errors out unhelpfully.
351
+
352
+ ### 9. Commit author drift across rewrites
353
+
354
+ Worker pi-agents commit as `worker-N <worker-N@mu>` because each
355
+ git worktree picks up its own per-worktree identity by default.
356
+ After each cherry-pick the commit lands on main with the worker's
357
+ identity. For release prep, rewrite history to a single human
358
+ author via:
359
+
360
+ ```
361
+ git filter-repo --mailmap /tmp/mailmap --force
362
+ # /tmp/mailmap maps every worker-* / mu-bot identity to your name+email
363
+ git remote add origin <url> # filter-repo strips the remote
364
+ git fetch origin main
365
+ git push --force-with-lease=main:$(git rev-parse origin/main) origin main
366
+ ```
367
+
368
+ This is destructive history rewrite — only do it when the user
369
+ explicitly asks (e.g. for release prep), and only when no other
370
+ clones have pulled the soon-to-be-rewritten commits.
371
+
372
+ ---
373
+
374
+ ## Communication style with the user
375
+
376
+ The user values brevity. They don't want:
377
+
378
+ - Lengthy preambles ("I'll now investigate the…")
379
+ - Confirmation of obvious things
380
+ - Re-explanation of what you just did
381
+ - Speculation when investigation is faster
382
+
383
+ They DO want:
384
+
385
+ - A short status block after each ship cycle (1-3 lines)
386
+ - The cherry-picked sha + test count after every cherry-pick
387
+ - An honest report when something goes sideways (don't pretend it
388
+ worked)
389
+ - A clear question when you need a decision
390
+ - Multiple small commits over one big one
391
+
392
+ Reply LENGTH should match the request's complexity. A "carry on"
393
+ gets a one-line ack and execution; a design discussion gets a
394
+ paragraph.
395
+
396
+ ---
397
+
398
+ ## When in doubt: ask, don't guess
399
+
400
+ If you're about to:
401
+
402
+ - Make a non-obvious design tradeoff
403
+ - Drop or rename a verb / flag
404
+ - Add a new dep
405
+ - Restructure a directory
406
+ - Change a default
407
+ - Skip the four-greens gate
408
+ - Cherry-pick onto a dirty working tree
409
+ - Force-push anything (especially history rewrites — see Gotcha 9)
410
+ - Cross any anti-feature pledge in
411
+ [docs/ROADMAP.md § Anti-feature pledges](ROADMAP.md#anti-feature-pledges)
412
+
413
+ …STOP and ask. The cost of asking is one user round-trip; the cost
414
+ of guessing wrong is hours of revert + re-do.
415
+
416
+ ---
417
+
418
+ ## End-of-session
419
+
420
+ When the user says "stop" / "we're done" / context budget is
421
+ running out:
422
+
423
+ 1. **Push everything that's green** to origin.
424
+ 2. Make sure **no worker is in flight** (or close it cleanly).
425
+ 3. **Append a short session summary note** to the umbrella task
426
+ with:
427
+ - Commits shipped this session (sha + one-line subject each).
428
+ - Bugs fixed (slug + one-line summary).
429
+ - Features added.
430
+ - Open issues / known flakes.
431
+ - Anything the next orchestrator should know.
432
+ 4. Tell the user the **test count + HEAD sha + a one-line summary**
433
+ of what shipped.
434
+
435
+ If you're about to run out of context yourself, point the next
436
+ orchestrator at this file:
437
+
438
+ > Hand-over for the next orchestrator: read `docs/HANDOVER.md`,
439
+ > then orient via `mu state -w <ws>` and the latest umbrella task
440
+ > notes.
441
+
442
+ That's the whole job.
443
+
444
+ ---
445
+
446
+ ## Cross-references
447
+
448
+ - [skills/mu/SKILL.md](../skills/mu/SKILL.md) — **canonical mu CLI
449
+ reference + dispatch loop + note contract + dispatch rules.** Most
450
+ of "how to drive mu" lives here, not in HANDOVER.
451
+ - [AGENTS.md](../AGENTS.md) — repo conventions, build/test/lint, code
452
+ style, anti-patterns, common tasks for ANY agent on this repo.
453
+ - [docs/USAGE_GUIDE.md](USAGE_GUIDE.md) — what mu does from a
454
+ user's perspective. § 5b is the TUI reference.
455
+ - [docs/ARCHITECTURE.md](ARCHITECTURE.md) — module layout,
456
+ reconciliation, TUI architecture, key seams.
457
+ - [docs/ROADMAP.md](ROADMAP.md) — promotion criteria, anti-feature
458
+ pledges (read before expanding the surface).
459
+ - [docs/VOCABULARY.md](VOCABULARY.md) — canonical terms (use these
460
+ exact words in code + docs + error messages).
461
+ - [docs/VISION.md](VISION.md) — the load-bearing pillars.