@mu-crew/mu 3.10.2 → 3.11.1

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 (42) hide show
  1. package/dist/{chunk-RXVYBV3P.js → chunk-2FJK6OOZ.js} +2 -2
  2. package/dist/{chunk-JEWHQ4GB.js → chunk-DXKJY3NT.js} +2 -2
  3. package/dist/{chunk-KGGOITI5.js → chunk-JYZUNPPO.js} +43 -2
  4. package/dist/chunk-JYZUNPPO.js.map +1 -0
  5. package/dist/{cli-GBIC22X7.js → cli-GRAPF5VC.js} +5 -5
  6. package/dist/cli.js +1 -1
  7. package/dist/extension/mu-pi.js +37 -7
  8. package/dist/extension/mu-pi.js.map +1 -1
  9. package/dist/index.d.ts +15 -1
  10. package/dist/index.js +4 -2
  11. package/dist/{tui-SKZMGHA6.js → tui-DGDEH4JX.js} +3 -3
  12. package/docs/VISION.md +3 -0
  13. package/docs/guide/delegate.md +4 -2
  14. package/package.json +1 -1
  15. package/skills/mu/SKILL.md +29 -37
  16. package/skills/mu/recipes/adversarial-review.md +26 -21
  17. package/skills/mu/recipes/brief.md +3 -2
  18. package/skills/mu/recipes/codemode-driver.md +9 -6
  19. package/skills/mu/recipes/deep-research.md +2 -1
  20. package/skills/mu/recipes/drift-audit.md +5 -4
  21. package/skills/mu/recipes/fan-out.md +5 -3
  22. package/skills/mu/recipes/findings.md +7 -3
  23. package/skills/mu/recipes/hypothesis-panel.md +2 -1
  24. package/skills/mu/recipes/models.md +102 -0
  25. package/skills/mu/recipes/orchestrator-loop.md +6 -8
  26. package/skills/mu/recipes/plan.md +5 -5
  27. package/skills/mu/recipes/recovery.md +9 -8
  28. package/skills/mu/recipes/refute.md +7 -4
  29. package/skills/mu/recipes/remote-workers.md +22 -14
  30. package/skills/mu/recipes/review-panel.md +4 -3
  31. package/skills/mu/recipes/rules-audit.md +7 -6
  32. package/skills/mu/recipes/tasks-or-calls.md +6 -5
  33. package/skills/mu/recipes/tournament.md +5 -2
  34. package/skills/mu/recipes/ultrathink.md +6 -4
  35. package/skills/mu/recipes/watcher.md +4 -0
  36. package/skills/mu/recipes/waves.md +5 -4
  37. package/skills/mu/recipes/worker.md +2 -2
  38. package/dist/chunk-KGGOITI5.js.map +0 -1
  39. /package/dist/{chunk-RXVYBV3P.js.map → chunk-2FJK6OOZ.js.map} +0 -0
  40. /package/dist/{chunk-JEWHQ4GB.js.map → chunk-DXKJY3NT.js.map} +0 -0
  41. /package/dist/{cli-GBIC22X7.js.map → cli-GRAPF5VC.js.map} +0 -0
  42. /package/dist/{tui-SKZMGHA6.js.map → tui-DGDEH4JX.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1901,6 +1901,20 @@ declare class AgentCtlUnreachableError extends Error implements HasNextSteps {
1901
1901
  constructor(agentName: string, workstream: string, socket: string, kind: "missing" | "refused");
1902
1902
  errorNextSteps(): NextStep[];
1903
1903
  }
1904
+ /**
1905
+ * A ctl verb (send, abort, ...) found the agent's control socket silent
1906
+ * AND its pane gone: the process exited (or the pane was closed behind
1907
+ * mu's back), so there is nothing to link, kick or forward. Raised
1908
+ * instead of AgentCtlUnreachableError, which is for a live pane.
1909
+ */
1910
+ declare class AgentPaneDeadError extends Error implements HasNextSteps {
1911
+ readonly agentName: string;
1912
+ readonly workstream: string;
1913
+ readonly paneId: string;
1914
+ readonly name = "AgentPaneDeadError";
1915
+ constructor(agentName: string, workstream: string, paneId: string);
1916
+ errorNextSteps(): NextStep[];
1917
+ }
1904
1918
  /**
1905
1919
  * `mu agent abort` on an agent that does not run pi: there is no control
1906
1920
  * socket to carry the abort, and mu does not silently signal the pane.
@@ -5696,4 +5710,4 @@ declare function summarizeWorkstream(db: Db, opts: WorkstreamOptions): Promise<W
5696
5710
  */
5697
5711
  declare function teardownWorkstream(db: Db, opts: TeardownWorkstreamOptions): Promise<TeardownResult>;
5698
5712
 
5699
- export { AGENT_STATE_GLYPH, type AbortAgentOptions, type AbortResult, type AddNoteOptions, type AddTaskOptions, type AdoptAgentOptions, type AdoptAgentResult, AgentAbortNeedsCtlError, AgentAbortTimeoutError, AgentBusyError, AgentCtlUnreachableError, AgentDiedOnSpawnError, AgentExistsError, AgentExtensionOutdatedError, AgentFreshNeedsCtlError, AgentNameExhaustedError, AgentNotFoundError, AgentNotInWorkstreamError, type AgentRow, AgentSlashCommandUnsupportedError, AgentSpawnCliNotFoundError, AgentSpawnStartupError, type AmbientOptions, type AmbientResult, type AppendLogOptions, type ApplyResult, type BlockEdgeResult, CAPTURE_TRIGGER_DDL, CURRENT_SCHEMA_VERSION, type CaptureDb, type CaptureIntent, type CaptureOptions, type CaseCollision, type CheapDriftReport, type ClaimResult, type ClaimTaskOptions, ClaimerNotRegisteredError, type CloseAgentOptions, type CloseAgentResult, type CloseSubstate, type CloseTaskResult, type CommandResolutionResult, type CommandResolver, CrossWorkstreamEdgeError, type CtlLink, CycleError, DEFAULT_SUBSTATE, DRIFT_REPORT_CAP, type Db, type DeleteTaskResult, type DoctorCheck, type DoctorStatus, type DoctorSummary, DriftDetectedError, type DriftRecord, type DriftReport, EXPECTED_TABLES, type EvidenceOption, type FileLockOptions, type FleetHazard, type FlushResult, type FsProbe, type FullDag, GLYPH, GroupIdAmbiguousError, type GroupSummary, HazardFailError, type HazardSeverity, type Hlc, HlcOverflowError, HlcParseError, HomeDirAsProjectRootError, type IdFromTitleResult, type IngestFromDbResult, type IngestResult, type InsertAgentInput, InvalidSubstateError, type InverseOp, KNOWN_INTENTS, KNOWN_VERBS, type KickAgentOptions, type KickAgentResult, type KickProcessExecutor, type KickSignal, type KnownIntent, LinkConflictError, type LinkState, type LinkStatus, type ListLiveAgentsOptions, type ListLogsOptions, type ListNotesOptions, type ListReadyOptions, type ListTasksOptions, type LiveAgent, type LiveAgentsView, type LoadFullDagOptions, type LoadWorkstreamSnapshotOptions, type LocalIntent, type LogKind, LogKindReservedError, type LogRow, MACHINE_LOCAL_ENTITIES, MACHINE_LOCAL_TABLES, MU_SHIM_MARKER, MachineIdentityMissingError, type MachineLocalEntity, type MachineLocalLoss, type MachineLocalTable, type MuxBackend, type MuxBackendName, MuxError, type MuxPane, type MuxPaneStatus, type MuxSession, type MuxWindow, type NewSessionOptions, type NewWindowOptions, NoForegroundProcessError, NoMultiplexerError, NothingToUndoError, OP_CTX_DDL, type Op, type OpContext, OpEntityNotSyncedError, OpKeyMalformedError, type OpenDbOptions, type OwnedTasksSummary, PANE_ID_RE, PEER_SHORT_LEN, PEER_STALE_MS, PORTABLE_TABLES, PaneNotFoundError, PaneNotInSessionError, type ParkTaskOptions, type PeerSegment, type PeerStatus, type PortableTable, ReaperDetectedDuringWaitError, type RebuildOptions, type RebuildReport, RebuildTargetExistsError, RebuildTargetIsSourceError, type ReconcileMode, type ReconcileOptions, type ReconcileReport, type ReleaseResult, type ReleaseTaskOptions, type RemoveBlockEdgeResult, type RenderableOp, type RenderedOp, type ReparentTaskResult, type RoiBucket, type RuntimeState, SEGMENT_FORMAT_VERSION, SYNCED_ENTITIES, SchemaTooNewError, SchemaTooOldError, type SegmentDefect, type SegmentDefectKind, type SegmentLine, type SegmentManifest, type SendOptions, type SendResult, type SendWarning, type SetStatusOptions, type SetStatusResult, type SlugifyResult, type SpawnAgentOptions, type SplitWindowOptions, StallDetectedDuringWaitError, type StateReading, type StateSource, type StrandedWorkspaceOrphan, SubstateReasonRequiredError, type SyncPassResult, SyncPeerNotFoundError, SyncPeerRefAmbiguousError, SyncSourceNotFoundError, type SyncedEntity, TASK_STATUSES, TASK_STATUS_LIST, TASK_SUBSTATES, TASK_SUBSTATE_ROWS, TaskAlreadyOwnedError, TaskClaimStaleWorkspaceError, type TaskEdgeWithStatus, type TaskEdges, type TaskEdgesWithStatus, TaskExistsError, TaskIdInvalidError, TaskInTriageError, TaskNotFoundError, TaskNotInWorkstreamError, type TaskNoteRow, type TaskPair, TaskParkStateError, TaskParkedError, type TaskRow, type TaskStatus, type TaskSubstate, TaskTitleSlugEmptyError, type TaskWaitOptions, type TaskWaitRef, type TaskWaitResult, type TaskWaitTaskState, type TeardownResult, TmuxError, type TmuxExecResult, type TmuxExecutor, type TmuxPane, type TmuxSession, type TmuxWindow, type Track, type Transport, UNKNOWN_REASON, UndoGroupNotFoundError, type UndoOptions, type UndoPlan, type UndoResult, UndoSupersededError, type UpdateTaskOptions, type UpdateTaskResult, type VcsBackend, type VcsBackendName, WORKSPACE_STALE_THRESHOLD, WorkspaceConflictError, WorkspaceDirtyError, WorkspaceExistsError, type WorkspaceFailure, WorkspaceNotFoundError, type WorkspaceOrphan, WorkspacePathNotEmptyError, WorkspacePreservedError, type WorkspaceRow, type WorkspaceStaleness, WorkspaceVcsRequiredError, WorkstreamExistsError, WorkstreamNameInvalidError, WorkstreamNameReservedError, WorkstreamNotFoundError, type WorkstreamOptions, type WorkstreamSnapshot, type WorkstreamSnapshotSlowFields, type WorkstreamSummary, abortAgent, acceptTask, activeMux, addBlockEdge, addNote, addTask, adoptAgent, agentKey, agentStateGlyph, agentStateHistogram, ambientFlush, ambientIngest, ambientSyncPass, appendLog, applyIncomingOp, applyOp, applyOps, assertValidPaneId, awaitPaneQuiescence, backendByName, capturePane, checkCaseCollisions, checkCheapDriftInvariant, checkCommandResolvable, checkDbInsideSyncDir, checkDrift, checkFleetHazards, checkNetworkMount, claimTask, classifyFsType, closeAgent, closeTask, compareHlc, composeAgentTitle, countProblems, createWorkspace, ctlRuntimeState, currentAgentName, currentOpContext, currentPaneTitle, decorateWithDirty, decorateWithStaleness, defaultDbPath, defaultSendDelayMs, defaultSendReadinessMs, defaultSpawnLivenessMs, defaultStateDir, deleteAgent, deleteTask, detectBackend, detectMux, discoverPeers, driftRemediation, emitEvent, ensureWorkstream, envVarNameForCli, expectsCtl, findCaseCollisions, flushSegment, foregroundPgid, formatDriftRecord, formatHlc, formatPair, freeWorkspace, getAgent, getAgentByPane, getParallelTracks, getPrerequisites, getTask, getTaskEdges, getTaskEdgesWithStatus, getWaitPollCount, getWatermark, getWorkspaceForAgent, getWorkspaceStaleness, gitBackend, hasWorkMarker, idFromTitle, idFromTitleVerbose, ingestFromDb, ingestSegment, insertAgent, inspectLinks, installCapture, interruptAgent, isKickSignal, isPathInside, isTaskStatus, isValidAgentName, isValidPair, isValidPaneId, isValidTaskId, isValidWorkstreamName, isWorkspaceStale, jjBackend, kickAgent, killPane, killSession, latestSeq, linkPi, linkSkill, listAgents, listAllOrphanWorkspaces, listBlocked, listGoals, listInProgress, listLiveAgents, listLogs, listNotes, listPanes, listPanesInSession, listReady, listRecentClosed, listRecentGroups, listSessions, listTasks, listTasksByOwner, listWindows, listWorkspaceOrphans, listWorkspaces, listWorkstreams, loadDoctorChecks, loadDoctorSummary, loadFullDag, loadWorkstreamSnapshot, loadWorkstreamSnapshotFast, loadWorkstreamSnapshotSlow, localMachineId, locksDir, mapLegacyStatus, mergeSnapshotFastSlow, mostRecentGroup, murmurAvailable, mux, muxByName, newSession, newSessionWithPane, newWindow, nextHlc, noneBackend, opSubject, openDb, openTask, paneExists, paneTTY, parkTask, parseAgentNameFromTitle, parseHlc, parseOpKey, parsePsTtyOutput, peerStatuses, planUndo, priorFieldValue, probeFilesystem, readAgent, readAgentStates, readFileLockMeta, readManifest, rebuildInto, receiveHlc, reconcile, refreshAgentTitle, releaseTask, remediationParagraph, removeBlockEdge, renderForest, renderOp, renderOpLine, renderTaskTree, repairPeer, reparentTask, resetCommandResolverForTests, resetKickProcessExecutor, resetMux, resetSleep, resetTmuxExecutor, resetWaitPollCount, resetWatermark, resolveActorIdentity, resolveCliCommand, resolveCliCommandWithSource, resolveGroupId, resolvePair, resolvePeerRef, roiBucket, segmentLineCount, segmentPath, selectLayout, sendToAgent, sendToPane, sendViaTransport, sessionExists, setCommandResolverForTests, setKickProcessExecutor, setMuxForTests, setPaneTitle, setSleepForTests, setTaskStatus, setTmuxExecutor, setWaitSleepForTests, setWaitStuckWarnForTests, setWatermark, slBackend, sleep, slugifyTitle, slugifyTitleVerbose, spawnAgent, splitWindow, summarizeOwnedTasks, summarizeWorkstream, syncDir, syncEnabled, syncPass, teardownWorkstream, tmux, tmuxBackend, transportNextSteps, undoGroup, unparkTask, updateTask, verifyAgainstManifest, waitForTasks, withCaptureSuppressed, withFileLock, withOpContext, workspacePath, workspacesRoot, yankCommandForCheck };
5713
+ export { AGENT_STATE_GLYPH, type AbortAgentOptions, type AbortResult, type AddNoteOptions, type AddTaskOptions, type AdoptAgentOptions, type AdoptAgentResult, AgentAbortNeedsCtlError, AgentAbortTimeoutError, AgentBusyError, AgentCtlUnreachableError, AgentDiedOnSpawnError, AgentExistsError, AgentExtensionOutdatedError, AgentFreshNeedsCtlError, AgentNameExhaustedError, AgentNotFoundError, AgentNotInWorkstreamError, AgentPaneDeadError, type AgentRow, AgentSlashCommandUnsupportedError, AgentSpawnCliNotFoundError, AgentSpawnStartupError, type AmbientOptions, type AmbientResult, type AppendLogOptions, type ApplyResult, type BlockEdgeResult, CAPTURE_TRIGGER_DDL, CURRENT_SCHEMA_VERSION, type CaptureDb, type CaptureIntent, type CaptureOptions, type CaseCollision, type CheapDriftReport, type ClaimResult, type ClaimTaskOptions, ClaimerNotRegisteredError, type CloseAgentOptions, type CloseAgentResult, type CloseSubstate, type CloseTaskResult, type CommandResolutionResult, type CommandResolver, CrossWorkstreamEdgeError, type CtlLink, CycleError, DEFAULT_SUBSTATE, DRIFT_REPORT_CAP, type Db, type DeleteTaskResult, type DoctorCheck, type DoctorStatus, type DoctorSummary, DriftDetectedError, type DriftRecord, type DriftReport, EXPECTED_TABLES, type EvidenceOption, type FileLockOptions, type FleetHazard, type FlushResult, type FsProbe, type FullDag, GLYPH, GroupIdAmbiguousError, type GroupSummary, HazardFailError, type HazardSeverity, type Hlc, HlcOverflowError, HlcParseError, HomeDirAsProjectRootError, type IdFromTitleResult, type IngestFromDbResult, type IngestResult, type InsertAgentInput, InvalidSubstateError, type InverseOp, KNOWN_INTENTS, KNOWN_VERBS, type KickAgentOptions, type KickAgentResult, type KickProcessExecutor, type KickSignal, type KnownIntent, LinkConflictError, type LinkState, type LinkStatus, type ListLiveAgentsOptions, type ListLogsOptions, type ListNotesOptions, type ListReadyOptions, type ListTasksOptions, type LiveAgent, type LiveAgentsView, type LoadFullDagOptions, type LoadWorkstreamSnapshotOptions, type LocalIntent, type LogKind, LogKindReservedError, type LogRow, MACHINE_LOCAL_ENTITIES, MACHINE_LOCAL_TABLES, MU_SHIM_MARKER, MachineIdentityMissingError, type MachineLocalEntity, type MachineLocalLoss, type MachineLocalTable, type MuxBackend, type MuxBackendName, MuxError, type MuxPane, type MuxPaneStatus, type MuxSession, type MuxWindow, type NewSessionOptions, type NewWindowOptions, NoForegroundProcessError, NoMultiplexerError, NothingToUndoError, OP_CTX_DDL, type Op, type OpContext, OpEntityNotSyncedError, OpKeyMalformedError, type OpenDbOptions, type OwnedTasksSummary, PANE_ID_RE, PEER_SHORT_LEN, PEER_STALE_MS, PORTABLE_TABLES, PaneNotFoundError, PaneNotInSessionError, type ParkTaskOptions, type PeerSegment, type PeerStatus, type PortableTable, ReaperDetectedDuringWaitError, type RebuildOptions, type RebuildReport, RebuildTargetExistsError, RebuildTargetIsSourceError, type ReconcileMode, type ReconcileOptions, type ReconcileReport, type ReleaseResult, type ReleaseTaskOptions, type RemoveBlockEdgeResult, type RenderableOp, type RenderedOp, type ReparentTaskResult, type RoiBucket, type RuntimeState, SEGMENT_FORMAT_VERSION, SYNCED_ENTITIES, SchemaTooNewError, SchemaTooOldError, type SegmentDefect, type SegmentDefectKind, type SegmentLine, type SegmentManifest, type SendOptions, type SendResult, type SendWarning, type SetStatusOptions, type SetStatusResult, type SlugifyResult, type SpawnAgentOptions, type SplitWindowOptions, StallDetectedDuringWaitError, type StateReading, type StateSource, type StrandedWorkspaceOrphan, SubstateReasonRequiredError, type SyncPassResult, SyncPeerNotFoundError, SyncPeerRefAmbiguousError, SyncSourceNotFoundError, type SyncedEntity, TASK_STATUSES, TASK_STATUS_LIST, TASK_SUBSTATES, TASK_SUBSTATE_ROWS, TaskAlreadyOwnedError, TaskClaimStaleWorkspaceError, type TaskEdgeWithStatus, type TaskEdges, type TaskEdgesWithStatus, TaskExistsError, TaskIdInvalidError, TaskInTriageError, TaskNotFoundError, TaskNotInWorkstreamError, type TaskNoteRow, type TaskPair, TaskParkStateError, TaskParkedError, type TaskRow, type TaskStatus, type TaskSubstate, TaskTitleSlugEmptyError, type TaskWaitOptions, type TaskWaitRef, type TaskWaitResult, type TaskWaitTaskState, type TeardownResult, TmuxError, type TmuxExecResult, type TmuxExecutor, type TmuxPane, type TmuxSession, type TmuxWindow, type Track, type Transport, UNKNOWN_REASON, UndoGroupNotFoundError, type UndoOptions, type UndoPlan, type UndoResult, UndoSupersededError, type UpdateTaskOptions, type UpdateTaskResult, type VcsBackend, type VcsBackendName, WORKSPACE_STALE_THRESHOLD, WorkspaceConflictError, WorkspaceDirtyError, WorkspaceExistsError, type WorkspaceFailure, WorkspaceNotFoundError, type WorkspaceOrphan, WorkspacePathNotEmptyError, WorkspacePreservedError, type WorkspaceRow, type WorkspaceStaleness, WorkspaceVcsRequiredError, WorkstreamExistsError, WorkstreamNameInvalidError, WorkstreamNameReservedError, WorkstreamNotFoundError, type WorkstreamOptions, type WorkstreamSnapshot, type WorkstreamSnapshotSlowFields, type WorkstreamSummary, abortAgent, acceptTask, activeMux, addBlockEdge, addNote, addTask, adoptAgent, agentKey, agentStateGlyph, agentStateHistogram, ambientFlush, ambientIngest, ambientSyncPass, appendLog, applyIncomingOp, applyOp, applyOps, assertValidPaneId, awaitPaneQuiescence, backendByName, capturePane, checkCaseCollisions, checkCheapDriftInvariant, checkCommandResolvable, checkDbInsideSyncDir, checkDrift, checkFleetHazards, checkNetworkMount, claimTask, classifyFsType, closeAgent, closeTask, compareHlc, composeAgentTitle, countProblems, createWorkspace, ctlRuntimeState, currentAgentName, currentOpContext, currentPaneTitle, decorateWithDirty, decorateWithStaleness, defaultDbPath, defaultSendDelayMs, defaultSendReadinessMs, defaultSpawnLivenessMs, defaultStateDir, deleteAgent, deleteTask, detectBackend, detectMux, discoverPeers, driftRemediation, emitEvent, ensureWorkstream, envVarNameForCli, expectsCtl, findCaseCollisions, flushSegment, foregroundPgid, formatDriftRecord, formatHlc, formatPair, freeWorkspace, getAgent, getAgentByPane, getParallelTracks, getPrerequisites, getTask, getTaskEdges, getTaskEdgesWithStatus, getWaitPollCount, getWatermark, getWorkspaceForAgent, getWorkspaceStaleness, gitBackend, hasWorkMarker, idFromTitle, idFromTitleVerbose, ingestFromDb, ingestSegment, insertAgent, inspectLinks, installCapture, interruptAgent, isKickSignal, isPathInside, isTaskStatus, isValidAgentName, isValidPair, isValidPaneId, isValidTaskId, isValidWorkstreamName, isWorkspaceStale, jjBackend, kickAgent, killPane, killSession, latestSeq, linkPi, linkSkill, listAgents, listAllOrphanWorkspaces, listBlocked, listGoals, listInProgress, listLiveAgents, listLogs, listNotes, listPanes, listPanesInSession, listReady, listRecentClosed, listRecentGroups, listSessions, listTasks, listTasksByOwner, listWindows, listWorkspaceOrphans, listWorkspaces, listWorkstreams, loadDoctorChecks, loadDoctorSummary, loadFullDag, loadWorkstreamSnapshot, loadWorkstreamSnapshotFast, loadWorkstreamSnapshotSlow, localMachineId, locksDir, mapLegacyStatus, mergeSnapshotFastSlow, mostRecentGroup, murmurAvailable, mux, muxByName, newSession, newSessionWithPane, newWindow, nextHlc, noneBackend, opSubject, openDb, openTask, paneExists, paneTTY, parkTask, parseAgentNameFromTitle, parseHlc, parseOpKey, parsePsTtyOutput, peerStatuses, planUndo, priorFieldValue, probeFilesystem, readAgent, readAgentStates, readFileLockMeta, readManifest, rebuildInto, receiveHlc, reconcile, refreshAgentTitle, releaseTask, remediationParagraph, removeBlockEdge, renderForest, renderOp, renderOpLine, renderTaskTree, repairPeer, reparentTask, resetCommandResolverForTests, resetKickProcessExecutor, resetMux, resetSleep, resetTmuxExecutor, resetWaitPollCount, resetWatermark, resolveActorIdentity, resolveCliCommand, resolveCliCommandWithSource, resolveGroupId, resolvePair, resolvePeerRef, roiBucket, segmentLineCount, segmentPath, selectLayout, sendToAgent, sendToPane, sendViaTransport, sessionExists, setCommandResolverForTests, setKickProcessExecutor, setMuxForTests, setPaneTitle, setSleepForTests, setTaskStatus, setTmuxExecutor, setWaitSleepForTests, setWaitStuckWarnForTests, setWatermark, slBackend, sleep, slugifyTitle, slugifyTitleVerbose, spawnAgent, splitWindow, summarizeOwnedTasks, summarizeWorkstream, syncDir, syncEnabled, syncPass, teardownWorkstream, tmux, tmuxBackend, transportNextSteps, undoGroup, unparkTask, updateTask, verifyAgainstManifest, waitForTasks, withCaptureSuppressed, withFileLock, withOpContext, workspacePath, workspacesRoot, yankCommandForCheck };
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  priorFieldValue,
9
9
  resolveGroupId,
10
10
  undoGroup
11
- } from "./chunk-JEWHQ4GB.js";
11
+ } from "./chunk-DXKJY3NT.js";
12
12
  import {
13
13
  AGENT_STATE_GLYPH,
14
14
  AgentAbortNeedsCtlError,
@@ -22,6 +22,7 @@ import {
22
22
  AgentNameExhaustedError,
23
23
  AgentNotFoundError,
24
24
  AgentNotInWorkstreamError,
25
+ AgentPaneDeadError,
25
26
  AgentSlashCommandUnsupportedError,
26
27
  AgentSpawnCliNotFoundError,
27
28
  AgentSpawnStartupError,
@@ -251,7 +252,7 @@ import {
251
252
  workspacePath,
252
253
  workspacesRoot,
253
254
  yankCommandForCheck
254
- } from "./chunk-KGGOITI5.js";
255
+ } from "./chunk-JYZUNPPO.js";
255
256
  import {
256
257
  CAPTURE_TRIGGER_DDL,
257
258
  CURRENT_SCHEMA_VERSION,
@@ -342,6 +343,7 @@ export {
342
343
  AgentNameExhaustedError,
343
344
  AgentNotFoundError,
344
345
  AgentNotInWorkstreamError,
346
+ AgentPaneDeadError,
345
347
  AgentSlashCommandUnsupportedError,
346
348
  AgentSpawnCliNotFoundError,
347
349
  AgentSpawnStartupError,
@@ -12,7 +12,7 @@ import {
12
12
  relTimeBasisForSort,
13
13
  sortTasks,
14
14
  truncate
15
- } from "./chunk-RXVYBV3P.js";
15
+ } from "./chunk-2FJK6OOZ.js";
16
16
  import {
17
17
  GLYPH,
18
18
  WORKSPACE_STALE_THRESHOLD,
@@ -41,7 +41,7 @@ import {
41
41
  summarizeOwnedTasks,
42
42
  superscriptDigit,
43
43
  yankCommandForCheck
44
- } from "./chunk-KGGOITI5.js";
44
+ } from "./chunk-JYZUNPPO.js";
45
45
  import {
46
46
  TASK_STATUSES,
47
47
  ambientSyncPass,
@@ -6449,4 +6449,4 @@ async function runTui(db, opts) {
6449
6449
  export {
6450
6450
  runTui
6451
6451
  };
6452
- //# sourceMappingURL=tui-SKZMGHA6.js.map
6452
+ //# sourceMappingURL=tui-DGDEH4JX.js.map
package/docs/VISION.md CHANGED
@@ -201,6 +201,9 @@ mu agent spawn worker-1 --cli pi_mini
201
201
  mu agent spawn reviewer-1 --cli pi_big
202
202
  ```
203
203
 
204
+ The skill's [model tiers](../skills/mu/recipes/models.md) are advice to
205
+ the agent choosing; mu reads none of it.
206
+
204
207
  ## What it enables
205
208
 
206
209
  - **Visible crews.** Spawn agents once and send them work all day. Each
@@ -22,7 +22,7 @@ Delegates called in one turn run in parallel.
22
22
  | `timeout` | Seconds to wait for the answer (default 3600). After it, the answer does not come back; the follow-up gives the `mu agent wait` command. |
23
23
  | `workspace` | Own VCS checkout, for delegates that edit files. The follow-up names its path. It isolates repository edits only. |
24
24
  | `cli` | Key for `$MU_<CLI>_COMMAND` (default `pi`). Only keys set in pi's environment exist. |
25
- | `model` | pi `--model` value, appended to the cli's command (`sonnet`, `openai/gpt-5:high`). Varies models across a panel. tmux only: herdr refuses a command override. |
25
+ | `model` | pi `--model` value, appended to the cli's command (`sonnet`, `<provider>/<model>:high`, copied from `pi --list-models`). Varies models across a panel. tmux only: herdr refuses a command override. |
26
26
  | `keep` | Keep the pane after it finishes, to talk to it again. |
27
27
  | `record` | `{ task, workstream? }` (or `task: "<ws>/<task>"`): write the answer's verdict onto that task as a note. See [Record a verdict](#record-a-verdict). |
28
28
 
@@ -30,7 +30,9 @@ Delegates called in one turn run in parallel.
30
30
  - Stop: `mu_delegate_cancel`, or `mu agent abort <name> -w scratch`.
31
31
  - The pane closes after a clean finish; died or timed-out panes stay
32
32
  as evidence.
33
- - pi's footer shows how many delegates this session is waiting on.
33
+ - pi's footer shows how many delegates this session is waiting on, and
34
+ `N results pending` for delegates that finished but whose answer has
35
+ not reached the conversation yet (queued behind the running turn).
34
36
  - Each delegate costs a pane and a pi process. A session runs at most
35
37
  `MU_DELEGATE_MAX` at once (default 16). Further calls are queued, up
36
38
  to four times the cap: the footer reads `16 delegates running, 4 queued`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mu-crew/mu",
3
- "version": "3.10.2",
3
+ "version": "3.11.1",
4
4
  "description": "A persistent, observable crew of pi agents running in one tmux or herdr session per workstream, coordinated through a built-in task DAG.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: mu
3
3
  description: >-
4
- Fresh-context subagents and crews in tmux/herdr panes. Check before you
4
+ Fresh-context delegates (mu's counterpart to hidden subagents) and crews
5
+ in tmux/herdr panes. Check before you
5
6
  commit: before acting on a claim, root cause, plan, fix or brief, have a
6
7
  `mu_delegate` call refute it. Also for a fresh delegate's second look at
7
8
  your own work or diff; parallel read-only research, investigation or fan-out
@@ -24,14 +25,14 @@ not in `--help` do not exist.
24
25
  Default output is a card on stdout plus a `Next:` block. Read both.
25
26
  Every verb takes `--json`: one stdout object; collections are
26
27
  `{items, count}`, except `mu agent list` (`{agents, orphans}`); `mu sql --json` is bare rows; `mu log --tail` is
27
- NDJSON. Errors are `{error,message,nextSteps,exitCode}` on stderr
28
+ NDJSON; `mu log` writes print text even with `--json`. Errors are `{error,message,nextSteps,exitCode}` on stderr
28
29
  (validation errors add `usage`). **`nextSteps` survives in JSON.**
29
30
 
30
31
  ## Vocabulary
31
32
 
32
33
  - **workstream** — one **mux session** `mu-<name>` (tmux session or
33
34
  herdr workspace) and one DB partition.
34
- - **agent** — named worker in a pane (you may be one).
35
+ - **agent** — named process in a pane (you may be one); a **worker** is an agent claiming tasks.
35
36
  - **mux** — tmux or herdr, one per invocation. `mu doctor` names it;
36
37
  `MU_MUX` forces it. `mu agent kick` is Linux-only on herdr.
37
38
  - **control socket (ctl)** — how mu drives a pi agent: the mu pi
@@ -44,7 +45,8 @@ NDJSON. Errors are `{error,message,nextSteps,exitCode}` on stderr
44
45
  - **claim / release** — atomic take/clear of `tasks.owner`.
45
46
  - **note** — append-only task context; survives sessions.
46
47
  - **track** — tasks connected by `block` edges (`mu task block B --by A`
47
- puts B on A's track); spawn at most one agent per ready track.
48
+ puts B on A's track). Spawn one agent per ready task, not per track:
49
+ an umbrella puts all its units on one track.
48
50
  - **workspace** — per-agent VCS copy under
49
51
  `<state-dir>/workspaces/<workstream>/<agent>/`.
50
52
 
@@ -62,7 +64,7 @@ Recipe words, the same in every recipe:
62
64
  - **finding** — one reported problem, recorded as an `OPEN/triage` task.
63
65
  - **verdict** — a check's answer: `VERDICT: <id> CONFIRMED | REFUTED |
64
66
  UNVERIFIED <one line>` plus `EVIDENCE:` lines (or ACCEPT | REJECT for
65
- a review gate).
67
+ a review gate). REFUTED on a brief means it holds a false claim: rewrite it.
66
68
  - **stop rule** — the command and condition that end a loop, written on
67
69
  the umbrella first ([loop-until-done](recipes/loop-until-done.md)).
68
70
 
@@ -76,12 +78,12 @@ or inspection.
76
78
 
77
79
  Before you act on a claim, root cause, plan, fix or brief, or to get a second
78
80
  look at your own work or diff, make a [delegate call](recipes/tasks-or-calls.md#delegate-call)
79
- that tries to refute it (briefs: see Orchestrator rules; many claims: [refute](recipes/refute.md)).
81
+ that tries to refute it, on another model family ([models](recipes/models.md#checkers); briefs: see
82
+ Orchestrator rules; many claims: [refute](recipes/refute.md)).
80
83
 
81
84
  For one-shot work inside pi, call `mu_delegate` (installed by `mu link pi`). Outside pi: spawn
82
- into the reserved `scratch` workstream (no task DAG, auto-created), `send --fresh --json`, then
83
- `mu agent wait --after-runs <its runs> --json` (`lastText`); without `--after-runs` a run that
84
- ends first hangs the wait. Recipes call either form a **delegate call**. A check judging a mu
85
+ into the reserved `scratch` workstream (no task DAG, auto-created), as in
86
+ [delegate call](recipes/tasks-or-calls.md#delegate-call). Recipes call either form a **delegate call**. A check judging a mu
85
87
  task lands its verdict there: `record: { task: "<ws>/<id>" }` on `mu_delegate`, a hand-written
86
88
  `REFUTER` note on the spawn path; with no task, skip both.
87
89
 
@@ -102,8 +104,10 @@ wrapper whose argv0 is not `pi`/`pi-meta` it shows `needs_input`): add
102
104
  ### Workstreams, DAGs, tracks
103
105
 
104
106
  The DAG has one edge: `mu task block A --by B` means **B blocks A**.
105
- Tracks sharing a prerequisite collapse into one, so two agents never
106
- take the same dependency.
107
+ Tracks sharing a prerequisite collapse into one, so an umbrella every
108
+ unit blocks makes the whole job one track. Parallelism is the ready
109
+ set: tasks that edit the same files get a `block` edge between them,
110
+ so only one is ready at a time.
107
111
 
108
112
  ### Workspaces prevent trampling
109
113
 
@@ -112,9 +116,9 @@ repo, spawn with `--workspace`. Two builds in one checkout corrupt each
112
116
  other; keep the main checkout for orchestration.
113
117
 
114
118
  Workspaces auto-detect jj, sl, or git (else `cp -a`). `mu agent close`
115
- frees one **only if clean** (no uncommitted changes, no commits since
116
- fork); otherwise it fails with `WorkspacePreservedError`. Then use
117
- `mu workspace free <agent>` or `--discard-workspace` (lossy).
119
+ frees one **only if clean**; otherwise it fails with
120
+ `WorkspacePreservedError`. A `cp -a` copy is never clean. Cherry-pick what
121
+ to keep, and pass `--discard-workspace` only to throw the rest away.
118
122
  Before each `--fresh` send, `mu workspace refresh <agent>` rebases onto
119
123
  main and keeps LLM context ([waves](recipes/waves.md) when workers share
120
124
  files). Claim and send warn at ≥10 commits behind
@@ -190,7 +194,7 @@ rules hold even when you skip it:
190
194
  - **Send, don't note, a running worker**: it never sees new notes. The note is the durable copy
191
195
  ([how to send](recipes/orchestrator-loop.md#sending)).
192
196
  - **Refute a brief claiming a cause, fix, threshold or code fact** before dispatch:
193
- one `record`ed refuter call; rewrite on AMEND. Others get a `REFUTE-EXEMPT: <why>` note.
197
+ one `record`ed refuter call; rewrite on REFUTED. Others get a `REFUTE-EXEMPT: <why>` note.
194
198
  - **Checks are calls, not tasks.** Refuters, claim checkers, judges and
195
199
  skeptics are [delegate calls](recipes/tasks-or-calls.md#delegate-call)
196
200
  (`mu_delegate`, or a `scratch` spawn without it), all issued in one
@@ -205,13 +209,9 @@ rules hold even when you skip it:
205
209
 
206
210
  ## CLI gotchas
207
211
 
208
- - **`task close --if-ready`** no-ops until every blocker is CLOSED; bare
209
- `task release` reopens IN_PROGRESS.
210
212
  - **`task close --as rejected|wontfix --why ...`** unblocks dependents
211
213
  (listed in the output). `rejected` = the claim is false; `wontfix` =
212
- true, not worth doing. To keep dependents waiting, `task park --why` instead: parked
213
- leaves `next`, and `claim` refuses it without `--force`. Park refuses
214
- IN_PROGRESS — `task release` first.
214
+ true, not worth doing. To keep dependents waiting, `task park --why` instead.
215
215
  - **For waits use `task wait`, not `log --tail`.** `mu log --kind <k>`
216
216
  entries are your own durable state (a ledger); `--intent` filters what
217
217
  mu recorded.
@@ -225,23 +225,14 @@ rules hold even when you skip it:
225
225
 
226
226
  ## Models and thinking effort
227
227
 
228
- mu doesn't reason about models; pi does. Controls:
228
+ mu passes the model through; you pick it. Before you choose one for a
229
+ spawn or a delegate call, read [recipes/models.md](recipes/models.md):
230
+ tiers, which roles need which, and local models as a last resort.
229
231
 
230
- ```bash
231
- mu agent spawn r --command "pi --model opus:high"
232
- export MU_PI_COMMAND="pi --model sonnet:medium"
233
- mu agent spawn a --cli pi_big # uses $MU_PI_BIG_COMMAND
234
- ```
235
-
236
- `pi_mini` scouts and finds, `pi` builds and refactors, `pi_big` designs and
237
- handles incidents. A reviewer, refuter,
238
- judge or auditor checks level or up, never down: at least the worker's
239
- capability, from another family if one exists (provider or model-id prefix in
240
- `pi --list-models`). Small-model signs: a local runtime (ollama, lmstudio,
241
- llama.cpp), a size (`4b`, `27b`), mini/haiku/flash/nano/lite, thinking `no`,
242
- context or max-out far below the worker's. No such peer: same model, fresh
243
- context, higher thinking unless at max. Probe an unused model first
244
- (`pi --model <provider/model> -p "say ok"`); `ctl: ok` does not test it.
232
+ - `mu_delegate` takes `model`; a spawn takes `--command "pi --model <id>"`.
233
+ - A checker (reviewer, refuter, judge, auditor) runs at the author's tier
234
+ or higher, from another family when one exists. A delegate with no
235
+ `model` runs the cli's default model; pass `model` when it matters.
245
236
 
246
237
  ## Reaper and agent state
247
238
 
@@ -264,7 +255,7 @@ Close the task as your last action, or the orchestrator's wait hangs.
264
255
  ## Guardrails
265
256
 
266
257
  Task ownership outranks agent state. Coordinate through task notes and
267
- the activity log. Keep edges within one workstream. Give workers
258
+ the ops log (`mu log`). Keep edges within one workstream. Give workers
268
259
  bounded paths and commands.
269
260
 
270
261
  ## Recipes
@@ -287,6 +278,7 @@ risky job that needs several of them, start with
287
278
  | [drift-audit](recipes/drift-audit.md) | hours into a long run, after a batch, compaction or resume, before a stop rule |
288
279
  | [watcher](recipes/watcher.md) | a helper polls a PR, CI, or log for change |
289
280
  | [findings](recipes/findings.md) | any review, audit, or check reports problems: where they live, how they are triaged |
281
+ | [models](recipes/models.md) | you pick a model for a spawn or delegate call |
290
282
  | [tasks-or-calls](recipes/tasks-or-calls.md) | a recipe step spawns an agent: DAG task or delegate call |
291
283
  | [adversarial-review](recipes/adversarial-review.md) | gate each unit you dispatch before it merges (a review task per unit) |
292
284
  | [fan-out](recipes/fan-out.md) | a sweep or migration: the same change over many files or call sites |
@@ -1,13 +1,15 @@
1
1
  # Adversarial review
2
2
 
3
3
  Use when a unit of work must be checked by someone other than its
4
- author before it counts: a fix, a finding, a claim, a plan. The author
4
+ author before it counts: a unit that produces commits (a fix, a feature).
5
+ Checking a finding or claim is a delegate call
6
+ ([findings § Triage](findings.md#triage), [refute](refute.md)). The author
5
7
  grades its own work generously; a fresh agent told to refute it does
6
8
  not. Every other review-shaped recipe builds on this one.
7
9
 
8
10
  The review is a task in the DAG, not a step inside the worker's
9
- session. Its verdict, its evidence, and every gap it finds stay in the
10
- DB: each gap is a finding task ([findings](findings.md)). For a one-off
11
+ session. Its verdict, its evidence, and every finding it makes stay in the
12
+ DB: each is a finding task ([findings](findings.md)). For a one-off
11
13
  check outside any workstream, one
12
14
  [delegate call](tasks-or-calls.md#delegate-call) is enough; to review a
13
15
  PR or diff from several angles, use [review-panel](review-panel.md).
@@ -22,27 +24,29 @@ PR or diff from several angles, use [review-panel](review-panel.md).
22
24
 
23
25
  ```bash
24
26
  mu task add review_x -w <ws> -t "Review x" -i 50 -e 0.5 --blocked-by x \
25
- --note 'ACCEPTANCE: see x notes. Refute; report gaps, not style.'
27
+ --note 'ACCEPTANCE: see x notes. Refute; report findings, not style.'
26
28
  ```
27
29
 
28
30
  3. **Dispatch the work** as usual. When `x` closes, `review_x` becomes
29
31
  ready.
30
32
  4. **Spawn a fresh reviewer.** A new agent, or `--fresh` on an idle one,
31
- so it has none of the author's reasoning, on a model chosen per
32
- [Models](../SKILL.md#models-and-thinking-effort). Give it the worker's workspace path
33
+ so it has none of the author's reasoning, at the worker's tier or
34
+ higher and from another family ([models](models.md#checkers)). Give it the worker's workspace path
33
35
  and commits read-only by instruction; it edits nothing.
34
36
  5. **Claim `review_x` for the reviewer**, send the brief (below), wait.
35
37
  6. **Act on the verdict:**
36
38
  The review's state is the verdict: `CLOSED/done` for ACCEPT,
37
39
  `CLOSED/rejected` for REJECT.
38
40
  - `ACCEPT`: cherry-pick `x`'s commits and verify the merge.
39
- - `REJECT`: the reviewer recorded each gap as an `OPEN/triage` task.
40
- Add `review_x_2` and block it on every gap
41
- (`mu task block review_x_2 --by <gap>`); work downstream of `x`
42
- waits on `review_x_2`, not on the rejected review. Decide each gap
43
- as a finding ([findings § Triage](findings.md#triage)), then
44
- dispatch the accepted gaps to the original worker, whose context
45
- still holds the work. Repeat from step 4 when the gaps are closed.
41
+ - `REJECT`: the reviewer recorded each finding as an `OPEN/triage` task.
42
+ Add `review_x_2` and block it on every finding
43
+ (`mu task block review_x_2 --by <finding>`). Closing `review_x`
44
+ `--as rejected` unblocked its dependents, so re-block each task
45
+ downstream of `x` on `review_x_2`
46
+ (`mu task block <downstream> --by review_x_2`). Decide each
47
+ finding ([findings § Triage](findings.md#triage)), then
48
+ dispatch the accepted ones to the original worker, whose context
49
+ still holds the work. Repeat from step 4 when the findings are closed.
46
50
  The DAG grows; nothing is rewritten.
47
51
  7. **Cap the rounds.** After two rejections on the same unit, stop the
48
52
  loop and decide yourself: split the unit, change the criteria, or
@@ -60,24 +64,25 @@ You are reviewing task <x>. You did not write it. Your job is to find
60
64
  where it fails the acceptance criteria in `mu task notes <x>`.
61
65
 
62
66
  - Read the diff (<range>) and the criteria. Run the tests that cover it.
63
- - Report gaps against the criteria: a requirement not met, an edge case
67
+ - Report findings against the criteria: a requirement not met, an edge case
64
68
  without a test, a change outside scope, a claim the evidence does not
65
69
  support. Not style, not preferences.
66
- - Record each gap as a finding, per findings.md § Record:
67
- mu task add -w <ws> --triage -t "<severity>: <gap>" -i <n> -e <days> \
68
- --note 'FINDING: <severity> <file:line> <gap> EVIDENCE: <command + output>'
70
+ - Record each as a finding, per findings.md § Record:
71
+ mu task add -w <ws> --triage -t "<severity>: <title>" -i <n> -e <days> \
72
+ --note 'FINDING: <severity> <file:line> <what fails> EVIDENCE: <command + output>'
69
73
  - If you could not check something (tool failed, no access), say
70
74
  UNVERIFIED for it. Unverified is not a pass and not a fail.
71
- - Do not edit files.
75
+ - Your only writes are `mu task add` (findings), the verdict note, and
76
+ the close; leave the workspace as you found it.
72
77
 
73
78
  Write the verdict note (FILES/COMMANDS/FINDINGS/VERIFIED), then close
74
79
  (long reasons: a heredoc variable, brief.md § Quoting):
75
80
  ACCEPT: mu task close review_<x> --evidence "<key command>: <result>"
76
81
  REJECT: mu task close review_<x> --as rejected \
77
- --why "<n> gaps: <id> (<why it fails, one clause>), ..."
82
+ --why "<n> findings: <id> (<why it fails, one clause>), ..."
78
83
  ```
79
84
 
80
- mu adds each named gap's title to the REJECTED note.
85
+ mu adds each named finding's title to the REJECTED note.
81
86
 
82
87
  **Closing a review yourself** (you fixed a finding, or accept without a
83
88
  fresh reviewer): write the reviewer's note plus `COMMIT: <sha> fixes
@@ -93,7 +98,7 @@ by orchestrator`.
93
98
  reviewer ran. A review with no evidence is a
94
99
  rejected review: re-send it.
95
100
  - **Reviewers drift into fixing.** A reviewer that edits the code is now
96
- an author nobody reviews. The fix belongs to the gap tasks.
101
+ an author nobody reviews. The fix belongs to the finding tasks.
97
102
  - **Review is not merge verification.** An accepted unit can still
98
103
  break once merged with moved main. Verify the merge as in
99
104
  [orchestrator-loop](orchestrator-loop.md#merging).
@@ -77,5 +77,6 @@ mu task close <id> -w <ws> --evidence "$v"
77
77
  Chain batched adds with `&&`, then `mu task list`, so one
78
78
  quoting failure cannot half-apply the batch unseen.
79
79
 
80
- Done when a worker with no other context could finish the task from
81
- the brief and the notes it points at, and could tell when it is done.
80
+ Done when the brief has GOAL, FILES, DONE WHEN, VERIFY and the
81
+ final-action block, every shared fact is a `Read:` pointer, and the task
82
+ holds a refuter verdict or a `REFUTE-EXEMPT:` note.
@@ -44,7 +44,7 @@ return wait.output;
44
44
 
45
45
  Size the worker list from the ceiling on the umbrella
46
46
  ([orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency)),
47
- one per ready track. Merge and verify outside the script
47
+ one per ready task. Merge and verify outside the script
48
48
  ([orchestrator-loop § Merging](orchestrator-loop.md#merging)). Check
49
49
  field names against `--json` output; the script is a shape, not an API.
50
50
 
@@ -54,8 +54,8 @@ field names against `--json` output; the script is a shape, not an API.
54
54
  answers arrive after the script, as follow-up messages: the script
55
55
  gains nothing over issuing the calls in one turn. Use it from a script
56
56
  only when `codemode.mode` is `only` and the tool is not offered
57
- directly. Check `Promise.allSettled` results for rejections: past the
58
- cap, `mu_delegate` refuses.
57
+ directly. Check `Promise.allSettled` results for rejections; the cap is in
58
+ [orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency).
59
59
 
60
60
  To get the verdicts back as one table instead of one message each, use
61
61
  the `scratch` form through `tools.bash`:
@@ -63,8 +63,9 @@ the `scratch` form through `tools.bash`:
63
63
  ```js
64
64
  // @options: {"timeout_ms": 1800000}
65
65
  const ws = "audit";
66
- const findings = ["f_auth_put", "f_sql_order"]; // finding task ids, at most the cap per script
66
+ const findings = ["f_auth_put", "f_sql_order"]; // finding task ids, within the cap
67
67
  const sh = async (c) => (await tools.bash({ command: c })).output;
68
+ const dir = `${(await sh("echo $HOME")).trim()}/.local/state/mu`;
68
69
  const json = (s) => { try { return JSON.parse(s); } catch { return {}; } };
69
70
  const el = (ms) => { const t = Math.round(ms / 1000); return t < 60 ? `${t}s` : `${Math.floor(t / 60)}m ${String(t % 60).padStart(2, "0")}s`; };
70
71
  const rows = await Promise.all(findings.map(async (id, i) => {
@@ -77,7 +78,8 @@ const rows = await Promise.all(findings.map(async (id, i) => {
77
78
  const note = w.outcome !== "done" ? `REFUTER ${i + 1}: no verdict (${w.outcome ?? "no result"})`
78
79
  : `REFUTER ${i + 1} (${a}, ${el(Date.now() - t0)}):\n` + (at < 0 ? `NO VERDICT LINE: ${(w.lastText ?? "").slice(-1500)}`
79
80
  : [lines[at], ...lines.slice(at + 1).filter((l) => /^[\s>*_`-]*EVIDENCE:/.test(l))].join("\n"));
80
- await sh(`mu task note ${id} -w ${ws} - <<'MU_EOF'\n${note}\nMU_EOF`);
81
+ await tools.write({ path: `${dir}/note-${a}.txt`, content: note }); // answer text never touches a shell
82
+ await sh(`mu task note ${id} -w ${ws} - < ${dir}/note-${a}.txt && rm ${dir}/note-${a}.txt`);
81
83
  if (w.outcome === "done") await sh(`mu agent close ${a} -w scratch`);
82
84
  return `${id}\t${note.split("\n")[1] ?? note}`;
83
85
  }));
@@ -87,7 +89,8 @@ return rows.join("\n");
87
89
  What the tool did for you, the script now owns:
88
90
 
89
91
  - **The cap.** `MU_DELEGATE_MAX` does not apply to bash spawns: keep
90
- each script's list at or under it.
92
+ each script's list within
93
+ [orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency).
91
94
  - **Cleanup.** Close each scratch pane; a timed-out one stays, readable
92
95
  with `mu agent read <a> -w scratch`.
93
96
  - **Recording.** The script writes each `REFUTER` note in `record`'s
@@ -31,7 +31,8 @@ answer rests on is an `OPEN/triage` task, decided like a finding
31
31
  ```
32
32
 
33
33
  A claim without a source and a quote is not a claim. Searchers can
34
- run on a cheap model.
34
+ run cheap (hosted, not local: [models](models.md#local-models-are-a-last-resort));
35
+ the checkers in step 4 run mid or higher.
35
36
  3. **Dedupe claims**: merge the same fact from several sources (keep
36
37
  every source), and flag claims that contradict each other. In
37
38
  workstream mode, each surviving claim becomes an `OPEN/triage` task
@@ -35,13 +35,14 @@ or close you compare against is often older than it.
35
35
  IN_PROGRESS note, and each merged fix its task's findings depend on:
36
36
  git merge-base --is-ancestor <fix> <pinned>. Exit 1 = pin is stale.
37
37
  3. Closed-task notes: notes added after the task's last task.close op,
38
- minus the `CLOSE:` or `<SUBSTATE>:` note the close verb itself writes
39
- as the very next op (seq + 1); any other note counts, whatever its
40
- prefix. Report each of the top 5 by count as its own finding with its count,
38
+ minus those the close verb writes in its own transaction
39
+ (`--evidence`, `--why`: timestamp within 50ms of the close op); any
40
+ other note counts, whatever its prefix. Report each of the top 5 by
41
+ count as its own finding with its count,
41
42
  even when the notes look routine. A late note that reports the
42
43
  closed bug again usually ran on a build without the closing fix:
43
44
  check its sha with git merge-base --is-ancestor <fix> <sha>.
44
- mu sql "select t.local_id name, count(*) late from tasks t join workstreams w on w.id=t.workstream_id join task_notes n on n.task_id=t.id join (select key, max(seq) seq, max(created_at) at from ops where intent='task.close' and entity='task' group by key) c on c.key='<ws>/'||t.local_id where w.name='<ws>' and t.status='CLOSED' and n.created_at > c.at and not exists (select 1 from ops x where x.seq=c.seq+1 and x.entity='note' and x.key=c.key||'#'||n.id and (n.content like 'CLOSE: %' or n.content like upper(t.substate)||': %')) group by t.local_id order by late desc"
45
+ mu sql "select t.local_id name, count(*) late from tasks t join workstreams w on w.id=t.workstream_id join task_notes n on n.task_id=t.id join (select key, max(created_at) at from ops where intent='task.close' and entity='task' group by key) c on c.key='<ws>/'||t.local_id where w.name='<ws>' and t.status='CLOSED' and (julianday(n.created_at)-julianday(c.at))*86400 > 0.05 group by t.local_id order by late desc"
45
46
  4. Thin decisions: an ACCEPT/REJECTED/CLOSE/SUPERSEDED note under 40
46
47
  chars; a refuter tally with no REFUTER or VERDICT note; a review the
47
48
  orchestrator closed with no FILES/COMMANDS note and no commit.
@@ -9,7 +9,9 @@ some and calls the job done; one task per unit cannot.
9
9
  1. **Enumerate first.** A scout (a [delegate call](tasks-or-calls.md#delegate-call)) lists the units and
10
10
  writes them to the umbrella's note, one per line. The list is done
11
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.
12
+ not when it looks complete. Record the command and the count. The
13
+ scout runs cheap; the units run mid, or strong when each is a
14
+ judgement call ([models](models.md#roles)).
13
15
  2. **One task per unit**, blocked into an umbrella:
14
16
 
15
17
  ```bash
@@ -23,13 +25,13 @@ some and calls the job done; one task per unit cannot.
23
25
  only checks (no commits) makes each unit a delegate call instead
24
26
  ([tasks-or-calls](tasks-or-calls.md)).
25
27
  3. **Cap concurrency** ([orchestrator-loop § Concurrency](orchestrator-loop.md#concurrency)).
26
- Spawn at most one agent per ready track. Tell workers to avoid
28
+ One agent per ready unit, up to the ceiling. Tell workers to avoid
27
29
  repo-wide commands so more can run.
28
30
  4. **Pipeline.** Dispatch, wait `--first`, merge
29
31
  ([orchestrator-loop § Merging](orchestrator-loop.md#merging)), dispatch
30
32
  the next unit to the freed worker with `--fresh`. With `codemode`, a
31
33
  [driver](codemode-driver.md) can dispatch each batch. Units that touch the same files
32
- go on one track (see [waves](waves.md)).
34
+ are chained with `block` (see [waves](waves.md)).
33
35
  5. **Review per unit** when a wrong unit is costly: add a review task
34
36
  per unit ([adversarial-review](adversarial-review.md)).
35
37
  6. **Synthesize** when the output is a report, not commits: one
@@ -94,8 +94,10 @@ across reviewers and creates one task per real problem.
94
94
  | could not check | stays in triage, with an `UNVERIFIED: <why>` note | |
95
95
 
96
96
  4. **Group** accepted findings that touch the same files into one fix
97
- task when separate workers would collide; close the grouped findings
98
- `--as superseded --why "fixed in <fix-task>"`.
97
+ task when separate workers would collide. Block the umbrella on the
98
+ fix task (`mu task block <umbrella> --by <fix-task>`), then close the
99
+ grouped findings `--as superseded --why "fixed in <fix-task>"`:
100
+ superseding unblocks the umbrella.
99
101
 
100
102
  Done when `mu task list --substate triage -w <ws>` lists only findings
101
103
  with an `UNVERIFIED` note, and each of those is reported to the human.
@@ -105,7 +107,9 @@ with an `UNVERIFIED` note, and each of those is reported to the human.
105
107
  Accepted findings are ordinary tasks: dispatch them, review the fix
106
108
  ([adversarial-review](adversarial-review.md)), merge. The umbrella
107
109
  closes with `mu task close <umbrella> --if-ready` once every finding is
108
- `CLOSED/*`. A plain `close` would succeed with findings still open.
110
+ `CLOSED/*`. A plain `close` would succeed with findings still open; an
111
+ `UNVERIFIED` finding blocks `--if-ready`, so the umbrella stays open
112
+ until the human decides it.
109
113
 
110
114
  The report is a query, not a document: `mu task list -w <ws>
111
115
  --substate rejected`, `--substate duplicate`, `--status OPEN`, and the
@@ -9,7 +9,8 @@ form independent theories; separate agents then try to kill them.
9
9
 
10
10
  1. **Write the symptom** on the umbrella: what happens, how often, the
11
11
  repro command, and what would count as fixed.
12
- 2. **One reader per evidence source** (a [delegate call](tasks-or-calls.md#delegate-call)): logs, the
12
+ 2. **One reader per evidence source** (a [delegate call](tasks-or-calls.md#delegate-call), strong tier:
13
+ root cause is judgement, [models](models.md#roles)): logs, the
13
14
  code path, recent commits, data, environment. Each sees only its
14
15
  source, so the theories do not anchor on each other. Record each
15
16
  theory as an `OPEN/triage` task blocking the umbrella, decided like