@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.
Files changed (71) hide show
  1. package/AGENTS.md +208 -599
  2. package/README.md +125 -329
  3. package/dist/cli.js +108 -78
  4. package/dist/cli.js.map +1 -1
  5. package/dist/extension/mu-pi.js +421 -56
  6. package/dist/extension/mu-pi.js.map +1 -1
  7. package/dist/index.d.ts +36 -10
  8. package/dist/index.js +89 -67
  9. package/dist/index.js.map +1 -1
  10. package/docs/ARCHITECTURE.md +176 -1072
  11. package/docs/ROADMAP.md +88 -169
  12. package/docs/VISION.md +205 -415
  13. package/docs/VOCABULARY.md +204 -466
  14. package/docs/architecture/control-socket.md +133 -0
  15. package/docs/architecture/dag.md +113 -0
  16. package/docs/architecture/mux.md +162 -0
  17. package/docs/architecture/ops-log.md +140 -0
  18. package/docs/architecture/sdk.md +185 -0
  19. package/docs/architecture/sync.md +129 -0
  20. package/docs/architecture/tui.md +146 -0
  21. package/docs/guide/README.md +30 -0
  22. package/docs/guide/backends.md +61 -0
  23. package/docs/guide/cleanup.md +74 -0
  24. package/docs/guide/delegate.md +87 -0
  25. package/docs/guide/dispatch.md +144 -0
  26. package/docs/guide/getting-started.md +180 -0
  27. package/docs/guide/recovery.md +135 -0
  28. package/docs/guide/remote.md +74 -0
  29. package/docs/guide/sql.md +76 -0
  30. package/docs/guide/stop-a-worker.md +64 -0
  31. package/docs/guide/sync.md +78 -0
  32. package/docs/guide/tui.md +98 -0
  33. package/docs/guide/upgrade.md +76 -0
  34. package/docs/history/CHANGELOG-pre-3.md +4866 -0
  35. package/docs/reference/env.md +87 -0
  36. package/docs/reference/naming.md +82 -0
  37. package/docs/specs/2026-09-28-agent-state-from-murmur.md +1 -1
  38. package/docs/specs/2026-09-29-task-substates.md +1 -1
  39. package/docs/specs/2026-10-03-keep-driving-nudge.md +142 -0
  40. package/package.json +2 -1
  41. package/prompts/mu-refute.md +8 -0
  42. package/prompts/mu-research.md +8 -0
  43. package/prompts/mu-review.md +8 -0
  44. package/prompts/mu-rules-audit.md +8 -0
  45. package/prompts/mu-tournament.md +9 -0
  46. package/prompts/ultrathink.md +9 -0
  47. package/skills/mu/SKILL.md +126 -255
  48. package/skills/mu/recipes/adversarial-review.md +83 -0
  49. package/skills/mu/recipes/brief.md +53 -0
  50. package/skills/mu/recipes/codemode-driver.md +54 -0
  51. package/skills/mu/recipes/deep-research.md +52 -0
  52. package/skills/mu/recipes/fan-out.md +36 -0
  53. package/skills/mu/recipes/hypothesis-panel.md +40 -0
  54. package/skills/mu/recipes/long-run.md +20 -0
  55. package/skills/mu/recipes/loop-until-done.md +38 -0
  56. package/skills/mu/recipes/orchestrator-loop.md +87 -0
  57. package/skills/mu/recipes/plan.md +54 -0
  58. package/skills/mu/recipes/recovery.md +26 -0
  59. package/skills/mu/recipes/refute.md +49 -0
  60. package/skills/mu/recipes/remote-workers.md +292 -0
  61. package/skills/mu/recipes/review-panel.md +57 -0
  62. package/skills/mu/recipes/rules-audit.md +70 -0
  63. package/skills/mu/recipes/tournament.md +37 -0
  64. package/skills/mu/recipes/triage.md +38 -0
  65. package/skills/mu/recipes/ultrathink.md +73 -0
  66. package/skills/mu/recipes/watcher.md +16 -0
  67. package/skills/mu/recipes/waves.md +19 -0
  68. package/skills/mu/recipes/worker.md +24 -0
  69. package/docs/HANDOVER.md +0 -486
  70. package/docs/USAGE_GUIDE.md +0 -2738
  71. package/skills/mu/REMOTE_WORKERS.md +0 -617
