@mu-crew/mu 4.2.1 → 4.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fold.ts","../src/apply.ts","../src/segment-manifest.ts","../src/sha256-resumable.ts","../src/sync-dir-guard.ts","../src/segments.ts","../src/segment-resume.ts","../src/task-auto.ts","../src/task-brief.ts","../src/auto-attempt.ts","../src/dag.ts","../src/log-render.ts","../src/output-contract.ts","../src/human-needed.ts","../src/next-hints.ts","../src/sync.ts","../src/wait-callers.ts","../src/agent-output.ts","../src/cli/tasks/records.ts","../src/cli/page-records.ts","../src/cli/log-records.ts"],"sourcesContent":["// mu — the FOLD: what the ops log says a portable row is.\n//\n// One pure function per kind of row, from the ops of ONE natural key (plus\n// the tombstone horizon that covers it) to the row's state. Nothing here\n// touches a database. Both write paths call these through src/apply.ts:\n// `mu rebuild` folds every key once, and a live apply (ingest, `--from`,\n// an SDK caller) folds the keys an op touches. So live state for a key is,\n// by construction, rebuild-of-that-key, whatever order its ops arrived in.\n//\n// THE RULES (docs/architecture/sync.md § Order-independent apply)\n// horizon a put older than the newest `del` of its own key or of an\n// ancestor (task -> workstream) is dead; the `del` wiped it.\n// task per-field LWW by HLC over the live puts. A field absent from\n// every live put takes its default, and a default that is a\n// timestamp is the ISO time of the HLC that began the life,\n// never \"now\": the same log folds to the same row on any\n// machine, at any time.\n// kind/wave per-field LWW like the rest; kind is one of TASK_KINDS (an\n// unknown value is dropped, default 'work'), wave is nullable.\n// substate not LWW: the newest live op that writes one, resolved\n// against the folded status (a concurrent close and park fall\n// back to the status default).\n// workstream exists from its first live put (its own, or a task's under\n// it: a task put creates its parent) until the next `del`.\n// note grow-only set by content identity (author, content,\n// created_at). A `del` kills the puts of that identity older\n// than itself; a later put brings it back.\n// edge LWW element: present iff a put is newer than its own `del`\n// and both endpoints' horizons; created_at is the first live\n// put's.\n//\n// A payload is decoded leniently: a field with a value the schema would\n// refuse (CHECK, NOT NULL) or of an unsupported type is dropped like an\n// unknown field. A RAISE during ingest would roll back the segment and\n// stall sync forever; the log is accepted as it is.\n\nimport {\n DEFAULT_EFFORT_DAYS,\n DEFAULT_IMPACT,\n NOTE_KINDS,\n TASK_KINDS,\n type TaskKind,\n} from \"./db.js\";\nimport { compareHlc, parseHlc } from \"./hlc.js\";\nimport {\n DEFAULT_SUBSTATE,\n isTaskStatus,\n mapLegacyStatus,\n resolvePair,\n type TaskStatus,\n} from \"./tasks/status.js\";\n\n/** The part of an op a fold reads. */\nexport interface LogOp {\n hlc: string;\n op: \"put\" | \"del\";\n /** The natural key; a note fold reads it to pair a `del` with its put. */\n key: string;\n payload: string;\n}\n\ntype Scalar = string | number | null;\n\n/** The scalar members of a payload; anything else (nested value, bad JSON,\n * a non-object) is dropped. Booleans become 0/1 like SQLite stores them. */\nfunction fieldsOf(payload: string): Record<string, Scalar> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch {\n return {};\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n const out: Record<string, Scalar> = {};\n for (const [field, value] of Object.entries(parsed)) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\") {\n out[field] = value;\n } else if (typeof value === \"boolean\") {\n out[field] = value ? 1 : 0;\n }\n }\n return out;\n}\n\n/** The ISO time of an HLC's wall clock: the deterministic stand-in for\n * \"now\" wherever a row's timestamp is not in any op. */\nexport function isoOfHlc(hlc: string): string {\n try {\n return new Date(parseHlc(hlc).wallMs).toISOString();\n } catch {\n return new Date(0).toISOString();\n }\n}\n\nconst ascending = (ops: readonly LogOp[]): LogOp[] =>\n [...ops].sort((a, b) => compareHlc(a.hlc, b.hlc));\n\n/** The newest `del` among `ops`, or null. */\nexport function newestDel(ops: readonly LogOp[]): string | null {\n let newest: string | null = null;\n for (const o of ops) {\n if (o.op === \"del\" && (newest === null || compareHlc(o.hlc, newest) > 0)) newest = o.hlc;\n }\n return newest;\n}\n\n/** The later of two horizons; null is \"none\". */\nexport function laterHlc(a: string | null, b: string | null): string | null {\n if (a === null) return b;\n if (b === null) return a;\n return compareHlc(a, b) >= 0 ? a : b;\n}\n\n/** Puts strictly newer than `horizon`, oldest first. */\nfunction livePuts(ops: readonly LogOp[], horizon: string | null): LogOp[] {\n return ascending(ops).filter(\n (o) => o.op === \"put\" && (horizon === null || compareHlc(o.hlc, horizon) > 0),\n );\n}\n\n/** The newest value of `field` that `accept` takes, in HLC order. */\nfunction lww<T>(\n puts: readonly { fields: Record<string, Scalar> }[],\n field: string,\n accept: (v: Scalar) => T | undefined,\n): { value: T } | undefined {\n let found: { value: T } | undefined;\n for (const p of puts) {\n if (!(field in p.fields)) continue;\n const v = accept(p.fields[field] ?? null);\n if (v !== undefined) found = { value: v };\n }\n return found;\n}\n\nconst str = (v: Scalar): string | undefined => (typeof v === \"string\" ? v : undefined);\nconst strOrNull = (v: Scalar): string | null | undefined =>\n v === null || typeof v === \"string\" ? v : undefined;\n\n// ─── workstream ───────────────────────────────────────────────────────\n\nexport interface WorkstreamState {\n createdAt: string;\n tornDownAt: string | null;\n}\n\n/**\n * The workstream's row, or null when it does not exist. `ops` are its own\n * puts and dels; `firstTaskPutAfter(h)` is the oldest put of any task\n * under it newer than `h` (null: none), because a task put creates the\n * parent. Its life starts at the oldest of those and its own first live\n * put, and a restart after a `del` forgets the dead life's fields.\n */\nexport function foldWorkstream(\n ops: readonly LogOp[],\n firstTaskPutAfter: (after: string | null) => string | null,\n): WorkstreamState | null {\n const horizon = newestDel(ops);\n const puts = livePuts(ops, horizon).map((o) => ({ hlc: o.hlc, fields: fieldsOf(o.payload) }));\n const created = lww(puts, \"created_at\", str);\n const torn = lww(puts, \"torn_down_at\", strOrNull);\n // The scan for a task put is the expensive input, so it runs only when\n // the answer needs it: existence with no live put of its own, or the\n // creation default with no created_at in any of them.\n const own = puts[0]?.hlc ?? null;\n if (own === null && firstTaskPutAfter(horizon) === null) return null;\n let createdAt = created?.value;\n if (createdAt === undefined) {\n const task = firstTaskPutAfter(horizon);\n const start = own === null ? task : task === null ? own : earlierHlc(own, task);\n createdAt = isoOfHlc(start ?? \"\");\n }\n return { createdAt, tornDownAt: torn?.value ?? null };\n}\n\nfunction earlierHlc(a: string, b: string): string {\n return compareHlc(a, b) <= 0 ? a : b;\n}\n\n// ─── task ─────────────────────────────────────────────────────────────\n\nexport interface TaskState {\n title: string;\n status: TaskStatus;\n substate: string;\n impact: number;\n effortDays: number;\n scored: number;\n dispatchHost: string | null;\n kind: TaskKind;\n wave: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** The substate a payload writes, or null if it writes none.\n *\n * - A legacy status writes the substate it maps to, overriding any\n * substate beside it (mirrors resolvePair).\n * - A known status with no substate writes the status's default. Capture\n * records only changed columns and the substate sets are disjoint, so a\n * v11 status change always carries its substate: a status-only op comes\n * from a v10 peer or pre-v11 history, where every status had exactly\n * its default.\n * - Otherwise the explicit substate, or null. */\nfunction carriedSubstate(fields: Record<string, Scalar>): string | null {\n const { status, substate } = fields;\n if (typeof status === \"string\") {\n const legacy = mapLegacyStatus(status);\n if (legacy) return legacy.substate;\n if (typeof substate !== \"string\" && isTaskStatus(status)) return DEFAULT_SUBSTATE[status];\n }\n return typeof substate === \"string\" ? substate : null;\n}\n\n/** A status this build knows, a legacy one mapped onto its pair's status. */\nfunction knownStatus(v: Scalar): TaskStatus | undefined {\n if (typeof v !== \"string\") return undefined;\n const legacy = mapLegacyStatus(v);\n if (legacy) return legacy.status;\n return isTaskStatus(v) ? v : undefined;\n}\n\nconst impactOf = (v: Scalar): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) && v >= 1 && v <= 100 ? v : undefined;\nconst effortOf = (v: Scalar): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : undefined;\nconst scoredOf = (v: Scalar): number | undefined => (v === 0 || v === 1 ? v : undefined);\n/** A task kind this build knows; any other value is dropped like an\n * unknown field, so a newer peer's kind never trips the CHECK in ingest. */\nconst kindOf = (v: Scalar): TaskKind | undefined =>\n typeof v === \"string\" && (TASK_KINDS as readonly string[]).includes(v)\n ? (v as TaskKind)\n : undefined;\n\n/**\n * The task's row, or null when it is dead (no put newer than `horizon`,\n * the newest `del` of the task or of its workstream).\n */\nexport function foldTask(\n ops: readonly LogOp[],\n horizon: string | null,\n localId: string,\n): TaskState | null {\n const puts = livePuts(ops, horizon).map((o) => ({ hlc: o.hlc, fields: fieldsOf(o.payload) }));\n const began = puts[0]?.hlc;\n if (began === undefined) return null;\n const born = isoOfHlc(began);\n const status = lww(puts, \"status\", knownStatus)?.value ?? \"OPEN\";\n let winner: string | null = null;\n for (const p of puts) winner = carriedSubstate(p.fields) ?? winner;\n const pair = resolvePair(status, winner ?? DEFAULT_SUBSTATE[status]);\n return {\n title: lww(puts, \"title\", str)?.value ?? localId,\n status,\n substate: pair?.substate ?? DEFAULT_SUBSTATE[status],\n impact: lww(puts, \"impact\", impactOf)?.value ?? DEFAULT_IMPACT,\n effortDays: lww(puts, \"effort_days\", effortOf)?.value ?? DEFAULT_EFFORT_DAYS,\n scored: lww(puts, \"scored\", scoredOf)?.value ?? 0,\n dispatchHost: lww(puts, \"dispatch_host\", strOrNull)?.value ?? null,\n kind: lww(puts, \"kind\", kindOf)?.value ?? \"work\",\n wave: lww(puts, \"wave\", strOrNull)?.value ?? null,\n createdAt: lww(puts, \"created_at\", str)?.value ?? born,\n updatedAt: lww(puts, \"updated_at\", str)?.value ?? born,\n };\n}\n\n// ─── note ─────────────────────────────────────────────────────────────\n\nexport interface NoteState {\n author: string | null;\n content: string;\n createdAt: string;\n kind: string;\n}\n\n/** A note's identity: the text is not unique (a machine repeats its lines),\n * so created_at is part of it. The origin id in the key is not: it names\n * the row on its origin machine only. */\nexport function noteIdentity(author: string | null, content: string, createdAt: string): string {\n return JSON.stringify([author ?? \"\", content, createdAt]);\n}\n\ninterface NotePut extends NoteState {\n hlc: string;\n key: string;\n}\n\nfunction notePut(o: LogOp): NotePut {\n const f = fieldsOf(o.payload);\n const author =\n typeof f.author === \"string\" ? f.author : f.author == null ? null : String(f.author);\n const sentKind = f.kind;\n return {\n hlc: o.hlc,\n key: o.key,\n author,\n content: f.content == null ? \"\" : String(f.content),\n createdAt: typeof f.created_at === \"string\" ? f.created_at : isoOfHlc(o.hlc),\n kind: (NOTE_KINDS as readonly unknown[]).includes(sentKind) ? (sentKind as string) : \"note\",\n };\n}\n\n/**\n * The notes of one task, keyed by identity. `ops` are every note op under\n * the task. A `del` names its note either by carrying the identity itself\n * (capture writes the full row when no put shares its key) or, bare, by\n * the newest put under its key that is older than it; created_at may be\n * absent from a hand-written one, which then matches every copy of the\n * text. `kind` is set once: the first put's.\n */\nexport function foldNotes(ops: readonly LogOp[], horizon: string | null): Map<string, NoteState> {\n const sorted = ascending(ops);\n const puts = sorted.filter((o) => o.op === \"put\").map(notePut);\n const kills: { hlc: string; author: string | null; content: string; createdAt: string | null }[] =\n [];\n for (const d of sorted) {\n if (d.op !== \"del\") continue;\n const f = fieldsOf(d.payload);\n if (f.content != null) {\n kills.push({\n hlc: d.hlc,\n author: f.author == null ? null : String(f.author),\n content: String(f.content),\n createdAt: typeof f.created_at === \"string\" ? f.created_at : null,\n });\n continue;\n }\n const src = puts.filter((p) => p.key === d.key && compareHlc(p.hlc, d.hlc) < 0).pop();\n if (src)\n kills.push({\n hlc: d.hlc,\n author: src.author,\n content: src.content,\n createdAt: src.createdAt,\n });\n }\n const out = new Map<string, NoteState>();\n for (const p of puts) {\n if (horizon !== null && compareHlc(p.hlc, horizon) <= 0) continue;\n const killed = kills.some(\n (k) =>\n compareHlc(k.hlc, p.hlc) > 0 &&\n k.content === p.content &&\n (k.author ?? \"\") === (p.author ?? \"\") &&\n (k.createdAt === null || k.createdAt === p.createdAt),\n );\n if (killed) continue;\n const id = noteIdentity(p.author, p.content, p.createdAt);\n if (!out.has(id))\n out.set(id, { author: p.author, content: p.content, createdAt: p.createdAt, kind: p.kind });\n }\n return out;\n}\n\n// ─── edge ─────────────────────────────────────────────────────────────\n\n/**\n * The edge's created_at, or null when it is absent: no put newer than its\n * own `del` and than the horizons of both endpoints.\n */\nexport function foldEdge(\n ops: readonly LogOp[],\n endpointHorizons: readonly (string | null)[],\n): { createdAt: string } | null {\n let horizon = newestDel(ops);\n for (const h of endpointHorizons) horizon = laterHlc(horizon, h);\n const first = livePuts(ops, horizon)[0];\n if (first === undefined) return null;\n const stamped = fieldsOf(first.payload).created_at;\n return { createdAt: typeof stamped === \"string\" ? stamped : isoOfHlc(first.hlc) };\n}\n","// mu — the APPLY path: how an op lands in the portable tables.\n//\n// The counterpart to src/capture.ts. Capture answers \"a row changed, what\n// op records it\"; this answers \"here is an op, local or from a peer, what\n// do the tables look like afterwards\". It knows nothing about segments,\n// files or watermarks.\n//\n// LIVE STATE IS REBUILD-OF-THAT-KEY\n// ---------------------------------\n// The ops log is the canonical record and the tables are a projection of\n// it. src/fold.ts defines the projection as a PURE function: the ops of\n// one natural key (plus the tombstone horizon covering it) in, the row's\n// state out. This module has no merge rule of its own. `applyOp` finds the\n// keys the op can change and re-folds each from ALL the ops the log knows\n// for it, then makes the table row equal the fold. `mu rebuild` replays\n// the log through the same call. So live state equals an HLC-order\n// rebuild for EVERY arrival order of the same op set, by construction:\n// there is no per-path comparison (put vs del, child vs parent) left to\n// get wrong, and no \"deferred\" op to repair later.\n//\n// WHAT AN OP CAN CHANGE\n// workstream put its own row.\n// workstream del its row, and every task, note and edge beneath it\n// (the horizon moved).\n// task put the task row and its workstream (a task put creates\n// its parent); when the task came into or went out of\n// existence, also its notes and the edges touching it.\n// task del the same, always.\n// note put / del that task's notes.\n// edge put / del that edge.\n//\n// PROVENANCE IS THE LOG\n// ---------------------\n// Every op carries its HLC and names the fields it touched, so \"the HLC\n// that last wrote field F of key K\" is a query over K's handful of ops\n// (`idx_ops_entity_key`), not a fact needing a side table. The op being\n// applied is passed in beside the log's rows, so record-then-apply and\n// apply-then-record fold identically, and re-applying an op is a no-op.\n//\n// TOMBSTONES ARE JUST OPS. There is no tombstone table: a `del` is an op\n// with an HLC, and a put older than the newest `del` covering its key is\n// dead whatever the arrival order.\n\nimport {\n type Db,\n MACHINE_LOCAL_ENTITIES,\n prepareCached,\n SYNCED_ENTITIES,\n type SyncedEntity,\n} from \"./db.js\";\nimport {\n foldEdge,\n foldNotes,\n foldTask,\n foldWorkstream,\n type LogOp,\n laterHlc,\n newestDel,\n noteIdentity,\n} from \"./fold.js\";\nimport { compareHlc } from \"./hlc.js\";\nimport { withCaptureSuppressed } from \"./op-context.js\";\n\n/** An op as applied. Mirrors the `ops` row shape, minus the local-only\n * `seq` (meaningless on a peer) and the advisory `created_at`. */\nexport interface Op {\n /** The ordering key. See docs/VOCABULARY.md § HLC. */\n hlc: string;\n /** Which peer minted it. Half of the (machine_id, hlc) identity. */\n machineId: string;\n /** One user-visible action (the op group). */\n groupId: string;\n /** Free text: agent name, \"user\", \"system\". */\n actor?: string | null;\n /** Semantic label, e.g. \"task.close\". */\n intent?: string | null;\n /** Which kind of thing this op addresses. */\n entity: string;\n /** The NATURAL key. Never a surrogate id. */\n key: string;\n /** 'put' = semantic partial update, 'del' = tombstone. */\n op: \"put\" | \"del\";\n /** JSON object of ONLY the fields this op touched. */\n payload: string;\n}\n\n/** Thrown when an op names an entity this build KNOWS is machine-local\n * (see `MACHINE_LOCAL_ENTITIES`). Loud by design: a peer shipping a\n * pane id or an absolute path is a real bug we want reported.\n *\n * NOT thrown for an entity we merely do not recognise. That is a\n * reader-behind-writer vocabulary skew in a mixed fleet, and treating\n * it as a defect froze one peer's watermark permanently — see\n * `MACHINE_LOCAL_ENTITIES` in src/db.ts for the incident. */\nexport class OpEntityNotSyncedError extends Error {\n constructor(readonly entity: string) {\n super(\n `op entity ${JSON.stringify(entity)} is machine-local and must never arrive from a peer ` +\n `(synced entities: ${SYNCED_ENTITIES.join(\", \")})`,\n );\n this.name = \"OpEntityNotSyncedError\";\n }\n}\n\n/** Thrown when an op's natural key does not parse for its entity. */\nexport class OpKeyMalformedError extends Error {\n constructor(\n readonly entity: string,\n readonly key: string,\n ) {\n super(`malformed ${entity} key: ${JSON.stringify(key)}`);\n this.name = \"OpKeyMalformedError\";\n }\n}\n\n/** What `applyOp` did, so callers (and tests) can assert on outcomes\n * rather than re-querying. */\nexport interface ApplyResult {\n /** True iff the DB changed. False for a dead, superseded or duplicate\n * op: legitimate and non-exceptional. */\n changed: boolean;\n /** The columns of a task or workstream row the op changed. */\n appliedFields: string[];\n}\n\nfunction isSyncedEntity(entity: string): entity is SyncedEntity {\n return (SYNCED_ENTITIES as readonly string[]).includes(entity);\n}\n\n/** Entities this build knows must never travel. Distinct from \"unknown\":\n * only these are a defect. */\nfunction isKnownMachineLocalEntity(entity: string): boolean {\n return (MACHINE_LOCAL_ENTITIES as readonly string[]).includes(entity);\n}\n\n// ─── Natural key parsing ──────────────────────────────────────────────\n//\n// The inverse of src/capture.ts's key builders. Kept here rather than\n// shared with capture because capture composes keys in SQL and this\n// decomposes them in TS; a \"shared\" helper would be two functions in one\n// file pretending to be one thing.\n\n/** `<workstream>/<local_id>` -> its parts. Task ids match\n * `[a-z][a-z0-9_-]*`, so they never contain '/', making the FIRST '/'\n * the unambiguous separator. */\nfunction parseTaskKey(key: string): { workstream: string; localId: string } {\n const slash = key.indexOf(\"/\");\n if (slash <= 0 || slash === key.length - 1) throw new OpKeyMalformedError(\"task\", key);\n const workstream = key.slice(0, slash);\n const localId = key.slice(slash + 1);\n if (workstream.length === 0 || localId.length === 0) {\n throw new OpKeyMalformedError(\"task\", key);\n }\n return { workstream, localId };\n}\n\n/** `<task-key>#<origin-id>` -> the task key it hangs off. Task ids\n * cannot contain '#', so the LAST '#' separates. The origin id is\n * validated as present (a key without one is malformed) but not\n * returned: it identifies the note on its ORIGIN machine only, and\n * `syncNotes` uses content identity instead. See its comment. */\nfunction parseNoteKey(key: string): { taskKey: string } {\n const hash = key.lastIndexOf(\"#\");\n if (hash <= 0 || hash === key.length - 1) throw new OpKeyMalformedError(\"note\", key);\n return { taskKey: key.slice(0, hash) };\n}\n\n/** `<blocker>-><blocked>` -> its parts. Task ids MAY end in '-', so\n * `demo/a-->demo/b` is a valid key for blocker `demo/a-`; splitting on\n * the FIRST '->' recovers that correctly, whereas a naive split('->')\n * would produce three fragments. */\nfunction parseEdgeKey(key: string): { blocker: string; blocked: string } {\n const arrow = key.indexOf(\"->\");\n if (arrow <= 0) throw new OpKeyMalformedError(\"edge\", key);\n const blocker = key.slice(0, arrow);\n const blocked = key.slice(arrow + 2);\n if (blocker.length === 0 || blocked.length === 0) throw new OpKeyMalformedError(\"edge\", key);\n return { blocker, blocked };\n}\n\n// ─── The log, as the folds read it ────────────────────────────────────\n\n/** The smallest string above every string starting with `p`. */\nconst hi = (p: string): string =>\n `${p.slice(0, -1)}${String.fromCharCode(p.charCodeAt(p.length - 1) + 1)}`;\n\ninterface LogRow {\n hlc: string;\n op: \"put\" | \"del\";\n key: string;\n payload: string;\n}\n\n/**\n * Read access to the ops log, plus the op being applied (which the caller\n * may not have recorded yet). Every query returns the union, deduplicated\n * by HLC (an HLC embeds its machine id, so it names one op).\n */\nclass Log {\n private readonly pending: LogRow | undefined;\n private readonly pendingEntity: string;\n\n constructor(\n private readonly db: Db,\n op?: Op,\n ) {\n this.pending = op && { hlc: op.hlc, op: op.op, key: op.key, payload: op.payload };\n this.pendingEntity = op?.entity ?? \"\";\n }\n\n private withPending(entity: string, rows: LogRow[], inScope: (key: string) => boolean): LogRow[] {\n const p = this.pending;\n if (p === undefined || entity !== this.pendingEntity || !inScope(p.key)) return rows;\n return rows.some((r) => r.hlc === p.hlc) ? rows : [...rows, p];\n }\n\n /** The ops of one natural key. */\n ofKey(entity: string, key: string): LogOp[] {\n const rows = prepareCached(\n this.db,\n \"SELECT hlc, op, key, payload FROM ops WHERE entity = ? AND key = ?\",\n ).all(entity, key) as LogRow[];\n return this.withPending(entity, rows, (k) => k === key);\n }\n\n /** The ops of every key in [lo, hi), grouped by key. */\n range(entity: string, lo: string, hiKey: string): Map<string, LogOp[]> {\n const rows = this.withPending(\n entity,\n prepareCached(\n this.db,\n \"SELECT hlc, op, key, payload FROM ops WHERE entity = ? AND key >= ? AND key < ?\",\n ).all(entity, lo, hiKey) as LogRow[],\n (k) => k >= lo && k < hiKey,\n );\n const out = new Map<string, LogOp[]>();\n for (const r of rows) {\n const list = out.get(r.key);\n if (list) list.push(r);\n else out.set(r.key, [r]);\n }\n return out;\n }\n\n /** The oldest task put under workstream `ws` newer than `after`. */\n firstTaskPutAfter(ws: string, after: string | null): string | null {\n const lo = `${ws}/`;\n const row = prepareCached(\n this.db,\n `SELECT MIN(hlc) AS hlc FROM ops\n WHERE entity = 'task' AND op = 'put' AND key >= @lo AND key < @hi\n AND (@after IS NULL OR hlc > @after)`,\n ).get({ lo, hi: hi(lo), after }) as { hlc: string | null };\n const p = this.pending;\n let best = row.hlc;\n if (\n p !== undefined &&\n this.pendingEntity === \"task\" &&\n p.op === \"put\" &&\n p.key >= lo &&\n p.key < hi(lo) &&\n (after === null || p.hlc > after)\n ) {\n best = best === null || p.hlc < best ? p.hlc : best;\n }\n return best;\n }\n\n /** Edge keys naming a task in `scope`: a workstream (`name/`) or one task. */\n edgeKeysTouching(scope: { workstream: string } | { task: string }): string[] {\n const candidates =\n \"workstream\" in scope\n ? prepareCached(\n this.db,\n `SELECT DISTINCT key FROM ops\n WHERE entity = 'edge' AND (instr(key, @to) > 0 OR (key >= @lo AND key < @hi))`,\n ).all({\n to: `->${scope.workstream}/`,\n lo: `${scope.workstream}/`,\n hi: hi(`${scope.workstream}/`),\n })\n : prepareCached(\n this.db,\n `SELECT DISTINCT key FROM ops\n WHERE entity = 'edge'\n AND ((key >= @lo AND key < @hi) OR substr(key, -length(@to)) = @to)`,\n ).all({ to: `->${scope.task}`, lo: `${scope.task}->`, hi: hi(`${scope.task}->`) });\n const keys = new Set((candidates as { key: string }[]).map((r) => r.key));\n const p = this.pending;\n if (p !== undefined && this.pendingEntity === \"edge\") keys.add(p.key);\n return [...keys].filter((key) => {\n let ends: { blocker: string; blocked: string };\n try {\n ends = parseEdgeKey(key);\n } catch {\n return false;\n }\n const inScope = (t: string): boolean =>\n \"workstream\" in scope ? t.startsWith(`${scope.workstream}/`) : t === scope.task;\n return inScope(ends.blocker) || inScope(ends.blocked);\n });\n }\n}\n\n/** The newest tombstone covering a task: its own `del` or its workstream's\n * (a workstream `del` cascades every task, note and edge beneath it). */\nfunction taskHorizon(log: Log, taskKey: string): string | null {\n const { workstream } = parseTaskKey(taskKey);\n return laterHlc(\n newestDel(log.ofKey(\"task\", taskKey)),\n newestDel(log.ofKey(\"workstream\", workstream)),\n );\n}\n\n// ─── Reconcile: make a row equal its fold ─────────────────────────────\n\ntype Fields = Record<string, string | number | null>;\n\n/** The names of the fields on which `a` and `b` differ, in `a`'s order. */\nfunction differing(a: Fields, b: Fields): string[] {\n return Object.keys(a).filter((k) => a[k] !== b[k]);\n}\n\nconst workstreamId = (db: Db, name: string): number | null =>\n (\n prepareCached(db, \"SELECT id FROM workstreams WHERE name = ?\").get(name) as\n | { id: number }\n | undefined\n )?.id ?? null;\n\n/** Surrogate id for a task natural key, or null when absent. */\nfunction taskRowId(db: Db, key: string): number | null {\n const { workstream, localId } = parseTaskKey(key);\n const row = prepareCached(\n db,\n `SELECT t.id AS id FROM tasks t JOIN workstreams w ON w.id = t.workstream_id\n WHERE w.name = ? AND t.local_id = ?`,\n ).get(workstream, localId) as { id: number } | undefined;\n return row?.id ?? null;\n}\n\ninterface Reconciled {\n changed: boolean;\n fields: string[];\n}\nconst UNCHANGED: Reconciled = { changed: false, fields: [] };\n\nfunction syncWorkstream(db: Db, log: Log, name: string): Reconciled {\n const state = foldWorkstream(log.ofKey(\"workstream\", name), (after) =>\n log.firstTaskPutAfter(name, after),\n );\n const row = prepareCached(\n db,\n \"SELECT id, created_at, torn_down_at FROM workstreams WHERE name = ?\",\n ).get(name) as { id: number; created_at: string; torn_down_at: string | null } | undefined;\n if (state === null) {\n if (row === undefined) return UNCHANGED;\n // FK CASCADE removes the tasks, notes and edges beneath it, and the\n // agents (agents.workstream_id): a trigger records their remote worktrees.\n prepareCached(db, \"DELETE FROM workstreams WHERE id = ?\").run(row.id);\n return { changed: true, fields: [] };\n }\n const want: Fields = { created_at: state.createdAt, torn_down_at: state.tornDownAt };\n if (row === undefined) {\n prepareCached(\n db,\n \"INSERT INTO workstreams (name, created_at, torn_down_at) VALUES (?, ?, ?)\",\n ).run(name, state.createdAt, state.tornDownAt);\n return { changed: true, fields: Object.keys(want) };\n }\n const fields = differing(want, { created_at: row.created_at, torn_down_at: row.torn_down_at });\n if (fields.length === 0) return UNCHANGED;\n prepareCached(db, \"UPDATE workstreams SET created_at = ?, torn_down_at = ? WHERE id = ?\").run(\n state.createdAt,\n state.tornDownAt,\n row.id,\n );\n return { changed: true, fields };\n}\n\nfunction syncTask(db: Db, log: Log, key: string): Reconciled {\n const { workstream, localId } = parseTaskKey(key);\n const state = foldTask(log.ofKey(\"task\", key), taskHorizon(log, key), localId);\n const existing = prepareCached(\n db,\n `SELECT t.id, t.title, t.status, t.substate, t.impact, t.effort_days, t.scored,\n t.dispatch_host, t.kind, t.wave, t.created_at, t.updated_at\n FROM tasks t JOIN workstreams w ON w.id = t.workstream_id\n WHERE w.name = ? AND t.local_id = ?`,\n ).get(workstream, localId) as (Fields & { id: number }) | undefined;\n if (state === null) {\n if (existing === undefined) return UNCHANGED;\n prepareCached(db, \"DELETE FROM tasks WHERE id = ?\").run(existing.id);\n return { changed: true, fields: [] };\n }\n const want: Fields = {\n title: state.title,\n status: state.status,\n substate: state.substate,\n impact: state.impact,\n effort_days: state.effortDays,\n scored: state.scored,\n dispatch_host: state.dispatchHost,\n kind: state.kind,\n wave: state.wave,\n created_at: state.createdAt,\n updated_at: state.updatedAt,\n };\n if (existing === undefined) {\n const wsId = workstreamId(db, workstream);\n // The workstream fold keeps the parent of every live task alive.\n if (wsId === null) return UNCHANGED;\n prepareCached(\n db,\n `INSERT INTO tasks (workstream_id, local_id, title, status, substate, impact, effort_days,\n scored, dispatch_host, kind, wave, owner_id, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?)`,\n ).run(\n wsId,\n localId,\n state.title,\n state.status,\n state.substate,\n state.impact,\n state.effortDays,\n state.scored,\n state.dispatchHost,\n state.kind,\n state.wave,\n state.createdAt,\n state.updatedAt,\n );\n return { changed: true, fields: Object.keys(want) };\n }\n const fields = differing(want, existing);\n if (fields.length === 0) return UNCHANGED;\n prepareCached(\n db,\n `UPDATE tasks SET title = ?, status = ?, substate = ?, impact = ?, effort_days = ?,\n scored = ?, dispatch_host = ?, kind = ?, wave = ?, created_at = ?, updated_at = ?\n WHERE id = ?`,\n ).run(\n state.title,\n state.status,\n state.substate,\n state.impact,\n state.effortDays,\n state.scored,\n state.dispatchHost,\n state.kind,\n state.wave,\n state.createdAt,\n state.updatedAt,\n existing.id,\n );\n return { changed: true, fields };\n}\n\nfunction syncNotes(db: Db, log: Log, taskKey: string): boolean {\n const taskId = taskRowId(db, taskKey);\n if (taskId === null) return false;\n const ops: LogOp[] = [...log.range(\"note\", `${taskKey}#`, `${taskKey}$`).values()].flat();\n const want = foldNotes(ops, taskHorizon(log, taskKey));\n const rows = prepareCached(\n db,\n \"SELECT id, author, content, created_at, kind FROM task_notes WHERE task_id = ? ORDER BY id\",\n ).all(taskId) as {\n id: number;\n author: string | null;\n content: string;\n created_at: string;\n kind: string;\n }[];\n let changed = false;\n const seen = new Set<string>();\n for (const r of rows) {\n const id = noteIdentity(r.author, r.content, r.created_at);\n if (want.has(id) && !seen.has(id)) {\n seen.add(id);\n continue;\n }\n // Not in the fold, or a repeat of an identity already kept.\n prepareCached(db, \"DELETE FROM task_notes WHERE id = ?\").run(r.id);\n changed = true;\n }\n for (const [id, n] of want) {\n if (seen.has(id)) continue;\n prepareCached(\n db,\n \"INSERT INTO task_notes (task_id, author, content, created_at, kind) VALUES (?, ?, ?, ?, ?)\",\n ).run(taskId, n.author, n.content, n.createdAt, n.kind);\n changed = true;\n }\n return changed;\n}\n\nfunction syncEdge(db: Db, log: Log, key: string): boolean {\n const { blocker, blocked } = parseEdgeKey(key);\n const state =\n blocker === blocked\n ? null\n : foldEdge(log.ofKey(\"edge\", key), [taskHorizon(log, blocker), taskHorizon(log, blocked)]);\n const fromId = taskRowId(db, blocker);\n const toId = taskRowId(db, blocked);\n const existing =\n fromId === null || toId === null\n ? undefined\n : (prepareCached(\n db,\n \"SELECT created_at FROM task_edges WHERE from_task_id = ? AND to_task_id = ?\",\n ).get(fromId, toId) as { created_at: string } | undefined);\n const wanted = state !== null && fromId !== null && toId !== null;\n if (!wanted) {\n if (existing === undefined || fromId === null || toId === null) return false;\n prepareCached(db, \"DELETE FROM task_edges WHERE from_task_id = ? AND to_task_id = ?\").run(\n fromId,\n toId,\n );\n return true;\n }\n if (existing === undefined) {\n prepareCached(\n db,\n \"INSERT INTO task_edges (from_task_id, to_task_id, created_at) VALUES (?, ?, ?)\",\n ).run(fromId, toId, state.createdAt);\n return true;\n }\n if (existing.created_at === state.createdAt) return false;\n prepareCached(\n db,\n \"UPDATE task_edges SET created_at = ? WHERE from_task_id = ? AND to_task_id = ?\",\n ).run(state.createdAt, fromId, toId);\n return true;\n}\n\n/** Re-fold a task's notes and every edge touching it: its existence or\n * horizon changed. */\nfunction syncDependents(db: Db, log: Log, taskKey: string): boolean {\n let changed = syncNotes(db, log, taskKey);\n for (const key of log.edgeKeysTouching({ task: taskKey })) {\n if (syncEdge(db, log, key)) changed = true;\n }\n return changed;\n}\n\n// ─── Per-entity application ───────────────────────────────────────────\n\nfunction applyWorkstream(db: Db, log: Log, op: Op): ApplyResult {\n const name = op.key;\n if (name.length === 0) throw new OpKeyMalformedError(\"workstream\", name);\n const ws = syncWorkstream(db, log, name);\n let changed = ws.changed;\n if (op.op === \"del\") {\n // The horizon moved: everything beneath the workstream re-folds.\n const prefix = `${name}/`;\n const taskKeys = [...log.range(\"task\", prefix, hi(prefix)).keys()];\n for (const key of taskKeys) if (syncTask(db, log, key).changed) changed = true;\n for (const key of taskKeys) if (syncNotes(db, log, key)) changed = true;\n const edges = log.edgeKeysTouching({ workstream: name });\n for (const key of edges) if (syncEdge(db, log, key)) changed = true;\n }\n return { changed, appliedFields: ws.fields };\n}\n\nfunction applyTask(db: Db, log: Log, op: Op): ApplyResult {\n const { workstream } = parseTaskKey(op.key);\n const existed = taskRowId(db, op.key) !== null;\n const ws = syncWorkstream(db, log, workstream);\n const task = syncTask(db, log, op.key);\n let changed = ws.changed || task.changed;\n const exists = taskRowId(db, op.key) !== null;\n if ((op.op === \"del\" || existed !== exists) && syncDependents(db, log, op.key)) changed = true;\n return { changed, appliedFields: task.fields };\n}\n\nfunction applyNote(db: Db, log: Log, op: Op): ApplyResult {\n const { taskKey } = parseNoteKey(op.key);\n return { changed: syncNotes(db, log, taskKey), appliedFields: [] };\n}\n\nfunction applyEdge(db: Db, log: Log, op: Op): ApplyResult {\n parseEdgeKey(op.key);\n return { changed: syncEdge(db, log, op.key), appliedFields: [] };\n}\n\n// ─── The seam ─────────────────────────────────────────────────────────\n\n/**\n * Apply one op to the portable tables.\n *\n * SYNCHRONOUS, for the same reason `withOpContext` is: the op context is\n * the shared main-DB `op_ctx` row, so two interleaved async apply scopes\n * would clobber each other's `applying` flag with no way to tell whose\n * suppression was in force. The scope is one synchronous transaction;\n * keeping this sync makes that unrepresentable rather than merely\n * discouraged.\n *\n * Runs inside `withCaptureSuppressed`, which is THE echo guard: without\n * it, writing a peer's op to `tasks` would fire the capture trigger,\n * mint a fresh local op, flush that back to the peer, and loop forever.\n * Runs in its own transaction (a savepoint when nested): one op rewrites\n * several rows, and they commit together or not at all.\n *\n * Does NOT insert the op into `ops` — that is the caller's job (which\n * owns segment bookkeeping and the (machine_id, hlc) dedupe). The op is\n * folded in beside the log's rows, so recording it before or after\n * changes nothing and a replay of ops already in the log is a no-op.\n *\n * Idempotent: applying the same op twice makes no second change, which\n * is what lets `mu sync --repair` be nothing more than \"re-read that\n * peer's segment from zero\".\n */\nexport function applyOp(db: Db, op: Op): ApplyResult {\n if (isKnownMachineLocalEntity(op.entity)) throw new OpEntityNotSyncedError(op.entity);\n // An entity this build does not recognise is a FORWARD-COMPATIBLE\n // no-op, projected nowhere, exactly like 'message'. Recording the op\n // is the caller's step and is what preserves it for a later build\n // (and for `mu rebuild`) without blocking every op behind it.\n if (!isSyncedEntity(op.entity)) return { changed: false, appliedFields: [] };\n // Log lines live in `ops` only; recording the op IS applying it.\n if (op.entity === \"message\") return { changed: false, appliedFields: [] };\n\n return withCaptureSuppressed(db, () =>\n db\n .transaction((): ApplyResult => {\n const log = new Log(db, op);\n switch (op.entity) {\n case \"workstream\":\n return applyWorkstream(db, log, op);\n case \"task\":\n return applyTask(db, log, op);\n case \"note\":\n return applyNote(db, log, op);\n default:\n return applyEdge(db, log, op);\n }\n })\n .immediate(),\n );\n}\n\n/**\n * Project the whole log: fold every workstream, task, note set and edge\n * the ops name, once each, into the (empty or stale) tables. This is\n * `mu rebuild`: no arrival order, no incremental step, just the fold. It\n * returns the number of table rows it wrote.\n *\n * Workstreams first (a task's fold needs its parent row), then tasks, then\n * the rows that hang off tasks.\n */\nexport function projectLog(db: Db): number {\n const log = new Log(db);\n const keys = (entity: string): string[] =>\n (\n prepareCached(db, \"SELECT DISTINCT key FROM ops WHERE entity = ?\").all(entity) as {\n key: string;\n }[]\n ).map((r) => r.key);\n const taskKeys = keys(\"task\");\n const noteTasks = [...new Set(keys(\"note\").map((k) => parseNoteKey(k).taskKey))];\n const workstreams = new Set([\n ...keys(\"workstream\"),\n ...taskKeys.map((k) => parseTaskKey(k).workstream),\n ]);\n let written = 0;\n return withCaptureSuppressed(db, () =>\n db\n .transaction(() => {\n for (const name of workstreams) if (syncWorkstream(db, log, name).changed) written += 1;\n for (const key of taskKeys) if (syncTask(db, log, key).changed) written += 1;\n for (const key of noteTasks) if (syncNotes(db, log, key)) written += 1;\n for (const key of keys(\"edge\")) if (syncEdge(db, log, key)) written += 1;\n return written;\n })\n .immediate(),\n );\n}\n\n/**\n * Apply many ops in HLC order, inside one transaction. The fold makes the\n * order irrelevant to the result; sorting keeps the work in log order.\n */\nexport function applyOps(db: Db, ops: readonly Op[]): ApplyResult[] {\n const ordered = [...ops].sort((a, b) => compareHlc(a.hlc, b.hlc));\n const run = db.transaction(() => ordered.map((op) => applyOp(db, op)));\n return run.immediate();\n}\n","// mu — the segment manifest (`<machine>.manifest`): layer 4 of the\n// segment robustness layers, plus the fields the owner's flush trusts\n// instead of rescanning its own segment. Split out of segments.ts\n// (1500-LOC cap); segments.ts re-exports the public names.\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { type Sha256State, sha256Digest } from \"./sha256-resumable.js\";\n\n/** Segment filename suffix. */\nconst SEGMENT_EXT = \".jsonl\";\n/** Manifest filename suffix. */\nconst MANIFEST_EXT = \".manifest\";\n\n/** Whole-file verification sidecar. */\nexport interface SegmentManifest {\n v: number;\n machine: string;\n count: number;\n lastHlc: string | null;\n sha256: string;\n updatedAt: string;\n /** Bytes of the segment `sha256` covers. Written by the owner so its\n * next flush can trust this manifest instead of rescanning; absent in\n * manifests from older builds. */\n size?: number;\n /** The segment's mtime when this manifest was written (owner-local). */\n mtimeMs?: number;\n /** Running hash state after `size` bytes, so an append rehashes only\n * what it added. */\n shaState?: Sha256State;\n /** sha256 over the fields above (`manifestSeal`). The owner trusts\n * count/size/shaState only when it matches, so a torn or hand-edited\n * manifest falls back to the full scan instead of being persisted. */\n seal?: string;\n}\n\nexport function manifestPath(segment: string): string {\n return segment.replace(new RegExp(`${SEGMENT_EXT}$`), MANIFEST_EXT);\n}\n\n/** A manifest as this build writes it, with every field the owner's\n * fast path relies on. */\nexport type SealedManifest = SegmentManifest & {\n size: number;\n mtimeMs: number;\n shaState: Sha256State;\n seal: string;\n};\n\n/** sha256 over every field the owner's fast path trusts, in a fixed\n * order. Not a defence against a deliberate forger, who could\n * recompute it; it binds count, lastHlc, size and the hash state to\n * each other so a torn write or a hand edit of one field is caught. */\nexport function manifestSeal(m: Omit<SealedManifest, \"seal\" | \"updatedAt\">): string {\n return createHash(\"sha256\")\n .update(\n [\n m.v,\n m.machine,\n m.count,\n m.lastHlc ?? \"\",\n m.sha256,\n m.size,\n m.mtimeMs,\n m.shaState.h,\n m.shaState.n,\n m.shaState.tail,\n ].join(\"\\u001f\"),\n )\n .digest(\"hex\");\n}\n\nconst HEX64 = /^[0-9a-f]{64}$/;\n\n/**\n * True when the manifest's trusted fields agree with each other: well\n * formed, count is zero exactly when size is, the hash state covers\n * `size` bytes and finishes to `sha256`, and the seal matches. Cheap\n * (at most two SHA-256 blocks plus a hash of a few hundred bytes), and\n * it reads no segment bytes. Anything off sends the owner to the full\n * scan, which recounts, rehashes and rewrites the manifest, so a\n * malformed field is never carried into the next manifest.\n */\nexport function manifestSelfConsistent(m: SegmentManifest): m is SealedManifest {\n const { count, lastHlc, size, mtimeMs, shaState, seal } = m;\n if (!Number.isSafeInteger(count) || count < 0) return false;\n if (typeof size !== \"number\" || !Number.isSafeInteger(size) || size < 0) return false;\n if (typeof mtimeMs !== \"number\" || !Number.isFinite(mtimeMs)) return false;\n if (lastHlc !== null && typeof lastHlc !== \"string\") return false;\n if ((count === 0) !== (size === 0) || (count === 0) !== (lastHlc === null)) return false;\n if (typeof m.sha256 !== \"string\" || !HEX64.test(m.sha256)) return false;\n if (typeof seal !== \"string\" || !HEX64.test(seal)) return false;\n if (\n typeof shaState !== \"object\" ||\n shaState === null ||\n typeof shaState.h !== \"string\" ||\n !HEX64.test(shaState.h) ||\n shaState.n !== size ||\n typeof shaState.tail !== \"string\"\n ) {\n return false;\n }\n const tail = Buffer.from(shaState.tail, \"base64\");\n if (tail.length !== size % 64 || tail.toString(\"base64\") !== shaState.tail) return false;\n if (sha256Digest(shaState) !== m.sha256) return false;\n return manifestSeal({ ...m, size, mtimeMs, shaState }) === seal;\n}\n\n/** Write `fields` as the manifest of `segment`, stamped and sealed. */\nexport function writeManifestFile(\n segment: string,\n fields: Omit<SealedManifest, \"seal\" | \"updatedAt\">,\n): void {\n const manifest: SegmentManifest = {\n ...fields,\n updatedAt: new Date().toISOString(),\n seal: manifestSeal(fields),\n };\n writeFileSync(manifestPath(segment), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n}\n\n/** Read a segment's manifest, or null when absent/unparsable. */\nexport function readManifest(segment: string): SegmentManifest | null {\n const path = manifestPath(segment);\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as SegmentManifest;\n } catch {\n return null;\n }\n}\n","// mu — SHA-256 whose running state can be saved and resumed.\n//\n// Why not node:crypto: a `Hash` cannot be serialised, and every mu\n// invocation is a fresh process. The segment manifest carries the\n// sha256 of the WHOLE append-only segment, so re-hashing with\n// node:crypto made each flush O(file size) forever. Persisting the\n// running state next to the digest lets the next flush hash only the\n// bytes it appends. The digest is byte-identical to node:crypto's (see\n// test/sha256-resumable.test.ts), so peers verifying with node:crypto\n// see no difference.\n\n/** Serialisable running state: eight hash words (hex), bytes hashed so\n * far, and the partial trailing block not yet compressed (base64). */\nexport interface Sha256State {\n h: string;\n n: number;\n tail: string;\n}\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst INITIAL_H = \"6a09e667bb67ae853c6ef372a54ff53a510e527f9b05688c1f83d9ab5be0cd19\";\n\n/** State of a hash that has consumed no bytes. */\nexport function sha256Initial(): Sha256State {\n return { h: INITIAL_H, n: 0, tail: \"\" };\n}\n\nfunction wordsOf(hex: string): Uint32Array {\n const h = new Uint32Array(8);\n for (let i = 0; i < 8; i++) h[i] = Number.parseInt(hex.slice(i * 8, i * 8 + 8), 16);\n return h;\n}\n\nfunction hexOf(h: Uint32Array): string {\n let out = \"\";\n for (const word of h) out += word.toString(16).padStart(8, \"0\");\n return out;\n}\n\nconst W = new Uint32Array(64);\n\n/** Compress every whole 64-byte block of `data` from `offset` into `h`. */\nfunction compress(h: Uint32Array, data: Uint8Array, offset: number, end: number): void {\n let h0 = h[0] ?? 0;\n let h1 = h[1] ?? 0;\n let h2 = h[2] ?? 0;\n let h3 = h[3] ?? 0;\n let h4 = h[4] ?? 0;\n let h5 = h[5] ?? 0;\n let h6 = h[6] ?? 0;\n let h7 = h[7] ?? 0;\n for (let p = offset; p + 64 <= end; p += 64) {\n for (let i = 0; i < 16; i++) {\n const j = p + i * 4;\n W[i] =\n ((data[j] ?? 0) << 24) |\n ((data[j + 1] ?? 0) << 16) |\n ((data[j + 2] ?? 0) << 8) |\n (data[j + 3] ?? 0);\n }\n for (let i = 16; i < 64; i++) {\n const w15 = W[i - 15] ?? 0;\n const w2 = W[i - 2] ?? 0;\n const s0 = ((w15 >>> 7) | (w15 << 25)) ^ ((w15 >>> 18) | (w15 << 14)) ^ (w15 >>> 3);\n const s1 = ((w2 >>> 17) | (w2 << 15)) ^ ((w2 >>> 19) | (w2 << 13)) ^ (w2 >>> 10);\n W[i] = ((W[i - 16] ?? 0) + s0 + (W[i - 7] ?? 0) + s1) | 0;\n }\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n let f = h5;\n let g = h6;\n let hh = h7;\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));\n const ch = (e & f) ^ (~e & g);\n const t1 = (hh + S1 + ch + (K[i] ?? 0) + (W[i] ?? 0)) | 0;\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const t2 = (S0 + maj) | 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h0 = (h0 + a) | 0;\n h1 = (h1 + b) | 0;\n h2 = (h2 + c) | 0;\n h3 = (h3 + d) | 0;\n h4 = (h4 + e) | 0;\n h5 = (h5 + f) | 0;\n h6 = (h6 + g) | 0;\n h7 = (h7 + hh) | 0;\n }\n h.set([h0, h1, h2, h3, h4, h5, h6, h7]);\n}\n\n/** Feed `data` into `state`, returning the new state. Pure. */\nexport function sha256Update(state: Sha256State, data: Uint8Array): Sha256State {\n const pending = Buffer.from(state.tail, \"base64\");\n const all = pending.length === 0 ? data : Buffer.concat([pending, data]);\n const h = wordsOf(state.h);\n const whole = all.length - (all.length % 64);\n compress(h, all, 0, whole);\n return {\n h: hexOf(h),\n n: state.n + data.length,\n tail: Buffer.from(all.subarray(whole)).toString(\"base64\"),\n };\n}\n\n/** Hex digest of everything fed into `state`. Does not mutate it. */\nexport function sha256Digest(state: Sha256State): string {\n const pending = Buffer.from(state.tail, \"base64\");\n const padLen = pending.length < 56 ? 64 : 128;\n const block = Buffer.alloc(padLen);\n pending.copy(block);\n block[pending.length] = 0x80;\n const bits = state.n * 8;\n block.writeUInt32BE(Math.floor(bits / 2 ** 32), padLen - 8);\n block.writeUInt32BE(bits >>> 0, padLen - 4);\n const h = wordsOf(state.h);\n compress(h, block, 0, padLen);\n return hexOf(h);\n}\n","// mu — the sync-dir guard: mu 4 never reads or writes a MU_SYNC_DIR that\n// a 3.x peer shares. 3.x reads only v1 lines and warns `unknown-version` on\n// every command once a v2 line lands in its folder (the 18:04 incident), so\n// no segment may open with a v1 line for mu 4 to touch the dir.\n// Builtins only: segments.ts and the CLI's handle() both import it.\n//\n// The guard lives INSIDE flushSegment, discoverPeers and ingestSegment, so\n// every caller (CLI, SDK, extension, TUI tick) is covered; handle() repeats it\n// before the DB opens so a refused run creates nothing at all.\n\nimport { closeSync, openSync, readdirSync, readFileSync, readSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** The one-line refusal. Exit 4 (conflict); nothing was written or read. */\nexport const SYNC_DIR_FOREIGN_MESSAGE = \"MU_SYNC_DIR holds 3.x segments; give mu 4 its own dir\";\n\nexport class SyncDirForeignError extends Error {\n override readonly name = \"SyncDirForeignError\";\n constructor(\n readonly dir: string,\n /** The segment that opens with a pre-v2 line. */\n readonly segment: string,\n ) {\n super(`${SYNC_DIR_FOREIGN_MESSAGE} (${segment})`);\n }\n}\n\n/** Every writer emits `{\"v\":N,` first (`encodeSegmentLine`), so the first\n * bytes are enough: no line is parsed, so a segment still being copied in\n * does not block the dir. */\nconst VERSION_PREFIX = /^\\{\"v\":(\\d+)[,}]/;\n\n/** Test seam: the foreign-version tests deliberately write v1 and v3 segments\n * into the dir. Never set outside a test. */\nlet guardOffForTests = false;\nexport function setSyncDirGuardForTests(off: boolean): void {\n guardOffForTests = off;\n}\n\n/** True when a `.manifest` says `\"v\"` below 2: a 3.x peer's sidecar. A 3.x\n * peer with no ops yet leaves an EMPTY segment and a v1 manifest, so the\n * segment's first line cannot show it. Unreadable or torn: not evidence. */\nfunction manifestIsPreV2(path: string): boolean {\n try {\n const v: unknown = (JSON.parse(readFileSync(path, \"utf8\")) as { v?: unknown } | null)?.v;\n return typeof v === \"number\" && v < 2;\n } catch {\n return false;\n }\n}\n\n/** False only when the file's first bytes are a recognisable pre-v2 line (what\n * 3.x writes). Empty, torn, garbage and newer-than-v2 files are not evidence\n * of a 3.x peer: the segment reader reports them as defects, and a v3 line\n * keeps its \"upgrade mu\" warning rather than a message that blames 3.x. */\nfunction startsAsV2OrUnknown(path: string): boolean {\n let fd: number;\n try {\n fd = openSync(path, \"r\");\n } catch {\n return true; // vanished or unreadable: not evidence of a 3.x peer\n }\n try {\n const buf = Buffer.alloc(24);\n const n = readSync(fd, buf, 0, buf.length, 0);\n const m = VERSION_PREFIX.exec(buf.toString(\"utf8\", 0, n));\n return m === null || Number(m[1]) >= 2;\n } catch {\n return true;\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Throw `SyncDirForeignError` when ANY file in `dir` is 3.x evidence: a\n * `*.jsonl` (conflict copies included) whose first line is pre-v2, or a\n * `*.manifest` whose `\"v\"` is below 2 (covers an empty segment). Every file is\n * scanned, in name order. A missing or empty dir passes. Only the first line\n * decides: a v1 file that later gained v2 lines is a 3.x file.\n */\nexport function assertSyncDirV2(dir: string): void {\n if (guardOffForTests) return;\n let names: string[];\n try {\n names = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names.sort()) {\n const path = join(dir, name);\n const foreign = name.endsWith(\".jsonl\")\n ? !startsAsV2OrUnknown(path)\n : name.endsWith(\".manifest\") && manifestIsPreV2(path);\n if (foreign) throw new SyncDirForeignError(dir, name);\n }\n}\n","// mu — segments: how ops LEAVE and ENTER a machine.\n//\n// THE ONE IDEA THAT MAKES THIS WORK\n// ---------------------------------\n// <MU_SYNC_DIR>/<machine_id>.jsonl\n//\n// Each machine APPENDS ONLY to its own segment and read-onlys every\n// other. No file is ever written by two machines, so there is no\n// file-level conflict, ever. That single property is what makes\n// Syncthing, rsync, scp, git, and a USB stick all adequate transport: it\n// removes the one thing every file-mover is bad at. There is nothing to\n// merge, so nothing can merge wrongly.\n//\n// TWO LOGS, ONLY ONE CRITICAL\n// ---------------------------\n// The CANONICAL log is the `ops` table inside mu.db: ACID, WAL,\n// crash-safe, written in the same transaction as the mutation it records.\n// A SEGMENT is DERIVED and REGENERABLE — literally `SELECT ... FROM ops` —\n// so losing one costs a re-flush and nothing else.\n//\n// That asymmetry is what licenses plain append-only files here, and it has\n// one concrete consequence worth stating because it looks like an\n// oversight: NO fsync ON APPEND. Losing the tail to power loss is\n// harmless, because the next flush re-derives it from the table. Paying\n// for durability twice would be paying for nothing.\n//\n// WHY NOT A SQLITE FILE PER PEER\n// ------------------------------\n// Rejected deliberately (design note): a `-wal`/`-shm` sidecar in a synced\n// folder is THE canonical way to corrupt a SQLite DB; a torn transfer is\n// fatal to the WHOLE file rather than costing one JSONL line; and page\n// churn defeats rsync/Syncthing delta transfer, whereas an append-only\n// file is the best case for it.\n//\n// ROBUSTNESS: FOUR LAYERS\n// -----------------------\n// The pattern every append-only log uses (RocksDB, Kafka, etcd,\n// SQLite-WAL): detect the bad record, stop at it, refetch the tail later.\n// Never guess, never skip-and-continue past damage.\n//\n// 1. JSON.parse failure = torn write. FREE, and truncation is the\n// DOMINANT failure mode (a transfer caught in flight).\n// 2. crc32 per line = bit rot that JSON.parse would happily\n// accept. Belt-and-braces, not load-bearing — see the note's\n// honesty about this. ~5 LOC via node:zlib.\n// 3. Monotonic hlc = reordering, duplication, and silent\n// mid-file truncation. Structural, zero extra bytes.\n// 4. Manifest sidecar = whole-file verification (count, last_hlc,\n// sha256). REPORTS, does not halt: it fires when every remaining\n// line is individually valid (a truncation on a line boundary), so\n// the prefix is safe to apply and the fix is a fresh copy.\n//\n// On a bad record (layers 1-3) we stop at the last GOOD one and advance\n// the watermark only that far, then report it. Because `UNIQUE (machine_id, hlc)` makes\n// ingest idempotent, the universal repair is \"re-read from zero\" — so a\n// damaged segment is recoverable, never fatal.\n\nimport { createHash } from \"node:crypto\";\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve, sep } from \"node:path\";\nimport { applyOp, type Op, OpEntityNotSyncedError } from \"./apply.js\";\nimport { compareStrings } from \"./compare.js\";\nimport { type Db, prepareCached, SYNCED_ENTITIES } from \"./db.js\";\nimport { locksDir, withFileLock } from \"./file-lock.js\";\nimport { receiveHlc } from \"./hlc.js\";\nimport {\n decodeLine,\n encodeSegmentLine,\n SEGMENT_FORMAT_VERSION,\n SEGMENT_READ_VERSIONS,\n type SegmentDefect,\n} from \"./segment-line.js\";\nimport {\n manifestPath,\n manifestSelfConsistent,\n readManifest,\n type SegmentManifest,\n writeManifestFile,\n} from \"./segment-manifest.js\";\nimport {\n encodeFingerprint,\n type ResumePoint,\n readAppended,\n resumePoint,\n segmentCaughtUp,\n segmentFingerprint,\n usableShaState,\n} from \"./segment-resume.js\";\nimport { type Sha256State, sha256Digest, sha256Initial, sha256Update } from \"./sha256-resumable.js\";\nimport { assertSyncDirV2 } from \"./sync-dir-guard.js\";\n\nexport {\n type DecodeResult,\n decodeLine,\n encodeSegmentLine,\n SEGMENT_FORMAT_VERSION,\n SEGMENT_READ_VERSIONS,\n type SegmentDefect,\n type SegmentDefectKind,\n type SegmentLine,\n} from \"./segment-line.js\";\n\nexport { manifestSeal, readManifest, type SegmentManifest } from \"./segment-manifest.js\";\nexport { segmentCaughtUp } from \"./segment-resume.js\";\n\n/** Segment filename suffix. */\nconst SEGMENT_EXT = \".jsonl\";\n\n// ─── sync dir + naming ────────────────────────────────────────────────\n\n/**\n * The sync directory, or null when sync is not configured.\n *\n * Null is the normal single-machine case, and every entry point here\n * treats it as \"do nothing, cost nothing\" rather than an error. Sync is\n * opt-in by setting one env var; there is no config file and no\n * membership list (see `discoverPeers`).\n */\nexport function syncDir(): string | null {\n const dir = process.env.MU_SYNC_DIR;\n if (dir === undefined || dir.trim() === \"\") return null;\n refuseUserSyncDirDuringTests(dir);\n return dir;\n}\n\n/**\n * The sibling of `refuseUserDbDuringTests` in src/db.ts, for the OTHER\n * piece of real state a stray test can reach.\n *\n * Pointing MU_DB_PATH at a temp file is not enough to contain a test:\n * sync is ambient, so the first flush stamps the temp DB's fresh\n * `machine_id` onto a segment in whatever MU_SYNC_DIR names. On a dev\n * box that is the user's REAL sync folder, and the result is a\n * permanent phantom peer — `mu sync` lists a machine that never\n * existed, forever, because absence of a segment is the only way a\n * peer disappears and nothing prunes them.\n *\n * Observed: eight such phantoms in ~/mu, each holding one op from a\n * throwaway `workstream init`. They came from the documented\n * smoke-test recipe (`MU_DB_PATH=/tmp/mu-smoke.db mu <verb>`), which\n * overrides the DB and says nothing about the sync dir.\n *\n * So: under a test runner, refuse a sync dir that is not clearly\n * disposable. Tests that exercise sync legitimately already point at a\n * per-test temp dir (mkdtemp under $TMPDIR), which is allowed; the\n * refusal only fires for a path outside it, which is by definition\n * somebody's real folder. Production never sets VITEST, so this is a\n * no-op for the shipped CLI.\n */\nfunction refuseUserSyncDirDuringTests(dir: string): void {\n const inTest = process.env.VITEST !== undefined || process.env.NODE_ENV === \"test\";\n if (!inTest) return;\n const resolved = resolve(dir);\n const temp = resolve(tmpdir());\n if (resolved === temp || resolved.startsWith(temp + sep)) return;\n throw new Error(\n `syncDir refused: tests must NEVER flush ops into a real sync dir (MU_SYNC_DIR=${resolved}). ` +\n `Doing so writes a segment named after this run's machine_id and leaves a permanent phantom peer. ` +\n `Point MU_SYNC_DIR at a mkdtemp() path under ${temp}, or leave it unset (test/_setup.ts clears it by default).`,\n );\n}\n\n/** This machine's id — the identity every op it writes is stamped with. */\nexport function localMachineId(db: Db): string {\n const row = db.prepare(\"SELECT machine_id FROM machine_identity WHERE id = 1\").get() as\n | { machine_id: string }\n | undefined;\n if (row === undefined) throw new Error(\"machine_identity row missing; not a mu DB\");\n return row.machine_id;\n}\n\n/** Path of a machine's own segment inside `dir`. */\nexport function segmentPath(dir: string, machineId: string): string {\n return join(dir, `${machineId}${SEGMENT_EXT}`);\n}\n\n// ─── flush: ops -> my segment ─────────────────────────────────────────\n\nexport interface FlushResult {\n /** Absolute path written, or null when sync is not configured. */\n segmentPath: string | null;\n /** Ops appended by this call. */\n appended: number;\n /** Total lines in the segment afterwards. */\n total: number;\n /** Ops skipped because their entity is machine-local. A full scan\n * (`verify`, or an untrusted manifest) counts every unflushed one; the\n * fast path counts only those up to the last op it appended, so a\n * no-op ambient flush reports 0 (see `pendingLines`). */\n skippedLocal: number;\n /**\n * Non-null when THIS MACHINE'S OWN segment was found defective past\n * its last good line (bit rot, a torn write not at EOF, a bad manual\n * edit). A segment is DERIVED and REGENERABLE from the canonical\n * `ops` table, so the repair is to truncate the file back to its\n * last good record and let the append below regenerate the rest —\n * never to append after the damage, which is the defect that caused\n * unbounded regrowth (each flush re-deriving the same ops from a\n * watermark frozen at the corruption point and stacking them after\n * it, forever). Surfaced here rather than printed directly: this\n * module does no I/O beyond the filesystem, callers decide how loud\n * to be (`mu sync`, `ambientFlush`).\n */\n selfRepaired: SegmentDefect | null;\n /**\n * Non-null when THIS MACHINE'S OWN segment holds a line of a version\n * this build cannot read (first such line, 1-based): written by a newer\n * mu. The segment is then READ-ONLY to this build: flush appends\n * nothing, repairs nothing (`selfRepaired` stays null), and deletes the\n * manifest so the fast path cannot vouch for the file. The pending ops\n * stay in `ops` until mu is upgraded. `foreignVersion` is the version\n * found. Both null otherwise.\n */\n foreignVersionAt: number | null;\n foreignVersion: number | null;\n /**\n * True when ops were pending but another process held the segment\n * lock past the wait, so this call wrote nothing. The ops stay\n * unflushed in `ops` (the segment's last hlc is the watermark), and\n * the next flush appends them. Never set on a successful flush.\n */\n lockBusy?: boolean;\n}\n\n/**\n * Append this machine's not-yet-flushed ops to its own segment.\n *\n * FILTERING IS LOAD-BEARING. Only ops whose entity is in\n * `SYNCED_ENTITIES` are written. Machine-local ops (agent.*)\n * are captured and DO appear in `mu log`, but they must never reach a\n * segment: they carry pane ids and absolute paths that are meaningless,\n * and frequently wrong, on another machine. \"Not synced\" is not \"not\n * logged\".\n *\n * Also filters `machine_id = <me>`: a segment holds ONE machine's ops.\n * Ops ingested from a peer live in our `ops` table too, and re-flushing\n * them into our own segment would duplicate a peer's history under our\n * name — and would grow without bound as two machines echoed each other.\n *\n * The high-water mark is the last hlc already in the file (read from the\n * manifest when present, else derived by scanning), so flush is\n * incremental and idempotent: calling it twice appends nothing the second\n * time.\n */\n/** How long an ambient flush (every verb's post-body hook) waits for\n * the segment lock before deferring its ops to the next invocation.\n * An incremental append holds the lock for milliseconds, so 2 s\n * clears a deep queue of parallel appenders; a holder slower than\n * that is doing a full rescan, and the verb should not wait it out. */\nexport const AMBIENT_FLUSH_LOCK_WAIT_MS = 2_000;\n/** Explicit `mu sync` (verify) waits longer: the operator asked for the\n * flush and a full-scan holder takes seconds on a large segment. */\nexport const VERIFY_FLUSH_LOCK_WAIT_MS = 15_000;\n\nexport async function flushSegment(\n db: Db,\n dir: string | null = syncDir(),\n opts?: { verify?: boolean; lockWaitMs?: number },\n): Promise<FlushResult> {\n if (dir === null)\n return {\n segmentPath: null,\n appended: 0,\n total: 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n\n // A 3.x peer shares the folder: write nothing into it.\n assertSyncDirV2(dir);\n const machineId = localMachineId(db);\n mkdirSync(dir, { recursive: true });\n const path = segmentPath(dir, machineId);\n\n // LOCK-FREE NO-OP. Most verbs write no synced op, and every mu\n // process used to queue on the lock below just to learn that, so N\n // parallel read-only verbs ran their flushes one after another. When\n // our own manifest still describes the file and no op is pending,\n // there is nothing to append and nothing to serialise against: a\n // concurrent appender either finished (we would see its manifest) or\n // has not, and its ops are its own to write.\n // `verify` (explicit `mu sync`) skips both shortcuts and decodes every\n // line, so damage that kept size, mtime and the last line intact\n // (bit rot mid-file) is still found and self-repaired somewhere.\n const verify = opts?.verify === true;\n const pre = verify ? null : trustedTail(path, machineId);\n if (pre !== null) {\n const pending = pendingLines(db, machineId, pre.lastHlc, false);\n if (pending.lines.length === 0) {\n return {\n segmentPath: path,\n appended: 0,\n total: pre.count,\n skippedLocal: pending.skippedLocal,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n }\n }\n\n // Serialise concurrent local flushes so two processes cannot interleave\n // partial lines in the same file. Keyed on the sync dir + machine, since\n // that names the single file being appended to.\n //\n // NEVER UNLOCKED. If the lock is still held at the deadline, write\n // nothing: an unlocked append can splice lines into another writer's,\n // or land after its self-repair truncate, and the ops are safe in the\n // DB anyway. The next invocation's flush appends them. A stale lock\n // (crashed holder) is still broken inside withFileLock.\n const lockName = createHash(\"sha256\")\n .update(`${dir}\\u001f${machineId}`)\n .digest(\"hex\")\n .slice(0, 16);\n return withFileLock(\n join(locksDir(), `segment-${lockName}.lock`),\n `segment:${machineId}`,\n () => Promise.resolve(flushLocked(db, path, machineId, verify)),\n {\n acquireTimeoutMs:\n opts?.lockWaitMs ?? (verify ? VERIFY_FLUSH_LOCK_WAIT_MS : AMBIENT_FLUSH_LOCK_WAIT_MS),\n onUnavailable: () => ({\n segmentPath: path,\n appended: 0,\n total: pre?.count ?? 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n lockBusy: true,\n }),\n },\n );\n}\n\nfunction flushLocked(db: Db, path: string, machineId: string, verify: boolean): FlushResult {\n // Fast path: our own manifest still describes the file (same size and\n // mtime, last line decodes to its lastHlc), so count and high-water\n // mark come from it and nothing before the tail is read.\n const trusted = verify ? null : trustedTail(path, machineId);\n let count: number;\n let since: string | null;\n let selfRepaired: SegmentDefect | null = null;\n if (trusted !== null) {\n count = trusted.count;\n since = trusted.lastHlc;\n } else {\n const existing = readSegmentTail(path);\n count = existing.count;\n since = existing.lastHlc;\n\n // The defect this exists to close: readSegmentTail STOPS at the first\n // bad record either because it hit real damage or because it simply\n // ran out of well-formed lines. Those two cases used to be\n // indistinguishable to this function, and treating \"stopped early on\n // damage\" the same as \"reached clean EOF\" is exactly what let a\n // corrupted line grow the file forever: `since` never advanced past\n // it, so every flush re-selected and re-appended the same ops after\n // it again, unbounded. Distinguish them and heal our own segment\n // (truncate back to the last verified-good line) before appending\n // anything new, rather than stacking fresh data after the wound.\n // A line of a version this build cannot read makes the whole segment\n // READ-ONLY here: append nothing, repair nothing, and delete the\n // manifest so the fast path cannot vouch for the file. The ops stay\n // pending in SQLite until mu is upgraded on this machine.\n if (existing.foreign !== null) {\n rmSync(manifestPath(path), { force: true });\n return {\n segmentPath: path,\n appended: 0,\n total: existing.lineCount,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: existing.foreign.line,\n foreignVersion: existing.foreign.version,\n };\n }\n if (existing.defect !== null) {\n selfRepaired = existing.defect;\n // Truncate back to the last verified-good line; everything after\n // is regenerated from `ops`.\n writeFileSync(\n path,\n existing.goodLines.length > 0 ? `${existing.goodLines.join(\"\\n\")}\\n` : \"\",\n \"utf8\",\n );\n }\n }\n\n const pending = pendingLines(db, machineId, since, trusted === null);\n let appended: Buffer | null = null;\n if (pending.lines.length > 0) {\n // NO fsync. The segment is derived from `ops`; a lost tail costs one\n // re-flush, so paying for durability here would buy nothing.\n appended = Buffer.from(`${pending.lines.join(\"\\n\")}\\n`, \"utf8\");\n appendFileSync(path, appended);\n } else if (!existsSync(path)) {\n // Create the file even with nothing to say, so peers can discover\n // this machine before its first change.\n writeFileSync(path, \"\", \"utf8\");\n }\n\n const total = count + pending.lines.length;\n const result = {\n segmentPath: path,\n appended: pending.lines.length,\n total,\n skippedLocal: pending.skippedLocal,\n selfRepaired,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n // Nothing changed and the manifest already says so: leave it alone,\n // so a read-only verb does not hand the sync tool a file to ship.\n if (trusted !== null && appended === null) return result;\n writeManifest(\n path,\n machineId,\n total,\n pending.lastHlc ?? since,\n trusted !== null && appended !== null\n ? { state: trusted.shaState, size: trusted.size, appended }\n : null,\n );\n return result;\n}\n\nconst SYNCED_ENTITIES_SQL = SYNCED_ENTITIES.map((e) => `'${e}'`).join(\", \");\n\n/**\n * This machine's synced ops newer than `since`, encoded as segment\n * lines, plus how many skipped ops (machine-local)\n * lie in the range this call covered.\n *\n * The entity filter is IN THE SQL, seeking\n * `idx_ops_machine_entity_hlc`, so a run of machine-local ops after the\n * segment's last line (agent.* churn from a long session) is never\n * read: the segment's watermark is the last SYNCED hlc, and filtering\n * in JS rescanned that whole run on every invocation. `INDEXED BY`\n * because without ANALYZE stats the planner prefers the UNIQUE\n * (machine_id, hlc) index and walks the run anyway.\n *\n * `skippedLocal` counts ops up to the last line written by this call.\n * With `countTrailing` (the full-scan path, already O(file)) it also\n * counts skipped ops after it, as before; the fast path does not,\n * because recounting the same trailing run every time is the cost this\n * query exists to avoid.\n */\nfunction pendingLines(\n db: Db,\n machineId: string,\n since: string | null,\n countTrailing: boolean,\n): { lines: string[]; lastHlc: string | null; skippedLocal: number } {\n // \"\" sorts before every hlc, so it stands for \"from the start\" and\n // keeps the range a plain index seek (an `IS NULL OR` defeats it).\n const from = since ?? \"\";\n const rows = prepareCached(\n db,\n `SELECT hlc, machine_id, group_id, intent, actor, entity, key, op, payload\n FROM ops INDEXED BY idx_ops_machine_entity_hlc\n WHERE machine_id = @machineId\n AND entity IN (${SYNCED_ENTITIES_SQL})\n AND hlc > @from\n ORDER BY hlc`,\n ).all({ machineId, from }) as Array<{\n hlc: string;\n machine_id: string;\n group_id: string;\n intent: string | null;\n actor: string | null;\n entity: string;\n key: string;\n op: string;\n payload: string;\n }>;\n\n const lines: string[] = [];\n let lastHlc: string | null = null;\n\n for (const row of rows) {\n lines.push(\n encodeSegmentLine({\n hlc: row.hlc,\n machineId: row.machine_id,\n groupId: row.group_id,\n intent: row.intent,\n actor: row.actor,\n entity: row.entity,\n key: row.key,\n op: row.op === \"del\" ? \"del\" : \"put\",\n payload: row.payload,\n }),\n );\n lastHlc = row.hlc;\n }\n // Everything in the covered range that did not become a line. A\n // range count on the UNIQUE (machine_id, hlc) index: proportional to\n // the range, never to what trails it on the fast path.\n let row: { n: number };\n if (countTrailing) {\n row = prepareCached(\n db,\n \"SELECT COUNT(*) AS n FROM ops WHERE machine_id = @machineId AND hlc > @from\",\n ).get({ machineId, from }) as { n: number };\n } else if (lastHlc !== null) {\n row = prepareCached(\n db,\n `SELECT COUNT(*) AS n FROM ops\n WHERE machine_id = @machineId AND hlc > @from AND hlc <= @upTo`,\n ).get({ machineId, from, upTo: lastHlc }) as { n: number };\n } else {\n return { lines, lastHlc, skippedLocal: 0 };\n }\n return { lines, lastHlc, skippedLocal: row.n - lines.length };\n}\n\n/**\n * Count, last hlc, size and running hash of OUR OWN segment, taken from\n * its manifest, or null when the manifest cannot be trusted and the\n * caller must scan the file.\n *\n * Trusted only when the manifest is ours, carries the fields this build\n * writes and they agree with each other (`manifestSelfConsistent`:\n * format, hash state finishing to `sha256`, seal), matches the file's\n * current size AND mtime (any rewrite, hand\n * edit or truncation changes one of them), and the file's last line ends\n * in a newline and decodes cleanly to the manifest's lastHlc. That last\n * check reads only the final line, so a torn or corrupt tail still falls\n * through to the full scan and its self-repair. Cost: one stat plus one\n * line, independent of file size.\n */\nfunction trustedTail(\n path: string,\n machineId: string,\n): { count: number; lastHlc: string | null; size: number; shaState: Sha256State } | null {\n const m = readManifest(path);\n if (m === null || !SEGMENT_READ_VERSIONS.includes(m.v) || m.machine !== machineId) return null;\n if (!manifestSelfConsistent(m)) return null;\n const { count, lastHlc, size, mtimeMs, shaState } = m;\n let stat: ReturnType<typeof statSync>;\n try {\n stat = statSync(path);\n } catch {\n return null;\n }\n if (stat.size !== size || stat.mtimeMs !== mtimeMs) return null;\n if (count === 0) return lastHlc === null ? { count, lastHlc, size, shaState } : null;\n const last = readLastLine(path, size);\n if (last === null) return null;\n const decoded = decodeLine(last);\n if (!decoded.ok || decoded.line.hlc !== lastHlc) return null;\n return { count, lastHlc, size, shaState };\n}\n\n/** The last newline-terminated line of the first `size` bytes of\n * `path`, without its newline; null when those bytes do not end in a\n * newline (a torn write). Reads backwards in chunks, so a long line\n * costs its own length and the file's size costs nothing. */\nfunction readLastLine(path: string, size: number): string | null {\n if (size === 0) return null;\n const fd = openSync(path, \"r\");\n try {\n const last = Buffer.alloc(1);\n readSync(fd, last, 0, 1, size - 1);\n if (last[0] !== 0x0a) return null;\n const chunks: Buffer[] = [];\n let end = size - 1;\n while (end > 0) {\n const start = Math.max(0, end - 64 * 1024);\n const buf = Buffer.alloc(end - start);\n readSync(fd, buf, 0, buf.length, start);\n const nl = buf.lastIndexOf(0x0a);\n if (nl >= 0) {\n chunks.unshift(buf.subarray(nl + 1));\n break;\n }\n chunks.unshift(buf);\n end = start;\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n } finally {\n closeSync(fd);\n }\n}\n\n/** The first line of a version this build cannot read in this machine's\n * own segment, or null. For `mu doctor`; reads the whole file. */\nexport function ownSegmentForeignLine(\n db: Db,\n dir: string | null = syncDir(),\n): { path: string; line: number; version: number } | null {\n if (dir === null) return null;\n const path = segmentPath(dir, localMachineId(db));\n const found = readSegmentTail(path).foreign;\n return found === null ? null : { path, ...found };\n}\n\n/** Own synced ops newer than the last op in this machine's segment: what\n * a flush would append now. Read-only, so `mu doctor` can report a\n * backlog (a flush that lost the lock race leaves one). */\nexport function countUnpublishedOps(db: Db, dir: string): number {\n const machineId = localMachineId(db);\n const { lastHlc } = readSegmentTail(segmentPath(dir, machineId));\n const row = prepareCached(\n db,\n `SELECT COUNT(*) AS n FROM ops INDEXED BY idx_ops_machine_entity_hlc\n WHERE machine_id = @machineId AND entity IN (${SYNCED_ENTITIES_SQL}) AND hlc > @from`,\n ).get({ machineId, from: lastHlc ?? \"\" }) as { n: number };\n return row.n;\n}\n\n/** Number of GOOD lines in a segment (stopping at the first defect, as\n * ingest does). The denominator of \"how far behind am I\" — exported for\n * `mu sync`'s peer table. */\nexport function segmentLineCount(path: string): number {\n return readSegmentTail(path).count;\n}\n\n/**\n * Count + last hlc of an existing segment, cheaply, plus (this is the\n * part that matters) WHY it stopped: `defect` is null when every line\n * decoded cleanly (a genuine, trustworthy EOF), and set when decoding\n * stopped early because a line was bad. Conflating those two used to be\n * the whole bug: a stop-on-damage looked exactly like a stop-on-EOF to\n * `flushLocked`, so it kept appending after the damage forever.\n * `goodLines` is the verified-good prefix, raw, so a caller that finds a\n * defect can truncate back to it byte-for-byte rather than re-encoding.\n */\nfunction readSegmentTail(path: string): {\n count: number;\n lastHlc: string | null;\n goodLines: readonly string[];\n defect: SegmentDefect | null;\n /** First line of a version this build cannot read ANYWHERE in the\n * file (1-based), even past a defect; null when there is none. */\n foreign: { line: number; version: number } | null;\n lineCount: number;\n} {\n if (!existsSync(path))\n return { count: 0, lastHlc: null, goodLines: [], defect: null, foreign: null, lineCount: 0 };\n const lines = segmentLines(readFileSync(path, \"utf8\"));\n let lastHlc: string | null = null;\n let count = 0;\n let defect: SegmentDefect | null = null;\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index];\n if (line === undefined) break;\n // Same rule as `ingestSegment`: a blank line is damage. Skipping it\n // here while peers halt on it left the owner blind to the defect,\n // so it never self-repaired and every peer stopped there forever.\n if (line.trim() === \"\") {\n defect = { kind: \"malformed-shape\", line: index + 1, detail: \"blank line\" };\n break;\n }\n const decoded = decodeLine(line);\n if (!decoded.ok) {\n defect = {\n kind: decoded.kind,\n line: index + 1,\n detail: decoded.detail,\n ...(decoded.version === undefined ? {} : { version: decoded.version }),\n };\n break;\n }\n lastHlc = decoded.line.hlc;\n count += 1;\n }\n // The scan above stops at the first defect; a foreign line behind it\n // still makes the segment read-only, so look at the rest.\n let foreign: { line: number; version: number } | null = null;\n if (defect?.kind === \"unknown-version\" && defect.version !== undefined) {\n foreign = { line: defect.line, version: defect.version };\n } else if (defect !== null) {\n for (let i = count + 1; i < lines.length && foreign === null; i++) {\n const later = decodeLine(lines[i] ?? \"\");\n if (!later.ok && later.kind === \"unknown-version\" && later.version !== undefined)\n foreign = { line: i + 1, version: later.version };\n }\n }\n return {\n count,\n lastHlc,\n goodLines: lines.slice(0, count),\n defect,\n foreign,\n lineCount: lines.length,\n };\n}\n\n/** Split a segment into its lines exactly as every reader must: a\n * trailing newline is normal, a trailing PARTIAL line is a torn write\n * (kept so layer 1 can catch it), and a blank line stays in place so\n * the caller reports it as damage. One splitter, so the owner's\n * self-check and a peer's ingest cannot disagree about line numbers. */\nfunction segmentLines(raw: string): string[] {\n const lines = raw.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n return lines;\n}\n\n/**\n * LAYER 4: whole-file verification sidecar.\n *\n * `incremental` carries the running hash of the bytes the manifest last\n * covered, so an append hashes only what it added. Without it (first\n * flush, a repair, a manifest from an older build, or a file that grew\n * by more than we appended) the whole file is hashed once.\n */\nfunction writeManifest(\n path: string,\n machine: string,\n count: number,\n lastHlc: string | null,\n incremental: { state: Sha256State; size: number; appended: Buffer } | null,\n): void {\n let stat = statSync(path);\n let shaState: Sha256State;\n if (incremental !== null && stat.size === incremental.size + incremental.appended.length) {\n shaState = sha256Update(incremental.state, incremental.appended);\n } else {\n const bytes = readFileSync(path);\n shaState = sha256Update(sha256Initial(), bytes);\n stat = statSync(path);\n }\n writeManifestFile(path, {\n v: SEGMENT_FORMAT_VERSION,\n machine,\n count,\n lastHlc,\n sha256: sha256Digest(shaState),\n size: shaState.n,\n mtimeMs: stat.mtimeMs,\n shaState,\n });\n}\n\n/**\n * Verify a segment against its manifest (layer 4).\n *\n * Whole-file, so it catches damage the per-line layers cannot see: a\n * segment silently replaced wholesale, or truncated exactly on a line\n * boundary (where every remaining line is individually valid).\n */\nexport function verifyAgainstManifest(\n segment: string,\n): { ok: true } | { ok: false; reason: string } {\n const manifest = readManifest(segment);\n if (manifest === null) return { ok: true }; // no manifest: nothing to check\n if (!existsSync(segment)) return { ok: false, reason: \"segment missing but manifest present\" };\n return checkBytesAgainstManifest(segment, manifest, readFileSync(segment));\n}\n\n/** `verifyAgainstManifest` over bytes the caller already read, so ingest\n * reads the segment once. `exact` is true when the bytes hash to the\n * manifest's sha256 (the manifest covers exactly this file). */\nfunction checkBytesAgainstManifest(\n segment: string,\n manifest: SegmentManifest,\n bytes: Buffer,\n): { ok: true; exact: boolean } | { ok: false; reason: string } {\n const sha = createHash(\"sha256\").update(bytes).digest(\"hex\");\n if (sha === manifest.sha256) return { ok: true, exact: true };\n // A GROWN file is expected: the peer appended after writing the\n // manifest we have, or our copy is mid-transfer. That is not damage.\n const tail = readSegmentTail(segment);\n if (tail.count >= manifest.count) {\n return { ok: true, exact: false };\n }\n return {\n ok: false,\n reason: `sha mismatch and file has FEWER records than the manifest (${tail.count} < ${manifest.count}): truncated`,\n };\n}\n\n// ─── peer discovery ───────────────────────────────────────────────────\n\nexport interface PeerSegment {\n /** Machine id the segment belongs to. */\n machineId: string;\n /** Key of this FILE's watermark in `sync_peers`: the machine id for\n * the peer's own segment, the full file stem for a conflict copy.\n * A copy diverges from its original, so line N of one says nothing\n * about line N of the other; sharing one watermark skipped every op\n * that existed only in the copy. Optional for SDK callers written\n * before it existed: absent means the machine id (`peerWatermarkKey`). */\n watermarkKey?: string;\n /** Path on disk. */\n path: string;\n /** True for a Syncthing-style conflict copy. */\n conflictCopy: boolean;\n}\n\n/**\n * Every segment in `dir` that is not mine.\n *\n * IMPLICIT, with no membership list. `MU_SYNC_PEERS` was explicitly\n * rejected as \"a config file with extra steps that must be kept\n * consistent across every machine\" — dropping a segment in the folder\n * joins the cluster, deleting it leaves.\n *\n * CONFLICT COPIES ARE INGESTED, not ignored. Syncthing names them\n * `<machine>.sync-conflict-20260609-123456-ABCDEFG.jsonl`; they are still\n * valid op logs, and dedup by `(machine_id, hlc)` makes reading them\n * safe. Ignoring them would silently drop real ops precisely when\n * something already went wrong.\n */\nexport function discoverPeers(dir: string, selfMachineId: string): PeerSegment[] {\n if (!existsSync(dir)) return [];\n assertSyncDirV2(dir); // a 3.x peer shares the folder: read nothing from it\n const peers: PeerSegment[] = [];\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(SEGMENT_EXT)) continue;\n const stem = name.slice(0, -SEGMENT_EXT.length);\n // Syncthing: \"<machine>.sync-conflict-<date>-<time>-<id>\"\n const conflictAt = stem.indexOf(\".sync-conflict-\");\n const conflictCopy = conflictAt > 0;\n const machineId = conflictCopy ? stem.slice(0, conflictAt) : stem;\n if (machineId === selfMachineId && !conflictCopy) continue;\n // A conflict copy OF MY OWN segment is still a peer's view of my\n // history; ingesting it is a no-op thanks to (machine_id, hlc)\n // dedupe, so allow it rather than special-casing.\n const path = join(dir, name);\n try {\n if (!statSync(path).isFile()) continue;\n } catch {\n continue;\n }\n peers.push({ machineId, watermarkKey: conflictCopy ? stem : machineId, path, conflictCopy });\n }\n return peers.sort((a, b) => compareStrings(a.path, b.path));\n}\n\n/** The `sync_peers` key for a segment file: `watermarkKey`, else the\n * machine id (the pre-watermarkKey `PeerSegment` shape). */\nexport function peerWatermarkKey(peer: PeerSegment): string {\n return peer.watermarkKey ?? peer.machineId;\n}\n\n// ─── watermarks ───────────────────────────────────────────────────────\n\n/**\n * How far into one segment file we have applied, keyed by\n * `PeerSegment.watermarkKey` (the machine id, or a conflict copy's own\n * stem).\n *\n * ONE INTEGER SUFFICES because segments are append-only and ordered — a\n * set or a vector clock would be strictly more state for no more\n * information. Stored in `sync_peers.last_applied_seq`, which has been in\n * the v9 schema unused until now.\n *\n * The integer is a LINE COUNT within that peer's segment, not the peer's\n * `ops.seq` (which is a local-only cursor on their machine and means\n * nothing here).\n */\nexport function getWatermark(db: Db, watermarkKey: string): number {\n const row = db\n .prepare(\"SELECT last_applied_seq AS n FROM sync_peers WHERE machine_id = ?\")\n .get(watermarkKey) as { n: number } | undefined;\n return row?.n ?? 0;\n}\n\n/**\n * Store a watermark and stamp `last_seen_at` with the ISO time. The\n * segment fingerprint goes to `sync_fingerprints` when the caller just\n * read the file cleanly to its end (`segmentCaughtUp`). Every other\n * write deletes it, so a reset or partial ingest never vouches for the\n * file.\n */\nexport function setWatermark(\n db: Db,\n watermarkKey: string,\n value: number,\n fingerprint?: string | null,\n): void {\n const now = new Date().toISOString();\n prepareCached(\n db,\n `INSERT INTO sync_peers (machine_id, last_applied_seq, last_seen_at)\n VALUES (@machineId, @value, @seenAt)\n ON CONFLICT (machine_id) DO UPDATE\n SET last_applied_seq = @value, last_seen_at = @seenAt`,\n ).run({ machineId: watermarkKey, value, seenAt: now });\n if (fingerprint == null) {\n prepareCached(db, \"DELETE FROM sync_fingerprints WHERE machine_id = ?\").run(watermarkKey);\n } else {\n prepareCached(\n db,\n `INSERT INTO sync_fingerprints (machine_id, fingerprint) VALUES (?, ?)\n ON CONFLICT (machine_id) DO UPDATE SET fingerprint = excluded.fingerprint`,\n ).run(watermarkKey, fingerprint);\n }\n}\n\n/** Reset a peer's watermark so the next ingest re-reads from zero. The\n * universal repair, safe because ingest is idempotent. */\nexport function resetWatermark(db: Db, watermarkKey: string): void {\n setWatermark(db, watermarkKey, 0);\n}\n\n// ─── ingest: peer segment -> applyOp ──────────────────────────────────\n\nexport interface IngestResult {\n machineId: string;\n path: string;\n /** Lines consumed past the starting watermark: applied plus skipped\n * (refused, re-delivered) lines. A line that\n * halted ingest is not counted. */\n read: number;\n /** Ops applied (some are no-ops: already present, or lost an LWW). */\n applied: number;\n /** Ops that changed a row. */\n changed: number;\n /** Watermark after this ingest. */\n watermark: number;\n /** Problems found, in line order. Reported, never swallowed. */\n defects: readonly SegmentDefect[];\n /** True iff a defect stopped us short of the file's end. */\n truncatedAt: number | null;\n}\n\n/**\n * Read one peer segment from its watermark and apply each op.\n *\n * STOPS AT THE FIRST DAMAGED RECORD and advances the watermark only that\n * far. Never skips a damaged line to continue past it: in an ordered log,\n * a gap is indistinguishable from reordering, and applying ops around a\n * hole risks a state neither machine ever had. The tail is re-read on the\n * next ingest, by which time the transfer has usually completed.\n *\n * A REFUSED line is not a damaged one. A well-formed op naming an entity\n * that must not travel (`entity-not-synced`) is reported as a defect and\n * SKIPPED: it projects nothing, so it leaves no hole, and halting on it\n * makes the watermark unrecoverable by any means the CLI offers.\n *\n * A RE-DELIVERED line is not a damaged one either. A block of ops the\n * peer already wrote, appended verbatim a second time, breaks the hlc\n * ordering (`duplicate-op`) without losing anything: every one of those\n * ops is already in our `ops` table byte-for-byte, so applying them\n * again is a no-op by construction. Halting there is unrecoverable —\n * `--repair` re-reads from zero straight back into the same three\n * lines, forever — so it is reported and SKIPPED. A non-monotonic line\n * we have NOT seen before is still real damage and still halts.\n *\n * A manifest mismatch (layer 4) is reported but does not halt: every\n * line still present is individually valid, so applying them is safe.\n *\n * Calls `receiveHlc` per op so the local clock advances past the peer's,\n * which is what makes \"laptop edits after seeing the devserver's op\" order\n * correctly rather than losing to it.\n */\nexport function ingestSegment(\n db: Db,\n peer: PeerSegment,\n opts?: { verify?: boolean },\n): IngestResult {\n assertSyncDirV2(dirname(peer.path)); // v1 is never ingested, whoever built the peer\n const defects: SegmentDefect[] = [];\n const watermarkKey = peerWatermarkKey(peer);\n const start = getWatermark(db, watermarkKey);\n\n // CAUGHT UP: the file and its manifest are byte-for-byte what the last\n // clean full read saw (size, exact mtime, manifest hash), and the\n // manifest counts the lines we consumed. Nothing to apply, so do not\n // read, hash or split the file. `verify` (explicit `mu sync`) skips\n // this and checks the whole file, so damage that kept size and mtime\n // is still reported somewhere.\n const nothing: IngestResult = {\n machineId: peer.machineId,\n path: peer.path,\n read: 0,\n applied: 0,\n changed: 0,\n watermark: start,\n defects,\n truncatedAt: null,\n };\n if (opts?.verify !== true && segmentCaughtUp(db, watermarkKey, peer.path, start)) return nothing;\n if (!existsSync(peer.path)) return nothing;\n\n const fingerprint = segmentFingerprint(peer.path);\n\n // RESUME: the last clean read recorded where it stopped and the running\n // hash there. When the file is that prefix plus appended bytes whose\n // hash is the manifest's, only the appended bytes are read and split.\n // Anything else (shrunk, stale manifest, no resume point, explicit\n // `verify`) takes the full read and whole-file verify below.\n const resume =\n opts?.verify !== true && fingerprint?.manifest != null && start > 0\n ? resumePoint(db, watermarkKey, start)\n : null;\n const appended =\n resume !== null && fingerprint?.manifest != null\n ? readAppended(peer.path, resume, fingerprint.manifest.sha256)\n : null;\n\n let lines: string[];\n let base: number; // lines before `lines[0]` in the file\n let seedHlc: string | null = null;\n let nextResume: ResumePoint | null = null; // set only after a clean read, below\n let resumeState: Sha256State | null = null;\n let resumeSize = 0;\n if (resume !== null && appended !== null) {\n lines = segmentLines(appended.bytes.toString(\"utf8\"));\n base = resume.lines;\n seedHlc = resume.lastHlc;\n resumeState = appended.bytes[appended.bytes.length - 1] === 0x0a ? appended.state : null;\n resumeSize = appended.state.n;\n } else {\n const manifest = readManifest(peer.path);\n const bytes = readFileSync(peer.path);\n if (manifest !== null) {\n const verified = checkBytesAgainstManifest(peer.path, manifest, bytes);\n if (!verified.ok) {\n // Whole-file damage, distinct from a torn line: every remaining\n // record may be individually valid (truncation exactly on a line\n // boundary), which is precisely what the per-line layers cannot\n // see. Reported, NOT a halt: the lines that remain are a valid\n // prefix, so the per-line layers below still decide how far to\n // apply.\n defects.push({ kind: \"manifest-mismatch\", line: 0, detail: verified.reason });\n } else if (verified.exact) {\n // The owner's manifest carries the running hash after exactly\n // these bytes: reuse it instead of hashing the file in JS.\n const state = usableShaState(manifest.shaState, bytes.length);\n if (\n state !== null &&\n bytes[bytes.length - 1] === 0x0a &&\n sha256Digest(state) === manifest.sha256\n ) {\n resumeState = state;\n resumeSize = bytes.length;\n }\n }\n }\n lines = segmentLines(bytes.toString(\"utf8\"));\n base = 0;\n // Seed the monotonicity check from the last line we already accepted,\n // so a segment rewritten out of order is caught even mid-file.\n if (start > 0 && start <= lines.length) {\n const prior = lines[start - 1];\n if (prior !== undefined) {\n const decoded = decodeLine(prior);\n if (decoded.ok) seedHlc = decoded.line.hlc;\n }\n }\n }\n const total = base + lines.length;\n\n let applied = 0;\n let changed = 0;\n let watermark = start;\n let truncatedAt: number | null = null;\n let previousHlc: string | null = seedHlc;\n\n const run = db.transaction(() => {\n for (let index = start - base; index < lines.length; index++) {\n const raw = lines[index];\n const lineNo = base + index + 1;\n if (raw === undefined || raw.trim() === \"\") {\n // Blank line: treat as damage rather than skipping, since a\n // well-formed segment never contains one.\n defects.push({ kind: \"malformed-shape\", line: lineNo, detail: \"blank line\" });\n truncatedAt = lineNo;\n break;\n }\n\n const decoded = decodeLine(raw);\n if (!decoded.ok) {\n defects.push({\n kind: decoded.kind,\n line: lineNo,\n detail: decoded.detail,\n ...(decoded.version === undefined ? {} : { version: decoded.version }),\n });\n truncatedAt = lineNo;\n break;\n }\n\n const op: Op = {\n hlc: decoded.line.hlc,\n machineId: decoded.line.machine,\n groupId: decoded.line.group,\n actor: decoded.line.actor,\n intent: decoded.line.intent,\n entity: decoded.line.entity,\n key: decoded.line.key,\n op: decoded.line.op,\n payload: decoded.payloadText,\n };\n\n // LAYER 3: monotonic hlc. Structural, zero extra bytes. Catches\n // reordering, duplication, and silent mid-file truncation.\n if (previousHlc !== null && decoded.line.hlc <= previousHlc) {\n // ... unless we have this exact op already, in which case the\n // peer re-appended a block it had already written and there is\n // nothing to reorder: an identical op carries identical state,\n // so skipping it cannot produce a state neither machine had.\n if (isAlreadyRecorded(db, op)) {\n defects.push({\n kind: \"duplicate-op\",\n line: lineNo,\n detail: `hlc ${decoded.line.hlc} re-delivered — skipped`,\n });\n watermark = lineNo;\n continue;\n }\n defects.push({\n kind: \"non-monotonic-hlc\",\n line: lineNo,\n detail: `hlc ${decoded.line.hlc} <= previous ${previousHlc}`,\n });\n truncatedAt = lineNo;\n break;\n }\n\n try {\n const result = applyIncomingOp(db, op);\n if (result.changed) changed += 1;\n } catch (err) {\n if (err instanceof OpEntityNotSyncedError) {\n // A peer sent something that must never cross a machine\n // boundary (a pane id, an absolute path). Report it as a\n // bad-peer defect — and SKIP THE LINE rather than stopping.\n //\n // Stopping is right for DAMAGE, where a gap is\n // indistinguishable from reordering. This line is not\n // damaged: it decoded, its crc verified, and its hlc is in\n // order. Refusing it projects nothing, so there is no hole to\n // reason about, and continuing is strictly safer than the\n // alternative we actually shipped — one such line at position\n // 2533 of a 20,305-line segment froze that peer's watermark\n // permanently, and `mu sync --repair` re-read straight back\n // into the same wall. A defect is reported; nothing is lost;\n // the remaining 17,772 ops arrive.\n defects.push({\n kind: \"entity-not-synced\",\n line: lineNo,\n detail: `peer sent machine-local entity '${op.entity}' — skipped`,\n });\n previousHlc = op.hlc;\n watermark = lineNo;\n continue;\n }\n throw err;\n }\n\n applied += 1;\n previousHlc = op.hlc;\n watermark = lineNo;\n }\n // Vouch for the file only after a clean read to its end, so a file\n // with a defect is read (and reported) again on every pass.\n const clean = defects.length === 0 && watermark === total;\n if (clean && resumeState !== null && previousHlc !== null) {\n nextResume = { lines: total, size: resumeSize, lastHlc: previousHlc, state: resumeState };\n }\n setWatermark(\n db,\n watermarkKey,\n watermark,\n clean && fingerprint !== null ? encodeFingerprint(fingerprint.key, nextResume) : null,\n );\n });\n run.immediate();\n\n return {\n machineId: peer.machineId,\n path: peer.path,\n read: watermark - start,\n applied,\n changed,\n watermark,\n defects,\n truncatedAt,\n };\n}\n\n/**\n * Is this exact op already in our `ops` table?\n *\n * `UNIQUE (machine_id, hlc)` is the op's identity everywhere else in\n * the system — it is what makes `applyIncomingOp` idempotent and\n * \"re-read from zero\" a safe universal repair — so it is the identity\n * used here too. Entity and key are matched as well so a hlc collision\n * between genuinely different ops (which the UNIQUE constraint would\n * itself refuse) can never be mistaken for a re-delivery.\n */\nfunction isAlreadyRecorded(db: Db, op: Op): boolean {\n const row = prepareCached(\n db,\n `SELECT 1 FROM ops\n WHERE machine_id = @machineId AND hlc = @hlc\n AND entity = @entity AND key = @key AND op = @op\n LIMIT 1`,\n ).get({\n machineId: op.machineId,\n hlc: op.hlc,\n entity: op.entity,\n key: op.key,\n op: op.op,\n });\n return row !== undefined;\n}\n\n/**\n * Apply ONE incoming op and record it in the local `ops` table.\n *\n * The shared tail of every ingest path — segment ingest above, and the\n * `mu sync --from <peer.db>` reader in `src/sync.ts`, which is a\n * different READER over the same apply semantics. Extracted so the two\n * cannot drift: a second copy of \"advance the clock, apply, record\" is\n * how one of them silently stops advancing the clock.\n *\n * Three steps, in this order:\n * 1. `receiveHlc` BEFORE applying, so anything we mint afterwards\n * sorts above the peer's op.\n * 2. `applyOp`, which is capture-suppressed (no echo op is minted).\n * 3. Record the op locally so it survives, participates in\n * provenance, and can be re-flushed by rebuild. INSERT OR IGNORE\n * makes this idempotent via UNIQUE (machine_id, hlc) — the\n * property that lets \"re-read from zero\" be the universal repair.\n */\nexport function applyIncomingOp(db: Db, op: Op): { changed: boolean } {\n receiveHlc(db, op.hlc);\n const result = applyOp(db, op);\n prepareCached(\n db,\n `INSERT OR IGNORE INTO ops\n (hlc, machine_id, group_id, actor, intent, entity, key, op, payload, created_at)\n VALUES (@hlc, @machineId, @groupId, @actor, @intent, @entity, @key, @op, @payload, @createdAt)`,\n ).run({\n hlc: op.hlc,\n machineId: op.machineId,\n groupId: op.groupId,\n actor: op.actor ?? null,\n intent: op.intent ?? null,\n entity: op.entity,\n key: op.key,\n op: op.op,\n payload: op.payload,\n createdAt: new Date().toISOString(),\n });\n return { changed: result.changed };\n}\n\n// ─── the two halves, together ─────────────────────────────────────────\n\nexport interface SyncPassResult {\n flushed: FlushResult;\n ingested: readonly IngestResult[];\n /** True iff any peer reported a defect. */\n defective: boolean;\n}\n\n/**\n * One flush + one ingest of every discovered peer.\n *\n * The SDK seam `mu sync` calls (src/cli/sync.ts); it deliberately\n * prints nothing and starts nothing. No daemon, no watcher, no polling\n * loop that outlives the command — the anti-feature pledges are firm, and\n * mu never moves files itself: the operator owns transport.\n *\n * A no-op costing nothing when `MU_SYNC_DIR` is unset, which is the\n * normal single-machine case.\n */\nexport async function syncPass(db: Db, dir: string | null = syncDir()): Promise<SyncPassResult> {\n if (dir === null) {\n return {\n flushed: {\n segmentPath: null,\n appended: 0,\n total: 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n },\n ingested: [],\n defective: false,\n };\n }\n const flushed = await flushSegment(db, dir, { verify: true });\n const self = localMachineId(db);\n const ingested = discoverPeers(dir, self).map((peer) =>\n ingestSegment(db, peer, { verify: true }),\n );\n return {\n flushed,\n ingested,\n defective:\n flushed.selfRepaired !== null ||\n flushed.foreignVersionAt !== null ||\n ingested.some((r) => r.defects.length > 0),\n };\n}\n","// mu — resume a peer segment ingest from a byte offset.\n//\n// A clean ingest of a peer's segment records, next to its caught-up\n// fingerprint (`sync_fingerprints`), where it stopped: lines consumed,\n// bytes consumed, the last hlc, and the running sha256 state over those\n// bytes. When the peer appends, the next ambient ingest reads only the\n// new bytes, hashes them from the saved state, and accepts them only\n// when the result is the sha256 in the peer's manifest. That equals a\n// whole-file check only while the prefix is what the first read saw: a\n// local change to those bytes that keeps the file growing is not seen\n// here, only by an explicit `mu sync` (`verify`). The full read and verify\n// also runs for a shrunk file, a stale manifest, and after a defect (a\n// defect never records a resume point). Split out of\n// segments.ts (1500-LOC cap).\n\nimport { createHash } from \"node:crypto\";\nimport { closeSync, fstatSync, openSync, readFileSync, readSync, statSync } from \"node:fs\";\nimport { type Db, prepareCached } from \"./db.js\";\nimport { manifestPath, type SegmentManifest } from \"./segment-manifest.js\";\nimport { type Sha256State, sha256Digest, sha256Update } from \"./sha256-resumable.js\";\n\n/** A peer manifest's optional `shaState`, usable only when it is\n * well-formed and covers exactly `length` bytes. The manifest is peer\n * input: anything off (null, wrong types, bad hex, a tail that is not\n * `length % 64` bytes of canonical base64, `n` out of range) yields\n * null and the caller hashes the bytes itself. */\nexport function usableShaState(state: unknown, length: number): Sha256State | null {\n if (typeof state !== \"object\" || state === null) return null;\n const { h, n, tail } = state as Record<string, unknown>;\n if (typeof h !== \"string\" || !/^[0-9a-f]{64}$/.test(h)) return null;\n if (typeof n !== \"number\" || !Number.isSafeInteger(n) || n < 0 || n !== length) return null;\n if (typeof tail !== \"string\") return null;\n const raw = Buffer.from(tail, \"base64\");\n if (raw.length !== n % 64 || raw.toString(\"base64\") !== tail) return null;\n return { h, n, tail };\n}\n\n/** Where a clean ingest stopped, and what it hashed to get there. */\nexport interface ResumePoint {\n /** Lines consumed; always the watermark it was recorded with. */\n lines: number;\n /** Bytes consumed; the last one is a newline. */\n size: number;\n /** Hlc of the last line consumed (the monotonicity seed). */\n lastHlc: string;\n /** Running sha256 over those `size` bytes. */\n state: Sha256State;\n}\n\n/** The `sync_fingerprints` value: the caught-up key, optionally followed\n * by tab-separated resume fields. An older mu compares the whole string,\n * so it never matches and just reads in full. */\nexport function encodeFingerprint(key: string, resume: ResumePoint | null): string {\n if (resume === null) return key;\n const { lines, size, lastHlc, state } = resume;\n return [key, lines, size, lastHlc, state.h, state.tail].join(\"\\t\");\n}\n\n/** Split a stored fingerprint into its caught-up key and resume point\n * (null when absent or malformed). */\nexport function decodeFingerprint(raw: string): { key: string; resume: ResumePoint | null } {\n const [key = \"\", lines, size, lastHlc, h, tail] = raw.split(\"\\t\");\n if (h === undefined || tail === undefined || lines === undefined || size === undefined) {\n return { key, resume: null };\n }\n const n = Number(size);\n const count = Number(lines);\n if (!Number.isSafeInteger(n) || n <= 0 || !Number.isSafeInteger(count) || count <= 0) {\n return { key, resume: null };\n }\n if (!lastHlc || !/^[0-9a-f]{64}$/.test(h)) return { key, resume: null };\n return { key, resume: { lines: count, size: n, lastHlc, state: { h, n, tail } } };\n}\n\n/**\n * The bytes of `path` past `resume.size`, with the running hash after\n * them, or null when the file cannot be resumed: it is not longer than\n * the recorded size, or the hash does not equal `manifestSha` (the\n * manifest is stale, or the prefix is not what we hashed).\n */\nexport function readAppended(\n path: string,\n resume: ResumePoint,\n manifestSha: string,\n): { bytes: Buffer; state: Sha256State } | null {\n let fd: number;\n try {\n fd = openSync(path, \"r\");\n } catch {\n return null;\n }\n try {\n const size = fstatSync(fd).size;\n if (size <= resume.size) return null;\n const bytes = Buffer.alloc(size - resume.size);\n for (let got = 0; got < bytes.length; ) {\n const n = readSync(fd, bytes, got, bytes.length - got, resume.size + got);\n if (n === 0) return null;\n got += n;\n }\n const state = sha256Update(resume.state, bytes);\n return sha256Digest(state) === manifestSha ? { bytes, state } : null;\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * What a full, clean ingest saw of a peer's segment: its size, its\n * exact mtime, and the sha256 of its manifest's bytes, plus the count\n * that manifest claims. Null when the segment or its manifest cannot be\n * read. Taken BEFORE the read, so a file that changes mid-read no longer\n * matches next time.\n */\nexport function segmentFingerprint(\n path: string,\n): { key: string; count: unknown; manifest: SegmentManifest | null } | null {\n try {\n const { size, mtimeMs } = statSync(path);\n const manifest = readFileSync(manifestPath(path));\n const sha = createHash(\"sha256\").update(manifest).digest(\"hex\");\n let count: unknown = null;\n let parsed: SegmentManifest | null = null;\n try {\n parsed = JSON.parse(manifest.toString(\"utf8\")) as SegmentManifest;\n count = parsed?.count;\n } catch {\n // An unparseable manifest still fingerprints; its count is unknown.\n }\n return { key: `${size} ${mtimeMs} ${sha}`, count, manifest: parsed };\n } catch {\n return null;\n }\n}\n\n/** The fingerprint recorded with a watermark (see `setWatermark`), or\n * null when the last write of the watermark recorded none. */\nfunction recordedFingerprint(db: Db, watermarkKey: string): string | null {\n const row = prepareCached(\n db,\n \"SELECT fingerprint FROM sync_fingerprints WHERE machine_id = ?\",\n ).get(watermarkKey) as { fingerprint: string } | undefined;\n return row?.fingerprint ?? null;\n}\n\n/**\n * True when ingest is caught up on the segment at `path`, judged without\n * reading it: the manifest counts `lines` (the watermark), and the\n * segment's size, exact mtime and manifest bytes are what the last full,\n * defect-free ingest of this file recorded. Any difference (an append, a\n * rewrite whatever its mtime, a new or edited manifest, a watermark\n * written since by a reset or partial ingest) sends the caller down the\n * full read, which hashes the file and reports any mismatch. Cost: one\n * row lookup, one stat and one manifest read.\n */\nexport function segmentCaughtUp(\n db: Db,\n watermarkKey: string,\n path: string,\n lines: number,\n): boolean {\n const recorded = recordedFingerprint(db, watermarkKey);\n if (recorded === null) return false;\n const now = segmentFingerprint(path);\n return now !== null && now.count === lines && now.key === decodeFingerprint(recorded).key;\n}\n\n/** The resume point recorded with the watermark's fingerprint, when it\n * was recorded at exactly `lines`. */\nexport function resumePoint(db: Db, watermarkKey: string, lines: number): ResumePoint | null {\n const recorded = recordedFingerprint(db, watermarkKey);\n const resume = recorded === null ? null : decodeFingerprint(recorded).resume;\n return resume !== null && resume.lines === lines ? resume : null;\n}\n","// mu — `mu task auto`: explicit, host-fenced permission for the executor.\n//\n// Ready is not permission. A task is dispatched by `mu next` only when the\n// orchestrator authorised it HERE: a machine-local `task_auto` row\n// (cli key, worktree mode, run ceiling, `enabled`) AND the synced\n// `tasks.dispatch_host` naming this machine, the one host allowed to\n// dispatch it. Both are written in ONE op-context transaction.\n//\n// `--off` flips `enabled` to 0 and keeps the row: `runs` and `last_spawn`\n// (the spawn-replay receipt) must survive a re-authorisation, so nothing\n// here ever DELETEs or REPLACEs a `task_auto` row.\n//\n// Two predicates, deliberately separate:\n// autoPermitted(db, taskId) may this machine steer/release/dispatch the\n// task? Status-independent (IN_PROGRESS and\n// exhausted tasks still answer yes).\n// authorisedReady(db, ws) ready AND permitted AND runs < max_runs.\n\nimport type { Db } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { withOpContext } from \"./op-context.js\";\nimport { localMachineId } from \"./segments.js\";\nimport { type TaskRow, taskIdFor } from \"./tasks/core.js\";\nimport { TaskNotFoundError } from \"./tasks/errors.js\";\nimport { getTask, listReady } from \"./tasks/queries.js\";\nimport { RESERVED_WORKSTREAM_NAMES } from \"./workstream.js\";\n\n/** A cli key: the lookup key of `MU_<UPPER_CLI>_COMMAND` (hyphen or underscore). */\nconst CLI_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;\n\n/** A refusal that leaves everything unwritten (exit 4). */\nexport class TaskAutoRefusedError extends Error {\n override readonly name = \"TaskAutoRefusedError\";\n constructor(\n message: string,\n public readonly workstream: string,\n public readonly taskId: string,\n ) {\n super(message);\n }\n}\n\n/** A bad `--cli` / `--max` / empty selection (exit 2). */\nexport class TaskAutoArgError extends Error {\n override readonly name = \"TaskAutoArgError\";\n}\n\nexport interface AuthorizeTasksOptions {\n workstream: string;\n /** The model key `mu next` spawns with. Ignored by `off`. */\n cli: string;\n worktree: boolean;\n /** Run ceiling (> 0). Ignored by `off`. */\n maxRuns: number;\n /** Revoke LOCAL permission (keeps the counters) instead of granting it. */\n off?: boolean;\n /** Also select every open transitive blocker of this task (not the task itself). */\n blockersOf?: string;\n /** Attribution for the captured ops. */\n actor?: string;\n}\n\nexport interface AuthorizeTasksResult {\n /** The tasks acted on, in selection order. */\n ids: string[];\n /** False when every row and designation was already as asked. */\n changed: boolean;\n}\n\nexport interface AutoConfig {\n cli: string;\n worktree: boolean;\n maxRuns: number;\n runs: number;\n lastSpawn: string | null;\n enabled: boolean;\n}\n\n/** A ready task the executor may act on, with its stored config. */\nexport interface AuthorisedTask extends TaskRow {\n auto: AutoConfig;\n}\n\ninterface AutoRow {\n cli: string;\n worktree: number;\n max_runs: number;\n runs: number;\n last_spawn: string | null;\n enabled: number;\n}\n\nconst configOf = (r: AutoRow): AutoConfig => ({\n cli: r.cli,\n worktree: r.worktree === 1,\n maxRuns: r.max_runs,\n runs: r.runs,\n lastSpawn: r.last_spawn,\n enabled: r.enabled === 1,\n});\n\n/** The stored config of one task (surrogate id), enabled or not. */\nexport function getAutoConfig(db: Db, taskId: number): AutoConfig | undefined {\n const row = db\n .prepare(\n \"SELECT cli, worktree, max_runs, runs, last_spawn, enabled FROM task_auto WHERE task_id = ?\",\n )\n .get(taskId) as AutoRow | undefined;\n return row === undefined ? undefined : configOf(row);\n}\n\n/**\n * May this machine act on the task (steer, release, dispatch)? True iff an\n * ENABLED `task_auto` row exists, the task is `kind=work`, and its synced\n * `dispatch_host` is this machine. Independent of status and of the run\n * ceiling. Resolve the surrogate id with `taskIdFor`.\n */\nexport function autoPermitted(db: Db, taskId: number): boolean {\n return (\n db\n .prepare(\n `SELECT 1 AS x FROM task_auto a JOIN tasks t ON t.id = a.task_id\n WHERE a.task_id = ? AND a.enabled = 1 AND t.kind = 'work' AND t.dispatch_host = ?`,\n )\n .get(taskId, localMachineId(db)) !== undefined\n );\n}\n\n/**\n * The tasks `mu next` may dispatch now, in `ready` order: ready (OPEN,\n * unblocked, not parked/triage) AND permitted AND `runs < max_runs`.\n * `kind` human/delegate never qualifies; the reserved scratch queue is empty.\n */\nexport function authorisedReady(db: Db, workstream: string): AuthorisedTask[] {\n if (RESERVED_WORKSTREAM_NAMES.has(workstream)) return [];\n const rows = db\n .prepare(\n `SELECT t.local_id AS local_id, a.cli, a.worktree, a.max_runs, a.runs, a.last_spawn, a.enabled\n FROM task_auto a\n JOIN tasks t ON t.id = a.task_id\n JOIN workstreams w ON w.id = t.workstream_id AND w.name = ?\n WHERE a.enabled = 1 AND a.runs < a.max_runs\n AND t.kind = 'work' AND t.dispatch_host = ?`,\n )\n .all(workstream, localMachineId(db)) as (AutoRow & { local_id: string })[];\n const byId = new Map(rows.map((r) => [r.local_id, configOf(r)]));\n const out: AuthorisedTask[] = [];\n for (const t of listReady(db, workstream)) {\n const auto = byId.get(t.name);\n if (auto !== undefined) out.push({ ...t, auto });\n }\n return out;\n}\n\n/**\n * The local ids of every OPEN or IN_PROGRESS transitive blocker of an\n * umbrella, sorted. Walks only the umbrella's own workstream, uncapped\n * (unlike the display frontier), safe on diamonds and cycles, never walks\n * through a CLOSED task, never lists the umbrella itself.\n */\nexport function openBlockersClosure(db: Db, workstreamId: number, umbrellaId: number): string[] {\n const blockersOf = db.prepare(\n `SELECT b.id AS id, b.local_id AS local_id, b.status AS status\n FROM task_edges e JOIN tasks b ON b.id = e.from_task_id\n WHERE e.to_task_id = ? AND b.workstream_id = ?`,\n );\n const seen = new Set<number>([umbrellaId]);\n const queue = [umbrellaId];\n const found: string[] = [];\n for (let cur = queue.shift(); cur !== undefined; cur = queue.shift()) {\n const rows = blockersOf.all(cur, workstreamId) as {\n id: number;\n local_id: string;\n status: string;\n }[];\n for (const r of rows) {\n if (seen.has(r.id) || r.status === \"CLOSED\") continue;\n seen.add(r.id);\n found.push(r.local_id);\n queue.push(r.id);\n }\n }\n return found.sort();\n}\n\n/**\n * Grant (or, with `off`, revoke) this machine's permission to dispatch the\n * selected tasks. Grant: upsert the local `task_auto` row (keeping `runs`\n * and `last_spawn`, setting `enabled`) and write the synced `dispatch_host`\n * = this machine. Off: `enabled = 0`, and `dispatch_host` cleared only when\n * this machine owns it. The whole batch is validated inside ONE\n * transaction before any write: a refusal leaves nothing changed.\n */\nexport function authorizeTasks(\n db: Db,\n ids: readonly string[],\n opts: AuthorizeTasksOptions,\n): AuthorizeTasksResult {\n const ws = opts.workstream;\n if (RESERVED_WORKSTREAM_NAMES.has(ws)) {\n throw new TaskAutoArgError(say(\"task.auto_reserved_ws\", ws));\n }\n if (!opts.off) {\n if (!CLI_KEY_RE.test(opts.cli)) {\n throw new TaskAutoArgError(say(\"task.auto_cli_key\", opts.cli));\n }\n if (!Number.isSafeInteger(opts.maxRuns) || opts.maxRuns < 1) {\n throw new TaskAutoArgError(say(\"task.auto_max\", opts.maxRuns));\n }\n }\n return withOpContext(\n db,\n { intent: opts.off ? \"task.auto-off\" : \"task.auto\", actor: opts.actor, group: \"new\" },\n () => {\n const me = localMachineId(db);\n const selected = [...ids];\n if (opts.blockersOf !== undefined) {\n const umbrella = getTask(db, opts.blockersOf, ws);\n if (!umbrella) throw new TaskNotFoundError(opts.blockersOf, ws);\n selected.push(...openBlockersClosure(db, umbrella.workstreamId, tidOf(db, umbrella)));\n }\n const names = [...new Set(selected)];\n if (names.length === 0) {\n throw new TaskAutoArgError(\n opts.blockersOf !== undefined\n ? say(\"task.auto_no_blockers\", opts.blockersOf)\n : say(\"task.auto_none_given\"),\n );\n }\n\n // Validate the whole batch first.\n const plan: { task: TaskRow; id: number }[] = [];\n for (const name of names) {\n const task = getTask(db, name, ws);\n if (!task) throw new TaskNotFoundError(name, ws);\n const id = tidOf(db, task);\n if (!opts.off) refuseUnauthorisable(task, me);\n plan.push({ task, id });\n }\n\n // Then write.\n const now = new Date().toISOString();\n let changed = false;\n for (const { task, id } of plan) {\n const row = db\n .prepare(\"SELECT cli, worktree, max_runs, enabled FROM task_auto WHERE task_id = ?\")\n .get(id) as Pick<AutoRow, \"cli\" | \"worktree\" | \"max_runs\" | \"enabled\"> | undefined;\n if (opts.off) {\n if (row !== undefined && row.enabled === 1) {\n db.prepare(\"UPDATE task_auto SET enabled = 0 WHERE task_id = ?\").run(id);\n changed = true;\n }\n if (task.dispatchHost === me) {\n setHost(db, id, null, now);\n changed = true;\n }\n continue;\n }\n const wt = opts.worktree ? 1 : 0;\n if (row === undefined) {\n db.prepare(\n \"INSERT INTO task_auto (task_id, cli, worktree, max_runs, created_at) VALUES (?, ?, ?, ?, ?)\",\n ).run(id, opts.cli, wt, opts.maxRuns, now);\n changed = true;\n } else if (\n row.cli !== opts.cli ||\n row.worktree !== wt ||\n row.max_runs !== opts.maxRuns ||\n row.enabled !== 1\n ) {\n db.prepare(\n \"UPDATE task_auto SET cli = ?, worktree = ?, max_runs = ?, enabled = 1 WHERE task_id = ?\",\n ).run(opts.cli, wt, opts.maxRuns, id);\n changed = true;\n }\n if (task.dispatchHost !== me) {\n setHost(db, id, me, now);\n changed = true;\n }\n }\n return { ids: names, changed };\n },\n );\n}\n\nfunction tidOf(db: Db, task: TaskRow): number {\n const id = taskIdFor(db, task.name, task.workstreamName);\n if (id === null) throw new TaskNotFoundError(task.name, task.workstreamName);\n return id;\n}\n\nfunction setHost(db: Db, taskId: number, host: string | null, now: string): void {\n db.prepare(\"UPDATE tasks SET dispatch_host = ?, updated_at = ? WHERE id = ?\").run(\n host,\n now,\n taskId,\n );\n}\n\n/** Why a task cannot be authorised for the executor, or return. */\nfunction refuseUnauthorisable(task: TaskRow, me: string): void {\n const refuse = (why: string): never => {\n throw new TaskAutoRefusedError(\n `cannot authorise ${task.name}: ${why}`,\n task.workstreamName,\n task.name,\n );\n };\n if (task.kind !== \"work\") refuse(`it is a ${task.kind} task, not a worker job`);\n if (task.status === \"CLOSED\") refuse(\"it is CLOSED\");\n if (task.substate === \"parked\") refuse(\"it is parked (unpark it first)\");\n if (task.substate === \"triage\") refuse(\"it is in triage (accept it first)\");\n if (task.dispatchHost !== null && task.dispatchHost !== me) {\n refuse(`another host (${task.dispatchHost}) is designated to dispatch it`);\n }\n}\n","// mu — `buildTaskBrief`: the prompt of one executor attempt, built from the\n// task's OWN notes. The first `brief` note, verbatim; the latest `report`\n// note; one footer naming the task and the CLOSE line. Nothing generated is\n// ever stored back, so a retry can never quote an earlier footer.\n//\n// The executor stores the built TEXT with the reservation and a replay sends\n// those exact bytes: it never calls this again, so a deleted note, a newer\n// report or a changed footer cannot alter a stored request. Pure SQL: no mux,\n// no ctl.\n\nimport type { Db } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { taskIdFor } from \"./tasks/core.js\";\nimport { TaskNotFoundError } from \"./tasks/errors.js\";\nimport { getTaskNote } from \"./tasks/queries.js\";\n\n/** The task has no `brief` note : nothing is built. */\nexport class TaskBriefMissingError extends Error {\n override readonly name = \"TaskBriefMissingError\";\n constructor(\n public readonly task: string,\n public readonly workstream: string,\n reason: string,\n ) {\n super(say(\"task.brief_missing\", task, reason));\n }\n}\n\nexport interface TaskBriefOptions {\n /** The previous attempt died (`true`) or its run stopped on an API error (`\"error\"`): say so. */\n retry?: boolean | \"error\";\n}\n\nexport interface TaskBrief {\n text: string;\n}\n\n/**\n * The pinned notes of a task: the 1-based number of its FIRST `brief` note and\n * of its LATEST `report` note (0 = none). A checker is briefed from the same two.\n */\nexport function pinnedNotes(\n db: Db,\n workstream: string,\n task: string,\n): { briefN: number; reportN: number } {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) throw new TaskNotFoundError(task, workstream);\n const kinds = (\n db.prepare(\"SELECT kind FROM task_notes WHERE task_id = ? ORDER BY id\").all(taskId) as {\n kind: string;\n }[]\n ).map((r) => r.kind);\n return { briefN: kinds.indexOf(\"brief\") + 1, reportN: kinds.lastIndexOf(\"report\") + 1 };\n}\n\n/** Build the prompt of one attempt for `task` (see the file header). */\nexport function buildTaskBrief(\n db: Db,\n workstream: string,\n task: string,\n opts: TaskBriefOptions = {},\n): TaskBrief {\n const { briefN, reportN } = pinnedNotes(db, workstream, task);\n if (briefN < 1) {\n throw new TaskBriefMissingError(task, workstream, \"it has no brief note (kind brief)\");\n }\n const brief = getTaskNote(db, task, workstream, briefN).content;\n const report = reportN < 1 ? null : getTaskNote(db, task, workstream, reportN).content;\n\n const parts = [brief.trimEnd()];\n if (report !== null) parts.push(`Latest report on this task:\\n${report.trimEnd()}`);\n if (opts.retry === true) {\n parts.push(\"The previous attempt died before it finished; continue from its report.\");\n } else if (opts.retry === \"error\") {\n parts.push(\n \"Your previous run stopped on an API error before it finished; continue where you stopped.\",\n );\n }\n parts.push(\n `Work only on task ${task} (workstream ${workstream}). Commit, then end your final message with:\\n` +\n `CLOSE: task=${task} evidence=\"<command + result>\"\\nREPORT:\\n<what you did>`,\n );\n return { text: parts.join(\"\\n\\n\") };\n}\n","// mu — the executor's attempt accounting (`mu next`, slice A).\n//\n// One authorised dispatch is one ATTEMPT, `auto:<n>` in `spawn_receipts`\n// (a different namespace from a manual `manual:<k>`), whose latest record\n// lives in `task_auto.last_spawn` as JSON. A run is CHARGED once, when the\n// attempt is reserved: counter, record and `reserved` receipt are written in\n// ONE immediate transaction that re-plans first, so two `mu next` (two\n// processes) cannot mint different attempts for a task, and a crash leaves\n// either nothing or a reservation that a later `mu next` resumes under the\n// SAME key. The record stores the EXACT prompt, so a replay sends those bytes\n// and never rebuilds (nothing can drift). Replays, UNKNOWN probes and receipt\n// checks never charge. A\n// definitely-unsent failure keeps its charge and its failed key (never\n// reset): the next attempt is a new key and a new charge, so real spawns can\n// never exceed `max_runs`.\n//\n// `planAttempt` is the read-only half (also the dry run); `reserveAttempt`\n// re-runs it inside the write transaction. No await, no ctl, no mux here.\n\nimport {\n getReceipt,\n requestSha,\n reserveReceipt,\n type SpawnReceipt,\n updateReceipt,\n} from \"./agents/receipts.js\";\nimport { savedIdentity } from \"./agents/task-spawn.js\";\nimport { MAX_AGENT_NAME_LEN } from \"./agents.js\";\nimport { newMsgId } from \"./ctl/client.js\";\nimport type { Db } from \"./db.js\";\nimport { taskRevision } from \"./revision.js\";\nimport { localMachineId } from \"./segments.js\";\nimport { type AutoConfig, autoPermitted, getAutoConfig } from \"./task-auto.js\";\nimport { buildTaskBrief, TaskBriefMissingError } from \"./task-brief.js\";\nimport { taskIdFor } from \"./tasks/core.js\";\nimport { listReady } from \"./tasks/queries.js\";\n\n/**\n * How a stored attempt ended without a delivery: `abandoned` (nothing left to\n * do: the task closed, the agent is gone) or `needs_human` (the prompt may\n * have landed and cannot be confirmed: never resent, parked behind a human\n * need). Either is terminal: never replayed, never counted again.\n */\nexport interface AttemptEnd {\n state: \"abandoned\" | \"needs_human\";\n reason: string;\n}\n\n/** `task_auto.last_spawn`: the latest attempt, with its exact request. */\nexport interface AttemptRecord {\n v: 1;\n attempt: number;\n /** `auto:<attempt>`: the `spawn_receipts.attempt_key`. */\n key: string;\n /** The agent name asked for (a taken one is moved on by `nextFree`; the receipt has the real one). */\n name: string;\n cli: string;\n worktree: boolean;\n /** The exact prompt, stored at reservation: a replay sends these bytes. */\n text: string;\n /** The previous attempt's worker is gone: the brief says so. */\n retry: boolean;\n /**\n * A retry IN PLACE: the same live worker (its saved registry id + pane) is\n * sent the brief again after an API-errored run. No pane is spawned, and no\n * failure ever removes the worker.\n */\n inPlace?: boolean;\n /** Set once the attempt reached a terminal state without a delivery. */\n end?: AttemptEnd;\n}\n\nexport interface AttemptPlan extends AttemptRecord {\n task: string;\n taskId: number;\n workstream: string;\n /** The task's derived revision the plan was made at. */\n revision: number;\n}\n\nexport type PlanCode =\n | \"not-found\"\n | \"not-permitted\"\n | \"in-flight\"\n | \"parked\"\n | \"delivered\"\n | \"ceiling\"\n | \"not-ready\"\n | \"no-brief\"\n | \"changed\";\n\nexport type PlanResult =\n | { ok: true; plan: AttemptPlan }\n | { ok: false; code: PlanCode; reason: string };\n\n/** Receipt states from which an attempt must be resumed, not replaced. */\nexport const IN_FLIGHT_STATES: ReadonlySet<string> = new Set([\n \"reserved\",\n \"pane\",\n \"claimed\",\n \"sending\",\n \"unknown\",\n]);\n\n/** Receipt states from which nothing has been written to the agent. */\nconst UNSENT_STATES: ReadonlySet<string> = new Set([\"reserved\", \"pane\", \"claimed\"]);\n\nconst refuse = (code: PlanCode, reason: string): PlanResult => ({ ok: false, code, reason });\n\n/**\n * Is the worker of a DELIVERED attempt known to be gone, with its task\n * reopened by the reaper? The saved registry id + pane no longer hold, and the\n * reaper's own note (`[reaper] previous owner <name> gone`) was written after\n * the attempt began. A task someone reopened by hand (a rejected review) has\n * no such note: that is a decision, never a death.\n */\nexport function workerGone(db: Db, taskId: number, receipt: SpawnReceipt): boolean {\n if (savedIdentity(db, receipt).stale === undefined) return false;\n const head = `[reaper] previous owner ${receipt.name} gone`;\n return (\n db\n .prepare(\n `SELECT 1 AS x FROM task_notes\n WHERE task_id = ? AND author = 'reaper' AND created_at >= ? AND instr(content, ?) = 1\n LIMIT 1`,\n )\n .get(taskId, receipt.createdAt, head) !== undefined\n );\n}\n\nexport function parseAttempt(raw: string | null): AttemptRecord | undefined {\n if (raw === null) return undefined;\n try {\n const r = JSON.parse(raw) as Partial<AttemptRecord>;\n if (\n r.v !== 1 ||\n typeof r.key !== \"string\" ||\n typeof r.attempt !== \"number\" ||\n typeof r.text !== \"string\"\n ) {\n return undefined;\n }\n return r as AttemptRecord;\n } catch {\n return undefined;\n }\n}\n\n/** The stored attempt of a task and its receipt (either may be absent). */\nexport function readAttempt(\n db: Db,\n taskId: number,\n): { auto?: AutoConfig; record?: AttemptRecord; receipt?: SpawnReceipt } {\n const auto = getAutoConfig(db, taskId);\n const record = parseAttempt(auto?.lastSpawn ?? null);\n const receipt = record === undefined ? undefined : getReceipt(db, taskId, record.key);\n return {\n ...(auto !== undefined ? { auto } : {}),\n ...(record !== undefined ? { record } : {}),\n ...(receipt !== undefined ? { receipt } : {}),\n };\n}\n\n/**\n * The DELIVERED receipt the latest attempt stands on: its own when `sent`; for\n * an in-place retry that failed unsent (the worker was never touched), the\n * delivery it retried. Undefined when nothing was delivered.\n */\nexport function deliveredOf(\n db: Db,\n taskId: number,\n): { record: AttemptRecord; receipt: SpawnReceipt } | undefined {\n const { record, receipt } = readAttempt(db, taskId);\n if (record === undefined || receipt === undefined || record.end !== undefined) return undefined;\n if (receipt.state === \"sent\") return { record, receipt };\n if (record.inPlace !== true || receipt.state !== \"failed\") return undefined;\n const prior = db\n .prepare(\n `SELECT attempt_key FROM spawn_receipts\n WHERE task_id = ? AND state = 'sent' AND attempt_key LIKE 'auto:%' AND agent_id = ?\n ORDER BY created_at DESC, attempt_key DESC LIMIT 1`,\n )\n .get(taskId, receipt.agentId) as { attempt_key: string } | undefined;\n const sent = prior === undefined ? undefined : getReceipt(db, taskId, prior.attempt_key);\n return sent === undefined ? undefined : { record, receipt: sent };\n}\n\n/**\n * Local ids of the permitted tasks of `workstream` whose latest attempt is\n * in flight (reserved … unknown) and not ended: to be RESUMED before anything\n * new is allocated, even at their run ceiling. Revoked, foreign and ended\n * (abandoned / needs_human) attempts are absent.\n */\nexport function pendingAttempts(db: Db, workstream: string): string[] {\n const rows = db\n .prepare(\n `SELECT t.id AS id, t.local_id AS local_id\n FROM task_auto a\n JOIN tasks t ON t.id = a.task_id\n JOIN workstreams w ON w.id = t.workstream_id AND w.name = ?\n JOIN spawn_receipts r ON r.task_id = a.task_id\n AND r.attempt_key = json_extract(a.last_spawn, '$.key')\n WHERE a.enabled = 1 AND t.kind = 'work' AND t.dispatch_host = ?\n AND r.state IN ('reserved', 'pane', 'claimed', 'sending', 'unknown')\n AND json_extract(a.last_spawn, '$.end') IS NULL\n AND json_extract(a.last_spawn, '$.text') IS NOT NULL\n ORDER BY t.id`,\n )\n .all(workstream, localMachineId(db)) as { id: number; local_id: string }[];\n return rows.filter((r) => autoPermitted(db, r.id)).map((r) => r.local_id);\n}\n\n/** The agent name an attempt asks for: the task id cut to leave room for `-<attempt>`. */\nexport function attemptName(task: string, attempt: number): string {\n const suffix = `-${attempt}`;\n return `${task.slice(0, MAX_AGENT_NAME_LEN - suffix.length)}${suffix}`;\n}\n\n/** The request hash of an attempt (the executor always spawns `nextFree`, locally). */\nexport const attemptSha = (name: string, text: string): string =>\n requestSha({ name, nextFree: true, text });\n\n/**\n * Read-only: may a NEW attempt for `task` be reserved now, and what would it\n * be? Checks, in order: permission (enabled, work, this host), an attempt\n * already in flight or delivered, the run ceiling, readiness and the brief.\n * `revision` (when given) must equal the task's current revision.\n */\nexport function planAttempt(\n db: Db,\n workstream: string,\n task: string,\n opts: { revision?: number } = {},\n): PlanResult {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) return refuse(\"not-found\", `no task ${task} in ${workstream}`);\n if (!autoPermitted(db, taskId)) {\n return refuse(\"not-permitted\", `${task} is not authorised for this machine (mu task auto)`);\n }\n const { auto, record, receipt } = readAttempt(db, taskId);\n if (auto === undefined) return refuse(\"not-permitted\", `${task} has no auto config`);\n let retry = false;\n if (record?.end?.state === \"needs_human\") {\n return refuse(\n \"parked\",\n `${record.key} of ${task} may have been delivered and waits for a human (${record.end.reason})`,\n );\n }\n if (record !== undefined && receipt !== undefined && record.end === undefined) {\n if (IN_FLIGHT_STATES.has(receipt.state)) {\n return refuse(\"in-flight\", `${record.key} of ${task} is ${receipt.state}: resume it`);\n }\n const delivered = deliveredOf(db, taskId);\n if (delivered !== undefined) {\n if (!workerGone(db, taskId, delivered.receipt)) {\n return refuse(\n \"delivered\",\n `${record.key} of ${task} was delivered and its worker is not known to be gone: not re-dispatched`,\n );\n }\n retry = true;\n }\n }\n if (auto.runs >= auto.maxRuns) {\n return refuse(\"ceiling\", `${task} used its ${auto.maxRuns} run(s)`);\n }\n if (!listReady(db, workstream).some((t) => t.name === task)) {\n return refuse(\"not-ready\", `${task} is not ready`);\n }\n const revision = taskRevision(db, workstream, task);\n if (opts.revision !== undefined && opts.revision !== revision) {\n return refuse(\n \"changed\",\n `${task} changed since it was planned (rev ${opts.revision} → ${revision})`,\n );\n }\n const attempt = auto.runs + 1;\n const name = attemptName(task, attempt);\n let brief: ReturnType<typeof buildTaskBrief>;\n try {\n brief = buildTaskBrief(db, workstream, task, { retry });\n } catch (err) {\n if (err instanceof TaskBriefMissingError) return refuse(\"no-brief\", err.message);\n throw err;\n }\n return {\n ok: true,\n plan: {\n v: 1,\n attempt,\n key: `auto:${attempt}`,\n name,\n cli: auto.cli,\n worktree: auto.worktree,\n text: brief.text,\n retry,\n task,\n taskId,\n workstream,\n revision,\n },\n };\n}\n\n/**\n * Charge one run and reserve its attempt, atomically (see the file header).\n * Re-plans INSIDE the immediate transaction, so a change seen at ingest\n * between the caller's view and now refuses instead of acting on it.\n */\nexport function reserveAttempt(\n db: Db,\n workstream: string,\n task: string,\n opts: { revision?: number } = {},\n): PlanResult {\n return db\n .transaction((): PlanResult => {\n const planned = planAttempt(db, workstream, task, opts);\n if (!planned.ok) return planned;\n const { plan } = planned;\n const { task: _t, taskId, workstream: _w, revision: _r, ...record } = plan;\n const charged = db\n .prepare(\n \"UPDATE task_auto SET runs = runs + 1, last_spawn = ? WHERE task_id = ? AND runs = ? AND enabled = 1\",\n )\n .run(JSON.stringify(record), taskId, plan.attempt - 1);\n if (charged.changes !== 1) return refuse(\"changed\", `${task}'s run counter moved`);\n reserveReceipt(db, {\n taskId,\n attemptKey: plan.key,\n name: plan.name,\n workstream,\n requestSha: attemptSha(plan.name, plan.text),\n msgId: newMsgId(),\n });\n return planned;\n })\n .immediate();\n}\n\n/**\n * Move the stored attempt `key` of a task to a terminal state (compare and\n * set on the key, so a newer attempt is never overwritten). A receipt that\n * never reached the send (reserved, pane, claimed) is failed with the reason;\n * a sending / unknown one is left as the evidence it is. False when the\n * record moved on.\n */\nexport function endAttempt(db: Db, taskId: number, key: string, end: AttemptEnd): boolean {\n return db\n .transaction((): boolean => {\n const { record, receipt } = readAttempt(db, taskId);\n if (record === undefined || record.key !== key || record.end !== undefined) return false;\n const changed = db\n .prepare(\"UPDATE task_auto SET last_spawn = ? WHERE task_id = ?\")\n .run(JSON.stringify({ ...record, end }), taskId).changes;\n if (changed !== 1) return false;\n if (receipt !== undefined && UNSENT_STATES.has(receipt.state)) {\n updateReceipt(db, taskId, key, { state: \"failed\", detail: `${end.state}: ${end.reason}` });\n }\n return true;\n })\n .immediate();\n}\n\n/** What `reserveRetry` needs of the worker observed to have stopped on an API error. */\nexport interface RetryTarget {\n /** The registry row the attempt saved: id + pane, and the name. */\n agent: { incarnation: number; paneId: string; name: string };\n /** pi's process incarnation the error was read from: the send is bound to it. */\n pi: string;\n /** pi's settled-run count of the errored run. */\n errorRuns: number;\n}\n\n/**\n * Charge one run and reserve an IN-PLACE retry of the delivered attempt, atomically\n * (see the file header): the same worker, the same task, a new `auto:<n>` key\n * whose receipt starts at `claimed` on the saved identity, so the guarded replay\n * skips the spawn and the claim and goes straight to the journaled send. Refuses\n * unless, in this transaction: the task is permitted and IN_PROGRESS, owned by the\n * very registry row the delivered attempt saved (id + pane), under its run\n * ceiling, and the error run is a newer one than the delivered send (so a retry\n * already sent is never charged twice for the same error).\n */\nexport function reserveRetry(\n db: Db,\n workstream: string,\n task: string,\n target: RetryTarget,\n): PlanResult {\n return db\n .transaction((): PlanResult => {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) return refuse(\"not-found\", `no task ${task} in ${workstream}`);\n if (!autoPermitted(db, taskId)) {\n return refuse(\"not-permitted\", `${task} is not authorised for this machine (mu task auto)`);\n }\n const { auto } = readAttempt(db, taskId);\n const delivered = deliveredOf(db, taskId);\n if (auto === undefined || delivered === undefined) {\n return refuse(\"changed\", `${task} has no delivered attempt`);\n }\n const { receipt } = delivered;\n const { agent } = target;\n if (\n receipt.agentId !== agent.incarnation ||\n receipt.paneId !== agent.paneId ||\n receipt.name !== agent.name ||\n savedIdentity(db, receipt).stale !== undefined\n ) {\n return refuse(\"changed\", `${task}: the worker is not the one its attempt delivered to`);\n }\n if (receipt.runs === null || target.errorRuns <= receipt.runs) {\n return refuse(\"changed\", `${task}: that error was already answered`);\n }\n const row = db.prepare(\"SELECT status, owner_id FROM tasks WHERE id = ?\").get(taskId) as {\n status: string;\n owner_id: number | null;\n };\n if (row.status !== \"IN_PROGRESS\" || row.owner_id !== agent.incarnation) {\n return refuse(\"changed\", `${task} is no longer in progress with ${agent.name}`);\n }\n if (auto.runs >= auto.maxRuns) {\n return refuse(\"ceiling\", `${task} used its ${auto.maxRuns} run(s)`);\n }\n let brief: ReturnType<typeof buildTaskBrief>;\n try {\n brief = buildTaskBrief(db, workstream, task, { retry: \"error\" });\n } catch (err) {\n if (err instanceof TaskBriefMissingError) return refuse(\"no-brief\", err.message);\n throw err;\n }\n const attempt = auto.runs + 1;\n const plan: AttemptPlan = {\n v: 1,\n attempt,\n key: `auto:${attempt}`,\n name: agent.name,\n cli: auto.cli,\n worktree: auto.worktree,\n text: brief.text,\n retry: true,\n inPlace: true,\n task,\n taskId,\n workstream,\n revision: taskRevision(db, workstream, task),\n };\n const { task: _t, taskId: _i, workstream: _w, revision: _r, ...stored } = plan;\n const charged = db\n .prepare(\n \"UPDATE task_auto SET runs = runs + 1, last_spawn = ? WHERE task_id = ? AND runs = ? AND enabled = 1\",\n )\n .run(JSON.stringify(stored), taskId, auto.runs);\n if (charged.changes !== 1) return refuse(\"changed\", `${task}'s run counter moved`);\n reserveReceipt(db, {\n taskId,\n attemptKey: plan.key,\n name: agent.name,\n workstream,\n requestSha: attemptSha(agent.name, plan.text),\n msgId: newMsgId(),\n });\n updateReceipt(db, taskId, plan.key, {\n state: \"claimed\",\n agentId: agent.incarnation,\n paneId: agent.paneId,\n incarnation: target.pi,\n });\n return { ok: true, plan };\n })\n .immediate();\n}\n","// mu — bounded open-task frontier read and its ASCII branch drawing, shared\n// by `mu task tree` and the dashboard.\n\nimport type { Db } from \"./db.js\";\nimport {\n type RawTaskRow,\n rowFromDb,\n SELECT_TASK_COLS,\n TASK_FROM_JOIN,\n type TaskRow,\n taskIdFor,\n} from \"./tasks.js\";\n\n/** Deepest level of a frontier read; a node past it keeps a `kids` count. */\nexport const FRONTIER_MAX_DEPTH = 12;\n/** Most distinct tasks one frontier read lists (recurrences are capped at the same number). */\nexport const FRONTIER_MAX_NODES = 2000;\n/** CLOSED neighbours listed under one node; the rest collapse into its `closed` count. */\nexport const FRONTIER_CLOSED_PER_NODE = 3;\n\nexport type FrontierDirection = \"blockers\" | \"dependents\";\n\n/** One line of the open task tree, in preorder. */\nexport interface FrontierEntry {\n task: TaskRow;\n /** 0 for a root. */\n depth: number;\n /** `local_id` of the entry it is listed under; null for a root. */\n parent: string | null;\n /** Already listed above (a diamond, or a cycle sync made): not expanded again. */\n again: boolean;\n /** Neighbours (in the read direction) that are not CLOSED and are not listed under this entry. */\n kids: number;\n /** CLOSED neighbours collapsed into this count instead of listed. */\n closed: number;\n /** Neighbours of any status the node cap left out (not in `kids` / `closed`). */\n capCut: number;\n}\n\nexport interface OpenTaskFrontier {\n direction: FrontierDirection;\n entries: FrontierEntry[];\n /** Start tasks left out by the node cap (only without a `root`). */\n rootsCut: number;\n /** Recurrence lines (diamonds) left out by the cap; every such task is listed elsewhere. */\n againCut: number;\n}\n\nexport interface OpenTaskFrontierOptions {\n /** Walk through CLOSED tasks too (still capped by depth and entries unless `uncapped`). */\n includeClosed?: boolean;\n /** No cap at all: CLOSED tasks walked, every level, every task, every recurrence (`task tree --all`). */\n uncapped?: boolean;\n /** Levels below a root to list (default and ceiling `FRONTIER_MAX_DEPTH`). */\n maxDepth?: number;\n}\n\n/**\n * The open part of the DAG, bounded: from `root` (always expanded, even when\n * CLOSED) or, without one, from every non-CLOSED task that has no non-CLOSED\n * predecessor; `direction` is the way to walk (dependents = what a task\n * blocks). A non-CLOSED task expands; a CLOSED one is a leaf, and only the\n * first `FRONTIER_CLOSED_PER_NODE` of a node's CLOSED neighbours are listed\n * (the rest are counted), so one umbrella with 870 closed children costs a\n * few lines. Depth is capped at `FRONTIER_MAX_DEPTH` and entries at\n * `FRONTIER_MAX_NODES`; what a cap leaves out is counted in `kids`. Diamonds\n * and cycles list a task once and mark later sightings `again`. One SQL read\n * per level (never per node), same-workstream edges only.\n */\nexport function loadOpenTaskFrontier(\n db: Db,\n workstream: string,\n root?: string,\n direction: FrontierDirection = \"dependents\",\n opts: OpenTaskFrontierOptions = {},\n): OpenTaskFrontier {\n const out: OpenTaskFrontier = { direction, entries: [], rootsCut: 0, againCut: 0 };\n const uncapped = opts.uncapped === true;\n const maxDepth = uncapped\n ? Number.POSITIVE_INFINITY\n : Math.min(opts.maxDepth ?? FRONTIER_MAX_DEPTH, FRONTIER_MAX_DEPTH);\n const maxNodes = uncapped ? Number.POSITIVE_INFINITY : FRONTIER_MAX_NODES;\n const closedPerNode = uncapped ? Number.POSITIVE_INFINITY : FRONTIER_CLOSED_PER_NODE;\n const wsRow = db\n .prepare(\"SELECT id FROM workstreams WHERE name = ? AND torn_down_at IS NULL\")\n .get(workstream) as { id: number } | undefined;\n if (wsRow === undefined) return out;\n const wsId = wsRow.id;\n const [from, to] =\n direction === \"dependents\" ? [\"from_task_id\", \"to_task_id\"] : [\"to_task_id\", \"from_task_id\"];\n const includeClosed = opts.includeClosed === true || uncapped;\n\n const nodes = new Map<number, TaskRow>();\n const rootIds = new Set<number>();\n let level: number[] = [];\n const startRows: RawTaskRow[] = [];\n if (root !== undefined) {\n const id = taskIdFor(db, root, workstream);\n if (id === null) return out;\n startRows.push(\n db\n .prepare(`SELECT ${SELECT_TASK_COLS} ${TASK_FROM_JOIN} WHERE t.id = ?`)\n .get(id) as RawTaskRow,\n );\n } else {\n // Open tasks nothing open blocks (dependents) / that block nothing open (blockers).\n startRows.push(\n ...(db\n .prepare(\n `SELECT ${SELECT_TASK_COLS} ${TASK_FROM_JOIN}\n WHERE t.workstream_id = ? AND t.status <> 'CLOSED'\n AND NOT EXISTS (SELECT 1 FROM task_edges e JOIN tasks p ON p.id = e.${from}\n WHERE e.${to} = t.id AND p.status <> 'CLOSED'\n AND p.workstream_id = t.workstream_id)\n ORDER BY t.local_id`,\n )\n .all(wsId) as RawTaskRow[]),\n );\n }\n for (const raw of startRows.slice(0, maxNodes)) {\n nodes.set(raw.id, rowFromDb(raw));\n rootIds.add(raw.id);\n level.push(raw.id);\n }\n const startCut = Math.max(0, startRows.length - maxNodes);\n\n const children = new Map<number, number[]>();\n const dropped = new Map<number, number>();\n const capDropped = new Map<number, number>();\n const closedHidden = new Map<number, number>();\n const expands = (id: number): boolean =>\n includeClosed || rootIds.has(id) || nodes.get(id)?.status !== \"CLOSED\";\n\n for (let depth = 0; level.length > 0; depth++) {\n const ids = level.filter(expands);\n if (ids.length === 0) break;\n if (depth >= maxDepth) {\n const counts: { src: number; open: number; closed: number }[] = [];\n for (let i = 0; i < ids.length; i += 500) {\n const chunk = ids.slice(i, i + 500);\n counts.push(\n ...(db\n .prepare(\n `SELECT e.${from} AS src,\n SUM(CASE WHEN t.status = 'CLOSED' AND ? = 0 THEN 0 ELSE 1 END) AS open,\n SUM(CASE WHEN t.status = 'CLOSED' AND ? = 0 THEN 1 ELSE 0 END) AS closed\n FROM task_edges e JOIN tasks t ON t.id = e.${to}\n WHERE e.${from} IN (${chunk.map(() => \"?\").join(\", \")}) AND t.workstream_id = ? GROUP BY e.${from}`,\n )\n .all(includeClosed ? 1 : 0, includeClosed ? 1 : 0, ...chunk, wsId) as {\n src: number;\n open: number;\n closed: number;\n }[]),\n );\n }\n for (const c of counts) {\n if (c.open > 0) dropped.set(c.src, (dropped.get(c.src) ?? 0) + c.open);\n if (c.closed > 0) closedHidden.set(c.src, (closedHidden.get(c.src) ?? 0) + c.closed);\n }\n break;\n }\n // Chunked: an uncapped level can hold more ids than SQLite takes as variables.\n const rows: (RawTaskRow & { src: number })[] = [];\n for (let i = 0; i < ids.length; i += 500) {\n const chunk = ids.slice(i, i + 500);\n rows.push(\n ...(db\n .prepare(\n `SELECT e.${from} AS src, ${SELECT_TASK_COLS}\n FROM task_edges e\n JOIN tasks t ON t.id = e.${to}\n JOIN workstreams ws ON ws.id = t.workstream_id AND ws.torn_down_at IS NULL\n LEFT JOIN agents ag ON ag.id = t.owner_id\n WHERE e.${from} IN (${chunk.map(() => \"?\").join(\", \")}) AND t.workstream_id = ?\n ORDER BY e.${from}, t.local_id`,\n )\n .all(...chunk, wsId) as (RawTaskRow & { src: number })[]),\n );\n }\n const next: number[] = [];\n const closedSeen = new Map<number, number>();\n // Rows come ordered by (parent, local_id). Once the node cap forces a drop, every later row\n // of the level is dropped too (seen or not).\n let capped = false;\n for (const row of rows) {\n const leaf = row.status === \"CLOSED\" && !includeClosed;\n if (!capped) {\n if (leaf) {\n const n = closedSeen.get(row.src) ?? 0;\n closedSeen.set(row.src, n + 1);\n if (n >= closedPerNode) {\n closedHidden.set(row.src, (closedHidden.get(row.src) ?? 0) + 1);\n continue;\n }\n }\n if (!nodes.has(row.id) && nodes.size >= maxNodes) capped = true;\n }\n if (capped) {\n capDropped.set(row.src, (capDropped.get(row.src) ?? 0) + 1);\n continue;\n }\n if (!nodes.has(row.id)) {\n nodes.set(row.id, rowFromDb(row));\n next.push(row.id);\n }\n const kids = children.get(row.src) ?? [];\n kids.push(row.id);\n children.set(row.src, kids);\n }\n level = next;\n }\n\n // Preorder over what was loaded; the entry cap counts recurrences too.\n const listed = new Set<number>();\n let recurrences = 0;\n const walk = (id: number, parent: string | null, depth: number): void => {\n const task = nodes.get(id);\n if (task === undefined) return;\n const entry: FrontierEntry = {\n task,\n depth,\n parent,\n again: false,\n kids: dropped.get(id) ?? 0,\n closed: closedHidden.get(id) ?? 0,\n capCut: capDropped.get(id) ?? 0,\n };\n out.entries.push(entry);\n listed.add(id);\n const kids = children.get(id) ?? [];\n if (depth >= maxDepth) {\n // The level cap holds for the walk too: a shared DAG loads nodes at a shallow\n // level that the walk first meets deep. What is not listed under this entry is counted.\n for (const child of kids) {\n if (nodes.get(child)?.status === \"CLOSED\" && !includeClosed) entry.closed++;\n else entry.kids++;\n }\n return;\n }\n for (const child of kids) {\n const c = nodes.get(child);\n if (c === undefined) continue;\n if (listed.has(child)) {\n if (recurrences >= maxNodes) {\n out.againCut++;\n entry.kids++;\n } else {\n recurrences++;\n out.entries.push({\n task: c,\n depth: depth + 1,\n parent: task.name,\n again: true,\n kids: 0,\n closed: 0,\n capCut: 0,\n });\n }\n continue;\n }\n walk(child, task.name, depth + 1);\n }\n };\n for (const id of [...rootIds].sort((a, b) =>\n (nodes.get(a)?.name ?? \"\").localeCompare(nodes.get(b)?.name ?? \"\"),\n )) {\n if (listed.has(id)) continue;\n walk(id, null, 0);\n }\n out.rootsCut = startCut;\n return out;\n}\n\n/** One ASCII tree line per frontier entry: the branch drawing, then `label(entry)`. */\nexport function renderFrontierLines(\n entries: readonly FrontierEntry[],\n label: (entry: FrontierEntry) => string,\n): string[] {\n const lines: string[] = [];\n const open: boolean[] = [];\n entries.forEach((e, i) => {\n if (e.depth === 0) {\n lines.push(label(e));\n return;\n }\n // Is there a later sibling (same depth, before the depth drops below it)?\n let last = true;\n for (let j = i + 1; j < entries.length; j++) {\n const d = entries[j]?.depth ?? 0;\n if (d < e.depth) break;\n if (d === e.depth) {\n last = false;\n break;\n }\n }\n open[e.depth] = !last;\n let prefix = \"\";\n for (let d = 1; d < e.depth; d++) prefix += open[d] ? \"│ \" : \" \";\n lines.push(`${prefix}${last ? \"└── \" : \"├── \"}${label(e)}`);\n });\n return lines;\n}\n","// mu — the ONE op → prose formatter.\n//\n// WHY THIS FILE EXISTS\n//\n// mu once rendered log lines by prefix-matching free prose: `classifyEventVerb`\n// walked `EVENT_VERB_PREFIXES` looking for a leading two-word verb, and\n// `CLAIM_EVENT_PREFIX` was bolted on because that matching kept breaking\n//. Rewording any payload silently\n// broke its renderer, and attribution had to be smuggled through a\n// tab-delimited prefix so it could be parsed back out.\n//\n// Since v2-capture + v2-retire-log-shim, every op carries a structured\n// `intent` ('task.close'), a natural `key` ('demo/t1'), and a JSON\n// payload holding ONLY the columns that changed. So rendering is a\n// lookup on intent, not a search through text. THIS FILE MUST NEVER\n// STRING-MATCH A PAYLOAD to decide what an op is — that is the exact\n// brittleness the ops log deletes. It reads `intent`, then pulls named fields\n// out of the parsed payload.\n//\n// Layering: pure and colour-free. `src/cli/format.ts` adds picocolors\n// for the terminal. It owns no prose logic — one formatter, shared by every\n// surface (ROADMAP: no second render layer).\n\nimport type { LocalIntent } from \"./logs.js\";\nimport { formatPair, resolvePair } from \"./tasks/status.js\";\n\n/** Every intent mu writes: the local ones (`emitEvent`, for changes no\n * trigger can see) plus the capture-trigger ones (set via\n * `withOpContext` around a portable-table mutation). */\nexport type CaptureIntent =\n | \"task.add\"\n | \"task.update\"\n | \"task.note\"\n | \"task.delete\"\n | \"task.close\"\n | \"task.open\"\n | \"task.park\"\n | \"task.unpark\"\n | \"task.accept\"\n | \"task.reject\"\n | \"task.defer\"\n | \"task.claim\"\n | \"task.release\"\n | \"task.reap\"\n | \"task.block\"\n | \"task.unblock\"\n | \"task.reparent\"\n | \"workstream.init\"\n | \"workstream.teardown\"\n // The settled-run close the executor applies (src/close-block.ts).\n | \"close.apply\"\n // Any write made through `mu sql`, on whichever portable table it hit.\n | \"sql.write\";\n\nexport type KnownIntent = CaptureIntent | LocalIntent;\n\n/** A log row, reduced to what rendering needs. Structural so both\n * `LogRow` (the SDK shape) and raw op rows satisfy it. */\nexport interface RenderableOp {\n intent: string | null;\n /** `ops.entity`. */\n kind: string;\n /** `ops.key` — the natural key, verbatim. */\n workstreamName: string | null;\n payload: string;\n /** `ops.actor`. */\n source: string;\n op?: string;\n}\n\n/** Rendered op, split so callers can colour the verb independently.\n * `subject` is the entity the line is about; `detail` is the\n * human-readable consequence. */\nexport interface RenderedOp {\n /** Operator-facing verb, e.g. 'task close'. Colour this. */\n verb: string;\n /** The entity acted on, already stripped of workstream scope. */\n subject: string;\n /** What changed, in prose. May be empty. */\n detail: string;\n}\n\n// ─── payload access ────────────────────────────────────────────────────\n\n/** Parse an op payload into a field bag. Tolerant by design: a payload\n * that is not JSON (operator prose from `mu log \"<text>\"`) yields an empty\n * bag rather than throwing, and the caller falls back to showing the\n * text verbatim. */\nfunction fields(payload: string): Record<string, unknown> {\n if (!payload.startsWith(\"{\")) return {};\n try {\n const parsed: unknown = JSON.parse(payload);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n return parsed as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nfunction str(bag: Record<string, unknown>, key: string): string | undefined {\n const v = bag[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction num(bag: Record<string, unknown>, key: string): number | undefined {\n const v = bag[key];\n return typeof v === \"number\" ? v : undefined;\n}\n\n/** Columns that are pure bookkeeping — never interesting on their own. */\nconst NOISE_FIELDS = new Set([\"updated_at\", \"created_at\"]);\n\n/** Field names, in the order a human wants to read them. */\nfunction changedFields(bag: Record<string, unknown>): string[] {\n return Object.keys(bag).filter((k) => !NOISE_FIELDS.has(k));\n}\n\n// ─── key parsing ───────────────────────────────────────────────────────\n\n/**\n * Split a natural key into workstream + local part.\n *\n * 'demo' -> { workstream: 'demo' }\n * 'demo/t1' -> { workstream: 'demo', local: 't1' }\n * 'demo/t1#3' -> { workstream: 'demo', local: 't1', note: '3' }\n * 'demo/a->demo/b' -> { workstream: 'demo', local: 'a', to: 'b' }\n */\nexport function parseOpKey(key: string | null): {\n workstream?: string;\n local?: string;\n note?: string;\n to?: string;\n} {\n if (key === null || key === \"\") return {};\n // Edge keys are '<ws>/<from>-><ws>/<to>'.\n const arrow = key.indexOf(\"->\");\n if (arrow !== -1) {\n const from = parseOpKey(key.slice(0, arrow));\n const to = parseOpKey(key.slice(arrow + 2));\n const out: { workstream?: string; local?: string; to?: string } = {};\n if (from.workstream !== undefined) out.workstream = from.workstream;\n if (from.local !== undefined) out.local = from.local;\n if (to.local !== undefined) out.to = to.local;\n return out;\n }\n const slash = key.indexOf(\"/\");\n if (slash === -1) return { workstream: key };\n const workstream = key.slice(0, slash);\n const rest = key.slice(slash + 1);\n const hash = rest.indexOf(\"#\");\n if (hash === -1) return { workstream, local: rest };\n return { workstream, local: rest.slice(0, hash), note: rest.slice(hash + 1) };\n}\n\n// ─── the formatter ─────────────────────────────────────────────────────\n\n/** Human verb per intent. Space-separated so it reads as a command,\n * matching how operators talk about these ('task close', not\n * 'task.close'). */\nconst VERBS: Record<KnownIntent, string> = {\n \"task.add\": \"task add\",\n \"task.update\": \"task update\",\n \"task.note\": \"task note\",\n \"task.delete\": \"task delete\",\n \"task.close\": \"task close\",\n \"close.apply\": \"close apply\",\n \"task.open\": \"task open\",\n \"task.park\": \"task park\",\n \"task.unpark\": \"task unpark\",\n \"task.accept\": \"task accept\",\n \"task.reject\": \"task reject\",\n \"task.defer\": \"task defer\",\n \"task.claim\": \"task claim\",\n \"task.release\": \"task release\",\n \"task.reap\": \"task reap\",\n \"task.block\": \"task block\",\n \"task.unblock\": \"task unblock\",\n \"task.reparent\": \"task reparent\",\n \"workstream.init\": \"workstream init\",\n \"workstream.teardown\": \"workstream teardown\",\n \"sql.write\": \"sql write\",\n \"agent.spawn\": \"agent spawn\",\n \"agent.spawn_failed\": \"agent spawn failed\",\n \"agent.close\": \"agent close\",\n \"agent.adopt\": \"agent adopt\",\n \"agent.kick\": \"agent kick\",\n \"agent.send\": \"agent send\",\n \"agent.abort\": \"agent abort\",\n // Payload prose reads \"agent stalled ...\"; keep the verb matching it\n // so the emitted text is not printed with a second, different verb.\n \"agent.stall\": \"agent stalled\",\n};\n\n/** Every intent this formatter knows, derived from the verb table so\n * the two can't drift. */\nexport const KNOWN_INTENTS: readonly KnownIntent[] = Object.keys(VERBS) as KnownIntent[];\n\n/** Every operator-facing verb the formatter can emit. Exported so audits\n * can check \"this emitter's verb is declared\" without re-deriving it\n * from the intent — the two are deliberately not always identical\n * (`agent.stall` renders as \"agent stalled\", matching its payload). */\nexport const KNOWN_VERBS: readonly string[] = Object.values(VERBS);\n\nfunction isKnownIntent(intent: string): intent is KnownIntent {\n return Object.hasOwn(VERBS, intent);\n}\n\n/**\n * Render one op as prose.\n *\n * Returns null when the row is not a rendered op at all — operator prose\n * from `mu log \"<text>\"` / a `--kind` ledger, which has no intent and\n * should be shown verbatim. Callers print `payload` in that case.\n */\nexport function renderOp(row: RenderableOp): RenderedOp | null {\n const intent = row.intent;\n if (intent === null) return null;\n\n // A bare status set (`setTaskStatus` with no more specific verb) uses\n // 'task.set-<status>' via intentIfUnset. Normalise it here rather than\n // enumerating six more table entries.\n const setPrefix = \"task.set-\";\n if (intent.startsWith(setPrefix)) {\n const status = intent.slice(setPrefix.length).toUpperCase();\n const { local } = parseOpKey(row.workstreamName);\n return { verb: \"task status\", subject: local ?? \"\", detail: `\\u2192 ${status}` };\n }\n\n if (!isKnownIntent(intent)) {\n // An intent this build does not know: written by a NEWER mu (ingested\n // from a peer's segment) or by a retired one ('migrate.*',\n // 'workstream.destroy', ...). Say only what the op row itself says:\n // the op (put or del), the key, the intent and entity verbatim, and the\n // NAMES of the changed columns. Never turn the intent into a command\n // verb ('workstream.delete' + op=put is not a delete), and never print a\n // JSON payload. A prose payload is the only information such a line\n // carries, so it follows. Not a throw: sync is never blocked by a\n // rendering gap.\n const parts = [`intent=${intent}`, `kind=${row.kind}`];\n if (row.payload.startsWith(\"{\")) {\n const patch = changedFields(fields(row.payload));\n if (patch.length > 0) parts.push(`patch=${patch.join(\",\")}`);\n } else if (row.payload !== \"\") {\n parts.push(`: ${oneLine(row.payload)}`);\n }\n return {\n verb: row.op === undefined ? \"op\" : `op ${row.op}`,\n subject: row.workstreamName ?? \"\",\n detail: parts.join(\" \"),\n };\n }\n // A note written inside another verb's op group (the close's evidence\n // note carries intent task.close) is still a note line.\n if (row.kind === \"note\" && row.op !== \"del\") return renderKnown(row, \"task.note\");\n return renderKnown(row, intent);\n}\n\n/** Split from `renderOp` so the switch is this function's ONLY exit\n * path: that is what makes TS treat it as exhaustive and reject a\n * missing `KnownIntent` case at COMPILE time (TS2366), instead of\n * silently falling through to a runtime default. */\nfunction renderKnown(row: RenderableOp, intent: KnownIntent): RenderedOp {\n const bag = fields(row.payload);\n const key = parseOpKey(row.workstreamName);\n const subject = key.local ?? key.workstream ?? \"\";\n const deleted = row.op === \"del\";\n\n // Exhaustive switch over the closed union: adding an intent to VERBS\n // without handling it here is a COMPILE error, not a runtime fallback.\n switch (intent) {\n case \"task.add\": {\n const impact = num(bag, \"impact\");\n const effort = num(bag, \"effort_days\");\n const title = str(bag, \"title\");\n const bits: string[] = [];\n if (title !== undefined) bits.push(`\"${title}\"`);\n if (impact !== undefined) bits.push(`impact=${impact}`);\n if (effort !== undefined) bits.push(`effort=${effort}`);\n return { verb: VERBS[intent], subject, detail: bits.join(\" \") };\n }\n case \"task.update\": {\n const changed = changedFields(bag);\n const detail = changed\n .map((f) => {\n const v = bag[f];\n return typeof v === \"object\" ? f : `${f}=${String(v)}`;\n })\n .join(\" \");\n // A payload of only updated_at is a parent-row touch (a note or\n // edge bumped its task). Say so rather than printing nothing.\n return { verb: VERBS[intent], subject, detail: detail === \"\" ? \"(touched)\" : detail };\n }\n case \"task.note\": {\n const author = str(bag, \"author\");\n const content = str(bag, \"content\") ?? \"\";\n const n = key.note;\n const head = n === undefined ? \"\" : `#${n} `;\n const by = author === undefined || author === \"\" ? \"\" : ` by ${author}`;\n return { verb: VERBS[intent], subject, detail: `${head}${oneLine(content)}${by}` };\n }\n case \"task.delete\":\n // Always a tombstone (op='del'), so the payload is '{}' — there is\n // nothing to report beyond the fact of it.\n return { verb: VERBS[intent], subject, detail: \"\" };\n case \"task.close\":\n case \"close.apply\":\n case \"task.open\":\n case \"task.reject\":\n case \"task.defer\": {\n const status = str(bag, \"status\");\n return {\n verb: VERBS[intent],\n subject,\n detail: status === undefined ? \"\" : `→ ${pairText(bag, status)}`,\n };\n }\n case \"task.park\":\n case \"task.unpark\":\n case \"task.accept\": {\n // All three stay OPEN, so the payload carries only the substate.\n const detail = str(bag, \"substate\") === undefined ? \"\" : `→ ${pairText(bag, \"OPEN\")}`;\n return { verb: VERBS[intent], subject, detail };\n }\n case \"task.claim\": {\n // The payload cannot name the actor on the `--self` path (owner_id\n // stays NULL by design), so attribution comes from ops.actor.\n const by = row.source === \"\" ? \"\" : `by ${row.source}`;\n const status = str(bag, \"status\");\n const tail = status === undefined ? \"\" : ` → ${status}`;\n return { verb: VERBS[intent], subject, detail: `${by}${tail}` };\n }\n case \"task.release\":\n case \"task.reap\": {\n const status = str(bag, \"status\");\n const bits: string[] = [];\n if (Object.hasOwn(bag, \"owner_id\") && bag.owner_id === null) bits.push(\"owner cleared\");\n if (status !== undefined) bits.push(`→ ${status}`);\n return { verb: VERBS[intent], subject, detail: bits.join(\" \") };\n }\n case \"task.block\":\n case \"task.unblock\":\n case \"task.reparent\": {\n // Edge ops carry the pair in the key; the task-row op that shares\n // the group is just a touch.\n if (key.to !== undefined) {\n const dir = intent === \"task.unblock\" ? \"no longer blocks\" : \"blocks\";\n return { verb: VERBS[intent], subject, detail: `${dir} ${key.to}` };\n }\n return { verb: VERBS[intent], subject, detail: deleted ? \"(edge removed)\" : \"(touched)\" };\n }\n case \"workstream.init\":\n return { verb: VERBS[intent], subject, detail: \"\" };\n case \"workstream.teardown\":\n return {\n verb: VERBS[intent],\n subject,\n detail: key.local === undefined ? \"\" : \"(cascaded)\",\n };\n case \"sql.write\": {\n // A raw write can hit any portable table, so name the entity and\n // the changed columns (values truncated: a note body is free text).\n if (deleted) return { verb: VERBS[intent], subject, detail: `${row.kind} deleted` };\n const edge = key.to === undefined ? \"\" : ` -> ${key.to}`;\n const changed = changedFields(bag)\n .map((f) => {\n const v = bag[f];\n return typeof v === \"object\" && v !== null ? f : `${f}=${oneLine(String(v))}`;\n })\n .join(\" \");\n return {\n verb: VERBS[intent],\n subject,\n detail: `${row.kind}${edge} ${changed === \"\" ? \"(touched)\" : changed}`,\n };\n }\n // Local intents: no trigger can see these, so `emitEvent` wrote the\n // payload as prose. It is already human-readable — show it as the\n // detail rather than inventing a second phrasing. The leading verb\n // is stripped so it is not printed twice.\n case \"agent.spawn\":\n case \"agent.spawn_failed\":\n case \"agent.close\":\n case \"agent.adopt\":\n case \"agent.kick\":\n case \"agent.send\":\n case \"agent.abort\":\n case \"agent.stall\": {\n const verb = VERBS[intent];\n // These payloads are prose by construction (emitEvent writes them).\n // Guard anyway: a JSON payload here would otherwise be dumped raw\n // into the line, and \"no raw JSON in mu log\" is a hard property.\n if (row.payload.startsWith(\"{\")) {\n const named = str(bag, \"name\") ?? subject;\n return { verb, subject: named, detail: changedFields(bag).join(\" \") };\n }\n const prose = row.payload.startsWith(verb)\n ? row.payload.slice(verb.length).trim()\n : row.payload;\n const firstSpace = prose.indexOf(\" \");\n const name = firstSpace === -1 ? prose : prose.slice(0, firstSpace);\n const rest = firstSpace === -1 ? \"\" : prose.slice(firstSpace + 1).trim();\n return { verb, subject: name, detail: rest };\n }\n }\n}\n\n/** \"CLOSED/wontfix\", or bare \"CLOSED\" for a default substate. */\nfunction pairText(bag: Record<string, unknown>, status: string): string {\n const pair = resolvePair(status, str(bag, \"substate\"));\n return pair === null ? status : formatPair(pair);\n}\n\n/** Collapse whitespace so free text is one line. Never shortens it: a record's\n * length is bounded (and its cut counted) at the output boundary, not here. */\nfunction oneLine(text: string): string {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Render an op as a single plain-text string. The convenience form for\n * callers that don't colour the verb separately (JSON `rendered` field,\n * TUI cards with their own column layout).\n */\nexport function renderOpLine(row: RenderableOp): string {\n const r = renderOp(row);\n if (r === null) return row.payload;\n return [r.verb, r.subject, r.detail].filter((s) => s !== \"\").join(\" \");\n}\n\n/**\n * The entity a row is about, for building a \"show me this\" command.\n * Reads `intent` + `key`, never prose.\n */\nexport function opSubject(row: RenderableOp): { kind: \"task\" | \"agent\"; id: string } | null {\n const intent = row.intent;\n if (intent === null) return null;\n const { local } = parseOpKey(row.workstreamName);\n if (intent.startsWith(\"task.\") && local !== undefined && local !== \"\") {\n return { kind: \"task\", id: local };\n }\n if (intent.startsWith(\"agent.\") && isKnownIntent(intent)) {\n const r = renderOp(row);\n if (r !== null && r.subject !== \"\") return { kind: \"agent\", id: r.subject };\n }\n return null;\n}\n","// mu wire contract: the one JSON document a `--json` invocation prints.\n//\n// success {\"ok\":true,\"data\":<payload>,\"next\":null}\n// failure {\"ok\":false,\"error\":<class>,\"message\":<one line>,\"next\":null,\"exit\":<n>}\n//\n// Both go to STDOUT (a failure with the real non-zero exit), so\n// `2>/dev/null` loses nothing. NDJSON log rows are not enveloped.\n//\n// Pure: no I/O, no mux, no DB. cli.ts (emitJson) and cli/handle.ts\n// (emitError) are the only writers.\n\n/** A follow-up plan: `seq` runs in order and is never truncated; `alt` offers alternatives. */\nexport type NextPlan = { mode: \"seq\" | \"alt\"; commands: string[] } | null;\n\nexport type Envelope<T> =\n | { ok: true; data: T; next: NextPlan }\n | {\n ok: false;\n error: string;\n message: string;\n next: NextPlan;\n /** The real process exit code that follows. */\n exit: number;\n /** Structured receipts kept beside the fixed keys (msgId, incarnation, delivery, usage…). */\n extra?: Record<string, unknown>;\n /** Partial evidence the failed verb already produced (a spawn whose --send failed). */\n data?: T;\n };\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching SGR escapes is the point\nconst SGR = /\\u001b\\[[0-9;]*m/g;\nconst stripAnsi = (s: string): string => s.replace(SGR, \"\");\n\n/**\n * Re-escape the characters JSON.stringify leaves raw but a terminal or line\n * tool treats specially (DEL, C1 controls incl. 8-bit CSI/NEL, bidi controls,\n * U+2028/9) as `\\uXXXX` JSON escapes: still valid, lossless JSON, one inert line.\n */\nexport function safeJsonLine(json: string): string {\n return json.replace(\n /[\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069]/gu,\n (c) => `\\\\u${(c.codePointAt(0) ?? 0).toString(16).padStart(4, \"0\")}`,\n );\n}\n\n/**\n * One line of JSON, no trailing newline, inert (see safeJsonLine). Every JSON\n * document goes through here, so a size measured on this string is the size emitted.\n * Error text is ANSI-free; `extra` never shadows a fixed key.\n */\nexport function encodeEnvelope<T>(envelope: Envelope<T>): string {\n return safeJsonLine(encodeEnvelopeRaw(envelope));\n}\n\nfunction encodeEnvelopeRaw<T>(envelope: Envelope<T>): string {\n if (envelope.ok) {\n return JSON.stringify({ ok: true, data: envelope.data, next: envelope.next });\n }\n const { extra, data } = envelope;\n const doc: Record<string, unknown> = {\n ok: false,\n error: stripAnsi(envelope.error),\n message: stripAnsi(envelope.message),\n next: envelope.next,\n exit: envelope.exit,\n };\n for (const [k, v] of Object.entries(extra ?? {})) if (!(k in doc)) doc[k] = v;\n if (data !== undefined && !(\"data\" in doc)) doc.data = data;\n return JSON.stringify(doc);\n}\n\n/** True only for an explicit success envelope: exactly `ok:true`, `data`, `next`. Never sniffs `data.ok`. */\nexport function isEnvelope(value: unknown): value is Extract<Envelope<unknown>, { ok: true }> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n return (\n keys.length === 3 &&\n (value as { ok?: unknown }).ok === true &&\n \"data\" in value &&\n \"next\" in value\n );\n}\n\n/** Wrap a payload as a success envelope exactly once (an envelope passes through). */\nexport function okEnvelope<T>(data: T): Extract<Envelope<T>, { ok: true }> {\n if (isEnvelope(data)) return data as Extract<Envelope<T>, { ok: true }>;\n return { ok: true, data, next: null };\n}\n\n/** Default byte budget for one result. */\nexport const RESULT_BYTES = 4096;\n","// mu — the durable human-needed stop (`mu human-needed <reason>`).\n//\n// The state-armed loop stops for exactly one reason of its own: a person must\n// decide. The caller records that explicitly; no error or refusal does.\n// A need is a `human` task, OPEN/parked (never ready, never auto, never\n// claimed: HumanTaskError), whose brief note holds the reason. Its caller\n// lives in the machine-local `human_needs` row (rebuild cannot restore it;\n// a note author is never trusted for ownership). The task closes only by an\n// explicit `mu task close`.\n\nimport { type Db, resolveWorkstreamId } from \"./db.js\";\nimport { withOpContext } from \"./op-context.js\";\nimport { addTasks, insertNote } from \"./tasks/edit.js\";\n\n/** A blank reason or caller: nothing is recorded (exit 2). */\nexport class HumanNeededInvalidError extends Error {\n override readonly name = \"HumanNeededInvalidError\";\n}\n\nexport interface HumanNeededOptions {\n workstream: string;\n /** Who is stopping: `spawnerFromEnv()` (managed `<ws>/<agent>` or `pi:<session>`). */\n caller: string;\n reason: string;\n}\n\nexport interface HumanNeeded {\n workstream: string;\n id: string;\n reason: string;\n}\n\nconst TITLE_CHARS = 60;\n\n/**\n * Record (or extend) the caller's open human need in a workstream, in ONE\n * transaction. Same caller + workstream with an open need: the same reason\n * is a no-op (`changed: false`), a different one appends a brief to it.\n */\nexport function recordHumanNeeded(\n db: Db,\n opts: HumanNeededOptions,\n): { id: string; changed: boolean } {\n const reason = opts.reason.trim();\n const caller = opts.caller.trim();\n if (reason === \"\") throw new HumanNeededInvalidError(\"human-needed: reason is blank\");\n if (caller === \"\") {\n throw new HumanNeededInvalidError(\n \"human-needed: no caller identity (run inside a mu agent or a pi session)\",\n );\n }\n return withOpContext(db, { intent: \"task.note\", actor: caller, group: \"new\" }, () =>\n db\n .transaction(() => {\n const open = openNeedFor(db, caller, opts.workstream);\n if (open !== undefined) {\n if (open.briefs.includes(reason)) return { id: open.id, changed: false };\n insertNote(db, open.id, reason, {\n workstream: opts.workstream,\n author: caller,\n kind: \"brief\",\n });\n return { id: open.id, changed: true };\n }\n const title = `human needed: ${reason.replace(/\\s+/g, \" \").slice(0, TITLE_CHARS)}`;\n const { ids } = addTasks(db, [{ title, note: reason }], {\n workstream: opts.workstream,\n kind: \"human\",\n noteAuthor: caller,\n });\n const id = ids[0];\n if (id === undefined) throw new Error(\"recordHumanNeeded: no task created\");\n const taskId = (\n db\n .prepare(\"SELECT id FROM tasks WHERE workstream_id = ? AND local_id = ?\")\n .get(resolveWorkstreamId(db, opts.workstream), id) as { id: number }\n ).id;\n db.prepare(\"INSERT INTO human_needs (task_id, caller) VALUES (?, ?)\").run(taskId, caller);\n return { id, changed: true };\n })\n .immediate(),\n );\n}\n\ninterface OpenNeedRow {\n taskId: number;\n id: string;\n workstream: string;\n}\n\nfunction openNeedRows(db: Db, caller: string, workstream?: string): OpenNeedRow[] {\n return db\n .prepare(\n `SELECT t.id AS taskId, t.local_id AS id, w.name AS workstream\n FROM human_needs h\n JOIN tasks t ON t.id = h.task_id\n JOIN workstreams w ON w.id = t.workstream_id\n WHERE h.caller = ? AND t.kind = 'human' AND t.status = 'OPEN'\n AND w.torn_down_at IS NULL AND (? IS NULL OR w.name = ?)\n ORDER BY t.id`,\n )\n .all(caller, workstream ?? null, workstream ?? null) as OpenNeedRow[];\n}\n\nfunction briefsOf(db: Db, taskId: number): string[] {\n return (\n db\n .prepare(\"SELECT content FROM task_notes WHERE task_id = ? AND kind = 'brief' ORDER BY id\")\n .all(taskId) as { content: string }[]\n ).map((r) => r.content);\n}\n\nfunction openNeedFor(\n db: Db,\n caller: string,\n workstream: string,\n): { id: string; briefs: string[] } | undefined {\n const row = openNeedRows(db, caller, workstream).at(-1);\n return row === undefined ? undefined : { id: row.id, briefs: briefsOf(db, row.taskId) };\n}\n\n/** The caller's OPEN human needs, oldest first, across workstreams. Another\n * caller's need never appears. Reasons of an extended need join with \"; \". */\nexport function openHumanNeeds(db: Db, caller: string): HumanNeeded[] {\n return openNeedRows(db, caller).map((r) => ({\n workstream: r.workstream,\n id: r.id,\n reason: briefsOf(db, r.taskId).join(\"; \"),\n }));\n}\n","// mu — `computeNext`: the ONE rule set behind every `next` (slice A of v_hints).\n//\n// A result's `next` (src/output-contract.ts `NextPlan`) is computed here, over\n// current state plus what the verb that just ran did (`NextOutcome`), and\n// nowhere else. The dashboard asks the same function with no outcome.\n//\n// Contract (docs/reference/surface-contract.md \"Next\"):\n// - READ-ONLY. It reads SQLite (and, through `expectsCtl`, whether a control\n// socket file exists). It never waits, registers, reaps, ingests, spawns or\n// runs what it suggests; it never consumes a cursor.\n// - Only state-advancing moves that are already authorised: the exact wait a\n// send owes, the stored resume of a wait, the apply of a preview (fenced\n// with `--if <rev>`), the brief a `claim --for` owes, `mu next` over tasks\n// the orchestrator authorised HERE, and the bare wait over refs the\n// callers already own. Reads (show/notes/list/read/log/check-by-guess) are\n// never suggested. Usually the plan is null.\n// - A move mu cannot fill is omitted: no `<…>`, `...`, `a|b`, no guessed flag\n// (`agent check` has no `--inc`, so an unknown delivery is suggested only\n// while the registry row the send went to is still the one registered).\n// - Never a resend. A refused delegate call is reissued by the pi tool\n// `mu_delegate_reissue`, not a shell, so it is never in `next`.\n// - Executable as printed: every command is an argv rendered word by word\n// with `shellWord` (POSIX single quotes). Safe moves rank before\n// destructive ones; a destructive move without `--if` is refused here.\n// - `seq` is never truncated: `capPlan` drops a too-big seq whole, and cuts\n// an `alt` from its tail.\n\nimport { expectsCtl } from \"./agents/transport.js\";\nimport { getAgent } from \"./agents.js\";\nimport { pendingAttempts } from \"./auto-attempt.js\";\nimport type { Db } from \"./db.js\";\nimport { openHumanNeeds } from \"./human-needed.js\";\nimport type { NextPlan } from \"./output-contract.js\";\nimport { shellWord } from \"./shell-quote.js\";\nimport { authorisedReady } from \"./task-auto.js\";\nimport { readWaitRegistration } from \"./wait-registration.js\";\nimport { isScratchWorkstream } from \"./workstream.js\";\n\n/** An agent as a hint names it: its workstream and name. */\nexport interface NextAgent {\n workstream: string;\n name: string;\n}\n\n/** What the verb that just ran did, as far as a follow-up depends on it. */\nexport type NextOutcome =\n /** A delivered send (also `spawn --send`/`--task`, `--fresh`, `--interrupt`): the baseline the SEND measured. */\n | { kind: \"sent\"; agent: NextAgent; runs?: number; incarnation?: string }\n /** A send written but unconfirmed: `msgId` and the registry id (`AgentRow.incarnation`) it went to. */\n | { kind: \"send-unknown\"; agent: NextAgent; msgId: string; agentId: number }\n /** A remote command gate spawned: its wait returns the command's exit. */\n | { kind: \"gate-spawned\"; agent: NextAgent }\n /** `task claim --for`: the owner still has to be sent the task. `muxCanSend: false` (tmux):\n * a non-pi owner cannot be sent anything, so no send is offered. */\n | {\n kind: \"claimed-for\";\n task: { workstream: string; id: string };\n owner: NextAgent;\n muxCanSend?: boolean;\n }\n /** A destructive preview: `apply` is the verb's argv (from `mu`), `revision` its fence. */\n | { kind: \"preview\"; apply: readonly string[]; revision: number }\n /** A wait ended with something still owed: its stored handle. */\n | { kind: \"waited\"; resumeId: string | null; scope?: string };\n\nexport interface NextContext {\n /** `currentCallers()`: the managed `<ws>/<agent>` and `pi:<session>`. Empty = no owned work. */\n callers: readonly string[];\n /** The resolved scope of the call, when it has one. */\n workstream?: string;\n outcome?: NextOutcome;\n /**\n * Whether the verb that just ran registered owed work (`armWait`). The CLI passes it, so\n * the bare wait follows only a command that created something to wait for; a read or an\n * unrelated write is not followed by it. Absent (the dashboard, no verb): any owed ref counts.\n */\n armed?: boolean;\n}\n\n/** One move: the argv as typed (`mu` first). Destructive moves must carry `--if`. */\nexport interface HintMove {\n argv: readonly string[];\n destructive?: boolean;\n}\n\n/** A destructive move without its revision fence. */\nexport class UnguardedMoveError extends Error {\n override readonly name = \"UnguardedMoveError\";\n}\n\n/** The `next` byte budget, a share of the 4 KB result (`RESULT_BYTES`). */\nexport const NEXT_BYTES = 1024;\n\n/** The most alternatives one plan offers. */\nexport const MAX_ALTERNATIVES = 3;\n\n/** The prompt that hands a claimed task to its owner. Message text (v_hint_messages owns the wording). */\nexport function dispatchPrompt(task: { workstream: string; id: string }): string {\n return `Claim done: work on ${task.id}. Read: mu task notes ${task.id} -w ${task.workstream}`;\n}\n\n/** `agent:<ws>/<name>[@<runs>][#<incarnation>]`: the typed ref a wait takes. */\nexport function agentRefOf(\n agent: { name: string; workstreamName: string },\n runs?: number,\n incarnation?: string,\n): string {\n return `agent:${agent.workstreamName}/${agent.name}${runs === undefined ? \"\" : `@${runs}`}${incarnation === undefined ? \"\" : `#${incarnation}`}`;\n}\n\n/** The one resume of a stored wait handle (`mu wait --resume <id>`), as argv. */\nexport function resumeArgv(id: string, scope?: string): string[] {\n return [\"mu\", \"wait\", \"--resume\", id, ...(scope === undefined ? [] : [\"-w\", scope])];\n}\n\n/** One command line, each word POSIX-quoted only when it needs it. */\nexport function renderArgv(argv: readonly string[]): string {\n if (argv[0] !== \"mu\") throw new Error(`a next move starts with mu (got ${argv[0] ?? \"nothing\"})`);\n return argv.map(shellWord).join(\" \");\n}\n\n/**\n * The plan for `moves` in order: safe moves first (stable), duplicates dropped, at most\n * MAX_ALTERNATIVES for `alt`. A `seq` is kept whole. null for no moves.\n */\nexport function renderPlan(mode: \"seq\" | \"alt\", moves: readonly HintMove[]): NextPlan {\n for (const m of moves) {\n if (m.destructive === true && !m.argv.includes(\"--if\")) {\n throw new UnguardedMoveError(`destructive move without --if: ${m.argv.join(\" \")}`);\n }\n }\n const ordered = mode === \"seq\" ? moves : [...moves].sort((a, b) => rank(a) - rank(b));\n const commands = [...new Set(ordered.map((m) => renderArgv(m.argv)))];\n const kept = mode === \"alt\" ? commands.slice(0, MAX_ALTERNATIVES) : commands;\n return kept.length === 0 ? null : { mode, commands: kept };\n}\n\nconst rank = (m: HintMove): number => (m.destructive === true ? 1 : 0);\n\nconst utf8 = (s: string): number => Buffer.byteLength(s, \"utf8\");\n\n/**\n * Fit a plan into `bytes` (its JSON encoding). A `seq` that does not fit is dropped WHOLE\n * (never a partial sequence); an `alt` loses alternatives from its tail. `cut` counts the\n * commands left out.\n */\nexport function capPlan(plan: NextPlan, bytes = NEXT_BYTES): { next: NextPlan; cut: number } {\n if (plan === null || utf8(JSON.stringify(plan)) <= bytes) return { next: plan, cut: 0 };\n if (plan.mode === \"seq\") return { next: null, cut: plan.commands.length };\n const commands = [...plan.commands];\n while (commands.length > 0 && utf8(JSON.stringify({ mode: \"alt\", commands })) > bytes) {\n commands.pop();\n }\n const cut = plan.commands.length - commands.length;\n return { next: commands.length === 0 ? null : { mode: \"alt\", commands }, cut };\n}\n\n/** The follow-up of what the verb did: at most one move, none when mu cannot fill it. */\nfunction outcomeMove(db: Db, o: NextOutcome): HintMove | undefined {\n switch (o.kind) {\n case \"sent\":\n if (o.runs === undefined) return undefined; // a mux send or a slash command started no fenced run\n return {\n argv: [\"mu\", \"wait\", agentRefOf(agentLike(o.agent), o.runs, o.incarnation)],\n };\n case \"send-unknown\": {\n // The receipt route, never a resend. `agent check` probes the name's CURRENT socket and has\n // no incarnation flag, so it is offered only while the row the send went to is still there.\n const row = getAgent(db, o.agent.name, o.agent.workstream);\n if (row === undefined || row.incarnation !== o.agentId) return undefined;\n return {\n argv: [\"mu\", \"agent\", \"check\", o.agent.name, o.msgId, \"-w\", o.agent.workstream, \"--json\"],\n };\n }\n case \"gate-spawned\":\n return { argv: [\"mu\", \"wait\", agentRefOf(agentLike(o.agent))] };\n case \"claimed-for\": {\n const owner = getAgent(db, o.owner.name, o.owner.workstream);\n if (owner === undefined) return undefined;\n const ctl = expectsCtl(owner);\n if (!ctl && o.muxCanSend === false) return undefined;\n const fresh = ctl ? [\"--fresh\"] : [];\n return {\n argv: [\n \"mu\",\n \"agent\",\n \"send\",\n owner.name,\n ...fresh,\n dispatchPrompt(o.task),\n \"-w\",\n owner.workstreamName,\n ],\n };\n }\n case \"preview\":\n return { argv: [...o.apply, \"--if\", String(o.revision)], destructive: true };\n case \"waited\":\n if (o.resumeId === null) return undefined;\n return { argv: resumeArgv(o.resumeId, o.scope) };\n }\n}\n\nconst agentLike = (a: NextAgent) => ({ name: a.name, workstreamName: a.workstream });\n\n/** Authorised work this machine's executor would act on now (stored attempts or ready auto tasks). */\nfunction executorMove(db: Db, ws: string): HintMove | undefined {\n if (isScratchWorkstream(ws)) return undefined;\n if (pendingAttempts(db, ws).length === 0 && authorisedReady(db, ws).length === 0) {\n return undefined;\n }\n return { argv: [\"mu\", \"next\", \"-w\", ws] };\n}\n\n/** The callers own registered refs (in `ws` when scoped): the bare wait picks them up. */\nfunction ownedWaitMove(db: Db, callers: readonly string[], ws?: string): HintMove | undefined {\n const owes = callers.some((c) =>\n (readWaitRegistration(db, c)?.refs ?? []).some((r) => ws === undefined || r.workstream === ws),\n );\n if (!owes) return undefined;\n return { argv: ws === undefined ? [\"mu\", \"wait\"] : [\"mu\", \"wait\", \"-w\", ws] };\n}\n\n/** A course check is due after this many CLOSED/done work tasks since the last one... */\nexport const COURSE_CHECK_CLOSED = 10;\n/** ...or this long since it (with at least one closed since). Constants: no flag, no env. */\nexport const COURSE_CHECK_AGE_MS = 24 * 3600_000;\n\n/**\n * The course-correct trigger (skills/mu/recipes/course-correct.md), read from\n * state, never remembered: since the newest note of `ws` starting `COURSE CHECK` (none: the\n * workstream's creation), count the CLOSED/done work tasks by their close note's time (a later\n * note does not move it). One line when due, else undefined.\n * Read-only; one query.\n */\nexport function courseCheckHint(db: Db, ws: string, now = Date.now()): string | undefined {\n const row = db\n .prepare(\n `WITH w AS (SELECT id, created_at FROM workstreams WHERE name = ? AND torn_down_at IS NULL),\n a AS (SELECT COALESCE(\n (SELECT MAX(n.created_at) FROM task_notes n JOIN tasks t ON t.id = n.task_id\n WHERE t.workstream_id = w.id AND n.content LIKE 'COURSE CHECK%'),\n w.created_at) AS since, w.id AS wid FROM w)\n SELECT a.since AS since,\n (SELECT COUNT(*) FROM tasks t WHERE t.workstream_id = a.wid AND t.status = 'CLOSED'\n AND t.substate = 'done' AND t.kind = 'work' AND (SELECT MAX(c.created_at)\n FROM task_notes c WHERE c.task_id = t.id AND c.kind = 'close') > a.since) AS closed\n FROM a`,\n )\n .get(ws) as { since: string; closed: number } | undefined;\n if (row === undefined || row.closed === 0) return undefined;\n const old = now - Date.parse(row.since) >= COURSE_CHECK_AGE_MS;\n if (row.closed < COURSE_CHECK_CLOSED && !old) return undefined;\n return `course check due: ${row.closed} closed since ${row.since.slice(0, 16)}Z. Stop dispatching: finish merging, then follow recipes/course-correct.md`;\n}\n\n/**\n * The `next` of a result: the outcome's own follow-up first, then (unless a caller has an\n * open human need, which stops everything it would start) `mu next` over authorised work and\n * the bare wait over owned refs (only after a verb that armed one), as alternatives. A preview's apply ranks last. Read-only.\n */\nexport function computeNext(db: Db, ctx: NextContext): NextPlan {\n const moves: HintMove[] = [];\n const own = ctx.outcome === undefined ? undefined : outcomeMove(db, ctx.outcome);\n if (own !== undefined) moves.push(own);\n const stopped = ctx.callers.some((c) => openHumanNeeds(db, c).length > 0);\n if (!stopped && ctx.outcome?.kind !== \"preview\") {\n const exec = ctx.workstream === undefined ? undefined : executorMove(db, ctx.workstream);\n if (exec !== undefined) moves.push(exec);\n // The bare wait is redundant beside a more exact wait.\n if (ctx.armed !== false && (own === undefined || own.argv[1] !== \"wait\")) {\n const wait = ownedWaitMove(db, ctx.callers, ctx.workstream);\n if (wait !== undefined) moves.push(wait);\n }\n }\n return capPlan(renderPlan(\"alt\", moves)).next;\n}\n\n/**\n * The one-line notices of a result, beside its `next` (they are not commands): today only\n * `courseCheckHint` for the call's workstream. `mu state` and `mu wait` print them as\n * `data.notices` (`noticesField`); empty when nothing is due. Read-only.\n */\nexport function computeNotices(db: Db, ctx: NextContext, now = Date.now()): string[] {\n const hint =\n ctx.workstream === undefined || isScratchWorkstream(ctx.workstream)\n ? undefined\n : courseCheckHint(db, ctx.workstream, now);\n return hint === undefined ? [] : [hint];\n}\n\n/** `computeNotices` over each workstream a result covers, in order, as `data.notices` (absent when empty). */\nexport function noticesField(\n db: Db,\n workstreams: readonly string[],\n now = Date.now(),\n): { notices?: string[] } {\n const notices = [...new Set(workstreams)].flatMap((workstream) =>\n computeNotices(db, { callers: [], workstream }, now),\n );\n return notices.length > 0 ? { notices } : {};\n}\n","// mu — the sync seam: peer status, the ambient hook, and the two power\n// tools behind `mu sync`.\n//\n// WHAT LIVES HERE AND WHAT DOES NOT\n// ---------------------------------\n// `src/segments.ts` owns the MECHANISM (flush / ingest / watermarks /\n// the four robustness layers). This file owns the OPERATOR-FACING\n// questions that mechanism cannot answer on its own:\n//\n// - who are my peers, how far behind am I, when did I last hear from\n// them (`peerStatuses`)\n// - the AMBIENT hook every mu invocation runs (`ambientIngest` /\n// `ambientFlush`)\n// - a DIFFERENT READER: a peer's `ops` table read straight out of a\n// copied / sshfs-mounted `mu.db` (`ingestFromDb`)\n// - the universal repair: reset a watermark and re-read from zero\n// (`repairPeer`)\n//\n// AMBIENT, NOT A DAEMON\n// ---------------------\n// There is no watcher, no background process, and no polling loop that\n// outlives the command. Sync happens because you already run `mu`\n// constantly: every invocation ingests before the verb body and flushes\n// after it. With `MU_SYNC_DIR` unset both halves are a single `if` that\n// reads one env var, so the single-machine case pays nothing. With 2-5\n// peers it is a handful of `stat`/`read` calls on small append-only\n// files.\n//\n// The TUI is the one long-lived surface, and it hangs the same pass off\n// its SLOW tick (10s), never the 1s fast tick — sync is filesystem work\n// and has no business on a repaint cadence.\n//\n// SYNC MUST NEVER FAIL A COMMAND\n// ------------------------------\n// A truncated segment, an unreadable sync dir, a full disk: all of them\n// warn and return. `mu task add` has to work when sync is broken,\n// because the alternative is a tool that stops working when a folder you\n// do not control misbehaves. Every ambient entry point here is\n// try/catch-total by construction (see `ambientIngest`).\n//\n// TRANSPORT STAYS THE OPERATOR'S\n// ------------------------------\n// mu reads and writes FILES. It does not shell out to ssh/scp/rsync, and\n// it will not grow `--push <host>`: that is a remote backend wearing a\n// small hat (ssh config, jump hosts, ProxyCommand, ports, identity\n// files, interactive prompts inside a TUI tick, network-vs-auth error\n// mapping), and it violates the standing ROADMAP pledge that the user\n// owns transport. `mu sync` reports a stale peer (`stale: true`); moving\n// its segment (Syncthing, rsync, a USB stick) is the operator's.\n\nimport { existsSync, statSync } from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type { Op } from \"./apply.js\";\nimport { CURRENT_SCHEMA_VERSION, type Db, SYNCED_ENTITIES } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { isJsonMode } from \"./output.js\";\nimport {\n applyIncomingOp,\n discoverPeers,\n type FlushResult,\n flushSegment,\n getWatermark,\n type IngestResult,\n ingestSegment,\n localMachineId,\n peerWatermarkKey,\n resetWatermark,\n type SegmentDefect,\n segmentCaughtUp,\n segmentLineCount,\n syncDir,\n} from \"./segments.js\";\n\n/** No discovered peer matches the operator's `--repair <peer>` ref.\n * Exit 3 (not found), like every other resolve-time miss. */\nexport class SyncPeerNotFoundError extends Error {\n override readonly name = \"SyncPeerNotFoundError\";\n constructor(\n readonly ref: string,\n readonly known: readonly string[],\n ) {\n super(say(\"sync.peer_not_found\", ref, known));\n }\n}\n\n/** A `--repair <peer>` prefix matched several peers. A conflict (exit 4),\n * never a guess — the same rule `mu log --group` follows for\n * abbreviated group ids. */\nexport class SyncPeerRefAmbiguousError extends Error {\n override readonly name = \"SyncPeerRefAmbiguousError\";\n constructor(\n readonly ref: string,\n readonly candidates: readonly string[],\n ) {\n super(say(\"sync.peer_ambiguous\", ref, candidates));\n }\n}\n\n/** `mu sync --from <path>` pointed at a file that is not there. Exit 3. */\nexport class SyncSourceNotFoundError extends Error {\n override readonly name = \"SyncSourceNotFoundError\";\n constructor(readonly path: string) {\n super(say(\"sync.source_missing\", path));\n }\n}\n\n/** `mu sync --from <db>` pointed at a DB written by a newer mu. Its ops\n * may carry fields this build would half-apply, which is exactly what a\n * segment line's version prevents; this path has no such line. Exit 4. */\nexport class SyncSourceTooNewError extends Error {\n override readonly name = \"SyncSourceTooNewError\";\n constructor(\n readonly path: string,\n readonly detectedVersion: number,\n ) {\n super(say(\"sync.source_too_new\", path, detectedVersion, CURRENT_SCHEMA_VERSION));\n }\n}\n\n/** A peer whose segment has not moved in this long is reported STALE.\n * A fixed constant, not an env var: it is a display threshold, and mu's\n * whole cluster configuration is deliberately ONE env var. */\nexport const PEER_STALE_MS = 24 * 60 * 60 * 1000;\n\n/** How many characters of a `machine_id` uuid we show. Peers are known\n * only by uuid — `machine_identity.hostname` is machine-LOCAL and never\n * ships, so mu genuinely cannot render a peer's hostname without\n * inventing a membership file. A short prefix is the honest display,\n * and every verb that takes one accepts any unique prefix (the\n * affordance git gives for shas). */\nexport const PEER_SHORT_LEN = 8;\n\nexport interface PeerStatus {\n machineId: string;\n /** First `PEER_SHORT_LEN` chars of the machine id, for display. */\n short: string;\n path: string;\n /** True for a Syncthing-style `*.sync-conflict-*.jsonl` copy. */\n conflictCopy: boolean;\n /** `sync_peers` key of this file's watermark (see `PeerSegment`).\n * `peerStatuses` always sets it. Optional so SDK callers that build\n * the pre-watermarkKey shape still compile; absent means the machine\n * id (`peerWatermarkKey`). */\n watermarkKey?: string;\n /** Lines of this segment file already applied. */\n watermark: number;\n /** GOOD lines currently in the segment (a defect stops the count). */\n total: number;\n /** `total - watermark`: how much of what we HOLD is not yet applied.\n * Non-zero after a defect stopped an ingest short, or mid-transfer. */\n behind: number;\n /** Segment mtime in epoch ms — when transport last delivered. */\n lastSeenMs: number | null;\n /** Age of the segment file, ms. Null when it does not exist. */\n ageMs: number | null;\n stale: boolean;\n}\n\n/** Peer table for the sync dir, newest contact first. Pure read: it\n * neither flushes nor ingests, so `mu sync` can call it after its own\n * pass and the TUI could call it on a tick. */\nexport function peerStatuses(db: Db, dir: string): PeerStatus[] {\n const self = localMachineId(db);\n const now = Date.now();\n const rows = discoverPeers(dir, self).map((peer) => {\n let lastSeenMs: number | null = null;\n try {\n lastSeenMs = statSync(peer.path).mtimeMs;\n } catch {\n lastSeenMs = null;\n }\n const watermarkKey = peerWatermarkKey(peer);\n const watermark = getWatermark(db, watermarkKey);\n // Caught up: the count is the watermark, no need to decode the file.\n const total = segmentCaughtUp(db, watermarkKey, peer.path, watermark)\n ? watermark\n : segmentLineCount(peer.path);\n const ageMs = lastSeenMs === null ? null : Math.max(0, now - lastSeenMs);\n return {\n machineId: peer.machineId,\n short: peer.machineId.slice(0, PEER_SHORT_LEN),\n path: peer.path,\n conflictCopy: peer.conflictCopy,\n watermarkKey,\n watermark,\n total,\n behind: Math.max(0, total - watermark),\n lastSeenMs,\n ageMs,\n stale: ageMs === null || ageMs > PEER_STALE_MS,\n };\n });\n return rows.sort((a, b) => (b.lastSeenMs ?? 0) - (a.lastSeenMs ?? 0));\n}\n\n/** Resolve an operator-typed peer reference (full machine id, or any\n * unique prefix) against the discovered peers. Ambiguity is a\n * UsageError, never a guess — repairing the wrong peer would re-read a\n * whole segment for nothing and confuse the report.\n *\n * A ref names a MACHINE, so a segment and its conflict copies (same\n * machine id) count as one match; the peer's own segment is returned\n * when present. Counting them separately made the short id `mu sync`\n * prints unresolvable. */\nexport function resolvePeerRef(peers: readonly PeerStatus[], ref: string): PeerStatus {\n const matches = peers.filter((p) => p.machineId.startsWith(ref));\n const exact = matches.filter((p) => p.machineId === ref);\n const candidates = exact.length > 0 ? exact : matches;\n const machines = [...new Set(candidates.map((p) => p.machineId))];\n const first = candidates.find((p) => !p.conflictCopy) ?? candidates[0];\n if (first === undefined) {\n throw new SyncPeerNotFoundError(\n ref,\n peers.map((p) => p.short),\n );\n }\n if (machines.length > 1) {\n throw new SyncPeerRefAmbiguousError(\n ref,\n machines.map((m) => m.slice(0, PEER_SHORT_LEN)),\n );\n }\n return first;\n}\n\n/** Reset the watermark of every segment file a peer has (its own and\n * any conflict copies) so the next ingest re-reads them from zero. Safe\n * by construction: apply is idempotent and `ops` dedupes on\n * `UNIQUE (machine_id, hlc)`. */\nexport function repairPeer(db: Db, ref: string, dir: string): PeerStatus {\n const peers = peerStatuses(db, dir);\n const peer = resolvePeerRef(peers, ref);\n for (const p of peers) {\n if (p.machineId === peer.machineId) resetWatermark(db, peerWatermarkKey(p));\n }\n return peer;\n}\n\n// ─── the ambient hook ─────────────────────────────────────────────────\n\n/** Is sync configured at all? THE single `if` the no-sync case pays.\n * Callers check this before awaiting anything, so an unconfigured\n * machine allocates no promise and touches no filesystem. */\nexport function syncEnabled(): boolean {\n return syncDir() !== null;\n}\n\nexport interface AmbientResult {\n /** Peers whose segments were read. Empty when sync is off. */\n ingested: readonly IngestResult[];\n /** Non-fatal problems, already warned about. */\n warnings: readonly string[];\n}\n\nexport interface AmbientOptions {\n /** Suppress the stderr warnings. Set by the TUI, which owns the\n * alternate screen — a stray write there paints garbage over the\n * dashboard. The warnings are still returned: the dashboard keeps the\n * latest ones as `sync` attention items until the next ingest. */\n quiet?: boolean;\n}\n\nexport interface AmbientFlushOptions extends AmbientOptions {\n /** How long to wait for the segment lock (default\n * AMBIENT_FLUSH_LOCK_WAIT_MS). On timeout nothing is written; the ops\n * stay in the DB and the next flush appends them. */\n lockWaitMs?: number;\n}\n\n/** Format one non-fatal sync problem for stderr. Prefixed so it is\n * unmistakably mu's own aside and not the verb's output. */\nfunction warn(message: string, opts?: AmbientOptions): void {\n if (opts?.quiet === true) return;\n // --json: stderr stays empty; the ops stay pending and `mu doctor` reports the backlog.\n if (isJsonMode()) return;\n // Deliberately stderr: stdout is the verb's contract (and may be JSON).\n process.stderr.write(`mu: sync: ${message}\\n`);\n}\n\n/** One line for an own segment holding a line of a version this build\n * cannot read (the segment is read-only here until mu is upgraded).\n * Shared by `mu sync`, the ambient warning and `mu doctor`. */\nexport function foreignVersionMessage(r: {\n segmentPath: string | null;\n foreignVersion: number | null;\n}): string {\n return `segment ${r.segmentPath ?? \"?\"} has a v${r.foreignVersion ?? \"?\"} line written by a newer mu; upgrade mu on this machine`;\n}\n\nfunction describeDefects(peerShort: string, defects: readonly SegmentDefect[]): string {\n const first = defects[0];\n const detail = first === undefined ? \"unknown defect\" : `${first.kind} at line ${first.line}`;\n const more = defects.length > 1 ? ` (+${defects.length - 1} more)` : \"\";\n // `--repair` only resets the watermark, so it is advice ONLY for a\n // defect a re-read can get past (a torn write mid-transfer). A refused\n // line is deterministic: re-reading hits the identical line and the\n // hint would be self-referentially useless, which is exactly how the\n // original incident's operator was sent in a circle. A re-delivered\n // op is deterministic for the same reason. So is a manifest mismatch:\n // the file itself is short, re-reading it changes nothing, and only a\n // fresh copy from the peer clears it.\n const skipped = new Set([\"entity-not-synced\", \"duplicate-op\"]);\n const fileWide = new Set([\"manifest-mismatch\"]);\n let hint: string;\n if (defects.every((d) => skipped.has(d.kind))) {\n hint = \" — skipped; the rest of the segment applied\";\n } else if (defects.every((d) => skipped.has(d.kind) || fileWide.has(d.kind))) {\n hint = \" — the file is shorter than its manifest; copy it from the peer again\";\n } else {\n hint = ` — re-read with \\`mu sync --repair ${peerShort}\\``;\n }\n return `peer ${peerShort}: ${detail}${more}${hint}`;\n}\n\n/**\n * INGEST half of the ambient hook: pull every peer segment before the\n * verb body runs, so the command sees the freshest state the filesystem\n * can offer.\n *\n * Total: no input can make this throw. A per-peer failure is isolated so\n * one broken segment cannot hide the others.\n */\nexport async function ambientIngest(db: Db, opts?: AmbientOptions): Promise<AmbientResult> {\n const dir = syncDir();\n if (dir === null) return { ingested: [], warnings: [] };\n const warnings: string[] = [];\n const ingested: IngestResult[] = [];\n try {\n const self = localMachineId(db);\n for (const peer of discoverPeers(dir, self)) {\n try {\n const result = ingestSegment(db, peer);\n ingested.push(result);\n if (result.defects.length > 0) {\n const message = describeDefects(peer.machineId.slice(0, PEER_SHORT_LEN), result.defects);\n warnings.push(message);\n warn(message, opts);\n }\n } catch (err) {\n const message = `peer ${peer.machineId.slice(0, PEER_SHORT_LEN)}: ${err instanceof Error ? err.message : String(err)}`;\n warnings.push(message);\n warn(message, opts);\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n warnings.push(message);\n warn(message, opts);\n }\n // `await` nothing above: ingest is synchronous better-sqlite3 work.\n // The async signature exists so the caller's seam is uniform with\n // ambientFlush (which takes a file lock).\n return { ingested, warnings };\n}\n\n/**\n * FLUSH half of the ambient hook: append this invocation's own ops to\n * this machine's segment AFTER the verb body has committed them.\n *\n * Order matters and is the whole reason the hook is split in two: a\n * flush before the body would leave the ops the operator just wrote\n * sitting unflushed until the NEXT invocation, so `mu task add` on the\n * laptop followed by `mu sync` on the devserver would show nothing —\n * exactly the no-hands claim, broken.\n *\n * Appends under the cross-process file lock inside `flushSegment`, so\n * two concurrent mu processes cannot interleave partial lines. A flush\n * with nothing to append skips the lock, so read-only verbs never queue.\n * A flush that cannot take the lock within AMBIENT_FLUSH_LOCK_WAIT_MS\n * writes nothing (`lockBusy`) and the verb carries on (exit 0) after one\n * stderr line: its ops stay pending in `ops` and the next invocation's\n * flush appends them. `mu doctor` reports the backlog (`unpublished-ops`).\n */\nexport async function ambientFlush(\n db: Db,\n opts?: AmbientFlushOptions,\n): Promise<FlushResult | null> {\n const dir = syncDir();\n if (dir === null) return null;\n try {\n const result = await flushSegment(db, dir, { lockWaitMs: opts?.lockWaitMs });\n if (result.selfRepaired !== null) {\n const d = result.selfRepaired;\n warn(\n `own segment truncated back to its last good line: ${d.kind} at line ${d.line} (${d.detail}) — regenerated from the ops table`,\n opts,\n );\n }\n if (result.foreignVersionAt !== null) warn(foreignVersionMessage(result), opts);\n if (result.lockBusy === true) {\n warn(\"segment locked by another mu; this op publishes on the next flush\", opts);\n }\n return result;\n } catch (err) {\n warn(err instanceof Error ? err.message : String(err), opts);\n return null;\n }\n}\n\n/**\n * Both halves in one call, for a caller that has no before/after seam to\n * straddle — today the TUI's SLOW tick (10s; never the 1s fast tick,\n * which is a repaint cadence and has no business doing filesystem work).\n *\n * Ingest first, then flush: the same order the CLI hook uses, so a\n * long-lived TUI converges on exactly the same schedule as a shell that\n * runs one verb every ten seconds.\n */\nexport async function ambientSyncPass(\n db: Db,\n opts?: AmbientOptions,\n): Promise<{ ingested: readonly IngestResult[]; flushed: FlushResult | null }> {\n if (!syncEnabled()) return { ingested: [], flushed: null };\n const { ingested } = await ambientIngest(db, opts);\n const flushed = await ambientFlush(db, opts);\n return { ingested, flushed };\n}\n\n// ─── `mu sync --from <peer.db>`: a different READER ───────────────────\n\nexport interface IngestFromDbResult {\n path: string;\n /** Ops read out of the peer's `ops` table (already filtered). */\n read: number;\n /** Ops that changed a row here. */\n changed: number;\n /** Ops skipped because their entity is machine-local. */\n skippedLocal: number;\n}\n\n/** The source DB's `schema_version`, or null when it has none (not a mu\n * DB, or one old enough that the ops query below fails on its own). */\nfunction sourceSchemaVersion(source: Database.Database): number | null {\n try {\n const row = source.prepare(\"SELECT version FROM schema_version WHERE id = 1\").get() as\n | { version: number }\n | undefined;\n return row?.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Ingest straight from a peer's `mu.db`, reading its `ops` table with\n * SQLite instead of parsing a JSONL segment.\n *\n * WHY THIS EARNS A FLAG when `MU_SYNC_DIR=/mnt/whatever mu state` covers\n * the one-off-directory case: it is a DIFFERENT READER, and nothing\n * about an env var can express it. The file you have is a database, not\n * a segment — because you scp'd it, or because you have the devserver's\n * state dir on sshfs and would rather read the real thing than wait for\n * a flush.\n *\n * Opened `readonly` so mu cannot write to a file it does not own, and\n * `fileMustExist` so a typo'd path is an error rather than a freshly\n * created empty DB.\n *\n * Filters exactly as flush does — `SYNCED_ENTITIES` only, and never the\n * peer's copy of OUR ops (we already have those; `UNIQUE (machine_id,\n * hlc)` would dedupe them anyway, but not reading them is cheaper and\n * keeps the reported count honest). Ops the peer itself ingested from a\n * THIRD machine are read, which is how transitive convergence falls out\n * for free.\n *\n * Watermarks are deliberately untouched: a watermark counts LINES of a\n * segment, and a DB has no such coordinate. The next segment ingest for\n * that peer re-reads from wherever it was, applies the same ops again,\n * and changes nothing — idempotence is what makes leaving it alone safe.\n */\nexport function ingestFromDb(db: Db, path: string): IngestFromDbResult {\n if (!existsSync(path)) throw new SyncSourceNotFoundError(path);\n const self = localMachineId(db);\n const source = new Database(path, { readonly: true, fileMustExist: true });\n try {\n const theirs = sourceSchemaVersion(source);\n if (theirs !== null && theirs > CURRENT_SCHEMA_VERSION) {\n throw new SyncSourceTooNewError(path, theirs);\n }\n const rows = source\n .prepare(\n `SELECT hlc, machine_id, group_id, actor, intent, entity, key, op, payload\n FROM ops\n WHERE machine_id != ?\n ORDER BY hlc`,\n )\n .all(self) as Array<{\n hlc: string;\n machine_id: string;\n group_id: string;\n actor: string | null;\n intent: string | null;\n entity: string;\n key: string;\n op: string;\n payload: string;\n }>;\n\n const synced = new Set<string>(SYNCED_ENTITIES);\n let read = 0;\n let changed = 0;\n let skippedLocal = 0;\n const run = db.transaction(() => {\n for (const row of rows) {\n if (!synced.has(row.entity)) {\n skippedLocal += 1;\n continue;\n }\n const op: Op = {\n hlc: row.hlc,\n machineId: row.machine_id,\n groupId: row.group_id,\n actor: row.actor,\n intent: row.intent,\n entity: row.entity,\n key: row.key,\n op: row.op === \"del\" ? \"del\" : \"put\",\n payload: row.payload,\n };\n const result = applyIncomingOp(db, op);\n read += 1;\n if (result.changed) changed += 1;\n }\n });\n run.immediate();\n return { path, read, changed, skippedLocal };\n } finally {\n try {\n source.close();\n } catch {\n // best effort\n }\n }\n}\n","// mu — who \"I\" am for a wait.\n//\n// One orchestrator is known under two names. The managed `<ws>/<agent>`\n// (`MU_MANAGED_AGENT=1`) owns the workers it spawns and the human stops it\n// records (`spawnerFromEnv`); `pi:<PI_SESSION_ID>` owns the delegate calls it\n// makes (extension/delegate.ts, `mu delegates`). A wait must see both, so a\n// caller is a SET: the union of the two when present. Neither alone, and never\n// a guess (USER, TMUX_PANE) or \"every caller\": an empty set owns nothing.\n\n/** The callers of this process, from its env: managed ws/name first, then pi:<session>. */\nexport function currentCallers(env: NodeJS.ProcessEnv = process.env): string[] {\n const out: string[] = [];\n const { MU_MANAGED_AGENT: managed, MU_WORKSTREAM: ws, MU_AGENT_NAME: name } = env;\n if (managed === \"1\" && ws && name) out.push(`${ws}/${name}`);\n if (env.PI_SESSION_ID) out.push(`pi:${env.PI_SESSION_ID}`);\n return out;\n}\n","// mu — agent output boundary: what `--json` prints for an agent.\n//\n// Pure (no I/O). Keys equal the SQL column names of `agents` and `id` is the\n// real primary key, which IS the registry incarnation (`AgentRow.incarnation`,\n// what `agent close --if` and every destructive write compare; not pi's string\n// `incarnation`). `workstream_id` is the real foreign key; `workstream` is its\n// name. Computed live facts (runtime state, ctl link) ride after the columns,\n// snake_cased, only when known. The deprecated `agents.status` column is never\n// emitted. The SDK keeps camelCase `AgentRow`; ONLY the CLI maps (README\n// Interface: output keys equal SQL column names).\n\nimport type { ClosePreview } from \"./agents/close.js\";\nimport type { AgentRow, LiveAgent } from \"./agents.js\";\nimport type { Db } from \"./db.js\";\n\n/** `workstreams.id` for a name, torn down or not (an agent row can outlive its workstream's teardown). */\nexport function workstreamIdOf(db: Db, workstream: string): number {\n const row = db.prepare(\"SELECT id FROM workstreams WHERE name = ?\").get(workstream) as\n | { id: number }\n | undefined;\n return row?.id ?? 0;\n}\n\n/** The live, computed half of an agent record (all optional: only what was read). */\nexport interface AgentLiveFacts {\n state?: string;\n source?: string;\n ctl?: string;\n ctlSocket?: string;\n since?: string | null;\n reason?: string;\n idle?: boolean;\n trustDialog?: boolean;\n}\n\n/** One agent as `--json` emits it. */\nexport interface AgentOutput {\n /** `agents.id`: the registry incarnation. */\n id: number;\n name: string;\n workstream_id: number;\n workstream: string;\n cli: string;\n pane_id: string;\n role: string;\n tab: string | null;\n cwd: string | null;\n base: string | null;\n command: string | null;\n command_source: string | null;\n spawner: string | null;\n host: string | null;\n collected_head: string | null;\n repo: string | null;\n gate_token: string | null;\n created_at: string;\n updated_at: string;\n state?: string;\n source?: string;\n ctl?: string;\n ctl_socket?: string;\n since?: string | null;\n reason?: string;\n idle?: boolean;\n trust_dialog?: boolean;\n}\n\n/** Boundary mapper: AgentRow (camelCase) plus its real workstream id → output record. */\nexport function agentToOutput(\n row: AgentRow,\n workstreamId: number,\n live: AgentLiveFacts = {},\n): AgentOutput {\n return {\n id: row.incarnation,\n name: row.name,\n workstream_id: workstreamId,\n workstream: row.workstreamName,\n cli: row.cli,\n pane_id: row.paneId,\n role: row.role,\n tab: row.tab,\n cwd: row.cwd,\n base: row.base,\n command: row.command,\n command_source: row.commandSource,\n spawner: row.spawner,\n host: row.host,\n collected_head: row.collectedHead,\n repo: row.repo,\n gate_token: row.gateToken,\n created_at: row.createdAt,\n updated_at: row.updatedAt,\n ...(live.state !== undefined ? { state: live.state } : {}),\n ...(live.source !== undefined ? { source: live.source } : {}),\n ...(live.ctl !== undefined ? { ctl: live.ctl } : {}),\n ...(live.ctlSocket !== undefined ? { ctl_socket: live.ctlSocket } : {}),\n ...(live.since !== undefined ? { since: live.since } : {}),\n ...(live.reason !== undefined ? { reason: live.reason } : {}),\n ...(live.idle !== undefined ? { idle: live.idle } : {}),\n ...(live.trustDialog !== undefined ? { trust_dialog: live.trustDialog } : {}),\n };\n}\n\n/**\n * A close preview with its identity under the SQL names (`id`, `pane_id`);\n * every verb-level field is kept. `id` is the REGISTRY incarnation (null for a\n * recovery: no row); a recovery's own id is `recovery_id` (the original\n * incarnation it was kept from), null otherwise.\n */\nexport function closePreviewToOutput(p: ClosePreview): Record<string, unknown> {\n const { incarnation, paneId, ...rest } = p;\n return { ...rest, id: incarnation, pane_id: paneId, recovery_id: p.recovery?.id ?? null };\n}\n\n/** A live agent (`list`, `state`, `show`, `me`) as its record: columns plus the computed state and ctl link. */\nexport function liveAgentToOutput(agent: LiveAgent, workstreamId: number): AgentOutput {\n return agentToOutput(agent, workstreamId, {\n state: agent.state,\n source: agent.source,\n ...(agent.ctl !== undefined ? { ctl: agent.ctl } : {}),\n since: agent.since,\n ...(agent.reason !== undefined ? { reason: agent.reason } : {}),\n ...(agent.idle !== undefined ? { idle: agent.idle } : {}),\n });\n}\n","// mu — task read records: the output boundary of list / next / owned-by / show / tree.\n//\n// Pure (no I/O, no DB). A task becomes ONE record per line, or one JSON item\n// whose keys are the SQL column names (`id` is the task's `local_id`; the\n// integer primary key never appears; `workstream_id` / `owner_id` are the real\n// foreign keys). Every result is bounded on its FINAL bytes (README Interface,\n// output caps): a record is at most RECORD_CHARS characters, a result at most\n// RESULT_BYTES, and a cut names the way back. There is ONE way back that always\n// works: the same read with `--all` (uncapped), and for a clipped field of one\n// task `mu task show <id> -w <ws> --all`. Neither is ever clipped itself.\n//\n// text task<TAB>id<TAB>STATE<TAB>key=value ...<TAB>title[<TAB>cut=N<TAB>next=<cmd>]\n// footer more=N next=<command>\n//\n// Everything a terminal or a line tool could misread is escaped: backslash,\n// newline, tab and CR as two characters, any other control, C1, bidi,\n// line/paragraph-separator character as `\\u{hex}`.\n\nimport { encodeEnvelope, okEnvelope, RESULT_BYTES } from \"../../output-contract.js\";\nimport { formatPair } from \"../../tasks/status.js\";\nimport type { TaskRow } from \"../../tasks.js\";\n\n/** Most characters of one list record (README: list record <= 400 chars). */\nexport const RECORD_CHARS = 400;\n/** Most characters of a title in a JSON item. */\nexport const JSON_TITLE_CHARS = 120;\n/** Most characters of a wave label or host in a JSON item (clipped ones count into `cut`). */\nconst JSON_FIELD_CHARS = 80;\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching control characters is the point\nconst UNSAFE = /[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069\\\\]/u;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching control characters is the point\nconst UNSAFE_G = /[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069\\\\]/gu;\n\n/** Escape so one value is one inert field of one line. */\nexport function escapeRecordText(s: string): string {\n if (!UNSAFE.test(s)) return s;\n return s.replace(UNSAFE_G, (c) => {\n switch (c) {\n case \"\\\\\":\n return \"\\\\\\\\\";\n case \"\\n\":\n return \"\\\\n\";\n case \"\\t\":\n return \"\\\\t\";\n case \"\\r\":\n return \"\\\\r\";\n default:\n return `\\\\u{${(c.codePointAt(0) ?? 0).toString(16)}}`;\n }\n });\n}\n\n/** The one JSON document line of a success envelope: the encoder every `--json` read emits through, so a size measured here is the size printed. */\nexport function jsonDocument(data: unknown): string {\n return encodeEnvelope(okEnvelope(data));\n}\n\nconst bytes = (s: string): number => Buffer.byteLength(s);\n/** Bytes of `lines` as printed (one newline each). */\nexport const linesBytes = (lines: readonly string[]): number => bytes(lines.join(\"\\n\")) + 1;\n\n/** Code points of `s`. */\nexport const codePoints = (s: string): string[] => [...s];\n\n/** `s` cut to at most `maxChars` code points AND `maxBytes` ESCAPED bytes; `cut` counts what was dropped. */\nexport function clipEscaped(\n s: string,\n maxChars: number,\n maxBytes = Number.POSITIVE_INFINITY,\n): { text: string; cut: number } {\n const cps = codePoints(s);\n let out = \"\";\n let used = 0;\n let n = 0;\n for (const cp of cps) {\n const esc = escapeRecordText(cp);\n if (out.length + esc.length > maxChars || used + bytes(esc) > maxBytes) break;\n out += esc;\n used += bytes(esc);\n n++;\n }\n return { text: out, cut: cps.length - n };\n}\n\n// ─── JSON items ────────────────────────────────────────────────────────\n\n/** One task as `--json` emits it: SQL column names, real foreign keys. */\nexport interface TaskOutput {\n /** The task's `local_id` (never the integer primary key). */\n id: string;\n local_id: string;\n /** Real `tasks.workstream_id`. */\n workstream_id: number;\n /** Name of that workstream; present only where the ref is otherwise ambiguous (`show`, cross-workstream views). */\n workstream?: string;\n title: string;\n status: string;\n substate: string;\n impact: number;\n effort_days: number;\n scored: 0 | 1;\n dispatch_host: string | null;\n /** Real `tasks.owner_id` (kept after close: lifecycle attribution). */\n owner_id: number | null;\n /** Owner's name; present ONLY while IN_PROGRESS (a CLOSED task's owner is history). */\n owner?: string;\n created_at: string;\n updated_at: string;\n kind: string;\n wave: string | null;\n /** What `--if <rev>` repeats; present when the verb computed it. */\n revision?: number;\n}\n\n/** Boundary mapper: TaskRow (names + real FKs) → output item. Never aliases name/effortDays. */\nexport function taskToOutput(\n row: TaskRow,\n opts: { revision?: number; withWorkstream?: boolean } = {},\n): TaskOutput {\n const out: TaskOutput = {\n id: row.name,\n local_id: row.name,\n workstream_id: row.workstreamId,\n title: row.title,\n status: row.status,\n substate: row.substate,\n impact: row.impact,\n effort_days: row.effortDays,\n scored: row.scored ? 1 : 0,\n dispatch_host: row.dispatchHost,\n owner_id: row.ownerId,\n created_at: row.createdAt,\n updated_at: row.updatedAt,\n kind: row.kind,\n wave: row.wave,\n };\n if (opts.withWorkstream === true) out.workstream = row.workstreamName;\n if (row.status === \"IN_PROGRESS\" && row.ownerName !== null) out.owner = row.ownerName;\n if (opts.revision !== undefined) out.revision = opts.revision;\n return out;\n}\n\n/** Title bound of a `show` (its own 4 KB result has a task, edges and notes to share; `show` shrinks it to fit). */\nexport const SHOW_TITLE_CHARS = 600;\n\n/** What a task read says when it cut something: `more=N` records left out, `cut=N` characters clipped, and the one command that prints it all. */\nexport interface Cuts {\n more: number;\n cut: number;\n}\n\n/** `more=N cut=N next=<command>` footer line; null when nothing was cut. `next` is the reserved tail: never sliced. */\nexport function footerLine(c: Cuts, next: string): string | null {\n if (c.more <= 0 && c.cut <= 0) return null;\n const parts = [c.more > 0 ? `more=${c.more}` : \"\", c.cut > 0 ? `cut=${c.cut}` : \"\"];\n return `${parts.filter(Boolean).join(\" \")} next=${next}`;\n}\n\n/** JSON item with bounded free-text fields; `cut` counts the code points clipped. `whole` clips nothing. */\nexport function taskItemCut(\n row: TaskRow,\n opts: {\n revision?: number;\n withWorkstream?: boolean;\n titleChars?: number;\n whole?: boolean;\n /** Code points already cut from a field the item does not hold itself (`show`'s last claimer). */\n extraCut?: number;\n } = {},\n): { item: TaskOutput; cut: number } {\n const item = taskToOutput(row, opts);\n if (opts.whole === true) return { item, cut: 0 };\n let cut = opts.extraCut ?? 0;\n const clip = (s: string, max: number): string => {\n const cps = codePoints(s);\n if (cps.length <= max) return s;\n cut += cps.length - Math.max(0, max - 1);\n return max <= 0 ? \"\" : `${cps.slice(0, max - 1).join(\"\")}…`;\n };\n item.title = clip(row.title, opts.titleChars ?? JSON_TITLE_CHARS);\n if (item.wave !== null) item.wave = clip(item.wave, JSON_FIELD_CHARS);\n if (item.dispatch_host !== null) item.dispatch_host = clip(item.dispatch_host, JSON_FIELD_CHARS);\n if (item.owner !== undefined) item.owner = clip(item.owner, JSON_FIELD_CHARS);\n return { item, cut };\n}\n\n// ─── Text records ──────────────────────────────────────────────────────\n\nexport interface RecordOpts {\n /** Name the workstream (cross-workstream views). */\n withWorkstream?: boolean;\n revision?: number;\n /** Show the owner as `by=<name>` when the row has none (an anonymous claim). */\n claimedBy?: string | null;\n /** Add `created=` and `updated=` (the `show` record). */\n times?: boolean;\n /** Extra `key=value` fields (`tree`'s depth, parent and what hangs below): kept even when metadata crowds the title out. */\n extra?: readonly string[];\n /** Add the one timestamp a `--sort recency|age` orders by. */\n basis?: \"updatedAt\" | \"createdAt\";\n /** Characters of the whole record (default RECORD_CHARS). */\n maxChars?: number;\n /** `show`: the title's own bound in code points (the record cap still applies). */\n titleChars?: number;\n /** Clip nothing (`--all`): only escape. */\n whole?: boolean;\n}\n\n/**\n * `task<TAB>id<TAB>STATE<TAB>k=v ...<TAB>title`: one line, escaped, <= maxChars\n * (never sliced: a clipped title ends in `…`, a field that does not fit is\n * dropped). `cut` counts the code points left out of the line; the caller's\n * footer carries the one way back (`--all` prints every record whole).\n */\nexport function taskRecordCut(row: TaskRow, opts: RecordOpts = {}): { line: string; cut: number } {\n const whole = opts.whole === true;\n let fieldCut = 0;\n const clip = (s: string, chars = 40): string => {\n if (whole) return escapeRecordText(s);\n const { text, cut } = clipEscaped(s, chars);\n if (cut === 0) return text;\n fieldCut += cut;\n return `${text}…`;\n };\n const kv: string[] = [`impact=${row.impact}`, `effort_days=${row.effortDays}`];\n if (!row.scored) kv.push(\"scored=0\");\n if (row.status === \"IN_PROGRESS\" && row.ownerName !== null)\n kv.push(`owner=${clip(row.ownerName)}`);\n if (opts.withWorkstream === true) kv.push(`ws=${clip(row.workstreamName)}`);\n if (row.status !== \"OPEN\" && row.ownerName === null && opts.claimedBy) {\n kv.push(`self=${clip(opts.claimedBy)}`);\n }\n if (row.kind !== \"work\") kv.push(`kind=${row.kind}`);\n if (row.wave !== null) kv.push(`wave=${clip(row.wave)}`);\n if (row.dispatchHost !== null) kv.push(`host=${clip(row.dispatchHost)}`);\n if (opts.times === true) kv.push(`created=${row.createdAt}`, `updated=${row.updatedAt}`);\n else if (opts.basis === \"updatedAt\") kv.push(`updated=${row.updatedAt}`);\n else if (opts.basis === \"createdAt\") kv.push(`created=${row.createdAt}`);\n if (opts.revision !== undefined) kv.push(`rev=${opts.revision}`);\n kv.push(...(opts.extra ?? []));\n const id = clip(row.name, 64);\n const head = [\"task\", id, formatPair(row), kv.join(\" \")].join(\"\\t\");\n const wholeTitle = escapeRecordText(row.title);\n if (whole) return { line: `${head}\\t${wholeTitle}`, cut: 0 };\n const max = opts.maxChars ?? RECORD_CHARS;\n const bound = opts.titleChars ?? Number.POSITIVE_INFINITY;\n const place = (h: string, extraCut: number): { line: string; cut: number } | undefined => {\n const roomMax = max - codePoints(h).length - 1;\n if (roomMax < 9) return undefined;\n const room = Math.min(roomMax, bound);\n if (codePoints(wholeTitle).length <= room)\n return { line: `${h}\\t${wholeTitle}`, cut: extraCut };\n const { text, cut } = clipEscaped(row.title, Math.max(0, room - 1));\n return { line: `${h}\\t${text}…`, cut: cut + extraCut };\n };\n const first = place(head, fieldCut);\n if (first !== undefined) return first;\n // Metadata crowds the title out: keep the identity and the score; the free-text fields\n // dropped from the line count into `cut` (`--all` prints them).\n const dropped = [\n row.status === \"IN_PROGRESS\" ? row.ownerName : null,\n opts.withWorkstream === true ? row.workstreamName : null,\n row.wave,\n row.dispatchHost,\n row.status !== \"OPEN\" && row.ownerName === null ? (opts.claimedBy ?? null) : null,\n ]\n .filter((v): v is string => typeof v === \"string\")\n .reduce((n, v) => n + codePoints(v).length, 0);\n const lean = [\n \"task\",\n id,\n formatPair(row),\n [...kv.slice(0, 2), ...(opts.extra ?? [])].join(\" \"),\n ].join(\"\\t\");\n const room = Math.min(Math.max(0, max - codePoints(lean).length - 2), Math.max(0, bound - 1));\n const { text, cut } = clipEscaped(row.title, room);\n return { line: `${lean}\\t${text}…`, cut: cut + dropped };\n}\n\n// ─── Paging ────────────────────────────────────────────────────────────\n\nexport interface RecordPage<T> {\n /** The records of this page (always at least one when any exist). */\n shown: T[];\n /** Records left out. */\n more: number;\n}\n\n/**\n * Take records from `all`, in order, as many as keep the FINAL emitted bytes\n * (`size(page)`: the caller serializes text lines or the JSON document, footer\n * and metadata included) within `budget`. The first record always goes out\n * (records are themselves bounded), so a page makes progress.\n */\nexport function pageRecords<T>(\n all: readonly T[],\n size: (page: RecordPage<T>) => number,\n budget: number = RESULT_BYTES,\n /** Records that go out even when over budget (default 1: progress). */\n min = 1,\n): RecordPage<T> {\n const build = (k: number): RecordPage<T> => ({ shown: all.slice(0, k), more: all.length - k });\n let page = build(Math.min(min, all.length));\n for (let k = min + 1; k <= all.length; k++) {\n const candidate = build(k);\n if (size(candidate) > budget) break;\n page = candidate;\n }\n return page;\n}\n\n// ─── A page of task records ────────────────────────────────────────────\n\nexport interface TaskPageOpts {\n /** `--all`: every record, whole, no cap. */\n all: boolean;\n /** The footer's `next=`: the same read, uncapped (`--all`; `--full` where `--all` is taken). */\n next: string;\n json: boolean;\n withWorkstream?: boolean;\n /** The timestamp the sort orders by, shown on text records. */\n basis?: \"updatedAt\" | \"createdAt\" | null;\n /** `local_id` → revision (list). */\n revisions?: ReadonlyMap<string, number>;\n}\n\nexport interface TaskPageOut {\n /** Text lines to print (no terminal framing); empty when `json`. */\n lines: string[];\n /** The `data` payload; undefined unless `json`. */\n data?: { items: TaskOutput[]; count: number; more: number; cut?: number; retrieve?: string };\n shown: number;\n more: number;\n}\n\n/** Page `rows` into at most RESULT_BYTES of final output, in text or JSON; `--all` prints every row whole. */\nexport function taskPage(rows: readonly TaskRow[], opts: TaskPageOpts): TaskPageOut {\n const ws = opts.withWorkstream === true;\n const whole = opts.all;\n const render = (\n page: RecordPage<TaskRow>,\n ): { lines: string[]; data: NonNullable<TaskPageOut[\"data\"]> } => {\n let cut = 0;\n const lines: string[] = [];\n const items: TaskOutput[] = [];\n for (const r of page.shown) {\n const revision = opts.revisions?.get(r.name);\n const rev = revision === undefined ? {} : { revision };\n if (opts.json) {\n const one = taskItemCut(r, { withWorkstream: ws, whole, ...rev });\n cut += one.cut;\n items.push(one.item);\n } else {\n const one = taskRecordCut(r, {\n withWorkstream: ws,\n whole,\n ...rev,\n ...(opts.basis ? { basis: opts.basis } : {}),\n });\n cut += one.cut;\n lines.push(one.line);\n }\n }\n const foot = footerLine({ more: page.more, cut }, opts.next);\n if (foot !== null) lines.push(foot);\n return {\n lines: opts.json ? [] : lines,\n data: {\n items,\n count: items.length,\n more: page.more,\n ...(cut > 0 ? { cut } : {}),\n ...(foot === null ? {} : { retrieve: opts.next }),\n },\n };\n };\n const page: RecordPage<TaskRow> = whole\n ? { shown: [...rows], more: 0 }\n : pageRecords(rows, (p) => {\n const r = render(p);\n return opts.json ? bytes(jsonDocument(r.data)) + 1 : linesBytes(r.lines);\n });\n const out = render(page);\n return {\n lines: out.lines,\n ...(opts.json ? { data: out.data } : {}),\n shown: page.shown.length,\n more: page.more,\n };\n}\n","// mu — the shared pager of the capped text/JSON reads that are not task reads\n// (`mu log`, `mu workstream list`).\n//\n// Pure (no I/O, no DB). A page is bounded on its FINAL bytes (RESULT_BYTES,\n// envelope and footer included). A cut is counted (`more=N` records\n// left out, `cut=N` characters clipped) and names its way back as a command that\n// runs as printed.\n\nimport { RESULT_BYTES } from \"../output-contract.js\";\nimport {\n clipEscaped,\n codePoints,\n escapeRecordText,\n jsonDocument,\n linesBytes,\n pageRecords,\n RECORD_CHARS,\n type RecordPage,\n} from \"./tasks/records.js\";\n\nconst bytes = (s: string): number => Buffer.byteLength(s);\n\n/** A fixed column (source, scope, ...) is clipped to this many characters. */\nconst COLUMN_CHARS = 64;\n/** One JSON item's own document stays within this, so a page always has room for its metadata. */\nexport const ITEM_BYTES = 2048;\n\n/** `s` clipped to `max` code points; `cut` counts the code points dropped. */\nexport function clipPlain(s: string, max: number): { text: string; cut: number } {\n const cps = codePoints(s);\n if (cps.length <= max) return { text: s, cut: 0 };\n return { text: cps.slice(0, max).join(\"\"), cut: cps.length - max };\n}\n\n/**\n * Build an item whose own document fits ITEM_BYTES whatever it holds (control\n * and multibyte characters escape to 6 bytes and more): every field's character\n * limit shrinks (halving, then to empty) until it does. `build(scale)` clips each\n * field to `floor(limit * scale)`.\n */\nexport function shrinkItem<I extends object>(\n build: (scale: number) => { item: I; cut: number },\n): { item: I; cut: number } {\n let out = build(1);\n for (const scale of [0.5, 0.25, 0.125, 0]) {\n if (bytes(jsonDocument({ items: [out.item] })) <= ITEM_BYTES) break;\n out = build(scale);\n }\n return out;\n}\n\n// ─── the generic pager ─────────────────────────────────────────────────\n\nexport interface PageSpec<T> {\n json: boolean;\n /** Every row, whole, no cap and no footer (`--all`). */\n whole?: boolean;\n /** Fill the page from the END of `rows` (the newest), printing it in the original order. */\n newest?: boolean;\n /** One text record; `cut` counts the characters it clipped (none when `whole`). */\n text(row: T, whole: boolean): { line: string; cut: number };\n /** One JSON item; `cut` counts the characters it clipped (none when `whole`). */\n item(row: T, whole: boolean): { item: object; cut: number };\n /** The command that reads the `more` records left out. */\n resume(shown: readonly T[], more: number): string;\n /** The command that reads the clipped rows whole; defaults to `resume`. */\n retrieve?(clipped: readonly T[]): string;\n /** JSON: name the one way back `retrieve`, with no separate `resume`. */\n singleRetrieve?: boolean;\n}\n\nexport interface PageData {\n items: object[];\n count: number;\n more: number;\n cut?: number;\n /** Reads the `more` records left out. */\n resume?: string;\n /** Reads the clipped records whole. */\n retrieve?: string;\n}\n\nexport interface PageOut {\n /** Text lines to print; empty when `json`. */\n lines: string[];\n /** The `data` payload; undefined unless `json`. */\n data?: PageData;\n shown: number;\n more: number;\n}\n\n/** Page `rows` into at most RESULT_BYTES of final output, as text lines or one JSON document. */\nexport function pageOut<T>(rows: readonly T[], spec: PageSpec<T>): PageOut {\n const newest = spec.newest === true;\n const whole = spec.whole === true;\n const render = (page: RecordPage<T>): { lines: string[]; data: PageData } => {\n const shown = newest ? [...page.shown].reverse() : page.shown;\n let cut = 0;\n const clipped: T[] = [];\n const lines: string[] = [];\n const items: object[] = [];\n for (const r of shown) {\n if (spec.json) {\n const one = spec.item(r, whole);\n if (one.cut > 0) clipped.push(r);\n cut += one.cut;\n items.push(one.item);\n } else {\n const one = spec.text(r, whole);\n if (one.cut > 0) clipped.push(r);\n cut += one.cut;\n lines.push(one.line);\n }\n }\n const resume = page.more > 0 ? spec.resume(shown, page.more) : undefined;\n const retrieve =\n cut > 0 ? (spec.retrieve ?? ((_c) => spec.resume(shown, page.more)))(clipped) : undefined;\n if (resume !== undefined && resume === retrieve) {\n lines.push(`more=${page.more} cut=${cut} next=${resume}`);\n } else {\n if (resume !== undefined) lines.push(`more=${page.more} next=${resume}`);\n if (retrieve !== undefined) lines.push(`cut=${cut} next=${retrieve}`);\n }\n const single = spec.singleRetrieve === true;\n const way = retrieve ?? (single ? resume : undefined);\n return {\n lines: spec.json ? [] : lines,\n data: {\n items,\n count: items.length,\n more: page.more,\n ...(cut > 0 ? { cut } : {}),\n ...(resume === undefined || single ? {} : { resume }),\n ...(way === undefined ? {} : { retrieve: way }),\n },\n };\n };\n const input = newest ? [...rows].reverse() : rows;\n // min 0: when even one record plus the footer would bust the cap, none goes out\n // and the footer says how to read on.\n const page: RecordPage<T> = whole\n ? { shown: [...input], more: 0 }\n : pageRecords(\n input,\n (p) => {\n const r = render(p);\n return spec.json ? bytes(jsonDocument(r.data)) + 1 : linesBytes(r.lines);\n },\n RESULT_BYTES,\n 0,\n );\n const out = render(page);\n return {\n lines: out.lines,\n ...(spec.json ? { data: out.data } : {}),\n shown: page.shown.length,\n more: page.more,\n };\n}\n\n/** One text record: fixed columns, then a free-text tail; escaped, at most RECORD_CHARS characters (`whole`: escaped, never clipped). */\nexport function clippedRecord(\n columns: readonly string[],\n free: string,\n whole = false,\n): { line: string; cut: number } {\n if (whole) return { line: [...columns, free].map(escapeRecordText).join(\"\\t\"), cut: 0 };\n let cut = 0;\n const lean = columns\n .map((c) => {\n const one = clipEscaped(c, COLUMN_CHARS);\n cut += one.cut;\n return one.text;\n })\n .join(\"\\t\");\n const room = Math.max(0, RECORD_CHARS - lean.length - 2);\n const tail = clipEscaped(free, room);\n cut += tail.cut;\n return { line: `${lean}\\t${tail.text}${tail.cut > 0 ? \"…\" : \"\"}`, cut };\n}\n","// mu — the output boundary of the log reads (`mu log`, `mu log --tail`) and of\n// the capped `mu workstream list` pages, which share its pager.\n//\n// Pure (no I/O, no DB). One op is ONE text record on ONE line (escaped, at most\n// RECORD_CHARS characters), or one JSON item keyed by the `ops` column names\n// (`key`, `actor`, `entity`, `group_id`, `created_at`; `rendered` is the prose of\n// the one formatter). The SDK's `LogRow` and `renderOp`'s input keep their names:\n// this adapter maps them at the CLI edge, and raw op rows are never rewritten.\n//\n// A page is bounded on its FINAL bytes (RESULT_BYTES, envelope included). A cut\n// is counted (`more=N` records left out, `cut=N` characters clipped) and names\n// its way back BY SEQ, never by filter: `mu log --seq A..B` (exact seqs, every\n// record whole, no scope) or, when the omitted ops are too scattered to name,\n// `mu log --after S` (a cursor into the whole log). A hint is digits only, so its\n// size is bounded however long the filters, groups or workstream names were.\n\nimport { parseOpKey, renderOp, renderOpLine } from \"../log-render.js\";\nimport type { LogRow } from \"../logs.js\";\nimport { clipPlain, clippedRecord, type PageOut, pageOut, shrinkItem } from \"./page-records.js\";\n\n// ─── log records ───────────────────────────────────────────────────────\n\n/** What an op says, on one line: the formatter's prose, or `kind: payload` for operator prose. */\nfunction whatLine(row: LogRow): string {\n const r = renderOp(row);\n if (r === null) return `${row.kind}: ${row.payload}`;\n return [r.verb, r.subject, r.detail].filter((s) => s !== \"\").join(\" \");\n}\n\n/** `log<TAB>seq<TAB>time<TAB>source<TAB>scope<TAB>what`: one escaped line, <= 400 characters. */\nexport function logRecord(row: LogRow, whole = false): { line: string; cut: number } {\n const time = row.createdAt.replace(/\\.\\d+Z$/, \"Z\");\n const scope = parseOpKey(row.workstreamName).workstream ?? \"-\";\n return clippedRecord([\"log\", String(row.seq), time, row.source, scope], whatLine(row), whole);\n}\n\n/** One op as `--json` and `--tail` print it: the `ops` column names plus the formatter's prose. */\nexport interface LogItem {\n seq: number;\n /** `ops.key`; '' for a machine-wide entry. */\n key: string;\n /** `ops.actor` ('system' where the op had none). */\n actor: string;\n intent: string | null;\n group_id: string;\n op: string;\n /** `ops.entity` (the `--kind` tag). */\n entity: string;\n payload: string;\n created_at: string;\n /** The one formatter's prose for this op. */\n rendered: string;\n /** Characters clipped from this item's text fields; absent when none. */\n cut?: number;\n}\n\nconst LIMITS = {\n key: 120,\n actor: 80,\n intent: 80,\n group_id: 64,\n op: 16,\n entity: 80,\n payload: 240,\n created_at: 40,\n rendered: 160,\n} as const;\n\n/** The item with every text field clipped to `scale` x its limit (cut counted); scale 0 empties them. */\nfunction buildItem(row: LogRow, scale: number): { item: LogItem; cut: number } {\n let cut = 0;\n const clip = (s: string, limit: number): string => {\n const one = clipPlain(s, Math.floor(limit * scale));\n cut += one.cut;\n return one.text;\n };\n const item: LogItem = {\n seq: row.seq,\n key: clip(row.workstreamName ?? \"\", LIMITS.key),\n actor: clip(row.source, LIMITS.actor),\n intent: row.intent === null ? null : clip(row.intent, LIMITS.intent),\n group_id: clip(row.group, LIMITS.group_id),\n op: clip(row.op, LIMITS.op),\n entity: clip(row.kind, LIMITS.entity),\n payload: clip(row.payload, LIMITS.payload),\n created_at: clip(row.createdAt, LIMITS.created_at),\n rendered: clip(renderOpLine(row), LIMITS.rendered),\n };\n if (cut > 0) item.cut = cut;\n return { item, cut };\n}\n\n/** A JSON item whose own document fits ITEM_BYTES (control and multibyte characters included): EVERY text field shrinks until it does. `whole`: every field as stored. */\nexport function logItem(row: LogRow, whole = false): { item: LogItem; cut: number } {\n if (whole) {\n return {\n cut: 0,\n item: {\n seq: row.seq,\n key: row.workstreamName ?? \"\",\n actor: row.source,\n intent: row.intent,\n group_id: row.group,\n op: row.op,\n entity: row.kind,\n payload: row.payload,\n created_at: row.createdAt,\n rendered: renderOpLine(row),\n },\n };\n }\n return shrinkItem((scale) => buildItem(row, scale));\n}\n\n/** Most exact runs a hint names; scattered omissions past this fall back to a cursor. */\nconst MAX_RUNS = 8;\n\n/**\n * The command that reads exactly `seqs`: `mu log --seq a..b,c,...` (no scope, every\n * record whole). `gapEmpty(a, b)` says no visible op lies strictly between a and b,\n * so a..b holds nothing else. Too scattered to name in `MAX_RUNS` runs: the cursor\n * `mu log --after <first - 1>` (a paged read of the whole log from there).\n */\nexport function seqCommand(\n seqs: readonly number[],\n gapEmpty: (a: number, b: number) => boolean,\n json: boolean,\n): string {\n const sorted = [...new Set(seqs)].sort((a, b) => a - b);\n const runs: [number, number][] = [];\n for (const n of sorted) {\n const last = runs[runs.length - 1];\n if (last !== undefined && (n === last[1] + 1 || gapEmpty(last[1], n))) last[1] = n;\n else runs.push([n, n]);\n if (runs.length > MAX_RUNS) break;\n }\n const tail = json ? \" --json\" : \"\";\n if (runs.length > MAX_RUNS || runs.length === 0) {\n return `mu log --after ${Math.max(0, (sorted[0] ?? 1) - 1)}${tail}`;\n }\n const spec = runs.map(([a, b]) => (a === b ? String(a) : `${a}..${b}`)).join(\",\");\n return `mu log --seq ${spec}${tail}`;\n}\n\nexport interface LogPageOpts {\n json: boolean;\n /** Fill from the newest record (a \"latest N\" read); else from the oldest (a cursor read). */\n newest: boolean;\n /** Every record whole, no cap, no footer (`--seq`). */\n whole?: boolean;\n /** A cursor read with no filter (`--after`): the resume is `--after <last shown>`. */\n cursor?: boolean;\n /** No visible op lies strictly between these two seqs (lets a hint name a range). */\n gapEmpty(a: number, b: number): boolean;\n}\n\n/** A page of log records (oldest first), at most RESULT_BYTES of final output. */\nexport function logPage(rows: readonly LogRow[], opts: LogPageOpts): PageOut {\n const say = (seqs: readonly number[]): string => seqCommand(seqs, opts.gapEmpty, opts.json);\n return pageOut(rows, {\n json: opts.json,\n newest: opts.newest,\n whole: opts.whole === true,\n text: (r, all) => logRecord(r, all),\n item: (r, all) => logItem(r, all),\n // The ops left out, by seq: a latest-N read omits the older ones, a cursor read the later.\n resume: (shown) => {\n if (opts.cursor === true) {\n const at = shown[shown.length - 1]?.seq ?? (rows[0]?.seq ?? 1) - 1;\n return `mu log --after ${at}${opts.json ? \" --json\" : \"\"}`;\n }\n const on = new Set(shown.map((r) => r.seq));\n return say(rows.filter((r) => !on.has(r.seq)).map((r) => r.seq));\n },\n retrieve: (clipped) => say(clipped.map((r) => r.seq)),\n });\n}\n\n/** One op as `--tail` and a log write print it: the item, plus the way back to the whole op when it was clipped. */\nexport function logOut(row: LogRow): LogItem & { retrieve?: string } {\n const { item } = logItem(row);\n return item.cut === undefined ? item : { ...item, retrieve: `mu log --seq ${row.seq} --json` };\n}\n\n/** The text receipt of a log write: the one record the log shows, plus `cut=N next=...` when it clipped. */\nexport function logReceipt(row: LogRow): string[] {\n const one = logRecord(row);\n return one.cut === 0 ? [one.line] : [one.line, `cut=${one.cut} next=mu log --seq ${row.seq}`];\n}\n"],"mappings":"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","names":["fields","fields","fields","readFileSync","readFileSync","createHash","closeSync","existsSync","openSync","readdirSync","readFileSync","readSync","statSync","writeFileSync","join","createHash","closeSync","openSync","readFileSync","readSync","openSync","bytes","readSync","closeSync","readFileSync","createHash","SEGMENT_EXT","join","createHash","writeFileSync","existsSync","row","statSync","openSync","readSync","closeSync","readFileSync","bytes","readdirSync","workstreamId","refuse","str","bytes","existsSync","statSync","statSync","existsSync","workstreamId","text","cut","room","page","bytes","page","say"]}
1
+ {"version":3,"sources":["../src/fold.ts","../src/apply.ts","../src/segment-manifest.ts","../src/sha256-resumable.ts","../src/sync-dir-guard.ts","../src/segments.ts","../src/segment-resume.ts","../src/task-auto.ts","../src/task-brief.ts","../src/auto-attempt.ts","../src/dag.ts","../src/log-render.ts","../src/output-contract.ts","../src/human-needed.ts","../src/next-hints.ts","../src/sync.ts","../src/wait-callers.ts","../src/agent-output.ts","../src/cli/tasks/records.ts","../src/cli/page-records.ts","../src/cli/log-records.ts"],"sourcesContent":["// mu — the FOLD: what the ops log says a portable row is.\n//\n// One pure function per kind of row, from the ops of ONE natural key (plus\n// the tombstone horizon that covers it) to the row's state. Nothing here\n// touches a database. Both write paths call these through src/apply.ts:\n// `mu rebuild` folds every key once, and a live apply (ingest, `--from`,\n// an SDK caller) folds the keys an op touches. So live state for a key is,\n// by construction, rebuild-of-that-key, whatever order its ops arrived in.\n//\n// THE RULES (docs/architecture/sync.md § Order-independent apply)\n// horizon a put older than the newest `del` of its own key or of an\n// ancestor (task -> workstream) is dead; the `del` wiped it.\n// task per-field LWW by HLC over the live puts. A field absent from\n// every live put takes its default, and a default that is a\n// timestamp is the ISO time of the HLC that began the life,\n// never \"now\": the same log folds to the same row on any\n// machine, at any time.\n// kind/wave per-field LWW like the rest; kind is one of TASK_KINDS (an\n// unknown value is dropped, default 'work'), wave is nullable.\n// substate not LWW: the newest live op that writes one, resolved\n// against the folded status (a concurrent close and park fall\n// back to the status default).\n// workstream exists from its first live put (its own, or a task's under\n// it: a task put creates its parent) until the next `del`.\n// note grow-only set by content identity (author, content,\n// created_at). A `del` kills the puts of that identity older\n// than itself; a later put brings it back.\n// edge LWW element: present iff a put is newer than its own `del`\n// and both endpoints' horizons; created_at is the first live\n// put's.\n//\n// A payload is decoded leniently: a field with a value the schema would\n// refuse (CHECK, NOT NULL) or of an unsupported type is dropped like an\n// unknown field. A RAISE during ingest would roll back the segment and\n// stall sync forever; the log is accepted as it is.\n\nimport {\n DEFAULT_EFFORT_DAYS,\n DEFAULT_IMPACT,\n NOTE_KINDS,\n TASK_KINDS,\n type TaskKind,\n} from \"./db.js\";\nimport { compareHlc, parseHlc } from \"./hlc.js\";\nimport {\n DEFAULT_SUBSTATE,\n isTaskStatus,\n mapLegacyStatus,\n resolvePair,\n type TaskStatus,\n} from \"./tasks/status.js\";\n\n/** The part of an op a fold reads. */\nexport interface LogOp {\n hlc: string;\n op: \"put\" | \"del\";\n /** The natural key; a note fold reads it to pair a `del` with its put. */\n key: string;\n payload: string;\n}\n\ntype Scalar = string | number | null;\n\n/** The scalar members of a payload; anything else (nested value, bad JSON,\n * a non-object) is dropped. Booleans become 0/1 like SQLite stores them. */\nfunction fieldsOf(payload: string): Record<string, Scalar> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch {\n return {};\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n const out: Record<string, Scalar> = {};\n for (const [field, value] of Object.entries(parsed)) {\n if (value === null || typeof value === \"string\" || typeof value === \"number\") {\n out[field] = value;\n } else if (typeof value === \"boolean\") {\n out[field] = value ? 1 : 0;\n }\n }\n return out;\n}\n\n/** The ISO time of an HLC's wall clock: the deterministic stand-in for\n * \"now\" wherever a row's timestamp is not in any op. */\nexport function isoOfHlc(hlc: string): string {\n try {\n return new Date(parseHlc(hlc).wallMs).toISOString();\n } catch {\n return new Date(0).toISOString();\n }\n}\n\nconst ascending = (ops: readonly LogOp[]): LogOp[] =>\n [...ops].sort((a, b) => compareHlc(a.hlc, b.hlc));\n\n/** The newest `del` among `ops`, or null. */\nexport function newestDel(ops: readonly LogOp[]): string | null {\n let newest: string | null = null;\n for (const o of ops) {\n if (o.op === \"del\" && (newest === null || compareHlc(o.hlc, newest) > 0)) newest = o.hlc;\n }\n return newest;\n}\n\n/** The later of two horizons; null is \"none\". */\nexport function laterHlc(a: string | null, b: string | null): string | null {\n if (a === null) return b;\n if (b === null) return a;\n return compareHlc(a, b) >= 0 ? a : b;\n}\n\n/** Puts strictly newer than `horizon`, oldest first. */\nfunction livePuts(ops: readonly LogOp[], horizon: string | null): LogOp[] {\n return ascending(ops).filter(\n (o) => o.op === \"put\" && (horizon === null || compareHlc(o.hlc, horizon) > 0),\n );\n}\n\n/** The newest value of `field` that `accept` takes, in HLC order. */\nfunction lww<T>(\n puts: readonly { fields: Record<string, Scalar> }[],\n field: string,\n accept: (v: Scalar) => T | undefined,\n): { value: T } | undefined {\n let found: { value: T } | undefined;\n for (const p of puts) {\n if (!(field in p.fields)) continue;\n const v = accept(p.fields[field] ?? null);\n if (v !== undefined) found = { value: v };\n }\n return found;\n}\n\nconst str = (v: Scalar): string | undefined => (typeof v === \"string\" ? v : undefined);\nconst strOrNull = (v: Scalar): string | null | undefined =>\n v === null || typeof v === \"string\" ? v : undefined;\n\n// ─── workstream ───────────────────────────────────────────────────────\n\nexport interface WorkstreamState {\n createdAt: string;\n tornDownAt: string | null;\n}\n\n/**\n * The workstream's row, or null when it does not exist. `ops` are its own\n * puts and dels; `firstTaskPutAfter(h)` is the oldest put of any task\n * under it newer than `h` (null: none), because a task put creates the\n * parent. Its life starts at the oldest of those and its own first live\n * put, and a restart after a `del` forgets the dead life's fields.\n */\nexport function foldWorkstream(\n ops: readonly LogOp[],\n firstTaskPutAfter: (after: string | null) => string | null,\n): WorkstreamState | null {\n const horizon = newestDel(ops);\n const puts = livePuts(ops, horizon).map((o) => ({ hlc: o.hlc, fields: fieldsOf(o.payload) }));\n const created = lww(puts, \"created_at\", str);\n const torn = lww(puts, \"torn_down_at\", strOrNull);\n // The scan for a task put is the expensive input, so it runs only when\n // the answer needs it: existence with no live put of its own, or the\n // creation default with no created_at in any of them.\n const own = puts[0]?.hlc ?? null;\n if (own === null && firstTaskPutAfter(horizon) === null) return null;\n let createdAt = created?.value;\n if (createdAt === undefined) {\n const task = firstTaskPutAfter(horizon);\n const start = own === null ? task : task === null ? own : earlierHlc(own, task);\n createdAt = isoOfHlc(start ?? \"\");\n }\n return { createdAt, tornDownAt: torn?.value ?? null };\n}\n\nfunction earlierHlc(a: string, b: string): string {\n return compareHlc(a, b) <= 0 ? a : b;\n}\n\n// ─── task ─────────────────────────────────────────────────────────────\n\nexport interface TaskState {\n title: string;\n status: TaskStatus;\n substate: string;\n impact: number;\n effortDays: number;\n scored: number;\n dispatchHost: string | null;\n kind: TaskKind;\n wave: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** The substate a payload writes, or null if it writes none.\n *\n * - A legacy status writes the substate it maps to, overriding any\n * substate beside it (mirrors resolvePair).\n * - A known status with no substate writes the status's default. Capture\n * records only changed columns and the substate sets are disjoint, so a\n * v11 status change always carries its substate: a status-only op comes\n * from a v10 peer or pre-v11 history, where every status had exactly\n * its default.\n * - Otherwise the explicit substate, or null. */\nfunction carriedSubstate(fields: Record<string, Scalar>): string | null {\n const { status, substate } = fields;\n if (typeof status === \"string\") {\n const legacy = mapLegacyStatus(status);\n if (legacy) return legacy.substate;\n if (typeof substate !== \"string\" && isTaskStatus(status)) return DEFAULT_SUBSTATE[status];\n }\n return typeof substate === \"string\" ? substate : null;\n}\n\n/** A status this build knows, a legacy one mapped onto its pair's status. */\nfunction knownStatus(v: Scalar): TaskStatus | undefined {\n if (typeof v !== \"string\") return undefined;\n const legacy = mapLegacyStatus(v);\n if (legacy) return legacy.status;\n return isTaskStatus(v) ? v : undefined;\n}\n\nconst impactOf = (v: Scalar): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) && v >= 1 && v <= 100 ? v : undefined;\nconst effortOf = (v: Scalar): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : undefined;\nconst scoredOf = (v: Scalar): number | undefined => (v === 0 || v === 1 ? v : undefined);\n/** A task kind this build knows; any other value is dropped like an\n * unknown field, so a newer peer's kind never trips the CHECK in ingest. */\nconst kindOf = (v: Scalar): TaskKind | undefined =>\n typeof v === \"string\" && (TASK_KINDS as readonly string[]).includes(v)\n ? (v as TaskKind)\n : undefined;\n\n/**\n * The task's row, or null when it is dead (no put newer than `horizon`,\n * the newest `del` of the task or of its workstream).\n */\nexport function foldTask(\n ops: readonly LogOp[],\n horizon: string | null,\n localId: string,\n): TaskState | null {\n const puts = livePuts(ops, horizon).map((o) => ({ hlc: o.hlc, fields: fieldsOf(o.payload) }));\n const began = puts[0]?.hlc;\n if (began === undefined) return null;\n const born = isoOfHlc(began);\n const status = lww(puts, \"status\", knownStatus)?.value ?? \"OPEN\";\n let winner: string | null = null;\n for (const p of puts) winner = carriedSubstate(p.fields) ?? winner;\n const pair = resolvePair(status, winner ?? DEFAULT_SUBSTATE[status]);\n return {\n title: lww(puts, \"title\", str)?.value ?? localId,\n status,\n substate: pair?.substate ?? DEFAULT_SUBSTATE[status],\n impact: lww(puts, \"impact\", impactOf)?.value ?? DEFAULT_IMPACT,\n effortDays: lww(puts, \"effort_days\", effortOf)?.value ?? DEFAULT_EFFORT_DAYS,\n scored: lww(puts, \"scored\", scoredOf)?.value ?? 0,\n dispatchHost: lww(puts, \"dispatch_host\", strOrNull)?.value ?? null,\n kind: lww(puts, \"kind\", kindOf)?.value ?? \"work\",\n wave: lww(puts, \"wave\", strOrNull)?.value ?? null,\n createdAt: lww(puts, \"created_at\", str)?.value ?? born,\n updatedAt: lww(puts, \"updated_at\", str)?.value ?? born,\n };\n}\n\n// ─── note ─────────────────────────────────────────────────────────────\n\nexport interface NoteState {\n author: string | null;\n content: string;\n createdAt: string;\n kind: string;\n}\n\n/** A note's identity: the text is not unique (a machine repeats its lines),\n * so created_at is part of it. The origin id in the key is not: it names\n * the row on its origin machine only. */\nexport function noteIdentity(author: string | null, content: string, createdAt: string): string {\n return JSON.stringify([author ?? \"\", content, createdAt]);\n}\n\ninterface NotePut extends NoteState {\n hlc: string;\n key: string;\n}\n\nfunction notePut(o: LogOp): NotePut {\n const f = fieldsOf(o.payload);\n const author =\n typeof f.author === \"string\" ? f.author : f.author == null ? null : String(f.author);\n const sentKind = f.kind;\n return {\n hlc: o.hlc,\n key: o.key,\n author,\n content: f.content == null ? \"\" : String(f.content),\n createdAt: typeof f.created_at === \"string\" ? f.created_at : isoOfHlc(o.hlc),\n kind: (NOTE_KINDS as readonly unknown[]).includes(sentKind) ? (sentKind as string) : \"note\",\n };\n}\n\n/**\n * The notes of one task, keyed by identity. `ops` are every note op under\n * the task. A `del` names its note either by carrying the identity itself\n * (capture writes the full row when no put shares its key) or, bare, by\n * the newest put under its key that is older than it; created_at may be\n * absent from a hand-written one, which then matches every copy of the\n * text. `kind` is set once: the first put's.\n */\nexport function foldNotes(ops: readonly LogOp[], horizon: string | null): Map<string, NoteState> {\n const sorted = ascending(ops);\n const puts = sorted.filter((o) => o.op === \"put\").map(notePut);\n const kills: { hlc: string; author: string | null; content: string; createdAt: string | null }[] =\n [];\n for (const d of sorted) {\n if (d.op !== \"del\") continue;\n const f = fieldsOf(d.payload);\n if (f.content != null) {\n kills.push({\n hlc: d.hlc,\n author: f.author == null ? null : String(f.author),\n content: String(f.content),\n createdAt: typeof f.created_at === \"string\" ? f.created_at : null,\n });\n continue;\n }\n const src = puts.filter((p) => p.key === d.key && compareHlc(p.hlc, d.hlc) < 0).pop();\n if (src)\n kills.push({\n hlc: d.hlc,\n author: src.author,\n content: src.content,\n createdAt: src.createdAt,\n });\n }\n const out = new Map<string, NoteState>();\n for (const p of puts) {\n if (horizon !== null && compareHlc(p.hlc, horizon) <= 0) continue;\n const killed = kills.some(\n (k) =>\n compareHlc(k.hlc, p.hlc) > 0 &&\n k.content === p.content &&\n (k.author ?? \"\") === (p.author ?? \"\") &&\n (k.createdAt === null || k.createdAt === p.createdAt),\n );\n if (killed) continue;\n const id = noteIdentity(p.author, p.content, p.createdAt);\n if (!out.has(id))\n out.set(id, { author: p.author, content: p.content, createdAt: p.createdAt, kind: p.kind });\n }\n return out;\n}\n\n// ─── edge ─────────────────────────────────────────────────────────────\n\n/**\n * The edge's created_at, or null when it is absent: no put newer than its\n * own `del` and than the horizons of both endpoints.\n */\nexport function foldEdge(\n ops: readonly LogOp[],\n endpointHorizons: readonly (string | null)[],\n): { createdAt: string } | null {\n let horizon = newestDel(ops);\n for (const h of endpointHorizons) horizon = laterHlc(horizon, h);\n const first = livePuts(ops, horizon)[0];\n if (first === undefined) return null;\n const stamped = fieldsOf(first.payload).created_at;\n return { createdAt: typeof stamped === \"string\" ? stamped : isoOfHlc(first.hlc) };\n}\n","// mu — the APPLY path: how an op lands in the portable tables.\n//\n// The counterpart to src/capture.ts. Capture answers \"a row changed, what\n// op records it\"; this answers \"here is an op, local or from a peer, what\n// do the tables look like afterwards\". It knows nothing about segments,\n// files or watermarks.\n//\n// LIVE STATE IS REBUILD-OF-THAT-KEY\n// ---------------------------------\n// The ops log is the canonical record and the tables are a projection of\n// it. src/fold.ts defines the projection as a PURE function: the ops of\n// one natural key (plus the tombstone horizon covering it) in, the row's\n// state out. This module has no merge rule of its own. `applyOp` finds the\n// keys the op can change and re-folds each from ALL the ops the log knows\n// for it, then makes the table row equal the fold. `mu rebuild` replays\n// the log through the same call. So live state equals an HLC-order\n// rebuild for EVERY arrival order of the same op set, by construction:\n// there is no per-path comparison (put vs del, child vs parent) left to\n// get wrong, and no \"deferred\" op to repair later.\n//\n// WHAT AN OP CAN CHANGE\n// workstream put its own row.\n// workstream del its row, and every task, note and edge beneath it\n// (the horizon moved).\n// task put the task row and its workstream (a task put creates\n// its parent); when the task came into or went out of\n// existence, also its notes and the edges touching it.\n// task del the same, always.\n// note put / del that task's notes.\n// edge put / del that edge.\n//\n// PROVENANCE IS THE LOG\n// ---------------------\n// Every op carries its HLC and names the fields it touched, so \"the HLC\n// that last wrote field F of key K\" is a query over K's handful of ops\n// (`idx_ops_entity_key`), not a fact needing a side table. The op being\n// applied is passed in beside the log's rows, so record-then-apply and\n// apply-then-record fold identically, and re-applying an op is a no-op.\n//\n// TOMBSTONES ARE JUST OPS. There is no tombstone table: a `del` is an op\n// with an HLC, and a put older than the newest `del` covering its key is\n// dead whatever the arrival order.\n\nimport {\n type Db,\n MACHINE_LOCAL_ENTITIES,\n prepareCached,\n SYNCED_ENTITIES,\n type SyncedEntity,\n} from \"./db.js\";\nimport {\n foldEdge,\n foldNotes,\n foldTask,\n foldWorkstream,\n type LogOp,\n laterHlc,\n newestDel,\n noteIdentity,\n} from \"./fold.js\";\nimport { compareHlc } from \"./hlc.js\";\nimport { withCaptureSuppressed } from \"./op-context.js\";\n\n/** An op as applied. Mirrors the `ops` row shape, minus the local-only\n * `seq` (meaningless on a peer) and the advisory `created_at`. */\nexport interface Op {\n /** The ordering key. See docs/VOCABULARY.md § HLC. */\n hlc: string;\n /** Which peer minted it. Half of the (machine_id, hlc) identity. */\n machineId: string;\n /** One user-visible action (the op group). */\n groupId: string;\n /** Free text: agent name, \"user\", \"system\". */\n actor?: string | null;\n /** Semantic label, e.g. \"task.close\". */\n intent?: string | null;\n /** Which kind of thing this op addresses. */\n entity: string;\n /** The NATURAL key. Never a surrogate id. */\n key: string;\n /** 'put' = semantic partial update, 'del' = tombstone. */\n op: \"put\" | \"del\";\n /** JSON object of ONLY the fields this op touched. */\n payload: string;\n}\n\n/** Thrown when an op names an entity this build KNOWS is machine-local\n * (see `MACHINE_LOCAL_ENTITIES`). Loud by design: a peer shipping a\n * pane id or an absolute path is a real bug we want reported.\n *\n * NOT thrown for an entity we merely do not recognise. That is a\n * reader-behind-writer vocabulary skew in a mixed fleet, and treating\n * it as a defect froze one peer's watermark permanently — see\n * `MACHINE_LOCAL_ENTITIES` in src/db.ts for the incident. */\nexport class OpEntityNotSyncedError extends Error {\n constructor(readonly entity: string) {\n super(\n `op entity ${JSON.stringify(entity)} is machine-local and must never arrive from a peer ` +\n `(synced entities: ${SYNCED_ENTITIES.join(\", \")})`,\n );\n this.name = \"OpEntityNotSyncedError\";\n }\n}\n\n/** Thrown when an op's natural key does not parse for its entity. */\nexport class OpKeyMalformedError extends Error {\n constructor(\n readonly entity: string,\n readonly key: string,\n ) {\n super(`malformed ${entity} key: ${JSON.stringify(key)}`);\n this.name = \"OpKeyMalformedError\";\n }\n}\n\n/** What `applyOp` did, so callers (and tests) can assert on outcomes\n * rather than re-querying. */\nexport interface ApplyResult {\n /** True iff the DB changed. False for a dead, superseded or duplicate\n * op: legitimate and non-exceptional. */\n changed: boolean;\n /** The columns of a task or workstream row the op changed. */\n appliedFields: string[];\n}\n\nfunction isSyncedEntity(entity: string): entity is SyncedEntity {\n return (SYNCED_ENTITIES as readonly string[]).includes(entity);\n}\n\n/** Entities this build knows must never travel. Distinct from \"unknown\":\n * only these are a defect. */\nfunction isKnownMachineLocalEntity(entity: string): boolean {\n return (MACHINE_LOCAL_ENTITIES as readonly string[]).includes(entity);\n}\n\n// ─── Natural key parsing ──────────────────────────────────────────────\n//\n// The inverse of src/capture.ts's key builders. Kept here rather than\n// shared with capture because capture composes keys in SQL and this\n// decomposes them in TS; a \"shared\" helper would be two functions in one\n// file pretending to be one thing.\n\n/** `<workstream>/<local_id>` -> its parts. Task ids match\n * `[a-z][a-z0-9_-]*`, so they never contain '/', making the FIRST '/'\n * the unambiguous separator. */\nfunction parseTaskKey(key: string): { workstream: string; localId: string } {\n const slash = key.indexOf(\"/\");\n if (slash <= 0 || slash === key.length - 1) throw new OpKeyMalformedError(\"task\", key);\n const workstream = key.slice(0, slash);\n const localId = key.slice(slash + 1);\n if (workstream.length === 0 || localId.length === 0) {\n throw new OpKeyMalformedError(\"task\", key);\n }\n return { workstream, localId };\n}\n\n/** `<task-key>#<origin-id>` -> the task key it hangs off. Task ids\n * cannot contain '#', so the LAST '#' separates. The origin id is\n * validated as present (a key without one is malformed) but not\n * returned: it identifies the note on its ORIGIN machine only, and\n * `syncNotes` uses content identity instead. See its comment. */\nfunction parseNoteKey(key: string): { taskKey: string } {\n const hash = key.lastIndexOf(\"#\");\n if (hash <= 0 || hash === key.length - 1) throw new OpKeyMalformedError(\"note\", key);\n return { taskKey: key.slice(0, hash) };\n}\n\n/** `<blocker>-><blocked>` -> its parts. Task ids MAY end in '-', so\n * `demo/a-->demo/b` is a valid key for blocker `demo/a-`; splitting on\n * the FIRST '->' recovers that correctly, whereas a naive split('->')\n * would produce three fragments. */\nfunction parseEdgeKey(key: string): { blocker: string; blocked: string } {\n const arrow = key.indexOf(\"->\");\n if (arrow <= 0) throw new OpKeyMalformedError(\"edge\", key);\n const blocker = key.slice(0, arrow);\n const blocked = key.slice(arrow + 2);\n if (blocker.length === 0 || blocked.length === 0) throw new OpKeyMalformedError(\"edge\", key);\n return { blocker, blocked };\n}\n\n// ─── The log, as the folds read it ────────────────────────────────────\n\n/** The smallest string above every string starting with `p`. */\nconst hi = (p: string): string =>\n `${p.slice(0, -1)}${String.fromCharCode(p.charCodeAt(p.length - 1) + 1)}`;\n\ninterface LogRow {\n hlc: string;\n op: \"put\" | \"del\";\n key: string;\n payload: string;\n}\n\n/**\n * Read access to the ops log, plus the op being applied (which the caller\n * may not have recorded yet). Every query returns the union, deduplicated\n * by HLC (an HLC embeds its machine id, so it names one op).\n */\nclass Log {\n private readonly pending: LogRow | undefined;\n private readonly pendingEntity: string;\n\n constructor(\n private readonly db: Db,\n op?: Op,\n ) {\n this.pending = op && { hlc: op.hlc, op: op.op, key: op.key, payload: op.payload };\n this.pendingEntity = op?.entity ?? \"\";\n }\n\n private withPending(entity: string, rows: LogRow[], inScope: (key: string) => boolean): LogRow[] {\n const p = this.pending;\n if (p === undefined || entity !== this.pendingEntity || !inScope(p.key)) return rows;\n return rows.some((r) => r.hlc === p.hlc) ? rows : [...rows, p];\n }\n\n /** The ops of one natural key. */\n ofKey(entity: string, key: string): LogOp[] {\n const rows = prepareCached(\n this.db,\n \"SELECT hlc, op, key, payload FROM ops WHERE entity = ? AND key = ?\",\n ).all(entity, key) as LogRow[];\n return this.withPending(entity, rows, (k) => k === key);\n }\n\n /** The ops of every key in [lo, hi), grouped by key. */\n range(entity: string, lo: string, hiKey: string): Map<string, LogOp[]> {\n const rows = this.withPending(\n entity,\n prepareCached(\n this.db,\n \"SELECT hlc, op, key, payload FROM ops WHERE entity = ? AND key >= ? AND key < ?\",\n ).all(entity, lo, hiKey) as LogRow[],\n (k) => k >= lo && k < hiKey,\n );\n const out = new Map<string, LogOp[]>();\n for (const r of rows) {\n const list = out.get(r.key);\n if (list) list.push(r);\n else out.set(r.key, [r]);\n }\n return out;\n }\n\n /** The oldest task put under workstream `ws` newer than `after`. */\n firstTaskPutAfter(ws: string, after: string | null): string | null {\n const lo = `${ws}/`;\n const row = prepareCached(\n this.db,\n `SELECT MIN(hlc) AS hlc FROM ops\n WHERE entity = 'task' AND op = 'put' AND key >= @lo AND key < @hi\n AND (@after IS NULL OR hlc > @after)`,\n ).get({ lo, hi: hi(lo), after }) as { hlc: string | null };\n const p = this.pending;\n let best = row.hlc;\n if (\n p !== undefined &&\n this.pendingEntity === \"task\" &&\n p.op === \"put\" &&\n p.key >= lo &&\n p.key < hi(lo) &&\n (after === null || p.hlc > after)\n ) {\n best = best === null || p.hlc < best ? p.hlc : best;\n }\n return best;\n }\n\n /** Edge keys naming a task in `scope`: a workstream (`name/`) or one task. */\n edgeKeysTouching(scope: { workstream: string } | { task: string }): string[] {\n const candidates =\n \"workstream\" in scope\n ? prepareCached(\n this.db,\n `SELECT DISTINCT key FROM ops\n WHERE entity = 'edge' AND (instr(key, @to) > 0 OR (key >= @lo AND key < @hi))`,\n ).all({\n to: `->${scope.workstream}/`,\n lo: `${scope.workstream}/`,\n hi: hi(`${scope.workstream}/`),\n })\n : prepareCached(\n this.db,\n `SELECT DISTINCT key FROM ops\n WHERE entity = 'edge'\n AND ((key >= @lo AND key < @hi) OR substr(key, -length(@to)) = @to)`,\n ).all({ to: `->${scope.task}`, lo: `${scope.task}->`, hi: hi(`${scope.task}->`) });\n const keys = new Set((candidates as { key: string }[]).map((r) => r.key));\n const p = this.pending;\n if (p !== undefined && this.pendingEntity === \"edge\") keys.add(p.key);\n return [...keys].filter((key) => {\n let ends: { blocker: string; blocked: string };\n try {\n ends = parseEdgeKey(key);\n } catch {\n return false;\n }\n const inScope = (t: string): boolean =>\n \"workstream\" in scope ? t.startsWith(`${scope.workstream}/`) : t === scope.task;\n return inScope(ends.blocker) || inScope(ends.blocked);\n });\n }\n}\n\n/** The newest tombstone covering a task: its own `del` or its workstream's\n * (a workstream `del` cascades every task, note and edge beneath it). */\nfunction taskHorizon(log: Log, taskKey: string): string | null {\n const { workstream } = parseTaskKey(taskKey);\n return laterHlc(\n newestDel(log.ofKey(\"task\", taskKey)),\n newestDel(log.ofKey(\"workstream\", workstream)),\n );\n}\n\n// ─── Reconcile: make a row equal its fold ─────────────────────────────\n\ntype Fields = Record<string, string | number | null>;\n\n/** The names of the fields on which `a` and `b` differ, in `a`'s order. */\nfunction differing(a: Fields, b: Fields): string[] {\n return Object.keys(a).filter((k) => a[k] !== b[k]);\n}\n\nconst workstreamId = (db: Db, name: string): number | null =>\n (\n prepareCached(db, \"SELECT id FROM workstreams WHERE name = ?\").get(name) as\n | { id: number }\n | undefined\n )?.id ?? null;\n\n/** Surrogate id for a task natural key, or null when absent. */\nfunction taskRowId(db: Db, key: string): number | null {\n const { workstream, localId } = parseTaskKey(key);\n const row = prepareCached(\n db,\n `SELECT t.id AS id FROM tasks t JOIN workstreams w ON w.id = t.workstream_id\n WHERE w.name = ? AND t.local_id = ?`,\n ).get(workstream, localId) as { id: number } | undefined;\n return row?.id ?? null;\n}\n\ninterface Reconciled {\n changed: boolean;\n fields: string[];\n}\nconst UNCHANGED: Reconciled = { changed: false, fields: [] };\n\nfunction syncWorkstream(db: Db, log: Log, name: string): Reconciled {\n const state = foldWorkstream(log.ofKey(\"workstream\", name), (after) =>\n log.firstTaskPutAfter(name, after),\n );\n const row = prepareCached(\n db,\n \"SELECT id, created_at, torn_down_at FROM workstreams WHERE name = ?\",\n ).get(name) as { id: number; created_at: string; torn_down_at: string | null } | undefined;\n if (state === null) {\n if (row === undefined) return UNCHANGED;\n // FK CASCADE removes the tasks, notes and edges beneath it, and the\n // agents (agents.workstream_id): a trigger records their remote worktrees.\n prepareCached(db, \"DELETE FROM workstreams WHERE id = ?\").run(row.id);\n return { changed: true, fields: [] };\n }\n const want: Fields = { created_at: state.createdAt, torn_down_at: state.tornDownAt };\n if (row === undefined) {\n prepareCached(\n db,\n \"INSERT INTO workstreams (name, created_at, torn_down_at) VALUES (?, ?, ?)\",\n ).run(name, state.createdAt, state.tornDownAt);\n return { changed: true, fields: Object.keys(want) };\n }\n const fields = differing(want, { created_at: row.created_at, torn_down_at: row.torn_down_at });\n if (fields.length === 0) return UNCHANGED;\n prepareCached(db, \"UPDATE workstreams SET created_at = ?, torn_down_at = ? WHERE id = ?\").run(\n state.createdAt,\n state.tornDownAt,\n row.id,\n );\n return { changed: true, fields };\n}\n\nfunction syncTask(db: Db, log: Log, key: string): Reconciled {\n const { workstream, localId } = parseTaskKey(key);\n const state = foldTask(log.ofKey(\"task\", key), taskHorizon(log, key), localId);\n const existing = prepareCached(\n db,\n `SELECT t.id, t.title, t.status, t.substate, t.impact, t.effort_days, t.scored,\n t.dispatch_host, t.kind, t.wave, t.created_at, t.updated_at\n FROM tasks t JOIN workstreams w ON w.id = t.workstream_id\n WHERE w.name = ? AND t.local_id = ?`,\n ).get(workstream, localId) as (Fields & { id: number }) | undefined;\n if (state === null) {\n if (existing === undefined) return UNCHANGED;\n prepareCached(db, \"DELETE FROM tasks WHERE id = ?\").run(existing.id);\n return { changed: true, fields: [] };\n }\n const want: Fields = {\n title: state.title,\n status: state.status,\n substate: state.substate,\n impact: state.impact,\n effort_days: state.effortDays,\n scored: state.scored,\n dispatch_host: state.dispatchHost,\n kind: state.kind,\n wave: state.wave,\n created_at: state.createdAt,\n updated_at: state.updatedAt,\n };\n if (existing === undefined) {\n const wsId = workstreamId(db, workstream);\n // The workstream fold keeps the parent of every live task alive.\n if (wsId === null) return UNCHANGED;\n prepareCached(\n db,\n `INSERT INTO tasks (workstream_id, local_id, title, status, substate, impact, effort_days,\n scored, dispatch_host, kind, wave, owner_id, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?)`,\n ).run(\n wsId,\n localId,\n state.title,\n state.status,\n state.substate,\n state.impact,\n state.effortDays,\n state.scored,\n state.dispatchHost,\n state.kind,\n state.wave,\n state.createdAt,\n state.updatedAt,\n );\n return { changed: true, fields: Object.keys(want) };\n }\n const fields = differing(want, existing);\n if (fields.length === 0) return UNCHANGED;\n prepareCached(\n db,\n `UPDATE tasks SET title = ?, status = ?, substate = ?, impact = ?, effort_days = ?,\n scored = ?, dispatch_host = ?, kind = ?, wave = ?, created_at = ?, updated_at = ?\n WHERE id = ?`,\n ).run(\n state.title,\n state.status,\n state.substate,\n state.impact,\n state.effortDays,\n state.scored,\n state.dispatchHost,\n state.kind,\n state.wave,\n state.createdAt,\n state.updatedAt,\n existing.id,\n );\n return { changed: true, fields };\n}\n\nfunction syncNotes(db: Db, log: Log, taskKey: string): boolean {\n const taskId = taskRowId(db, taskKey);\n if (taskId === null) return false;\n const ops: LogOp[] = [...log.range(\"note\", `${taskKey}#`, `${taskKey}$`).values()].flat();\n const want = foldNotes(ops, taskHorizon(log, taskKey));\n const rows = prepareCached(\n db,\n \"SELECT id, author, content, created_at, kind FROM task_notes WHERE task_id = ? ORDER BY id\",\n ).all(taskId) as {\n id: number;\n author: string | null;\n content: string;\n created_at: string;\n kind: string;\n }[];\n let changed = false;\n const seen = new Set<string>();\n for (const r of rows) {\n const id = noteIdentity(r.author, r.content, r.created_at);\n if (want.has(id) && !seen.has(id)) {\n seen.add(id);\n continue;\n }\n // Not in the fold, or a repeat of an identity already kept.\n prepareCached(db, \"DELETE FROM task_notes WHERE id = ?\").run(r.id);\n changed = true;\n }\n for (const [id, n] of want) {\n if (seen.has(id)) continue;\n prepareCached(\n db,\n \"INSERT INTO task_notes (task_id, author, content, created_at, kind) VALUES (?, ?, ?, ?, ?)\",\n ).run(taskId, n.author, n.content, n.createdAt, n.kind);\n changed = true;\n }\n return changed;\n}\n\nfunction syncEdge(db: Db, log: Log, key: string): boolean {\n const { blocker, blocked } = parseEdgeKey(key);\n const state =\n blocker === blocked\n ? null\n : foldEdge(log.ofKey(\"edge\", key), [taskHorizon(log, blocker), taskHorizon(log, blocked)]);\n const fromId = taskRowId(db, blocker);\n const toId = taskRowId(db, blocked);\n const existing =\n fromId === null || toId === null\n ? undefined\n : (prepareCached(\n db,\n \"SELECT created_at FROM task_edges WHERE from_task_id = ? AND to_task_id = ?\",\n ).get(fromId, toId) as { created_at: string } | undefined);\n const wanted = state !== null && fromId !== null && toId !== null;\n if (!wanted) {\n if (existing === undefined || fromId === null || toId === null) return false;\n prepareCached(db, \"DELETE FROM task_edges WHERE from_task_id = ? AND to_task_id = ?\").run(\n fromId,\n toId,\n );\n return true;\n }\n if (existing === undefined) {\n prepareCached(\n db,\n \"INSERT INTO task_edges (from_task_id, to_task_id, created_at) VALUES (?, ?, ?)\",\n ).run(fromId, toId, state.createdAt);\n return true;\n }\n if (existing.created_at === state.createdAt) return false;\n prepareCached(\n db,\n \"UPDATE task_edges SET created_at = ? WHERE from_task_id = ? AND to_task_id = ?\",\n ).run(state.createdAt, fromId, toId);\n return true;\n}\n\n/** Re-fold a task's notes and every edge touching it: its existence or\n * horizon changed. */\nfunction syncDependents(db: Db, log: Log, taskKey: string): boolean {\n let changed = syncNotes(db, log, taskKey);\n for (const key of log.edgeKeysTouching({ task: taskKey })) {\n if (syncEdge(db, log, key)) changed = true;\n }\n return changed;\n}\n\n// ─── Per-entity application ───────────────────────────────────────────\n\nfunction applyWorkstream(db: Db, log: Log, op: Op): ApplyResult {\n const name = op.key;\n if (name.length === 0) throw new OpKeyMalformedError(\"workstream\", name);\n const ws = syncWorkstream(db, log, name);\n let changed = ws.changed;\n if (op.op === \"del\") {\n // The horizon moved: everything beneath the workstream re-folds.\n const prefix = `${name}/`;\n const taskKeys = [...log.range(\"task\", prefix, hi(prefix)).keys()];\n for (const key of taskKeys) if (syncTask(db, log, key).changed) changed = true;\n for (const key of taskKeys) if (syncNotes(db, log, key)) changed = true;\n const edges = log.edgeKeysTouching({ workstream: name });\n for (const key of edges) if (syncEdge(db, log, key)) changed = true;\n }\n return { changed, appliedFields: ws.fields };\n}\n\nfunction applyTask(db: Db, log: Log, op: Op): ApplyResult {\n const { workstream } = parseTaskKey(op.key);\n const existed = taskRowId(db, op.key) !== null;\n const ws = syncWorkstream(db, log, workstream);\n const task = syncTask(db, log, op.key);\n let changed = ws.changed || task.changed;\n const exists = taskRowId(db, op.key) !== null;\n if ((op.op === \"del\" || existed !== exists) && syncDependents(db, log, op.key)) changed = true;\n return { changed, appliedFields: task.fields };\n}\n\nfunction applyNote(db: Db, log: Log, op: Op): ApplyResult {\n const { taskKey } = parseNoteKey(op.key);\n return { changed: syncNotes(db, log, taskKey), appliedFields: [] };\n}\n\nfunction applyEdge(db: Db, log: Log, op: Op): ApplyResult {\n parseEdgeKey(op.key);\n return { changed: syncEdge(db, log, op.key), appliedFields: [] };\n}\n\n// ─── The seam ─────────────────────────────────────────────────────────\n\n/**\n * Apply one op to the portable tables.\n *\n * SYNCHRONOUS, for the same reason `withOpContext` is: the op context is\n * the shared main-DB `op_ctx` row, so two interleaved async apply scopes\n * would clobber each other's `applying` flag with no way to tell whose\n * suppression was in force. The scope is one synchronous transaction;\n * keeping this sync makes that unrepresentable rather than merely\n * discouraged.\n *\n * Runs inside `withCaptureSuppressed`, which is THE echo guard: without\n * it, writing a peer's op to `tasks` would fire the capture trigger,\n * mint a fresh local op, flush that back to the peer, and loop forever.\n * Runs in its own transaction (a savepoint when nested): one op rewrites\n * several rows, and they commit together or not at all.\n *\n * Does NOT insert the op into `ops` — that is the caller's job (which\n * owns segment bookkeeping and the (machine_id, hlc) dedupe). The op is\n * folded in beside the log's rows, so recording it before or after\n * changes nothing and a replay of ops already in the log is a no-op.\n *\n * Idempotent: applying the same op twice makes no second change, which\n * is what lets `mu sync --repair` be nothing more than \"re-read that\n * peer's segment from zero\".\n */\nexport function applyOp(db: Db, op: Op): ApplyResult {\n if (isKnownMachineLocalEntity(op.entity)) throw new OpEntityNotSyncedError(op.entity);\n // An entity this build does not recognise is a FORWARD-COMPATIBLE\n // no-op, projected nowhere, exactly like 'message'. Recording the op\n // is the caller's step and is what preserves it for a later build\n // (and for `mu rebuild`) without blocking every op behind it.\n if (!isSyncedEntity(op.entity)) return { changed: false, appliedFields: [] };\n // Log lines live in `ops` only; recording the op IS applying it.\n if (op.entity === \"message\") return { changed: false, appliedFields: [] };\n\n return withCaptureSuppressed(db, () =>\n db\n .transaction((): ApplyResult => {\n const log = new Log(db, op);\n switch (op.entity) {\n case \"workstream\":\n return applyWorkstream(db, log, op);\n case \"task\":\n return applyTask(db, log, op);\n case \"note\":\n return applyNote(db, log, op);\n default:\n return applyEdge(db, log, op);\n }\n })\n .immediate(),\n );\n}\n\n/**\n * Project the whole log: fold every workstream, task, note set and edge\n * the ops name, once each, into the (empty or stale) tables. This is\n * `mu rebuild`: no arrival order, no incremental step, just the fold. It\n * returns the number of table rows it wrote.\n *\n * Workstreams first (a task's fold needs its parent row), then tasks, then\n * the rows that hang off tasks.\n */\nexport function projectLog(db: Db): number {\n const log = new Log(db);\n const keys = (entity: string): string[] =>\n (\n prepareCached(db, \"SELECT DISTINCT key FROM ops WHERE entity = ?\").all(entity) as {\n key: string;\n }[]\n ).map((r) => r.key);\n const taskKeys = keys(\"task\");\n const noteTasks = [...new Set(keys(\"note\").map((k) => parseNoteKey(k).taskKey))];\n const workstreams = new Set([\n ...keys(\"workstream\"),\n ...taskKeys.map((k) => parseTaskKey(k).workstream),\n ]);\n let written = 0;\n return withCaptureSuppressed(db, () =>\n db\n .transaction(() => {\n for (const name of workstreams) if (syncWorkstream(db, log, name).changed) written += 1;\n for (const key of taskKeys) if (syncTask(db, log, key).changed) written += 1;\n for (const key of noteTasks) if (syncNotes(db, log, key)) written += 1;\n for (const key of keys(\"edge\")) if (syncEdge(db, log, key)) written += 1;\n return written;\n })\n .immediate(),\n );\n}\n\n/**\n * Apply many ops in HLC order, inside one transaction. The fold makes the\n * order irrelevant to the result; sorting keeps the work in log order.\n */\nexport function applyOps(db: Db, ops: readonly Op[]): ApplyResult[] {\n const ordered = [...ops].sort((a, b) => compareHlc(a.hlc, b.hlc));\n const run = db.transaction(() => ordered.map((op) => applyOp(db, op)));\n return run.immediate();\n}\n","// mu — the segment manifest (`<machine>.manifest`): layer 4 of the\n// segment robustness layers, plus the fields the owner's flush trusts\n// instead of rescanning its own segment. Split out of segments.ts\n// (1500-LOC cap); segments.ts re-exports the public names.\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { type Sha256State, sha256Digest } from \"./sha256-resumable.js\";\n\n/** Segment filename suffix. */\nconst SEGMENT_EXT = \".jsonl\";\n/** Manifest filename suffix. */\nconst MANIFEST_EXT = \".manifest\";\n\n/** Whole-file verification sidecar. */\nexport interface SegmentManifest {\n v: number;\n machine: string;\n count: number;\n lastHlc: string | null;\n sha256: string;\n updatedAt: string;\n /** Bytes of the segment `sha256` covers. Written by the owner so its\n * next flush can trust this manifest instead of rescanning; absent in\n * manifests from older builds. */\n size?: number;\n /** The segment's mtime when this manifest was written (owner-local). */\n mtimeMs?: number;\n /** Running hash state after `size` bytes, so an append rehashes only\n * what it added. */\n shaState?: Sha256State;\n /** sha256 over the fields above (`manifestSeal`). The owner trusts\n * count/size/shaState only when it matches, so a torn or hand-edited\n * manifest falls back to the full scan instead of being persisted. */\n seal?: string;\n}\n\nexport function manifestPath(segment: string): string {\n return segment.replace(new RegExp(`${SEGMENT_EXT}$`), MANIFEST_EXT);\n}\n\n/** A manifest as this build writes it, with every field the owner's\n * fast path relies on. */\nexport type SealedManifest = SegmentManifest & {\n size: number;\n mtimeMs: number;\n shaState: Sha256State;\n seal: string;\n};\n\n/** sha256 over every field the owner's fast path trusts, in a fixed\n * order. Not a defence against a deliberate forger, who could\n * recompute it; it binds count, lastHlc, size and the hash state to\n * each other so a torn write or a hand edit of one field is caught. */\nexport function manifestSeal(m: Omit<SealedManifest, \"seal\" | \"updatedAt\">): string {\n return createHash(\"sha256\")\n .update(\n [\n m.v,\n m.machine,\n m.count,\n m.lastHlc ?? \"\",\n m.sha256,\n m.size,\n m.mtimeMs,\n m.shaState.h,\n m.shaState.n,\n m.shaState.tail,\n ].join(\"\\u001f\"),\n )\n .digest(\"hex\");\n}\n\nconst HEX64 = /^[0-9a-f]{64}$/;\n\n/**\n * True when the manifest's trusted fields agree with each other: well\n * formed, count is zero exactly when size is, the hash state covers\n * `size` bytes and finishes to `sha256`, and the seal matches. Cheap\n * (at most two SHA-256 blocks plus a hash of a few hundred bytes), and\n * it reads no segment bytes. Anything off sends the owner to the full\n * scan, which recounts, rehashes and rewrites the manifest, so a\n * malformed field is never carried into the next manifest.\n */\nexport function manifestSelfConsistent(m: SegmentManifest): m is SealedManifest {\n const { count, lastHlc, size, mtimeMs, shaState, seal } = m;\n if (!Number.isSafeInteger(count) || count < 0) return false;\n if (typeof size !== \"number\" || !Number.isSafeInteger(size) || size < 0) return false;\n if (typeof mtimeMs !== \"number\" || !Number.isFinite(mtimeMs)) return false;\n if (lastHlc !== null && typeof lastHlc !== \"string\") return false;\n if ((count === 0) !== (size === 0) || (count === 0) !== (lastHlc === null)) return false;\n if (typeof m.sha256 !== \"string\" || !HEX64.test(m.sha256)) return false;\n if (typeof seal !== \"string\" || !HEX64.test(seal)) return false;\n if (\n typeof shaState !== \"object\" ||\n shaState === null ||\n typeof shaState.h !== \"string\" ||\n !HEX64.test(shaState.h) ||\n shaState.n !== size ||\n typeof shaState.tail !== \"string\"\n ) {\n return false;\n }\n const tail = Buffer.from(shaState.tail, \"base64\");\n if (tail.length !== size % 64 || tail.toString(\"base64\") !== shaState.tail) return false;\n if (sha256Digest(shaState) !== m.sha256) return false;\n return manifestSeal({ ...m, size, mtimeMs, shaState }) === seal;\n}\n\n/** Write `fields` as the manifest of `segment`, stamped and sealed. */\nexport function writeManifestFile(\n segment: string,\n fields: Omit<SealedManifest, \"seal\" | \"updatedAt\">,\n): void {\n const manifest: SegmentManifest = {\n ...fields,\n updatedAt: new Date().toISOString(),\n seal: manifestSeal(fields),\n };\n writeFileSync(manifestPath(segment), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n}\n\n/** Read a segment's manifest, or null when absent/unparsable. */\nexport function readManifest(segment: string): SegmentManifest | null {\n const path = manifestPath(segment);\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as SegmentManifest;\n } catch {\n return null;\n }\n}\n","// mu — SHA-256 whose running state can be saved and resumed.\n//\n// Why not node:crypto: a `Hash` cannot be serialised, and every mu\n// invocation is a fresh process. The segment manifest carries the\n// sha256 of the WHOLE append-only segment, so re-hashing with\n// node:crypto made each flush O(file size) forever. Persisting the\n// running state next to the digest lets the next flush hash only the\n// bytes it appends. The digest is byte-identical to node:crypto's (see\n// test/sha256-resumable.test.ts), so peers verifying with node:crypto\n// see no difference.\n\n/** Serialisable running state: eight hash words (hex), bytes hashed so\n * far, and the partial trailing block not yet compressed (base64). */\nexport interface Sha256State {\n h: string;\n n: number;\n tail: string;\n}\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst INITIAL_H = \"6a09e667bb67ae853c6ef372a54ff53a510e527f9b05688c1f83d9ab5be0cd19\";\n\n/** State of a hash that has consumed no bytes. */\nexport function sha256Initial(): Sha256State {\n return { h: INITIAL_H, n: 0, tail: \"\" };\n}\n\nfunction wordsOf(hex: string): Uint32Array {\n const h = new Uint32Array(8);\n for (let i = 0; i < 8; i++) h[i] = Number.parseInt(hex.slice(i * 8, i * 8 + 8), 16);\n return h;\n}\n\nfunction hexOf(h: Uint32Array): string {\n let out = \"\";\n for (const word of h) out += word.toString(16).padStart(8, \"0\");\n return out;\n}\n\nconst W = new Uint32Array(64);\n\n/** Compress every whole 64-byte block of `data` from `offset` into `h`. */\nfunction compress(h: Uint32Array, data: Uint8Array, offset: number, end: number): void {\n let h0 = h[0] ?? 0;\n let h1 = h[1] ?? 0;\n let h2 = h[2] ?? 0;\n let h3 = h[3] ?? 0;\n let h4 = h[4] ?? 0;\n let h5 = h[5] ?? 0;\n let h6 = h[6] ?? 0;\n let h7 = h[7] ?? 0;\n for (let p = offset; p + 64 <= end; p += 64) {\n for (let i = 0; i < 16; i++) {\n const j = p + i * 4;\n W[i] =\n ((data[j] ?? 0) << 24) |\n ((data[j + 1] ?? 0) << 16) |\n ((data[j + 2] ?? 0) << 8) |\n (data[j + 3] ?? 0);\n }\n for (let i = 16; i < 64; i++) {\n const w15 = W[i - 15] ?? 0;\n const w2 = W[i - 2] ?? 0;\n const s0 = ((w15 >>> 7) | (w15 << 25)) ^ ((w15 >>> 18) | (w15 << 14)) ^ (w15 >>> 3);\n const s1 = ((w2 >>> 17) | (w2 << 15)) ^ ((w2 >>> 19) | (w2 << 13)) ^ (w2 >>> 10);\n W[i] = ((W[i - 16] ?? 0) + s0 + (W[i - 7] ?? 0) + s1) | 0;\n }\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n let f = h5;\n let g = h6;\n let hh = h7;\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));\n const ch = (e & f) ^ (~e & g);\n const t1 = (hh + S1 + ch + (K[i] ?? 0) + (W[i] ?? 0)) | 0;\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const t2 = (S0 + maj) | 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h0 = (h0 + a) | 0;\n h1 = (h1 + b) | 0;\n h2 = (h2 + c) | 0;\n h3 = (h3 + d) | 0;\n h4 = (h4 + e) | 0;\n h5 = (h5 + f) | 0;\n h6 = (h6 + g) | 0;\n h7 = (h7 + hh) | 0;\n }\n h.set([h0, h1, h2, h3, h4, h5, h6, h7]);\n}\n\n/** Feed `data` into `state`, returning the new state. Pure. */\nexport function sha256Update(state: Sha256State, data: Uint8Array): Sha256State {\n const pending = Buffer.from(state.tail, \"base64\");\n const all = pending.length === 0 ? data : Buffer.concat([pending, data]);\n const h = wordsOf(state.h);\n const whole = all.length - (all.length % 64);\n compress(h, all, 0, whole);\n return {\n h: hexOf(h),\n n: state.n + data.length,\n tail: Buffer.from(all.subarray(whole)).toString(\"base64\"),\n };\n}\n\n/** Hex digest of everything fed into `state`. Does not mutate it. */\nexport function sha256Digest(state: Sha256State): string {\n const pending = Buffer.from(state.tail, \"base64\");\n const padLen = pending.length < 56 ? 64 : 128;\n const block = Buffer.alloc(padLen);\n pending.copy(block);\n block[pending.length] = 0x80;\n const bits = state.n * 8;\n block.writeUInt32BE(Math.floor(bits / 2 ** 32), padLen - 8);\n block.writeUInt32BE(bits >>> 0, padLen - 4);\n const h = wordsOf(state.h);\n compress(h, block, 0, padLen);\n return hexOf(h);\n}\n","// mu — the sync-dir guard: mu 4 never reads or writes a MU_SYNC_DIR that\n// a 3.x peer shares. 3.x reads only v1 lines and warns `unknown-version` on\n// every command once a v2 line lands in its folder (the 18:04 incident), so\n// no segment may open with a v1 line for mu 4 to touch the dir.\n// Builtins only: segments.ts and the CLI's handle() both import it.\n//\n// The guard lives INSIDE flushSegment, discoverPeers and ingestSegment, so\n// every caller (CLI, SDK, extension, TUI tick) is covered; handle() repeats it\n// before the DB opens so a refused run creates nothing at all.\n\nimport { closeSync, openSync, readdirSync, readFileSync, readSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** The one-line refusal. Exit 4 (conflict); nothing was written or read. */\nexport const SYNC_DIR_FOREIGN_MESSAGE = \"MU_SYNC_DIR holds 3.x segments; give mu 4 its own dir\";\n\nexport class SyncDirForeignError extends Error {\n override readonly name = \"SyncDirForeignError\";\n constructor(\n readonly dir: string,\n /** The segment that opens with a pre-v2 line. */\n readonly segment: string,\n ) {\n super(`${SYNC_DIR_FOREIGN_MESSAGE} (${segment})`);\n }\n}\n\n/** Every writer emits `{\"v\":N,` first (`encodeSegmentLine`), so the first\n * bytes are enough: no line is parsed, so a segment still being copied in\n * does not block the dir. */\nconst VERSION_PREFIX = /^\\{\"v\":(\\d+)[,}]/;\n\n/** Test seam: the foreign-version tests deliberately write v1 and v3 segments\n * into the dir. Never set outside a test. */\nlet guardOffForTests = false;\nexport function setSyncDirGuardForTests(off: boolean): void {\n guardOffForTests = off;\n}\n\n/** True when a `.manifest` says `\"v\"` below 2: a 3.x peer's sidecar. A 3.x\n * peer with no ops yet leaves an EMPTY segment and a v1 manifest, so the\n * segment's first line cannot show it. Unreadable or torn: not evidence. */\nfunction manifestIsPreV2(path: string): boolean {\n try {\n const v: unknown = (JSON.parse(readFileSync(path, \"utf8\")) as { v?: unknown } | null)?.v;\n return typeof v === \"number\" && v < 2;\n } catch {\n return false;\n }\n}\n\n/** False only when the file's first bytes are a recognisable pre-v2 line (what\n * 3.x writes). Empty, torn, garbage and newer-than-v2 files are not evidence\n * of a 3.x peer: the segment reader reports them as defects, and a v3 line\n * keeps its \"upgrade mu\" warning rather than a message that blames 3.x. */\nfunction startsAsV2OrUnknown(path: string): boolean {\n let fd: number;\n try {\n fd = openSync(path, \"r\");\n } catch {\n return true; // vanished or unreadable: not evidence of a 3.x peer\n }\n try {\n const buf = Buffer.alloc(24);\n const n = readSync(fd, buf, 0, buf.length, 0);\n const m = VERSION_PREFIX.exec(buf.toString(\"utf8\", 0, n));\n return m === null || Number(m[1]) >= 2;\n } catch {\n return true;\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * Throw `SyncDirForeignError` when ANY file in `dir` is 3.x evidence: a\n * `*.jsonl` (conflict copies included) whose first line is pre-v2, or a\n * `*.manifest` whose `\"v\"` is below 2 (covers an empty segment). Every file is\n * scanned, in name order. A missing or empty dir passes. Only the first line\n * decides: a v1 file that later gained v2 lines is a 3.x file.\n */\nexport function assertSyncDirV2(dir: string): void {\n if (guardOffForTests) return;\n let names: string[];\n try {\n names = readdirSync(dir);\n } catch {\n return;\n }\n for (const name of names.sort()) {\n const path = join(dir, name);\n const foreign = name.endsWith(\".jsonl\")\n ? !startsAsV2OrUnknown(path)\n : name.endsWith(\".manifest\") && manifestIsPreV2(path);\n if (foreign) throw new SyncDirForeignError(dir, name);\n }\n}\n","// mu — segments: how ops LEAVE and ENTER a machine.\n//\n// THE ONE IDEA THAT MAKES THIS WORK\n// ---------------------------------\n// <MU_SYNC_DIR>/<machine_id>.jsonl\n//\n// Each machine APPENDS ONLY to its own segment and read-onlys every\n// other. No file is ever written by two machines, so there is no\n// file-level conflict, ever. That single property is what makes\n// Syncthing, rsync, scp, git, and a USB stick all adequate transport: it\n// removes the one thing every file-mover is bad at. There is nothing to\n// merge, so nothing can merge wrongly.\n//\n// TWO LOGS, ONLY ONE CRITICAL\n// ---------------------------\n// The CANONICAL log is the `ops` table inside mu.db: ACID, WAL,\n// crash-safe, written in the same transaction as the mutation it records.\n// A SEGMENT is DERIVED and REGENERABLE — literally `SELECT ... FROM ops` —\n// so losing one costs a re-flush and nothing else.\n//\n// That asymmetry is what licenses plain append-only files here, and it has\n// one concrete consequence worth stating because it looks like an\n// oversight: NO fsync ON APPEND. Losing the tail to power loss is\n// harmless, because the next flush re-derives it from the table. Paying\n// for durability twice would be paying for nothing.\n//\n// WHY NOT A SQLITE FILE PER PEER\n// ------------------------------\n// Rejected deliberately (design note): a `-wal`/`-shm` sidecar in a synced\n// folder is THE canonical way to corrupt a SQLite DB; a torn transfer is\n// fatal to the WHOLE file rather than costing one JSONL line; and page\n// churn defeats rsync/Syncthing delta transfer, whereas an append-only\n// file is the best case for it.\n//\n// ROBUSTNESS: FOUR LAYERS\n// -----------------------\n// The pattern every append-only log uses (RocksDB, Kafka, etcd,\n// SQLite-WAL): detect the bad record, stop at it, refetch the tail later.\n// Never guess, never skip-and-continue past damage.\n//\n// 1. JSON.parse failure = torn write. FREE, and truncation is the\n// DOMINANT failure mode (a transfer caught in flight).\n// 2. crc32 per line = bit rot that JSON.parse would happily\n// accept. Belt-and-braces, not load-bearing — see the note's\n// honesty about this. ~5 LOC via node:zlib.\n// 3. Monotonic hlc = reordering, duplication, and silent\n// mid-file truncation. Structural, zero extra bytes.\n// 4. Manifest sidecar = whole-file verification (count, last_hlc,\n// sha256). REPORTS, does not halt: it fires when every remaining\n// line is individually valid (a truncation on a line boundary), so\n// the prefix is safe to apply and the fix is a fresh copy.\n//\n// On a bad record (layers 1-3) we stop at the last GOOD one and advance\n// the watermark only that far, then report it. Because `UNIQUE (machine_id, hlc)` makes\n// ingest idempotent, the universal repair is \"re-read from zero\" — so a\n// damaged segment is recoverable, never fatal.\n\nimport { createHash } from \"node:crypto\";\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve, sep } from \"node:path\";\nimport { applyOp, type Op, OpEntityNotSyncedError } from \"./apply.js\";\nimport { compareStrings } from \"./compare.js\";\nimport { type Db, prepareCached, SYNCED_ENTITIES } from \"./db.js\";\nimport { locksDir, withFileLock } from \"./file-lock.js\";\nimport { receiveHlc } from \"./hlc.js\";\nimport {\n decodeLine,\n encodeSegmentLine,\n SEGMENT_FORMAT_VERSION,\n SEGMENT_READ_VERSIONS,\n type SegmentDefect,\n} from \"./segment-line.js\";\nimport {\n manifestPath,\n manifestSelfConsistent,\n readManifest,\n type SegmentManifest,\n writeManifestFile,\n} from \"./segment-manifest.js\";\nimport {\n encodeFingerprint,\n type ResumePoint,\n readAppended,\n resumePoint,\n segmentCaughtUp,\n segmentFingerprint,\n usableShaState,\n} from \"./segment-resume.js\";\nimport { type Sha256State, sha256Digest, sha256Initial, sha256Update } from \"./sha256-resumable.js\";\nimport { assertSyncDirV2 } from \"./sync-dir-guard.js\";\n\nexport {\n type DecodeResult,\n decodeLine,\n encodeSegmentLine,\n SEGMENT_FORMAT_VERSION,\n SEGMENT_READ_VERSIONS,\n type SegmentDefect,\n type SegmentDefectKind,\n type SegmentLine,\n} from \"./segment-line.js\";\n\nexport { manifestSeal, readManifest, type SegmentManifest } from \"./segment-manifest.js\";\nexport { segmentCaughtUp } from \"./segment-resume.js\";\n\n/** Segment filename suffix. */\nconst SEGMENT_EXT = \".jsonl\";\n\n// ─── sync dir + naming ────────────────────────────────────────────────\n\n/**\n * The sync directory, or null when sync is not configured.\n *\n * Null is the normal single-machine case, and every entry point here\n * treats it as \"do nothing, cost nothing\" rather than an error. Sync is\n * opt-in by setting one env var; there is no config file and no\n * membership list (see `discoverPeers`).\n */\nexport function syncDir(): string | null {\n const dir = process.env.MU_SYNC_DIR;\n if (dir === undefined || dir.trim() === \"\") return null;\n refuseUserSyncDirDuringTests(dir);\n return dir;\n}\n\n/**\n * The sibling of `refuseUserDbDuringTests` in src/db.ts, for the OTHER\n * piece of real state a stray test can reach.\n *\n * Pointing MU_DB_PATH at a temp file is not enough to contain a test:\n * sync is ambient, so the first flush stamps the temp DB's fresh\n * `machine_id` onto a segment in whatever MU_SYNC_DIR names. On a dev\n * box that is the user's REAL sync folder, and the result is a\n * permanent phantom peer — `mu sync` lists a machine that never\n * existed, forever, because absence of a segment is the only way a\n * peer disappears and nothing prunes them.\n *\n * Observed: eight such phantoms in ~/mu, each holding one op from a\n * throwaway `workstream init`. They came from the documented\n * smoke-test recipe (`MU_DB_PATH=/tmp/mu-smoke.db mu <verb>`), which\n * overrides the DB and says nothing about the sync dir.\n *\n * So: under a test runner, refuse a sync dir that is not clearly\n * disposable. Tests that exercise sync legitimately already point at a\n * per-test temp dir (mkdtemp under $TMPDIR), which is allowed; the\n * refusal only fires for a path outside it, which is by definition\n * somebody's real folder. Production never sets VITEST, so this is a\n * no-op for the shipped CLI.\n */\nfunction refuseUserSyncDirDuringTests(dir: string): void {\n const inTest = process.env.VITEST !== undefined || process.env.NODE_ENV === \"test\";\n if (!inTest) return;\n const resolved = resolve(dir);\n const temp = resolve(tmpdir());\n if (resolved === temp || resolved.startsWith(temp + sep)) return;\n throw new Error(\n `syncDir refused: tests must NEVER flush ops into a real sync dir (MU_SYNC_DIR=${resolved}). ` +\n `Doing so writes a segment named after this run's machine_id and leaves a permanent phantom peer. ` +\n `Point MU_SYNC_DIR at a mkdtemp() path under ${temp}, or leave it unset (test/_setup.ts clears it by default).`,\n );\n}\n\n/** This machine's id — the identity every op it writes is stamped with. */\nexport function localMachineId(db: Db): string {\n const row = db.prepare(\"SELECT machine_id FROM machine_identity WHERE id = 1\").get() as\n | { machine_id: string }\n | undefined;\n if (row === undefined) throw new Error(\"machine_identity row missing; not a mu DB\");\n return row.machine_id;\n}\n\n/** Path of a machine's own segment inside `dir`. */\nexport function segmentPath(dir: string, machineId: string): string {\n return join(dir, `${machineId}${SEGMENT_EXT}`);\n}\n\n// ─── flush: ops -> my segment ─────────────────────────────────────────\n\nexport interface FlushResult {\n /** Absolute path written, or null when sync is not configured. */\n segmentPath: string | null;\n /** Ops appended by this call. */\n appended: number;\n /** Total lines in the segment afterwards. */\n total: number;\n /** Ops skipped because their entity is machine-local. A full scan\n * (`verify`, or an untrusted manifest) counts every unflushed one; the\n * fast path counts only those up to the last op it appended, so a\n * no-op ambient flush reports 0 (see `pendingLines`). */\n skippedLocal: number;\n /**\n * Non-null when THIS MACHINE'S OWN segment was found defective past\n * its last good line (bit rot, a torn write not at EOF, a bad manual\n * edit). A segment is DERIVED and REGENERABLE from the canonical\n * `ops` table, so the repair is to truncate the file back to its\n * last good record and let the append below regenerate the rest —\n * never to append after the damage, which is the defect that caused\n * unbounded regrowth (each flush re-deriving the same ops from a\n * watermark frozen at the corruption point and stacking them after\n * it, forever). Surfaced here rather than printed directly: this\n * module does no I/O beyond the filesystem, callers decide how loud\n * to be (`mu sync`, `ambientFlush`).\n */\n selfRepaired: SegmentDefect | null;\n /**\n * Non-null when THIS MACHINE'S OWN segment holds a line of a version\n * this build cannot read (first such line, 1-based): written by a newer\n * mu. The segment is then READ-ONLY to this build: flush appends\n * nothing, repairs nothing (`selfRepaired` stays null), and deletes the\n * manifest so the fast path cannot vouch for the file. The pending ops\n * stay in `ops` until mu is upgraded. `foreignVersion` is the version\n * found. Both null otherwise.\n */\n foreignVersionAt: number | null;\n foreignVersion: number | null;\n /**\n * True when ops were pending but another process held the segment\n * lock past the wait, so this call wrote nothing. The ops stay\n * unflushed in `ops` (the segment's last hlc is the watermark), and\n * the next flush appends them. Never set on a successful flush.\n */\n lockBusy?: boolean;\n}\n\n/**\n * Append this machine's not-yet-flushed ops to its own segment.\n *\n * FILTERING IS LOAD-BEARING. Only ops whose entity is in\n * `SYNCED_ENTITIES` are written. Machine-local ops (agent.*)\n * are captured and DO appear in `mu log`, but they must never reach a\n * segment: they carry pane ids and absolute paths that are meaningless,\n * and frequently wrong, on another machine. \"Not synced\" is not \"not\n * logged\".\n *\n * Also filters `machine_id = <me>`: a segment holds ONE machine's ops.\n * Ops ingested from a peer live in our `ops` table too, and re-flushing\n * them into our own segment would duplicate a peer's history under our\n * name — and would grow without bound as two machines echoed each other.\n *\n * The high-water mark is the last hlc already in the file (read from the\n * manifest when present, else derived by scanning), so flush is\n * incremental and idempotent: calling it twice appends nothing the second\n * time.\n */\n/** How long an ambient flush (every verb's post-body hook) waits for\n * the segment lock before deferring its ops to the next invocation.\n * An incremental append holds the lock for milliseconds, so 2 s\n * clears a deep queue of parallel appenders; a holder slower than\n * that is doing a full rescan, and the verb should not wait it out. */\nexport const AMBIENT_FLUSH_LOCK_WAIT_MS = 2_000;\n/** Explicit `mu sync` (verify) waits longer: the operator asked for the\n * flush and a full-scan holder takes seconds on a large segment. */\nexport const VERIFY_FLUSH_LOCK_WAIT_MS = 15_000;\n\nexport async function flushSegment(\n db: Db,\n dir: string | null = syncDir(),\n opts?: { verify?: boolean; lockWaitMs?: number },\n): Promise<FlushResult> {\n if (dir === null)\n return {\n segmentPath: null,\n appended: 0,\n total: 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n\n // A 3.x peer shares the folder: write nothing into it.\n assertSyncDirV2(dir);\n const machineId = localMachineId(db);\n mkdirSync(dir, { recursive: true });\n const path = segmentPath(dir, machineId);\n\n // LOCK-FREE NO-OP. Most verbs write no synced op, and every mu\n // process used to queue on the lock below just to learn that, so N\n // parallel read-only verbs ran their flushes one after another. When\n // our own manifest still describes the file and no op is pending,\n // there is nothing to append and nothing to serialise against: a\n // concurrent appender either finished (we would see its manifest) or\n // has not, and its ops are its own to write.\n // `verify` (explicit `mu sync`) skips both shortcuts and decodes every\n // line, so damage that kept size, mtime and the last line intact\n // (bit rot mid-file) is still found and self-repaired somewhere.\n const verify = opts?.verify === true;\n const pre = verify ? null : trustedTail(path, machineId);\n if (pre !== null) {\n const pending = pendingLines(db, machineId, pre.lastHlc, false);\n if (pending.lines.length === 0) {\n return {\n segmentPath: path,\n appended: 0,\n total: pre.count,\n skippedLocal: pending.skippedLocal,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n }\n }\n\n // Serialise concurrent local flushes so two processes cannot interleave\n // partial lines in the same file. Keyed on the sync dir + machine, since\n // that names the single file being appended to.\n //\n // NEVER UNLOCKED. If the lock is still held at the deadline, write\n // nothing: an unlocked append can splice lines into another writer's,\n // or land after its self-repair truncate, and the ops are safe in the\n // DB anyway. The next invocation's flush appends them. A stale lock\n // (crashed holder) is still broken inside withFileLock.\n const lockName = createHash(\"sha256\")\n .update(`${dir}\\u001f${machineId}`)\n .digest(\"hex\")\n .slice(0, 16);\n return withFileLock(\n join(locksDir(), `segment-${lockName}.lock`),\n `segment:${machineId}`,\n () => Promise.resolve(flushLocked(db, path, machineId, verify)),\n {\n acquireTimeoutMs:\n opts?.lockWaitMs ?? (verify ? VERIFY_FLUSH_LOCK_WAIT_MS : AMBIENT_FLUSH_LOCK_WAIT_MS),\n onUnavailable: () => ({\n segmentPath: path,\n appended: 0,\n total: pre?.count ?? 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n lockBusy: true,\n }),\n },\n );\n}\n\nfunction flushLocked(db: Db, path: string, machineId: string, verify: boolean): FlushResult {\n // Fast path: our own manifest still describes the file (same size and\n // mtime, last line decodes to its lastHlc), so count and high-water\n // mark come from it and nothing before the tail is read.\n const trusted = verify ? null : trustedTail(path, machineId);\n let count: number;\n let since: string | null;\n let selfRepaired: SegmentDefect | null = null;\n if (trusted !== null) {\n count = trusted.count;\n since = trusted.lastHlc;\n } else {\n const existing = readSegmentTail(path);\n count = existing.count;\n since = existing.lastHlc;\n\n // The defect this exists to close: readSegmentTail STOPS at the first\n // bad record either because it hit real damage or because it simply\n // ran out of well-formed lines. Those two cases used to be\n // indistinguishable to this function, and treating \"stopped early on\n // damage\" the same as \"reached clean EOF\" is exactly what let a\n // corrupted line grow the file forever: `since` never advanced past\n // it, so every flush re-selected and re-appended the same ops after\n // it again, unbounded. Distinguish them and heal our own segment\n // (truncate back to the last verified-good line) before appending\n // anything new, rather than stacking fresh data after the wound.\n // A line of a version this build cannot read makes the whole segment\n // READ-ONLY here: append nothing, repair nothing, and delete the\n // manifest so the fast path cannot vouch for the file. The ops stay\n // pending in SQLite until mu is upgraded on this machine.\n if (existing.foreign !== null) {\n rmSync(manifestPath(path), { force: true });\n return {\n segmentPath: path,\n appended: 0,\n total: existing.lineCount,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: existing.foreign.line,\n foreignVersion: existing.foreign.version,\n };\n }\n if (existing.defect !== null) {\n selfRepaired = existing.defect;\n // Truncate back to the last verified-good line; everything after\n // is regenerated from `ops`.\n writeFileSync(\n path,\n existing.goodLines.length > 0 ? `${existing.goodLines.join(\"\\n\")}\\n` : \"\",\n \"utf8\",\n );\n }\n }\n\n const pending = pendingLines(db, machineId, since, trusted === null);\n let appended: Buffer | null = null;\n if (pending.lines.length > 0) {\n // NO fsync. The segment is derived from `ops`; a lost tail costs one\n // re-flush, so paying for durability here would buy nothing.\n appended = Buffer.from(`${pending.lines.join(\"\\n\")}\\n`, \"utf8\");\n appendFileSync(path, appended);\n } else if (!existsSync(path)) {\n // Create the file even with nothing to say, so peers can discover\n // this machine before its first change.\n writeFileSync(path, \"\", \"utf8\");\n }\n\n const total = count + pending.lines.length;\n const result = {\n segmentPath: path,\n appended: pending.lines.length,\n total,\n skippedLocal: pending.skippedLocal,\n selfRepaired,\n foreignVersionAt: null,\n foreignVersion: null,\n };\n // Nothing changed and the manifest already says so: leave it alone,\n // so a read-only verb does not hand the sync tool a file to ship.\n if (trusted !== null && appended === null) return result;\n writeManifest(\n path,\n machineId,\n total,\n pending.lastHlc ?? since,\n trusted !== null && appended !== null\n ? { state: trusted.shaState, size: trusted.size, appended }\n : null,\n );\n return result;\n}\n\nconst SYNCED_ENTITIES_SQL = SYNCED_ENTITIES.map((e) => `'${e}'`).join(\", \");\n\n/**\n * This machine's synced ops newer than `since`, encoded as segment\n * lines, plus how many skipped ops (machine-local)\n * lie in the range this call covered.\n *\n * The entity filter is IN THE SQL, seeking\n * `idx_ops_machine_entity_hlc`, so a run of machine-local ops after the\n * segment's last line (agent.* churn from a long session) is never\n * read: the segment's watermark is the last SYNCED hlc, and filtering\n * in JS rescanned that whole run on every invocation. `INDEXED BY`\n * because without ANALYZE stats the planner prefers the UNIQUE\n * (machine_id, hlc) index and walks the run anyway.\n *\n * `skippedLocal` counts ops up to the last line written by this call.\n * With `countTrailing` (the full-scan path, already O(file)) it also\n * counts skipped ops after it, as before; the fast path does not,\n * because recounting the same trailing run every time is the cost this\n * query exists to avoid.\n */\nfunction pendingLines(\n db: Db,\n machineId: string,\n since: string | null,\n countTrailing: boolean,\n): { lines: string[]; lastHlc: string | null; skippedLocal: number } {\n // \"\" sorts before every hlc, so it stands for \"from the start\" and\n // keeps the range a plain index seek (an `IS NULL OR` defeats it).\n const from = since ?? \"\";\n const rows = prepareCached(\n db,\n `SELECT hlc, machine_id, group_id, intent, actor, entity, key, op, payload\n FROM ops INDEXED BY idx_ops_machine_entity_hlc\n WHERE machine_id = @machineId\n AND entity IN (${SYNCED_ENTITIES_SQL})\n AND hlc > @from\n ORDER BY hlc`,\n ).all({ machineId, from }) as Array<{\n hlc: string;\n machine_id: string;\n group_id: string;\n intent: string | null;\n actor: string | null;\n entity: string;\n key: string;\n op: string;\n payload: string;\n }>;\n\n const lines: string[] = [];\n let lastHlc: string | null = null;\n\n for (const row of rows) {\n lines.push(\n encodeSegmentLine({\n hlc: row.hlc,\n machineId: row.machine_id,\n groupId: row.group_id,\n intent: row.intent,\n actor: row.actor,\n entity: row.entity,\n key: row.key,\n op: row.op === \"del\" ? \"del\" : \"put\",\n payload: row.payload,\n }),\n );\n lastHlc = row.hlc;\n }\n // Everything in the covered range that did not become a line. A\n // range count on the UNIQUE (machine_id, hlc) index: proportional to\n // the range, never to what trails it on the fast path.\n let row: { n: number };\n if (countTrailing) {\n row = prepareCached(\n db,\n \"SELECT COUNT(*) AS n FROM ops WHERE machine_id = @machineId AND hlc > @from\",\n ).get({ machineId, from }) as { n: number };\n } else if (lastHlc !== null) {\n row = prepareCached(\n db,\n `SELECT COUNT(*) AS n FROM ops\n WHERE machine_id = @machineId AND hlc > @from AND hlc <= @upTo`,\n ).get({ machineId, from, upTo: lastHlc }) as { n: number };\n } else {\n return { lines, lastHlc, skippedLocal: 0 };\n }\n return { lines, lastHlc, skippedLocal: row.n - lines.length };\n}\n\n/**\n * Count, last hlc, size and running hash of OUR OWN segment, taken from\n * its manifest, or null when the manifest cannot be trusted and the\n * caller must scan the file.\n *\n * Trusted only when the manifest is ours, carries the fields this build\n * writes and they agree with each other (`manifestSelfConsistent`:\n * format, hash state finishing to `sha256`, seal), matches the file's\n * current size AND mtime (any rewrite, hand\n * edit or truncation changes one of them), and the file's last line ends\n * in a newline and decodes cleanly to the manifest's lastHlc. That last\n * check reads only the final line, so a torn or corrupt tail still falls\n * through to the full scan and its self-repair. Cost: one stat plus one\n * line, independent of file size.\n */\nfunction trustedTail(\n path: string,\n machineId: string,\n): { count: number; lastHlc: string | null; size: number; shaState: Sha256State } | null {\n const m = readManifest(path);\n if (m === null || !SEGMENT_READ_VERSIONS.includes(m.v) || m.machine !== machineId) return null;\n if (!manifestSelfConsistent(m)) return null;\n const { count, lastHlc, size, mtimeMs, shaState } = m;\n let stat: ReturnType<typeof statSync>;\n try {\n stat = statSync(path);\n } catch {\n return null;\n }\n if (stat.size !== size || stat.mtimeMs !== mtimeMs) return null;\n if (count === 0) return lastHlc === null ? { count, lastHlc, size, shaState } : null;\n const last = readLastLine(path, size);\n if (last === null) return null;\n const decoded = decodeLine(last);\n if (!decoded.ok || decoded.line.hlc !== lastHlc) return null;\n return { count, lastHlc, size, shaState };\n}\n\n/** The last newline-terminated line of the first `size` bytes of\n * `path`, without its newline; null when those bytes do not end in a\n * newline (a torn write). Reads backwards in chunks, so a long line\n * costs its own length and the file's size costs nothing. */\nfunction readLastLine(path: string, size: number): string | null {\n if (size === 0) return null;\n const fd = openSync(path, \"r\");\n try {\n const last = Buffer.alloc(1);\n readSync(fd, last, 0, 1, size - 1);\n if (last[0] !== 0x0a) return null;\n const chunks: Buffer[] = [];\n let end = size - 1;\n while (end > 0) {\n const start = Math.max(0, end - 64 * 1024);\n const buf = Buffer.alloc(end - start);\n readSync(fd, buf, 0, buf.length, start);\n const nl = buf.lastIndexOf(0x0a);\n if (nl >= 0) {\n chunks.unshift(buf.subarray(nl + 1));\n break;\n }\n chunks.unshift(buf);\n end = start;\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n } finally {\n closeSync(fd);\n }\n}\n\n/** The first line of a version this build cannot read in this machine's\n * own segment, or null. For `mu doctor`; reads the whole file. */\nexport function ownSegmentForeignLine(\n db: Db,\n dir: string | null = syncDir(),\n): { path: string; line: number; version: number } | null {\n if (dir === null) return null;\n const path = segmentPath(dir, localMachineId(db));\n const found = readSegmentTail(path).foreign;\n return found === null ? null : { path, ...found };\n}\n\n/** Own synced ops newer than the last op in this machine's segment: what\n * a flush would append now. Read-only, so `mu doctor` can report a\n * backlog (a flush that lost the lock race leaves one). */\nexport function countUnpublishedOps(db: Db, dir: string): number {\n const machineId = localMachineId(db);\n const { lastHlc } = readSegmentTail(segmentPath(dir, machineId));\n const row = prepareCached(\n db,\n `SELECT COUNT(*) AS n FROM ops INDEXED BY idx_ops_machine_entity_hlc\n WHERE machine_id = @machineId AND entity IN (${SYNCED_ENTITIES_SQL}) AND hlc > @from`,\n ).get({ machineId, from: lastHlc ?? \"\" }) as { n: number };\n return row.n;\n}\n\n/** Number of GOOD lines in a segment (stopping at the first defect, as\n * ingest does). The denominator of \"how far behind am I\" — exported for\n * `mu sync`'s peer table. */\nexport function segmentLineCount(path: string): number {\n return readSegmentTail(path).count;\n}\n\n/**\n * Count + last hlc of an existing segment, cheaply, plus (this is the\n * part that matters) WHY it stopped: `defect` is null when every line\n * decoded cleanly (a genuine, trustworthy EOF), and set when decoding\n * stopped early because a line was bad. Conflating those two used to be\n * the whole bug: a stop-on-damage looked exactly like a stop-on-EOF to\n * `flushLocked`, so it kept appending after the damage forever.\n * `goodLines` is the verified-good prefix, raw, so a caller that finds a\n * defect can truncate back to it byte-for-byte rather than re-encoding.\n */\nfunction readSegmentTail(path: string): {\n count: number;\n lastHlc: string | null;\n goodLines: readonly string[];\n defect: SegmentDefect | null;\n /** First line of a version this build cannot read ANYWHERE in the\n * file (1-based), even past a defect; null when there is none. */\n foreign: { line: number; version: number } | null;\n lineCount: number;\n} {\n if (!existsSync(path))\n return { count: 0, lastHlc: null, goodLines: [], defect: null, foreign: null, lineCount: 0 };\n const lines = segmentLines(readFileSync(path, \"utf8\"));\n let lastHlc: string | null = null;\n let count = 0;\n let defect: SegmentDefect | null = null;\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index];\n if (line === undefined) break;\n // Same rule as `ingestSegment`: a blank line is damage. Skipping it\n // here while peers halt on it left the owner blind to the defect,\n // so it never self-repaired and every peer stopped there forever.\n if (line.trim() === \"\") {\n defect = { kind: \"malformed-shape\", line: index + 1, detail: \"blank line\" };\n break;\n }\n const decoded = decodeLine(line);\n if (!decoded.ok) {\n defect = {\n kind: decoded.kind,\n line: index + 1,\n detail: decoded.detail,\n ...(decoded.version === undefined ? {} : { version: decoded.version }),\n };\n break;\n }\n lastHlc = decoded.line.hlc;\n count += 1;\n }\n // The scan above stops at the first defect; a foreign line behind it\n // still makes the segment read-only, so look at the rest.\n let foreign: { line: number; version: number } | null = null;\n if (defect?.kind === \"unknown-version\" && defect.version !== undefined) {\n foreign = { line: defect.line, version: defect.version };\n } else if (defect !== null) {\n for (let i = count + 1; i < lines.length && foreign === null; i++) {\n const later = decodeLine(lines[i] ?? \"\");\n if (!later.ok && later.kind === \"unknown-version\" && later.version !== undefined)\n foreign = { line: i + 1, version: later.version };\n }\n }\n return {\n count,\n lastHlc,\n goodLines: lines.slice(0, count),\n defect,\n foreign,\n lineCount: lines.length,\n };\n}\n\n/** Split a segment into its lines exactly as every reader must: a\n * trailing newline is normal, a trailing PARTIAL line is a torn write\n * (kept so layer 1 can catch it), and a blank line stays in place so\n * the caller reports it as damage. One splitter, so the owner's\n * self-check and a peer's ingest cannot disagree about line numbers. */\nfunction segmentLines(raw: string): string[] {\n const lines = raw.split(\"\\n\");\n if (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n return lines;\n}\n\n/**\n * LAYER 4: whole-file verification sidecar.\n *\n * `incremental` carries the running hash of the bytes the manifest last\n * covered, so an append hashes only what it added. Without it (first\n * flush, a repair, a manifest from an older build, or a file that grew\n * by more than we appended) the whole file is hashed once.\n */\nfunction writeManifest(\n path: string,\n machine: string,\n count: number,\n lastHlc: string | null,\n incremental: { state: Sha256State; size: number; appended: Buffer } | null,\n): void {\n let stat = statSync(path);\n let shaState: Sha256State;\n if (incremental !== null && stat.size === incremental.size + incremental.appended.length) {\n shaState = sha256Update(incremental.state, incremental.appended);\n } else {\n const bytes = readFileSync(path);\n shaState = sha256Update(sha256Initial(), bytes);\n stat = statSync(path);\n }\n writeManifestFile(path, {\n v: SEGMENT_FORMAT_VERSION,\n machine,\n count,\n lastHlc,\n sha256: sha256Digest(shaState),\n size: shaState.n,\n mtimeMs: stat.mtimeMs,\n shaState,\n });\n}\n\n/**\n * Verify a segment against its manifest (layer 4).\n *\n * Whole-file, so it catches damage the per-line layers cannot see: a\n * segment silently replaced wholesale, or truncated exactly on a line\n * boundary (where every remaining line is individually valid).\n */\nexport function verifyAgainstManifest(\n segment: string,\n): { ok: true } | { ok: false; reason: string } {\n const manifest = readManifest(segment);\n if (manifest === null) return { ok: true }; // no manifest: nothing to check\n if (!existsSync(segment)) return { ok: false, reason: \"segment missing but manifest present\" };\n return checkBytesAgainstManifest(segment, manifest, readFileSync(segment));\n}\n\n/** `verifyAgainstManifest` over bytes the caller already read, so ingest\n * reads the segment once. `exact` is true when the bytes hash to the\n * manifest's sha256 (the manifest covers exactly this file). */\nfunction checkBytesAgainstManifest(\n segment: string,\n manifest: SegmentManifest,\n bytes: Buffer,\n): { ok: true; exact: boolean } | { ok: false; reason: string } {\n const sha = createHash(\"sha256\").update(bytes).digest(\"hex\");\n if (sha === manifest.sha256) return { ok: true, exact: true };\n // A GROWN file is expected: the peer appended after writing the\n // manifest we have, or our copy is mid-transfer. That is not damage.\n const tail = readSegmentTail(segment);\n if (tail.count >= manifest.count) {\n return { ok: true, exact: false };\n }\n return {\n ok: false,\n reason: `sha mismatch and file has FEWER records than the manifest (${tail.count} < ${manifest.count}): truncated`,\n };\n}\n\n// ─── peer discovery ───────────────────────────────────────────────────\n\nexport interface PeerSegment {\n /** Machine id the segment belongs to. */\n machineId: string;\n /** Key of this FILE's watermark in `sync_peers`: the machine id for\n * the peer's own segment, the full file stem for a conflict copy.\n * A copy diverges from its original, so line N of one says nothing\n * about line N of the other; sharing one watermark skipped every op\n * that existed only in the copy. Optional for SDK callers written\n * before it existed: absent means the machine id (`peerWatermarkKey`). */\n watermarkKey?: string;\n /** Path on disk. */\n path: string;\n /** True for a Syncthing-style conflict copy. */\n conflictCopy: boolean;\n}\n\n/**\n * Every segment in `dir` that is not mine.\n *\n * IMPLICIT, with no membership list. `MU_SYNC_PEERS` was explicitly\n * rejected as \"a config file with extra steps that must be kept\n * consistent across every machine\" — dropping a segment in the folder\n * joins the cluster, deleting it leaves.\n *\n * CONFLICT COPIES ARE INGESTED, not ignored. Syncthing names them\n * `<machine>.sync-conflict-20260609-123456-ABCDEFG.jsonl`; they are still\n * valid op logs, and dedup by `(machine_id, hlc)` makes reading them\n * safe. Ignoring them would silently drop real ops precisely when\n * something already went wrong.\n */\nexport function discoverPeers(dir: string, selfMachineId: string): PeerSegment[] {\n if (!existsSync(dir)) return [];\n assertSyncDirV2(dir); // a 3.x peer shares the folder: read nothing from it\n const peers: PeerSegment[] = [];\n for (const name of readdirSync(dir)) {\n if (!name.endsWith(SEGMENT_EXT)) continue;\n const stem = name.slice(0, -SEGMENT_EXT.length);\n // Syncthing: \"<machine>.sync-conflict-<date>-<time>-<id>\"\n const conflictAt = stem.indexOf(\".sync-conflict-\");\n const conflictCopy = conflictAt > 0;\n const machineId = conflictCopy ? stem.slice(0, conflictAt) : stem;\n if (machineId === selfMachineId && !conflictCopy) continue;\n // A conflict copy OF MY OWN segment is still a peer's view of my\n // history; ingesting it is a no-op thanks to (machine_id, hlc)\n // dedupe, so allow it rather than special-casing.\n const path = join(dir, name);\n try {\n if (!statSync(path).isFile()) continue;\n } catch {\n continue;\n }\n peers.push({ machineId, watermarkKey: conflictCopy ? stem : machineId, path, conflictCopy });\n }\n return peers.sort((a, b) => compareStrings(a.path, b.path));\n}\n\n/** The `sync_peers` key for a segment file: `watermarkKey`, else the\n * machine id (the pre-watermarkKey `PeerSegment` shape). */\nexport function peerWatermarkKey(peer: PeerSegment): string {\n return peer.watermarkKey ?? peer.machineId;\n}\n\n// ─── watermarks ───────────────────────────────────────────────────────\n\n/**\n * How far into one segment file we have applied, keyed by\n * `PeerSegment.watermarkKey` (the machine id, or a conflict copy's own\n * stem).\n *\n * ONE INTEGER SUFFICES because segments are append-only and ordered — a\n * set or a vector clock would be strictly more state for no more\n * information. Stored in `sync_peers.last_applied_seq`, which has been in\n * the v9 schema unused until now.\n *\n * The integer is a LINE COUNT within that peer's segment, not the peer's\n * `ops.seq` (which is a local-only cursor on their machine and means\n * nothing here).\n */\nexport function getWatermark(db: Db, watermarkKey: string): number {\n const row = db\n .prepare(\"SELECT last_applied_seq AS n FROM sync_peers WHERE machine_id = ?\")\n .get(watermarkKey) as { n: number } | undefined;\n return row?.n ?? 0;\n}\n\n/**\n * Store a watermark and stamp `last_seen_at` with the ISO time. The\n * segment fingerprint goes to `sync_fingerprints` when the caller just\n * read the file cleanly to its end (`segmentCaughtUp`). Every other\n * write deletes it, so a reset or partial ingest never vouches for the\n * file.\n */\nexport function setWatermark(\n db: Db,\n watermarkKey: string,\n value: number,\n fingerprint?: string | null,\n): void {\n const now = new Date().toISOString();\n prepareCached(\n db,\n `INSERT INTO sync_peers (machine_id, last_applied_seq, last_seen_at)\n VALUES (@machineId, @value, @seenAt)\n ON CONFLICT (machine_id) DO UPDATE\n SET last_applied_seq = @value, last_seen_at = @seenAt`,\n ).run({ machineId: watermarkKey, value, seenAt: now });\n if (fingerprint == null) {\n prepareCached(db, \"DELETE FROM sync_fingerprints WHERE machine_id = ?\").run(watermarkKey);\n } else {\n prepareCached(\n db,\n `INSERT INTO sync_fingerprints (machine_id, fingerprint) VALUES (?, ?)\n ON CONFLICT (machine_id) DO UPDATE SET fingerprint = excluded.fingerprint`,\n ).run(watermarkKey, fingerprint);\n }\n}\n\n/** Reset a peer's watermark so the next ingest re-reads from zero. The\n * universal repair, safe because ingest is idempotent. */\nexport function resetWatermark(db: Db, watermarkKey: string): void {\n setWatermark(db, watermarkKey, 0);\n}\n\n// ─── ingest: peer segment -> applyOp ──────────────────────────────────\n\nexport interface IngestResult {\n machineId: string;\n path: string;\n /** Lines consumed past the starting watermark: applied plus skipped\n * (refused, re-delivered) lines. A line that\n * halted ingest is not counted. */\n read: number;\n /** Ops applied (some are no-ops: already present, or lost an LWW). */\n applied: number;\n /** Ops that changed a row. */\n changed: number;\n /** Watermark after this ingest. */\n watermark: number;\n /** Problems found, in line order. Reported, never swallowed. */\n defects: readonly SegmentDefect[];\n /** True iff a defect stopped us short of the file's end. */\n truncatedAt: number | null;\n}\n\n/**\n * Read one peer segment from its watermark and apply each op.\n *\n * STOPS AT THE FIRST DAMAGED RECORD and advances the watermark only that\n * far. Never skips a damaged line to continue past it: in an ordered log,\n * a gap is indistinguishable from reordering, and applying ops around a\n * hole risks a state neither machine ever had. The tail is re-read on the\n * next ingest, by which time the transfer has usually completed.\n *\n * A REFUSED line is not a damaged one. A well-formed op naming an entity\n * that must not travel (`entity-not-synced`) is reported as a defect and\n * SKIPPED: it projects nothing, so it leaves no hole, and halting on it\n * makes the watermark unrecoverable by any means the CLI offers.\n *\n * A RE-DELIVERED line is not a damaged one either. A block of ops the\n * peer already wrote, appended verbatim a second time, breaks the hlc\n * ordering (`duplicate-op`) without losing anything: every one of those\n * ops is already in our `ops` table byte-for-byte, so applying them\n * again is a no-op by construction. Halting there is unrecoverable —\n * `--repair` re-reads from zero straight back into the same three\n * lines, forever — so it is reported and SKIPPED. A non-monotonic line\n * we have NOT seen before is still real damage and still halts.\n *\n * A manifest mismatch (layer 4) is reported but does not halt: every\n * line still present is individually valid, so applying them is safe.\n *\n * Calls `receiveHlc` per op so the local clock advances past the peer's,\n * which is what makes \"laptop edits after seeing the devserver's op\" order\n * correctly rather than losing to it.\n */\nexport function ingestSegment(\n db: Db,\n peer: PeerSegment,\n opts?: { verify?: boolean },\n): IngestResult {\n assertSyncDirV2(dirname(peer.path)); // v1 is never ingested, whoever built the peer\n const defects: SegmentDefect[] = [];\n const watermarkKey = peerWatermarkKey(peer);\n const start = getWatermark(db, watermarkKey);\n\n // CAUGHT UP: the file and its manifest are byte-for-byte what the last\n // clean full read saw (size, exact mtime, manifest hash), and the\n // manifest counts the lines we consumed. Nothing to apply, so do not\n // read, hash or split the file. `verify` (explicit `mu sync`) skips\n // this and checks the whole file, so damage that kept size and mtime\n // is still reported somewhere.\n const nothing: IngestResult = {\n machineId: peer.machineId,\n path: peer.path,\n read: 0,\n applied: 0,\n changed: 0,\n watermark: start,\n defects,\n truncatedAt: null,\n };\n if (opts?.verify !== true && segmentCaughtUp(db, watermarkKey, peer.path, start)) return nothing;\n if (!existsSync(peer.path)) return nothing;\n\n const fingerprint = segmentFingerprint(peer.path);\n\n // RESUME: the last clean read recorded where it stopped and the running\n // hash there. When the file is that prefix plus appended bytes whose\n // hash is the manifest's, only the appended bytes are read and split.\n // Anything else (shrunk, stale manifest, no resume point, explicit\n // `verify`) takes the full read and whole-file verify below.\n const resume =\n opts?.verify !== true && fingerprint?.manifest != null && start > 0\n ? resumePoint(db, watermarkKey, start)\n : null;\n const appended =\n resume !== null && fingerprint?.manifest != null\n ? readAppended(peer.path, resume, fingerprint.manifest.sha256)\n : null;\n\n let lines: string[];\n let base: number; // lines before `lines[0]` in the file\n let seedHlc: string | null = null;\n let nextResume: ResumePoint | null = null; // set only after a clean read, below\n let resumeState: Sha256State | null = null;\n let resumeSize = 0;\n if (resume !== null && appended !== null) {\n lines = segmentLines(appended.bytes.toString(\"utf8\"));\n base = resume.lines;\n seedHlc = resume.lastHlc;\n resumeState = appended.bytes[appended.bytes.length - 1] === 0x0a ? appended.state : null;\n resumeSize = appended.state.n;\n } else {\n const manifest = readManifest(peer.path);\n const bytes = readFileSync(peer.path);\n if (manifest !== null) {\n const verified = checkBytesAgainstManifest(peer.path, manifest, bytes);\n if (!verified.ok) {\n // Whole-file damage, distinct from a torn line: every remaining\n // record may be individually valid (truncation exactly on a line\n // boundary), which is precisely what the per-line layers cannot\n // see. Reported, NOT a halt: the lines that remain are a valid\n // prefix, so the per-line layers below still decide how far to\n // apply.\n defects.push({ kind: \"manifest-mismatch\", line: 0, detail: verified.reason });\n } else if (verified.exact) {\n // The owner's manifest carries the running hash after exactly\n // these bytes: reuse it instead of hashing the file in JS.\n const state = usableShaState(manifest.shaState, bytes.length);\n if (\n state !== null &&\n bytes[bytes.length - 1] === 0x0a &&\n sha256Digest(state) === manifest.sha256\n ) {\n resumeState = state;\n resumeSize = bytes.length;\n }\n }\n }\n lines = segmentLines(bytes.toString(\"utf8\"));\n base = 0;\n // Seed the monotonicity check from the last line we already accepted,\n // so a segment rewritten out of order is caught even mid-file.\n if (start > 0 && start <= lines.length) {\n const prior = lines[start - 1];\n if (prior !== undefined) {\n const decoded = decodeLine(prior);\n if (decoded.ok) seedHlc = decoded.line.hlc;\n }\n }\n }\n const total = base + lines.length;\n\n let applied = 0;\n let changed = 0;\n let watermark = start;\n let truncatedAt: number | null = null;\n let previousHlc: string | null = seedHlc;\n\n const run = db.transaction(() => {\n for (let index = start - base; index < lines.length; index++) {\n const raw = lines[index];\n const lineNo = base + index + 1;\n if (raw === undefined || raw.trim() === \"\") {\n // Blank line: treat as damage rather than skipping, since a\n // well-formed segment never contains one.\n defects.push({ kind: \"malformed-shape\", line: lineNo, detail: \"blank line\" });\n truncatedAt = lineNo;\n break;\n }\n\n const decoded = decodeLine(raw);\n if (!decoded.ok) {\n defects.push({\n kind: decoded.kind,\n line: lineNo,\n detail: decoded.detail,\n ...(decoded.version === undefined ? {} : { version: decoded.version }),\n });\n truncatedAt = lineNo;\n break;\n }\n\n const op: Op = {\n hlc: decoded.line.hlc,\n machineId: decoded.line.machine,\n groupId: decoded.line.group,\n actor: decoded.line.actor,\n intent: decoded.line.intent,\n entity: decoded.line.entity,\n key: decoded.line.key,\n op: decoded.line.op,\n payload: decoded.payloadText,\n };\n\n // LAYER 3: monotonic hlc. Structural, zero extra bytes. Catches\n // reordering, duplication, and silent mid-file truncation.\n if (previousHlc !== null && decoded.line.hlc <= previousHlc) {\n // ... unless we have this exact op already, in which case the\n // peer re-appended a block it had already written and there is\n // nothing to reorder: an identical op carries identical state,\n // so skipping it cannot produce a state neither machine had.\n if (isAlreadyRecorded(db, op)) {\n defects.push({\n kind: \"duplicate-op\",\n line: lineNo,\n detail: `hlc ${decoded.line.hlc} re-delivered — skipped`,\n });\n watermark = lineNo;\n continue;\n }\n defects.push({\n kind: \"non-monotonic-hlc\",\n line: lineNo,\n detail: `hlc ${decoded.line.hlc} <= previous ${previousHlc}`,\n });\n truncatedAt = lineNo;\n break;\n }\n\n try {\n const result = applyIncomingOp(db, op);\n if (result.changed) changed += 1;\n } catch (err) {\n if (err instanceof OpEntityNotSyncedError) {\n // A peer sent something that must never cross a machine\n // boundary (a pane id, an absolute path). Report it as a\n // bad-peer defect — and SKIP THE LINE rather than stopping.\n //\n // Stopping is right for DAMAGE, where a gap is\n // indistinguishable from reordering. This line is not\n // damaged: it decoded, its crc verified, and its hlc is in\n // order. Refusing it projects nothing, so there is no hole to\n // reason about, and continuing is strictly safer than the\n // alternative we actually shipped — one such line at position\n // 2533 of a 20,305-line segment froze that peer's watermark\n // permanently, and `mu sync --repair` re-read straight back\n // into the same wall. A defect is reported; nothing is lost;\n // the remaining 17,772 ops arrive.\n defects.push({\n kind: \"entity-not-synced\",\n line: lineNo,\n detail: `peer sent machine-local entity '${op.entity}' — skipped`,\n });\n previousHlc = op.hlc;\n watermark = lineNo;\n continue;\n }\n throw err;\n }\n\n applied += 1;\n previousHlc = op.hlc;\n watermark = lineNo;\n }\n // Vouch for the file only after a clean read to its end, so a file\n // with a defect is read (and reported) again on every pass.\n const clean = defects.length === 0 && watermark === total;\n if (clean && resumeState !== null && previousHlc !== null) {\n nextResume = { lines: total, size: resumeSize, lastHlc: previousHlc, state: resumeState };\n }\n setWatermark(\n db,\n watermarkKey,\n watermark,\n clean && fingerprint !== null ? encodeFingerprint(fingerprint.key, nextResume) : null,\n );\n });\n run.immediate();\n\n return {\n machineId: peer.machineId,\n path: peer.path,\n read: watermark - start,\n applied,\n changed,\n watermark,\n defects,\n truncatedAt,\n };\n}\n\n/**\n * Is this exact op already in our `ops` table?\n *\n * `UNIQUE (machine_id, hlc)` is the op's identity everywhere else in\n * the system — it is what makes `applyIncomingOp` idempotent and\n * \"re-read from zero\" a safe universal repair — so it is the identity\n * used here too. Entity and key are matched as well so a hlc collision\n * between genuinely different ops (which the UNIQUE constraint would\n * itself refuse) can never be mistaken for a re-delivery.\n */\nfunction isAlreadyRecorded(db: Db, op: Op): boolean {\n const row = prepareCached(\n db,\n `SELECT 1 FROM ops\n WHERE machine_id = @machineId AND hlc = @hlc\n AND entity = @entity AND key = @key AND op = @op\n LIMIT 1`,\n ).get({\n machineId: op.machineId,\n hlc: op.hlc,\n entity: op.entity,\n key: op.key,\n op: op.op,\n });\n return row !== undefined;\n}\n\n/**\n * Apply ONE incoming op and record it in the local `ops` table.\n *\n * The shared tail of every ingest path — segment ingest above, and the\n * `mu sync --from <peer.db>` reader in `src/sync.ts`, which is a\n * different READER over the same apply semantics. Extracted so the two\n * cannot drift: a second copy of \"advance the clock, apply, record\" is\n * how one of them silently stops advancing the clock.\n *\n * Three steps, in this order:\n * 1. `receiveHlc` BEFORE applying, so anything we mint afterwards\n * sorts above the peer's op.\n * 2. `applyOp`, which is capture-suppressed (no echo op is minted).\n * 3. Record the op locally so it survives, participates in\n * provenance, and can be re-flushed by rebuild. INSERT OR IGNORE\n * makes this idempotent via UNIQUE (machine_id, hlc) — the\n * property that lets \"re-read from zero\" be the universal repair.\n */\nexport function applyIncomingOp(db: Db, op: Op): { changed: boolean } {\n receiveHlc(db, op.hlc);\n const result = applyOp(db, op);\n prepareCached(\n db,\n `INSERT OR IGNORE INTO ops\n (hlc, machine_id, group_id, actor, intent, entity, key, op, payload, created_at)\n VALUES (@hlc, @machineId, @groupId, @actor, @intent, @entity, @key, @op, @payload, @createdAt)`,\n ).run({\n hlc: op.hlc,\n machineId: op.machineId,\n groupId: op.groupId,\n actor: op.actor ?? null,\n intent: op.intent ?? null,\n entity: op.entity,\n key: op.key,\n op: op.op,\n payload: op.payload,\n createdAt: new Date().toISOString(),\n });\n return { changed: result.changed };\n}\n\n// ─── the two halves, together ─────────────────────────────────────────\n\nexport interface SyncPassResult {\n flushed: FlushResult;\n ingested: readonly IngestResult[];\n /** True iff any peer reported a defect. */\n defective: boolean;\n}\n\n/**\n * One flush + one ingest of every discovered peer.\n *\n * The SDK seam `mu sync` calls (src/cli/sync.ts); it deliberately\n * prints nothing and starts nothing. No daemon, no watcher, no polling\n * loop that outlives the command — the anti-feature pledges are firm, and\n * mu never moves files itself: the operator owns transport.\n *\n * A no-op costing nothing when `MU_SYNC_DIR` is unset, which is the\n * normal single-machine case.\n */\nexport async function syncPass(db: Db, dir: string | null = syncDir()): Promise<SyncPassResult> {\n if (dir === null) {\n return {\n flushed: {\n segmentPath: null,\n appended: 0,\n total: 0,\n skippedLocal: 0,\n selfRepaired: null,\n foreignVersionAt: null,\n foreignVersion: null,\n },\n ingested: [],\n defective: false,\n };\n }\n const flushed = await flushSegment(db, dir, { verify: true });\n const self = localMachineId(db);\n const ingested = discoverPeers(dir, self).map((peer) =>\n ingestSegment(db, peer, { verify: true }),\n );\n return {\n flushed,\n ingested,\n defective:\n flushed.selfRepaired !== null ||\n flushed.foreignVersionAt !== null ||\n ingested.some((r) => r.defects.length > 0),\n };\n}\n","// mu — resume a peer segment ingest from a byte offset.\n//\n// A clean ingest of a peer's segment records, next to its caught-up\n// fingerprint (`sync_fingerprints`), where it stopped: lines consumed,\n// bytes consumed, the last hlc, and the running sha256 state over those\n// bytes. When the peer appends, the next ambient ingest reads only the\n// new bytes, hashes them from the saved state, and accepts them only\n// when the result is the sha256 in the peer's manifest. That equals a\n// whole-file check only while the prefix is what the first read saw: a\n// local change to those bytes that keeps the file growing is not seen\n// here, only by an explicit `mu sync` (`verify`). The full read and verify\n// also runs for a shrunk file, a stale manifest, and after a defect (a\n// defect never records a resume point). Split out of\n// segments.ts (1500-LOC cap).\n\nimport { createHash } from \"node:crypto\";\nimport { closeSync, fstatSync, openSync, readFileSync, readSync, statSync } from \"node:fs\";\nimport { type Db, prepareCached } from \"./db.js\";\nimport { manifestPath, type SegmentManifest } from \"./segment-manifest.js\";\nimport { type Sha256State, sha256Digest, sha256Update } from \"./sha256-resumable.js\";\n\n/** A peer manifest's optional `shaState`, usable only when it is\n * well-formed and covers exactly `length` bytes. The manifest is peer\n * input: anything off (null, wrong types, bad hex, a tail that is not\n * `length % 64` bytes of canonical base64, `n` out of range) yields\n * null and the caller hashes the bytes itself. */\nexport function usableShaState(state: unknown, length: number): Sha256State | null {\n if (typeof state !== \"object\" || state === null) return null;\n const { h, n, tail } = state as Record<string, unknown>;\n if (typeof h !== \"string\" || !/^[0-9a-f]{64}$/.test(h)) return null;\n if (typeof n !== \"number\" || !Number.isSafeInteger(n) || n < 0 || n !== length) return null;\n if (typeof tail !== \"string\") return null;\n const raw = Buffer.from(tail, \"base64\");\n if (raw.length !== n % 64 || raw.toString(\"base64\") !== tail) return null;\n return { h, n, tail };\n}\n\n/** Where a clean ingest stopped, and what it hashed to get there. */\nexport interface ResumePoint {\n /** Lines consumed; always the watermark it was recorded with. */\n lines: number;\n /** Bytes consumed; the last one is a newline. */\n size: number;\n /** Hlc of the last line consumed (the monotonicity seed). */\n lastHlc: string;\n /** Running sha256 over those `size` bytes. */\n state: Sha256State;\n}\n\n/** The `sync_fingerprints` value: the caught-up key, optionally followed\n * by tab-separated resume fields. An older mu compares the whole string,\n * so it never matches and just reads in full. */\nexport function encodeFingerprint(key: string, resume: ResumePoint | null): string {\n if (resume === null) return key;\n const { lines, size, lastHlc, state } = resume;\n return [key, lines, size, lastHlc, state.h, state.tail].join(\"\\t\");\n}\n\n/** Split a stored fingerprint into its caught-up key and resume point\n * (null when absent or malformed). */\nexport function decodeFingerprint(raw: string): { key: string; resume: ResumePoint | null } {\n const [key = \"\", lines, size, lastHlc, h, tail] = raw.split(\"\\t\");\n if (h === undefined || tail === undefined || lines === undefined || size === undefined) {\n return { key, resume: null };\n }\n const n = Number(size);\n const count = Number(lines);\n if (!Number.isSafeInteger(n) || n <= 0 || !Number.isSafeInteger(count) || count <= 0) {\n return { key, resume: null };\n }\n if (!lastHlc || !/^[0-9a-f]{64}$/.test(h)) return { key, resume: null };\n return { key, resume: { lines: count, size: n, lastHlc, state: { h, n, tail } } };\n}\n\n/**\n * The bytes of `path` past `resume.size`, with the running hash after\n * them, or null when the file cannot be resumed: it is not longer than\n * the recorded size, or the hash does not equal `manifestSha` (the\n * manifest is stale, or the prefix is not what we hashed).\n */\nexport function readAppended(\n path: string,\n resume: ResumePoint,\n manifestSha: string,\n): { bytes: Buffer; state: Sha256State } | null {\n let fd: number;\n try {\n fd = openSync(path, \"r\");\n } catch {\n return null;\n }\n try {\n const size = fstatSync(fd).size;\n if (size <= resume.size) return null;\n const bytes = Buffer.alloc(size - resume.size);\n for (let got = 0; got < bytes.length; ) {\n const n = readSync(fd, bytes, got, bytes.length - got, resume.size + got);\n if (n === 0) return null;\n got += n;\n }\n const state = sha256Update(resume.state, bytes);\n return sha256Digest(state) === manifestSha ? { bytes, state } : null;\n } finally {\n closeSync(fd);\n }\n}\n\n/**\n * What a full, clean ingest saw of a peer's segment: its size, its\n * exact mtime, and the sha256 of its manifest's bytes, plus the count\n * that manifest claims. Null when the segment or its manifest cannot be\n * read. Taken BEFORE the read, so a file that changes mid-read no longer\n * matches next time.\n */\nexport function segmentFingerprint(\n path: string,\n): { key: string; count: unknown; manifest: SegmentManifest | null } | null {\n try {\n const { size, mtimeMs } = statSync(path);\n const manifest = readFileSync(manifestPath(path));\n const sha = createHash(\"sha256\").update(manifest).digest(\"hex\");\n let count: unknown = null;\n let parsed: SegmentManifest | null = null;\n try {\n parsed = JSON.parse(manifest.toString(\"utf8\")) as SegmentManifest;\n count = parsed?.count;\n } catch {\n // An unparseable manifest still fingerprints; its count is unknown.\n }\n return { key: `${size} ${mtimeMs} ${sha}`, count, manifest: parsed };\n } catch {\n return null;\n }\n}\n\n/** The fingerprint recorded with a watermark (see `setWatermark`), or\n * null when the last write of the watermark recorded none. */\nfunction recordedFingerprint(db: Db, watermarkKey: string): string | null {\n const row = prepareCached(\n db,\n \"SELECT fingerprint FROM sync_fingerprints WHERE machine_id = ?\",\n ).get(watermarkKey) as { fingerprint: string } | undefined;\n return row?.fingerprint ?? null;\n}\n\n/**\n * True when ingest is caught up on the segment at `path`, judged without\n * reading it: the manifest counts `lines` (the watermark), and the\n * segment's size, exact mtime and manifest bytes are what the last full,\n * defect-free ingest of this file recorded. Any difference (an append, a\n * rewrite whatever its mtime, a new or edited manifest, a watermark\n * written since by a reset or partial ingest) sends the caller down the\n * full read, which hashes the file and reports any mismatch. Cost: one\n * row lookup, one stat and one manifest read.\n */\nexport function segmentCaughtUp(\n db: Db,\n watermarkKey: string,\n path: string,\n lines: number,\n): boolean {\n const recorded = recordedFingerprint(db, watermarkKey);\n if (recorded === null) return false;\n const now = segmentFingerprint(path);\n return now !== null && now.count === lines && now.key === decodeFingerprint(recorded).key;\n}\n\n/** The resume point recorded with the watermark's fingerprint, when it\n * was recorded at exactly `lines`. */\nexport function resumePoint(db: Db, watermarkKey: string, lines: number): ResumePoint | null {\n const recorded = recordedFingerprint(db, watermarkKey);\n const resume = recorded === null ? null : decodeFingerprint(recorded).resume;\n return resume !== null && resume.lines === lines ? resume : null;\n}\n","// mu — `mu task auto`: explicit, host-fenced permission for the executor.\n//\n// Ready is not permission. A task is dispatched by `mu next` only when the\n// orchestrator authorised it HERE: a machine-local `task_auto` row\n// (cli key, worktree mode, run ceiling, `enabled`) AND the synced\n// `tasks.dispatch_host` naming this machine, the one host allowed to\n// dispatch it. Both are written in ONE op-context transaction.\n//\n// `--off` flips `enabled` to 0 and keeps the row: `runs` and `last_spawn`\n// (the spawn-replay receipt) must survive a re-authorisation, so nothing\n// here ever DELETEs or REPLACEs a `task_auto` row.\n//\n// Two predicates, deliberately separate:\n// autoPermitted(db, taskId) may this machine steer/release/dispatch the\n// task? Status-independent (IN_PROGRESS and\n// exhausted tasks still answer yes).\n// authorisedReady(db, ws) ready AND permitted AND runs < max_runs.\n\nimport type { Db } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { withOpContext } from \"./op-context.js\";\nimport { localMachineId } from \"./segments.js\";\nimport { type TaskRow, taskIdFor } from \"./tasks/core.js\";\nimport { TaskNotFoundError } from \"./tasks/errors.js\";\nimport { getTask, listReady } from \"./tasks/queries.js\";\nimport { RESERVED_WORKSTREAM_NAMES } from \"./workstream.js\";\n\n/** A cli key: the lookup key of `MU_<UPPER_CLI>_COMMAND` (hyphen or underscore). */\nconst CLI_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;\n\n/** A refusal that leaves everything unwritten (exit 4). */\nexport class TaskAutoRefusedError extends Error {\n override readonly name = \"TaskAutoRefusedError\";\n constructor(\n message: string,\n public readonly workstream: string,\n public readonly taskId: string,\n ) {\n super(message);\n }\n}\n\n/** A bad `--cli` / `--max` / empty selection (exit 2). */\nexport class TaskAutoArgError extends Error {\n override readonly name = \"TaskAutoArgError\";\n}\n\nexport interface AuthorizeTasksOptions {\n workstream: string;\n /** The model key `mu next` spawns with. Ignored by `off`. */\n cli: string;\n worktree: boolean;\n /** Run ceiling (> 0). Ignored by `off`. */\n maxRuns: number;\n /** Revoke LOCAL permission (keeps the counters) instead of granting it. */\n off?: boolean;\n /** Also select every open transitive blocker of this task (not the task itself). */\n blockersOf?: string;\n /** Attribution for the captured ops. */\n actor?: string;\n}\n\nexport interface AuthorizeTasksResult {\n /** The tasks acted on, in selection order. */\n ids: string[];\n /** False when every row and designation was already as asked. */\n changed: boolean;\n}\n\nexport interface AutoConfig {\n cli: string;\n worktree: boolean;\n maxRuns: number;\n runs: number;\n lastSpawn: string | null;\n enabled: boolean;\n}\n\n/** A ready task the executor may act on, with its stored config. */\nexport interface AuthorisedTask extends TaskRow {\n auto: AutoConfig;\n}\n\ninterface AutoRow {\n cli: string;\n worktree: number;\n max_runs: number;\n runs: number;\n last_spawn: string | null;\n enabled: number;\n}\n\nconst configOf = (r: AutoRow): AutoConfig => ({\n cli: r.cli,\n worktree: r.worktree === 1,\n maxRuns: r.max_runs,\n runs: r.runs,\n lastSpawn: r.last_spawn,\n enabled: r.enabled === 1,\n});\n\n/** The stored config of one task (surrogate id), enabled or not. */\nexport function getAutoConfig(db: Db, taskId: number): AutoConfig | undefined {\n const row = db\n .prepare(\n \"SELECT cli, worktree, max_runs, runs, last_spawn, enabled FROM task_auto WHERE task_id = ?\",\n )\n .get(taskId) as AutoRow | undefined;\n return row === undefined ? undefined : configOf(row);\n}\n\n/**\n * May this machine act on the task (steer, release, dispatch)? True iff an\n * ENABLED `task_auto` row exists, the task is `kind=work`, and its synced\n * `dispatch_host` is this machine. Independent of status and of the run\n * ceiling. Resolve the surrogate id with `taskIdFor`.\n */\nexport function autoPermitted(db: Db, taskId: number): boolean {\n return (\n db\n .prepare(\n `SELECT 1 AS x FROM task_auto a JOIN tasks t ON t.id = a.task_id\n WHERE a.task_id = ? AND a.enabled = 1 AND t.kind = 'work' AND t.dispatch_host = ?`,\n )\n .get(taskId, localMachineId(db)) !== undefined\n );\n}\n\n/**\n * The tasks `mu next` may dispatch now, in `ready` order: ready (OPEN,\n * unblocked, not parked/triage) AND permitted AND `runs < max_runs`.\n * `kind` human/delegate never qualifies; the reserved scratch queue is empty.\n */\nexport function authorisedReady(db: Db, workstream: string): AuthorisedTask[] {\n if (RESERVED_WORKSTREAM_NAMES.has(workstream)) return [];\n const rows = db\n .prepare(\n `SELECT t.local_id AS local_id, a.cli, a.worktree, a.max_runs, a.runs, a.last_spawn, a.enabled\n FROM task_auto a\n JOIN tasks t ON t.id = a.task_id\n JOIN workstreams w ON w.id = t.workstream_id AND w.name = ?\n WHERE a.enabled = 1 AND a.runs < a.max_runs\n AND t.kind = 'work' AND t.dispatch_host = ?`,\n )\n .all(workstream, localMachineId(db)) as (AutoRow & { local_id: string })[];\n const byId = new Map(rows.map((r) => [r.local_id, configOf(r)]));\n const out: AuthorisedTask[] = [];\n for (const t of listReady(db, workstream)) {\n const auto = byId.get(t.name);\n if (auto !== undefined) out.push({ ...t, auto });\n }\n return out;\n}\n\n/**\n * The local ids of every OPEN or IN_PROGRESS transitive blocker of an\n * umbrella, sorted. Walks only the umbrella's own workstream, uncapped\n * (unlike the display frontier), safe on diamonds and cycles, never walks\n * through a CLOSED task, never lists the umbrella itself.\n */\nexport function openBlockersClosure(db: Db, workstreamId: number, umbrellaId: number): string[] {\n const blockersOf = db.prepare(\n `SELECT b.id AS id, b.local_id AS local_id, b.status AS status\n FROM task_edges e JOIN tasks b ON b.id = e.from_task_id\n WHERE e.to_task_id = ? AND b.workstream_id = ?`,\n );\n const seen = new Set<number>([umbrellaId]);\n const queue = [umbrellaId];\n const found: string[] = [];\n for (let cur = queue.shift(); cur !== undefined; cur = queue.shift()) {\n const rows = blockersOf.all(cur, workstreamId) as {\n id: number;\n local_id: string;\n status: string;\n }[];\n for (const r of rows) {\n if (seen.has(r.id) || r.status === \"CLOSED\") continue;\n seen.add(r.id);\n found.push(r.local_id);\n queue.push(r.id);\n }\n }\n return found.sort();\n}\n\n/**\n * Grant (or, with `off`, revoke) this machine's permission to dispatch the\n * selected tasks. Grant: upsert the local `task_auto` row (keeping `runs`\n * and `last_spawn`, setting `enabled`) and write the synced `dispatch_host`\n * = this machine. Off: `enabled = 0`, and `dispatch_host` cleared only when\n * this machine owns it. The whole batch is validated inside ONE\n * transaction before any write: a refusal leaves nothing changed.\n */\nexport function authorizeTasks(\n db: Db,\n ids: readonly string[],\n opts: AuthorizeTasksOptions,\n): AuthorizeTasksResult {\n const ws = opts.workstream;\n if (RESERVED_WORKSTREAM_NAMES.has(ws)) {\n throw new TaskAutoArgError(say(\"task.auto_reserved_ws\", ws));\n }\n if (!opts.off) {\n if (!CLI_KEY_RE.test(opts.cli)) {\n throw new TaskAutoArgError(say(\"task.auto_cli_key\", opts.cli));\n }\n if (!Number.isSafeInteger(opts.maxRuns) || opts.maxRuns < 1) {\n throw new TaskAutoArgError(say(\"task.auto_max\", opts.maxRuns));\n }\n }\n return withOpContext(\n db,\n { intent: opts.off ? \"task.auto-off\" : \"task.auto\", actor: opts.actor, group: \"new\" },\n () => {\n const me = localMachineId(db);\n const selected = [...ids];\n if (opts.blockersOf !== undefined) {\n const umbrella = getTask(db, opts.blockersOf, ws);\n if (!umbrella) throw new TaskNotFoundError(opts.blockersOf, ws);\n selected.push(...openBlockersClosure(db, umbrella.workstreamId, tidOf(db, umbrella)));\n }\n const names = [...new Set(selected)];\n if (names.length === 0) {\n throw new TaskAutoArgError(\n opts.blockersOf !== undefined\n ? say(\"task.auto_no_blockers\", opts.blockersOf)\n : say(\"task.auto_none_given\"),\n );\n }\n\n // Validate the whole batch first.\n const plan: { task: TaskRow; id: number }[] = [];\n for (const name of names) {\n const task = getTask(db, name, ws);\n if (!task) throw new TaskNotFoundError(name, ws);\n const id = tidOf(db, task);\n if (!opts.off) refuseUnauthorisable(task, me);\n plan.push({ task, id });\n }\n\n // Then write.\n const now = new Date().toISOString();\n let changed = false;\n for (const { task, id } of plan) {\n const row = db\n .prepare(\"SELECT cli, worktree, max_runs, enabled FROM task_auto WHERE task_id = ?\")\n .get(id) as Pick<AutoRow, \"cli\" | \"worktree\" | \"max_runs\" | \"enabled\"> | undefined;\n if (opts.off) {\n if (row !== undefined && row.enabled === 1) {\n db.prepare(\"UPDATE task_auto SET enabled = 0 WHERE task_id = ?\").run(id);\n changed = true;\n }\n if (task.dispatchHost === me) {\n setHost(db, id, null, now);\n changed = true;\n }\n continue;\n }\n const wt = opts.worktree ? 1 : 0;\n if (row === undefined) {\n db.prepare(\n \"INSERT INTO task_auto (task_id, cli, worktree, max_runs, created_at) VALUES (?, ?, ?, ?, ?)\",\n ).run(id, opts.cli, wt, opts.maxRuns, now);\n changed = true;\n } else if (\n row.cli !== opts.cli ||\n row.worktree !== wt ||\n row.max_runs !== opts.maxRuns ||\n row.enabled !== 1\n ) {\n db.prepare(\n \"UPDATE task_auto SET cli = ?, worktree = ?, max_runs = ?, enabled = 1 WHERE task_id = ?\",\n ).run(opts.cli, wt, opts.maxRuns, id);\n changed = true;\n }\n if (task.dispatchHost !== me) {\n setHost(db, id, me, now);\n changed = true;\n }\n }\n return { ids: names, changed };\n },\n );\n}\n\nfunction tidOf(db: Db, task: TaskRow): number {\n const id = taskIdFor(db, task.name, task.workstreamName);\n if (id === null) throw new TaskNotFoundError(task.name, task.workstreamName);\n return id;\n}\n\nfunction setHost(db: Db, taskId: number, host: string | null, now: string): void {\n db.prepare(\"UPDATE tasks SET dispatch_host = ?, updated_at = ? WHERE id = ?\").run(\n host,\n now,\n taskId,\n );\n}\n\n/** Why a task cannot be authorised for the executor, or return. */\nfunction refuseUnauthorisable(task: TaskRow, me: string): void {\n const refuse = (why: string): never => {\n throw new TaskAutoRefusedError(\n `cannot authorise ${task.name}: ${why}`,\n task.workstreamName,\n task.name,\n );\n };\n if (task.kind !== \"work\") refuse(`it is a ${task.kind} task, not a worker job`);\n if (task.status === \"CLOSED\") refuse(\"it is CLOSED\");\n if (task.substate === \"parked\") refuse(\"it is parked (unpark it first)\");\n if (task.substate === \"triage\") refuse(\"it is in triage (accept it first)\");\n if (task.dispatchHost !== null && task.dispatchHost !== me) {\n refuse(`another host (${task.dispatchHost}) is designated to dispatch it`);\n }\n}\n","// mu — `buildTaskBrief`: the prompt of one executor attempt, built from the\n// task's OWN notes. The first `brief` note, verbatim; the latest `report`\n// note; one footer naming the task and the CLOSE line. Nothing generated is\n// ever stored back, so a retry can never quote an earlier footer.\n//\n// The executor stores the built TEXT with the reservation and a replay sends\n// those exact bytes: it never calls this again, so a deleted note, a newer\n// report or a changed footer cannot alter a stored request. Pure SQL: no mux,\n// no ctl.\n\nimport type { Db } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { taskIdFor } from \"./tasks/core.js\";\nimport { TaskNotFoundError } from \"./tasks/errors.js\";\nimport { getTaskNote } from \"./tasks/queries.js\";\n\n/** The task has no `brief` note : nothing is built. */\nexport class TaskBriefMissingError extends Error {\n override readonly name = \"TaskBriefMissingError\";\n constructor(\n public readonly task: string,\n public readonly workstream: string,\n reason: string,\n ) {\n super(say(\"task.brief_missing\", task, reason));\n }\n}\n\nexport interface TaskBriefOptions {\n /** The previous attempt died (`true`) or its run stopped on an API error (`\"error\"`): say so. */\n retry?: boolean | \"error\";\n}\n\nexport interface TaskBrief {\n text: string;\n}\n\n/**\n * The pinned notes of a task: the 1-based number of its FIRST `brief` note and\n * of its LATEST `report` note (0 = none). A checker is briefed from the same two.\n */\nexport function pinnedNotes(\n db: Db,\n workstream: string,\n task: string,\n): { briefN: number; reportN: number } {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) throw new TaskNotFoundError(task, workstream);\n const kinds = (\n db.prepare(\"SELECT kind FROM task_notes WHERE task_id = ? ORDER BY id\").all(taskId) as {\n kind: string;\n }[]\n ).map((r) => r.kind);\n return { briefN: kinds.indexOf(\"brief\") + 1, reportN: kinds.lastIndexOf(\"report\") + 1 };\n}\n\n/** Build the prompt of one attempt for `task` (see the file header). */\nexport function buildTaskBrief(\n db: Db,\n workstream: string,\n task: string,\n opts: TaskBriefOptions = {},\n): TaskBrief {\n const { briefN, reportN } = pinnedNotes(db, workstream, task);\n if (briefN < 1) {\n throw new TaskBriefMissingError(task, workstream, \"it has no brief note (kind brief)\");\n }\n const brief = getTaskNote(db, task, workstream, briefN).content;\n const report = reportN < 1 ? null : getTaskNote(db, task, workstream, reportN).content;\n\n const parts = [brief.trimEnd()];\n if (report !== null) parts.push(`Latest report on this task:\\n${report.trimEnd()}`);\n if (opts.retry === true) {\n parts.push(\"The previous attempt died before it finished; continue from its report.\");\n } else if (opts.retry === \"error\") {\n parts.push(\n \"Your previous run stopped on an API error before it finished; continue where you stopped.\",\n );\n }\n parts.push(\n `Work only on task ${task} (workstream ${workstream}). Commit, then end your final message with:\\n` +\n `CLOSE: task=${task} evidence=\"<command + result>\"\\nREPORT:\\n<what you did>`,\n );\n return { text: parts.join(\"\\n\\n\") };\n}\n","// mu — the executor's attempt accounting (`mu next`, slice A).\n//\n// One authorised dispatch is one ATTEMPT, `auto:<n>` in `spawn_receipts`\n// (a different namespace from a manual `manual:<k>`), whose latest record\n// lives in `task_auto.last_spawn` as JSON. A run is CHARGED once, when the\n// attempt is reserved: counter, record and `reserved` receipt are written in\n// ONE immediate transaction that re-plans first, so two `mu next` (two\n// processes) cannot mint different attempts for a task, and a crash leaves\n// either nothing or a reservation that a later `mu next` resumes under the\n// SAME key. The record stores the EXACT prompt, so a replay sends those bytes\n// and never rebuilds (nothing can drift). Replays, UNKNOWN probes and receipt\n// checks never charge. A\n// definitely-unsent failure keeps its charge and its failed key (never\n// reset): the next attempt is a new key and a new charge, so real spawns can\n// never exceed `max_runs`.\n//\n// `planAttempt` is the read-only half (also the dry run); `reserveAttempt`\n// re-runs it inside the write transaction. No await, no ctl, no mux here.\n\nimport {\n getReceipt,\n requestSha,\n reserveReceipt,\n type SpawnReceipt,\n updateReceipt,\n} from \"./agents/receipts.js\";\nimport { savedIdentity } from \"./agents/task-spawn.js\";\nimport { MAX_AGENT_NAME_LEN } from \"./agents.js\";\nimport { newMsgId } from \"./ctl/client.js\";\nimport type { Db } from \"./db.js\";\nimport { taskRevision } from \"./revision.js\";\nimport { localMachineId } from \"./segments.js\";\nimport { type AutoConfig, autoPermitted, getAutoConfig } from \"./task-auto.js\";\nimport { buildTaskBrief, TaskBriefMissingError } from \"./task-brief.js\";\nimport { taskIdFor } from \"./tasks/core.js\";\nimport { listReady } from \"./tasks/queries.js\";\n\n/**\n * How a stored attempt ended without a delivery: `abandoned` (nothing left to\n * do: the task closed, the agent is gone) or `needs_human` (the prompt may\n * have landed and cannot be confirmed: never resent, parked behind a human\n * need). Either is terminal: never replayed, never counted again.\n */\nexport interface AttemptEnd {\n state: \"abandoned\" | \"needs_human\";\n reason: string;\n}\n\n/** `task_auto.last_spawn`: the latest attempt, with its exact request. */\nexport interface AttemptRecord {\n v: 1;\n attempt: number;\n /** `auto:<attempt>`: the `spawn_receipts.attempt_key`. */\n key: string;\n /** The agent name asked for (a taken one is moved on by `nextFree`; the receipt has the real one). */\n name: string;\n cli: string;\n worktree: boolean;\n /** The exact prompt, stored at reservation: a replay sends these bytes. */\n text: string;\n /** The previous attempt's worker is gone: the brief says so. */\n retry: boolean;\n /**\n * A retry IN PLACE: the same live worker (its saved registry id + pane) is\n * sent the brief again after an API-errored run. No pane is spawned, and no\n * failure ever removes the worker.\n */\n inPlace?: boolean;\n /** Set once the attempt reached a terminal state without a delivery. */\n end?: AttemptEnd;\n}\n\nexport interface AttemptPlan extends AttemptRecord {\n task: string;\n taskId: number;\n workstream: string;\n /** The task's derived revision the plan was made at. */\n revision: number;\n}\n\nexport type PlanCode =\n | \"not-found\"\n | \"not-permitted\"\n | \"in-flight\"\n | \"parked\"\n | \"delivered\"\n | \"ceiling\"\n | \"not-ready\"\n | \"no-brief\"\n | \"changed\";\n\nexport type PlanResult =\n | { ok: true; plan: AttemptPlan }\n | { ok: false; code: PlanCode; reason: string };\n\n/** Receipt states from which an attempt must be resumed, not replaced. */\nexport const IN_FLIGHT_STATES: ReadonlySet<string> = new Set([\n \"reserved\",\n \"pane\",\n \"claimed\",\n \"sending\",\n \"unknown\",\n]);\n\n/** Receipt states from which nothing has been written to the agent. */\nconst UNSENT_STATES: ReadonlySet<string> = new Set([\"reserved\", \"pane\", \"claimed\"]);\n\nconst refuse = (code: PlanCode, reason: string): PlanResult => ({ ok: false, code, reason });\n\n/**\n * Is the worker of a DELIVERED attempt known to be gone, with its task\n * reopened by the reaper? The saved registry id + pane no longer hold, and the\n * reaper's own note (`[reaper] previous owner <name> gone`) was written after\n * the attempt began. A task someone reopened by hand (a rejected review) has\n * no such note: that is a decision, never a death.\n */\nexport function workerGone(db: Db, taskId: number, receipt: SpawnReceipt): boolean {\n if (savedIdentity(db, receipt).stale === undefined) return false;\n const head = `[reaper] previous owner ${receipt.name} gone`;\n return (\n db\n .prepare(\n `SELECT 1 AS x FROM task_notes\n WHERE task_id = ? AND author = 'reaper' AND created_at >= ? AND instr(content, ?) = 1\n LIMIT 1`,\n )\n .get(taskId, receipt.createdAt, head) !== undefined\n );\n}\n\nexport function parseAttempt(raw: string | null): AttemptRecord | undefined {\n if (raw === null) return undefined;\n try {\n const r = JSON.parse(raw) as Partial<AttemptRecord>;\n if (\n r.v !== 1 ||\n typeof r.key !== \"string\" ||\n typeof r.attempt !== \"number\" ||\n typeof r.text !== \"string\"\n ) {\n return undefined;\n }\n return r as AttemptRecord;\n } catch {\n return undefined;\n }\n}\n\n/** The stored attempt of a task and its receipt (either may be absent). */\nexport function readAttempt(\n db: Db,\n taskId: number,\n): { auto?: AutoConfig; record?: AttemptRecord; receipt?: SpawnReceipt } {\n const auto = getAutoConfig(db, taskId);\n const record = parseAttempt(auto?.lastSpawn ?? null);\n const receipt = record === undefined ? undefined : getReceipt(db, taskId, record.key);\n return {\n ...(auto !== undefined ? { auto } : {}),\n ...(record !== undefined ? { record } : {}),\n ...(receipt !== undefined ? { receipt } : {}),\n };\n}\n\n/**\n * The DELIVERED receipt the latest attempt stands on: its own when `sent`; for\n * an in-place retry that failed unsent (the worker was never touched), the\n * delivery it retried. Undefined when nothing was delivered.\n */\nexport function deliveredOf(\n db: Db,\n taskId: number,\n): { record: AttemptRecord; receipt: SpawnReceipt } | undefined {\n const { record, receipt } = readAttempt(db, taskId);\n if (record === undefined || receipt === undefined || record.end !== undefined) return undefined;\n if (receipt.state === \"sent\") return { record, receipt };\n if (record.inPlace !== true || receipt.state !== \"failed\") return undefined;\n const prior = db\n .prepare(\n `SELECT attempt_key FROM spawn_receipts\n WHERE task_id = ? AND state = 'sent' AND attempt_key LIKE 'auto:%' AND agent_id = ?\n ORDER BY created_at DESC, attempt_key DESC LIMIT 1`,\n )\n .get(taskId, receipt.agentId) as { attempt_key: string } | undefined;\n const sent = prior === undefined ? undefined : getReceipt(db, taskId, prior.attempt_key);\n return sent === undefined ? undefined : { record, receipt: sent };\n}\n\n/**\n * Local ids of the permitted tasks of `workstream` whose latest attempt is\n * in flight (reserved … unknown) and not ended: to be RESUMED before anything\n * new is allocated, even at their run ceiling. Revoked, foreign and ended\n * (abandoned / needs_human) attempts are absent.\n */\nexport function pendingAttempts(db: Db, workstream: string): string[] {\n const rows = db\n .prepare(\n `SELECT t.id AS id, t.local_id AS local_id\n FROM task_auto a\n JOIN tasks t ON t.id = a.task_id\n JOIN workstreams w ON w.id = t.workstream_id AND w.name = ?\n JOIN spawn_receipts r ON r.task_id = a.task_id\n AND r.attempt_key = json_extract(a.last_spawn, '$.key')\n WHERE a.enabled = 1 AND t.kind = 'work' AND t.dispatch_host = ?\n AND r.state IN ('reserved', 'pane', 'claimed', 'sending', 'unknown')\n AND json_extract(a.last_spawn, '$.end') IS NULL\n AND json_extract(a.last_spawn, '$.text') IS NOT NULL\n ORDER BY t.id`,\n )\n .all(workstream, localMachineId(db)) as { id: number; local_id: string }[];\n return rows.filter((r) => autoPermitted(db, r.id)).map((r) => r.local_id);\n}\n\n/** The agent name an attempt asks for: the task id cut to leave room for `-<attempt>`. */\nexport function attemptName(task: string, attempt: number): string {\n const suffix = `-${attempt}`;\n return `${task.slice(0, MAX_AGENT_NAME_LEN - suffix.length)}${suffix}`;\n}\n\n/** The request hash of an attempt (the executor always spawns `nextFree`, locally). */\nexport const attemptSha = (name: string, text: string): string =>\n requestSha({ name, nextFree: true, text });\n\n/**\n * Read-only: may a NEW attempt for `task` be reserved now, and what would it\n * be? Checks, in order: permission (enabled, work, this host), an attempt\n * already in flight or delivered, the run ceiling, readiness and the brief.\n * `revision` (when given) must equal the task's current revision.\n */\nexport function planAttempt(\n db: Db,\n workstream: string,\n task: string,\n opts: { revision?: number } = {},\n): PlanResult {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) return refuse(\"not-found\", `no task ${task} in ${workstream}`);\n if (!autoPermitted(db, taskId)) {\n return refuse(\"not-permitted\", `${task} is not authorised for this machine (mu task auto)`);\n }\n const { auto, record, receipt } = readAttempt(db, taskId);\n if (auto === undefined) return refuse(\"not-permitted\", `${task} has no auto config`);\n let retry = false;\n if (record?.end?.state === \"needs_human\") {\n return refuse(\n \"parked\",\n `${record.key} of ${task} may have been delivered and waits for a human (${record.end.reason})`,\n );\n }\n if (record !== undefined && receipt !== undefined && record.end === undefined) {\n if (IN_FLIGHT_STATES.has(receipt.state)) {\n return refuse(\"in-flight\", `${record.key} of ${task} is ${receipt.state}: resume it`);\n }\n const delivered = deliveredOf(db, taskId);\n if (delivered !== undefined) {\n if (!workerGone(db, taskId, delivered.receipt)) {\n return refuse(\n \"delivered\",\n `${record.key} of ${task} was delivered and its worker is not known to be gone: not re-dispatched`,\n );\n }\n retry = true;\n }\n }\n if (auto.runs >= auto.maxRuns) {\n return refuse(\"ceiling\", `${task} used its ${auto.maxRuns} run(s)`);\n }\n if (!listReady(db, workstream).some((t) => t.name === task)) {\n return refuse(\"not-ready\", `${task} is not ready`);\n }\n const revision = taskRevision(db, workstream, task);\n if (opts.revision !== undefined && opts.revision !== revision) {\n return refuse(\n \"changed\",\n `${task} changed since it was planned (rev ${opts.revision} → ${revision})`,\n );\n }\n const attempt = auto.runs + 1;\n const name = attemptName(task, attempt);\n let brief: ReturnType<typeof buildTaskBrief>;\n try {\n brief = buildTaskBrief(db, workstream, task, { retry });\n } catch (err) {\n if (err instanceof TaskBriefMissingError) return refuse(\"no-brief\", err.message);\n throw err;\n }\n return {\n ok: true,\n plan: {\n v: 1,\n attempt,\n key: `auto:${attempt}`,\n name,\n cli: auto.cli,\n worktree: auto.worktree,\n text: brief.text,\n retry,\n task,\n taskId,\n workstream,\n revision,\n },\n };\n}\n\n/**\n * Charge one run and reserve its attempt, atomically (see the file header).\n * Re-plans INSIDE the immediate transaction, so a change seen at ingest\n * between the caller's view and now refuses instead of acting on it.\n */\nexport function reserveAttempt(\n db: Db,\n workstream: string,\n task: string,\n opts: { revision?: number } = {},\n): PlanResult {\n return db\n .transaction((): PlanResult => {\n const planned = planAttempt(db, workstream, task, opts);\n if (!planned.ok) return planned;\n const { plan } = planned;\n const { task: _t, taskId, workstream: _w, revision: _r, ...record } = plan;\n const charged = db\n .prepare(\n \"UPDATE task_auto SET runs = runs + 1, last_spawn = ? WHERE task_id = ? AND runs = ? AND enabled = 1\",\n )\n .run(JSON.stringify(record), taskId, plan.attempt - 1);\n if (charged.changes !== 1) return refuse(\"changed\", `${task}'s run counter moved`);\n reserveReceipt(db, {\n taskId,\n attemptKey: plan.key,\n name: plan.name,\n workstream,\n requestSha: attemptSha(plan.name, plan.text),\n msgId: newMsgId(),\n });\n return planned;\n })\n .immediate();\n}\n\n/**\n * Move the stored attempt `key` of a task to a terminal state (compare and\n * set on the key, so a newer attempt is never overwritten). A receipt that\n * never reached the send (reserved, pane, claimed) is failed with the reason;\n * a sending / unknown one is left as the evidence it is. False when the\n * record moved on.\n */\nexport function endAttempt(db: Db, taskId: number, key: string, end: AttemptEnd): boolean {\n return db\n .transaction((): boolean => {\n const { record, receipt } = readAttempt(db, taskId);\n if (record === undefined || record.key !== key || record.end !== undefined) return false;\n const changed = db\n .prepare(\"UPDATE task_auto SET last_spawn = ? WHERE task_id = ?\")\n .run(JSON.stringify({ ...record, end }), taskId).changes;\n if (changed !== 1) return false;\n if (receipt !== undefined && UNSENT_STATES.has(receipt.state)) {\n updateReceipt(db, taskId, key, { state: \"failed\", detail: `${end.state}: ${end.reason}` });\n }\n return true;\n })\n .immediate();\n}\n\n/** What `reserveRetry` needs of the worker observed to have stopped on an API error. */\nexport interface RetryTarget {\n /** The registry row the attempt saved: id + pane, and the name. */\n agent: { incarnation: number; paneId: string; name: string };\n /** pi's process incarnation the error was read from: the send is bound to it. */\n pi: string;\n /** pi's settled-run count of the errored run. */\n errorRuns: number;\n}\n\n/**\n * Charge one run and reserve an IN-PLACE retry of the delivered attempt, atomically\n * (see the file header): the same worker, the same task, a new `auto:<n>` key\n * whose receipt starts at `claimed` on the saved identity, so the guarded replay\n * skips the spawn and the claim and goes straight to the journaled send. Refuses\n * unless, in this transaction: the task is permitted and IN_PROGRESS, owned by the\n * very registry row the delivered attempt saved (id + pane), under its run\n * ceiling, and the error run is a newer one than the delivered send (so a retry\n * already sent is never charged twice for the same error).\n */\nexport function reserveRetry(\n db: Db,\n workstream: string,\n task: string,\n target: RetryTarget,\n): PlanResult {\n return db\n .transaction((): PlanResult => {\n const taskId = taskIdFor(db, task, workstream);\n if (taskId === null) return refuse(\"not-found\", `no task ${task} in ${workstream}`);\n if (!autoPermitted(db, taskId)) {\n return refuse(\"not-permitted\", `${task} is not authorised for this machine (mu task auto)`);\n }\n const { auto } = readAttempt(db, taskId);\n const delivered = deliveredOf(db, taskId);\n if (auto === undefined || delivered === undefined) {\n return refuse(\"changed\", `${task} has no delivered attempt`);\n }\n const { receipt } = delivered;\n const { agent } = target;\n if (\n receipt.agentId !== agent.incarnation ||\n receipt.paneId !== agent.paneId ||\n receipt.name !== agent.name ||\n savedIdentity(db, receipt).stale !== undefined\n ) {\n return refuse(\"changed\", `${task}: the worker is not the one its attempt delivered to`);\n }\n if (receipt.runs === null || target.errorRuns <= receipt.runs) {\n return refuse(\"changed\", `${task}: that error was already answered`);\n }\n const row = db.prepare(\"SELECT status, owner_id FROM tasks WHERE id = ?\").get(taskId) as {\n status: string;\n owner_id: number | null;\n };\n if (row.status !== \"IN_PROGRESS\" || row.owner_id !== agent.incarnation) {\n return refuse(\"changed\", `${task} is no longer in progress with ${agent.name}`);\n }\n if (auto.runs >= auto.maxRuns) {\n return refuse(\"ceiling\", `${task} used its ${auto.maxRuns} run(s)`);\n }\n let brief: ReturnType<typeof buildTaskBrief>;\n try {\n brief = buildTaskBrief(db, workstream, task, { retry: \"error\" });\n } catch (err) {\n if (err instanceof TaskBriefMissingError) return refuse(\"no-brief\", err.message);\n throw err;\n }\n const attempt = auto.runs + 1;\n const plan: AttemptPlan = {\n v: 1,\n attempt,\n key: `auto:${attempt}`,\n name: agent.name,\n cli: auto.cli,\n worktree: auto.worktree,\n text: brief.text,\n retry: true,\n inPlace: true,\n task,\n taskId,\n workstream,\n revision: taskRevision(db, workstream, task),\n };\n const { task: _t, taskId: _i, workstream: _w, revision: _r, ...stored } = plan;\n const charged = db\n .prepare(\n \"UPDATE task_auto SET runs = runs + 1, last_spawn = ? WHERE task_id = ? AND runs = ? AND enabled = 1\",\n )\n .run(JSON.stringify(stored), taskId, auto.runs);\n if (charged.changes !== 1) return refuse(\"changed\", `${task}'s run counter moved`);\n reserveReceipt(db, {\n taskId,\n attemptKey: plan.key,\n name: agent.name,\n workstream,\n requestSha: attemptSha(agent.name, plan.text),\n msgId: newMsgId(),\n });\n updateReceipt(db, taskId, plan.key, {\n state: \"claimed\",\n agentId: agent.incarnation,\n paneId: agent.paneId,\n incarnation: target.pi,\n });\n return { ok: true, plan };\n })\n .immediate();\n}\n","// mu — bounded open-task frontier read and its ASCII branch drawing, shared\n// by `mu task tree` and the dashboard.\n\nimport type { Db } from \"./db.js\";\nimport {\n type RawTaskRow,\n rowFromDb,\n SELECT_TASK_COLS,\n TASK_FROM_JOIN,\n type TaskRow,\n taskIdFor,\n} from \"./tasks.js\";\n\n/** Deepest level of a frontier read; a node past it keeps a `kids` count. */\nexport const FRONTIER_MAX_DEPTH = 12;\n/** Most distinct tasks one frontier read lists (recurrences are capped at the same number). */\nexport const FRONTIER_MAX_NODES = 2000;\n/** CLOSED neighbours listed under one node; the rest collapse into its `closed` count. */\nexport const FRONTIER_CLOSED_PER_NODE = 3;\n\nexport type FrontierDirection = \"blockers\" | \"dependents\";\n\n/** One line of the open task tree, in preorder. */\nexport interface FrontierEntry {\n task: TaskRow;\n /** 0 for a root. */\n depth: number;\n /** `local_id` of the entry it is listed under; null for a root. */\n parent: string | null;\n /** Already listed above (a diamond, or a cycle sync made): not expanded again. */\n again: boolean;\n /** Neighbours (in the read direction) that are not CLOSED and are not listed under this entry. */\n kids: number;\n /** CLOSED neighbours collapsed into this count instead of listed. */\n closed: number;\n /** Neighbours of any status the node cap left out (not in `kids` / `closed`). */\n capCut: number;\n}\n\nexport interface OpenTaskFrontier {\n direction: FrontierDirection;\n entries: FrontierEntry[];\n /** Start tasks left out by the node cap (only without a `root`). */\n rootsCut: number;\n /** Recurrence lines (diamonds) left out by the cap; every such task is listed elsewhere. */\n againCut: number;\n}\n\nexport interface OpenTaskFrontierOptions {\n /** Walk through CLOSED tasks too (still capped by depth and entries unless `uncapped`). */\n includeClosed?: boolean;\n /** No cap at all: CLOSED tasks walked, every level, every task, every recurrence (`task tree --all`). */\n uncapped?: boolean;\n /** Levels below a root to list (default and ceiling `FRONTIER_MAX_DEPTH`). */\n maxDepth?: number;\n}\n\n/**\n * The open part of the DAG, bounded: from `root` (always expanded, even when\n * CLOSED) or, without one, from every non-CLOSED task that has no non-CLOSED\n * predecessor; `direction` is the way to walk (dependents = what a task\n * blocks). A non-CLOSED task expands; a CLOSED one is a leaf, and only the\n * first `FRONTIER_CLOSED_PER_NODE` of a node's CLOSED neighbours are listed\n * (the rest are counted), so one umbrella with 870 closed children costs a\n * few lines. Depth is capped at `FRONTIER_MAX_DEPTH` and entries at\n * `FRONTIER_MAX_NODES`; what a cap leaves out is counted in `kids`. Diamonds\n * and cycles list a task once and mark later sightings `again`. One SQL read\n * per level (never per node), same-workstream edges only.\n */\nexport function loadOpenTaskFrontier(\n db: Db,\n workstream: string,\n root?: string,\n direction: FrontierDirection = \"dependents\",\n opts: OpenTaskFrontierOptions = {},\n): OpenTaskFrontier {\n const out: OpenTaskFrontier = { direction, entries: [], rootsCut: 0, againCut: 0 };\n const uncapped = opts.uncapped === true;\n const maxDepth = uncapped\n ? Number.POSITIVE_INFINITY\n : Math.min(opts.maxDepth ?? FRONTIER_MAX_DEPTH, FRONTIER_MAX_DEPTH);\n const maxNodes = uncapped ? Number.POSITIVE_INFINITY : FRONTIER_MAX_NODES;\n const closedPerNode = uncapped ? Number.POSITIVE_INFINITY : FRONTIER_CLOSED_PER_NODE;\n const wsRow = db\n .prepare(\"SELECT id FROM workstreams WHERE name = ? AND torn_down_at IS NULL\")\n .get(workstream) as { id: number } | undefined;\n if (wsRow === undefined) return out;\n const wsId = wsRow.id;\n const [from, to] =\n direction === \"dependents\" ? [\"from_task_id\", \"to_task_id\"] : [\"to_task_id\", \"from_task_id\"];\n const includeClosed = opts.includeClosed === true || uncapped;\n\n const nodes = new Map<number, TaskRow>();\n const rootIds = new Set<number>();\n let level: number[] = [];\n const startRows: RawTaskRow[] = [];\n if (root !== undefined) {\n const id = taskIdFor(db, root, workstream);\n if (id === null) return out;\n startRows.push(\n db\n .prepare(`SELECT ${SELECT_TASK_COLS} ${TASK_FROM_JOIN} WHERE t.id = ?`)\n .get(id) as RawTaskRow,\n );\n } else {\n // Open tasks nothing open blocks (dependents) / that block nothing open (blockers).\n startRows.push(\n ...(db\n .prepare(\n `SELECT ${SELECT_TASK_COLS} ${TASK_FROM_JOIN}\n WHERE t.workstream_id = ? AND t.status <> 'CLOSED'\n AND NOT EXISTS (SELECT 1 FROM task_edges e JOIN tasks p ON p.id = e.${from}\n WHERE e.${to} = t.id AND p.status <> 'CLOSED'\n AND p.workstream_id = t.workstream_id)\n ORDER BY t.local_id`,\n )\n .all(wsId) as RawTaskRow[]),\n );\n }\n for (const raw of startRows.slice(0, maxNodes)) {\n nodes.set(raw.id, rowFromDb(raw));\n rootIds.add(raw.id);\n level.push(raw.id);\n }\n const startCut = Math.max(0, startRows.length - maxNodes);\n\n const children = new Map<number, number[]>();\n const dropped = new Map<number, number>();\n const capDropped = new Map<number, number>();\n const closedHidden = new Map<number, number>();\n const expands = (id: number): boolean =>\n includeClosed || rootIds.has(id) || nodes.get(id)?.status !== \"CLOSED\";\n\n for (let depth = 0; level.length > 0; depth++) {\n const ids = level.filter(expands);\n if (ids.length === 0) break;\n if (depth >= maxDepth) {\n const counts: { src: number; open: number; closed: number }[] = [];\n for (let i = 0; i < ids.length; i += 500) {\n const chunk = ids.slice(i, i + 500);\n counts.push(\n ...(db\n .prepare(\n `SELECT e.${from} AS src,\n SUM(CASE WHEN t.status = 'CLOSED' AND ? = 0 THEN 0 ELSE 1 END) AS open,\n SUM(CASE WHEN t.status = 'CLOSED' AND ? = 0 THEN 1 ELSE 0 END) AS closed\n FROM task_edges e JOIN tasks t ON t.id = e.${to}\n WHERE e.${from} IN (${chunk.map(() => \"?\").join(\", \")}) AND t.workstream_id = ? GROUP BY e.${from}`,\n )\n .all(includeClosed ? 1 : 0, includeClosed ? 1 : 0, ...chunk, wsId) as {\n src: number;\n open: number;\n closed: number;\n }[]),\n );\n }\n for (const c of counts) {\n if (c.open > 0) dropped.set(c.src, (dropped.get(c.src) ?? 0) + c.open);\n if (c.closed > 0) closedHidden.set(c.src, (closedHidden.get(c.src) ?? 0) + c.closed);\n }\n break;\n }\n // Chunked: an uncapped level can hold more ids than SQLite takes as variables.\n const rows: (RawTaskRow & { src: number })[] = [];\n for (let i = 0; i < ids.length; i += 500) {\n const chunk = ids.slice(i, i + 500);\n rows.push(\n ...(db\n .prepare(\n `SELECT e.${from} AS src, ${SELECT_TASK_COLS}\n FROM task_edges e\n JOIN tasks t ON t.id = e.${to}\n JOIN workstreams ws ON ws.id = t.workstream_id AND ws.torn_down_at IS NULL\n LEFT JOIN agents ag ON ag.id = t.owner_id\n WHERE e.${from} IN (${chunk.map(() => \"?\").join(\", \")}) AND t.workstream_id = ?\n ORDER BY e.${from}, t.local_id`,\n )\n .all(...chunk, wsId) as (RawTaskRow & { src: number })[]),\n );\n }\n const next: number[] = [];\n const closedSeen = new Map<number, number>();\n // Rows come ordered by (parent, local_id). Once the node cap forces a drop, every later row\n // of the level is dropped too (seen or not).\n let capped = false;\n for (const row of rows) {\n const leaf = row.status === \"CLOSED\" && !includeClosed;\n if (!capped) {\n if (leaf) {\n const n = closedSeen.get(row.src) ?? 0;\n closedSeen.set(row.src, n + 1);\n if (n >= closedPerNode) {\n closedHidden.set(row.src, (closedHidden.get(row.src) ?? 0) + 1);\n continue;\n }\n }\n if (!nodes.has(row.id) && nodes.size >= maxNodes) capped = true;\n }\n if (capped) {\n capDropped.set(row.src, (capDropped.get(row.src) ?? 0) + 1);\n continue;\n }\n if (!nodes.has(row.id)) {\n nodes.set(row.id, rowFromDb(row));\n next.push(row.id);\n }\n const kids = children.get(row.src) ?? [];\n kids.push(row.id);\n children.set(row.src, kids);\n }\n level = next;\n }\n\n // Preorder over what was loaded; the entry cap counts recurrences too.\n const listed = new Set<number>();\n let recurrences = 0;\n const walk = (id: number, parent: string | null, depth: number): void => {\n const task = nodes.get(id);\n if (task === undefined) return;\n const entry: FrontierEntry = {\n task,\n depth,\n parent,\n again: false,\n kids: dropped.get(id) ?? 0,\n closed: closedHidden.get(id) ?? 0,\n capCut: capDropped.get(id) ?? 0,\n };\n out.entries.push(entry);\n listed.add(id);\n const kids = children.get(id) ?? [];\n if (depth >= maxDepth) {\n // The level cap holds for the walk too: a shared DAG loads nodes at a shallow\n // level that the walk first meets deep. What is not listed under this entry is counted.\n for (const child of kids) {\n if (nodes.get(child)?.status === \"CLOSED\" && !includeClosed) entry.closed++;\n else entry.kids++;\n }\n return;\n }\n for (const child of kids) {\n const c = nodes.get(child);\n if (c === undefined) continue;\n if (listed.has(child)) {\n if (recurrences >= maxNodes) {\n out.againCut++;\n entry.kids++;\n } else {\n recurrences++;\n out.entries.push({\n task: c,\n depth: depth + 1,\n parent: task.name,\n again: true,\n kids: 0,\n closed: 0,\n capCut: 0,\n });\n }\n continue;\n }\n walk(child, task.name, depth + 1);\n }\n };\n for (const id of [...rootIds].sort((a, b) =>\n (nodes.get(a)?.name ?? \"\").localeCompare(nodes.get(b)?.name ?? \"\"),\n )) {\n if (listed.has(id)) continue;\n walk(id, null, 0);\n }\n out.rootsCut = startCut;\n return out;\n}\n\n/** One ASCII tree line per frontier entry: the branch drawing, then `label(entry)`. */\nexport function renderFrontierLines(\n entries: readonly FrontierEntry[],\n label: (entry: FrontierEntry) => string,\n): string[] {\n const lines: string[] = [];\n const open: boolean[] = [];\n entries.forEach((e, i) => {\n if (e.depth === 0) {\n lines.push(label(e));\n return;\n }\n // Is there a later sibling (same depth, before the depth drops below it)?\n let last = true;\n for (let j = i + 1; j < entries.length; j++) {\n const d = entries[j]?.depth ?? 0;\n if (d < e.depth) break;\n if (d === e.depth) {\n last = false;\n break;\n }\n }\n open[e.depth] = !last;\n let prefix = \"\";\n for (let d = 1; d < e.depth; d++) prefix += open[d] ? \"│ \" : \" \";\n lines.push(`${prefix}${last ? \"└── \" : \"├── \"}${label(e)}`);\n });\n return lines;\n}\n","// mu — the ONE op → prose formatter.\n//\n// WHY THIS FILE EXISTS\n//\n// mu once rendered log lines by prefix-matching free prose: `classifyEventVerb`\n// walked `EVENT_VERB_PREFIXES` looking for a leading two-word verb, and\n// `CLAIM_EVENT_PREFIX` was bolted on because that matching kept breaking\n//. Rewording any payload silently\n// broke its renderer, and attribution had to be smuggled through a\n// tab-delimited prefix so it could be parsed back out.\n//\n// Since v2-capture + v2-retire-log-shim, every op carries a structured\n// `intent` ('task.close'), a natural `key` ('demo/t1'), and a JSON\n// payload holding ONLY the columns that changed. So rendering is a\n// lookup on intent, not a search through text. THIS FILE MUST NEVER\n// STRING-MATCH A PAYLOAD to decide what an op is — that is the exact\n// brittleness the ops log deletes. It reads `intent`, then pulls named fields\n// out of the parsed payload.\n//\n// Layering: pure and colour-free. `src/cli/format.ts` adds picocolors\n// for the terminal. It owns no prose logic — one formatter, shared by every\n// surface (ROADMAP: no second render layer).\n\nimport type { LocalIntent } from \"./logs.js\";\nimport { formatPair, resolvePair } from \"./tasks/status.js\";\n\n/** Every intent mu writes: the local ones (`emitEvent`, for changes no\n * trigger can see) plus the capture-trigger ones (set via\n * `withOpContext` around a portable-table mutation). */\nexport type CaptureIntent =\n | \"task.add\"\n | \"task.update\"\n | \"task.note\"\n | \"task.delete\"\n | \"task.close\"\n | \"task.open\"\n | \"task.park\"\n | \"task.unpark\"\n | \"task.accept\"\n | \"task.reject\"\n | \"task.defer\"\n | \"task.claim\"\n | \"task.release\"\n | \"task.reap\"\n | \"task.block\"\n | \"task.unblock\"\n | \"task.reparent\"\n | \"workstream.init\"\n | \"workstream.teardown\"\n // The settled-run close the executor applies (src/close-block.ts).\n | \"close.apply\"\n // Any write made through `mu sql`, on whichever portable table it hit.\n | \"sql.write\";\n\nexport type KnownIntent = CaptureIntent | LocalIntent;\n\n/** A log row, reduced to what rendering needs. Structural so both\n * `LogRow` (the SDK shape) and raw op rows satisfy it. */\nexport interface RenderableOp {\n intent: string | null;\n /** `ops.entity`. */\n kind: string;\n /** `ops.key` — the natural key, verbatim. */\n workstreamName: string | null;\n payload: string;\n /** `ops.actor`. */\n source: string;\n op?: string;\n}\n\n/** Rendered op, split so callers can colour the verb independently.\n * `subject` is the entity the line is about; `detail` is the\n * human-readable consequence. */\nexport interface RenderedOp {\n /** Operator-facing verb, e.g. 'task close'. Colour this. */\n verb: string;\n /** The entity acted on, already stripped of workstream scope. */\n subject: string;\n /** What changed, in prose. May be empty. */\n detail: string;\n}\n\n// ─── payload access ────────────────────────────────────────────────────\n\n/** Parse an op payload into a field bag. Tolerant by design: a payload\n * that is not JSON (operator prose from `mu log \"<text>\"`) yields an empty\n * bag rather than throwing, and the caller falls back to showing the\n * text verbatim. */\nfunction fields(payload: string): Record<string, unknown> {\n if (!payload.startsWith(\"{\")) return {};\n try {\n const parsed: unknown = JSON.parse(payload);\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n return parsed as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nfunction str(bag: Record<string, unknown>, key: string): string | undefined {\n const v = bag[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction num(bag: Record<string, unknown>, key: string): number | undefined {\n const v = bag[key];\n return typeof v === \"number\" ? v : undefined;\n}\n\n/** Columns that are pure bookkeeping — never interesting on their own. */\nconst NOISE_FIELDS = new Set([\"updated_at\", \"created_at\"]);\n\n/** Field names, in the order a human wants to read them. */\nfunction changedFields(bag: Record<string, unknown>): string[] {\n return Object.keys(bag).filter((k) => !NOISE_FIELDS.has(k));\n}\n\n// ─── key parsing ───────────────────────────────────────────────────────\n\n/**\n * Split a natural key into workstream + local part.\n *\n * 'demo' -> { workstream: 'demo' }\n * 'demo/t1' -> { workstream: 'demo', local: 't1' }\n * 'demo/t1#3' -> { workstream: 'demo', local: 't1', note: '3' }\n * 'demo/a->demo/b' -> { workstream: 'demo', local: 'a', to: 'b' }\n */\nexport function parseOpKey(key: string | null): {\n workstream?: string;\n local?: string;\n note?: string;\n to?: string;\n} {\n if (key === null || key === \"\") return {};\n // Edge keys are '<ws>/<from>-><ws>/<to>'.\n const arrow = key.indexOf(\"->\");\n if (arrow !== -1) {\n const from = parseOpKey(key.slice(0, arrow));\n const to = parseOpKey(key.slice(arrow + 2));\n const out: { workstream?: string; local?: string; to?: string } = {};\n if (from.workstream !== undefined) out.workstream = from.workstream;\n if (from.local !== undefined) out.local = from.local;\n if (to.local !== undefined) out.to = to.local;\n return out;\n }\n const slash = key.indexOf(\"/\");\n if (slash === -1) return { workstream: key };\n const workstream = key.slice(0, slash);\n const rest = key.slice(slash + 1);\n const hash = rest.indexOf(\"#\");\n if (hash === -1) return { workstream, local: rest };\n return { workstream, local: rest.slice(0, hash), note: rest.slice(hash + 1) };\n}\n\n// ─── the formatter ─────────────────────────────────────────────────────\n\n/** Human verb per intent. Space-separated so it reads as a command,\n * matching how operators talk about these ('task close', not\n * 'task.close'). */\nconst VERBS: Record<KnownIntent, string> = {\n \"task.add\": \"task add\",\n \"task.update\": \"task update\",\n \"task.note\": \"task note\",\n \"task.delete\": \"task delete\",\n \"task.close\": \"task close\",\n \"close.apply\": \"close apply\",\n \"task.open\": \"task open\",\n \"task.park\": \"task park\",\n \"task.unpark\": \"task unpark\",\n \"task.accept\": \"task accept\",\n \"task.reject\": \"task reject\",\n \"task.defer\": \"task defer\",\n \"task.claim\": \"task claim\",\n \"task.release\": \"task release\",\n \"task.reap\": \"task reap\",\n \"task.block\": \"task block\",\n \"task.unblock\": \"task unblock\",\n \"task.reparent\": \"task reparent\",\n \"workstream.init\": \"workstream init\",\n \"workstream.teardown\": \"workstream teardown\",\n \"sql.write\": \"sql write\",\n \"agent.spawn\": \"agent spawn\",\n \"agent.spawn_failed\": \"agent spawn failed\",\n \"agent.close\": \"agent close\",\n \"agent.adopt\": \"agent adopt\",\n \"agent.kick\": \"agent kick\",\n \"agent.send\": \"agent send\",\n \"agent.abort\": \"agent abort\",\n // Payload prose reads \"agent stalled ...\"; keep the verb matching it\n // so the emitted text is not printed with a second, different verb.\n \"agent.stall\": \"agent stalled\",\n};\n\n/** Every intent this formatter knows, derived from the verb table so\n * the two can't drift. */\nexport const KNOWN_INTENTS: readonly KnownIntent[] = Object.keys(VERBS) as KnownIntent[];\n\n/** Every operator-facing verb the formatter can emit. Exported so audits\n * can check \"this emitter's verb is declared\" without re-deriving it\n * from the intent — the two are deliberately not always identical\n * (`agent.stall` renders as \"agent stalled\", matching its payload). */\nexport const KNOWN_VERBS: readonly string[] = Object.values(VERBS);\n\nfunction isKnownIntent(intent: string): intent is KnownIntent {\n return Object.hasOwn(VERBS, intent);\n}\n\n/**\n * Render one op as prose.\n *\n * Returns null when the row is not a rendered op at all — operator prose\n * from `mu log \"<text>\"` / a `--kind` ledger, which has no intent and\n * should be shown verbatim. Callers print `payload` in that case.\n */\nexport function renderOp(row: RenderableOp): RenderedOp | null {\n const intent = row.intent;\n if (intent === null) return null;\n\n // A bare status set (`setTaskStatus` with no more specific verb) uses\n // 'task.set-<status>' via intentIfUnset. Normalise it here rather than\n // enumerating six more table entries.\n const setPrefix = \"task.set-\";\n if (intent.startsWith(setPrefix)) {\n const status = intent.slice(setPrefix.length).toUpperCase();\n const { local } = parseOpKey(row.workstreamName);\n return { verb: \"task status\", subject: local ?? \"\", detail: `\\u2192 ${status}` };\n }\n\n if (!isKnownIntent(intent)) {\n // An intent this build does not know: written by a NEWER mu (ingested\n // from a peer's segment) or by a retired one ('migrate.*',\n // 'workstream.destroy', ...). Say only what the op row itself says:\n // the op (put or del), the key, the intent and entity verbatim, and the\n // NAMES of the changed columns. Never turn the intent into a command\n // verb ('workstream.delete' + op=put is not a delete), and never print a\n // JSON payload. A prose payload is the only information such a line\n // carries, so it follows. Not a throw: sync is never blocked by a\n // rendering gap.\n const parts = [`intent=${intent}`, `kind=${row.kind}`];\n if (row.payload.startsWith(\"{\")) {\n const patch = changedFields(fields(row.payload));\n if (patch.length > 0) parts.push(`patch=${patch.join(\",\")}`);\n } else if (row.payload !== \"\") {\n parts.push(`: ${oneLine(row.payload)}`);\n }\n return {\n verb: row.op === undefined ? \"op\" : `op ${row.op}`,\n subject: row.workstreamName ?? \"\",\n detail: parts.join(\" \"),\n };\n }\n // A note written inside another verb's op group (the close's evidence\n // note carries intent task.close) is still a note line.\n if (row.kind === \"note\" && row.op !== \"del\") return renderKnown(row, \"task.note\");\n return renderKnown(row, intent);\n}\n\n/** Split from `renderOp` so the switch is this function's ONLY exit\n * path: that is what makes TS treat it as exhaustive and reject a\n * missing `KnownIntent` case at COMPILE time (TS2366), instead of\n * silently falling through to a runtime default. */\nfunction renderKnown(row: RenderableOp, intent: KnownIntent): RenderedOp {\n const bag = fields(row.payload);\n const key = parseOpKey(row.workstreamName);\n const subject = key.local ?? key.workstream ?? \"\";\n const deleted = row.op === \"del\";\n\n // Exhaustive switch over the closed union: adding an intent to VERBS\n // without handling it here is a COMPILE error, not a runtime fallback.\n switch (intent) {\n case \"task.add\": {\n const impact = num(bag, \"impact\");\n const effort = num(bag, \"effort_days\");\n const title = str(bag, \"title\");\n const bits: string[] = [];\n if (title !== undefined) bits.push(`\"${title}\"`);\n if (impact !== undefined) bits.push(`impact=${impact}`);\n if (effort !== undefined) bits.push(`effort=${effort}`);\n return { verb: VERBS[intent], subject, detail: bits.join(\" \") };\n }\n case \"task.update\": {\n const changed = changedFields(bag);\n const detail = changed\n .map((f) => {\n const v = bag[f];\n return typeof v === \"object\" ? f : `${f}=${String(v)}`;\n })\n .join(\" \");\n // A payload of only updated_at is a parent-row touch (a note or\n // edge bumped its task). Say so rather than printing nothing.\n return { verb: VERBS[intent], subject, detail: detail === \"\" ? \"(touched)\" : detail };\n }\n case \"task.note\": {\n const author = str(bag, \"author\");\n const content = str(bag, \"content\") ?? \"\";\n const n = key.note;\n const head = n === undefined ? \"\" : `#${n} `;\n const by = author === undefined || author === \"\" ? \"\" : ` by ${author}`;\n return { verb: VERBS[intent], subject, detail: `${head}${oneLine(content)}${by}` };\n }\n case \"task.delete\":\n // Always a tombstone (op='del'), so the payload is '{}' — there is\n // nothing to report beyond the fact of it.\n return { verb: VERBS[intent], subject, detail: \"\" };\n case \"task.close\":\n case \"close.apply\":\n case \"task.open\":\n case \"task.reject\":\n case \"task.defer\": {\n const status = str(bag, \"status\");\n return {\n verb: VERBS[intent],\n subject,\n detail: status === undefined ? \"\" : `→ ${pairText(bag, status)}`,\n };\n }\n case \"task.park\":\n case \"task.unpark\":\n case \"task.accept\": {\n // All three stay OPEN, so the payload carries only the substate.\n const detail = str(bag, \"substate\") === undefined ? \"\" : `→ ${pairText(bag, \"OPEN\")}`;\n return { verb: VERBS[intent], subject, detail };\n }\n case \"task.claim\": {\n // The payload cannot name the actor on the `--self` path (owner_id\n // stays NULL by design), so attribution comes from ops.actor.\n const by = row.source === \"\" ? \"\" : `by ${row.source}`;\n const status = str(bag, \"status\");\n const tail = status === undefined ? \"\" : ` → ${status}`;\n return { verb: VERBS[intent], subject, detail: `${by}${tail}` };\n }\n case \"task.release\":\n case \"task.reap\": {\n const status = str(bag, \"status\");\n const bits: string[] = [];\n if (Object.hasOwn(bag, \"owner_id\") && bag.owner_id === null) bits.push(\"owner cleared\");\n if (status !== undefined) bits.push(`→ ${status}`);\n return { verb: VERBS[intent], subject, detail: bits.join(\" \") };\n }\n case \"task.block\":\n case \"task.unblock\":\n case \"task.reparent\": {\n // Edge ops carry the pair in the key; the task-row op that shares\n // the group is just a touch.\n if (key.to !== undefined) {\n const dir = intent === \"task.unblock\" ? \"no longer blocks\" : \"blocks\";\n return { verb: VERBS[intent], subject, detail: `${dir} ${key.to}` };\n }\n return { verb: VERBS[intent], subject, detail: deleted ? \"(edge removed)\" : \"(touched)\" };\n }\n case \"workstream.init\":\n return { verb: VERBS[intent], subject, detail: \"\" };\n case \"workstream.teardown\":\n return {\n verb: VERBS[intent],\n subject,\n detail: key.local === undefined ? \"\" : \"(cascaded)\",\n };\n case \"sql.write\": {\n // A raw write can hit any portable table, so name the entity and\n // the changed columns (values truncated: a note body is free text).\n if (deleted) return { verb: VERBS[intent], subject, detail: `${row.kind} deleted` };\n const edge = key.to === undefined ? \"\" : ` -> ${key.to}`;\n const changed = changedFields(bag)\n .map((f) => {\n const v = bag[f];\n return typeof v === \"object\" && v !== null ? f : `${f}=${oneLine(String(v))}`;\n })\n .join(\" \");\n return {\n verb: VERBS[intent],\n subject,\n detail: `${row.kind}${edge} ${changed === \"\" ? \"(touched)\" : changed}`,\n };\n }\n // Local intents: no trigger can see these, so `emitEvent` wrote the\n // payload as prose. It is already human-readable — show it as the\n // detail rather than inventing a second phrasing. The leading verb\n // is stripped so it is not printed twice.\n case \"agent.spawn\":\n case \"agent.spawn_failed\":\n case \"agent.close\":\n case \"agent.adopt\":\n case \"agent.kick\":\n case \"agent.send\":\n case \"agent.abort\":\n case \"agent.stall\": {\n const verb = VERBS[intent];\n // These payloads are prose by construction (emitEvent writes them).\n // Guard anyway: a JSON payload here would otherwise be dumped raw\n // into the line, and \"no raw JSON in mu log\" is a hard property.\n if (row.payload.startsWith(\"{\")) {\n const named = str(bag, \"name\") ?? subject;\n return { verb, subject: named, detail: changedFields(bag).join(\" \") };\n }\n const prose = row.payload.startsWith(verb)\n ? row.payload.slice(verb.length).trim()\n : row.payload;\n const firstSpace = prose.indexOf(\" \");\n const name = firstSpace === -1 ? prose : prose.slice(0, firstSpace);\n const rest = firstSpace === -1 ? \"\" : prose.slice(firstSpace + 1).trim();\n return { verb, subject: name, detail: rest };\n }\n }\n}\n\n/** \"CLOSED/wontfix\", or bare \"CLOSED\" for a default substate. */\nfunction pairText(bag: Record<string, unknown>, status: string): string {\n const pair = resolvePair(status, str(bag, \"substate\"));\n return pair === null ? status : formatPair(pair);\n}\n\n/** Collapse whitespace so free text is one line. Never shortens it: a record's\n * length is bounded (and its cut counted) at the output boundary, not here. */\nfunction oneLine(text: string): string {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Render an op as a single plain-text string. The convenience form for\n * callers that don't colour the verb separately (JSON `rendered` field,\n * TUI cards with their own column layout).\n */\nexport function renderOpLine(row: RenderableOp): string {\n const r = renderOp(row);\n if (r === null) return row.payload;\n return [r.verb, r.subject, r.detail].filter((s) => s !== \"\").join(\" \");\n}\n\n/**\n * The entity a row is about, for building a \"show me this\" command.\n * Reads `intent` + `key`, never prose.\n */\nexport function opSubject(row: RenderableOp): { kind: \"task\" | \"agent\"; id: string } | null {\n const intent = row.intent;\n if (intent === null) return null;\n const { local } = parseOpKey(row.workstreamName);\n if (intent.startsWith(\"task.\") && local !== undefined && local !== \"\") {\n return { kind: \"task\", id: local };\n }\n if (intent.startsWith(\"agent.\") && isKnownIntent(intent)) {\n const r = renderOp(row);\n if (r !== null && r.subject !== \"\") return { kind: \"agent\", id: r.subject };\n }\n return null;\n}\n","// mu wire contract: the one JSON document a `--json` invocation prints.\n//\n// success {\"ok\":true,\"data\":<payload>,\"next\":null}\n// failure {\"ok\":false,\"error\":<class>,\"message\":<one line>,\"next\":null,\"exit\":<n>}\n//\n// Both go to STDOUT (a failure with the real non-zero exit), so\n// `2>/dev/null` loses nothing. NDJSON log rows are not enveloped.\n//\n// Pure: no I/O, no mux, no DB. cli.ts (emitJson) and cli/handle.ts\n// (emitError) are the only writers.\n\n/** A follow-up plan: `seq` runs in order and is never truncated; `alt` offers alternatives. */\nexport type NextPlan = { mode: \"seq\" | \"alt\"; commands: string[] } | null;\n\nexport type Envelope<T> =\n | { ok: true; data: T; next: NextPlan }\n | {\n ok: false;\n error: string;\n message: string;\n next: NextPlan;\n /** The real process exit code that follows. */\n exit: number;\n /** Structured receipts kept beside the fixed keys (msgId, incarnation, delivery, usage…). */\n extra?: Record<string, unknown>;\n /** Partial evidence the failed verb already produced (a spawn whose --send failed). */\n data?: T;\n };\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching SGR escapes is the point\nconst SGR = /\\u001b\\[[0-9;]*m/g;\nconst stripAnsi = (s: string): string => s.replace(SGR, \"\");\n\n/**\n * Re-escape the characters JSON.stringify leaves raw but a terminal or line\n * tool treats specially (DEL, C1 controls incl. 8-bit CSI/NEL, bidi controls,\n * U+2028/9) as `\\uXXXX` JSON escapes: still valid, lossless JSON, one inert line.\n */\nexport function safeJsonLine(json: string): string {\n return json.replace(\n /[\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069]/gu,\n (c) => `\\\\u${(c.codePointAt(0) ?? 0).toString(16).padStart(4, \"0\")}`,\n );\n}\n\n/**\n * One line of JSON, no trailing newline, inert (see safeJsonLine). Every JSON\n * document goes through here, so a size measured on this string is the size emitted.\n * Error text is ANSI-free; `extra` never shadows a fixed key.\n */\nexport function encodeEnvelope<T>(envelope: Envelope<T>): string {\n return safeJsonLine(encodeEnvelopeRaw(envelope));\n}\n\nfunction encodeEnvelopeRaw<T>(envelope: Envelope<T>): string {\n if (envelope.ok) {\n return JSON.stringify({ ok: true, data: envelope.data, next: envelope.next });\n }\n const { extra, data } = envelope;\n const doc: Record<string, unknown> = {\n ok: false,\n error: stripAnsi(envelope.error),\n message: stripAnsi(envelope.message),\n next: envelope.next,\n exit: envelope.exit,\n };\n for (const [k, v] of Object.entries(extra ?? {})) if (!(k in doc)) doc[k] = v;\n if (data !== undefined && !(\"data\" in doc)) doc.data = data;\n return JSON.stringify(doc);\n}\n\n/** True only for an explicit success envelope: exactly `ok:true`, `data`, `next`. Never sniffs `data.ok`. */\nexport function isEnvelope(value: unknown): value is Extract<Envelope<unknown>, { ok: true }> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n return (\n keys.length === 3 &&\n (value as { ok?: unknown }).ok === true &&\n \"data\" in value &&\n \"next\" in value\n );\n}\n\n/** Wrap a payload as a success envelope exactly once (an envelope passes through). */\nexport function okEnvelope<T>(data: T): Extract<Envelope<T>, { ok: true }> {\n if (isEnvelope(data)) return data as Extract<Envelope<T>, { ok: true }>;\n return { ok: true, data, next: null };\n}\n\n/** Default byte budget for one result. */\nexport const RESULT_BYTES = 4096;\n","// mu — the durable human-needed stop (`mu human-needed <reason>`).\n//\n// The state-armed loop stops for exactly one reason of its own: a person must\n// decide. The caller records that explicitly; no error or refusal does.\n// A need is a `human` task, OPEN/parked (never ready, never auto, never\n// claimed: HumanTaskError), whose brief note holds the reason. Its caller\n// lives in the machine-local `human_needs` row (rebuild cannot restore it;\n// a note author is never trusted for ownership). The task closes only by an\n// explicit `mu task close`.\n//\n// `stop: false` (`--no-stop`) records a human item that is NOT a stop: the\n// same `human` task with no `human_needs` row, so the settle, `mu next` and\n// the hints never see it. The dashboard's attention lists it like any OPEN\n// human task. One task per reason; an identical open one is a no-op.\n\nimport { type Db, resolveWorkstreamId } from \"./db.js\";\nimport { withOpContext } from \"./op-context.js\";\nimport { addTasks, insertNote } from \"./tasks/edit.js\";\n\n/** A blank reason or caller: nothing is recorded (exit 2). */\nexport class HumanNeededInvalidError extends Error {\n override readonly name = \"HumanNeededInvalidError\";\n}\n\nexport interface HumanNeededOptions {\n workstream: string;\n /** Who is stopping: `spawnerFromEnv()` (managed `<ws>/<agent>` or `pi:<session>`). */\n caller: string;\n reason: string;\n /** false: a human item that never stops the loop (no `human_needs` row). Default true. */\n stop?: boolean;\n}\n\nexport interface HumanNeeded {\n workstream: string;\n id: string;\n reason: string;\n}\n\nconst TITLE_CHARS = 60;\n\n/**\n * Record (or extend) the caller's open human need in a workstream, in ONE\n * transaction. Same caller + workstream with an open need: the same reason\n * is a no-op (`changed: false`), a different one appends a brief to it.\n */\nexport function recordHumanNeeded(\n db: Db,\n opts: HumanNeededOptions,\n): { id: string; changed: boolean } {\n const reason = opts.reason.trim();\n const caller = opts.caller.trim();\n if (reason === \"\") throw new HumanNeededInvalidError(\"human-needed: reason is blank\");\n if (caller === \"\") {\n throw new HumanNeededInvalidError(\n \"human-needed: no caller identity (run inside a mu agent or a pi session)\",\n );\n }\n return withOpContext(db, { intent: \"task.note\", actor: caller, group: \"new\" }, () =>\n db\n .transaction(() => {\n if (opts.stop === false) {\n const same = openItemWith(db, opts.workstream, reason);\n if (same !== undefined) return { id: same, changed: false };\n return { id: addHumanTask(db, opts.workstream, caller, reason), changed: true };\n }\n const open = openNeedFor(db, caller, opts.workstream);\n if (open !== undefined) {\n if (open.briefs.includes(reason)) return { id: open.id, changed: false };\n insertNote(db, open.id, reason, {\n workstream: opts.workstream,\n author: caller,\n kind: \"brief\",\n });\n return { id: open.id, changed: true };\n }\n const id = addHumanTask(db, opts.workstream, caller, reason);\n const taskId = (\n db\n .prepare(\"SELECT id FROM tasks WHERE workstream_id = ? AND local_id = ?\")\n .get(resolveWorkstreamId(db, opts.workstream), id) as { id: number }\n ).id;\n db.prepare(\"INSERT INTO human_needs (task_id, caller) VALUES (?, ?)\").run(taskId, caller);\n return { id, changed: true };\n })\n .immediate(),\n );\n}\n\n/** Add the parked `human` task (title from the reason, brief = reason); its local id. */\nfunction addHumanTask(db: Db, workstream: string, caller: string, reason: string): string {\n const title = `human needed: ${reason.replace(/\\s+/g, \" \").slice(0, TITLE_CHARS)}`;\n const { ids } = addTasks(db, [{ title, note: reason }], {\n workstream,\n kind: \"human\",\n noteAuthor: caller,\n });\n const id = ids[0];\n if (id === undefined) throw new Error(\"recordHumanNeeded: no task created\");\n return id;\n}\n\n/** An OPEN `human` item (no stop row) in `workstream` whose first brief is `reason`. */\nfunction openItemWith(db: Db, workstream: string, reason: string): string | undefined {\n const row = db\n .prepare(\n `SELECT t.local_id AS id\n FROM tasks t\n JOIN workstreams w ON w.id = t.workstream_id\n WHERE w.name = ? AND t.kind = 'human' AND t.status = 'OPEN'\n AND NOT EXISTS (SELECT 1 FROM human_needs h WHERE h.task_id = t.id)\n AND (SELECT n.content FROM task_notes n\n WHERE n.task_id = t.id AND n.kind = 'brief' ORDER BY n.id LIMIT 1) = ?\n LIMIT 1`,\n )\n .get(workstream, reason) as { id: string } | undefined;\n return row?.id;\n}\n\ninterface OpenNeedRow {\n taskId: number;\n id: string;\n workstream: string;\n}\n\nfunction openNeedRows(db: Db, caller: string, workstream?: string): OpenNeedRow[] {\n return db\n .prepare(\n `SELECT t.id AS taskId, t.local_id AS id, w.name AS workstream\n FROM human_needs h\n JOIN tasks t ON t.id = h.task_id\n JOIN workstreams w ON w.id = t.workstream_id\n WHERE h.caller = ? AND t.kind = 'human' AND t.status = 'OPEN'\n AND w.torn_down_at IS NULL AND (? IS NULL OR w.name = ?)\n ORDER BY t.id`,\n )\n .all(caller, workstream ?? null, workstream ?? null) as OpenNeedRow[];\n}\n\nfunction briefsOf(db: Db, taskId: number): string[] {\n return (\n db\n .prepare(\"SELECT content FROM task_notes WHERE task_id = ? AND kind = 'brief' ORDER BY id\")\n .all(taskId) as { content: string }[]\n ).map((r) => r.content);\n}\n\nfunction openNeedFor(\n db: Db,\n caller: string,\n workstream: string,\n): { id: string; briefs: string[] } | undefined {\n const row = openNeedRows(db, caller, workstream).at(-1);\n return row === undefined ? undefined : { id: row.id, briefs: briefsOf(db, row.taskId) };\n}\n\n/** The caller's OPEN human needs, oldest first, across workstreams. Another\n * caller's need never appears. Reasons of an extended need join with \"; \". */\nexport function openHumanNeeds(db: Db, caller: string): HumanNeeded[] {\n return openNeedRows(db, caller).map((r) => ({\n workstream: r.workstream,\n id: r.id,\n reason: briefsOf(db, r.taskId).join(\"; \"),\n }));\n}\n","// mu — `computeNext`: the ONE rule set behind every `next` (slice A of v_hints).\n//\n// A result's `next` (src/output-contract.ts `NextPlan`) is computed here, over\n// current state plus what the verb that just ran did (`NextOutcome`), and\n// nowhere else. The dashboard asks the same function with no outcome.\n//\n// Contract (docs/reference/surface-contract.md \"Next\"):\n// - READ-ONLY. It reads SQLite (and, through `expectsCtl`, whether a control\n// socket file exists). It never waits, registers, reaps, ingests, spawns or\n// runs what it suggests; it never consumes a cursor.\n// - Only state-advancing moves that are already authorised: the exact wait a\n// send owes, the stored resume of a wait, the apply of a preview (fenced\n// with `--if <rev>`), the brief a `claim --for` owes, `mu next` over tasks\n// the orchestrator authorised HERE, and the bare wait over refs the\n// callers already own. Reads (show/notes/list/read/log/check-by-guess) are\n// never suggested. Usually the plan is null.\n// - A move mu cannot fill is omitted: no `<…>`, `...`, `a|b`, no guessed flag\n// (`agent check` has no `--inc`, so an unknown delivery is suggested only\n// while the registry row the send went to is still the one registered).\n// - Never a resend. A refused delegate call is reissued by the pi tool\n// `mu_delegate_reissue`, not a shell, so it is never in `next`.\n// - Executable as printed: every command is an argv rendered word by word\n// with `shellWord` (POSIX single quotes). Safe moves rank before\n// destructive ones; a destructive move without `--if` is refused here.\n// - `seq` is never truncated: `capPlan` drops a too-big seq whole, and cuts\n// an `alt` from its tail.\n\nimport { expectsCtl } from \"./agents/transport.js\";\nimport { getAgent } from \"./agents.js\";\nimport { pendingAttempts } from \"./auto-attempt.js\";\nimport type { Db } from \"./db.js\";\nimport { openHumanNeeds } from \"./human-needed.js\";\nimport type { NextPlan } from \"./output-contract.js\";\nimport { shellWord } from \"./shell-quote.js\";\nimport { authorisedReady } from \"./task-auto.js\";\nimport { readWaitRegistration } from \"./wait-registration.js\";\nimport { isScratchWorkstream } from \"./workstream.js\";\n\n/** An agent as a hint names it: its workstream and name. */\nexport interface NextAgent {\n workstream: string;\n name: string;\n}\n\n/** What the verb that just ran did, as far as a follow-up depends on it. */\nexport type NextOutcome =\n /** A delivered send (also `spawn --send`/`--task`, `--fresh`, `--interrupt`): the baseline the SEND measured. */\n | { kind: \"sent\"; agent: NextAgent; runs?: number; incarnation?: string }\n /** A send written but unconfirmed: `msgId` and the registry id (`AgentRow.incarnation`) it went to. */\n | { kind: \"send-unknown\"; agent: NextAgent; msgId: string; agentId: number }\n /** A remote command gate spawned: its wait returns the command's exit. */\n | { kind: \"gate-spawned\"; agent: NextAgent }\n /** `task claim --for`: the owner still has to be sent the task. `muxCanSend: false` (tmux):\n * a non-pi owner cannot be sent anything, so no send is offered. */\n | {\n kind: \"claimed-for\";\n task: { workstream: string; id: string };\n owner: NextAgent;\n muxCanSend?: boolean;\n }\n /** A destructive preview: `apply` is the verb's argv (from `mu`), `revision` its fence. */\n | { kind: \"preview\"; apply: readonly string[]; revision: number }\n /** A wait ended with something still owed: its stored handle. */\n | { kind: \"waited\"; resumeId: string | null; scope?: string };\n\nexport interface NextContext {\n /** `currentCallers()`: the managed `<ws>/<agent>` and `pi:<session>`. Empty = no owned work. */\n callers: readonly string[];\n /** The resolved scope of the call, when it has one. */\n workstream?: string;\n outcome?: NextOutcome;\n /**\n * Whether the verb that just ran registered owed work (`armWait`). The CLI passes it, so\n * the bare wait follows only a command that created something to wait for; a read or an\n * unrelated write is not followed by it. Absent (the dashboard, no verb): any owed ref counts.\n */\n armed?: boolean;\n}\n\n/** One move: the argv as typed (`mu` first). Destructive moves must carry `--if`. */\nexport interface HintMove {\n argv: readonly string[];\n destructive?: boolean;\n}\n\n/** A destructive move without its revision fence. */\nexport class UnguardedMoveError extends Error {\n override readonly name = \"UnguardedMoveError\";\n}\n\n/** The `next` byte budget, a share of the 4 KB result (`RESULT_BYTES`). */\nexport const NEXT_BYTES = 1024;\n\n/** The most alternatives one plan offers. */\nexport const MAX_ALTERNATIVES = 3;\n\n/** The prompt that hands a claimed task to its owner. Message text (v_hint_messages owns the wording). */\nexport function dispatchPrompt(task: { workstream: string; id: string }): string {\n return `Claim done: work on ${task.id}. Read: mu task notes ${task.id} -w ${task.workstream}`;\n}\n\n/** `agent:<ws>/<name>[@<runs>][#<incarnation>]`: the typed ref a wait takes. */\nexport function agentRefOf(\n agent: { name: string; workstreamName: string },\n runs?: number,\n incarnation?: string,\n): string {\n return `agent:${agent.workstreamName}/${agent.name}${runs === undefined ? \"\" : `@${runs}`}${incarnation === undefined ? \"\" : `#${incarnation}`}`;\n}\n\n/** The one resume of a stored wait handle (`mu wait --resume <id>`), as argv. */\nexport function resumeArgv(id: string, scope?: string): string[] {\n return [\"mu\", \"wait\", \"--resume\", id, ...(scope === undefined ? [] : [\"-w\", scope])];\n}\n\n/** One command line, each word POSIX-quoted only when it needs it. */\nexport function renderArgv(argv: readonly string[]): string {\n if (argv[0] !== \"mu\") throw new Error(`a next move starts with mu (got ${argv[0] ?? \"nothing\"})`);\n return argv.map(shellWord).join(\" \");\n}\n\n/**\n * The plan for `moves` in order: safe moves first (stable), duplicates dropped, at most\n * MAX_ALTERNATIVES for `alt`. A `seq` is kept whole. null for no moves.\n */\nexport function renderPlan(mode: \"seq\" | \"alt\", moves: readonly HintMove[]): NextPlan {\n for (const m of moves) {\n if (m.destructive === true && !m.argv.includes(\"--if\")) {\n throw new UnguardedMoveError(`destructive move without --if: ${m.argv.join(\" \")}`);\n }\n }\n const ordered = mode === \"seq\" ? moves : [...moves].sort((a, b) => rank(a) - rank(b));\n const commands = [...new Set(ordered.map((m) => renderArgv(m.argv)))];\n const kept = mode === \"alt\" ? commands.slice(0, MAX_ALTERNATIVES) : commands;\n return kept.length === 0 ? null : { mode, commands: kept };\n}\n\nconst rank = (m: HintMove): number => (m.destructive === true ? 1 : 0);\n\nconst utf8 = (s: string): number => Buffer.byteLength(s, \"utf8\");\n\n/**\n * Fit a plan into `bytes` (its JSON encoding). A `seq` that does not fit is dropped WHOLE\n * (never a partial sequence); an `alt` loses alternatives from its tail. `cut` counts the\n * commands left out.\n */\nexport function capPlan(plan: NextPlan, bytes = NEXT_BYTES): { next: NextPlan; cut: number } {\n if (plan === null || utf8(JSON.stringify(plan)) <= bytes) return { next: plan, cut: 0 };\n if (plan.mode === \"seq\") return { next: null, cut: plan.commands.length };\n const commands = [...plan.commands];\n while (commands.length > 0 && utf8(JSON.stringify({ mode: \"alt\", commands })) > bytes) {\n commands.pop();\n }\n const cut = plan.commands.length - commands.length;\n return { next: commands.length === 0 ? null : { mode: \"alt\", commands }, cut };\n}\n\n/** The follow-up of what the verb did: at most one move, none when mu cannot fill it. */\nfunction outcomeMove(db: Db, o: NextOutcome): HintMove | undefined {\n switch (o.kind) {\n case \"sent\":\n if (o.runs === undefined) return undefined; // a mux send or a slash command started no fenced run\n return {\n argv: [\"mu\", \"wait\", agentRefOf(agentLike(o.agent), o.runs, o.incarnation)],\n };\n case \"send-unknown\": {\n // The receipt route, never a resend. `agent check` probes the name's CURRENT socket and has\n // no incarnation flag, so it is offered only while the row the send went to is still there.\n const row = getAgent(db, o.agent.name, o.agent.workstream);\n if (row === undefined || row.incarnation !== o.agentId) return undefined;\n return {\n argv: [\"mu\", \"agent\", \"check\", o.agent.name, o.msgId, \"-w\", o.agent.workstream, \"--json\"],\n };\n }\n case \"gate-spawned\":\n return { argv: [\"mu\", \"wait\", agentRefOf(agentLike(o.agent))] };\n case \"claimed-for\": {\n const owner = getAgent(db, o.owner.name, o.owner.workstream);\n if (owner === undefined) return undefined;\n const ctl = expectsCtl(owner);\n if (!ctl && o.muxCanSend === false) return undefined;\n const fresh = ctl ? [\"--fresh\"] : [];\n return {\n argv: [\n \"mu\",\n \"agent\",\n \"send\",\n owner.name,\n ...fresh,\n dispatchPrompt(o.task),\n \"-w\",\n owner.workstreamName,\n ],\n };\n }\n case \"preview\":\n return { argv: [...o.apply, \"--if\", String(o.revision)], destructive: true };\n case \"waited\":\n if (o.resumeId === null) return undefined;\n return { argv: resumeArgv(o.resumeId, o.scope) };\n }\n}\n\nconst agentLike = (a: NextAgent) => ({ name: a.name, workstreamName: a.workstream });\n\n/** Authorised work this machine's executor would act on now (stored attempts or ready auto tasks). */\nfunction executorMove(db: Db, ws: string): HintMove | undefined {\n if (isScratchWorkstream(ws)) return undefined;\n if (pendingAttempts(db, ws).length === 0 && authorisedReady(db, ws).length === 0) {\n return undefined;\n }\n return { argv: [\"mu\", \"next\", \"-w\", ws] };\n}\n\n/** The callers own registered refs (in `ws` when scoped): the bare wait picks them up. */\nfunction ownedWaitMove(db: Db, callers: readonly string[], ws?: string): HintMove | undefined {\n const owes = callers.some((c) =>\n (readWaitRegistration(db, c)?.refs ?? []).some((r) => ws === undefined || r.workstream === ws),\n );\n if (!owes) return undefined;\n return { argv: ws === undefined ? [\"mu\", \"wait\"] : [\"mu\", \"wait\", \"-w\", ws] };\n}\n\n/** A course check is due after this many CLOSED/done work tasks since the last one... */\nexport const COURSE_CHECK_CLOSED = 10;\n/** ...or this long since it (with at least one closed since). Constants: no flag, no env. */\nexport const COURSE_CHECK_AGE_MS = 24 * 3600_000;\n\n/**\n * The course-correct trigger (skills/mu/recipes/course-correct.md), read from\n * state, never remembered: since the newest note of `ws` starting `COURSE CHECK` (none: the\n * workstream's creation), count the CLOSED/done work tasks by their close note's time (a later\n * note does not move it). One line when due, else undefined.\n * Read-only; one query.\n */\nexport function courseCheckHint(db: Db, ws: string, now = Date.now()): string | undefined {\n const row = db\n .prepare(\n `WITH w AS (SELECT id, created_at FROM workstreams WHERE name = ? AND torn_down_at IS NULL),\n a AS (SELECT COALESCE(\n (SELECT MAX(n.created_at) FROM task_notes n JOIN tasks t ON t.id = n.task_id\n WHERE t.workstream_id = w.id AND n.content LIKE 'COURSE CHECK%'),\n w.created_at) AS since, w.id AS wid FROM w)\n SELECT a.since AS since,\n (SELECT COUNT(*) FROM tasks t WHERE t.workstream_id = a.wid AND t.status = 'CLOSED'\n AND t.substate = 'done' AND t.kind = 'work' AND (SELECT MAX(c.created_at)\n FROM task_notes c WHERE c.task_id = t.id AND c.kind = 'close') > a.since) AS closed\n FROM a`,\n )\n .get(ws) as { since: string; closed: number } | undefined;\n if (row === undefined || row.closed === 0) return undefined;\n const old = now - Date.parse(row.since) >= COURSE_CHECK_AGE_MS;\n if (row.closed < COURSE_CHECK_CLOSED && !old) return undefined;\n return `course check due: ${row.closed} closed since ${row.since.slice(0, 16)}Z. Stop dispatching: finish merging, then follow recipes/course-correct.md`;\n}\n\n/**\n * The `next` of a result: the outcome's own follow-up first, then (unless a caller has an\n * open human need, which stops everything it would start) `mu next` over authorised work and\n * the bare wait over owned refs (only after a verb that armed one), as alternatives. A preview's apply ranks last. Read-only.\n */\nexport function computeNext(db: Db, ctx: NextContext): NextPlan {\n const moves: HintMove[] = [];\n const own = ctx.outcome === undefined ? undefined : outcomeMove(db, ctx.outcome);\n if (own !== undefined) moves.push(own);\n const stopped = ctx.callers.some((c) => openHumanNeeds(db, c).length > 0);\n if (!stopped && ctx.outcome?.kind !== \"preview\") {\n const exec = ctx.workstream === undefined ? undefined : executorMove(db, ctx.workstream);\n if (exec !== undefined) moves.push(exec);\n // The bare wait is redundant beside a more exact wait.\n if (ctx.armed !== false && (own === undefined || own.argv[1] !== \"wait\")) {\n const wait = ownedWaitMove(db, ctx.callers, ctx.workstream);\n if (wait !== undefined) moves.push(wait);\n }\n }\n return capPlan(renderPlan(\"alt\", moves)).next;\n}\n\n/**\n * The one-line notices of a result, beside its `next` (they are not commands): today only\n * `courseCheckHint` for the call's workstream. `mu state` and `mu wait` print them as\n * `data.notices` (`noticesField`); empty when nothing is due. Read-only.\n */\nexport function computeNotices(db: Db, ctx: NextContext, now = Date.now()): string[] {\n const hint =\n ctx.workstream === undefined || isScratchWorkstream(ctx.workstream)\n ? undefined\n : courseCheckHint(db, ctx.workstream, now);\n return hint === undefined ? [] : [hint];\n}\n\n/** `computeNotices` over each workstream a result covers, in order, as `data.notices` (absent when empty). */\nexport function noticesField(\n db: Db,\n workstreams: readonly string[],\n now = Date.now(),\n): { notices?: string[] } {\n const notices = [...new Set(workstreams)].flatMap((workstream) =>\n computeNotices(db, { callers: [], workstream }, now),\n );\n return notices.length > 0 ? { notices } : {};\n}\n","// mu — the sync seam: peer status, the ambient hook, and the two power\n// tools behind `mu sync`.\n//\n// WHAT LIVES HERE AND WHAT DOES NOT\n// ---------------------------------\n// `src/segments.ts` owns the MECHANISM (flush / ingest / watermarks /\n// the four robustness layers). This file owns the OPERATOR-FACING\n// questions that mechanism cannot answer on its own:\n//\n// - who are my peers, how far behind am I, when did I last hear from\n// them (`peerStatuses`)\n// - the AMBIENT hook every mu invocation runs (`ambientIngest` /\n// `ambientFlush`)\n// - a DIFFERENT READER: a peer's `ops` table read straight out of a\n// copied / sshfs-mounted `mu.db` (`ingestFromDb`)\n// - the universal repair: reset a watermark and re-read from zero\n// (`repairPeer`)\n//\n// AMBIENT, NOT A DAEMON\n// ---------------------\n// There is no watcher, no background process, and no polling loop that\n// outlives the command. Sync happens because you already run `mu`\n// constantly: every invocation ingests before the verb body and flushes\n// after it. With `MU_SYNC_DIR` unset both halves are a single `if` that\n// reads one env var, so the single-machine case pays nothing. With 2-5\n// peers it is a handful of `stat`/`read` calls on small append-only\n// files.\n//\n// The TUI is the one long-lived surface, and it hangs the same pass off\n// its SLOW tick (10s), never the 1s fast tick — sync is filesystem work\n// and has no business on a repaint cadence.\n//\n// SYNC MUST NEVER FAIL A COMMAND\n// ------------------------------\n// A truncated segment, an unreadable sync dir, a full disk: all of them\n// warn and return. `mu task add` has to work when sync is broken,\n// because the alternative is a tool that stops working when a folder you\n// do not control misbehaves. Every ambient entry point here is\n// try/catch-total by construction (see `ambientIngest`).\n//\n// TRANSPORT STAYS THE OPERATOR'S\n// ------------------------------\n// mu reads and writes FILES. It does not shell out to ssh/scp/rsync, and\n// it will not grow `--push <host>`: that is a remote backend wearing a\n// small hat (ssh config, jump hosts, ProxyCommand, ports, identity\n// files, interactive prompts inside a TUI tick, network-vs-auth error\n// mapping), and it violates the standing ROADMAP pledge that the user\n// owns transport. `mu sync` reports a stale peer (`stale: true`); moving\n// its segment (Syncthing, rsync, a USB stick) is the operator's.\n\nimport { existsSync, statSync } from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type { Op } from \"./apply.js\";\nimport { CURRENT_SCHEMA_VERSION, type Db, SYNCED_ENTITIES } from \"./db.js\";\nimport { say } from \"./messages.js\";\nimport { isJsonMode } from \"./output.js\";\nimport {\n applyIncomingOp,\n discoverPeers,\n type FlushResult,\n flushSegment,\n getWatermark,\n type IngestResult,\n ingestSegment,\n localMachineId,\n peerWatermarkKey,\n resetWatermark,\n type SegmentDefect,\n segmentCaughtUp,\n segmentLineCount,\n syncDir,\n} from \"./segments.js\";\n\n/** No discovered peer matches the operator's `--repair <peer>` ref.\n * Exit 3 (not found), like every other resolve-time miss. */\nexport class SyncPeerNotFoundError extends Error {\n override readonly name = \"SyncPeerNotFoundError\";\n constructor(\n readonly ref: string,\n readonly known: readonly string[],\n ) {\n super(say(\"sync.peer_not_found\", ref, known));\n }\n}\n\n/** A `--repair <peer>` prefix matched several peers. A conflict (exit 4),\n * never a guess — the same rule `mu log --group` follows for\n * abbreviated group ids. */\nexport class SyncPeerRefAmbiguousError extends Error {\n override readonly name = \"SyncPeerRefAmbiguousError\";\n constructor(\n readonly ref: string,\n readonly candidates: readonly string[],\n ) {\n super(say(\"sync.peer_ambiguous\", ref, candidates));\n }\n}\n\n/** `mu sync --from <path>` pointed at a file that is not there. Exit 3. */\nexport class SyncSourceNotFoundError extends Error {\n override readonly name = \"SyncSourceNotFoundError\";\n constructor(readonly path: string) {\n super(say(\"sync.source_missing\", path));\n }\n}\n\n/** `mu sync --from <db>` pointed at a DB written by a newer mu. Its ops\n * may carry fields this build would half-apply, which is exactly what a\n * segment line's version prevents; this path has no such line. Exit 4. */\nexport class SyncSourceTooNewError extends Error {\n override readonly name = \"SyncSourceTooNewError\";\n constructor(\n readonly path: string,\n readonly detectedVersion: number,\n ) {\n super(say(\"sync.source_too_new\", path, detectedVersion, CURRENT_SCHEMA_VERSION));\n }\n}\n\n/** A peer whose segment has not moved in this long is reported STALE.\n * A fixed constant, not an env var: it is a display threshold, and mu's\n * whole cluster configuration is deliberately ONE env var. */\nexport const PEER_STALE_MS = 24 * 60 * 60 * 1000;\n\n/** How many characters of a `machine_id` uuid we show. Peers are known\n * only by uuid — `machine_identity.hostname` is machine-LOCAL and never\n * ships, so mu genuinely cannot render a peer's hostname without\n * inventing a membership file. A short prefix is the honest display,\n * and every verb that takes one accepts any unique prefix (the\n * affordance git gives for shas). */\nexport const PEER_SHORT_LEN = 8;\n\nexport interface PeerStatus {\n machineId: string;\n /** First `PEER_SHORT_LEN` chars of the machine id, for display. */\n short: string;\n path: string;\n /** True for a Syncthing-style `*.sync-conflict-*.jsonl` copy. */\n conflictCopy: boolean;\n /** `sync_peers` key of this file's watermark (see `PeerSegment`).\n * `peerStatuses` always sets it. Optional so SDK callers that build\n * the pre-watermarkKey shape still compile; absent means the machine\n * id (`peerWatermarkKey`). */\n watermarkKey?: string;\n /** Lines of this segment file already applied. */\n watermark: number;\n /** GOOD lines currently in the segment (a defect stops the count). */\n total: number;\n /** `total - watermark`: how much of what we HOLD is not yet applied.\n * Non-zero after a defect stopped an ingest short, or mid-transfer. */\n behind: number;\n /** Segment mtime in epoch ms — when transport last delivered. */\n lastSeenMs: number | null;\n /** Age of the segment file, ms. Null when it does not exist. */\n ageMs: number | null;\n stale: boolean;\n}\n\n/** Peer table for the sync dir, newest contact first. Pure read: it\n * neither flushes nor ingests, so `mu sync` can call it after its own\n * pass and the TUI could call it on a tick. */\nexport function peerStatuses(db: Db, dir: string): PeerStatus[] {\n const self = localMachineId(db);\n const now = Date.now();\n const rows = discoverPeers(dir, self).map((peer) => {\n let lastSeenMs: number | null = null;\n try {\n lastSeenMs = statSync(peer.path).mtimeMs;\n } catch {\n lastSeenMs = null;\n }\n const watermarkKey = peerWatermarkKey(peer);\n const watermark = getWatermark(db, watermarkKey);\n // Caught up: the count is the watermark, no need to decode the file.\n const total = segmentCaughtUp(db, watermarkKey, peer.path, watermark)\n ? watermark\n : segmentLineCount(peer.path);\n const ageMs = lastSeenMs === null ? null : Math.max(0, now - lastSeenMs);\n return {\n machineId: peer.machineId,\n short: peer.machineId.slice(0, PEER_SHORT_LEN),\n path: peer.path,\n conflictCopy: peer.conflictCopy,\n watermarkKey,\n watermark,\n total,\n behind: Math.max(0, total - watermark),\n lastSeenMs,\n ageMs,\n stale: ageMs === null || ageMs > PEER_STALE_MS,\n };\n });\n return rows.sort((a, b) => (b.lastSeenMs ?? 0) - (a.lastSeenMs ?? 0));\n}\n\n/** Resolve an operator-typed peer reference (full machine id, or any\n * unique prefix) against the discovered peers. Ambiguity is a\n * UsageError, never a guess — repairing the wrong peer would re-read a\n * whole segment for nothing and confuse the report.\n *\n * A ref names a MACHINE, so a segment and its conflict copies (same\n * machine id) count as one match; the peer's own segment is returned\n * when present. Counting them separately made the short id `mu sync`\n * prints unresolvable. */\nexport function resolvePeerRef(peers: readonly PeerStatus[], ref: string): PeerStatus {\n const matches = peers.filter((p) => p.machineId.startsWith(ref));\n const exact = matches.filter((p) => p.machineId === ref);\n const candidates = exact.length > 0 ? exact : matches;\n const machines = [...new Set(candidates.map((p) => p.machineId))];\n const first = candidates.find((p) => !p.conflictCopy) ?? candidates[0];\n if (first === undefined) {\n throw new SyncPeerNotFoundError(\n ref,\n peers.map((p) => p.short),\n );\n }\n if (machines.length > 1) {\n throw new SyncPeerRefAmbiguousError(\n ref,\n machines.map((m) => m.slice(0, PEER_SHORT_LEN)),\n );\n }\n return first;\n}\n\n/** Reset the watermark of every segment file a peer has (its own and\n * any conflict copies) so the next ingest re-reads them from zero. Safe\n * by construction: apply is idempotent and `ops` dedupes on\n * `UNIQUE (machine_id, hlc)`. */\nexport function repairPeer(db: Db, ref: string, dir: string): PeerStatus {\n const peers = peerStatuses(db, dir);\n const peer = resolvePeerRef(peers, ref);\n for (const p of peers) {\n if (p.machineId === peer.machineId) resetWatermark(db, peerWatermarkKey(p));\n }\n return peer;\n}\n\n// ─── the ambient hook ─────────────────────────────────────────────────\n\n/** Is sync configured at all? THE single `if` the no-sync case pays.\n * Callers check this before awaiting anything, so an unconfigured\n * machine allocates no promise and touches no filesystem. */\nexport function syncEnabled(): boolean {\n return syncDir() !== null;\n}\n\nexport interface AmbientResult {\n /** Peers whose segments were read. Empty when sync is off. */\n ingested: readonly IngestResult[];\n /** Non-fatal problems, already warned about. */\n warnings: readonly string[];\n}\n\nexport interface AmbientOptions {\n /** Suppress the stderr warnings. Set by the TUI, which owns the\n * alternate screen — a stray write there paints garbage over the\n * dashboard. The warnings are still returned: the dashboard keeps the\n * latest ones as `sync` attention items until the next ingest. */\n quiet?: boolean;\n}\n\nexport interface AmbientFlushOptions extends AmbientOptions {\n /** How long to wait for the segment lock (default\n * AMBIENT_FLUSH_LOCK_WAIT_MS). On timeout nothing is written; the ops\n * stay in the DB and the next flush appends them. */\n lockWaitMs?: number;\n}\n\n/** Format one non-fatal sync problem for stderr. Prefixed so it is\n * unmistakably mu's own aside and not the verb's output. */\nfunction warn(message: string, opts?: AmbientOptions): void {\n if (opts?.quiet === true) return;\n // --json: stderr stays empty; the ops stay pending and `mu doctor` reports the backlog.\n if (isJsonMode()) return;\n // Deliberately stderr: stdout is the verb's contract (and may be JSON).\n process.stderr.write(`mu: sync: ${message}\\n`);\n}\n\n/** One line for an own segment holding a line of a version this build\n * cannot read (the segment is read-only here until mu is upgraded).\n * Shared by `mu sync`, the ambient warning and `mu doctor`. */\nexport function foreignVersionMessage(r: {\n segmentPath: string | null;\n foreignVersion: number | null;\n}): string {\n return `segment ${r.segmentPath ?? \"?\"} has a v${r.foreignVersion ?? \"?\"} line written by a newer mu; upgrade mu on this machine`;\n}\n\nfunction describeDefects(peerShort: string, defects: readonly SegmentDefect[]): string {\n const first = defects[0];\n const detail = first === undefined ? \"unknown defect\" : `${first.kind} at line ${first.line}`;\n const more = defects.length > 1 ? ` (+${defects.length - 1} more)` : \"\";\n // `--repair` only resets the watermark, so it is advice ONLY for a\n // defect a re-read can get past (a torn write mid-transfer). A refused\n // line is deterministic: re-reading hits the identical line and the\n // hint would be self-referentially useless, which is exactly how the\n // original incident's operator was sent in a circle. A re-delivered\n // op is deterministic for the same reason. So is a manifest mismatch:\n // the file itself is short, re-reading it changes nothing, and only a\n // fresh copy from the peer clears it.\n const skipped = new Set([\"entity-not-synced\", \"duplicate-op\"]);\n const fileWide = new Set([\"manifest-mismatch\"]);\n let hint: string;\n if (defects.every((d) => skipped.has(d.kind))) {\n hint = \" — skipped; the rest of the segment applied\";\n } else if (defects.every((d) => skipped.has(d.kind) || fileWide.has(d.kind))) {\n hint = \" — the file is shorter than its manifest; copy it from the peer again\";\n } else {\n hint = ` — re-read with \\`mu sync --repair ${peerShort}\\``;\n }\n return `peer ${peerShort}: ${detail}${more}${hint}`;\n}\n\n/**\n * INGEST half of the ambient hook: pull every peer segment before the\n * verb body runs, so the command sees the freshest state the filesystem\n * can offer.\n *\n * Total: no input can make this throw. A per-peer failure is isolated so\n * one broken segment cannot hide the others.\n */\nexport async function ambientIngest(db: Db, opts?: AmbientOptions): Promise<AmbientResult> {\n const dir = syncDir();\n if (dir === null) return { ingested: [], warnings: [] };\n const warnings: string[] = [];\n const ingested: IngestResult[] = [];\n try {\n const self = localMachineId(db);\n for (const peer of discoverPeers(dir, self)) {\n try {\n const result = ingestSegment(db, peer);\n ingested.push(result);\n if (result.defects.length > 0) {\n const message = describeDefects(peer.machineId.slice(0, PEER_SHORT_LEN), result.defects);\n warnings.push(message);\n warn(message, opts);\n }\n } catch (err) {\n const message = `peer ${peer.machineId.slice(0, PEER_SHORT_LEN)}: ${err instanceof Error ? err.message : String(err)}`;\n warnings.push(message);\n warn(message, opts);\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n warnings.push(message);\n warn(message, opts);\n }\n // `await` nothing above: ingest is synchronous better-sqlite3 work.\n // The async signature exists so the caller's seam is uniform with\n // ambientFlush (which takes a file lock).\n return { ingested, warnings };\n}\n\n/**\n * FLUSH half of the ambient hook: append this invocation's own ops to\n * this machine's segment AFTER the verb body has committed them.\n *\n * Order matters and is the whole reason the hook is split in two: a\n * flush before the body would leave the ops the operator just wrote\n * sitting unflushed until the NEXT invocation, so `mu task add` on the\n * laptop followed by `mu sync` on the devserver would show nothing —\n * exactly the no-hands claim, broken.\n *\n * Appends under the cross-process file lock inside `flushSegment`, so\n * two concurrent mu processes cannot interleave partial lines. A flush\n * with nothing to append skips the lock, so read-only verbs never queue.\n * A flush that cannot take the lock within AMBIENT_FLUSH_LOCK_WAIT_MS\n * writes nothing (`lockBusy`) and the verb carries on (exit 0) after one\n * stderr line: its ops stay pending in `ops` and the next invocation's\n * flush appends them. `mu doctor` reports the backlog (`unpublished-ops`).\n */\nexport async function ambientFlush(\n db: Db,\n opts?: AmbientFlushOptions,\n): Promise<FlushResult | null> {\n const dir = syncDir();\n if (dir === null) return null;\n try {\n const result = await flushSegment(db, dir, { lockWaitMs: opts?.lockWaitMs });\n if (result.selfRepaired !== null) {\n const d = result.selfRepaired;\n warn(\n `own segment truncated back to its last good line: ${d.kind} at line ${d.line} (${d.detail}) — regenerated from the ops table`,\n opts,\n );\n }\n if (result.foreignVersionAt !== null) warn(foreignVersionMessage(result), opts);\n if (result.lockBusy === true) {\n warn(\"segment locked by another mu; this op publishes on the next flush\", opts);\n }\n return result;\n } catch (err) {\n warn(err instanceof Error ? err.message : String(err), opts);\n return null;\n }\n}\n\n/**\n * Both halves in one call, for a caller that has no before/after seam to\n * straddle — today the TUI's SLOW tick (10s; never the 1s fast tick,\n * which is a repaint cadence and has no business doing filesystem work).\n *\n * Ingest first, then flush: the same order the CLI hook uses, so a\n * long-lived TUI converges on exactly the same schedule as a shell that\n * runs one verb every ten seconds.\n */\nexport async function ambientSyncPass(\n db: Db,\n opts?: AmbientOptions,\n): Promise<{ ingested: readonly IngestResult[]; flushed: FlushResult | null }> {\n if (!syncEnabled()) return { ingested: [], flushed: null };\n const { ingested } = await ambientIngest(db, opts);\n const flushed = await ambientFlush(db, opts);\n return { ingested, flushed };\n}\n\n// ─── `mu sync --from <peer.db>`: a different READER ───────────────────\n\nexport interface IngestFromDbResult {\n path: string;\n /** Ops read out of the peer's `ops` table (already filtered). */\n read: number;\n /** Ops that changed a row here. */\n changed: number;\n /** Ops skipped because their entity is machine-local. */\n skippedLocal: number;\n}\n\n/** The source DB's `schema_version`, or null when it has none (not a mu\n * DB, or one old enough that the ops query below fails on its own). */\nfunction sourceSchemaVersion(source: Database.Database): number | null {\n try {\n const row = source.prepare(\"SELECT version FROM schema_version WHERE id = 1\").get() as\n | { version: number }\n | undefined;\n return row?.version ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Ingest straight from a peer's `mu.db`, reading its `ops` table with\n * SQLite instead of parsing a JSONL segment.\n *\n * WHY THIS EARNS A FLAG when `MU_SYNC_DIR=/mnt/whatever mu state` covers\n * the one-off-directory case: it is a DIFFERENT READER, and nothing\n * about an env var can express it. The file you have is a database, not\n * a segment — because you scp'd it, or because you have the devserver's\n * state dir on sshfs and would rather read the real thing than wait for\n * a flush.\n *\n * Opened `readonly` so mu cannot write to a file it does not own, and\n * `fileMustExist` so a typo'd path is an error rather than a freshly\n * created empty DB.\n *\n * Filters exactly as flush does — `SYNCED_ENTITIES` only, and never the\n * peer's copy of OUR ops (we already have those; `UNIQUE (machine_id,\n * hlc)` would dedupe them anyway, but not reading them is cheaper and\n * keeps the reported count honest). Ops the peer itself ingested from a\n * THIRD machine are read, which is how transitive convergence falls out\n * for free.\n *\n * Watermarks are deliberately untouched: a watermark counts LINES of a\n * segment, and a DB has no such coordinate. The next segment ingest for\n * that peer re-reads from wherever it was, applies the same ops again,\n * and changes nothing — idempotence is what makes leaving it alone safe.\n */\nexport function ingestFromDb(db: Db, path: string): IngestFromDbResult {\n if (!existsSync(path)) throw new SyncSourceNotFoundError(path);\n const self = localMachineId(db);\n const source = new Database(path, { readonly: true, fileMustExist: true });\n try {\n const theirs = sourceSchemaVersion(source);\n if (theirs !== null && theirs > CURRENT_SCHEMA_VERSION) {\n throw new SyncSourceTooNewError(path, theirs);\n }\n const rows = source\n .prepare(\n `SELECT hlc, machine_id, group_id, actor, intent, entity, key, op, payload\n FROM ops\n WHERE machine_id != ?\n ORDER BY hlc`,\n )\n .all(self) as Array<{\n hlc: string;\n machine_id: string;\n group_id: string;\n actor: string | null;\n intent: string | null;\n entity: string;\n key: string;\n op: string;\n payload: string;\n }>;\n\n const synced = new Set<string>(SYNCED_ENTITIES);\n let read = 0;\n let changed = 0;\n let skippedLocal = 0;\n const run = db.transaction(() => {\n for (const row of rows) {\n if (!synced.has(row.entity)) {\n skippedLocal += 1;\n continue;\n }\n const op: Op = {\n hlc: row.hlc,\n machineId: row.machine_id,\n groupId: row.group_id,\n actor: row.actor,\n intent: row.intent,\n entity: row.entity,\n key: row.key,\n op: row.op === \"del\" ? \"del\" : \"put\",\n payload: row.payload,\n };\n const result = applyIncomingOp(db, op);\n read += 1;\n if (result.changed) changed += 1;\n }\n });\n run.immediate();\n return { path, read, changed, skippedLocal };\n } finally {\n try {\n source.close();\n } catch {\n // best effort\n }\n }\n}\n","// mu — who \"I\" am for a wait.\n//\n// One orchestrator is known under two names. The managed `<ws>/<agent>`\n// (`MU_MANAGED_AGENT=1`) owns the workers it spawns and the human stops it\n// records (`spawnerFromEnv`); `pi:<PI_SESSION_ID>` owns the delegate calls it\n// makes (extension/delegate.ts, `mu delegates`). A wait must see both, so a\n// caller is a SET: the union of the two when present. Neither alone, and never\n// a guess (USER, TMUX_PANE) or \"every caller\": an empty set owns nothing.\n\n/** The callers of this process, from its env: managed ws/name first, then pi:<session>. */\nexport function currentCallers(env: NodeJS.ProcessEnv = process.env): string[] {\n const out: string[] = [];\n const { MU_MANAGED_AGENT: managed, MU_WORKSTREAM: ws, MU_AGENT_NAME: name } = env;\n if (managed === \"1\" && ws && name) out.push(`${ws}/${name}`);\n if (env.PI_SESSION_ID) out.push(`pi:${env.PI_SESSION_ID}`);\n return out;\n}\n","// mu — agent output boundary: what `--json` prints for an agent.\n//\n// Pure (no I/O). Keys equal the SQL column names of `agents` and `id` is the\n// real primary key, which IS the registry incarnation (`AgentRow.incarnation`,\n// what `agent close --if` and every destructive write compare; not pi's string\n// `incarnation`). `workstream_id` is the real foreign key; `workstream` is its\n// name. Computed live facts (runtime state, ctl link) ride after the columns,\n// snake_cased, only when known. The deprecated `agents.status` column is never\n// emitted. The SDK keeps camelCase `AgentRow`; ONLY the CLI maps (README\n// Interface: output keys equal SQL column names).\n\nimport type { ClosePreview } from \"./agents/close.js\";\nimport type { AgentRow, LiveAgent } from \"./agents.js\";\nimport type { Db } from \"./db.js\";\n\n/** `workstreams.id` for a name, torn down or not (an agent row can outlive its workstream's teardown). */\nexport function workstreamIdOf(db: Db, workstream: string): number {\n const row = db.prepare(\"SELECT id FROM workstreams WHERE name = ?\").get(workstream) as\n | { id: number }\n | undefined;\n return row?.id ?? 0;\n}\n\n/** The live, computed half of an agent record (all optional: only what was read). */\nexport interface AgentLiveFacts {\n state?: string;\n source?: string;\n ctl?: string;\n ctlSocket?: string;\n since?: string | null;\n reason?: string;\n idle?: boolean;\n trustDialog?: boolean;\n}\n\n/** One agent as `--json` emits it. */\nexport interface AgentOutput {\n /** `agents.id`: the registry incarnation. */\n id: number;\n name: string;\n workstream_id: number;\n workstream: string;\n cli: string;\n pane_id: string;\n role: string;\n tab: string | null;\n cwd: string | null;\n base: string | null;\n command: string | null;\n command_source: string | null;\n spawner: string | null;\n host: string | null;\n collected_head: string | null;\n repo: string | null;\n gate_token: string | null;\n created_at: string;\n updated_at: string;\n state?: string;\n source?: string;\n ctl?: string;\n ctl_socket?: string;\n since?: string | null;\n reason?: string;\n idle?: boolean;\n trust_dialog?: boolean;\n}\n\n/** Boundary mapper: AgentRow (camelCase) plus its real workstream id → output record. */\nexport function agentToOutput(\n row: AgentRow,\n workstreamId: number,\n live: AgentLiveFacts = {},\n): AgentOutput {\n return {\n id: row.incarnation,\n name: row.name,\n workstream_id: workstreamId,\n workstream: row.workstreamName,\n cli: row.cli,\n pane_id: row.paneId,\n role: row.role,\n tab: row.tab,\n cwd: row.cwd,\n base: row.base,\n command: row.command,\n command_source: row.commandSource,\n spawner: row.spawner,\n host: row.host,\n collected_head: row.collectedHead,\n repo: row.repo,\n gate_token: row.gateToken,\n created_at: row.createdAt,\n updated_at: row.updatedAt,\n ...(live.state !== undefined ? { state: live.state } : {}),\n ...(live.source !== undefined ? { source: live.source } : {}),\n ...(live.ctl !== undefined ? { ctl: live.ctl } : {}),\n ...(live.ctlSocket !== undefined ? { ctl_socket: live.ctlSocket } : {}),\n ...(live.since !== undefined ? { since: live.since } : {}),\n ...(live.reason !== undefined ? { reason: live.reason } : {}),\n ...(live.idle !== undefined ? { idle: live.idle } : {}),\n ...(live.trustDialog !== undefined ? { trust_dialog: live.trustDialog } : {}),\n };\n}\n\n/**\n * A close preview with its identity under the SQL names (`id`, `pane_id`);\n * every verb-level field is kept. `id` is the REGISTRY incarnation (null for a\n * recovery: no row); a recovery's own id is `recovery_id` (the original\n * incarnation it was kept from), null otherwise.\n */\nexport function closePreviewToOutput(p: ClosePreview): Record<string, unknown> {\n const { incarnation, paneId, ...rest } = p;\n return { ...rest, id: incarnation, pane_id: paneId, recovery_id: p.recovery?.id ?? null };\n}\n\n/** A live agent (`list`, `state`, `show`, `me`) as its record: columns plus the computed state and ctl link. */\nexport function liveAgentToOutput(agent: LiveAgent, workstreamId: number): AgentOutput {\n return agentToOutput(agent, workstreamId, {\n state: agent.state,\n source: agent.source,\n ...(agent.ctl !== undefined ? { ctl: agent.ctl } : {}),\n since: agent.since,\n ...(agent.reason !== undefined ? { reason: agent.reason } : {}),\n ...(agent.idle !== undefined ? { idle: agent.idle } : {}),\n });\n}\n","// mu — task read records: the output boundary of list / next / owned-by / show / tree.\n//\n// Pure (no I/O, no DB). A task becomes ONE record per line, or one JSON item\n// whose keys are the SQL column names (`id` is the task's `local_id`; the\n// integer primary key never appears; `workstream_id` / `owner_id` are the real\n// foreign keys). Every result is bounded on its FINAL bytes (README Interface,\n// output caps): a record is at most RECORD_CHARS characters, a result at most\n// RESULT_BYTES, and a cut names the way back. There is ONE way back that always\n// works: the same read with `--all` (uncapped), and for a clipped field of one\n// task `mu task show <id> -w <ws> --all`. Neither is ever clipped itself.\n//\n// text task<TAB>id<TAB>STATE<TAB>key=value ...<TAB>title[<TAB>cut=N<TAB>next=<cmd>]\n// footer more=N next=<command>\n//\n// Everything a terminal or a line tool could misread is escaped: backslash,\n// newline, tab and CR as two characters, any other control, C1, bidi,\n// line/paragraph-separator character as `\\u{hex}`.\n\nimport { encodeEnvelope, okEnvelope, RESULT_BYTES } from \"../../output-contract.js\";\nimport { formatPair } from \"../../tasks/status.js\";\nimport type { TaskRow } from \"../../tasks.js\";\n\n/** Most characters of one list record (README: list record <= 400 chars). */\nexport const RECORD_CHARS = 400;\n/** Most characters of a title in a JSON item. */\nexport const JSON_TITLE_CHARS = 120;\n/** Most characters of a wave label or host in a JSON item (clipped ones count into `cut`). */\nconst JSON_FIELD_CHARS = 80;\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching control characters is the point\nconst UNSAFE = /[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069\\\\]/u;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: matching control characters is the point\nconst UNSAFE_G = /[\\u0000-\\u001f\\u007f-\\u009f\\u061c\\u200e\\u200f\\u2028-\\u202e\\u2066-\\u2069\\\\]/gu;\n\n/** Escape so one value is one inert field of one line. */\nexport function escapeRecordText(s: string): string {\n if (!UNSAFE.test(s)) return s;\n return s.replace(UNSAFE_G, (c) => {\n switch (c) {\n case \"\\\\\":\n return \"\\\\\\\\\";\n case \"\\n\":\n return \"\\\\n\";\n case \"\\t\":\n return \"\\\\t\";\n case \"\\r\":\n return \"\\\\r\";\n default:\n return `\\\\u{${(c.codePointAt(0) ?? 0).toString(16)}}`;\n }\n });\n}\n\n/** The one JSON document line of a success envelope: the encoder every `--json` read emits through, so a size measured here is the size printed. */\nexport function jsonDocument(data: unknown): string {\n return encodeEnvelope(okEnvelope(data));\n}\n\nconst bytes = (s: string): number => Buffer.byteLength(s);\n/** Bytes of `lines` as printed (one newline each). */\nexport const linesBytes = (lines: readonly string[]): number => bytes(lines.join(\"\\n\")) + 1;\n\n/** Code points of `s`. */\nexport const codePoints = (s: string): string[] => [...s];\n\n/** `s` cut to at most `maxChars` code points AND `maxBytes` ESCAPED bytes; `cut` counts what was dropped. */\nexport function clipEscaped(\n s: string,\n maxChars: number,\n maxBytes = Number.POSITIVE_INFINITY,\n): { text: string; cut: number } {\n const cps = codePoints(s);\n let out = \"\";\n let used = 0;\n let n = 0;\n for (const cp of cps) {\n const esc = escapeRecordText(cp);\n if (out.length + esc.length > maxChars || used + bytes(esc) > maxBytes) break;\n out += esc;\n used += bytes(esc);\n n++;\n }\n return { text: out, cut: cps.length - n };\n}\n\n// ─── JSON items ────────────────────────────────────────────────────────\n\n/** One task as `--json` emits it: SQL column names, real foreign keys. */\nexport interface TaskOutput {\n /** The task's `local_id` (never the integer primary key). */\n id: string;\n local_id: string;\n /** Real `tasks.workstream_id`. */\n workstream_id: number;\n /** Name of that workstream; present only where the ref is otherwise ambiguous (`show`, cross-workstream views). */\n workstream?: string;\n title: string;\n status: string;\n substate: string;\n impact: number;\n effort_days: number;\n scored: 0 | 1;\n dispatch_host: string | null;\n /** Real `tasks.owner_id` (kept after close: lifecycle attribution). */\n owner_id: number | null;\n /** Owner's name; present ONLY while IN_PROGRESS (a CLOSED task's owner is history). */\n owner?: string;\n created_at: string;\n updated_at: string;\n kind: string;\n wave: string | null;\n /** What `--if <rev>` repeats; present when the verb computed it. */\n revision?: number;\n}\n\n/** Boundary mapper: TaskRow (names + real FKs) → output item. Never aliases name/effortDays. */\nexport function taskToOutput(\n row: TaskRow,\n opts: { revision?: number; withWorkstream?: boolean } = {},\n): TaskOutput {\n const out: TaskOutput = {\n id: row.name,\n local_id: row.name,\n workstream_id: row.workstreamId,\n title: row.title,\n status: row.status,\n substate: row.substate,\n impact: row.impact,\n effort_days: row.effortDays,\n scored: row.scored ? 1 : 0,\n dispatch_host: row.dispatchHost,\n owner_id: row.ownerId,\n created_at: row.createdAt,\n updated_at: row.updatedAt,\n kind: row.kind,\n wave: row.wave,\n };\n if (opts.withWorkstream === true) out.workstream = row.workstreamName;\n if (row.status === \"IN_PROGRESS\" && row.ownerName !== null) out.owner = row.ownerName;\n if (opts.revision !== undefined) out.revision = opts.revision;\n return out;\n}\n\n/** Title bound of a `show` (its own 4 KB result has a task, edges and notes to share; `show` shrinks it to fit). */\nexport const SHOW_TITLE_CHARS = 600;\n\n/** What a task read says when it cut something: `more=N` records left out, `cut=N` characters clipped, and the one command that prints it all. */\nexport interface Cuts {\n more: number;\n cut: number;\n}\n\n/** `more=N cut=N next=<command>` footer line; null when nothing was cut. `next` is the reserved tail: never sliced. */\nexport function footerLine(c: Cuts, next: string): string | null {\n if (c.more <= 0 && c.cut <= 0) return null;\n const parts = [c.more > 0 ? `more=${c.more}` : \"\", c.cut > 0 ? `cut=${c.cut}` : \"\"];\n return `${parts.filter(Boolean).join(\" \")} next=${next}`;\n}\n\n/** JSON item with bounded free-text fields; `cut` counts the code points clipped. `whole` clips nothing. */\nexport function taskItemCut(\n row: TaskRow,\n opts: {\n revision?: number;\n withWorkstream?: boolean;\n titleChars?: number;\n whole?: boolean;\n /** Code points already cut from a field the item does not hold itself (`show`'s last claimer). */\n extraCut?: number;\n } = {},\n): { item: TaskOutput; cut: number } {\n const item = taskToOutput(row, opts);\n if (opts.whole === true) return { item, cut: 0 };\n let cut = opts.extraCut ?? 0;\n const clip = (s: string, max: number): string => {\n const cps = codePoints(s);\n if (cps.length <= max) return s;\n cut += cps.length - Math.max(0, max - 1);\n return max <= 0 ? \"\" : `${cps.slice(0, max - 1).join(\"\")}…`;\n };\n item.title = clip(row.title, opts.titleChars ?? JSON_TITLE_CHARS);\n if (item.wave !== null) item.wave = clip(item.wave, JSON_FIELD_CHARS);\n if (item.dispatch_host !== null) item.dispatch_host = clip(item.dispatch_host, JSON_FIELD_CHARS);\n if (item.owner !== undefined) item.owner = clip(item.owner, JSON_FIELD_CHARS);\n return { item, cut };\n}\n\n// ─── Text records ──────────────────────────────────────────────────────\n\nexport interface RecordOpts {\n /** Name the workstream (cross-workstream views). */\n withWorkstream?: boolean;\n revision?: number;\n /** Show the owner as `by=<name>` when the row has none (an anonymous claim). */\n claimedBy?: string | null;\n /** Add `created=` and `updated=` (the `show` record). */\n times?: boolean;\n /** Extra `key=value` fields (`tree`'s depth, parent and what hangs below): kept even when metadata crowds the title out. */\n extra?: readonly string[];\n /** Add the one timestamp a `--sort recency|age` orders by. */\n basis?: \"updatedAt\" | \"createdAt\";\n /** Characters of the whole record (default RECORD_CHARS). */\n maxChars?: number;\n /** `show`: the title's own bound in code points (the record cap still applies). */\n titleChars?: number;\n /** Clip nothing (`--all`): only escape. */\n whole?: boolean;\n}\n\n/**\n * `task<TAB>id<TAB>STATE<TAB>k=v ...<TAB>title`: one line, escaped, <= maxChars\n * (never sliced: a clipped title ends in `…`, a field that does not fit is\n * dropped). `cut` counts the code points left out of the line; the caller's\n * footer carries the one way back (`--all` prints every record whole).\n */\nexport function taskRecordCut(row: TaskRow, opts: RecordOpts = {}): { line: string; cut: number } {\n const whole = opts.whole === true;\n let fieldCut = 0;\n const clip = (s: string, chars = 40): string => {\n if (whole) return escapeRecordText(s);\n const { text, cut } = clipEscaped(s, chars);\n if (cut === 0) return text;\n fieldCut += cut;\n return `${text}…`;\n };\n const kv: string[] = [`impact=${row.impact}`, `effort_days=${row.effortDays}`];\n if (!row.scored) kv.push(\"scored=0\");\n if (row.status === \"IN_PROGRESS\" && row.ownerName !== null)\n kv.push(`owner=${clip(row.ownerName)}`);\n if (opts.withWorkstream === true) kv.push(`ws=${clip(row.workstreamName)}`);\n if (row.status !== \"OPEN\" && row.ownerName === null && opts.claimedBy) {\n kv.push(`self=${clip(opts.claimedBy)}`);\n }\n if (row.kind !== \"work\") kv.push(`kind=${row.kind}`);\n if (row.wave !== null) kv.push(`wave=${clip(row.wave)}`);\n if (row.dispatchHost !== null) kv.push(`host=${clip(row.dispatchHost)}`);\n if (opts.times === true) kv.push(`created=${row.createdAt}`, `updated=${row.updatedAt}`);\n else if (opts.basis === \"updatedAt\") kv.push(`updated=${row.updatedAt}`);\n else if (opts.basis === \"createdAt\") kv.push(`created=${row.createdAt}`);\n if (opts.revision !== undefined) kv.push(`rev=${opts.revision}`);\n kv.push(...(opts.extra ?? []));\n const id = clip(row.name, 64);\n const head = [\"task\", id, formatPair(row), kv.join(\" \")].join(\"\\t\");\n const wholeTitle = escapeRecordText(row.title);\n if (whole) return { line: `${head}\\t${wholeTitle}`, cut: 0 };\n const max = opts.maxChars ?? RECORD_CHARS;\n const bound = opts.titleChars ?? Number.POSITIVE_INFINITY;\n const place = (h: string, extraCut: number): { line: string; cut: number } | undefined => {\n const roomMax = max - codePoints(h).length - 1;\n if (roomMax < 9) return undefined;\n const room = Math.min(roomMax, bound);\n if (codePoints(wholeTitle).length <= room)\n return { line: `${h}\\t${wholeTitle}`, cut: extraCut };\n const { text, cut } = clipEscaped(row.title, Math.max(0, room - 1));\n return { line: `${h}\\t${text}…`, cut: cut + extraCut };\n };\n const first = place(head, fieldCut);\n if (first !== undefined) return first;\n // Metadata crowds the title out: keep the identity and the score; the free-text fields\n // dropped from the line count into `cut` (`--all` prints them).\n const dropped = [\n row.status === \"IN_PROGRESS\" ? row.ownerName : null,\n opts.withWorkstream === true ? row.workstreamName : null,\n row.wave,\n row.dispatchHost,\n row.status !== \"OPEN\" && row.ownerName === null ? (opts.claimedBy ?? null) : null,\n ]\n .filter((v): v is string => typeof v === \"string\")\n .reduce((n, v) => n + codePoints(v).length, 0);\n const lean = [\n \"task\",\n id,\n formatPair(row),\n [...kv.slice(0, 2), ...(opts.extra ?? [])].join(\" \"),\n ].join(\"\\t\");\n const room = Math.min(Math.max(0, max - codePoints(lean).length - 2), Math.max(0, bound - 1));\n const { text, cut } = clipEscaped(row.title, room);\n return { line: `${lean}\\t${text}…`, cut: cut + dropped };\n}\n\n// ─── Paging ────────────────────────────────────────────────────────────\n\nexport interface RecordPage<T> {\n /** The records of this page (always at least one when any exist). */\n shown: T[];\n /** Records left out. */\n more: number;\n}\n\n/**\n * Take records from `all`, in order, as many as keep the FINAL emitted bytes\n * (`size(page)`: the caller serializes text lines or the JSON document, footer\n * and metadata included) within `budget`. The first record always goes out\n * (records are themselves bounded), so a page makes progress.\n */\nexport function pageRecords<T>(\n all: readonly T[],\n size: (page: RecordPage<T>) => number,\n budget: number = RESULT_BYTES,\n /** Records that go out even when over budget (default 1: progress). */\n min = 1,\n): RecordPage<T> {\n const build = (k: number): RecordPage<T> => ({ shown: all.slice(0, k), more: all.length - k });\n let page = build(Math.min(min, all.length));\n for (let k = min + 1; k <= all.length; k++) {\n const candidate = build(k);\n if (size(candidate) > budget) break;\n page = candidate;\n }\n return page;\n}\n\n// ─── A page of task records ────────────────────────────────────────────\n\nexport interface TaskPageOpts {\n /** `--all`: every record, whole, no cap. */\n all: boolean;\n /** The footer's `next=`: the same read, uncapped (`--all`; `--full` where `--all` is taken). */\n next: string;\n json: boolean;\n withWorkstream?: boolean;\n /** The timestamp the sort orders by, shown on text records. */\n basis?: \"updatedAt\" | \"createdAt\" | null;\n /** `local_id` → revision (list). */\n revisions?: ReadonlyMap<string, number>;\n}\n\nexport interface TaskPageOut {\n /** Text lines to print (no terminal framing); empty when `json`. */\n lines: string[];\n /** The `data` payload; undefined unless `json`. */\n data?: { items: TaskOutput[]; count: number; more: number; cut?: number; retrieve?: string };\n shown: number;\n more: number;\n}\n\n/** Page `rows` into at most RESULT_BYTES of final output, in text or JSON; `--all` prints every row whole. */\nexport function taskPage(rows: readonly TaskRow[], opts: TaskPageOpts): TaskPageOut {\n const ws = opts.withWorkstream === true;\n const whole = opts.all;\n const render = (\n page: RecordPage<TaskRow>,\n ): { lines: string[]; data: NonNullable<TaskPageOut[\"data\"]> } => {\n let cut = 0;\n const lines: string[] = [];\n const items: TaskOutput[] = [];\n for (const r of page.shown) {\n const revision = opts.revisions?.get(r.name);\n const rev = revision === undefined ? {} : { revision };\n if (opts.json) {\n const one = taskItemCut(r, { withWorkstream: ws, whole, ...rev });\n cut += one.cut;\n items.push(one.item);\n } else {\n const one = taskRecordCut(r, {\n withWorkstream: ws,\n whole,\n ...rev,\n ...(opts.basis ? { basis: opts.basis } : {}),\n });\n cut += one.cut;\n lines.push(one.line);\n }\n }\n const foot = footerLine({ more: page.more, cut }, opts.next);\n if (foot !== null) lines.push(foot);\n return {\n lines: opts.json ? [] : lines,\n data: {\n items,\n count: items.length,\n more: page.more,\n ...(cut > 0 ? { cut } : {}),\n ...(foot === null ? {} : { retrieve: opts.next }),\n },\n };\n };\n const page: RecordPage<TaskRow> = whole\n ? { shown: [...rows], more: 0 }\n : pageRecords(rows, (p) => {\n const r = render(p);\n return opts.json ? bytes(jsonDocument(r.data)) + 1 : linesBytes(r.lines);\n });\n const out = render(page);\n return {\n lines: out.lines,\n ...(opts.json ? { data: out.data } : {}),\n shown: page.shown.length,\n more: page.more,\n };\n}\n","// mu — the shared pager of the capped text/JSON reads that are not task reads\n// (`mu log`, `mu workstream list`).\n//\n// Pure (no I/O, no DB). A page is bounded on its FINAL bytes (RESULT_BYTES,\n// envelope and footer included). A cut is counted (`more=N` records\n// left out, `cut=N` characters clipped) and names its way back as a command that\n// runs as printed.\n\nimport { RESULT_BYTES } from \"../output-contract.js\";\nimport {\n clipEscaped,\n codePoints,\n escapeRecordText,\n jsonDocument,\n linesBytes,\n pageRecords,\n RECORD_CHARS,\n type RecordPage,\n} from \"./tasks/records.js\";\n\nconst bytes = (s: string): number => Buffer.byteLength(s);\n\n/** A fixed column (source, scope, ...) is clipped to this many characters. */\nconst COLUMN_CHARS = 64;\n/** One JSON item's own document stays within this, so a page always has room for its metadata. */\nexport const ITEM_BYTES = 2048;\n\n/** `s` clipped to `max` code points; `cut` counts the code points dropped. */\nexport function clipPlain(s: string, max: number): { text: string; cut: number } {\n const cps = codePoints(s);\n if (cps.length <= max) return { text: s, cut: 0 };\n return { text: cps.slice(0, max).join(\"\"), cut: cps.length - max };\n}\n\n/**\n * Build an item whose own document fits ITEM_BYTES whatever it holds (control\n * and multibyte characters escape to 6 bytes and more): every field's character\n * limit shrinks (halving, then to empty) until it does. `build(scale)` clips each\n * field to `floor(limit * scale)`.\n */\nexport function shrinkItem<I extends object>(\n build: (scale: number) => { item: I; cut: number },\n): { item: I; cut: number } {\n let out = build(1);\n for (const scale of [0.5, 0.25, 0.125, 0]) {\n if (bytes(jsonDocument({ items: [out.item] })) <= ITEM_BYTES) break;\n out = build(scale);\n }\n return out;\n}\n\n// ─── the generic pager ─────────────────────────────────────────────────\n\nexport interface PageSpec<T> {\n json: boolean;\n /** Every row, whole, no cap and no footer (`--all`). */\n whole?: boolean;\n /** Fill the page from the END of `rows` (the newest), printing it in the original order. */\n newest?: boolean;\n /** One text record; `cut` counts the characters it clipped (none when `whole`). */\n text(row: T, whole: boolean): { line: string; cut: number };\n /** One JSON item; `cut` counts the characters it clipped (none when `whole`). */\n item(row: T, whole: boolean): { item: object; cut: number };\n /** The command that reads the `more` records left out. */\n resume(shown: readonly T[], more: number): string;\n /** The command that reads the clipped rows whole; defaults to `resume`. */\n retrieve?(clipped: readonly T[]): string;\n /** JSON: name the one way back `retrieve`, with no separate `resume`. */\n singleRetrieve?: boolean;\n}\n\nexport interface PageData {\n items: object[];\n count: number;\n more: number;\n cut?: number;\n /** Reads the `more` records left out. */\n resume?: string;\n /** Reads the clipped records whole. */\n retrieve?: string;\n}\n\nexport interface PageOut {\n /** Text lines to print; empty when `json`. */\n lines: string[];\n /** The `data` payload; undefined unless `json`. */\n data?: PageData;\n shown: number;\n more: number;\n}\n\n/** Page `rows` into at most RESULT_BYTES of final output, as text lines or one JSON document. */\nexport function pageOut<T>(rows: readonly T[], spec: PageSpec<T>): PageOut {\n const newest = spec.newest === true;\n const whole = spec.whole === true;\n const render = (page: RecordPage<T>): { lines: string[]; data: PageData } => {\n const shown = newest ? [...page.shown].reverse() : page.shown;\n let cut = 0;\n const clipped: T[] = [];\n const lines: string[] = [];\n const items: object[] = [];\n for (const r of shown) {\n if (spec.json) {\n const one = spec.item(r, whole);\n if (one.cut > 0) clipped.push(r);\n cut += one.cut;\n items.push(one.item);\n } else {\n const one = spec.text(r, whole);\n if (one.cut > 0) clipped.push(r);\n cut += one.cut;\n lines.push(one.line);\n }\n }\n const resume = page.more > 0 ? spec.resume(shown, page.more) : undefined;\n const retrieve =\n cut > 0 ? (spec.retrieve ?? ((_c) => spec.resume(shown, page.more)))(clipped) : undefined;\n if (resume !== undefined && resume === retrieve) {\n lines.push(`more=${page.more} cut=${cut} next=${resume}`);\n } else {\n if (resume !== undefined) lines.push(`more=${page.more} next=${resume}`);\n if (retrieve !== undefined) lines.push(`cut=${cut} next=${retrieve}`);\n }\n const single = spec.singleRetrieve === true;\n const way = retrieve ?? (single ? resume : undefined);\n return {\n lines: spec.json ? [] : lines,\n data: {\n items,\n count: items.length,\n more: page.more,\n ...(cut > 0 ? { cut } : {}),\n ...(resume === undefined || single ? {} : { resume }),\n ...(way === undefined ? {} : { retrieve: way }),\n },\n };\n };\n const input = newest ? [...rows].reverse() : rows;\n // min 0: when even one record plus the footer would bust the cap, none goes out\n // and the footer says how to read on.\n const page: RecordPage<T> = whole\n ? { shown: [...input], more: 0 }\n : pageRecords(\n input,\n (p) => {\n const r = render(p);\n return spec.json ? bytes(jsonDocument(r.data)) + 1 : linesBytes(r.lines);\n },\n RESULT_BYTES,\n 0,\n );\n const out = render(page);\n return {\n lines: out.lines,\n ...(spec.json ? { data: out.data } : {}),\n shown: page.shown.length,\n more: page.more,\n };\n}\n\n/** One text record: fixed columns, then a free-text tail; escaped, at most RECORD_CHARS characters (`whole`: escaped, never clipped). */\nexport function clippedRecord(\n columns: readonly string[],\n free: string,\n whole = false,\n): { line: string; cut: number } {\n if (whole) return { line: [...columns, free].map(escapeRecordText).join(\"\\t\"), cut: 0 };\n let cut = 0;\n const lean = columns\n .map((c) => {\n const one = clipEscaped(c, COLUMN_CHARS);\n cut += one.cut;\n return one.text;\n })\n .join(\"\\t\");\n const room = Math.max(0, RECORD_CHARS - lean.length - 2);\n const tail = clipEscaped(free, room);\n cut += tail.cut;\n return { line: `${lean}\\t${tail.text}${tail.cut > 0 ? \"…\" : \"\"}`, cut };\n}\n","// mu — the output boundary of the log reads (`mu log`, `mu log --tail`) and of\n// the capped `mu workstream list` pages, which share its pager.\n//\n// Pure (no I/O, no DB). One op is ONE text record on ONE line (escaped, at most\n// RECORD_CHARS characters), or one JSON item keyed by the `ops` column names\n// (`key`, `actor`, `entity`, `group_id`, `created_at`; `rendered` is the prose of\n// the one formatter). The SDK's `LogRow` and `renderOp`'s input keep their names:\n// this adapter maps them at the CLI edge, and raw op rows are never rewritten.\n//\n// A page is bounded on its FINAL bytes (RESULT_BYTES, envelope included). A cut\n// is counted (`more=N` records left out, `cut=N` characters clipped) and names\n// its way back BY SEQ, never by filter: `mu log --seq A..B` (exact seqs, every\n// record whole, no scope) or, when the omitted ops are too scattered to name,\n// `mu log --after S` (a cursor into the whole log). A hint is digits only, so its\n// size is bounded however long the filters, groups or workstream names were.\n\nimport { parseOpKey, renderOp, renderOpLine } from \"../log-render.js\";\nimport type { LogRow } from \"../logs.js\";\nimport { clipPlain, clippedRecord, type PageOut, pageOut, shrinkItem } from \"./page-records.js\";\n\n// ─── log records ───────────────────────────────────────────────────────\n\n/** What an op says, on one line: the formatter's prose, or `kind: payload` for operator prose. */\nfunction whatLine(row: LogRow): string {\n const r = renderOp(row);\n if (r === null) return `${row.kind}: ${row.payload}`;\n return [r.verb, r.subject, r.detail].filter((s) => s !== \"\").join(\" \");\n}\n\n/** `log<TAB>seq<TAB>time<TAB>source<TAB>scope<TAB>what`: one escaped line, <= 400 characters. */\nexport function logRecord(row: LogRow, whole = false): { line: string; cut: number } {\n const time = row.createdAt.replace(/\\.\\d+Z$/, \"Z\");\n const scope = parseOpKey(row.workstreamName).workstream ?? \"-\";\n return clippedRecord([\"log\", String(row.seq), time, row.source, scope], whatLine(row), whole);\n}\n\n/** One op as `--json` and `--tail` print it: the `ops` column names plus the formatter's prose. */\nexport interface LogItem {\n seq: number;\n /** `ops.key`; '' for a machine-wide entry. */\n key: string;\n /** `ops.actor` ('system' where the op had none). */\n actor: string;\n intent: string | null;\n group_id: string;\n op: string;\n /** `ops.entity` (the `--kind` tag). */\n entity: string;\n payload: string;\n created_at: string;\n /** The one formatter's prose for this op. */\n rendered: string;\n /** Characters clipped from this item's text fields; absent when none. */\n cut?: number;\n}\n\nconst LIMITS = {\n key: 120,\n actor: 80,\n intent: 80,\n group_id: 64,\n op: 16,\n entity: 80,\n payload: 240,\n created_at: 40,\n rendered: 160,\n} as const;\n\n/** The item with every text field clipped to `scale` x its limit (cut counted); scale 0 empties them. */\nfunction buildItem(row: LogRow, scale: number): { item: LogItem; cut: number } {\n let cut = 0;\n const clip = (s: string, limit: number): string => {\n const one = clipPlain(s, Math.floor(limit * scale));\n cut += one.cut;\n return one.text;\n };\n const item: LogItem = {\n seq: row.seq,\n key: clip(row.workstreamName ?? \"\", LIMITS.key),\n actor: clip(row.source, LIMITS.actor),\n intent: row.intent === null ? null : clip(row.intent, LIMITS.intent),\n group_id: clip(row.group, LIMITS.group_id),\n op: clip(row.op, LIMITS.op),\n entity: clip(row.kind, LIMITS.entity),\n payload: clip(row.payload, LIMITS.payload),\n created_at: clip(row.createdAt, LIMITS.created_at),\n rendered: clip(renderOpLine(row), LIMITS.rendered),\n };\n if (cut > 0) item.cut = cut;\n return { item, cut };\n}\n\n/** A JSON item whose own document fits ITEM_BYTES (control and multibyte characters included): EVERY text field shrinks until it does. `whole`: every field as stored. */\nexport function logItem(row: LogRow, whole = false): { item: LogItem; cut: number } {\n if (whole) {\n return {\n cut: 0,\n item: {\n seq: row.seq,\n key: row.workstreamName ?? \"\",\n actor: row.source,\n intent: row.intent,\n group_id: row.group,\n op: row.op,\n entity: row.kind,\n payload: row.payload,\n created_at: row.createdAt,\n rendered: renderOpLine(row),\n },\n };\n }\n return shrinkItem((scale) => buildItem(row, scale));\n}\n\n/** Most exact runs a hint names; scattered omissions past this fall back to a cursor. */\nconst MAX_RUNS = 8;\n\n/**\n * The command that reads exactly `seqs`: `mu log --seq a..b,c,...` (no scope, every\n * record whole). `gapEmpty(a, b)` says no visible op lies strictly between a and b,\n * so a..b holds nothing else. Too scattered to name in `MAX_RUNS` runs: the cursor\n * `mu log --after <first - 1>` (a paged read of the whole log from there).\n */\nexport function seqCommand(\n seqs: readonly number[],\n gapEmpty: (a: number, b: number) => boolean,\n json: boolean,\n): string {\n const sorted = [...new Set(seqs)].sort((a, b) => a - b);\n const runs: [number, number][] = [];\n for (const n of sorted) {\n const last = runs[runs.length - 1];\n if (last !== undefined && (n === last[1] + 1 || gapEmpty(last[1], n))) last[1] = n;\n else runs.push([n, n]);\n if (runs.length > MAX_RUNS) break;\n }\n const tail = json ? \" --json\" : \"\";\n if (runs.length > MAX_RUNS || runs.length === 0) {\n return `mu log --after ${Math.max(0, (sorted[0] ?? 1) - 1)}${tail}`;\n }\n const spec = runs.map(([a, b]) => (a === b ? String(a) : `${a}..${b}`)).join(\",\");\n return `mu log --seq ${spec}${tail}`;\n}\n\nexport interface LogPageOpts {\n json: boolean;\n /** Fill from the newest record (a \"latest N\" read); else from the oldest (a cursor read). */\n newest: boolean;\n /** Every record whole, no cap, no footer (`--seq`). */\n whole?: boolean;\n /** A cursor read with no filter (`--after`): the resume is `--after <last shown>`. */\n cursor?: boolean;\n /** No visible op lies strictly between these two seqs (lets a hint name a range). */\n gapEmpty(a: number, b: number): boolean;\n}\n\n/** A page of log records (oldest first), at most RESULT_BYTES of final output. */\nexport function logPage(rows: readonly LogRow[], opts: LogPageOpts): PageOut {\n const say = (seqs: readonly number[]): string => seqCommand(seqs, opts.gapEmpty, opts.json);\n return pageOut(rows, {\n json: opts.json,\n newest: opts.newest,\n whole: opts.whole === true,\n text: (r, all) => logRecord(r, all),\n item: (r, all) => logItem(r, all),\n // The ops left out, by seq: a latest-N read omits the older ones, a cursor read the later.\n resume: (shown) => {\n if (opts.cursor === true) {\n const at = shown[shown.length - 1]?.seq ?? (rows[0]?.seq ?? 1) - 1;\n return `mu log --after ${at}${opts.json ? \" --json\" : \"\"}`;\n }\n const on = new Set(shown.map((r) => r.seq));\n return say(rows.filter((r) => !on.has(r.seq)).map((r) => r.seq));\n },\n retrieve: (clipped) => say(clipped.map((r) => r.seq)),\n });\n}\n\n/** One op as `--tail` and a log write print it: the item, plus the way back to the whole op when it was clipped. */\nexport function logOut(row: LogRow): LogItem & { retrieve?: string } {\n const { item } = logItem(row);\n return item.cut === undefined ? item : { ...item, retrieve: `mu log --seq ${row.seq} --json` };\n}\n\n/** The text receipt of a log write: the one record the log shows, plus `cut=N next=...` when it clipped. */\nexport function logReceipt(row: LogRow): string[] {\n const one = logRecord(row);\n return one.cut === 0 ? [one.line] : [one.line, `cut=${one.cut} next=mu log --seq ${row.seq}`];\n}\n"],"mappings":"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","names":["fields","fields","fields","readFileSync","readFileSync","createHash","closeSync","existsSync","openSync","readdirSync","readFileSync","readSync","statSync","writeFileSync","join","createHash","closeSync","openSync","readFileSync","readSync","openSync","bytes","readSync","closeSync","readFileSync","createHash","SEGMENT_EXT","join","createHash","writeFileSync","existsSync","row","statSync","openSync","readSync","closeSync","readFileSync","bytes","readdirSync","workstreamId","refuse","str","bytes","existsSync","statSync","statSync","existsSync","workstreamId","text","cut","room","page","bytes","page","say"]}