@mu-crew/mu 3.7.0 → 3.8.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.
@@ -6,15 +6,25 @@ or may hit flakes.
6
6
  1. **Define done first.** Before dispatch, write the completion criterion
7
7
  into the task note: the checks, how many runs must agree, the
8
8
  allowed variance. A worker that finds the bar in the note stops at
9
- the bar, not at the first green.
9
+ the bar, not at the first green. For chained batches (sweeps,
10
+ campaigns, soaks) it also names the **inputs** each batch runs on
11
+ (build sha, oracle commit, config) and when to refresh them
12
+ ("rebuild from main before each batch"); each batch report states
13
+ the inputs it used, and the stop rule counts only batches on
14
+ current inputs.
10
15
  2. **Split into independent units** ([fan-out](fan-out.md)). Shard a long proof into tasks
11
16
  that run in parallel, so one flake restarts only its unit. Each unit
12
17
  carries its own criterion.
13
18
  3. **Keep state in the DB.** Progress lives in task notes, not in the
14
19
  orchestrator's context. After a compaction, `mu state` and
15
20
  `mu task notes <id>` are the whole picture.
16
- 4. **Accept evidence, not close notes**
17
- ([orchestrator-loop § Merging](orchestrator-loop.md#merging)).
21
+ 4. **Bound each tool call** to minutes: batches of ≤10 minutes,
22
+ `mu task wait --timeout` re-issued, no open-ended `sleep` loops.
23
+ A `--steer` lands only when the running tool returns.
24
+ 5. **Accept evidence, not close notes**
25
+ ([orchestrator-loop § Merging](orchestrator-loop.md#merging)), and
26
+ run a [drift-audit](drift-audit.md) after each batch report and
27
+ every few hours.
18
28
 
19
29
  Done when every unit is `CLOSED/done` and the criterion from step 1
20
30
  holds on the merged tree.
@@ -25,11 +25,12 @@ written down first does neither.
25
25
  `MEASURE: 14 errors (was 31)`, or `NEW: 0 flaky tests`.
26
26
  4. **After each round, check the rule** yourself, from the measurement
27
27
  command, not from the worker's note.
28
- - Rule met: `mu task close <umbrella> --if-ready --evidence '<stop
29
- command + result>'` (each round blocks the umbrella).
28
+ - Rule met: `mu task close <umbrella> --if-ready --evidence "<stop
29
+ command + result>"` (each round blocks the umbrella).
30
30
  - No progress: stop the loop and decide. Change the approach, split
31
31
  the work, or park the umbrella with
32
- `mu task park <umbrella> --why '<what is stuck>'` and tell the human.
32
+ `mu task park <umbrella> --why "<what is stuck>"` and tell the human.
33
+ Prose reasons: [brief § Quoting](brief.md#quoting).
33
34
  - Otherwise: add the next round and dispatch it.
34
35
 
35
36
  Done when the stop rule holds on the merged tree, run by you.
@@ -39,8 +39,8 @@ keeps it.
39
39
  - **Answers arrive when you stop**, as pi follow-up messages, never
40
40
  mid-turn. pi's `followUpMode: "all"` delivers every waiting answer in
41
41
  one turn instead of one turn each; each answer names its delegate and
42
- ends with its `VERDICT: <id>` line, so a batch still maps back. Record
43
- every verdict in the batch before acting on any.
42
+ ends with its `VERDICT: <id>` block, so a batch still maps back. Read
43
+ every verdict in the batch before deciding any.
44
44
  - **Workers with workspaces** build and test: about one per CPU core,
45
45
  fewer when each runs the full suite. A remote host has its own
46
46
  session cap ([remote-workers](remote-workers.md)).
@@ -79,7 +79,8 @@ per turn ([remote-workers](remote-workers.md#step-5-poll-once-per-turn)).
79
79
  test once passed with zero cases.
80
80
  - **Accept evidence, not close notes.** Re-run the key measurement from
81
81
  a clean checkout; close notes have claimed unpushed commits. A
82
- worker's "done" counts only once the diff shows the change.
82
+ worker's "done" counts only once the diff shows the change. Your own
83
+ accept and close notes name the check run and the commit.
83
84
  - **Ask whether the check could have failed.** A gate that cannot say
84
85
  no is not evidence: a test filtered to zero cases, a script you wrote
85
86
  agreeing with itself, a fixture you tuned on. A nonzero diff is a
@@ -87,16 +88,24 @@ per turn ([remote-workers](remote-workers.md#step-5-poll-once-per-turn)).
87
88
 
88
89
  ## Sending
89
90
 
90
- - A plain `mu agent send` appends to prior context; use it to steer or
91
- answer. Unrelated work to pi: `mu agent send worker-1 --fresh 'Claim
92
- task_x...'`.
91
+ A running worker sees what you send, never a new task note: deliver
92
+ an instruction for it with a send (or the next `--fresh` brief), and
93
+ keep the note as the durable copy. pi:
94
+
95
+ | `mu agent send` | busy pi acts | Use for |
96
+ | --- | --- | --- |
97
+ | plain | after the run ends | answers, same-task additions |
98
+ | `--steer` | after the current tool call | advice that can wait for the tool boundary |
99
+ | `--interrupt` | now: kills the running tool | a correction that wastes the current work (stale input, wrong target, changed stop rule) |
100
+ | `--fresh` | refused (`--force` drops the run) | unrelated work: new session + prompt |
101
+
93
102
  - claude-code/codex: send `/new` (codex: `/clear`), then the prompt; a
94
- send it cannot confirm prints a `warning:` on stderr. For pi,
95
- `--fresh` does both in one step.
96
- - Use `mu agent send`, not raw mux input. Single-quote prompts
97
- containing shell expansions, or use a quoted heredoc.
103
+ send it cannot confirm prints a `warning:` on stderr.
104
+ - Use `mu agent send`, not raw mux input. Quote prompts per
105
+ [brief](brief.md#quoting).
98
106
  - Cross-workstream wait and claim use qualified refs; only task
99
107
  ownership crosses.
108
+ - A long run drifts unseen: audit it per [drift-audit](drift-audit.md).
100
109
 
101
110
  ## Stopping a worker
102
111
 
@@ -40,14 +40,18 @@ human asks for a file.
40
40
  consumes what B produces. Plan order is not a dependency: an extra
41
41
  edge serialises tracks that could run in parallel. The exception:
42
42
  tasks that edit the same files share a track ([waves](waves.md)).
43
- 7. **Self-review before dispatch.** Walk each spec requirement and name
44
- the task that implements it. Grep the notes for placeholders. Check
45
- that names in INTERFACES match across tasks. Then read the graph back
46
- with `mu task tree task_0 -w <ws> --down`, or `mu state -w <ws>` for the tracks.
43
+ 7. **Self-review before dispatch.** Map each spec requirement to its
44
+ task, grep the notes for placeholders, match INTERFACES names across
45
+ tasks, and read the graph back (`mu task tree task_0 -w <ws> --down`).
46
+ Then refute each brief that makes claims ([call](tasks-or-calls.md#delegate-call),
47
+ all in one turn): "What in this brief is false about the code,
48
+ ambiguous, or would make a correct worker fail review? Cite
49
+ file:line." Rewrite each AMEND. Five of six briefs refuted in one run had
50
+ such a defect, e.g. a fallback test old extensions made unpassable.
47
51
 
48
52
  Done when every spec requirement maps to a task, no note holds a
49
- placeholder, and `mu state` shows the intended parallel tracks. Then
50
- dispatch per [orchestrator-loop](orchestrator-loop.md).
53
+ placeholder, every claim-making brief has a verdict, and `mu state`
54
+ shows the intended parallel tracks. Then dispatch per [orchestrator-loop](orchestrator-loop.md).
51
55
 
52
56
  ## Notes
53
57
 
@@ -27,8 +27,9 @@ fact-check nobody will track, use delegate mode from
27
27
  [delegate call](tasks-or-calls.md#delegate-call), not a task. The
28
28
  refuter gets the finding and the code, not the finder's reasoning,
29
29
  and tries to prove it false: run it, find the guard, read the caller.
30
- Record its verdict on the finding, and apply the skip and
31
- three-refuter rules, as in [findings § Triage](findings.md#triage).
30
+ Pass `record` so its verdict lands on the finding, and apply the
31
+ skip and three-refuter rules, as in
32
+ [findings § Triage](findings.md#triage).
32
33
  Many findings: issue the calls in batches under the cap ([orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency)); to
33
34
  get the verdicts back as one table, see
34
35
  [codemode-driver § Delegate calls](codemode-driver.md#delegate-calls).
@@ -56,7 +56,7 @@ triage and the umbrella closes with `--if-ready` (workstream mode).
56
56
 
57
57
  - **Reviewers padding the list.** A panel that always finds ten things
58
58
  is guessing.
59
- - **Use different models across angles** where you can; one model's
60
- blind spot repeated five times is still one blind spot.
59
+ - **Vary models across angles** ([Models](../SKILL.md#models-and-thinking-effort)); one model's blind spot
60
+ repeated five times is still one blind spot.
61
61
  - **The panel is not the gate command.** Merge verification still runs on the
62
62
  merged tree ([orchestrator-loop](orchestrator-loop.md#merging)).
@@ -37,7 +37,10 @@ rules are findings: [findings](findings.md) says where they live.
37
37
  line and the rule, and drops false positives (the rule does not
38
38
  apply here, the code already complies, the rule has a stated
39
39
  exception). In workstream mode, a dropped flag is
40
- `close --as rejected --why '<reason>'`; a confirmed one is accepted.
40
+ `close --as rejected --why "<why the rule does not bite here>"`; a
41
+ confirmed one is accepted with `--evidence` naming the flagged line
42
+ ([findings § Triage](findings.md#triage) step 3; quoting:
43
+ [brief § Quoting](brief.md#quoting)).
41
44
  5. **Report or fix** confirmed violations, as in review-panel step 5.
42
45
 
43
46
  Done when every rule from step 1 has a checker result, and every flag
@@ -62,10 +65,12 @@ is decided.
62
65
  corrections from different occasions; a one-off is not a rule.
63
66
  3. **One `OPEN/triage` task per candidate rule**, the rule as the
64
67
  title and its cluster of corrections in the note.
65
- 4. **Refute each candidate** with a [delegate call](tasks-or-calls.md#delegate-call): would it have
66
- prevented the real mistakes in its cluster? Does it contradict an
67
- existing rule? Is it already enforced by a linter or test (then it
68
- needs no prose)? Dropped candidates close `--as rejected`.
68
+ 4. **Refute each candidate** with a
69
+ [delegate call](tasks-or-calls.md#delegate-call) that passes
70
+ `record`: would it have prevented the real mistakes in its cluster?
71
+ Does it contradict an existing rule? Is it already enforced by a
72
+ linter or test (then it needs no prose)? Dropped candidates close
73
+ `--as rejected --why` naming the deciding answer.
69
74
  5. **Propose, don't commit.** The candidates left in triage are the
70
75
  proposal: write them as a diff to the rule file in the umbrella's
71
76
  note, worded per [brief](brief.md) (positive, specific, with the
@@ -7,34 +7,49 @@ hundreds of tasks and a workstream nobody wanted.
7
7
 
8
8
  ## Delegate call
9
9
 
10
- A **delegate call** is one `mu_delegate` tool call in pi. Without the
11
- tool (another harness, a script):
10
+ A **delegate call** is one `mu_delegate` tool call in pi.
12
11
 
13
- ```bash
14
- mu agent spawn refuter-1 -w scratch
15
- runs=$(mu agent send refuter-1 -w scratch --fresh '<brief>' --json | jq .runs)
16
- mu agent wait refuter-1 -w scratch --after-runs "$runs" --json # answer in lastText
17
- ```
12
+ - **It starts empty.** The brief carries everything: the finding or
13
+ claim, file paths, the criteria, and the answer to end with. See
14
+ [brief](brief.md). A tournament judge ends with `WINNER: ...`
15
+ ([tournament](tournament.md)). A refuter or claim checker passes
16
+ `record: { task: "<ws>/<id>" }` and ends with:
18
17
 
19
- `--after-runs` takes the run count the send reported, so a run that
20
- finished before the wait started still counts. A plain wait would sit
21
- until `--timeout`.
18
+ ```text
19
+ VERDICT: <id> CONFIRMED|REFUTED|UNVERIFIED <one line>
20
+ EVIDENCE: <file:line or command + result> (3-6 lines)
21
+ ```
22
22
 
23
- - **It starts empty.** The brief carries everything: the finding or
24
- claim, file paths, the criteria, and the answer line to end with
25
- (`VERDICT: ...`, `WINNER: ...`). See [brief](brief.md).
26
23
  - **Fan out in one turn.** Issue every call for a step together; in pi
27
24
  the answers arrive later as follow-up messages. Calling one, waiting,
28
25
  then the next runs them in series.
29
- - **It leaves no task.** Its `scratch` pane stays attachable while it
30
- runs. `mu_delegate` closes it after a clean finish and keeps it on a
31
- crash, timeout, or API error (`keep: true` always keeps it); the bash
32
- form needs `mu agent close <name> -w scratch`. You record its verdict
33
- on the task it judged.
26
+ - **Its `scratch` pane** stays attachable while it runs; `mu_delegate`
27
+ closes it after a clean finish and keeps it on a crash, timeout, or
28
+ API error (or always, with `keep: true`).
34
29
  - **An API error is yours to decide.** Re-issue the call, or record the
35
30
  check as `UNVERIFIED` on its task, then close the kept pane
36
31
  (`mu_delegate_cancel`, or `mu agent close`).
37
32
 
33
+ Without the tool, write the note `record` would, before deciding:
34
+
35
+ ```bash
36
+ mu agent spawn refuter-1 -w scratch
37
+ runs=$(mu agent send refuter-1 -w scratch --fresh - --json <<'EOF' | jq .runs
38
+ <brief, ending with the VERDICT block>
39
+ EOF
40
+ )
41
+ mu agent wait refuter-1 -w scratch --after-runs "$runs" --json # answer in lastText
42
+ mu task note <id> -w <ws> - <<'EOF'
43
+ REFUTER 1 (refuter-1, 4m 05s):
44
+ <the VERDICT line and EVIDENCE lines, verbatim>
45
+ EOF
46
+ mu agent close refuter-1 -w scratch
47
+ ```
48
+
49
+ A wait that times out or dies leaves `REFUTER 1: no verdict (<outcome>)`.
50
+ `--after-runs` counts a run that finished before the wait started; the
51
+ quoted heredocs keep the evidence verbatim ([brief § Quoting](brief.md#quoting)).
52
+
38
53
  ## The rule
39
54
 
40
55
  **A task is a thing the graph tracks. Checking a thing is a call.**
@@ -47,17 +62,15 @@ until `--timeout`.
47
62
  | the umbrella, and each round of a loop | a skeptic or dedupe pass |
48
63
  | anything that needs its own workspace | a reader or scout whose output feeds one step |
49
64
 
50
- A call writes nothing to mu. Its answer lands on the task it judged:
51
- the orchestrator records the verdict as a note and a state change
52
- (`mu task accept`, `close --as rejected --why '<evidence>'`). The graph
53
- keeps the decision and its evidence without a node per check.
65
+ A call adds no node: its note and your decision land on the task it
66
+ judged ([findings § Triage](findings.md#triage)).
54
67
 
55
68
  ## Examples
56
69
 
57
- - A refuter checks 30 findings: 30 delegate calls, 0 new tasks; each
58
- finding task gets the refuter's evidence and is accepted or closed.
59
- - A tournament over 16 names: 15 judge delegate calls; the winner goes
60
- in the umbrella's note.
70
+ - 30 findings to refute: 30 delegate calls, 0 new tasks; each finding
71
+ gets a `REFUTER` note, then your decision.
72
+ - A tournament over 16 names: 15 judge calls; each round's `WINNER:`
73
+ lines go on the umbrella.
61
74
  - A hypothesis test that reverts commits or forces a race needs a
62
75
  workspace: that one is a task.
63
76
 
@@ -20,8 +20,9 @@ reliable than scoring one.
20
20
  each, so no judge holds the whole field
21
21
  ([tasks-or-calls](tasks-or-calls.md)). The judge sees the two
22
22
  candidates and the rubric and ends with `WINNER: <a|b> <reason>`.
23
- Record each round's results in the umbrella's note; winners meet in
24
- the next round. A round wider than the cap runs in batches
23
+ A judge decides a pair, not a task: no `record`. Record each round
24
+ (pair, winner, reason) in the umbrella's note; winners meet in the
25
+ next round. A round wider than the cap runs in batches
25
26
  ([orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency)).
26
27
  5. **Confirm the winner** with a final check against the rubric, then
27
28
  merge it. Free the losing workspaces.
@@ -35,6 +36,6 @@ final check passed.
35
36
  calls, judge the pair twice with the order swapped; a split decision
36
37
  goes to a third judge.
37
38
  - **Same model, same taste.** Vary the attempt models, and judge with a
38
- model that made no attempt.
39
+ model that made no attempt ([Models](../SKILL.md#models-and-thinking-effort)).
39
40
  - **Ranking many items** (tickets by severity): bucket them in parallel,
40
41
  then run pairwise comparisons only within and across bucket edges.
@@ -43,8 +43,8 @@ and check, skip it.
43
43
  [brief](brief.md) ([plan](plan.md) for a spec-driven build). Rounds
44
44
  of a loop are the one exception: add each when the last closes.
45
45
  5. **Review every unit that ships.** Each commit-producing task gets a
46
- review task ([adversarial-review](adversarial-review.md)), on a
47
- different model where you can. Every finding is a triage task,
46
+ review task ([adversarial-review](adversarial-review.md)) on a
47
+ [comparable model](../SKILL.md#models-and-thinking-effort). Every finding is a triage task,
48
48
  refuted before it is accepted ([findings](findings.md)).
49
49
  6. **Run the loop** ([orchestrator-loop](orchestrator-loop.md)): pipeline
50
50
  merges, verify each merge, keep workers busy
@@ -17,8 +17,9 @@ mu task note <id> "FILES: ...\nDECISION: ...\nVERIFIED: ..."
17
17
  mu task close <id> --evidence "tests pass: ..." # LAST action
18
18
  ```
19
19
 
20
- The note follows the task note contract in SKILL.md. Commit before you
21
- close: the orchestrator cherry-picks your commits, not your tree. A
20
+ The note follows the task note contract in SKILL.md. Keep each tool
21
+ call to minutes (short batches, waits with a timeout): steering reaches
22
+ you only between tool calls. Commit before you close: the orchestrator cherry-picks your commits, not your tree. A
22
23
  review or audit task records each problem per
23
24
  [findings § Record](findings.md#record).
24
25