@@ -0,0 +1,54 @@
1
+ # Codemode driver
2
+
3
+ Use when a pi orchestrator with the `codemode` tool runs a recipe with
4
+ many parallel units, and one tool call per spawn, send, and wait is
5
+ slow. A script can issue those calls in parallel. It stays a driver:
6
+ the plan, the state, and the results live in the DB.
7
+
8
+ ## The rule
9
+
10
+ **Delete the script mid-run and nothing is lost.** That holds when:
11
+
12
+ - The script calls only `mu` verbs, through `tools.bash`. It reads
13
+ state with `mu state --json` / `mu task notes`, never from its own
14
+ variables across calls.
15
+ - Every task it dispatches exists in the DAG before the script starts.
16
+ The script adds no tasks the orchestrator has not planned, except the
17
+ ones a recipe step names (the next round, a `fix_` task).
18
+ - `store()` / `load()` hold nothing a re-run needs. The DAG is the
19
+ cursor.
20
+ - The script's source goes into the log before it runs:
21
+ `mu log -w <ws> --kind driver '<what it does, which tasks>'`.
22
+
23
+ ## Shape
24
+
25
+ ```js
26
+ // @options: {"timeout_ms": 1800000}
27
+ const ws = "audit";
28
+ const sh = async (c) => {
29
+ const r = await tools.bash({ command: c });
30
+ if (r.exit_code !== 0) throw new Error(`${c}: ${r.output}`);
31
+ return r.output;
32
+ };
33
+ const ready = JSON.parse(await sh(`mu task next -w ${ws} -n 0 --json`)).items;
34
+ await Promise.allSettled(ready.slice(0, 4).map(async (t, i) => {
35
+ const w = `worker-${i + 1}`;
36
+ await sh(`mu task claim ${t.name} -w ${ws} --for ${w} --evidence 'driver dispatch'`);
37
+ await sh(`mu agent send ${w} -w ${ws} --fresh 'Work on ${t.name}. Read: mu task notes ${t.name} -w ${ws}'`);
38
+ }));
39
+ const wait = await tools.bash({ command: `mu task wait -w ${ws} ${ready.slice(0, 4).map((t) => t.name).join(" ")} --first --on-stall exit --json` });
40
+ return wait.output;
41
+ ```
42
+
43
+ Check field names against `--json` output before relying on them; the
44
+ script above is a shape, not an API.
45
+
46
+ ## Traps
47
+
48
+ - **One wave per script.** A script that loops forever hides progress
49
+ from you and from the human. Dispatch, wait for the first close,
50
+ return; merge and verify outside the script, then run it again.
51
+ - **A script timeout cancels the waits, not the workers.** Workers keep
52
+ running and their tasks stay claimed. Re-read `mu state` and carry on.
53
+ - **Exit codes are data.** `mu task wait` exit 7 means a worker needs
54
+ you; return it to the model instead of retrying.
@@ -0,0 +1,52 @@
1
+ # Deep research
2
+
3
+ Use when a question needs more sources than one context can read and
4
+ checking them against each other: how a library or protocol behaves,
5
+ what changed between versions, how competitors solve a problem, whether
6
+ a claim in a draft holds. This is [refute](refute.md) applied to
7
+ sources. Workers need a web search tool (pi's `brave_search`, or
8
+ `curl` on docs) or the code they research.
9
+
10
+ ## Steps
11
+
12
+ 1. **Write the question and the bar** on an umbrella task: the exact
13
+ question, what a good answer contains (a recommendation, a
14
+ comparison table, a yes/no with conditions), and how fresh sources
15
+ must be.
16
+ 2. **Split by angle**, one search task per angle: official docs,
17
+ changelogs and release notes, issue trackers, independent write-ups,
18
+ the code itself. Each searcher reads, fetches, and writes claims to
19
+ its note, one per line:
20
+
21
+ ```text
22
+ CLAIM: c4 "Node 22 enables the permission model by default" SOURCE: <url> QUOTE: "<exact words>"
23
+ ```
24
+
25
+ A claim without a source and a quote is not a claim. Searchers can
26
+ run on a cheap model.
27
+ 3. **Dedupe claims** in one task: merge the same fact from several
28
+ sources (keep every source), and flag claims that contradict each
29
+ other.
30
+ 4. **One check task per claim** that the answer depends on. The checker
31
+ gets the claim and its sources, not the searcher's reasoning, fetches
32
+ the source itself, and tries to break the claim: is the quote there,
33
+ does it say that, is it current, does another source disagree? It
34
+ ends with `VERDICT: c4 CONFIRMED | REFUTED | UNVERIFIED <evidence>`.
35
+ For contradicted claims, one checker per side.
36
+ 5. **Synthesize** in a task blocked by every check: answer the question
37
+ from confirmed claims only, each with its source URL. List
38
+ unverified claims separately. Note what the sources disagree on and
39
+ which side the evidence favours.
40
+
41
+ Done when every claim the answer uses has a `CONFIRMED` verdict line,
42
+ every sentence of fact in the report cites a URL, and the report meets
43
+ the bar from step 1.
44
+
45
+ ## Traps
46
+
47
+ - **A fetch failure is UNVERIFIED, not REFUTED.** Rate limits and
48
+ paywalls block checkers; say so, do not drop the claim silently.
49
+ - **Secondary sources copy each other.** Three blog posts repeating one
50
+ changelog are one source. Prefer the primary source in the dedupe.
51
+ - **Version drift.** A claim true for v2 can be false for v3. Checkers
52
+ confirm the version the question asks about.
@@ -0,0 +1,36 @@
1
+ # Fan-out
2
+
3
+ Use when the same treatment applies to many units: files, call sites,
4
+ failing tests, findings, modules. One context holding 50 units drops
5
+ some and calls the job done; one task per unit cannot.
6
+
7
+ ## Steps
8
+
9
+ 1. **Enumerate first, as its own task.** A scout lists the units and
10
+ writes them to the umbrella's note, one per line. The list is done
11
+ when it matches a command the scout ran (`rg -l`, a test listing),
12
+ not when it looks complete. Record the command and the count.
13
+ 2. **One task per unit**, blocked into an umbrella:
14
+
15
+ ```bash
16
+ mu task add sweep -w <ws> -t "Sweep: <goal>" -i 60 -e 1 --note 'UNITS: 37 (rg -l ... | wc -l)'
17
+ mu task add sweep_auth_ts -w <ws> -t "Sweep src/auth.ts" -i 50 -e 0.2
18
+ mu task block sweep -w <ws> --by sweep_auth_ts
19
+ ```
20
+
21
+ Put the shared brief and acceptance criteria on the umbrella; each
22
+ unit task's note holds only what differs.
23
+ 3. **Cap concurrency.** Spawn at most one agent per ready track, and no
24
+ more than the machine can build and test at once. Tell workers to
25
+ avoid repo-wide commands so more can run.
26
+ 4. **Pipeline.** Dispatch, wait `--first`, merge, dispatch the next unit
27
+ to the freed worker with `--fresh`. Units that touch the same files
28
+ go on one track (see [waves](waves.md)).
29
+ 5. **Review per unit** when a wrong unit is costly: add a review task
30
+ per unit ([adversarial-review](adversarial-review.md)).
31
+ 6. **Synthesize** when the output is a report, not commits: a final
32
+ task blocked by every unit reads their notes and writes one result.
33
+ It reads notes, not transcripts.
34
+
35
+ Done when `mu task close sweep --if-ready` closes the umbrella: every
36
+ unit is closed, and the closed count matches the step 1 count.
@@ -0,0 +1,40 @@
1
+ # Hypothesis panel
2
+
3
+ Use for root-cause work: a flaky test, an intermittent bug, a metric
4
+ that moved. One agent that forms a theory then tests its own theory
5
+ finds evidence for it. Separate agents, each given different evidence,
6
+ form independent theories; separate agents then try to kill them.
7
+
8
+ ## Steps
9
+
10
+ 1. **Write the symptom** on the umbrella: what happens, how often, the
11
+ repro command, and what would count as fixed.
12
+ 2. **One hypothesis task per evidence source**: logs, the code path,
13
+ recent commits, data, environment. Each agent sees only its source,
14
+ so the theories do not anchor on each other. Each ends with:
15
+
16
+ ```text
17
+ HYPOTHESIS: h2 <cause>
18
+ PREDICTS: <an observation that is true if h2 is the cause, false otherwise>
19
+ ```
20
+
21
+ 3. **One test task per hypothesis**, in its own workspace. The tester
22
+ builds the experiment that would kill the hypothesis (force the race,
23
+ revert the commit, feed the data) and reports
24
+ `VERDICT: h2 SURVIVES | KILLED <evidence>`.
25
+ 4. **If one survives**, add a fix task for it, then a review task
26
+ ([adversarial-review](adversarial-review.md)). The fix is accepted
27
+ only if the step 1 repro stops reproducing.
28
+ 5. **If none survives**, start another round
29
+ ([loop-until-done](loop-until-done.md)): the new hypothesis tasks get
30
+ the killed hypotheses and their evidence as input.
31
+
32
+ Done when a fix closed `ACCEPT` and the repro from step 1 no longer
33
+ reproduces at the rate step 1 recorded.
34
+
35
+ ## Traps
36
+
37
+ - **Two survivors** usually means the experiments were too weak. Design
38
+ one experiment that separates them before you fix either.
39
+ - **Flaky repros need counts.** "Passed once" proves nothing for a 1 in
40
+ 50 failure. Put the run count in step 1.
@@ -0,0 +1,20 @@
1
+ # Long runs
2
+
3
+ Use when a task or proof runs for hours, crosses context compaction,
4
+ or may hit flakes.
5
+
6
+ 1. **Fix done first.** Before dispatch, write the completion criterion
7
+ into the task note: the checks, how many runs must agree, the
8
+ allowed variance. A worker that finds the bar in the note stops at
9
+ the bar, not at the first green.
10
+ 2. **Split into independent units.** Shard a long proof into tasks
11
+ that run in parallel, so one flake restarts only its unit. Each unit
12
+ carries its own criterion.
13
+ 3. **Keep state in the DB.** Progress lives in task notes, not in the
14
+ orchestrator's context. After a compaction, `mu state` and
15
+ `mu task notes <id>` are the whole picture.
16
+ 4. **Accept evidence, not close notes.** Re-run the key measurement
17
+ from a clean checkout before you count a unit as done.
18
+
19
+ Done when every unit is `CLOSED/done` and the criterion from step 1
20
+ holds on the merged tree.
@@ -0,0 +1,38 @@
1
+ # Loop until done
2
+
3
+ Use when the amount of work is unknown: fix type errors until clean,
4
+ find flaky tests until none are new, search until nothing new turns up.
5
+ A fixed number of passes stops too early or runs too long; a stop rule
6
+ written down first does neither.
7
+
8
+ ## Steps
9
+
10
+ 1. **Write the stop rule** on the umbrella before the first round. It
11
+ names a command and a condition, plus a no-progress rule:
12
+
13
+ ```text
14
+ STOP: `npx tsc --noEmit` exits 0
15
+ NO-PROGRESS: two rounds in a row reduce the error count by zero
16
+ ```
17
+
18
+ 2. **Each round is a task**, blocked by the previous one:
19
+ `round_1`, `round_2`, .... Add the next round only when the current
20
+ one closes; never pre-create rounds.
21
+ 3. **Each round ends with its measurement** in the note:
22
+ `MEASURE: 14 errors (was 31)`, or `NEW: 0 flaky tests`.
23
+ 4. **After each round, check the rule** yourself, from the measurement
24
+ command, not from the worker's note.
25
+ - Rule met: close the umbrella.
26
+ - No progress: stop the loop and decide. Change the approach, split
27
+ the work, or park the umbrella with
28
+ `mu task park <umbrella> --why '<what is stuck>'` and tell the human.
29
+ - Otherwise: add the next round and dispatch it.
30
+
31
+ Done when the stop rule holds on the merged tree, run by you.
32
+
33
+ ## Traps
34
+
35
+ - **A round that only reports is not progress.** Each round must change
36
+ something (fix, new search slice) or produce a new measurement.
37
+ - **Moving goalposts.** Edit the stop rule only with a note saying why;
38
+ the old rule stays in the history.
@@ -0,0 +1,87 @@
1
+ # Orchestrator loop
2
+
3
+ Use when you run a workstream: you dispatch DAG tasks to workers and
4
+ merge their commits. The hard rules in SKILL.md still apply; this is
5
+ the loop and the reasons behind them.
6
+
7
+ ## Every turn
8
+
9
+ 1. `mu state -w <ws>` — read agents, IN_PROGRESS, ready tasks,
10
+ parallel tracks.
11
+ 2. Spawn at most one agent per independent ready track.
12
+ 3. **Claim before sending — even one-shot reviewers/scouts.**
13
+ `mu task claim <id> -w <ws> --for <agent> --evidence "..."`.
14
+ If no task exists, `mu task add` first (`--note 'REPRO: ...'` when
15
+ the title is not enough). Ownership is durable and waitable; agent
16
+ state is not.
17
+ 4. Send each new task with `mu agent send <w> --fresh '...'` (new
18
+ session + prompt in one step; refuses while busy): task id,
19
+ files/notes to read, workspace path, validation command, scope
20
+ guards, task note contract. Follow the `Next:` block; it picks
21
+ `--fresh` vs `--steer` for you.
22
+ 5. End with a loud final-action block:
23
+
24
+ ```text
25
+ ⚠️ FINAL ACTION
26
+ git commit -am '...' THEN
27
+ mu task close <id> -w <ws> --evidence '...'
28
+ ```
29
+
30
+ 6. `mu task wait ... --first --on-stall exit --json`.
31
+ 7. Cherry-pick the closed worker's **new** commit(s), verify the MERGE,
32
+ then continue the loop in the same turn. Do not barrier or loop in
33
+ shell.
34
+ Only `CLOSED/done` ships; other closes: read the reason note.
35
+ 8. Repeat from `mu state`.
36
+
37
+ ## Waiting
38
+
39
+ Use `--first --on-stall exit`: `--first` populates `.firing`, and
40
+ `--on-stall exit` stops an unattended wait when a worker needs attention.
41
+ Exit 6 is a dead pane; exit 7 is an owner in `needs_input`. Read that
42
+ pane (`mu agent read <owner>`) and answer: the worker may be waiting on
43
+ you. Questions are cheaper than rework.
44
+
45
+ For an idle worker, read the pane, then answer, retry, or release its
46
+ task. `MU_IDLE_THRESHOLD_MS` defaults to 5m.
47
+
48
+ ## Merging
49
+
50
+ - **Pipeline; don't barrier.** Wait for one task, cherry-pick only its
51
+ new commits, verify, dispatch the next. An umbrella wait hides progress;
52
+ merging stale branches can restore reverted code.
53
+ - **Verify the merge, not the worker's rerun.** Only the combination
54
+ with moved main is new; that found three breaks rerunning found none
55
+ of. Remote hosts: [run the merged gate there](remote-workers.md#run-the-merged-gate-on-the-host).
56
+ - **Push only from a green gate.** Make `git push` the last line under
57
+ `set -e`. Check the gate runs what it claims: an env-gated randomized
58
+ test once passed with zero cases.
59
+ - **Accept evidence, not close notes.** Re-run the key measurement from
60
+ a clean checkout; close notes have claimed unpushed commits. A
61
+ worker's "done" counts only once the diff shows the change.
62
+ - **Ask whether the check could have failed.** A gate that cannot say
63
+ no is not evidence: a test filtered to zero cases, a script you wrote
64
+ agreeing with itself, a fixture you tuned on. A nonzero diff is a
65
+ failure even when the command exited 0.
66
+ - **Dispatch from current main.** Reset the worker's worktree to main
67
+ before each task.
68
+
69
+ ## Sending
70
+
71
+ - A plain `mu agent send` appends to prior context; use it to steer or
72
+ answer. Unrelated work to pi: `mu agent send worker-1 --fresh 'Claim
73
+ task_x...'`.
74
+ - claude-code/codex: send `/new` (codex: `/clear`), then the prompt; a
75
+ send it cannot confirm prints a `warning:` on stderr. For pi,
76
+ `--fresh` does both in one step.
77
+ - Use `mu agent send`, not raw mux input. Single-quote prompts
78
+ containing shell expansions, or use a quoted heredoc.
79
+ - Cross-workstream wait and claim use qualified refs; only task
80
+ ownership crosses.
81
+
82
+ ## Stopping a worker
83
+
84
+ `mu agent abort <w>` first for pi (exact, local or remote, keeps
85
+ context, waits for idle; exit 5 = still busy; queued follow-ups return
86
+ to the editor unsent). Then `mu agent kick` (pi unresponsive, or
87
+ non-pi; local panes only), then `mu agent close`.
@@ -0,0 +1,54 @@
1
+ # Planning a DAG
2
+
3
+ Use when you turn a spec or a clear set of requirements into tasks.
4
+ The DAG is the plan: each task's note carries its full content, and
5
+ `mu state` is the progress tracker. Write a markdown plan only when the
6
+ human asks for a file.
7
+
8
+ ## Steps
9
+
10
+ 1. **Map the files first.** List what gets created or changed and what
11
+ each file is responsible for. Task boundaries fall out of this map.
12
+ 2. **Size the tasks.** A task is the smallest unit that carries its own
13
+ verification and is worth a review. Split only where a reviewer
14
+ could reject one task and accept its neighbour. Fold setup, config,
15
+ and docs into the task whose deliverable needs them.
16
+ 3. **Write the root task.** `task_0` holds the goal, the architecture
17
+ in two or three sentences, and the global constraints copied
18
+ verbatim from the spec. Every other task is blocked by it; close it
19
+ at once. It carries notes, not work.
20
+ 4. **Write each task's note** as a [brief](brief.md):
21
+
22
+ ```text
23
+ FILES: Create/Modify/Test with exact paths (line ranges if known)
24
+ INTERFACES: Consumes: <exact signatures from earlier tasks>
25
+ Produces: <exact names and types later tasks use>
26
+ STEPS: one action each; code steps carry the code
27
+ VERIFY: <exact command and expected result>
28
+ ```
29
+
30
+ The worker sees only its own task. INTERFACES is how it learns the
31
+ names its neighbours use.
32
+ 5. **No placeholders.** "TBD", "add error handling", "similar to
33
+ task 3", "write tests for the above": each is a missing decision the
34
+ worker will make alone. Write the actual content; tasks are read out
35
+ of order.
36
+ 6. **Add edges for dependencies only.** `mu task block A --by B` when A
37
+ consumes what B produces. Plan order is not a dependency: an extra
38
+ edge serialises tracks that could run in parallel.
39
+ 7. **Self-review before dispatch.** Walk each spec requirement and name
40
+ the task that implements it. Grep the notes for placeholders. Check
41
+ that names in INTERFACES match across tasks. Then read the graph back
42
+ with `mu task tree task_0 -w <ws> --down`, or `mu state -w <ws>` for the tracks.
43
+
44
+ Done when every spec requirement maps to a task, no note holds a
45
+ placeholder, and `mu state` shows the intended parallel tracks.
46
+
47
+ ## Notes
48
+
49
+ - `impact` comes from what breaks without the task; `effort_days` from
50
+ its step count. Guess honestly rather than defaulting to 50 and 1.
51
+ - Review gates follow [adversarial-review](adversarial-review.md): a
52
+ review task blocked by the work.
53
+ - When reality disagrees with the plan, append a note saying so. Do not
54
+ rewrite earlier notes.
@@ -0,0 +1,26 @@
1
+ # Recovery: undo, rebuild, sync
2
+
3
+ Use before you undo a change, rebuild the DB, tear down a workstream,
4
+ set up sync, or act on `mu doctor` output. Each of these can lose work
5
+ when done in the wrong order.
6
+
7
+ - **`workstream teardown`** is dry-run without `--yes`. It writes
8
+ TOMBSTONE ops, so `mu undo <group> --yes` reverses it; the log is the
9
+ backup. `workstream list --torn-down` lists group ids to undo.
10
+ - **`mu undo`** bare lists groups; `<group>` previews; `<group> --yes`
11
+ emits inverse ops for that group only (redo = undo the undo). Exit 4
12
+ if a later action changed the same fields (`--force` discards it).
13
+ Rows only: killed panes and freed workspace dirs do not come back.
14
+ - **`mu rebuild <file>`** writes a new DB from the ops log, without
15
+ agents or workspaces; re-spawn after the swap. Recovery is
16
+ `mu rebuild`, not `mu db backup`.
17
+ - **Sync:** set `MU_SYNC_DIR` on each machine to a shared folder
18
+ (Syncthing). Every command flushes and ingests ops, merged per field.
19
+ mu never runs ssh or rsync; `mu sync` prints the line.
20
+ `--repair <peer>` is always safe. Agents, workspaces, and task
21
+ ownership never travel.
22
+ - **`mu doctor --deep` DRIFT** (exit 5) is a capture bug: back up and
23
+ report it. Do not rebuild; the live rows may hold work the log missed.
24
+ - The `doctor` `disk` section is report-only: an orphan dir may hold the
25
+ only copy of uncommitted work, so mu prints cleanup commands and runs
26
+ none. Read before you run them.
@@ -0,0 +1,49 @@
1
+ # Find, refute, synthesize
2
+
3
+ Use for audits, bug sweeps, research, and fact-checks: anything that
4
+ produces findings or claims. Finders over-report; a separate agent told
5
+ to kill each finding filters what survives. Builds on
6
+ [fan-out](fan-out.md) and [adversarial-review](adversarial-review.md).
7
+
8
+ ## Steps
9
+
10
+ 1. **Split the search** into dimensions or slices (security, data
11
+ integrity, one module each). One finder task per slice. Finders read;
12
+ they do not fix.
13
+ 2. **Finders write structured findings** to their task note, one line
14
+ each:
15
+
16
+ ```text
17
+ FINDING: f3 src/routes/user.ts:42 high: handler skips the auth check on PUT
18
+ ```
19
+
20
+ 3. **Dedupe** before refuting: one task reads every finder note and
21
+ merges duplicates, keeping the ids. Refuting the same bug twice pays
22
+ twice.
23
+ 4. **One refute task per finding**, blocked by the dedupe task. The
24
+ refuter gets the finding and the code, not the finder's reasoning,
25
+ and tries to prove it false: run it, find the guard, read the caller.
26
+ It ends with one line:
27
+
28
+ ```text
29
+ VERDICT: f3 CONFIRMED | REFUTED | UNVERIFIED <evidence>
30
+ ```
31
+
32
+ For high-severity findings, run three refuters and keep the finding
33
+ only if most fail to kill it.
34
+ 5. **Synthesize**: a final task blocked by every refute task writes the
35
+ report from the verdict lines. Confirmed findings, ranked. Unverified
36
+ ones listed apart. Refuted ones counted, not shown.
37
+
38
+ Done when every finding id from step 3 has a verdict line, and the
39
+ synthesis task closed.
40
+
41
+ ## Traps
42
+
43
+ - **UNVERIFIED is not REFUTED.** A refuter that hit a rate limit or
44
+ could not run the code did not disprove anything. Keep the finding in
45
+ its own section.
46
+ - **Cheap finders, strong refuters.** Finders can run on `pi_mini`;
47
+ the refute step is where the judgement is (`pi_big`).
48
+ - **No findings is a result.** A slice that finds nothing closes with
49
+ that in its note; do not re-run it until it finds something.