@tangle-network/agent-runtime 0.116.0 → 0.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/{activation-DuqQhee6.js → activation-BZ2FyX0O.js} +3 -3
- package/dist/{activation-DuqQhee6.js.map → activation-BZ2FyX0O.js.map} +1 -1
- package/dist/agent.d.ts +3 -64
- package/dist/agent.js +5 -207
- package/dist/agent.js.map +1 -1
- package/dist/{analyst-loop-BoNIG2hA.js → analyst-loop-DvSciOfB.js} +2 -2
- package/dist/{analyst-loop-BoNIG2hA.js.map → analyst-loop-DvSciOfB.js.map} +1 -1
- package/dist/analyst-loop.js +1 -1
- package/dist/candidate-execution/index.d.ts +3 -3
- package/dist/candidate-execution/index.js +5 -5
- package/dist/{candidate-execution-CfpJrd3o.js → candidate-execution-PX61zXd2.js} +4 -4
- package/dist/{candidate-execution-CfpJrd3o.js.map → candidate-execution-PX61zXd2.js.map} +1 -1
- package/dist/{environment-provider-CWsRh6Uz.d.ts → environment-provider-CTZjdIUg.d.ts} +298 -32
- package/dist/{environment-provider-CCaEhA-l.js → environment-provider-CzcEyRL7.js} +140 -31
- package/dist/environment-provider-CzcEyRL7.js.map +1 -0
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/{improvement-cycle-C1cmjvPD.js → improvement-cycle-Bcqz8rZI.js} +160 -19
- package/dist/improvement-cycle-Bcqz8rZI.js.map +1 -0
- package/dist/{index-CYkDeM5L.d.ts → index-BHSYaWrC.d.ts} +3 -3
- package/dist/{index-DcLMNnG5.d.ts → index-BTUG4Xln.d.ts} +6 -6
- package/dist/{index-COumPQka.d.ts → index-DPWJxSRa.d.ts} +847 -275
- package/dist/{index-C-FYUuFG.d.ts → index-X2YwyWkc.d.ts} +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +12 -12
- package/dist/intelligence.d.ts +8 -7
- package/dist/intelligence.js +15 -9
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +3 -3
- package/dist/kernel.js +8 -8
- package/dist/{knowledge-DOzbywZT.js → knowledge-CDlrayRc.js} +7 -7
- package/dist/knowledge-CDlrayRc.js.map +1 -0
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-BuQjc5DR.js → loop-runner-bin-BxhhDtmG.js} +4 -4
- package/dist/{loop-runner-bin-BuQjc5DR.js.map → loop-runner-bin-BxhhDtmG.js.map} +1 -1
- package/dist/{loop-runner-bin-BFrhPLKt.d.ts → loop-runner-bin-oyL7it5O.d.ts} +3 -3
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +43 -10
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +3 -43
- package/dist/mcp/index.js +5 -204
- package/dist/mcp/index.js.map +1 -1
- package/dist/{openai-tools-_Wyp4udO.js → openai-tools-CO9X36zy.js} +2 -2
- package/dist/{openai-tools-_Wyp4udO.js.map → openai-tools-CO9X36zy.js.map} +1 -1
- package/dist/{prepare-BHQBb02e.js → prepare-BbI6qGOW.js} +5 -2
- package/dist/prepare-BbI6qGOW.js.map +1 -0
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/{protected-model-port-BP6Z4eau.d.ts → protected-model-port-B0yXMpLL.d.ts} +10 -2
- package/dist/{protected-model-port-DqAH1Z2M.js → protected-model-port-COnyZfML.js} +2 -2
- package/dist/{protected-model-port-DqAH1Z2M.js.map → protected-model-port-COnyZfML.js.map} +1 -1
- package/dist/{runtime-Ut1pkd2n.js → runtime-Ce39zfqn.js} +145 -53
- package/dist/runtime-Ce39zfqn.js.map +1 -0
- package/dist/{sandbox-events-DeI5xX8P.js → sandbox-events-Yhd1GYWl.js} +4 -2
- package/dist/sandbox-events-Yhd1GYWl.js.map +1 -0
- package/dist/spawn-journal-B_mu_oH2.js +857 -0
- package/dist/spawn-journal-B_mu_oH2.js.map +1 -0
- package/dist/{structural-rollout-CVY_0hJp.js → structural-rollout-DLwW69R4.js} +4 -4
- package/dist/structural-rollout-DLwW69R4.js.map +1 -0
- package/dist/{supervise-BUR9ByF7.js → supervise-U7_K5yuV.js} +2598 -821
- package/dist/supervise-U7_K5yuV.js.map +1 -0
- package/dist/{supervisor-BBbPBXpe.js → supervisor-CAXiCKnX.js} +2808 -973
- package/dist/supervisor-CAXiCKnX.js.map +1 -0
- package/dist/testing.js +98 -76
- package/dist/testing.js.map +1 -1
- package/dist/{workspace-archive-DXzJq7WP.js → workspace-archive-CqPIijFA.js} +2 -2
- package/dist/{workspace-archive-DXzJq7WP.js.map → workspace-archive-CqPIijFA.js.map} +1 -1
- package/package.json +1 -1
- package/dist/environment-provider-CCaEhA-l.js.map +0 -1
- package/dist/improvement-cycle-C1cmjvPD.js.map +0 -1
- package/dist/knowledge-DOzbywZT.js.map +0 -1
- package/dist/prepare-BHQBb02e.js.map +0 -1
- package/dist/runtime-Ut1pkd2n.js.map +0 -1
- package/dist/sandbox-events-DeI5xX8P.js.map +0 -1
- package/dist/spawn-journal-DCPbicXB.js +0 -457
- package/dist/spawn-journal-DCPbicXB.js.map +0 -1
- package/dist/structural-rollout-CVY_0hJp.js.map +0 -1
- package/dist/supervise-BUR9ByF7.js.map +0 -1
- package/dist/supervisor-BBbPBXpe.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"supervise-BUR9ByF7.js","names":["isAsyncIterable","str","sleep","abortableSleep","TEARDOWN_TIMEOUT_MS","describeArgs","linkSignals","httpsRequest","httpRequest","AgentEvalError"],"sources":["../src/runtime/supervise/completion-gate.ts","../src/runtime/supervise/model-policy.ts","../src/runtime/supervise/otel-spans.ts","../src/runtime/supervise/coordination-log.ts","../src/runtime/sandbox-acquire.ts","../src/runtime/sandbox-capabilities.ts","../src/runtime/sandbox-lineage.ts","../src/runtime/run-loop.ts","../src/runtime/supervise/inbox.ts","../src/runtime/supervise/pi-mcp.ts","../src/runtime/supervise/trace-source.ts","../src/runtime/supervise/pi-executor.ts","../src/runtime/supervise/sandbox-session.ts","../src/runtime/supervise/worktree-cli-executor.ts","../src/runtime/supervise/runtime.ts","../src/runtime/supervise/run-context.ts","../src/runtime/supervise/detector-monitor.ts","../src/runtime/supervise/dispatch.ts","../src/runtime/supervise/event-bus.ts","../src/mcp/tools/coordination.ts","../src/runtime/anytime.ts","../src/runtime/supervise/stop-rules.ts","../src/runtime/supervise/coordination-driver.ts","../src/mcp/feedback-store.ts","../src/mcp/delegation-store.ts","../src/mcp/delegation-trace.ts","../src/mcp/task-queue.ts","../src/runtime/supervise/authoring.ts","../src/runtime/supervise/delegate.ts","../src/mcp/tools/delegate.ts","../src/mcp/tools/delegate-feedback.ts","../src/mcp/tools/delegate-ui-audit.ts","../src/mcp/tools/delegation-history.ts","../src/mcp/tools/delegation-status.ts","../src/mcp/server.ts","../src/runtime/supervise/coordination-mcp.ts","../src/runtime/supervise/supervisor-agent.ts","../src/runtime/supervise/supervise.ts"],"sourcesContent":["/**\n *\n * The completion-oracle: **settled ⟺ DELIVERED.**\n *\n * Foreman's one hard lesson (0/18 self-improvement deliverables) — \"done\" must mean a check\n * PASSED, not the agent's say-so. `gateOnDeliverable` wraps an `Executor` so its settlement\n * is `valid` ONLY when the deliverable check passes. The child still RUNS and settles (its\n * spend is conserved into the pool either way), but a child that ran WITHOUT delivering\n * settles `valid:false` — so a keep-best driver never counts it as done, and a gate never\n * inflates with self-judged wins.\n *\n * Dual-purpose by construction:\n * - product: the agent fleet only advances on real, checked deliverables.\n * - proof: the gate's `valid` is the honest settle — equal-k comparisons can't be gamed by an\n * arm that \"ran\" without producing the artifact.\n *\n * The check is a DEPLOYABLE oracle — a test command, a state verifier, the commit0 judge —\n * read off the child's output, never the model judging itself. A throwing check is\n * fail-closed (not delivered), never a crash.\n *\n * @experimental\n */\n\nimport type { DefaultVerdict, Executor, ExecutorResult, UsageEvent } from './types'\n\n/**\n * The deployable completion oracle passed to {@link gateOnDeliverable}: a `check` that\n * decides DELIVERED (settles `valid` ⟺ it resolves true) plus an optional `describe` of\n * what the spawn was supposed to produce. The check reads the child's output — never the\n * model judging itself.\n */\nexport interface DeliverableSpec<Out = unknown> {\n /** The deployable check that decides DELIVERED. `settled.valid ⟺ this resolves true`. */\n check: (out: Out) => boolean | Promise<boolean>\n /** What the spawn was supposed to produce — surfaced in traces/reports. */\n describe?: string\n}\n\n/**\n * Wrap an `Executor` so its settlement `valid` reflects the deliverable check, not the\n * inner verdict. Handles both `execute` shapes (one-shot `Promise<ExecutorResult>` and\n * streaming `AsyncIterable<UsageEvent>` + `resultArtifact()`); the check runs once the inner\n * executor has produced its output. The inner `score` is preserved; only `valid` is gated.\n */\nexport function gateOnDeliverable<Out>(\n inner: Executor<Out>,\n deliverable: DeliverableSpec<Out>,\n): Executor<Out> {\n let gated: DefaultVerdict | undefined\n\n const check = async (out: Out, baseScore?: number): Promise<DefaultVerdict> => {\n let delivered: boolean\n try {\n delivered = (await deliverable.check(out)) === true\n } catch {\n delivered = false // fail-closed: a throwing check is NOT a delivery\n }\n return { valid: delivered, score: baseScore ?? (delivered ? 1 : 0) }\n }\n\n return {\n runtime: inner.runtime,\n ...(inner.budgetExempt !== undefined ? { budgetExempt: inner.budgetExempt } : {}),\n ...(inner.deliver ? { deliver: (m: unknown) => inner.deliver?.(m) } : {}),\n // Forward the OPTIONAL live-observation surfaces so a gated worker stays supervisable\n // mid-flight. The scope captures `progress`/`traceSource` at spawn and only if the executor\n // exposes them; a gate that drops them makes `observe_agent` read `recentActivity:[]` and\n // loses online detection for a running worker (it saw the tokens/turns the fold derives, but\n // none of the harness's own turn count or tool activity). `metered` is a driver-executor's\n // OWN-inference subtree total, re-homed by the parent on settle — dropping it would leak a\n // gated sub-driver's inference out of the journal. Preserve the \"undefined ⟺ not implemented\"\n // contract: only expose a method the inner executor actually implements.\n ...(inner.progress ? { progress: () => inner.progress?.() } : {}),\n ...(inner.traceSource ? { traceSource: () => inner.traceSource?.() } : {}),\n ...(inner.metered ? { metered: () => inner.metered?.() } : {}),\n execute(task, signal) {\n const r = inner.execute(task, signal)\n if (isAsyncIterable(r)) {\n // Streaming: pass the usage events through (the conserved-pool fold consumes them),\n // then gate the verdict from the settled artifact.\n return (async function* () {\n for await (const ev of r) yield ev\n const art = inner.resultArtifact()\n gated = await check(art.out, art.verdict?.score)\n })()\n }\n // One-shot: gate the resolved result's verdict in place.\n return (async () => {\n const res = await r\n gated = await check(res.out, res.verdict?.score)\n return { ...res, verdict: gated } satisfies ExecutorResult<Out>\n })()\n },\n teardown: (grace) => inner.teardown(grace),\n resultArtifact() {\n const art = inner.resultArtifact()\n return { ...art, verdict: gated ?? art.verdict }\n },\n }\n}\n\nfunction isAsyncIterable(v: unknown): v is AsyncIterable<UsageEvent> {\n return (\n v != null &&\n typeof (v as { [Symbol.asyncIterator]?: unknown })[Symbol.asyncIterator] === 'function'\n )\n}\n","/**\n * `assertModelAllowed` — a fail-loud guard that restricts a run to a chosen subset of\n * models. The two front doors (`supervise()` / `improve()`) call it once per configured\n * model at resolve time, so a run that names a model outside the allowed set throws before\n * any compute is spent — never silently swapped or silently allowed.\n */\nimport { ConfigError } from '../../errors'\n\n/**\n * Throw a `ConfigError` when `allowed` is set, `model` is defined, and `model` is not a\n * member of `allowed`. No-op when `allowed` is unset (the unrestricted default) or when\n * `model` is undefined (nothing was configured to check).\n */\nexport function assertModelAllowed(\n model: string | undefined,\n allowed: readonly string[] | undefined,\n): void {\n if (!allowed || model === undefined) return\n if (!allowed.includes(model)) {\n throw new ConfigError(\n `model ${JSON.stringify(model)} is not in the allowed set ${JSON.stringify([...allowed])}`,\n )\n }\n}\n","/**\n * Supervisor tree → OTLP spans. OPT-IN, off by default.\n *\n * WHY. A supervised tree is legible today only by parsing this package's own spawn journal, so\n * every other multi-agent shape on the machine (a coding-CLI's subagents, a pi fanout, ad-hoc tool\n * parallelism) needs its own bespoke reader. A span carrying `parent_span_id` IS a tree, and any\n * system can emit one — so emitting spans makes the supervisor readable by the same viewer as\n * everything else, with no per-system reader.\n *\n * WHAT IT IS NOT. This is telemetry, never the record of truth. The spawn journal remains the sole\n * durable ledger for replay/resume and for cost; nothing here is read back, and a run whose export\n * fails is unaffected in every observable way. The two data models are deliberately separate.\n *\n * HOW IT ATTACHES. This is a pure `RuntimeHooks` observer over the lifecycle events `Scope` ALREADY\n * emits — `agent.spawn` (a node opened), `agent.child` (a node settled), `agent.turn` (a driver\n * inference turn was metered). It adds no event, mutates no journal, and changes no result. Because\n * `Scope` re-seeds the same hooks into every nested scope (`makeNestedScopeSeam`), one observer sees\n * the WHOLE recursion at arbitrary depth.\n *\n * SPAN SHAPE. One span per supervised node, opened at spawn and closed at settle, parented to its\n * parent node's span; the run root is the trace. Driver inference rides as an `LLM` child span under\n * the node that metered it. Attributes reuse the vocabulary the rest of the stack already reads\n * (`openinference.span.kind`, `agent.name`, `llm.token_count.*`, `llm.cost_usd`, `tangle.cost.usd`)\n * — see `@tangle-network/agent-eval`'s `src/trace/attribute-vocabulary.ts`, which is the consumer.\n *\n * UNKNOWN IS NEVER ZERO. `Spend.tokensKnown === false` / `usdKnown === false` mark work that\n * HAPPENED with an unreported count. Those spans OMIT the token/cost attribute entirely and set\n * `tangle.supervise.tokens_known` / `tangle.supervise.cost_known` to `false`, so a reader can never\n * mistake an unmeasured turn for a free one.\n */\n\nimport { contentAddress } from '../../durable/spawn-journal'\nimport type { OtelExportConfig, OtelExporter, OtelSpan } from '../../otel-export'\nimport { createOtelExporter, generateSpanId, toOtelAttributes } from '../../otel-export'\nimport type { RuntimeHookEvent, RuntimeHooks } from '../../runtime-hooks'\nimport type { Budget, Spend, SupervisedResult } from './types'\nimport type { TraceContext, WorkerTraceResolver } from './worker-trace'\n\n/** OTEL status codes (`UNSET` / `OK` / `ERROR`) — the numeric wire values `OtelSpan.status` carries. */\nconst STATUS_UNSET = 0\nconst STATUS_OK = 1\nconst STATUS_ERROR = 2\n\n/** Longest string attribute value written from free-form detail, so an oversized turn payload\n * cannot inflate a span. Identity/label attributes we control are never truncated. */\nconst MAX_DETAIL_CHARS = 256\n\n/** OTLP span attribute values. Exported because `SupervisorSpanOptions.attributes` is public and\n * a consumer cannot name the type it is asked to supply otherwise. */\nexport type SupervisorSpanAttributes = Record<string, string | number | boolean>\n\ntype Attrs = SupervisorSpanAttributes\n\nexport interface SupervisorSpanOptions {\n /**\n * The supervised run id (`SupervisorOpts.runId`). Roots the trace, identifies the root span, and\n * is the parent lookup key for every depth-0 spawn (a root scope's `parentId` IS the run id).\n */\n readonly runId: string\n /**\n * Bring your own exporter. It is FLUSHED but never shut down by `finish()` — a caller that owns\n * the exporter owns its lifecycle. Takes precedence over `exportConfig`.\n */\n readonly exporter?: OtelExporter\n /**\n * Otherwise build one with {@link createOtelExporter}. With no `endpoint` here it reads\n * `OTEL_EXPORTER_OTLP_ENDPOINT`, and with neither it resolves to `undefined` — which makes\n * {@link createSupervisorSpanRecorder} return `undefined` and the run emit nothing.\n */\n readonly exportConfig?: OtelExportConfig\n /**\n * Trace id (32 hex chars). Pass the caller's own to JOIN an outer trace. Default: derived\n * deterministically from `runId`, so a resumed run lands in the SAME trace as the process that\n * started it.\n */\n readonly traceId?: string\n /** Parent span id (16 hex chars) to hang the run's root span under — an inherited delegation span. */\n readonly parentSpanId?: string\n /** `agent.name` on the root span. Default `'supervisor'`. */\n readonly agentName?: string\n /** Extra attributes stamped on every span this recorder emits (subject, workspace, campaign, …). */\n readonly attributes?: Attrs\n /** Injectable clock; used only for the root span's start/end. Default `Date.now`. */\n readonly now?: () => number\n}\n\n/** How the supervised run ended, as `finish()` records it on the root span. */\nexport interface SupervisorSpanOutcome {\n readonly result?: SupervisedResult<unknown>\n /** A rejection out of the run itself (the supervisor never resolved). */\n readonly error?: unknown\n}\n\nexport interface SupervisorSpanRecorder {\n /** Attach to `SupervisorOpts.hooks` (compose with a caller's own via `composeRuntimeHooks`). */\n readonly hooks: RuntimeHooks\n /** The trace every span of this run belongs to. */\n readonly traceId: string\n /** The run's root span id — pass it to a child process to join this trace. */\n readonly rootSpanId: string\n /**\n * The trace context a worker spawned BY node `spawningNodeId` should inherit, so its own spans\n * join THIS trace under the span of the node that spawned it. Thread it to a run as\n * `SupervisorOpts.workerTrace` (`supervise()` does this whenever it builds a recorder) and the\n * `Scope` seeds it onto every child's `ExecutorContext`; a backend with an environment channel\n * stamps it with `workerTraceEnv`. An unknown node — one whose span was never opened — resolves\n * to the run's root span rather than to nothing, so a worker is never filed outside its own run.\n */\n readonly workerTrace: WorkerTraceResolver\n /**\n * Close the root span (and any node that never settled, marked as such), export, and flush. Safe\n * to call twice; never throws — a telemetry failure is not a run failure.\n */\n finish(outcome?: SupervisorSpanOutcome): Promise<void>\n}\n\n/** A node span held open between its `agent.spawn` and its `agent.child`. */\ninterface OpenNode {\n readonly spanId: string\n readonly parentSpanId: string\n readonly name: string\n readonly startMs: number\n readonly attrs: Attrs\n}\n\n/**\n * Build the span recorder for one supervised run, or `undefined` when no exporter resolves — the\n * off-by-default path. A run that passes no `exporter` and no `exportConfig` never reaches this\n * function at all; one that passes an `exportConfig` with no endpoint (and no env endpoint) gets\n * `undefined` here, so \"configured but unreachable\" also costs nothing.\n */\nexport function createSupervisorSpanRecorder(\n opts: SupervisorSpanOptions,\n): SupervisorSpanRecorder | undefined {\n const exporter = opts.exporter ?? createOtelExporter(opts.exportConfig)\n if (!exporter) return undefined\n // Only an exporter we built is ours to shut down.\n const ownsExporter = opts.exporter === undefined\n\n const now = opts.now ?? Date.now\n const traceId = normalizeTraceId(opts.traceId, opts.runId)\n const rootSpanId = generateSpanId()\n const rootStartMs = now()\n const base: Attrs = {\n 'tangle.run.id': opts.runId,\n // The sample vocabulary our own OTLP producers already emit; kept so one reader groups a\n // supervised run with a pi/coding-CLI session without a per-producer special case.\n 'tangle.sessionId': opts.runId,\n ...(opts.attributes ?? {}),\n }\n\n /** Node id → its open span. Seeded with the run id ⇒ the root span, because a depth-0 spawn's\n * `parentId` is the run id itself and every deeper spawn's is a real node id. */\n const open = new Map<string, OpenNode>()\n const spanIdOf = new Map<string, string>([[opts.runId, rootSpanId]])\n let finished = false\n\n /** Every export is best-effort: a throwing exporter must never reach the run. */\n const emit = (span: OtelSpan): void => {\n try {\n exporter.exportSpan(span)\n } catch {\n // Telemetry is not the work.\n }\n }\n\n const span = (\n spanId: string,\n parentSpanId: string | undefined,\n name: string,\n startMs: number,\n endMs: number,\n attrs: Attrs,\n status: number,\n message?: string,\n ): OtelSpan => ({\n traceId,\n spanId,\n ...(parentSpanId ? { parentSpanId } : {}),\n name,\n kind: 1,\n startTimeUnixNano: msToNano(startMs),\n endTimeUnixNano: msToNano(Math.max(startMs, endMs)),\n attributes: toOtelAttributes(attrs),\n status: { code: status, ...(message ? { message } : {}) },\n })\n\n function onSpawn(event: RuntimeHookEvent): void {\n const p = record(event.payload)\n const childId = str(p.childId)\n if (!childId) return\n const label = str(p.label) ?? 'node'\n const runtime = str(p.runtime)\n const isWait = runtime === 'wait'\n const attrs: Attrs = {\n ...base,\n // A wait-state node holds no executor and burns nothing; `CHAIN` keeps a token/cost reader\n // from counting it as an agent that reported nothing.\n 'openinference.span.kind': isWait ? 'CHAIN' : 'AGENT',\n 'agent.name': label,\n 'tangle.supervise.node.id': childId,\n 'tangle.supervise.node.label': label,\n 'tangle.supervise.node.kind': isWait ? 'wait' : 'agent',\n // The journal tree this node lives in: a nested driver subtree gets its own tree key, which\n // is what joins a span back to the journal rows that prove its spend.\n 'tangle.supervise.tree.root': event.runId,\n }\n if (event.parentId) attrs['tangle.supervise.node.parent_id'] = event.parentId\n if (runtime) attrs['tangle.supervise.node.runtime'] = runtime\n if (typeof p.depth === 'number') attrs['tangle.supervise.node.depth'] = p.depth\n if (typeof event.stepIndex === 'number')\n attrs['tangle.supervise.node.ordinal'] = event.stepIndex\n if (p.resumed === true) attrs['tangle.supervise.node.resumed'] = true\n assignBudget(attrs, p.budget)\n\n const spanId = generateSpanId()\n spanIdOf.set(childId, spanId)\n open.set(childId, {\n spanId,\n parentSpanId: (event.parentId && spanIdOf.get(event.parentId)) || rootSpanId,\n name: label,\n startMs: event.timestamp,\n attrs,\n })\n }\n\n function onSettled(event: RuntimeHookEvent): void {\n const p = record(event.payload)\n const childId = str(p.childId)\n if (!childId) return\n const node = open.get(childId)\n if (!node) return\n open.delete(childId)\n\n const status = str(p.status)\n const down = status === 'down'\n const attrs: Attrs = { ...node.attrs, 'tangle.supervise.node.status': status ?? 'done' }\n if (typeof event.stepIndex === 'number') attrs['tangle.supervise.node.seq'] = event.stepIndex\n if (typeof p.outRef === 'string') attrs['tangle.supervise.node.out_ref'] = p.outRef\n if (typeof p.valid === 'boolean') attrs['tangle.supervise.verdict.valid'] = p.valid\n if (typeof p.score === 'number') attrs['tangle.supervise.verdict.score'] = p.score\n if (down) {\n attrs['error.type'] = p.infra === true ? 'infra' : 'child-down'\n const reason = str(p.reason)\n if (reason) attrs['error.message'] = truncate(reason)\n if (typeof p.infra === 'boolean') attrs['tangle.supervise.node.infra'] = p.infra\n }\n // A wait node settles with its outcome instead of a spend — free by construction, not by\n // measurement, so it carries no token or cost attribute at all.\n const wait = record(p.wait)\n const wokeBy = str(wait.settled)\n if (wokeBy) attrs['tangle.supervise.wait.settled'] = wokeBy\n assignSpend(attrs, p.spent)\n\n emit(\n span(\n node.spanId,\n node.parentSpanId,\n node.name,\n node.startMs,\n event.timestamp,\n attrs,\n down ? STATUS_ERROR : STATUS_OK,\n down ? (str(p.reason) ?? 'child down') : undefined,\n ),\n )\n }\n\n function onTurn(event: RuntimeHookEvent): void {\n const p = record(event.payload)\n const parentId = event.parentId\n const parentSpanId = (parentId && spanIdOf.get(parentId)) || rootSpanId\n const attrs: Attrs = {\n ...base,\n 'openinference.span.kind': 'LLM',\n 'inference.observation_kind': 'LLM',\n 'tangle.supervise.node.kind': 'inference',\n }\n if (parentId) attrs['tangle.supervise.node.id'] = parentId\n // Free-form `Scope.meter` detail: named keys get the canonical attribute, the rest ride\n // namespaced and bounded so a caller's extra context survives without unbounded span growth.\n for (const [key, value] of Object.entries(p)) {\n if (key === 'spend') continue\n if (key === 'driver' && typeof value === 'string') {\n attrs['agent.name'] = value\n attrs['inference.agent_name'] = value\n continue\n }\n if (key === 'model' && typeof value === 'string') {\n attrs['llm.model_name'] = value\n continue\n }\n if (Array.isArray(value)) {\n const scalars = value.filter((v) => typeof v === 'string' || typeof v === 'number')\n if (scalars.length > 0) {\n attrs[`tangle.supervise.turn.${key}`] = truncate(scalars.join(','))\n }\n continue\n }\n if (typeof value === 'string') attrs[`tangle.supervise.turn.${key}`] = truncate(value)\n else if (typeof value === 'number' || typeof value === 'boolean') {\n attrs[`tangle.supervise.turn.${key}`] = value\n }\n }\n const spend = assignSpend(attrs, p.spend)\n const endMs = event.timestamp + (spend?.ms ?? 0)\n emit(\n span(\n generateSpanId(),\n parentSpanId,\n 'gen_ai.client.inference',\n event.timestamp,\n endMs,\n attrs,\n STATUS_OK,\n ),\n )\n }\n\n const hooks: RuntimeHooks = {\n onEvent(event) {\n if (finished) return\n try {\n if (event.phase !== 'after') return\n if (event.target === 'agent.spawn') onSpawn(event)\n else if (event.target === 'agent.child') onSettled(event)\n else if (event.target === 'agent.turn') onTurn(event)\n } catch {\n // A malformed payload or a broken exporter is a telemetry defect, never a run failure.\n // `notifyRuntimeHookEvent` would already contain a throw; this makes it true regardless of\n // who calls the hook.\n }\n },\n }\n\n return {\n hooks,\n traceId,\n rootSpanId,\n workerTrace(spawningNodeId: string): TraceContext {\n return { traceId, parentSpanId: spanIdOf.get(spawningNodeId) ?? rootSpanId }\n },\n async finish(outcome?: SupervisorSpanOutcome): Promise<void> {\n if (finished) return\n finished = true\n const endMs = now()\n try {\n // A node still open here never settled — the run was aborted, cancelled, or died with it in\n // flight. Its span is closed UNSET and explicitly marked, never silently dropped and never\n // reported as a clean finish.\n for (const [nodeId, node] of open) {\n emit(\n span(\n node.spanId,\n node.parentSpanId,\n node.name,\n node.startMs,\n endMs,\n {\n ...node.attrs,\n 'tangle.supervise.node.status': 'unsettled',\n 'tangle.supervise.node.settled': false,\n 'tangle.supervise.node.id': nodeId,\n },\n STATUS_UNSET,\n ),\n )\n }\n open.clear()\n emit(\n span(\n rootSpanId,\n opts.parentSpanId,\n 'supervisor.run',\n rootStartMs,\n endMs,\n rootAttrs(base, opts.agentName ?? 'supervisor', outcome),\n rootStatus(outcome),\n rootMessage(outcome),\n ),\n )\n await exporter.flush()\n if (ownsExporter) await exporter.shutdown()\n } catch {\n // Telemetry is not the work.\n }\n },\n }\n}\n\n// ── Attribute mapping ─────────────────────────────────────────────────────────\n\nfunction rootAttrs(base: Attrs, agentName: string, outcome?: SupervisorSpanOutcome): Attrs {\n const attrs: Attrs = {\n ...base,\n 'openinference.span.kind': 'AGENT',\n 'inference.observation_kind': 'AGENT',\n 'agent.name': agentName,\n 'inference.agent_name': agentName,\n 'tangle.supervise.node.kind': 'root',\n }\n const result = outcome?.result\n if (result) {\n attrs['tangle.supervise.result'] = result.kind\n if (result.kind === 'no-winner') {\n attrs['tangle.supervise.reason'] = result.reason\n attrs['tangle.supervise.down_count'] = result.downCount\n if (result.reason === 'driver-failed') {\n attrs['error.type'] = result.error.name\n attrs['error.message'] = truncate(result.error.message)\n }\n }\n assignSpend(attrs, result.spentTotal)\n }\n if (outcome?.error !== undefined) {\n attrs['tangle.supervise.result'] = 'error'\n const err = outcome.error\n attrs['error.type'] = err instanceof Error ? err.name : typeof err\n attrs['error.message'] = truncate(err instanceof Error ? err.message : String(err))\n }\n return attrs\n}\n\nfunction rootStatus(outcome?: SupervisorSpanOutcome): number {\n if (outcome?.error !== undefined) return STATUS_ERROR\n if (!outcome?.result) return STATUS_UNSET\n return outcome.result.kind === 'winner' ? STATUS_OK : STATUS_ERROR\n}\n\nfunction rootMessage(outcome?: SupervisorSpanOutcome): string | undefined {\n if (outcome?.error !== undefined) {\n return truncate(outcome.error instanceof Error ? outcome.error.message : String(outcome.error))\n }\n const result = outcome?.result\n return result && result.kind === 'no-winner' ? result.reason : undefined\n}\n\n/**\n * Write a `Spend` onto a span, honouring the \"a missing measurement is never zero\" invariant: a\n * channel marked NOT known contributes no number at all and instead flags itself, so nothing\n * downstream can sum an unmeasured turn as free. Returns the spend it read (for the duration).\n */\nfunction assignSpend(attrs: Attrs, value: unknown): Spend | undefined {\n if (!isRecord(value)) return undefined\n const spend = value as unknown as Spend\n const tokens = isRecord(spend.tokens) ? spend.tokens : undefined\n if (spend.tokensKnown === false) {\n attrs['tangle.supervise.tokens_known'] = false\n } else if (tokens) {\n if (typeof tokens.input === 'number') attrs['llm.token_count.prompt'] = tokens.input\n if (typeof tokens.output === 'number') attrs['llm.token_count.completion'] = tokens.output\n }\n if (spend.usdKnown === false) {\n attrs['tangle.supervise.cost_known'] = false\n } else if (typeof spend.usd === 'number' && Number.isFinite(spend.usd)) {\n attrs['llm.cost_usd'] = spend.usd\n attrs['tangle.cost.usd'] = spend.usd\n }\n if (typeof spend.iterations === 'number') attrs['tangle.supervise.iterations'] = spend.iterations\n if (typeof spend.ms === 'number' && spend.ms > 0) attrs['tangle.supervise.duration_ms'] = spend.ms\n return spend\n}\n\nfunction assignBudget(attrs: Attrs, value: unknown): void {\n if (!isRecord(value)) return\n const budget = value as unknown as Budget\n if (typeof budget.maxTokens === 'number') {\n attrs['tangle.supervise.budget.max_tokens'] = budget.maxTokens\n }\n if (typeof budget.maxIterations === 'number') {\n attrs['tangle.supervise.budget.max_iterations'] = budget.maxIterations\n }\n if (typeof budget.maxUsd === 'number') attrs['tangle.supervise.budget.max_usd'] = budget.maxUsd\n}\n\n// ── Small helpers ─────────────────────────────────────────────────────────────\n\n/**\n * A trace id must be 32 hex characters. A caller-supplied one is used verbatim when it already is;\n * anything else (and the default) is DERIVED from the run id by content address — deterministic, so\n * a resumed run rejoins the trace its first process opened rather than forking a new one.\n */\nfunction normalizeTraceId(traceId: string | undefined, runId: string): string {\n if (traceId && /^[0-9a-f]{32}$/i.test(traceId)) return traceId.toLowerCase()\n return contentAddress(traceId ?? runId).slice('sha256:'.length, 'sha256:'.length + 32)\n}\n\nfunction msToNano(ms: number): string {\n const safe = Number.isFinite(ms) ? Math.floor(ms) : 0\n return (BigInt(safe) * 1_000_000n).toString()\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {}\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction truncate(value: string): string {\n return value.length > MAX_DETAIL_CHARS ? `${value.slice(0, MAX_DETAIL_CHARS)}…` : value\n}\n","/**\n * Durable side-log for the coordination bus: questions and analyst findings, the two UP-leg\n * message kinds the spawn journal does NOT record (it owns spawns/settlements/waits/spend). A\n * durable run (`supervise({ runDir })`) appends them as they publish and replays them on resume,\n * so a restarted coordinator still sees the questions its workers raised and the findings its\n * analysts produced — instead of losing both with the process.\n *\n * Answer down-events are logged too, ONLY to fold status on load: a question answered before the\n * crash reloads as `answered`, not as a re-blocking `open`. Settled events are skipped (the spawn\n * journal is their ledger); steer events are skipped (a delivered steer to a dead worker has no\n * meaning to a new process).\n *\n * JSONL, one fsynced record per event, keyed by `runId` — several runs may share one log file\n * exactly as they share one spawn-journal file.\n *\n * @experimental\n */\n\nimport type {\n AnalystFindingEvent,\n CoordinationEvent,\n QuestionRecord,\n} from '../../mcp/tools/coordination'\n\n/** What a prior process's coordination log replays into a resumed driver. */\nexport interface PriorCoordination {\n /** Every question the prior process raised, with answer-status folded in, raise order. */\n readonly questions: ReadonlyArray<QuestionRecord>\n /** Every analyst finding the prior process published, publish order. */\n readonly findings: ReadonlyArray<AnalystFindingEvent>\n}\n\n/** The durable coordination side-log seam. `append` records one bus event (kinds it does not\n * persist are ignored); `load` replays a run's prior records folded into `PriorCoordination`. */\nexport interface CoordinationLog {\n append(runId: string, event: CoordinationEvent, at: string): Promise<void>\n load(runId: string): Promise<PriorCoordination>\n}\n\ntype CoordinationLogRecord = {\n readonly runId: string\n readonly at: string\n readonly event: CoordinationEvent\n}\n\n/** Should this bus event be persisted? Questions and findings ARE the prior context a resumed\n * driver needs; answers fold their status; everything else has a better ledger or none. */\nfunction persisted(event: CoordinationEvent): boolean {\n return event.type === 'question' || event.type === 'finding' || event.type === 'answer'\n}\n\n/** FS-backed `CoordinationLog`: append-only JSONL, fsynced per record. */\nexport class FileCoordinationLog implements CoordinationLog {\n constructor(private readonly path: string) {}\n\n async append(runId: string, event: CoordinationEvent, at: string): Promise<void> {\n if (!persisted(event)) return\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n await fs.mkdir(path.dirname(this.path), { recursive: true })\n const record: CoordinationLogRecord = { runId, at, event }\n const fh = await fs.open(this.path, 'a')\n try {\n await fh.write(`${JSON.stringify(record)}\\n`)\n await fh.sync()\n } finally {\n await fh.close()\n }\n }\n\n async load(runId: string): Promise<PriorCoordination> {\n const fs = await import('node:fs/promises')\n let text: string\n try {\n text = await fs.readFile(this.path, 'utf8')\n } catch (err) {\n if (isNoEntError(err)) return { questions: [], findings: [] }\n throw err\n }\n const byId = new Map<string, QuestionRecord>()\n const findings: AnalystFindingEvent[] = []\n for (const line of text.split('\\n')) {\n if (line.length === 0) continue\n const record = JSON.parse(line) as CoordinationLogRecord\n if (record.runId !== runId) continue\n const ev = record.event\n if (ev.type === 'question') {\n byId.set(ev.question.id, ev.question)\n } else if (ev.type === 'finding') {\n findings.push(ev.finding)\n } else if (ev.type === 'answer') {\n // Fold the answer into the question it decided, so an answered blocking question does\n // not reload as open and re-block the resumed run's stop. `by` is not on the wire —\n // the honest attribution is the prior run itself.\n const prior = byId.get(ev.questionId)\n if (prior) {\n byId.set(ev.questionId, {\n ...prior,\n status: 'answered',\n decision: { kind: 'answer', answer: ev.down.instruction, by: 'prior-run' },\n })\n }\n }\n }\n return { questions: [...byId.values()], findings }\n }\n}\n\nfunction isNoEntError(err: unknown): boolean {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n (err as { code: unknown }).code === 'ENOENT'\n )\n}\n","/**\n *\n * `acquireSandbox` — cold-start-resilient sandbox acquisition. Eliminates the\n * \"create timed out at the proxy\" failure mode conceptually by DECOUPLING \"the\n * create HTTP call returned\" from \"the sandbox is ready\":\n *\n * - Create is initiated with a known `name`.\n * - Readiness is observed from the sandbox's own `status` (`refresh()` polls\n * true state), NOT from whether the create call returned in time.\n * - If the create call itself times out at a gateway (502/503/504/522/524 or\n * a transport timeout), provisioning is still running server-side — so we\n * find the named sandbox via `list()` and wait for it to reach `running`.\n *\n * Result: a scale-from-zero cold start (node boot + host-agent registration,\n * minutes) can no longer surface as a create failure behind a ~100s proxy\n * limit. The loop becomes indifferent to whether the host pool is warm or cold.\n *\n * Invariant: an instance reporting no `status` (the minimal test fakes) is\n * treated as ready; only an explicit `pending`/`provisioning` status triggers\n * waiting, and only a retryable THROW triggers the find-by-name path. Real\n * errors (auth, validation, budget) fail loud. A box that is created (or found)\n * but never reaches `running` (abort, terminal status, budget) is torn down\n * before the failure propagates, so an abort storm during cold start does not\n * leak live sandboxes.\n *\n * @experimental\n */\n\nimport type { CreateSandboxOptions, SandboxInstance } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { SandboxClient } from './types'\nimport { sleep as abortableSleep, deleteBoxSafe, randomUuid, throwIfAborted } from './util'\n\n/**\n * HTTP statuses where create should be retried — gateway timeouts\n * (502/503/504/522/524) where provisioning may continue server-side, plus\n * request-level retryables (408/425/429).\n */\nconst RETRYABLE_HTTP = new Set([502, 503, 504, 522, 524, 408, 425, 429])\nconst TERMINAL_STATUS = new Set(['failed', 'expired', 'stopped'])\n\n/** @experimental */\nexport interface AcquireOptions {\n /**\n * Total budget for the sandbox to reach `running`, covering on-demand node\n * cold-start. Default 600_000ms — matches the orchestrator's pending-host\n * registration window so we never give up before the platform itself would.\n */\n readyTimeoutMs?: number\n /** Poll interval while waiting for `running` / for the named sandbox to appear. */\n pollIntervalMs?: number\n /** Cancellation (user abort). Distinct from create-call timeouts. */\n signal?: AbortSignal\n /** Stamp a name so a timed-out create is recoverable by lookup. Auto-generated if absent. */\n name?: string\n /** Clock override for deterministic tests. */\n now?: () => number\n /** Sleep override for deterministic tests. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Minimal client surface acquire needs beyond `create` (the real SDK satisfies it). */\ninterface PollableClient extends SandboxClient {\n list?: (options?: unknown) => Promise<SandboxInstance[]>\n get?: (id: string) => Promise<SandboxInstance | null>\n}\n\n/**\n * Cold-start-resilient sandbox acquisition: create by name, observe readiness from the sandbox's own status (not the create call), and re-attach after gateway timeouts.\n *\n * @experimental\n */\nexport async function acquireSandbox(\n client: SandboxClient,\n options: CreateSandboxOptions,\n acquire: AcquireOptions = {},\n): Promise<SandboxInstance> {\n if (!client || typeof client.create !== 'function') {\n throw new ValidationError('acquireSandbox: client.create is required')\n }\n const now = acquire.now ?? Date.now\n const sleep = acquire.sleep ?? ((ms: number) => abortableSleep(ms, acquire.signal))\n const pollMs = acquire.pollIntervalMs ?? 3000\n const deadline = now() + (acquire.readyTimeoutMs ?? 600_000)\n // After a retryable create error (commonly a gateway/request timeout on a cold\n // scale-from-zero), the orchestrator has usually ACCEPTED the request and is\n // still provisioning the NAMED box — which appears in list() a few seconds\n // AFTER the create call gave up. Scan list() this many windows for it to\n // appear before re-POSTing: re-creating immediately restarts a fresh cold\n // provision and hits the same wall — that thrash is why a cold acquire never\n // converges within the budget; attaching to the in-flight box does.\n const appearScans = 5\n // crypto.randomUUID is collision-resistant — find-by-name recovery scans\n // list() for this exact name, so two concurrent acquires must never collide.\n const name = options.name ?? acquire.name ?? `loop-sbx-${randomUuid()}`\n const createOpts: CreateSandboxOptions = { ...options, name }\n const c = client as PollableClient\n\n let lastErr: unknown\n let attempt = 0\n while (now() < deadline) {\n throwIfAborted(acquire.signal)\n try {\n const box = await client.create(createOpts)\n // Tear the just-created box down if it never reaches `running` (abort,\n // terminal status, budget) so a failed wait never leaks a live sandbox.\n return await waitReadyOrDestroy(box, deadline, pollMs, acquire.signal, now, sleep)\n } catch (err) {\n throwIfAborted(acquire.signal)\n // Non-retryable (auth/validation/budget) fails loud immediately.\n if (!isRetryable(err)) throw err\n lastErr = err\n // Recovery for a gateway-timed-out create, in order:\n // (a) the orchestrator usually ACCEPTED the create and is provisioning\n // the named box — it appears in list() a few seconds later, so poll\n // for it across `appearScans` windows and attach (this is the cold-\n // start fix: a single scan misses a row not yet written and the loop\n // would otherwise re-POST a fresh cold provision every backoff);\n // (b) only if it never appears did the create truly roll back — retry\n // create with backoff (lands once a warm host exists / autoscaler\n // caught up).\n if (typeof c.list === 'function') {\n for (let scan = 0; scan < appearScans && now() < deadline; scan += 1) {\n const found = (await c.list().catch(() => []))?.find((b) => b.name === name)\n if (found)\n return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep)\n if (scan < appearScans - 1) await sleep(pollMs)\n }\n }\n attempt += 1\n await sleep(Math.min(pollMs * attempt, 15_000))\n }\n }\n throw new ValidationError(\n `acquireSandbox: could not acquire a running sandbox \"${name}\" within budget`,\n { cause: lastErr instanceof Error ? lastErr : undefined },\n )\n}\n\n/** `waitUntilReady`, tearing the box down (best-effort) on any throw so a box\n * that never reaches `running` (abort, terminal status, budget) does not leak. */\nasync function waitReadyOrDestroy(\n box: SandboxInstance,\n deadline: number,\n pollMs: number,\n signal: AbortSignal | undefined,\n now: () => number,\n sleep: (ms: number) => Promise<void>,\n): Promise<SandboxInstance> {\n try {\n return await waitUntilReady(box, deadline, pollMs, signal, now, sleep)\n } catch (err) {\n await deleteBoxSafe(box)\n throw err\n }\n}\n\n/** Wait for `running`. No status (minimal fakes) = ready. Terminal status throws. */\nasync function waitUntilReady(\n box: SandboxInstance,\n deadline: number,\n pollMs: number,\n signal: AbortSignal | undefined,\n now: () => number,\n sleep: (ms: number) => Promise<void>,\n): Promise<SandboxInstance> {\n for (;;) {\n throwIfAborted(signal)\n const status = readStatus(box)\n if (status === undefined || status === 'running') return box\n if (TERMINAL_STATUS.has(status)) {\n throw new ValidationError(\n `acquireSandbox: sandbox ${box.id ?? '(unknown)'} is ${status}${box.error ? `: ${box.error}` : ''}`,\n )\n }\n if (now() >= deadline) {\n throw new ValidationError(\n `acquireSandbox: sandbox ${box.id ?? '(unknown)'} not running within budget (last status: ${status})`,\n )\n }\n await sleep(pollMs)\n if (typeof box.refresh === 'function') await box.refresh()\n }\n}\n\nfunction readStatus(box: SandboxInstance): string | undefined {\n const s = (box as { status?: unknown }).status\n return typeof s === 'string' ? s : undefined\n}\n\nfunction isRetryable(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n const e = err as { status?: number; statusCode?: number; name?: string; message?: string }\n const status = e.status ?? e.statusCode\n if (typeof status === 'number' && RETRYABLE_HTTP.has(status)) return true\n const name = e.name ?? ''\n if (name === 'TimeoutError' || name === 'ServerError' || name === 'NetworkError') return true\n const msg = e.message ?? ''\n // Transient TRANSPORT failures.\n if (\n /\\b(timed out|timeout|gateway|temporarily unavailable|too many requests|ECONNRESET|ETIMEDOUT|EAI_AGAIN)\\b/i.test(\n msg,\n )\n ) {\n return true\n }\n // Transient PLATFORM provisioning failures thrown by `create` itself — edge data\n // plane unreachable, container-phase provision failure, or a rolled-back create.\n // Retry create onto a FRESH host rather than failing the whole rollout; the loop\n // stays bounded by the ready deadline. A box that booted and then reached a\n // terminal `failed` status with a real error is NOT retried here — that's a genuine\n // fault surfaced by `waitUntilReady`, not a host blip.\n return /provision failed|edge data plane|not reachable|failed to create sandbox/i.test(msg)\n}\n","/**\n *\n * Capability probe for the loop kernel's backend-blind lineage seams. The\n * kernel must NEVER ask \"is this Docker or Firecracker?\"; it asks \"can this\n * platform fork a checkpoint?\" via `client.criuStatus()` and degrades to fresh\n * boxes when the answer is no. CRIU availability is a per-platform fact, so the\n * probe is memoized per client — one network round-trip, reused across every\n * fanout in the run.\n *\n * Invariant: a client with no `criuStatus` method (the loop's test fakes, the\n * raw SDK before it grew the probe) reports `canFork = false`. The seam is\n * fail-CLOSED — never assume forking works, only enable it on a positive probe.\n *\n * @experimental\n */\n\nimport type { SandboxClient } from './types'\n\n/**\n * What the loop kernel is allowed to know about a sandbox backend: a single\n * capability bit, never the backend's identity. `canFork` gates the\n * checkpoint+fork fanout path; everything else (session continuation) is a\n * universal SDK feature that needs no probe.\n *\n * @experimental\n */\nexport interface SandboxCapabilities {\n /**\n * True only when `client.criuStatus()` returned `{ available: true }`. When\n * false, a fork-enabled fanout degrades to independent fresh boxes — same\n * result, no shared context prefix.\n */\n canFork: boolean\n}\n\nconst probeCache = new WeakMap<object, Promise<SandboxCapabilities>>()\n\n/**\n * Probe (and memoize per client) what the loop may rely on. A client without a\n * `criuStatus` method, or whose probe rejects, yields `canFork = false` — a\n * failed probe must never claim a capability the platform may not have. The\n * promise is cached so concurrent fanout branches share one round-trip.\n *\n * @experimental\n */\nexport function probeSandboxCapabilities(client: SandboxClient): Promise<SandboxCapabilities> {\n const key = client as unknown as object\n const cached = probeCache.get(key)\n if (cached) return cached\n const probe = resolveCapabilities(client)\n probeCache.set(key, probe)\n return probe\n}\n\nasync function resolveCapabilities(client: SandboxClient): Promise<SandboxCapabilities> {\n const criuStatus = (client as CriuCapableClient).criuStatus\n if (typeof criuStatus !== 'function') return { canFork: false }\n try {\n const status = await criuStatus.call(client)\n return { canFork: status?.available === true }\n } catch {\n // A probe that throws (transport error, unsupported endpoint) is treated as\n // \"no fork\" — fail closed so a flaky probe degrades to fresh boxes rather\n // than attempting a checkpoint the platform can't honor.\n return { canFork: false }\n }\n}\n\n/**\n * Narrowed view of the optional CRIU probe. The loop-side `SandboxClient`\n * does not require `criuStatus`; this widens it optionally so the probe can be\n * read without importing sandbox-backend specifics. @experimental\n */\nexport interface CriuCapableClient {\n criuStatus?: () => Promise<{ available: boolean; criuVersion?: string; reason?: string }>\n}\n","/**\n *\n * `SandboxLineage` — the backend-blind owner of box + session handles for a\n * single `runAgentRounds` invocation. It exists so `run-loop.ts` never references a\n * backend (Docker / Firecracker): the lineage turns \"continue this session\" and\n * \"fork this branch\" into capability-gated sandbox-SDK calls and degrades to\n * fresh boxes when a capability is absent.\n *\n * Three operations, mirroring the kernel's per-iteration choices:\n * - `start(spec, prompt)` → a fresh box; the FIRST `streamPrompt` carries a\n * minted `sessionId` so later `continue` calls reuse the same server-side\n * conversation instead of re-injecting prior context as prompt text.\n * - `continue(handle, prompt)` → the SAME box, `streamPrompt({ sessionId })`.\n * The context lives in the sandbox; the prompt is only the new turn. Before\n * streaming it ASSERTS the session is still live server-side (via\n * `box.session(id).status()`): if the platform never honored the\n * client-minted id (or reaped it), `status()` is `null` and `continue`\n * fails loud rather than silently re-running the turn without prior context.\n * - `fork(handle, n, ...)` → when `canFork`, `checkpoint({ leaveRunning })` on\n * the parent then `fork(checkpointId)` × n so N branches inherit a shared\n * context prefix; otherwise N independent fresh boxes (same result, no\n * prefix). Either way each branch streams its own turn. Child-box creation\n * is bounded by the lineage's `maxConcurrency` — a 20-way fanout under a\n * concurrency cap of 2 provisions boxes in bounded waves, not all at once.\n *\n * Invariant: the lineage OWNS every box it starts or forks and tears them all\n * down on `teardown()` (or earlier via `prune`). It never tears down a box\n * mid-flight — the kernel decides when a handle is done. Streaming itself stays\n * in `run-loop.ts`; the lineage only hands back the live `streamPrompt` iterable\n * so the kernel keeps ownership of event collection, cost accounting, and trace\n * emission.\n *\n * @experimental\n */\n\nimport type {\n CreateSandboxOptions,\n PromptOptions,\n SandboxEvent,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport { acquireSandbox } from './sandbox-acquire'\nimport { buildBackendOptions } from './sandbox-backend'\nimport type { SandboxCapabilities } from './sandbox-capabilities'\nimport type { AgentRunSpec, MountRecorder, SandboxClient } from './types'\nimport {\n deleteBoxSafe,\n mapWithConcurrency,\n randomUuid,\n throwAbort,\n throwIfAborted,\n withTimeout,\n} from './util'\n\nconst TEARDOWN_TIMEOUT_MS = 15_000\nconst DEFAULT_FORK_CONCURRENCY = 4\n\n/**\n * One turn's event stream, in the lineage's chosen streaming mode.\n *\n * - `'sse'` (default): live `streamPrompt` — low latency, full per-token trace.\n * Best for interactive chat.\n * - `'poll'`: fire-and-detach via `dispatchPrompt`, await the terminal result by\n * status-polling (NOT a held SSE), then yield the answer as one synthesized\n * event. A long, quiet in-box turn (clone + build + test) never holds a live\n * stream a proxy idle-timeout can drop mid-execution — the failure mode that\n * made batch eval runs lose their stream on both prod and staging. Lower trace\n * fidelity (one terminal event, not per-token), so it is opt-in for batch.\n *\n * Both yield the same `SandboxEvent` vocabulary, so callers are agnostic.\n */\nasync function* pollPromptEvents(\n box: SandboxInstance,\n prompt: string,\n sessionId: string,\n signal: AbortSignal,\n promptOptions?: Omit<PromptOptions, 'signal' | 'sessionId'>,\n): AsyncIterable<SandboxEvent> {\n if (signal.aborted) throwAbort()\n // dispatchPrompt returns the session id the platform actually assigned, which\n // may be one it MINTED rather than the supplied `sessionId`. Polling the\n // supplied id when the platform minted a different one 404s the session-events\n // endpoint (\"Resource not found\"). Always follow the assigned id.\n const dispatched = await box.dispatchPrompt(prompt, {\n ...(promptOptions ?? {}),\n sessionId,\n signal,\n })\n const activeSessionId = dispatched.sessionId\n const result = await box.session(activeSessionId).result()\n if (signal.aborted) throwAbort()\n yield {\n type: 'result',\n id: activeSessionId,\n data: {\n finalText: result.response ?? '',\n success: result.success,\n ...(result.error ? { error: result.error } : {}),\n ...(result.usage ? { usage: result.usage } : {}),\n },\n }\n}\n\nexport function promptEvents(\n streaming: 'sse' | 'poll',\n box: SandboxInstance,\n prompt: string,\n sessionId: string,\n signal: AbortSignal,\n promptOptions?: Omit<PromptOptions, 'signal' | 'sessionId'>,\n): AsyncIterable<SandboxEvent> {\n return streaming === 'poll'\n ? pollPromptEvents(box, prompt, sessionId, signal, promptOptions)\n : box.streamPrompt(prompt, { ...(promptOptions ?? {}), sessionId, signal })\n}\n\n/**\n * A live box plus the session that threads its iterations together. Handed back\n * by `start`/`fork`, passed into `continue`/`fork` to descend from. Opaque to\n * the kernel beyond `box` (for placement/teardown) and `sessionId` (trace).\n *\n * @experimental\n */\nexport interface SandboxLineageHandle {\n /** The owned, running sandbox this handle drives. */\n box: SandboxInstance\n /**\n * Stable session id threaded through this box's `streamPrompt` calls. Minted\n * by the lineage on `start`; reused on `continue` so the server continues the\n * same conversation. A forked handle starts a fresh session on its new box —\n * the shared context comes from the checkpoint, not a shared session id.\n */\n sessionId: string\n}\n\n/**\n * Owns box + session handles for one loop run and offers the three\n * capability-gated lifecycle moves. Construct via `createSandboxLineage`.\n *\n * @experimental\n */\nexport interface SandboxLineage {\n /**\n * Acquire a fresh box and begin a new session on it. Returns the handle and\n * the live `streamPrompt` iterable for the first turn (caller drains it).\n */\n start(\n spec: AgentRunSpec<unknown>,\n prompt: string,\n signal: AbortSignal,\n promptOptions?: Omit<PromptOptions, 'signal' | 'sessionId'>,\n ): Promise<{ handle: SandboxLineageHandle; events: AsyncIterable<SandboxEvent> }>\n /**\n * Continue an existing handle's session with one more turn on the SAME box.\n * The prior context is server-side; `prompt` is only the new turn. Asserts the\n * session is still known to the sandbox first (fail-loud) so a platform that\n * silently dropped the client-minted session id surfaces as an error instead\n * of a contextless turn the caller mistakes for a real continuation.\n */\n continue(\n handle: SandboxLineageHandle,\n prompt: string,\n signal: AbortSignal,\n promptOptions?: Omit<PromptOptions, 'signal' | 'sessionId'>,\n ): Promise<AsyncIterable<SandboxEvent>>\n /**\n * Branch `count` children from `parent`. When the platform can fork, each\n * child inherits `parent`'s checkpoint — and therefore the parent's IMAGE and\n * PROFILE: under a real fork `specs[i]` does NOT re-select a per-branch\n * profile (the SDK forks the running box, it can't swap the image). `specs[i]`\n * picks the per-branch profile ONLY on the degraded fresh-box path (no CRIU).\n * A heterogeneous-profile fanout therefore homogenizes to the parent's profile\n * when fork is available — pass a single shared spec for forked fanouts, or\n * use `random@k` (no fork) when branches must differ. Each child's first turn\n * streams `prompts[i]`. Child-box creation is bounded by `maxConcurrency`.\n */\n fork(\n parent: SandboxLineageHandle,\n prompts: string[],\n specs: AgentRunSpec<unknown>[],\n signal: AbortSignal,\n ): Promise<{ handle: SandboxLineageHandle; events: AsyncIterable<SandboxEvent> }[]>\n /**\n * Destroy every owned box whose handle is NOT in `keep`, freeing it before\n * loop end. The kernel calls this after a round when it can prove no future\n * round will descend from the pruned boxes (deterministic, monotonic branch\n * selection); boxes still reachable as a future branch source are retained.\n * Best-effort, bounded, parallel — a failed delete never throws.\n */\n prune(keep: Iterable<SandboxLineageHandle>): Promise<void>\n /** Destroy every box this lineage owns. Best-effort, bounded, parallel. */\n teardown(): Promise<void>\n}\n\n/**\n * Build a lineage bound to one client + its probed capabilities. The\n * capabilities are passed in (not re-probed) so the kernel probes once per run\n * and the lineage stays a pure function of \"what this platform can do\".\n *\n * @experimental\n */\nexport function createSandboxLineage(\n client: SandboxClient,\n capabilities: SandboxCapabilities,\n options: {\n maxConcurrency?: number\n streaming?: 'sse' | 'poll'\n /** Run provenance recorder forwarded to every `prepareBox` the lineage runs\n * (fresh start, continue, and fork branches). Absent ⇒ mounts go unrecorded\n * (a no-op recorder stands in so the ctx shape is always satisfied). */\n recordMount?: MountRecorder\n } = {},\n): SandboxLineage {\n if (!client || typeof client.create !== 'function') {\n throw new ValidationError('createSandboxLineage: client.create is required')\n }\n // 'sse' (default) preserves the byte-identical live-stream behavior; 'poll' is\n // the drop-resilient fire-and-detach path for long, quiet batch turns.\n const streaming = options.streaming ?? 'sse'\n const recordMount: MountRecorder = options.recordMount ?? (() => {})\n // Bounds the burst of box creation inside `fork` so an N-way fanout doesn't\n // provision N boxes simultaneously regardless of the loop's concurrency cap.\n const forkConcurrency = Math.max(\n 1,\n Math.floor(options.maxConcurrency ?? DEFAULT_FORK_CONCURRENCY),\n )\n const owned: SandboxInstance[] = []\n\n const acquireFresh = async (\n spec: AgentRunSpec<unknown>,\n signal: AbortSignal,\n ): Promise<SandboxInstance> => {\n if (signal.aborted) throwAbort()\n const opts: CreateSandboxOptions = buildBackendOptions(spec.profile, spec.sandboxOverrides)\n const box = await acquireSandbox(client, opts, { signal })\n await spec.prepareBox?.(box, { signal, recordMount })\n owned.push(box)\n return box\n }\n\n return {\n async start(spec, prompt, signal, promptOptions) {\n const box = await acquireFresh(spec, signal)\n const sessionId = mintSessionId()\n const events = promptEvents(streaming, box, prompt, sessionId, signal, promptOptions)\n return { handle: { box, sessionId }, events }\n },\n\n async continue(handle, prompt, signal, promptOptions) {\n if (signal.aborted) throwAbort()\n // Fail loud if the platform did not preserve the client-minted session:\n // continuing a dead/unknown session would silently lose all prior context.\n await assertSessionLive(handle.box, handle.sessionId)\n // Same box, same session id — the server continues the conversation; we do\n // NOT re-acquire and do NOT re-inject prior context as prompt text.\n return promptEvents(streaming, handle.box, prompt, handle.sessionId, signal, promptOptions)\n },\n\n async fork(parent, prompts, specs, signal) {\n if (prompts.length === 0) {\n throw new ValidationError('SandboxLineage.fork: prompts must be non-empty')\n }\n if (signal.aborted) throwAbort()\n const checkpointId = capabilities.canFork\n ? await checkpointForFork(parent.box, signal)\n : undefined\n // checkpointId === undefined ⇒ either the platform can't fork or the\n // checkpoint call yielded nothing usable: degrade to independent fresh\n // boxes. Never silently reuse the parent box for a branch.\n //\n // Bounded by `forkConcurrency`: an N-way fanout creates child boxes in\n // waves of at most `forkConcurrency`, not all N at once. Abort is checked\n // per branch (between waves), since the SDK's `fork`/`create` calls take no\n // signal and cannot be interrupted once in flight.\n return mapWithConcurrency(prompts, forkConcurrency, async (prompt, i) => {\n throwIfAborted(signal)\n const spec = specs[i % specs.length]\n if (!spec) throw new ValidationError('SandboxLineage.fork: no AgentRunSpec for branch')\n if (checkpointId !== undefined) {\n const box = await forkFromCheckpoint(parent.box, checkpointId, signal)\n owned.push(box)\n await spec.prepareBox?.(box, { signal, recordMount })\n const sessionId = mintSessionId()\n return {\n handle: { box, sessionId },\n events: promptEvents(streaming, box, prompt, sessionId, signal),\n }\n }\n const box = await acquireFresh(spec, signal)\n const sessionId = mintSessionId()\n return {\n handle: { box, sessionId },\n events: promptEvents(streaming, box, prompt, sessionId, signal),\n }\n })\n },\n\n async prune(keep) {\n const keepBoxes = new Set<SandboxInstance>()\n for (const handle of keep) keepBoxes.add(handle.box)\n const survivors: SandboxInstance[] = []\n const doomed: SandboxInstance[] = []\n for (const box of owned) (keepBoxes.has(box) ? survivors : doomed).push(box)\n if (doomed.length === 0) return\n owned.length = 0\n owned.push(...survivors)\n await Promise.allSettled(doomed.map((box) => destroyBounded(box)))\n },\n\n async teardown() {\n const boxes = owned.splice(0, owned.length)\n await Promise.allSettled(boxes.map((box) => destroyBounded(box)))\n },\n }\n}\n\n/** Stable, collision-resistant session id minted per box (the caller owns the id). */\nfunction mintSessionId(): string {\n return `loop-sess-${randomUuid()}`\n}\n\n/**\n * Checkpoint the parent leaving it running, returning the checkpoint id to fork\n * from, or `undefined` when the box exposes no `checkpoint` (the loop's fakes)\n * or the call produced no id. `undefined` makes the caller degrade to fresh\n * boxes — a fork that can't checkpoint must not pretend to share context.\n */\nasync function checkpointForFork(\n box: SandboxInstance,\n signal: AbortSignal,\n): Promise<string | undefined> {\n const checkpoint = (box as CheckpointCapableBox).checkpoint\n if (typeof checkpoint !== 'function') return undefined\n if (signal.aborted) throwAbort()\n const result = await checkpoint.call(box, { leaveRunning: true })\n const id = result?.checkpointId\n return typeof id === 'string' && id.length > 0 ? id : undefined\n}\n\n/**\n * Fork a child box from `checkpointId`. The box exposes `fork` whenever the\n * platform advertised `canFork`; a missing `fork` here is a contract violation\n * (probe said yes, box says no) and fails loud rather than silently degrading.\n *\n * `signal` gates entry only: the SDK's `fork(checkpointId, options)` takes no\n * abort signal (`ForkOptions` is name/env/resources/metadata), so an in-flight\n * fork cannot be interrupted. The caller (`fork`) checks abort per branch, so\n * cancellation is responsive at branch boundaries, not mid-fork.\n */\nasync function forkFromCheckpoint(\n box: SandboxInstance,\n checkpointId: string,\n signal: AbortSignal,\n): Promise<SandboxInstance> {\n const fork = (box as ForkCapableBox).fork\n if (typeof fork !== 'function') {\n throw new ValidationError(\n 'SandboxLineage.fork: capabilities report canFork but the box has no fork() method',\n )\n }\n if (signal.aborted) throwAbort()\n return fork.call(box, checkpointId)\n}\n\n/**\n * Fail loud when a handle's session is no longer known to the sandbox. The real\n * SDK box exposes `session(id).status()` which resolves `null` for an unknown /\n * reaped id; a `null` here means a `continue` would run WITHOUT the prior\n * context the caller believes is threaded — so refuse it. Boxes that expose no\n * `session` method (the loop's test fakes, or an SDK without the session API)\n * cannot be verified and are allowed through unchecked.\n */\nasync function assertSessionLive(box: SandboxInstance, sessionId: string): Promise<void> {\n const session = (box as SessionCapableBox).session\n if (typeof session !== 'function') return\n const info = await session.call(box, sessionId).status()\n if (info === null) {\n throw new ValidationError(\n `SandboxLineage.continue: session ${sessionId} is not known to the sandbox — the platform ` +\n 'did not preserve the client-minted session id (or it was reaped). Continuing would run ' +\n 'without prior context; refusing to silently lose conversation continuity.',\n )\n }\n}\n\nasync function destroyBounded(box: SandboxInstance): Promise<void> {\n await withTimeout(deleteBoxSafe(box), TEARDOWN_TIMEOUT_MS)\n}\n\n/**\n * Loop-side widening of the box's optional checkpoint method. The\n * `SandboxClient`/`SandboxInstance` surface the kernel relies on does not\n * require checkpointing; this reads it optionally so the lineage can probe-gate\n * without importing sandbox-backend specifics. @experimental\n */\nexport interface CheckpointCapableBox {\n checkpoint?: (options?: { leaveRunning?: boolean; tags?: string[] }) => Promise<{\n checkpointId: string\n }>\n}\n\n/** Loop-side widening of the box's optional fork method. @experimental */\nexport interface ForkCapableBox {\n fork?: (checkpointId: string, options?: { name?: string }) => Promise<SandboxInstance>\n}\n\n/**\n * Loop-side widening of the box's optional session accessor. The real\n * `SandboxInstance` exposes `session(id).status()`; the loop reads it optionally\n * so `continue` can assert session liveness without requiring it of the test\n * fakes. `status()` resolves `null` when the id is unknown to the sandbox.\n * @experimental\n */\nexport interface SessionCapableBox {\n session?: (id: string) => { status: () => Promise<unknown | null> }\n}\n","/**\n *\n * `runAgentRounds` — the topology-agnostic kernel built atop the sandbox SDK.\n *\n * Each iteration:\n * 1. `driver.plan(task, history)` → N tasks (1 = refine, N = fanout, 0 = stop)\n * 2. For each task (parallel, bounded by `maxConcurrency`):\n * a. round-robin an `AgentRunSpec` from `agentRuns`\n * b. `sandboxClient.create({ backend: { profile }, ...overrides })`\n * c. emit `loop.iteration.dispatch` with the placement\n * (`{ sibling, sandboxId }` or `{ fleet, fleetId, machineId, sandboxId }`)\n * d. iterate `box.streamPrompt(taskToPrompt(task))` and collect events\n * 3. `output.parse(events)` → typed `Output`\n * 4. `validator?.validate(output)` → `DefaultVerdict`\n * 5. Append `Iteration` to history; emit `loop.iteration.ended`\n * 6. `driver.decide(history)` → if terminal, return result + winner\n *\n * The kernel owns: iteration accounting, per-iteration timing, error\n * capture, abort propagation, concurrency cap, cost aggregation, and trace\n * emission. The kernel does NOT own: what the agent runs (sandbox SDK +\n * profile), how outputs are decoded (output adapter), how outputs are\n * scored (validator), or topology (driver).\n *\n * @experimental\n */\n\nimport type { SandboxEvent, SandboxInstance } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport { notifyRuntimeHookEvent } from '../runtime-hooks'\nimport { acquireSandbox } from './sandbox-acquire'\nimport { buildBackendOptions } from './sandbox-backend'\nimport { probeSandboxCapabilities } from './sandbox-capabilities'\nimport { extractLlmCallEvent, notifySandboxEventObserver } from './sandbox-events'\nimport {\n createSandboxLineage,\n promptEvents,\n type SandboxLineage,\n type SandboxLineageHandle,\n} from './sandbox-lineage'\nimport type {\n AgentRunSpec,\n Driver,\n ExecCtx,\n Iteration,\n LoopLineageOptions,\n LoopResult,\n LoopSandboxPlacement,\n LoopTokenUsage,\n LoopTraceEmitter,\n LoopTraceEvent,\n LoopWinner,\n MountManifestEntry,\n MountRecorder,\n OutputAdapter,\n SandboxClient,\n SelectionReceipt,\n Validator,\n} from './types'\nimport {\n addTokenUsage,\n deleteBoxSafe,\n randomSuffix,\n stringifySafe,\n throwAbort,\n withTimeout,\n zeroTokenUsage,\n} from './util'\n\nconst DEFAULT_MAX_ITERATIONS = 10\nconst DEFAULT_MAX_CONCURRENCY = 4\n\n/** @experimental */\nexport interface RunAgentRoundsOptions<Task, Output, Decision> {\n driver: Driver<Task, Output, Decision>\n /**\n * Single agent spec — every iteration uses this profile. Mutually\n * exclusive with `agentRuns`.\n */\n agentRun?: AgentRunSpec<Task>\n /**\n * Multiple specs for heterogeneous fanout. The kernel round-robins\n * through them when the driver plans N tasks. Mutually exclusive with\n * `agentRun`.\n */\n agentRuns?: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator?: Validator<Output>\n task: Task\n ctx: ExecCtx\n /** Default 10. Hard cap on total iterations across all `plan()` rounds. */\n maxIterations?: number\n /** Default 4. In-flight worker cap within a single `plan()` batch. */\n maxConcurrency?: number\n /**\n * Pre-allocated id for trace correlation. Default = `loop-${random}`.\n * Surfaces as `runId` on every emitted `LoopTraceEvent`.\n */\n runId?: string\n /**\n * Clock override; default `Date.now`. Deterministic tests pass a\n * monotonic counter to stabilize iteration timing fields.\n */\n now?: () => number\n /**\n * Override the default winner selector (highest-valid-score, ties broken\n * by earliest iteration).\n */\n selectWinner?: (iterations: Iteration<Task, Output>[]) => LoopWinner<Task, Output> | undefined\n /**\n * Same-sandbox driver mode — a kernel→caller out-channel, not a value handed\n * in. When set, the kernel keeps each finished worker box alive across the\n * `plan()` boundary and hands it here, so a same-sandbox planner\n * (one that reuses the worker's box) can stream its move INTO the\n * worker's live box — steering from the worker's real filesystem and state,\n * not just a history summary. The kernel owns teardown: every box kept alive\n * this way is destroyed at loop end (and the callback is invoked with\n * `undefined` then as a teardown sentinel). Without it, worker boxes are torn\n * down per-iteration (default) and a same-sandbox planner has nothing to\n * reuse. Intended for single-worker (refine) loops: under fanout every box is\n * still kept for teardown, but only the last-finishing box is handed here, so\n * a planner sees an arbitrary branch's filesystem — pair it with refine.\n */\n onWorkerBox?: (box: SandboxInstance | undefined) => void\n /**\n * Opt-in box-lineage controls. Default OFF — unset means every iteration\n * acquires a fresh box, streams once, and tears it down (today's behavior,\n * byte-identical). With `sessionContinuity` on, a refine round continues the\n * parent iteration's session on its live box; with `forkFanout` on (and a\n * fork-capable platform), a fanout round forks the parent's checkpoint so the\n * branches share a context prefix. The lineage owns every box it starts or\n * forks and tears them all down at loop end — so these paths are mutually\n * exclusive with `onWorkerBox`, which claims the same box-ownership channel.\n * @experimental\n */\n lineage?: LoopLineageOptions\n}\n\n/**\n * The round-synchronous MULTI-AGENT kernel: each round `driver.plan()` fans N tasks\n * out to N sandboxes (bounded concurrency), parses + validates each output, and folds\n * the round's results through `driver.decide` — fanout → validate → vote/select →\n * refine, repeated until the driver says stop. One call spans many agent sessions.\n *\n * Not to be confused with `runToolLoop` / `streamToolLoop` (`/tool-loop`): those\n * run ONE chat turn against ONE model, dispatching the tool calls that turn emits and\n * folding the results back in until the model stops calling tools. No sandboxes, no\n * rounds, no winner selection.\n *\n * @experimental\n */\nexport async function runAgentRounds<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n): Promise<LoopResult<Task, Output, Decision>> {\n const specs = resolveAgentRuns(options)\n const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('runAgentRounds: maxIterations must be > 0')\n }\n const maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY\n if (!Number.isFinite(maxConcurrency) || maxConcurrency <= 0) {\n throw new ValidationError('runAgentRounds: maxConcurrency must be > 0')\n }\n // Default fresh-box path streaming mode (read regardless of lineage activation,\n // which gates on sessionContinuity/forkFanout — the bench uses neither).\n const sandboxStreaming = options.lineage?.streaming ?? 'sse'\n if (!options.ctx?.sandboxClient || typeof options.ctx.sandboxClient.create !== 'function') {\n throw new ValidationError('runAgentRounds: ctx.sandboxClient.create is required')\n }\n const now = options.now ?? Date.now\n const runId = options.runId ?? `loop-${randomSuffix()}`\n const loopStart = now()\n const driverName = options.driver.name ?? 'driver'\n const iterations: Iteration<Task, Output>[] = []\n // Per-run provenance manifest. `recordMount` is threaded into every box\n // preparation path (fresh + lineage) so a `prepareBox` declares what it\n // mounted. The kernel never inspects box contents — it only collects what the\n // caller records.\n const mounts: MountManifestEntry[] = []\n const recordMount: MountRecorder = (entry) => {\n mounts.push(entry)\n }\n let round = 0\n // Same-sandbox mode: worker boxes are kept alive (not torn down per-iteration)\n // so the planner can stream into the latest; the kernel destroys them at loop end.\n const ownedBoxes: SandboxInstance[] = []\n const collectBox = options.onWorkerBox\n ? (box: SandboxInstance) => {\n ownedBoxes.push(box)\n options.onWorkerBox?.(box)\n }\n : undefined\n\n // Opt-in box lineage: when either flag is set, a backend-blind lineage owns\n // box+session handles so a refine continues the parent session and a fanout\n // forks the parent checkpoint. Both flags off ⇒ lineage stays undefined and\n // the per-iteration acquire/stream/teardown path is byte-identical to today.\n const lineageState = await setUpLineage(options, maxConcurrency, recordMount)\n\n emitRunLoopHook(options, {\n target: 'agent.run',\n phase: 'before',\n runId,\n timestamp: now(),\n payload: {\n driver: driverName,\n agentRunNames: specs.map((spec) => spec.name ?? spec.profile.name ?? 'agent'),\n maxIterations,\n maxConcurrency,\n },\n })\n\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.started',\n runId,\n timestamp: now(),\n payload: {\n driver: driverName,\n agentRunNames: specs.map((spec) => spec.name ?? spec.profile.name ?? 'agent'),\n maxIterations,\n maxConcurrency,\n },\n })\n\n const controller = new AbortController()\n const onOuterAbort = () => controller.abort()\n if (options.ctx.signal) {\n if (options.ctx.signal.aborted) controller.abort()\n else options.ctx.signal.addEventListener('abort', onOuterAbort, { once: true })\n }\n\n try {\n while (iterations.length < maxIterations) {\n if (controller.signal.aborted) throwAbort()\n emitRunLoopHook(options, {\n target: 'agent.plan',\n phase: 'before',\n runId,\n timestamp: now(),\n stepIndex: round,\n payload: { roundIndex: round, historyLength: iterations.length },\n })\n const planned = await options.driver.plan(options.task, iterations)\n // plan() may be a long LLM call (sandbox planner); an abort during it must\n // not launch a fresh batch of workers on an already-cancelled loop.\n if (controller.signal.aborted) throwAbort()\n const planDesc = options.driver.describePlan?.()\n const roundIndex = round\n const baseIndex = iterations.length\n const remaining = maxIterations - iterations.length\n const slice = planned.slice(0, remaining)\n // Edge lineage: a driver may DECLARE the branch source (planner-authored\n // topology); otherwise the kernel infers it — round 0 branches from root\n // (undefined), later rounds from the best-valid (else latest) iteration so\n // far. Either way it's emitted, not guessed by the viewer.\n const parentIndex =\n planDesc?.parentIndex ?? (roundIndex === 0 ? undefined : branchPoint(iterations))\n const childIndices = slice.map((_, i) => baseIndex + i)\n const moveKind =\n planDesc?.kind ??\n (planned.length === 0 ? 'stop' : planned.length === 1 ? 'refine' : 'fanout')\n emitRunLoopHook(options, {\n target: 'agent.plan',\n phase: 'after',\n runId,\n timestamp: now(),\n stepIndex: roundIndex,\n payload: {\n roundIndex,\n plannedCount: planned.length,\n moveKind,\n parentIndex,\n childIndices,\n },\n })\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.plan',\n runId,\n timestamp: now(),\n payload: {\n roundIndex,\n plannedCount: planned.length,\n moveKind,\n rationale: planDesc?.rationale,\n parentIndex,\n childIndices,\n },\n })\n round += 1\n if (planned.length === 0) break\n\n // Reserve slots up front so concurrent workers may mutate by index.\n for (let i = 0; i < slice.length; i += 1) {\n const spec = specs[(baseIndex + i) % specs.length]!\n iterations.push({\n index: baseIndex + i,\n task: slice[i] as Task,\n agentRunName: spec.name ?? spec.profile.name ?? 'agent',\n events: [],\n startedAt: now(),\n endedAt: 0,\n costUsd: 0,\n tokenUsage: zeroTokenUsage(),\n })\n }\n\n // Decide how this round acquires its sandbox streams. Without lineage it's\n // a fresh box per iteration (today's path). With lineage it may continue\n // the parent session (refine) or fork the parent checkpoint (fanout).\n const lineagePlan = lineageState\n ? planLineageRound(lineageState, specs, slice, parentIndex, controller.signal)\n : undefined\n\n await runBatch({\n slice,\n baseIndex,\n iterations,\n specs,\n output: options.output,\n validator: options.validator,\n maxConcurrency,\n streaming: sandboxStreaming,\n signal: controller.signal,\n ctx: options.ctx,\n runId,\n now,\n roundIndex,\n parentIndex,\n collectBox,\n lineagePlan,\n lineageState,\n recordMount,\n })\n\n if (controller.signal.aborted) throwAbort()\n\n emitRunLoopHook(options, {\n target: 'agent.decision',\n phase: 'before',\n runId,\n timestamp: now(),\n stepIndex: roundIndex,\n payload: { historyLength: iterations.length },\n })\n const decision = await options.driver.decide(iterations)\n emitRunLoopHook(options, {\n target: 'agent.decision',\n phase: 'after',\n runId,\n timestamp: now(),\n stepIndex: roundIndex,\n payload: { decision: stringifySafe(decision), historyLength: iterations.length },\n })\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: stringifySafe(decision), historyLength: iterations.length },\n })\n // Terminal decision ends the loop; a non-terminal one falls through to the\n // next plan() round, so this must return rather than continue.\n if (isTerminalDecision(decision)) {\n return await finalizeAndEmitEnded(\n options,\n decision,\n iterations,\n loopStart,\n now,\n runId,\n mounts,\n )\n }\n // The loop continues: free any lineage boxes no future round can descend\n // from, so the live-box set tracks the active frontier instead of growing\n // with every round. No-op unless pruning is provably safe (see canPrune).\n if (lineageState) await pruneLineage(lineageState, iterations)\n }\n\n // Either the cap was reached without a terminal decision, or plan() returned\n // [] first — both ask the driver for its final state and close out identically.\n return await decideAndFinalize(options, iterations, loopStart, now, runId, mounts)\n } finally {\n if (options.ctx.signal) options.ctx.signal.removeEventListener('abort', onOuterAbort)\n // Same-sandbox mode kept worker boxes alive across plan() so the planner could\n // stream into them — the kernel owns their teardown. Destroy in parallel so a\n // large fanout's deletes don't serialize, and bound each so a hung platform\n // delete cannot wedge loop return after the caller aborted.\n await Promise.allSettled(\n ownedBoxes.map((b) => destroySandboxSafe(b, options.ctx.traceEmitter, runId, now)),\n )\n if (options.onWorkerBox) options.onWorkerBox(undefined)\n // The lineage owns every box it started or forked across all rounds; it tears\n // them down at loop end (kept alive between rounds so a later round can\n // continue/fork them).\n if (lineageState) await lineageState.lineage.teardown()\n }\n}\n\n/**\n * Pre-rename name for {@link runAgentRounds}; identical function, kept so existing\n * call sites keep working.\n *\n * @deprecated Use {@link runAgentRounds}. The clearer name says what it is: the\n * multi-agent fanout/vote/refine kernel over sandboxes, NOT the one-turn tool loop\n * (`runToolLoop` / `streamToolLoop`, `/tool-loop`). `runLoop` shipped on `/kernel`\n * next to `routerToolLoop`, which made the two read as variants of one thing. The alias\n * is removed in the next major.\n */\nexport const runLoop = runAgentRounds\n\n/**\n * Pre-rename name for {@link RunAgentRoundsOptions}.\n *\n * @deprecated Use {@link RunAgentRoundsOptions}. Removed in the next major.\n */\nexport type RunLoopOptions<Task, Output, Decision> = RunAgentRoundsOptions<Task, Output, Decision>\n\n/**\n * Per-loop lineage state: the backend-blind lineage, the caller's opt-in flags,\n * and the live handle for each completed iteration so a later round can continue\n * or fork from it. `undefined` ⇒ no lineage; the kernel uses the fresh-box path.\n */\ninterface LineageState {\n lineage: SandboxLineage\n options: LoopLineageOptions\n /** iteration index → its live box+session handle (kept alive across rounds). */\n handles: Map<number, SandboxLineageHandle>\n /**\n * Whether the kernel may free non-frontier boxes after each round. Safe only\n * when the driver never authors its own branch point (`describePlan` absent),\n * so the kernel-inferred `branchPoint` — which moves monotonically toward\n * higher-scoring iterations — is the only descent source. A driver that\n * declares `parentIndex` may descend from any prior iteration, so no box can\n * be freed before loop end.\n */\n canPrune: boolean\n}\n\n/**\n * Build the lineage when either lineage flag is set. Probes the platform's fork\n * capability once per run (the lineage degrades gracefully when it's absent).\n * Rejects the lineage + `onWorkerBox` combination: both claim the same\n * box-ownership channel, and silently honoring one would leak or double-free.\n */\nasync function setUpLineage<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n maxConcurrency: number,\n recordMount: MountRecorder,\n): Promise<LineageState | undefined> {\n const lineageOpts = options.lineage\n if (!lineageOpts || (!lineageOpts.sessionContinuity && !lineageOpts.forkFanout)) return undefined\n if (options.onWorkerBox) {\n throw new ValidationError(\n 'runAgentRounds: `lineage` and `onWorkerBox` both own worker boxes — pass only one',\n )\n }\n const capabilities = await probeSandboxCapabilities(options.ctx.sandboxClient)\n return {\n lineage: createSandboxLineage(options.ctx.sandboxClient, capabilities, {\n maxConcurrency,\n streaming: lineageOpts.streaming,\n recordMount,\n }),\n options: lineageOpts,\n handles: new Map(),\n canPrune: typeof options.driver.describePlan !== 'function',\n }\n}\n\n/**\n * One iteration's sandbox-stream source for a lineage round. The kernel awaits\n * `acquire()` inside the concurrency-bounded batch (so a fork's per-branch\n * `streamPrompt` and a continue's same-box stream are both rate-limited and\n * abort-checked like a fresh create). Returns the live event stream plus the\n * handle to record for the NEXT round to descend from.\n */\ninterface LineageStreamSource {\n acquire(): Promise<{ events: AsyncIterable<SandboxEvent>; handle: SandboxLineageHandle }>\n}\n\n/** The per-round lineage plan: a stream source per slice offset, or `undefined`\n * for offsets with no lineage source (defensive — never expected). */\ntype LineageRoundPlan = (LineageStreamSource | undefined)[]\n\n/**\n * Decide, for one round, how each iteration acquires its sandbox stream:\n * - refine (1 task) + `sessionContinuity` + a live parent handle ⇒ continue\n * the parent session on its box.\n * - fanout (N tasks) + `forkFanout` + a live parent handle ⇒ fork the parent\n * checkpoint once and stream each branch from a child box (degrades to fresh\n * boxes inside the lineage when the platform can't fork).\n * - otherwise (round 0, no parent, the off flag) ⇒ start a fresh box per\n * iteration THROUGH the lineage so it's owned + a handle is recorded for a\n * later round to descend from.\n * Round 0 (parentIndex undefined) always starts fresh — the independence of the\n * first batch is preserved.\n */\nfunction planLineageRound<Task>(\n state: LineageState,\n specs: AgentRunSpec<Task>[],\n slice: Task[],\n parentIndex: number | undefined,\n signal: AbortSignal,\n): LineageRoundPlan {\n const lineage = state.lineage\n const parent = parentIndex !== undefined ? state.handles.get(parentIndex) : undefined\n const promptFor = (offset: number): string => {\n const spec = specs[offset % specs.length]\n if (!spec)\n throw new ValidationError('runAgentRounds: no AgentRunSpec available for lineage iteration')\n return spec.taskToPrompt(slice[offset] as Task)\n }\n const specAt = (offset: number): AgentRunSpec<unknown> => {\n const spec = specs[offset % specs.length]\n if (!spec)\n throw new ValidationError('runAgentRounds: no AgentRunSpec available for lineage iteration')\n return spec as AgentRunSpec<unknown>\n }\n\n // Continue the parent session: a single-task round descending from a live\n // handle, with the flag on. Reuses the parent's box + session id.\n if (slice.length === 1 && parent && state.options.sessionContinuity) {\n return [\n {\n async acquire() {\n const events = await lineage.continue(parent, promptFor(0), signal)\n // Continuation threads the SAME handle forward — later rounds keep\n // descending from this box's evolving session.\n return { events, handle: parent }\n },\n },\n ]\n }\n\n // Fork the parent checkpoint: a multi-task round descending from a live handle,\n // with the flag on. One checkpoint, N child streams — lazily awaited once and\n // shared across the offsets so the batch checkpoints exactly once.\n if (slice.length > 1 && parent && state.options.forkFanout) {\n const prompts = slice.map((_, offset) => promptFor(offset))\n const childSpecs = slice.map((_, offset) => specAt(offset))\n let forked: Promise<{ handle: SandboxLineageHandle; events: AsyncIterable<SandboxEvent> }[]>\n const ensureForked = () => {\n forked ??= lineage.fork(parent, prompts, childSpecs, signal)\n return forked\n }\n return slice.map((_, offset) => ({\n async acquire() {\n const branches = await ensureForked()\n const branch = branches[offset]\n if (!branch)\n throw new ValidationError('runAgentRounds: lineage fork produced no branch for offset')\n return branch\n },\n }))\n }\n\n // Fresh through the lineage (round 0, no parent, or the relevant flag off):\n // start an owned box per iteration and record a handle for later descent.\n return slice.map((_, offset) => ({\n async acquire() {\n return lineage.start(specAt(offset), promptFor(offset), signal)\n },\n }))\n}\n\n/**\n * After a round, free lineage boxes no future round can descend from. The only\n * descent source for a kernel-inferred topology is `branchPoint`, which moves\n * monotonically toward higher-scoring iterations and never returns to one it has\n * passed — so every box except the current branch point's is unreachable and can\n * be torn down now instead of at loop end. Skipped entirely when the driver\n * authors its own branch point (`canPrune` false): it may descend from any prior\n * iteration. Also skipped when the branch point has no recorded handle (its\n * acquire failed) — that conservative case keeps every box.\n */\nasync function pruneLineage<Task, Output>(\n state: LineageState,\n iterations: ReadonlyArray<Iteration<Task, Output>>,\n): Promise<void> {\n if (!state.canPrune) return\n const keepIndex = branchPoint(iterations)\n if (keepIndex === undefined) return\n const keep = state.handles.get(keepIndex)\n if (!keep) return\n await state.lineage.prune([keep])\n // Drop handle entries pointing at the now-freed boxes so the map never hands a\n // later round a deleted box. Entries sharing the kept box (a refine chain)\n // stay.\n const stale: number[] = []\n for (const [index, handle] of state.handles) {\n if (handle.box !== keep.box) stale.push(index)\n }\n for (const index of stale) state.handles.delete(index)\n}\n\ninterface RunBatchArgs<Task, Output> {\n slice: Task[]\n baseIndex: number\n iterations: Iteration<Task, Output>[]\n specs: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator: Validator<Output> | undefined\n maxConcurrency: number\n signal: AbortSignal\n ctx: ExecCtx\n runId: string\n now: () => number\n /** Plan round these iterations belong to — stamped as `groupId`. */\n roundIndex: number\n /** Iteration this round branched from — stamped as `parentIndex`. */\n parentIndex?: number\n /**\n * Same-sandbox mode: when set, a finished iteration's box is handed here\n * (kept alive for the planner) instead of being torn down. `undefined` =\n * default per-iteration teardown.\n */\n collectBox?: (box: SandboxInstance) => void\n /**\n * Lineage mode: per-offset stream sources for this round. When set, an\n * iteration acquires its sandbox stream through the lineage (continue / fork /\n * fresh) instead of `createSandboxForSpec`, and the lineage — not the\n * iteration — owns box teardown (deferred to loop end).\n */\n lineagePlan?: LineageRoundPlan\n /** The loop's lineage state; iterations record their handle here for the next\n * round to descend from. Set iff `lineagePlan` is. */\n lineageState?: LineageState\n /** Sandbox streaming mode for the default fresh-box path. 'poll' fire-and-\n * detaches + status-polls the terminal result (drop-resilient for long batch\n * turns); 'sse' streams live (default). */\n streaming: 'sse' | 'poll'\n /** The run's provenance recorder, forwarded to `prepareBox` on the default\n * fresh-box path so a mount declares itself into the manifest. (The lineage\n * path carries its own recorder from `createSandboxLineage`.) */\n recordMount: MountRecorder\n}\n\nasync function runBatch<Task, Output>(args: RunBatchArgs<Task, Output>) {\n const queue = args.slice.map((task, offset) => ({ task, index: args.baseIndex + offset }))\n const inflight = new Set<Promise<void>>()\n // Every started worker, so a rejecting iteration (abort short-circuit, or a\n // throwing trace emitter) cannot orphan its still-running siblings: we always\n // drain ALL of them before propagating the first error.\n const started: Promise<void>[] = []\n let firstError: unknown\n try {\n while (queue.length > 0 || inflight.size > 0) {\n while (inflight.size < args.maxConcurrency && queue.length > 0) {\n const item = queue.shift()!\n const p = executeIteration({ ...args, item }).finally(() => inflight.delete(p))\n started.push(p)\n inflight.add(p)\n }\n if (inflight.size === 0) break\n try {\n await Promise.race(inflight)\n } catch (err) {\n if (firstError === undefined) firstError = err\n // Stop scheduling new work; drain the rest in the finally below.\n queue.length = 0\n break\n }\n }\n } finally {\n const settled = await Promise.allSettled(started)\n if (firstError === undefined) {\n const rejected = settled.find((s) => s.status === 'rejected')\n if (rejected && rejected.status === 'rejected') firstError = rejected.reason\n }\n }\n if (firstError !== undefined) throw firstError\n}\n\ninterface ExecuteIterationArgs<Task, Output> extends RunBatchArgs<Task, Output> {\n item: { task: Task; index: number }\n}\n\nasync function executeIteration<Task, Output>(args: ExecuteIterationArgs<Task, Output>) {\n const slot = args.iterations[args.item.index]\n if (!slot)\n throw new ValidationError(`runAgentRounds: missing iteration slot at index ${args.item.index}`)\n const spec = args.specs[args.item.index % args.specs.length]\n if (!spec) throw new ValidationError('runAgentRounds: no AgentRunSpec available for iteration')\n slot.startedAt = args.now()\n slot.agentRunName = spec.name ?? spec.profile.name ?? 'agent'\n\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.started',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n taskHash: hashJson(args.item.task),\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n },\n })\n\n let box: SandboxInstance | undefined\n // Lineage-owned boxes are torn down by the lineage at loop end, not here. The\n // flag tracks whether THIS iteration's box came from the lineage so the\n // teardown branch below skips it.\n let lineageOwned = false\n try {\n // Stream source: the lineage (continue / fork / fresh) when this round runs\n // under lineage, else a fresh box + a single `streamPrompt` (today's path,\n // byte-identical when no lineage). The lineage path supplies a session id on\n // the stream; the fresh path passes none — preserving N-independent-boxes.\n let stream: AsyncIterable<SandboxEvent>\n const source = args.lineagePlan?.[args.item.index - args.baseIndex]\n if (source) {\n const acquired = await source.acquire()\n box = acquired.handle.box\n lineageOwned = true\n args.lineageState?.handles.set(args.item.index, acquired.handle)\n stream = acquired.events\n } else {\n box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount)\n const prompt = spec.taskToPrompt(args.item.task)\n // 'poll' (opt-in) fire-and-detaches + status-polls the terminal result so a\n // long, quiet turn never holds a drop-prone live SSE; 'sse' (default)\n // streams live — byte-identical to the prior path.\n stream =\n args.streaming === 'poll'\n ? promptEvents('poll', box, prompt, `${args.runId}-i${args.item.index}`, args.signal)\n : box.streamPrompt(prompt, { signal: args.signal })\n }\n const placement = describeSandboxPlacement(args.ctx.sandboxClient, box)\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.dispatch',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n placement: placement.kind,\n sandboxId: placement.sandboxId,\n fleetId: placement.fleetId,\n machineId: placement.machineId,\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n },\n })\n const events: SandboxEvent[] = []\n for await (const event of stream) {\n events.push(event)\n // Tee each raw event to an optional host observer so a caller can stream\n // the agent's live output. Best-effort + isolated: the observer gets a\n // defensive copy (mutating it cannot corrupt the event the run itself\n // consumes for cost accounting + output parsing below), and a sync throw\n // or a rejected async result is swallowed — it can never break the run.\n notifySandboxEventObserver(event, args.ctx.onSandboxEvent, {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n })\n const llmCall = extractLlmCallEvent(event, slot.agentRunName)\n if (llmCall) {\n slot.costUsd += llmCall.costUsd ?? 0\n addTokenUsage(slot.tokenUsage, { input: llmCall.tokensIn, output: llmCall.tokensOut })\n args.ctx.runHandle?.observe(llmCall)\n }\n }\n slot.events = events\n slot.output = args.output.parse(events)\n if (args.validator) {\n slot.verdict = await args.validator.validate(slot.output, {\n iteration: args.item.index,\n ...(box ? { box } : {}),\n signal: args.signal,\n traceEmitter: args.ctx.traceEmitter,\n })\n }\n } catch (err) {\n slot.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n slot.endedAt = args.now()\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.ended',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n outputHash: slot.output !== undefined ? hashJson(slot.output) : undefined,\n verdict: slot.verdict,\n error: slot.error?.message,\n costUsd: slot.costUsd,\n durationMs: slot.endedAt - slot.startedAt,\n tokenUsage:\n slot.tokenUsage.input || slot.tokenUsage.output ? { ...slot.tokenUsage } : undefined,\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n outputPreview:\n slot.output !== undefined ? stringifySafe(slot.output, { max: 280 }) : undefined,\n },\n })\n // The loop owns the per-shot box lifecycle. Default: tear it down now so\n // sandboxes don't leak. Same-sandbox mode: hand it to the kernel to keep\n // alive for the planner. Lineage mode: the lineage owns the box and keeps it\n // alive across rounds (a later round may continue/fork it), tearing it down\n // at loop end — so skip per-iteration teardown here.\n if (lineageOwned) {\n // no-op: lineage.teardown() reaps this box at loop end\n } else if (args.collectBox && box) {\n args.collectBox(box)\n } else {\n await destroySandboxSafe(box, args.ctx.traceEmitter, args.runId, args.now)\n }\n }\n // An abort caught above is NOT a soft per-iteration failure — it must\n // short-circuit the batch, not degrade to a recorded empty iteration. The\n // trace was already emitted in the finally, so re-throw it now.\n if (isAbortError(slot.error) || args.signal.aborted) {\n if (slot.error) throw slot.error\n throwAbort()\n }\n // A structural lineage error (a dropped session, a fork-capability contract\n // violation, a missing spec) is likewise not a soft worker failure: it\n // invalidates the run's continuity/branching guarantee, so propagate it\n // instead of degrading to a recorded empty iteration the driver might ignore.\n if (slot.error instanceof ValidationError) throw slot.error\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError'\n}\n\nconst TEARDOWN_TIMEOUT_MS = 15_000\n\n/**\n * Best-effort sandbox teardown. A failed delete must never surface as a loop\n * error, and instances without a `delete` (the loop's test fakes) are skipped.\n * A delete that throws or hangs (bounded by `TEARDOWN_TIMEOUT_MS`) is recorded\n * as a `loop.teardown.failed` trace so a silently-leaking box is observable —\n * distinct from a fake with no `delete`, which is expected and stays silent.\n */\nasync function destroySandboxSafe(\n box: SandboxInstance | undefined,\n trace?: LoopTraceEmitter,\n runId?: string,\n now?: () => number,\n): Promise<void> {\n if (!box || typeof (box as { delete?: unknown }).delete !== 'function') return\n const emitFailed = async (reason: string) => {\n if (!trace || !runId) return\n await emitTrace(trace, {\n kind: 'loop.teardown.failed',\n runId,\n timestamp: (now ?? Date.now)(),\n payload: { sandboxId: readSandboxId(box), reason },\n })\n }\n // Bound the delete so a hung platform delete can't wedge loop return after an\n // abort. `undefined` = timed out; `false` = delete threw; `true` = deleted.\n const outcome = await withTimeout(deleteBoxSafe(box), TEARDOWN_TIMEOUT_MS)\n if (outcome === undefined) await emitFailed('timeout')\n else if (outcome === false) await emitFailed('delete threw')\n}\n\n/**\n * Branch point for a new round — the iteration a later round descends from.\n * Highest-valid-score iteration so far; ties + no-valid fall back to the latest\n * index. Inferred (not driver-declared), so refine renders as a chain and\n * fanout→refine chains off the fanout winner.\n */\nfunction branchPoint<Task, Output>(\n iterations: ReadonlyArray<Iteration<Task, Output>>,\n): number | undefined {\n if (iterations.length === 0) return undefined\n let best = iterations.length - 1\n let bestScore = -Infinity\n for (const iter of iterations) {\n if (iter.verdict?.valid !== true) continue\n const score = iter.verdict.score ?? 0\n if (score > bestScore) {\n bestScore = score\n best = iter.index\n }\n }\n return best\n}\n\nexport function describeSandboxPlacement(\n client: SandboxClient,\n box: SandboxInstance,\n): LoopSandboxPlacement {\n if (typeof client.describePlacement === 'function') {\n try {\n const result = client.describePlacement(box)\n if (\n result &&\n typeof result === 'object' &&\n (result.kind === 'sibling' || result.kind === 'fleet')\n ) {\n return {\n kind: result.kind,\n sandboxId: result.sandboxId ?? readSandboxId(box),\n fleetId: result.fleetId,\n machineId: result.machineId,\n }\n }\n } catch {\n // Adapter bug must not corrupt the iteration; fall through to default.\n }\n }\n return { kind: 'sibling', sandboxId: readSandboxId(box) }\n}\n\nfunction readSandboxId(box: SandboxInstance): string | undefined {\n const raw = (box as unknown as { id?: unknown }).id\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined\n}\n\n/**\n * Instantiate a sandbox for an `AgentRunSpec`: sets `backend.profile` to the\n * spec's profile (inferring the backend type when the spec doesn't override\n * it) and merges `sandboxOverrides`. Shared by the loop kernel and the\n * `AgentRuntime.act` sandbox bridge so both boot the sandbox identically.\n *\n * `recordMount`, when supplied, is forwarded to `prepareBox` so the caller can\n * declare what it mounted into the box for the run's provenance manifest. The\n * loop kernel passes its per-run recorder; other callers (which have no\n * `LoopResult` to attach to) omit it and the prepareBox recorder is a no-op.\n */\nexport async function createSandboxForSpec<Task>(\n client: SandboxClient,\n spec: AgentRunSpec<Task>,\n signal: AbortSignal,\n recordMount?: MountRecorder,\n): Promise<SandboxInstance> {\n const opts = buildBackendOptions(spec.profile, spec.sandboxOverrides)\n // Cold-start-resilient acquire: a slow scale-from-zero create (node boot +\n // host-agent registration) can't surface as a failure — readiness is observed\n // from sandbox status, and a gateway-timed-out create is recovered by lookup.\n if (signal.aborted) throwAbort()\n const box = await acquireSandbox(client, opts, { signal })\n await invokePrepareBox(spec, box, signal, recordMount)\n return box\n}\n\n/**\n * Invoke a spec's `prepareBox` with a complete ctx. `recordMount` is the run's\n * provenance recorder when one is threaded down; absent, a no-op stands in so\n * the ctx shape is always satisfied and a caller that records mounts on a path\n * with no manifest (e.g. the `AgentRuntime.act` bridge) silently drops nothing\n * it cares about — it simply has nowhere to surface a manifest.\n */\nasync function invokePrepareBox<Task>(\n spec: AgentRunSpec<Task>,\n box: SandboxInstance,\n signal: AbortSignal,\n recordMount?: MountRecorder,\n): Promise<void> {\n if (!spec.prepareBox) return\n await spec.prepareBox(box, { signal, recordMount: recordMount ?? noopMountRecorder })\n}\n\n/** Shared no-op recorder for box-preparation paths that have no run manifest. */\nconst noopMountRecorder: MountRecorder = () => {}\n\ninterface FinalizeArgs<Task, Output, Decision> {\n options: RunAgentRoundsOptions<Task, Output, Decision>\n decision: Decision\n iterations: Iteration<Task, Output>[]\n startMs: number\n now: () => number\n runId: string\n /** Provenance mounts recorded across the run's box preparations. */\n mounts: MountManifestEntry[]\n}\n\nfunction finalize<Task, Output, Decision>(\n args: FinalizeArgs<Task, Output, Decision>,\n): LoopResult<Task, Output, Decision> {\n // Precedence: an explicit caller `selectWinner` wins; else a driver-AUTHORED\n // winner (a `select` topology move); else the default argmax. A driver that\n // declares nothing returns undefined and falls through — existing behavior.\n // Track which selector produced the winner so the receipts attribute it.\n let selector: SelectionReceipt['selector']\n let winner: LoopWinner<Task, Output> | undefined\n if (args.options.selectWinner) {\n selector = 'caller'\n winner = args.options.selectWinner(args.iterations)\n } else {\n const authored = args.options.driver.selectWinner?.(args.iterations)\n if (authored) {\n selector = 'driver'\n winner = authored\n } else {\n selector = 'default'\n winner = defaultSelectWinner(args.iterations)\n }\n }\n const costUsd = args.iterations.reduce((sum, iter) => sum + (iter.costUsd || 0), 0)\n const tokenUsage = args.iterations.reduce((acc: LoopTokenUsage, iter) => {\n addTokenUsage(acc, iter.tokenUsage)\n return acc\n }, zeroTokenUsage())\n const result: LoopResult<Task, Output, Decision> = {\n decision: args.decision,\n iterations: args.iterations,\n winner,\n durationMs: args.now() - args.startMs,\n costUsd,\n tokenUsage,\n provenance: {\n mounts: args.mounts,\n selectionReceipts: buildSelectionReceipts(args.iterations, winner, selector),\n },\n }\n return result\n}\n\n/**\n * One receipt per scored candidate — a candidate being an iteration that\n * produced an output without erroring (an errored or output-less iteration was\n * never selectable, so it gets no receipt). The receipt records the candidate's\n * score and whether the selector chose it as the winner, attributed to the\n * selector identity that ran. Domain-free: it states WHAT was selected and its\n * score, never anything about the task or output content.\n */\nfunction buildSelectionReceipts<Task, Output>(\n iterations: Iteration<Task, Output>[],\n winner: LoopWinner<Task, Output> | undefined,\n selector: SelectionReceipt['selector'],\n): SelectionReceipt[] {\n const receipts: SelectionReceipt[] = []\n for (const iter of iterations) {\n if (iter.output === undefined || iter.error) continue\n const selected = winner?.iterationIndex === iter.index\n const receipt: SelectionReceipt = {\n candidateIndex: iter.index,\n selected,\n selector,\n }\n if (iter.verdict?.score !== undefined) receipt.score = iter.verdict.score\n // The kernel can only speak to its OWN selection logic. A caller- or\n // driver-authored winner runs by its own rationale, so the kernel leaves\n // `reason` unset rather than inventing one.\n if (selector === 'default') receipt.reason = defaultSelectorReason(iter, selected)\n receipts.push(receipt)\n }\n return receipts\n}\n\n/** Plain-language reason for the default selector's decision (best-valid-score,\n * earliest-index tiebreak, falling back to best non-errored when none valid). */\nfunction defaultSelectorReason<Task, Output>(\n iter: Iteration<Task, Output>,\n selected: boolean,\n): string {\n const valid = iter.verdict?.valid === true\n if (selected) return valid ? 'best valid score' : 'best non-errored score (no valid candidate)'\n return valid ? 'valid but not top score' : 'not selected'\n}\n\n/**\n * Run `decide`, emit the `loop.decision` trace, then finalize and emit\n * `loop.ended`. The two post-while exits (cap reached / `plan()` returned `[]`)\n * share this exact sequence.\n */\nasync function decideAndFinalize<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n iterations: Iteration<Task, Output>[],\n startMs: number,\n now: () => number,\n runId: string,\n mounts: MountManifestEntry[],\n): Promise<LoopResult<Task, Output, Decision>> {\n emitRunLoopHook(options, {\n target: 'agent.decision',\n phase: 'before',\n runId,\n timestamp: now(),\n payload: { historyLength: iterations.length },\n })\n const decision = await options.driver.decide(iterations)\n emitRunLoopHook(options, {\n target: 'agent.decision',\n phase: 'after',\n runId,\n timestamp: now(),\n payload: { decision: stringifySafe(decision), historyLength: iterations.length },\n })\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: stringifySafe(decision), historyLength: iterations.length },\n })\n return finalizeAndEmitEnded(options, decision, iterations, startMs, now, runId, mounts)\n}\n\n/** Finalize the loop and emit the terminal `loop.ended` span. Used by the\n * in-loop terminal path (decision trace already emitted) and decideAndFinalize. */\nasync function finalizeAndEmitEnded<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n decision: Decision,\n iterations: Iteration<Task, Output>[],\n startMs: number,\n now: () => number,\n runId: string,\n mounts: MountManifestEntry[],\n): Promise<LoopResult<Task, Output, Decision>> {\n const result = finalize({ options, decision, iterations, startMs, now, runId, mounts })\n emitRunLoopHook(options, {\n target: 'agent.run',\n phase: 'after',\n runId,\n timestamp: now(),\n payload: {\n decision: stringifySafe(decision),\n winnerIterationIndex: result.winner?.iterationIndex,\n totalCostUsd: result.costUsd,\n durationMs: result.durationMs,\n iterations: iterations.length,\n },\n })\n // Await the terminal span (unlike a fire-and-forget) so a process exiting\n // right after runAgentRounds resolves (MCP subprocess / CLI dispatch) can't drop it.\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.ended',\n runId,\n timestamp: now(),\n payload: {\n winnerIterationIndex: result.winner?.iterationIndex,\n totalCostUsd: result.costUsd,\n durationMs: result.durationMs,\n iterations: iterations.length,\n },\n })\n return result\n}\n\n/**\n * The kernel's winner argmax — best-valid-score, ties broken by earliest index,\n * falling back to the best-scoring non-errored output when none is valid. Exported\n * so the `runProgram` tree executor selects across merged sub-loop iterations with\n * the SAME semantics the kernel uses at a single loop's finalize (one selector, not\n * a forked copy).\n */\nexport function defaultSelectWinner<Task, Output>(\n iterations: Iteration<Task, Output>[],\n): LoopWinner<Task, Output> | undefined {\n const candidates = iterations.filter((iter) => iter.output !== undefined && !iter.error)\n if (candidates.length === 0) return undefined\n const valid = candidates.filter((iter) => iter.verdict?.valid === true)\n const pool = valid.length > 0 ? valid : candidates\n const sorted = [...pool].sort(\n (a, b) => (b.verdict?.score ?? 0) - (a.verdict?.score ?? 0) || a.index - b.index,\n )\n const top = sorted[0]\n if (!top || top.output === undefined) return undefined\n return {\n task: top.task,\n output: top.output,\n verdict: top.verdict,\n iterationIndex: top.index,\n agentRunName: top.agentRunName,\n }\n}\n\nfunction resolveAgentRuns<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n): AgentRunSpec<Task>[] {\n if (options.agentRun && options.agentRuns) {\n throw new ValidationError('runAgentRounds: pass exactly one of `agentRun` or `agentRuns`')\n }\n if (options.agentRun) return [options.agentRun]\n if (options.agentRuns && options.agentRuns.length > 0) return options.agentRuns\n throw new ValidationError('runAgentRounds: `agentRun` or non-empty `agentRuns` is required')\n}\n\nfunction isTerminalDecision(decision: unknown): boolean {\n return (\n decision === 'stop' || decision === 'pick-winner' || decision === 'fail' || decision === 'done'\n )\n}\n\nfunction emitRunLoopHook<Task, Output, Decision>(\n options: RunAgentRoundsOptions<Task, Output, Decision>,\n event: {\n target: 'agent.run' | 'agent.plan' | 'agent.decision'\n phase: 'before' | 'after' | 'error' | 'event'\n runId: string\n timestamp: number\n stepIndex?: number\n payload?: Record<string, unknown>\n },\n): void {\n notifyRuntimeHookEvent(\n options.ctx.hooks,\n {\n id: `${event.runId}:${event.target}:${event.phase}${\n event.stepIndex === undefined ? '' : `:${event.stepIndex}`\n }`,\n runId: event.runId,\n target: event.target,\n phase: event.phase,\n timestamp: event.timestamp,\n stepIndex: event.stepIndex,\n payload: event.payload,\n metadata: { producer: 'run-loop' },\n },\n { signal: options.ctx.signal },\n )\n}\n\nasync function emitTrace(\n emitter: LoopTraceEmitter | undefined,\n event: LoopTraceEvent,\n): Promise<void> {\n if (!emitter) return\n await emitter.emit(event)\n}\n\n/**\n * Stable hash for the trace payload. Not cryptographic — only used so\n * downstream eval pipelines can group iterations whose task / output is the\n * same. Bare structural hash; non-JSON values stringify via their `toString`.\n */\nfunction hashJson(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(value) ?? String(value)\n } catch {\n str = String(value)\n }\n // FNV-1a 32-bit — branch-free, dependency-free, good enough for grouping.\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\n}\n","/**\n *\n * The worker-side receive end of the down-leg: a per-worker inbox an executor exposes as\n * `Executor.deliver`. The driver's `steer_agent` / `answer_question` land here,\n * and the worker's agent loop drains them at two points (Drew's two delivery modes):\n *\n * - QUEUED (default): the message accumulates and is FLUSHED at the next step boundary — folded\n * into the conversation before the next think. A worker is also forced to flush BEFORE it may\n * settle, so it can never finish while a steer/answer it never read is still pending.\n * - FORCEFUL (`interrupt: true`): trips `freshInterrupt()`'s signal so the loop can abort its\n * in-flight turn immediately, then re-plan with the message folded in — breaking the worker out\n * of a wrong path mid-task instead of waiting for it to finish the step.\n *\n * `deliver` never throws — a malformed message is ignored, per the `Executor.deliver` contract.\n *\n * @experimental\n */\n\nexport interface InboxMessage {\n readonly kind: 'steer' | 'answer'\n readonly text: string\n /** Forceful messages abort the in-flight turn; queued ones wait for the boundary flush. */\n readonly interrupt: boolean\n /** Present for an `answer` — the question id it resolves. */\n readonly questionId?: string\n}\n\nexport interface Inbox {\n /** The `Executor.deliver` implementation — accept a raw down-message from `Scope.send`. */\n deliver(msg: unknown): void\n /** Remove and return all pending messages (the flush). */\n drain(): InboxMessage[]\n pending(): number\n /** Open a fresh per-turn interrupt signal; a later forceful `deliver` aborts it. The loop links\n * this into the signal it passes to its inference call, then re-plans when it fires. */\n freshInterrupt(): AbortSignal\n /** Render drained messages as ONE operator turn to fold into the worker's conversation. */\n fold(messages: ReadonlyArray<InboxMessage>): string\n}\n\nfunction parseDown(msg: unknown): InboxMessage | undefined {\n if (!msg || typeof msg !== 'object') return undefined\n const m = msg as Record<string, unknown>\n const interrupt = m.interrupt === true\n if (typeof m.steer === 'string') return { kind: 'steer', text: m.steer, interrupt }\n if (typeof m.answer === 'string')\n return {\n kind: 'answer',\n text: m.answer,\n interrupt,\n ...(typeof m.questionId === 'string' ? { questionId: m.questionId } : {}),\n }\n return undefined\n}\n\n/** Create the worker-side inbox for the down-leg: the driver's `steer_agent` / `answer_question` messages queue here and the worker's loop drains them at step boundaries and before settle. */\nexport function createInbox(): Inbox {\n const pending: InboxMessage[] = []\n let live: AbortController | null = null\n return {\n deliver(msg) {\n const m = parseDown(msg)\n if (!m) return\n pending.push(m)\n // A forceful message aborts the turn currently in flight (if any).\n if (m.interrupt && live && !live.signal.aborted) live.abort()\n },\n drain() {\n return pending.splice(0, pending.length)\n },\n pending: () => pending.length,\n freshInterrupt() {\n live = new AbortController()\n return live.signal\n },\n fold(messages) {\n const lines = messages.map((m) => {\n if (m.kind === 'answer')\n return `- Answer to your question${m.questionId ? ` (${m.questionId})` : ''}: ${m.text}`\n return `- New instruction from your supervisor: ${m.text}`\n })\n return `[SUPERVISOR] Out-of-band message(s) — address these before continuing:\\n${lines.join('\\n')}`\n },\n }\n}\n","/**\n *\n * MCP for the `pi` harness — the mount `piExecutor` performs before it spawns pi.\n *\n * pi ships NO MCP support of its own. MCP arrives through the `pi-mcp-adapter` extension, and the\n * adapter takes its config from a path the CALLER names: it registers a `--mcp-config <path>` flag\n * (`pi-mcp-adapter` `index.ts:252`, read back at `init.ts:101` and off raw argv at `utils.ts:55`).\n * So \"give pi an MCP server\" means: write the canonical `{ mcpServers: … }` object to a path this\n * run owns, pass that path with `--mcp-config`, make sure the adapter is loaded, and delete the\n * file afterwards. This module does exactly that and nothing else.\n *\n * Three rules carry the whole design:\n *\n * 1. **Fail loud, never fail safe.** If the profile declares MCP servers and `pi-mcp-adapter` is not\n * installed, `preparePiMcp` throws BEFORE any file is written and before pi is spawned. A run\n * whose tools never existed must fail, not score zero for the wrong reason.\n * 2. **`--no-extensions` is a trap.** When `extensions.pi.load` is an array, pi runs\n * `--no-extensions`, which suppresses ALL auto-discovery — cwd `.pi/extensions`, global\n * `~/.pi/agent/extensions`, AND the `settings.json` `packages` list that would otherwise have\n * auto-loaded the adapter. So `load: ['pi-memory']` alongside `mcp` kills MCP dead even though\n * the adapter IS installed. When MCP is declared, this module adds `pi-mcp-adapter` to the\n * resolved load list and REPORTS that it did (`PiMcpReceipt.adapterInjected`). The caller's\n * profile object is never mutated.\n * 3. **One config file per worker EXECUTION, never one per workspace.** `PiSeam.cwd` comes from the\n * `ExecutorConfig` and is therefore shared by every worker the factory builds, so a config\n * discovered by cwd is a file two concurrent siblings fight over. `mountPiMcpConfig` instead\n * creates a fresh `mkdtemp` directory — OS-guaranteed unique, so no counter, lock, merge or\n * restore is needed — and hands its path to `--mcp-config`. Concurrent workers built from ONE\n * seam get ONE config each and never collide.\n *\n * Why the flag is safe to emit here even though pi only lists it under `Extension CLI Flags`: it is\n * emitted ONLY when the profile declares at least one usable MCP server, and that case has already\n * passed the `piMcpAdapterAvailable()` gate above, so the extension that registers the flag is\n * guaranteed loadable (auto-discovered, or force-loaded by the `--extension` this module appends).\n * A machine without the adapter never reaches the flag — it fails at the gate with an install\n * command instead.\n *\n * Where the run's servers sit in pi's config layering, stated plainly because it is a real\n * behavioral edge: `--mcp-config` REPLACES pi's user-global override file (`config.ts:310`,\n * `getPiGlobalConfigPath(overridePath)`), so the operator's own `~/.pi/agent/mcp.json` servers no\n * longer leak into a worker — good. It does NOT suppress project discovery: the adapter still\n * layers `<cwd>/.mcp.json` and `<cwd>/.pi/mcp.json` on top (`config.ts:352-373`), and those are\n * later sources, so a workspace that ships a server under the SAME NAME overrides this run's entry.\n * The consequence is worth naming: an A/B whose arms differ only in `profile.mcp` is confounded\n * when the shared workspace carries its own MCP config. Deleting a file the run did not create\n * would be worse — a run cannot quietly edit the repo it was pointed at.\n *\n * Upstream note: `@tangle-network/agent-profile-materialize` is the shared owner of profile → harness\n * mapping and already declares `pi` a first-class `HarnessId`, but as of 0.9.4 its pi arm answers\n * `unsupported('mcp', 'pi MCP requires a loaded MCP extension; the base Pi runtime has no MCP\n * control')` and its pi extensions arm answers `unsupported('extensions', …)`. That refusal is now\n * factually stale — the shape is exactly its `kimi-code` arm's (write a config file, push a config\n * flag, because the harness has no cwd discovery worth trusting). Teaching the materializer these\n * two rows is the durable home for this mapping; until it lands, this module is the only thing in\n * the `backend: 'pi'` path that can honor `profile.mcp` at all.\n *\n * Verified against pi 0.83.0 and pi-mcp-adapter 2.15.0.\n *\n * @experimental\n */\n\nimport { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { homedir, tmpdir } from 'node:os'\nimport { isAbsolute, join, sep } from 'node:path'\nimport type {\n AgentProfile,\n AgentProfileConfigValue,\n AgentProfileMcpServer,\n} from '@tangle-network/agent-interface'\nimport { ConfigError, ValidationError } from '../../errors'\n\n/** The pi extension that gives pi MCP at all. Everything here is gated on it being loadable. */\nexport const PI_MCP_ADAPTER = 'pi-mcp-adapter'\n\n/** Overrides adapter detection for installs whose path does not carry the adapter's name. */\nexport const PI_MCP_ADAPTER_ENV = 'AGENT_RUNTIME_PI_MCP_ADAPTER'\n\n/** The adapter-registered flag that names this run's config file (`pi-mcp-adapter` `index.ts:252`). */\nexport const PI_MCP_CONFIG_FLAG = '--mcp-config'\n\n/** What the caller must call once pi has exited, and where the config landed. */\nexport interface PiMcpMount {\n /** Absolute path of the file passed to `--mcp-config`. Unique to this worker execution. */\n configPath: string\n /** Server names actually written, post-filter — never the raw `profile.mcp` keys. */\n serverNames: string[]\n /** Remove the private config directory. Idempotent; safe to call on any exit path. */\n cleanup(): void\n}\n\n/**\n * What pi was actually given, as opposed to what the profile declared. This is the observable that\n * makes rule 2 above honest: `adapterInjected` is `true` exactly when this module added an extension\n * the caller did not ask for, because without it the MCP servers the caller DID ask for could not\n * have mounted.\n */\nexport interface PiMcpReceipt {\n /** Server names written into `configPath`, in declaration order. */\n servers: string[]\n /** Absolute path of the mounted config. */\n configPath: string\n /** `extensions.pi.load` entries as pi received them, resolved to absolute entry files. */\n extensions: string[]\n /** True when `pi-mcp-adapter` was absent from an explicit `load` array and was added here. */\n adapterInjected: boolean\n}\n\n/** Everything `piExecutor` needs between \"profile in hand\" and \"pi spawned\". */\nexport interface PiMcpPreparation {\n /** Extra argv for `pi`, in flag order: extension flags first, then `--mcp-config <path>`. */\n args: string[]\n /** Present only when at least one usable MCP server was declared. */\n mount: PiMcpMount | null\n /** Present only when a mount happened — the derived-versus-declared record. */\n receipt: PiMcpReceipt | undefined\n}\n\n/** pi's agent home. Holds `settings.json` and `npm/node_modules/<extension>`. */\nexport function piAgentDir(): string {\n return process.env.PI_CODING_AGENT_DIR ?? join(homedir(), '.pi', 'agent')\n}\n\n/** `<agentDir>/npm`, whose `node_modules/<pkg>` holds installed pi extensions. */\nexport function piNpmRoot(): string {\n return join(piAgentDir(), 'npm')\n}\n\n/**\n * True when pi can actually consume MCP config — i.e. `pi-mcp-adapter` is installed. Ported from\n * cli-bridge `pi.ts:189`: an env override first (for vendored installs whose path does not carry the\n * adapter's name), then the npm install directory, then a scan of `settings.json` `packages` in\n * which a local-path entry is resolved by reading the target's `package.json` `name`. An\n * unreadable or absent `settings.json` reports \"not detected\"; it never throws and never assumes.\n */\nexport function piMcpAdapterAvailable(): boolean {\n const override = process.env[PI_MCP_ADAPTER_ENV]\n if (override === '1' || override === 'true') return true\n if (override === '0' || override === 'false') return false\n const agentDir = piAgentDir()\n if (existsSync(join(agentDir, 'npm', 'node_modules', PI_MCP_ADAPTER))) return true\n try {\n const settings = JSON.parse(readFileSync(join(agentDir, 'settings.json'), 'utf-8')) as {\n packages?: unknown\n }\n if (!Array.isArray(settings.packages)) return false\n return settings.packages.some((entry) => packageEntryIsAdapter(entry, agentDir))\n } catch {\n // unreadable/absent settings — fall through to \"not detected\"\n return false\n }\n}\n\n/** One `settings.json` `packages[]` entry: a name containing the adapter, or a local path to it. */\nfunction packageEntryIsAdapter(entry: unknown, agentDir: string): boolean {\n if (typeof entry !== 'string') return false\n if (entry.includes(PI_MCP_ADAPTER)) return true\n // Local-path installs (`/some/dir`, `./rel`, `file:…`, `path:…`) may not carry the adapter's name\n // in the path. Relative specs resolve against the agent dir (where settings.json lives), never the\n // host process cwd.\n const spec = entry.replace(/^(file|path):(\\/\\/)?/, '')\n const windowsAbsolute = /^[A-Za-z]:[\\\\/]/.test(spec)\n if (!isAbsolute(spec) && !windowsAbsolute && !spec.startsWith('.')) return false\n const localPath = isAbsolute(spec) || windowsAbsolute ? spec : join(agentDir, spec)\n return readPackageName(localPath) === PI_MCP_ADAPTER\n}\n\nfunction readPackageName(packageDir: string): string | undefined {\n try {\n const manifest = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf-8')) as {\n name?: unknown\n }\n return typeof manifest.name === 'string' ? manifest.name : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Read one `AgentProfileConfigValue` as public bytes. A `secret-ref` is REFUSED rather than\n * stringified: this executor has no secret provider, so the only alternatives are writing a\n * placeholder into the config (an auth failure disguised as a tool bug) or writing the literal\n * reference object (nonsense to the adapter). Plain strings, numbers and booleans are accepted\n * because profiles authored as JSON commonly carry them where the type says `{kind:'public'}`.\n */\nfunction publicConfigString(\n value: AgentProfileConfigValue | string | number | boolean,\n where: string,\n): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n if (value && typeof value === 'object' && value.kind === 'public') return value.value\n if (value && typeof value === 'object' && value.kind === 'secret-ref') {\n throw new ConfigError(\n `piExecutor: ${where} is a secret-ref (\"${value.key}\") and piExecutor has no secret provider; ` +\n 'resolve it before handing the profile to the executor, or declare a public value',\n )\n }\n throw new ValidationError(`piExecutor: ${where} is not a public configuration value`)\n}\n\n/**\n * Build the canonical `{ mcpServers }` body the adapter reads, from `AgentProfile.mcp`.\n *\n * Every server is written with `directTools: true` (`pi-mcp-adapter` types.ts:351), which\n * registers its tools as NATIVE pi tools instead of hiding them behind the generic `mcp` tool.\n * Without it an agent must discover its own verbs before it can use them — connect to the server,\n * then describe each tool — and a measured run spent 58 turns and 639,632 input tokens doing that\n * before it could delegate once. A profile that declares an MCP server is asking for its tools,\n * not for a directory it has to browse.\n *\n * This is cli-bridge's `buildCanonicalMcpServers`\n * (`/home/drew/code/cli-bridge/src/backends/profile-support.ts:253`) reproduced field for field and\n * in the same key order — same drop of `enabled:false`, same stdio-versus-remote decision\n * (`isStdioMcpSpec`, `profile-support.ts:177`), same `{command, args, env}` and `{type, url,\n * headers}` bodies, same silent drop of an entry with nothing to connect to. For any server both\n * input types can express, the emitted JSON is byte-identical.\n *\n * The two input types are not the same type, so three differences remain and each is a field one\n * side cannot express:\n *\n * 1. **`cwd` (emitted here, absent there).** `AgentProfileLocalMcpServer` has `cwd`; cli-bridge's\n * `McpServerSpec` (`src/backends/types.ts:53`) has no such field, so it can never emit one. The\n * adapter honors it (`pi-mcp-adapter` `types.ts:325`, `ServerEntry.cwd`), so dropping it would\n * silently discard a declared setting. It is emitted where cli-bridge emits `timeout`.\n * 2. **`timeout` (emitted there, absent here).** `AgentProfileMcpServer` has no timeout field, so\n * there is nothing to emit. (The adapter's own knob is `requestTimeoutMs`, not `timeout`.)\n * 3. **A `url` with no declared transport.** cli-bridge DROPS it — its remote branch requires an\n * explicit `spec.type` — even though its own `McpServerSpec` docstring says \"http is implied if\n * `url` is set\" (`types.ts:53-56`). `transport` is optional on `AgentProfileRemoteMcpServer`, so\n * dropping such a server here would be exactly the silent-drop bug this module exists to fix.\n * We honor the documented convention and emit `type: 'http'`.\n *\n * `sse` is ACCEPTED and forwarded verbatim, as cli-bridge forwards it. The adapter connects a URL\n * server by probing StreamableHTTP and falling back to `SSEClientTransport` when the probe fails\n * (`pi-mcp-adapter` `server-manager.ts:765`), so an SSE-only endpoint does connect. Its\n * `ServerEntry` (`types.ts:319`) carries no transport discriminator at all, which means the `type`\n * key is inert to the adapter either way — but it is what cli-bridge writes, and a config file that\n * round-trips the caller's declared transport is the one that stays readable by both.\n */\nexport function buildPiMcpServers(\n mcp: Record<string, AgentProfileMcpServer> | undefined,\n): Record<string, Record<string, unknown>> {\n const out: Record<string, Record<string, unknown>> = {}\n if (!mcp || typeof mcp !== 'object') return out\n for (const [name, raw] of Object.entries(mcp)) {\n if (!name || !raw || typeof raw !== 'object') continue\n if (raw.enabled === false) continue\n const transport = raw.transport\n const command = typeof raw.command === 'string' && raw.command.length > 0 ? raw.command : null\n const url = typeof raw.url === 'string' && raw.url.length > 0 ? raw.url : null\n // cli-bridge `isStdioMcpSpec`: an explicit stdio transport still needs a command; an explicit\n // remote transport is never stdio; with no transport declared, a command decides.\n const stdio = transport === 'http' || transport === 'sse' ? false : command !== null\n if (stdio && command !== null) {\n const args = Array.isArray(raw.args)\n ? raw.args.map((a, i) => publicConfigString(a, `mcp[\"${name}\"].args[${i}]`))\n : []\n const env = readConfigRecord(raw.env, `mcp[\"${name}\"].env`)\n out[name] = {\n command,\n ...(args.length > 0 ? { args } : {}),\n ...(Object.keys(env).length > 0 ? { env } : {}),\n ...(typeof raw.cwd === 'string' && raw.cwd.length > 0 ? { cwd: raw.cwd } : {}),\n directTools: true,\n }\n continue\n }\n if (url !== null && transport !== 'stdio') {\n const headers = readConfigRecord(raw.headers, `mcp[\"${name}\"].headers`)\n out[name] = {\n type: transport === 'sse' ? 'sse' : 'http',\n url,\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n directTools: true,\n }\n }\n // No command and no url — nothing to connect to. Dropped, exactly as cli-bridge drops it.\n }\n return out\n}\n\nfunction readConfigRecord(\n record: Record<string, AgentProfileConfigValue> | undefined,\n where: string,\n): Record<string, string> {\n if (!record || typeof record !== 'object') return {}\n const out: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) continue\n out[key] = publicConfigString(value, `${where}[\"${key}\"]`)\n }\n return out\n}\n\n/**\n * Resolve one `extensions.pi.load` entry to an absolute extension entry file. Ported from cli-bridge\n * `resolvePiExtensionEntry` (`pi.ts:123`): an absolute path is used verbatim; a bare package name\n * resolves to `<npmRoot>/node_modules/<pkg>/<package.json main>`, `main` defaulting to `index.ts`.\n * The resolution is required because pi's per-file loader does NOT resolve bare specifiers against\n * `~/.pi/agent/npm/node_modules`. Fail-closed: an unreadable manifest or a missing entry file\n * rejects the run rather than letting an ablation arm run without the extension it declared.\n */\nexport function resolvePiExtensionEntry(spec: string, npmRoot: string): string {\n let entry: string\n if (isAbsolute(spec)) {\n entry = spec\n } else {\n const packageDir = join(npmRoot, 'node_modules', spec)\n let main = 'index.ts'\n try {\n const manifest = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf-8')) as {\n main?: unknown\n }\n if (typeof manifest.main === 'string' && manifest.main) main = manifest.main\n } catch (err) {\n throw new ConfigError(\n `piExecutor: cannot load pi extension \"${spec}\": ${join(packageDir, 'package.json')} is ` +\n `not readable (install it with \\`pi install npm:${spec}\\`): ` +\n `${err instanceof Error ? err.message : String(err)}`,\n )\n }\n entry = join(packageDir, main)\n }\n if (!existsSync(entry)) {\n throw new ConfigError(\n `piExecutor: cannot load pi extension \"${spec}\": resolved entry ${entry} does not exist`,\n )\n }\n return entry\n}\n\n/** Does this `load` entry name the MCP adapter, before resolution? */\nfunction entryNamesAdapter(spec: string): boolean {\n if (!isAbsolute(spec)) return spec === PI_MCP_ADAPTER\n const normalized = spec.split(/[\\\\/]/)\n if (normalized.includes(PI_MCP_ADAPTER)) return true\n // An absolute path outside a `pi-mcp-adapter/` directory still counts when the package it belongs\n // to declares that name — a vendored checkout under any directory name.\n const parent = spec.slice(0, spec.lastIndexOf(sep) + 1)\n return parent.length > 0 && readPackageName(parent) === PI_MCP_ADAPTER\n}\n\n/** Outcome of lowering `extensions.pi.load` into argv. */\nexport interface PiExtensionArgs {\n args: string[]\n /** Resolved absolute entry files, in the order pi receives them. */\n entries: string[]\n adapterInjected: boolean\n}\n\n/**\n * Lower `AgentProfile.extensions.pi.load` into pi argv, honoring the `--no-extensions` trap.\n *\n * `load` absent (not an array) → no flags at all, so pi keeps its default discovery and the adapter\n * auto-loads from `settings.json` `packages`. `load` present → `--no-extensions` plus one\n * `--extension <absolute entry>` per listed extension, which is what makes an ablation arm\n * reproducible and leak-free.\n *\n * When `mcpRequested` is true and an explicit `load` array does not already name the adapter, the\n * adapter is APPENDED — otherwise `--no-extensions` would suppress the very extension that turns\n * the `--mcp-config` file into tools. The caller's profile is not touched; the addition is reported\n * through `adapterInjected` so it reaches the executor receipt and the live progress channel.\n *\n * A non-string or blank entry is a schema error here, not a silent skip: an ablation arm that\n * quietly drops a typo'd extension is the same class of structural false-null this module exists to\n * eliminate.\n */\nexport function derivePiExtensionArgs(\n profile: { extensions?: Record<string, Record<string, unknown> | undefined> } | undefined,\n mcpRequested: boolean,\n): PiExtensionArgs {\n const load = profile?.extensions?.pi?.load\n if (!Array.isArray(load)) return { args: [], entries: [], adapterInjected: false }\n\n const declared: string[] = []\n for (const [index, entry] of load.entries()) {\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new ValidationError(\n `piExecutor: extensions.pi.load[${index}] must be a non-empty string ` +\n `(got ${entry === null ? 'null' : typeof entry})`,\n )\n }\n declared.push(entry.trim())\n }\n\n const adapterInjected = mcpRequested && !declared.some(entryNamesAdapter)\n const resolvedSpecs = adapterInjected ? [...declared, PI_MCP_ADAPTER] : declared\n\n const npmRoot = piNpmRoot()\n const entries = resolvedSpecs.map((spec) => resolvePiExtensionEntry(spec, npmRoot))\n const args = ['--no-extensions']\n for (const entry of entries) args.push('--extension', entry)\n return { args, entries, adapterInjected }\n}\n\n/** Where one worker execution's private config directory is created, and what it is called. */\nexport interface PiMcpMountOptions {\n /**\n * The worker's own working directory (`PiSeam.cwd`). Omit when the seam names none: the config\n * then lands in the OS temp directory. It is NEVER written into `process.cwd()` — the operator's\n * own working directory is not a scratch space for a worker's config.\n */\n cwd?: string\n /**\n * The executor's per-execution run id, folded into the directory name so a directory that somehow\n * survives names the worker that left it. Uniqueness is NOT taken from this — `mkdtemp` provides\n * it — because two workers built from one factory in the same millisecond share a run id stem.\n */\n runId: string\n}\n\n/** Directory-name-safe form of a run id; the `mkdtemp` suffix supplies the uniqueness. */\nfunction runIdSlug(runId: string): string {\n const slug = runId.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '')\n return slug.length > 0 ? slug.slice(0, 60) : 'worker'\n}\n\n/**\n * Write this worker execution's MCP config to a directory only it owns, and hand back the removal.\n *\n * Every property of the old cwd-discovered mount — a cross-process lock, a merge under whatever the\n * workspace already had, a verbatim byte restore, a symlink guard on `.pi` — existed because two\n * workers sharing a `PiSeam` shared one file path. `mkdtemp` deletes the shared path, and with it\n * the entire class of problem: the directory did not exist a moment ago, nothing else can name it,\n * `cleanup()` removes it whole, and two siblings started in the same millisecond get two configs.\n *\n * Returns `null` when there are no usable servers, so the no-MCP path writes nothing at all.\n */\nexport function mountPiMcpConfig(\n mcpServers: Record<string, Record<string, unknown>>,\n options: PiMcpMountOptions,\n): PiMcpMount | null {\n const serverNames = Object.keys(mcpServers)\n if (serverNames.length === 0) return null\n\n const slug = runIdSlug(options.runId)\n // ALWAYS the OS temp directory, never the worker's workspace. The path is handed to pi by\n // `--mcp-config`, so it does not need to sit anywhere discoverable — and a scratch directory\n // inside the workspace is a file the worker did not create, in a tree it may commit, diff, or\n // clean. A dot prefix hides it from `ls`, not from `git status`.\n const base = tmpdir()\n const prefix = `agent-runtime-pi-mcp-${slug}-`\n\n let dir: string\n try {\n dir = mkdtempSync(join(base, prefix))\n } catch (err) {\n throw new ConfigError(\n `piExecutor: cannot create a private MCP config directory under ${base}: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n const configPath = join(dir, 'mcp.json')\n try {\n // `wx` because a fresh mkdtemp directory cannot already hold this file — if it does, something\n // is wrong enough that overwriting would hide it.\n writeFileSync(configPath, JSON.stringify({ mcpServers }, null, 2), { flag: 'wx', mode: 0o600 })\n } catch (err) {\n rmSync(dir, { recursive: true, force: true })\n throw new ConfigError(\n `piExecutor: failed to write the MCP config at ${configPath}: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n let cleaned = false\n return {\n configPath,\n serverNames,\n cleanup: (): void => {\n if (cleaned) return\n cleaned = true\n rmSync(dir, { recursive: true, force: true })\n },\n }\n}\n\n/**\n * The one call `piExecutor` makes before spawning pi: decide what pi must be told, fail loud if it\n * cannot work, then mount.\n *\n * Order matters and is the point:\n *\n * 1. Canonicalize `profile.mcp` first, so the adapter gate keys off servers that would ACTUALLY be\n * written — a block of `enabled:false` entries must not trip it.\n * 2. If any server survives and `pi-mcp-adapter` is not installed, throw. No file has been written\n * and pi has not been spawned.\n * 3. Lower `extensions.pi.load` (which may itself throw on an unresolvable extension) — still before\n * any file exists.\n * 4. Only then create this execution's private config directory and emit `--mcp-config`.\n *\n * A profile with no usable MCP server is a pure no-op: no adapter check, no directory, no flags, no\n * throw. `extensions.pi.load` on its own still produces flags, because reproducible ablation arms\n * need them whether or not MCP is involved.\n *\n * The caller MUST call `mount.cleanup()` on every exit path — settle, throw, abort, timeout, and\n * spawn failure — so the directory does not outlive the worker that owns it.\n */\nexport function preparePiMcp(\n profile: AgentProfile | undefined,\n options: PiMcpMountOptions,\n): PiMcpPreparation {\n const mcpServers = buildPiMcpServers(profile?.mcp)\n const requested = Object.keys(mcpServers)\n\n if (requested.length > 0 && !piMcpAdapterAvailable()) {\n throw new ConfigError(\n `piExecutor: cannot mount MCP servers for pi (${requested.join(', ')}): the ` +\n `${PI_MCP_ADAPTER} extension is not installed. pi ships no MCP support of its own, so ` +\n 'these servers would never connect and the worker would run tool-less. Looked in ' +\n `${join(piNpmRoot(), 'node_modules', PI_MCP_ADAPTER)} and in the \\`packages\\` list of ` +\n `${join(piAgentDir(), 'settings.json')}. Install it with ` +\n `\\`pi install npm:${PI_MCP_ADAPTER}\\`, or set ${PI_MCP_ADAPTER_ENV}=1 if it is vendored ` +\n 'somewhere this check cannot see.',\n )\n }\n\n const extensions = derivePiExtensionArgs(profile, requested.length > 0)\n if (requested.length === 0) return { args: extensions.args, mount: null, receipt: undefined }\n\n const mount = mountPiMcpConfig(mcpServers, options)\n if (!mount) return { args: extensions.args, mount: null, receipt: undefined }\n return {\n args: [...extensions.args, PI_MCP_CONFIG_FLAG, mount.configPath],\n mount,\n receipt: {\n servers: mount.serverNames,\n configPath: mount.configPath,\n extensions: extensions.entries,\n adapterInjected: extensions.adapterInjected,\n },\n }\n}\n","/**\n *\n * `TraceSource` — the ONE substrate-agnostic source of a worker's tool-call trace. The online\n * detectors and the settle-time analyzers consume agent-eval `ToolSpan`s from here, regardless of\n * whether the worker is:\n * - an OWNED tool loop (router-tools, cli-bridge tool dispatch) → push spans as we dispatch them;\n * - a SANDBOX / fleet box → read the harness's tool calls off the session (`streamPrompt` parts\n * live, `session.messages()` / `findCompletedTurn` at settle).\n *\n * The common currency is agent-eval's `ToolSpan` (so the same detectors + `buildTrajectory`/\n * `stuckLoopView`/`toolWasteView` run over any source). A source exposes two lanes:\n * - `onSpan` — live spans for ONLINE detection (best-effort; a black-box box may only collect).\n * - `collect` — the full span set at settle for the BATCH analyzers (always available).\n *\n * This module imports NO substrate SDK — it decodes generic message parts / OpenAI tool-call shapes.\n * The sandbox wiring (`sandboxSessionTraceSource`) is the thin adapter that feeds box session parts in.\n *\n * @experimental\n */\n\nimport type { ToolSpan } from '@tangle-network/agent-eval'\nimport type { ToolPart, ToolState } from '@tangle-network/agent-interface'\n\nexport interface ToolStepInput {\n readonly toolName: string\n readonly args: unknown\n /** False when the call was observed but its original arguments were unavailable. */\n readonly argsCaptured?: boolean\n readonly status?: 'ok' | 'error'\n readonly result?: unknown\n readonly error?: string\n /** Stable id of the tool call — used to de-duplicate the repeated state transitions a harness\n * streams for one call (opencode emits pending→running→completed, plus a `raw`-wrapped copy). */\n readonly callId?: string\n /** Real per-call wall-clock when the source has it (owned tool-loop; opencode parts with `time`).\n * When omitted the span collapses to a single instant (`at`) — order + counts only, no duration. */\n readonly startedAt?: number\n readonly endedAt?: number\n}\n\nexport interface TraceSource {\n /** Subscribe to tool spans as they are produced (ONLINE). Returns an unsubscribe. A source that\n * only exposes its trace at the end registers nothing and returns a no-op. */\n onSpan(handler: (span: ToolSpan) => void): () => void\n /** The full set of tool spans for the run (SETTLE / batch). Always available. */\n collect(): Promise<ToolSpan[]>\n}\n\n/** Project a normalized tool step into the canonical agent-eval `ToolSpan`. When the step carries\n * real wall-clock (`startedAt`/`endedAt`) the span gets a true duration; otherwise it collapses to\n * the single instant `at` (order + counts only — the historical behavior). */\nexport function toToolSpan(input: ToolStepInput, runId: string, seq: number, at: number): ToolSpan {\n const startedAt = typeof input.startedAt === 'number' ? input.startedAt : at\n const endedAt = typeof input.endedAt === 'number' ? input.endedAt : startedAt\n return {\n spanId: `${runId}-t${seq}`,\n runId,\n kind: 'tool',\n name: input.toolName,\n toolName: input.toolName,\n args: input.args,\n ...(input.argsCaptured === false ? { argsCaptured: false } : {}),\n status: input.status ?? 'ok',\n ...(input.error !== undefined ? { error: input.error } : {}),\n startedAt,\n endedAt,\n ...(input.result !== undefined ? { result: input.result } : {}),\n }\n}\n\n/** Decode one harness message part into a tool step, or `undefined` if it is not a (completed) tool\n * call. ONE adapter per harness family — each owns its real wire shape; the flow downstream is\n * identical. Add a harness = add a decoder + register it; no other code changes. */\nexport type ToolPartDecoder = (part: Record<string, unknown>) => ToolStepInput | undefined\n\nconst obj = (v: unknown): Record<string, unknown> | undefined =>\n v && typeof v === 'object' ? (v as Record<string, unknown>) : undefined\nconst str = (v: unknown): string | undefined => (typeof v === 'string' && v ? v : undefined)\n\n/** opencode parts ARE agent-interface's canonical `ToolPart` (`{ type:'tool', tool, callID?,\n * state: ToolState }`) — the shape every adc sdk-provider normalizes its harness output into. We\n * decode against that published type (single source of truth) rather than a re-derived shape; the\n * `ToolState` union drives the status mapping, so a status that adc adds/renames is a compile error\n * here, not a silent miss. The same call streams pending→running→terminal; only a terminal state\n * (`completed` / `error` / `failed`) is a finished call. */\nexport const decodeOpencodePart: ToolPartDecoder = (raw) => {\n if (str(raw.type)?.toLowerCase() !== 'tool' || !str(raw.tool)) return undefined\n const part = raw as Partial<ToolPart>\n const state = obj(part.state) as ToolState | undefined\n const status = state?.status\n if (!status || status === 'pending' || status === 'running') return undefined\n return {\n toolName: part.tool as string,\n args: state?.input ?? {},\n // ToolStateError carries 'error' OR 'failed' — the reverse-engineered decoder missed 'failed'.\n status: status === 'error' || status === 'failed' ? 'error' : 'ok',\n ...(str(part.callID) ? { callId: part.callID as string } : {}),\n }\n}\n\n/** Anthropic / claude-code (also kimi's tool_use variant): a `{ type:'tool_use', id|tool_use_id,\n * name|tool, input }` content block. CONFIRMED against the cli-bridge's authoritative parsers\n * (claude.ts reads `block.type==='tool_use', block.id, block.name, block.input`; kimi.ts adds the\n * `tool_use_id`/`tool` fallbacks) — the canonical readers of these harnesses' real native output. */\nexport const decodeAnthropicPart: ToolPartDecoder = (p) => {\n if (str(p.type)?.toLowerCase() !== 'tool_use') return undefined\n const name = str(p.name) ?? str(p.tool)\n if (!name) return undefined\n const id = str(p.id) ?? str(p.tool_use_id)\n return {\n toolName: name,\n args: p.input ?? {},\n ...(id ? { callId: id } : {}),\n }\n}\n\n/** OpenAI-compatible (router / kimi's top-level form / glm): `{ type:'function'|'tool_call', id,\n * function:{ name, arguments:<JSON string> } }`. CONFIRMED against the cli-bridge (kimi.ts surfaces\n * kimi's top-level `tool_calls:[{type:'function', id, function:{name,arguments}}]` exactly this way).\n * NOTE: codex does NOT emit structured tool calls (the bridge's codex.ts never yields `tool_calls` —\n * it runs shell internally and surfaces only text), so per-tool detection is unavailable for codex\n * from any path — a harness property, not a decoder gap. */\nexport const decodeOpenAiPart: ToolPartDecoder = (p) => {\n const type = str(p.type)?.toLowerCase()\n const fn = obj(p.function)\n // Match on the type OpenAI always sets — not the mere presence of a `.function` field (a\n // `{type:'text', function:{…}}` part must not decode). Name is required below.\n if (type !== 'function' && type !== 'tool_call') return undefined\n const name = str(fn?.name) ?? str(p.name)\n if (!name) return undefined\n const rawArgs = fn?.arguments ?? p.arguments\n return {\n toolName: name,\n args: typeof rawArgs === 'string' ? safeParse(rawArgs) : (rawArgs ?? {}),\n ...(str(p.id) ? { callId: p.id as string } : str(fn?.id) ? { callId: fn?.id as string } : {}),\n }\n}\n\n/** The harness → decoder registry. Add a harness by adding one entry. */\nexport const toolPartDecoders: Record<string, ToolPartDecoder> = {\n opencode: decodeOpencodePart,\n 'claude-code': decodeAnthropicPart,\n anthropic: decodeAnthropicPart,\n codex: decodeOpenAiPart,\n openai: decodeOpenAiPart,\n router: decodeOpenAiPart,\n kimi: decodeOpenAiPart,\n}\n\n/** Decode a part with a specific harness's adapter when known, else try every registered adapter\n * (the composite — robust to mixed/unknown streams). Never throws. */\nexport function decodeToolPart(part: unknown, harness?: string): ToolStepInput | undefined {\n const p = obj(part)\n if (!p) return undefined\n const specific = harness ? toolPartDecoders[harness] : undefined\n if (specific) return specific(p)\n for (const decode of new Set(Object.values(toolPartDecoders))) {\n const step = decode(p)\n if (step) return step\n }\n return undefined\n}\n\nfunction safeParse(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n\nlet runSeq = 0\n\n/** A push source for OWNED tool loops (router-tools / cli-bridge tool dispatch): the loop calls\n * `record(step)` for each tool call; it becomes a span, fan-out to live subscribers + buffered for\n * `collect`. */\nexport function createPushTraceSource(opts: { runId?: string; now?: () => number } = {}): {\n source: TraceSource\n record: (input: ToolStepInput) => ToolSpan\n} {\n const runId = opts.runId ?? `push-${runSeq++}`\n const now = opts.now ?? Date.now\n const spans: ToolSpan[] = []\n const subs = new Set<(span: ToolSpan) => void>()\n return {\n record(input) {\n const span = toToolSpan(input, runId, spans.length, now())\n spans.push(span)\n for (const fn of subs) {\n try {\n fn(span)\n } catch {\n // a throwing subscriber (e.g. a detector onSignal) must never break the producer loop\n }\n }\n return span\n },\n source: {\n onSpan(handler) {\n subs.add(handler)\n return () => subs.delete(handler)\n },\n collect: () => Promise.resolve([...spans]),\n },\n }\n}\n\n/** A source backed by harness message PARTS (sandbox session, cli-bridge). `collect` reads the full\n * part list and decodes the tool calls; `subscribe`, when given, streams parts live for online\n * detection. The caller supplies how to get parts (e.g. `box.session(id).messages()` flat-mapped to\n * parts) — keeping this module free of any substrate SDK. */\nexport function createPartsTraceSource(opts: {\n collectParts: () => Promise<ReadonlyArray<unknown>>\n subscribeParts?: (onPart: (part: unknown) => void) => () => void\n /** The harness whose decoder to use (e.g. 'opencode'); omit to try every registered adapter. */\n harness?: string\n runId?: string\n now?: () => number\n}): TraceSource {\n const runId = opts.runId ?? `parts-${runSeq++}`\n const now = opts.now ?? Date.now\n const subs = new Set<(span: ToolSpan) => void>()\n // De-dup the repeated transitions a harness streams for one call (pending/running/completed + a\n // `raw`-wrapped copy all decode to the same terminal step) — one span per callId.\n const seenLive = new Set<string>()\n let liveSeq = 0\n let unsub: (() => void) | undefined\n const startLive = () => {\n if (unsub || !opts.subscribeParts) return\n unsub = opts.subscribeParts((part) => {\n const step = decodeToolPart(part, opts.harness)\n if (!step) return\n if (step.callId) {\n if (seenLive.has(step.callId)) return\n seenLive.add(step.callId)\n }\n const span = toToolSpan(step, runId, liveSeq++, now())\n for (const fn of subs) {\n try {\n fn(span)\n } catch {\n // a throwing subscriber (e.g. a detector onSignal) must never break the producer loop\n }\n }\n })\n }\n return {\n onSpan(handler) {\n subs.add(handler)\n startLive()\n return () => {\n subs.delete(handler)\n if (subs.size === 0 && unsub) {\n unsub()\n unsub = undefined\n }\n }\n },\n async collect() {\n const parts = await opts.collectParts()\n const spans: ToolSpan[] = []\n const seen = new Set<string>()\n for (const part of parts) {\n const step = decodeToolPart(part, opts.harness)\n if (!step) continue\n if (step.callId) {\n if (seen.has(step.callId)) continue\n seen.add(step.callId)\n }\n spans.push(toToolSpan(step, runId, spans.length, now()))\n }\n return spans\n },\n }\n}\n\n/** A harness session message carrying parts (the shape `box.messages()` returns). Structurally typed\n * so this works with the real `@tangle-network/sandbox` box AND a test double, no SDK import. */\nexport interface SessionMessageLike {\n readonly parts?: ReadonlyArray<unknown>\n}\n\n/** The minimal box surface this needs: list a session's messages (incl. mid-turn partials). */\nexport interface SessionTraceBox {\n messages(opts: { sessionId: string }): Promise<ReadonlyArray<SessionMessageLike>>\n}\n\n/** The SANDBOX / fleet trace source: read a box session's message parts and decode the harness's tool\n * calls into spans. `collect` (settle) is the solid path — `box.messages({sessionId})` → parts → spans;\n * black-box harnesses aren't mid-step interruptible, so online steering is the owned-loop's job and a\n * live `subscribe` is opt-in (pass `subscribeParts` from `streamPrompt` when the harness streams parts). */\nexport function sandboxSessionTraceSource(\n box: SessionTraceBox,\n sessionId: string,\n opts: {\n /** The box's harness (e.g. 'opencode', 'claude-code') → selects its decoder adapter. */\n harness?: string\n subscribeParts?: (onPart: (part: unknown) => void) => () => void\n runId?: string\n now?: () => number\n } = {},\n): TraceSource {\n return createPartsTraceSource({\n collectParts: async () => {\n const msgs = await box.messages({ sessionId })\n return msgs.flatMap((m) => (m.parts ? [...m.parts] : []))\n },\n ...(opts.harness ? { harness: opts.harness } : {}),\n ...(opts.subscribeParts ? { subscribeParts: opts.subscribeParts } : {}),\n runId: opts.runId ?? `box-${sessionId}`,\n ...(opts.now ? { now: opts.now } : {}),\n })\n}\n","/**\n *\n * `piExecutor` — pi wrapped behind `Executor`, NOT forked.\n *\n * pi already implements everything a steerable worker needs, and implements it well: a queued\n * steering channel delivered between turns, follow-ups, abort, compaction, session persistence\n * with fork/branch, and an out-of-process line-delimited JSON protocol over stdin/stdout\n * (`pi --mode rpc`). Reimplementing any of that here would mean owning a turn loop someone else\n * already maintains. So this module is a thin protocol adapter, and every capability maps onto a\n * verb pi already has:\n *\n * `execute` → `prompt`, draining pi's event stream until `agent_settled`\n * `deliver` → `prompt` with `streamingBehavior` — pi owns the queue, we do not\n * `teardown` → `abort`, then close stdin and reap the process\n * `progress` → pi's `tool_execution_start`/`_end` + `turn_end` events, plus `get_state`'s\n * `pendingMessageCount` mirrored locally so the read stays synchronous\n * `traceSource` → the same tool events decoded into the shared `ToolSpan` currency\n * `resultArtifact` → the terminal successful assistant turn\n *\n * It is registered through the DOCUMENTED extension point (`ExecutorRegistry.register('pi', …)`),\n * so nothing in the resolver switches on it and a consumer can replace it wholesale.\n *\n * agent-runtime does NOT take a dependency on pi. The wire shapes (`RpcCommand`, `AgentEvent`)\n * are read structurally off JSON lines, so a pi that adds commands stays compatible and a pi that\n * is not installed simply fails loud at spawn instead of at import.\n *\n * Usage accounting: pi repeats the same assistant receipt in `message_end` and `turn_end`.\n * Only `turn_end` is counted, once per model call. Pi reports cache traffic separately from fresh\n * input, so all three input classes are folded into Runtime's two-field token total. Subscription\n * usage whose dollar price is absent or zero stays explicitly unknown through the live usage\n * stream and terminal artifact.\n *\n * ## What of the `AgentProfile` this executor honors, and what it does not\n *\n * This adapter is NOT a profile materializer. It reads a deliberately small part of\n * `spec.profile`, and a caller who needs the rest must lower it before handing the profile over.\n * Stated exhaustively so a silent drop is never a surprise:\n *\n * | Field | Status |\n * | --- | --- |\n * | `profile.name` | honored — trace `runId` label only, no behavioral effect |\n * | `profile.prompt.systemPrompt` | honored — prepended to the task text (pi RPC takes no separate system-prompt channel) |\n * | `profile.mcp` | honored — written to this execution's own file and passed as `--mcp-config` for `pi-mcp-adapter`; see `pi-mcp.ts` |\n * | `profile.extensions.pi.load` | honored — lowered to `--no-extensions` + `--extension <abs>` |\n * | `profile.prompt.instructions` | DROPPED — fold into `systemPrompt` before calling |\n * | `profile.model` | DROPPED — the seam's `model` is the only model channel; a profile that disagrees with the seam is silently overridden by the seam |\n * | `profile.model.reasoningEffort` | DROPPED — no `--thinking` flag is emitted, so pi's configured `defaultThinkingLevel` applies |\n * | `profile.tools` | DROPPED — no `--no-tools` / allow-deny mapping; pi runs its full builtin tool set |\n * | `profile.permissions` | DROPPED |\n * | `profile.resources` (context / skills / commands / subagents / instructions) | DROPPED — nothing is written into the run cwd |\n * | `profile.hooks` | DROPPED |\n * | `profile.subagents`, `profile.connections`, `profile.modes`, `profile.confidential` | DROPPED |\n * | `profile.resources.failOnError` | not consulted — the MCP path above is unconditionally fail-closed, which is the stricter reading |\n * | every other `profile.extensions.<ns>` | DROPPED — only the `pi` namespace is read |\n *\n * Closing those gaps belongs in `@tangle-network/agent-profile-materialize`, whose plan this\n * executor would then apply, rather than in a second mapping grown here.\n *\n * @experimental\n */\n\nimport { type ChildProcess, spawn } from 'node:child_process'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ValidationError } from '../../errors'\nimport { abortError, throwIfAborted } from '../util'\nimport { createInbox, type Inbox, type InboxMessage } from './inbox'\nimport { PI_MCP_ADAPTER, type PiMcpReceipt, preparePiMcp } from './pi-mcp'\nimport { type ActivityLog, createActivityLog, type ExecutorProgress } from './progress'\nimport { createPushTraceSource, type ToolStepInput, type TraceSource } from './trace-source'\nimport type {\n ExecutorContext,\n ExecutorFactory,\n ExecutorResult,\n Runtime,\n Spend,\n UsageEvent,\n} from './types'\nimport { workerTraceEnv } from './worker-trace'\n\n/** The runtime name `piExecutor` registers under. */\nexport const PI_RUNTIME: Runtime = 'pi'\n\n/** Seam key the registry threads a `PiSeam` through (`ExecutorContext.seams['pi']`). */\nexport const piSeamKey = 'pi'\n\n/** How to launch pi in its out-of-process RPC mode, and how long to wait on it. */\nexport interface PiSeam {\n /** The pi executable (default `'pi'`). Anything on PATH or an absolute path. */\n bin?: string\n /** Extra args appended after `--mode rpc`. `--provider` / `--model` are added from `model`. */\n args?: ReadonlyArray<string>\n /** `provider/model` or just `model` — split on the first `/` into pi's two flags. */\n model?: string\n cwd?: string\n env?: Record<string, string>\n /** Wall-clock ceiling for one `prompt` (the wait for `agent_settled`). Omit = no timeout. */\n turnTimeoutMs?: number\n /** Newest-last activity window `progress()` reports. Default 12. */\n activityWindow?: number\n}\n\n/** Structural read of Pi's stdout records: agent events plus correlated RPC responses. */\ninterface PiEvent {\n id?: string\n type?: string\n command?: string\n success?: boolean\n error?: string\n toolCallId?: string\n toolName?: string\n args?: unknown\n result?: unknown\n isError?: boolean\n message?: unknown\n}\n\ninterface PendingPiTool {\n args: unknown\n startedAt: number\n}\n\ninterface PiAssistantOutcome {\n text: string\n stopReason?: string\n errorMessage?: string\n}\n\n/** Build the `Executor` for one pi worker. Registered as runtime `'pi'`. */\nexport const piExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n const seam = readPiSeam(ctx)\n // `TRACE_ID` / `PARENT_SPAN_ID` for this worker when the run records spans; `{}` otherwise, which\n // leaves the spawn environment byte-identical to the untraced path.\n const traceEnv = workerTraceEnv(ctx)\n const inbox = createInbox()\n const activity = createActivityLog(seam.activityWindow ?? 12)\n // One id per worker EXECUTION, not per factory: it labels the trace and names this worker's\n // private MCP config directory, and two workers built from one seam must not share either.\n const runId = `pi-${spec.profile.name ?? 'worker'}-${Date.now()}`\n const trace = createPushTraceSource({ runId })\n // What this executor changed about what the caller declared. Unlike `recentActivity` this is\n // never evicted, so a run that fails after the change still reports it.\n const derived: string[] = []\n\n const controller = new AbortController()\n const cascade = () => controller.abort()\n if (ctx.signal.aborted) controller.abort()\n else ctx.signal.addEventListener('abort', cascade, { once: true })\n\n const state = {\n turns: 0,\n lastText: '',\n note: 'starting',\n proc: undefined as ChildProcess | undefined,\n artifact: undefined as ExecutorResult<unknown> | undefined,\n }\n\n return {\n runtime: PI_RUNTIME,\n // pi owns the queue; `deliver` only routes through its state-safe `prompt` command. Its\n // streaming behavior chooses steer versus follow-up atomically in pi, rather than trusting\n // this adapter's delayed view of whether the current run has already ended.\n deliver: (m) => inbox.deliver(m),\n progress: (): ExecutorProgress => ({\n turns: state.turns,\n pendingMessages: inbox.pending(),\n recentActivity: activity.read(),\n ...(derived.length > 0 ? { derived: [...derived] } : {}),\n note: state.note,\n }),\n traceSource: (): TraceSource => trace.source,\n execute(task, signal): AsyncIterable<UsageEvent> {\n return streamPiSession({\n task,\n signal,\n controller,\n seam,\n traceEnv,\n spec,\n runId,\n inbox,\n activity,\n derived,\n record: (step: ToolStepInput) => {\n trace.record(step)\n },\n state,\n })\n },\n async teardown(grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n const proc = state.proc\n if (!proc || proc.exitCode !== null || proc.killed) return { destroyed: true }\n // Ask pi to stop cleanly first — an `abort` lets it finalize its session JSONL, which is\n // the whole reason to wrap pi rather than kill it.\n sendCommand(proc, { type: 'abort' })\n return killPi(proc, grace)\n },\n resultArtifact() {\n if (!state.artifact) {\n throw new ValidationError('piExecutor: resultArtifact() read before stream drained')\n }\n return state.artifact\n },\n }\n}\n\n/** What one pi run reports about the terminal assistant turn, plus any derived MCP mount. */\nexport interface PiExecutorOutput {\n content: string\n turns: number\n /** Present only when `profile.mcp` declared at least one usable server. Records what pi was\n * actually given — including an extension this executor added that the profile did not list. */\n mcp?: PiMcpReceipt\n}\n\ninterface StreamPiArgs {\n task: unknown\n signal: AbortSignal\n controller: AbortController\n seam: PiSeam\n /** Inherited `TRACE_ID` / `PARENT_SPAN_ID` for the pi subprocess; empty when tracing is off. */\n traceEnv: Record<string, string>\n spec: { profile: AgentProfile }\n /** This execution's id — labels the trace and names the private MCP config directory. */\n runId: string\n inbox: Inbox\n activity: ActivityLog\n /** Append-only record of what this executor changed about the caller's declaration. */\n derived: string[]\n record: (step: ToolStepInput) => void\n state: {\n turns: number\n lastText: string\n note: string\n proc: ChildProcess | undefined\n artifact: ExecutorResult<unknown> | undefined\n }\n}\n\n/**\n * One pi RPC session, run to `agent_settled`. Every steer delivered while the turn is in flight is\n * forwarded to pi IMMEDIATELY (pi queues and delivers it at its own turn boundary — the queue we\n * deliberately do not reimplement), and any steer still unread when pi settles re-prompts it.\n * `agent_end` is deliberately not terminal: Pi may auto-retry or compact after emitting it.\n */\nasync function* streamPiSession(args: StreamPiArgs): AsyncIterable<UsageEvent> {\n const { seam, inbox, activity, state } = args\n const started = Date.now()\n const tokens = { input: 0, output: 0 }\n let usd = 0\n let usdKnown = true\n throwIfAborted(args.signal)\n throwIfAborted(args.controller.signal)\n\n // Profile-declared MCP servers become this execution's OWN `--mcp-config` file BEFORE pi starts,\n // because `pi-mcp-adapter` reads that path at load time. The file is private to this worker, so\n // two workers built from one seam never share it. This THROWS — before any file is written and\n // before pi is spawned — when the adapter that gives pi MCP at all is missing, rather than\n // starting a worker whose declared tools silently do not exist.\n const piMcp = preparePiMcp(args.spec.profile, {\n ...(seam.cwd !== undefined ? { cwd: seam.cwd } : {}),\n runId: args.runId,\n })\n if (piMcp.receipt) {\n const injected = piMcp.receipt.adapterInjected ? ` (+${PI_MCP_ADAPTER} added)` : ''\n activity.push({\n at: Date.now(),\n kind: 'note',\n label: 'mcp',\n detail: `${piMcp.receipt.servers.join(', ')}${injected}`,\n })\n // `recentActivity` is a bounded ring and `resultArtifact()` throws until the stream drains, so\n // neither can answer \"what was pi actually given?\" for a run that failed on turn 40. This can.\n args.derived.push(\n `mcp: mounted ${piMcp.receipt.servers.join(', ')} via --mcp-config ${piMcp.receipt.configPath}`,\n )\n if (piMcp.receipt.adapterInjected) {\n args.derived.push(\n `extensions: added ${PI_MCP_ADAPTER} to extensions.pi.load — the profile's own list would ` +\n 'have run under --no-extensions and suppressed it, mounting zero servers',\n )\n }\n }\n\n let proc: ChildProcess\n try {\n proc = spawnPi(seam, piMcp.args, args.traceEnv)\n } catch (spawnFailure) {\n // The config directory was created before the spawn was attempted; a spawn that never happened\n // still owes its removal.\n piMcp.mount?.cleanup()\n throw spawnFailure\n }\n state.proc = proc\n state.note = 'connected'\n\n const events: PiEvent[] = []\n const pendingTools = new Map<string, PendingPiTool>()\n const awaitingPromptResponses = new Set<string>()\n let settled = false\n let acceptedPromptSinceSettlement = false\n let promptSequence = 0\n let lastAssistant: PiAssistantOutcome | undefined\n let failure: Error | undefined\n let abortDeadline: number | undefined\n let exited = false\n let exitCode: number | null | undefined\n let wake: (() => void) | undefined\n const notify = () => {\n const w = wake\n wake = undefined\n w?.()\n }\n\n const stdoutLines = readJsonLines(proc, (value) => {\n const ev = value as PiEvent\n events.push(ev)\n notify()\n })\n\n proc.once('exit', (code) => {\n exited = true\n exitCode = code\n notify()\n })\n proc.once('error', (e) => {\n failure = new ValidationError(`piExecutor: pi failed to start: ${e.message}`)\n notify()\n })\n\n const abortAll = () => {\n if (abortDeadline !== undefined) return\n sendCommand(proc, { type: 'abort' })\n abortDeadline = Date.now() + PI_ABORT_RECEIPT_MS\n state.note = 'aborting'\n notify()\n }\n args.signal.addEventListener('abort', abortAll, { once: true })\n args.controller.signal.addEventListener('abort', abortAll, { once: true })\n\n const system = args.spec.profile.prompt?.systemPrompt\n const opening = system ? `${system}\\n\\n${taskText(args.task)}` : taskText(args.task)\n const deadline = seam.turnTimeoutMs ? Date.now() + seam.turnTimeoutMs : undefined\n const sendPrompt = (message: string, streamingBehavior?: 'steer' | 'followUp'): void => {\n const id = `agent-runtime-prompt-${++promptSequence}`\n awaitingPromptResponses.add(id)\n sendCommand(proc, {\n id,\n type: 'prompt',\n message,\n ...(streamingBehavior ? { streamingBehavior } : {}),\n })\n }\n\n try {\n // Close the check→listener race without ever dispatching a cancelled task.\n if (args.signal.aborted || args.controller.signal.aborted) throw abortError()\n sendPrompt(opening)\n state.note = 'turn 0'\n\n for (;;) {\n // Forward anything the driver delivered — pi's own queue is the single source of truth\n // for ordering, so this is a route, not a second queue.\n if (!settled && abortDeadline === undefined) forwardPending(inbox, activity, sendPrompt)\n\n // Drain what pi has emitted so far, projecting usage + activity.\n while (events.length > 0) {\n const ev = events.shift() as PiEvent\n if (\n ev.type === 'response' &&\n ev.command === 'prompt' &&\n typeof ev.id === 'string' &&\n awaitingPromptResponses.delete(ev.id)\n ) {\n if (ev.success === true) {\n // A settlement that preceded this acceptance belongs to an older prompt. Require a\n // later `agent_settled` before ending the session.\n acceptedPromptSinceSettlement = true\n } else {\n failure = new ValidationError(\n `piExecutor: Pi rejected prompt: ${ev.error ?? 'unknown RPC error'}`,\n )\n }\n }\n if (ev.type === 'agent_start') settled = false\n if (ev.type === 'agent_settled') {\n settled = true\n acceptedPromptSinceSettlement = false\n }\n const projected = projectPiEvent(ev, args, tokens, pendingTools)\n if (projected.assistant) lastAssistant = projected.assistant\n for (const usage of projected.events) {\n if (usage.kind === 'cost') {\n usd += usage.usd\n if (usage.usdKnown === false) usdKnown = false\n }\n yield usage\n }\n }\n\n if (failure) throw failure\n if (abortDeadline !== undefined && (settled || exited)) throw abortError()\n if (\n abortDeadline === undefined &&\n exited &&\n (!settled || awaitingPromptResponses.size > 0 || acceptedPromptSinceSettlement)\n ) {\n throw new ValidationError(\n `piExecutor: pi exited before agent_settled (code ${exitCode ?? 'unknown'})`,\n )\n }\n // Once cancellation starts, Pi's terminal receipt gets its own bounded drain window.\n if (abortDeadline === undefined && deadline !== undefined && Date.now() > deadline) {\n throw new ValidationError('piExecutor: turn exceeded turnTimeoutMs')\n }\n if (abortDeadline !== undefined && Date.now() > abortDeadline) {\n const error = abortError()\n error.message = `piExecutor: abort did not settle within ${PI_ABORT_RECEIPT_MS}ms`\n throw error\n }\n\n if (settled && awaitingPromptResponses.size === 0 && !acceptedPromptSinceSettlement) {\n // A steer delivered in the settle gap starts a new Pi prompt. Pi has declared the prior\n // session activity fully quiet, so no retry/compaction can race this transition.\n const pending = inbox.drain()\n if (pending.length === 0) break\n settled = false\n lastAssistant = undefined\n sendPrompt(inbox.fold(pending))\n state.note = `turn ${state.turns}`\n continue\n }\n\n await new Promise<void>((resolve) => {\n wake = resolve\n // A short fence keeps the loop responsive to a steer that arrives with no pi output.\n const t = setTimeout(() => {\n if (wake === resolve) {\n wake = undefined\n resolve()\n }\n }, 50)\n if (typeof t.unref === 'function') t.unref()\n })\n }\n } finally {\n stdoutLines()\n state.note = 'settled'\n args.signal.removeEventListener('abort', abortAll)\n args.controller.signal.removeEventListener('abort', abortAll)\n await killPi(proc, 2_000).catch(() => ({ destroyed: false }))\n // Every exit path — settle, throw, abort, turn timeout — removes this execution's config\n // directory. Only after pi is reaped, so a still-running pi can never observe it half-removed.\n piMcp.mount?.cleanup()\n }\n\n if (args.signal.aborted || args.controller.signal.aborted) throw abortError()\n if (!lastAssistant) {\n throw new ValidationError('piExecutor: agent_settled without an assistant turn')\n }\n if (lastAssistant.stopReason === 'aborted') throw abortError()\n if (lastAssistant.stopReason === 'error') {\n throw new ValidationError(\n `piExecutor: Pi assistant failed: ${lastAssistant.errorMessage ?? 'unknown provider error'}`,\n )\n }\n state.lastText = lastAssistant.text\n\n const spent: Spend = {\n iterations: state.turns,\n tokens,\n usd,\n ...(usdKnown ? {} : { usdKnown: false }),\n ms: Date.now() - started,\n }\n const out: PiExecutorOutput = {\n content: state.lastText,\n turns: state.turns,\n ...(piMcp.receipt ? { mcp: piMcp.receipt } : {}),\n }\n state.artifact = {\n outRef: `pi:${hash(state.lastText)}`,\n out,\n spent,\n }\n}\n\n/** Route messages through pi's state-safe prompt command; pi owns the queue and idle transition. */\nfunction forwardPending(\n inbox: Inbox,\n activity: ActivityLog,\n sendPrompt: (message: string, streamingBehavior?: 'steer' | 'followUp') => void,\n): void {\n const pending = inbox.drain()\n for (const m of pending) {\n sendPrompt(renderOne(m), m.interrupt ? 'steer' : 'followUp')\n activity.push({\n at: Date.now(),\n kind: 'note',\n label: m.interrupt ? 'steer' : 'follow-up',\n detail: m.text.length > 80 ? `${m.text.slice(0, 77)}...` : m.text,\n })\n }\n}\n\nfunction renderOne(m: InboxMessage): string {\n if (m.kind === 'answer') {\n return `Answer to your question${m.questionId ? ` (${m.questionId})` : ''}: ${m.text}`\n }\n return `New instruction from your supervisor: ${m.text}`\n}\n\n/** Project one pi event onto usage events, updating turn count / activity / trace as a side\n * effect. pi's tool events are the live trace; its `turn_end` bumps the turn counter. */\nfunction projectPiEvent(\n ev: PiEvent,\n args: StreamPiArgs,\n tokens: { input: number; output: number },\n pendingTools: Map<string, PendingPiTool>,\n): { events: UsageEvent[]; assistant?: PiAssistantOutcome } {\n const out: UsageEvent[] = []\n const at = Date.now()\n if (ev.type === 'tool_execution_start' && typeof ev.toolName === 'string') {\n args.activity.push({ at, kind: 'tool', label: ev.toolName, detail: describeArgs(ev.args) })\n if (typeof ev.toolCallId === 'string') {\n pendingTools.set(ev.toolCallId, { args: ev.args ?? {}, startedAt: at })\n }\n return { events: out }\n }\n if (ev.type === 'tool_execution_end' && typeof ev.toolName === 'string') {\n const status = ev.isError === true ? 'error' : 'ok'\n const callId = typeof ev.toolCallId === 'string' ? ev.toolCallId : undefined\n const started = callId ? pendingTools.get(callId) : undefined\n if (callId) pendingTools.delete(callId)\n const error = status === 'error' ? describeToolError(ev.result) : undefined\n args.activity.push({ at, kind: 'tool', label: ev.toolName, status })\n args.record({\n toolName: ev.toolName,\n args: started?.args ?? {},\n ...(started ? {} : { argsCaptured: false }),\n status,\n ...(ev.result !== undefined ? { result: ev.result } : {}),\n ...(error !== undefined ? { error } : {}),\n ...(callId ? { callId } : {}),\n ...(started ? { startedAt: started.startedAt } : {}),\n endedAt: at,\n })\n return { events: out }\n }\n // Pi emits this for user, assistant, and toolResult messages. `turn_end.message` is the\n // authoritative assistant receipt; a generic message can never become the result artifact.\n if (ev.type === 'message_end') return { events: out }\n if (ev.type === 'turn_end') {\n const usage = readUsage(ev.message)\n if (usage && (usage.input || usage.output)) {\n tokens.input += usage.input\n tokens.output += usage.output\n out.push({ kind: 'tokens', input: usage.input, output: usage.output })\n }\n out.push(\n usage?.usd !== undefined\n ? { kind: 'cost', usd: usage.usd }\n : { kind: 'cost', usd: 0, usdKnown: false },\n )\n args.state.turns += 1\n args.activity.push({ at, kind: 'turn', label: `turn ${args.state.turns}` })\n out.push({ kind: 'iteration' })\n const assistant = readAssistantOutcome(ev.message)\n return { events: out, ...(assistant ? { assistant } : {}) }\n }\n return { events: out }\n}\n\n/** Pi's fresh input excludes cache reads and writes. Runtime's input channel includes all model\n * input, so combine them once at the assistant receipt. A missing or zero price is unknown because\n * subscription-backed providers report zero even when compute was not free. */\nfunction readUsage(message: unknown): { input: number; output: number; usd?: number } | undefined {\n if (!message || typeof message !== 'object') return undefined\n const usage = (message as { usage?: unknown }).usage\n if (!usage || typeof usage !== 'object') return undefined\n const u = usage as Record<string, unknown>\n const promptTokens = num(u.prompt_tokens)\n const input =\n promptTokens ??\n (num(u.input) ?? num(u.inputTokens) ?? 0) +\n (num(u.cacheRead) ?? num(u.cache_read_input_tokens) ?? num(u.cacheReadInputTokens) ?? 0) +\n (num(u.cacheWrite) ??\n num(u.cache_creation_input_tokens) ??\n num(u.cacheCreationInputTokens) ??\n 0)\n const output = num(u.output) ?? num(u.outputTokens) ?? num(u.completion_tokens) ?? 0\n const costRaw = u.cost\n const reportedUsd =\n num(costRaw) ??\n (costRaw && typeof costRaw === 'object'\n ? (num((costRaw as Record<string, unknown>).total) ??\n num((costRaw as Record<string, unknown>).totalCost))\n : undefined)\n return {\n input,\n output,\n ...(reportedUsd !== undefined && reportedUsd > 0 ? { usd: reportedUsd } : {}),\n }\n}\n\nfunction readAssistantOutcome(message: unknown): PiAssistantOutcome | undefined {\n if (!message || typeof message !== 'object') return undefined\n const value = message as Record<string, unknown>\n if (value.role !== 'assistant') return undefined\n return {\n text: readText(message) ?? '',\n ...(typeof value.stopReason === 'string' ? { stopReason: value.stopReason } : {}),\n ...(typeof value.errorMessage === 'string' ? { errorMessage: value.errorMessage } : {}),\n }\n}\n\nfunction readText(message: unknown): string | undefined {\n if (!message || typeof message !== 'object') return undefined\n const content = (message as { content?: unknown }).content\n if (typeof content === 'string' && content.length > 0) return content\n if (!Array.isArray(content)) return undefined\n const text = content\n .map((block) =>\n block && typeof block === 'object' && typeof (block as { text?: unknown }).text === 'string'\n ? ((block as { text: string }).text ?? '')\n : '',\n )\n .join('')\n return text.length > 0 ? text : undefined\n}\n\nfunction num(v: unknown): number | undefined {\n return typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined\n}\n\nfunction describeArgs(argsValue: unknown): string | undefined {\n if (!argsValue || typeof argsValue !== 'object') return undefined\n const a = argsValue as Record<string, unknown>\n for (const key of ['filePath', 'file_path', 'path', 'file', 'command', 'cmd', 'pattern']) {\n const v = a[key]\n if (typeof v === 'string' && v.length > 0) return v.length > 120 ? `${v.slice(0, 117)}...` : v\n }\n return undefined\n}\n\nfunction describeToolError(result: unknown): string | undefined {\n if (typeof result === 'string' && result.length > 0) return result\n if (result && typeof result === 'object') {\n const value = result as Record<string, unknown>\n const direct = value.error ?? value.message\n if (typeof direct === 'string' && direct.length > 0) return direct\n if (Array.isArray(value.content)) {\n const text = value.content\n .map((block) =>\n block &&\n typeof block === 'object' &&\n typeof (block as { text?: unknown }).text === 'string'\n ? (block as { text: string }).text\n : '',\n )\n .filter(Boolean)\n .join('\\n')\n if (text.length > 0) return text\n }\n }\n return undefined\n}\n\nfunction taskText(task: unknown): string {\n if (typeof task === 'string') return task\n try {\n return JSON.stringify(task) ?? String(task)\n } catch {\n return String(task)\n }\n}\n\n/**\n * Launch `pi --mode rpc`, plus provider/model flags derived from the seam's `provider/model` and\n * the profile-derived extension flags (`--no-extensions` / `--extension`). Seam args go LAST so an\n * operator's explicit flag wins over a derived one under pi's last-flag-wins parsing; RPC mode has\n * no positional prompt, so nothing here has to precede an argument.\n *\n * `traceEnv` is the inherited `TRACE_ID` / `PARENT_SPAN_ID` pair (empty when the run records no\n * spans). It sits ABOVE the supervisor's ambient `process.env` — a supervisor that was itself\n * launched as someone's worker holds ids describing ITS place in an outer trace, which are the\n * wrong parent for this child — and BELOW `seam.env`, so an operator who sets either id explicitly\n * still wins. See `worker-trace.ts` for the full precedence rule.\n */\nfunction spawnPi(\n seam: PiSeam,\n profileArgs: ReadonlyArray<string> = [],\n traceEnv: Record<string, string> = {},\n): ChildProcess {\n const bin = seam.bin ?? 'pi'\n const argv = ['--mode', 'rpc']\n if (seam.model) {\n const slash = seam.model.indexOf('/')\n if (slash > 0) {\n argv.push('--provider', seam.model.slice(0, slash), '--model', seam.model.slice(slash + 1))\n } else {\n argv.push('--model', seam.model)\n }\n }\n argv.push(...profileArgs)\n if (seam.args) argv.push(...seam.args)\n return spawn(bin, argv, {\n ...(seam.cwd ? { cwd: seam.cwd } : {}),\n env: { ...process.env, ...traceEnv, ...(seam.env ?? {}) },\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n}\n\n/** Write one `RpcCommand` as a JSON line on pi's stdin. Best-effort: a dead process is not an\n * error here (the stream loop already observes the exit and fails loud there). */\nfunction sendCommand(proc: ChildProcess, command: Record<string, unknown>): void {\n try {\n proc.stdin?.write(`${JSON.stringify(command)}\\n`)\n } catch {\n // The exit/error handlers own the failure path.\n }\n}\n\n/** Read newline-delimited JSON off pi's stdout; returns an unsubscribe. Malformed lines are\n * ignored (pi writes only JSONL on stdout; anything else is noise from a wrapper script). */\nfunction readJsonLines(proc: ChildProcess, onValue: (value: unknown) => void): () => void {\n let buffer = ''\n const onData = (chunk: Buffer | string) => {\n buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8')\n for (;;) {\n const nl = buffer.indexOf('\\n')\n if (nl < 0) break\n const line = buffer.slice(0, nl).trim()\n buffer = buffer.slice(nl + 1)\n if (!line) continue\n try {\n onValue(JSON.parse(line))\n } catch {\n // not JSON — ignore\n }\n }\n }\n proc.stdout?.on('data', onData)\n return () => {\n proc.stdout?.off('data', onData)\n }\n}\n\n/** The grace window pi gets to act on the `abort` it was just sent, before a signal is used.\n * Without it the SIGTERM races the command down the pipe and pi never sees the abort at all —\n * which defeats the reason to wrap pi rather than kill it (a clean abort finalizes its session). */\nconst PI_ABORT_GRACE_MS = 500\n/** Maximum wait for Pi's aborted receipt and `agent_settled` before forced teardown. */\nconst PI_ABORT_RECEIPT_MS = 2_000\n\nasync function killPi(\n proc: ChildProcess,\n grace: number | 'brutalKill' | 'infinity',\n): Promise<{ destroyed: boolean }> {\n if (proc.exitCode !== null || proc.killed) return { destroyed: true }\n if (grace === 'brutalKill') {\n endStdin(proc)\n proc.kill('SIGKILL')\n return { destroyed: true }\n }\n const total = grace === 'infinity' ? 10_000 : Math.max(0, grace)\n // Phase 1: let the already-sent `abort` land and pi exit on its own terms.\n if (await waitForExit(proc, Math.min(PI_ABORT_GRACE_MS, total))) return { destroyed: true }\n // Phase 2: close its input and ask the OS politely.\n endStdin(proc)\n proc.kill('SIGTERM')\n if (await waitForExit(proc, Math.max(0, total - PI_ABORT_GRACE_MS))) return { destroyed: true }\n proc.kill('SIGKILL')\n return { destroyed: true }\n}\n\nfunction endStdin(proc: ChildProcess): void {\n try {\n proc.stdin?.end()\n } catch {\n // already closed\n }\n}\n\nfunction waitForExit(proc: ChildProcess, ms: number): Promise<boolean> {\n if (proc.exitCode !== null) return Promise.resolve(true)\n return new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), ms)\n if (typeof timer.unref === 'function') timer.unref()\n proc.once('exit', () => {\n clearTimeout(timer)\n resolve(true)\n })\n })\n}\n\nfunction readPiSeam(ctx: ExecutorContext): PiSeam {\n const seam = ctx.seams[piSeamKey]\n if (seam === undefined) return {}\n if (!seam || typeof seam !== 'object') {\n throw new ValidationError(`piExecutor: seams['${piSeamKey}'] must be a PiSeam object`)\n }\n return seam as PiSeam\n}\n\n/** FNV-1a over the terminal text — the same non-cryptographic content address the other leaf\n * executors mint for their `outRef` dedup hint (the journal re-derives the canonical one). */\nfunction hash(value: string): string {\n let h = 0x811c9dc5\n for (let i = 0; i < value.length; i += 1) {\n h ^= value.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\n}\n","/**\n *\n * The STEERABLE sandbox worker: one box, one server-side session, MANY turns — so a message\n * from the driver has a boundary to be folded into.\n *\n * The default cloud worker was built on `singleShotDriver`: one `runAgentRounds` shot, no turn\n * boundary, and no `Executor.deliver`. `Scope.send` therefore returned `false` for it and\n * `steer_agent` reported `delivered:false` on every call — steering the DEFAULT worker was\n * mechanically impossible, not merely unused. This module is the missing continuation loop.\n *\n * Structure deliberately mirrors `streamBridgeSession` (the cli-bridge equivalent that already\n * works) so both steerable runtimes have ONE shape:\n *\n * - turn 0 sends the task through `SandboxLineage.start` (fresh box, minted session id);\n * - each later turn fires ONLY when the inbox has a steer/answer to fold, and goes through\n * `SandboxLineage.continue` — the SAME box and the SAME server-side session, so the prompt\n * carries only the new instruction and the worker keeps everything it had already learned;\n * - a worker may not settle while a delivered steer is unread: the loop drains once more\n * before breaking, which is what makes `steer_agent` a promise rather than a hint;\n * - a forceful (`interrupt:true`) steer aborts the in-flight turn so the worker re-plans\n * immediately instead of finishing a path the supervisor already rejected.\n *\n * It also produces the LIVE signal a supervisor steers FROM: every sandbox event stamps\n * activity, tool parts are decoded into the shared `ToolSpan` currency for the online detector\n * panel, and `progress()` answers turn / tool / idle / pending-steer questions synchronously.\n *\n * Reports REAL usage only — token and cost numbers come from the sandbox events themselves.\n *\n * @experimental\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { BackendType, PromptOptions, SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../../errors'\nimport { probeSandboxCapabilities } from '../sandbox-capabilities'\nimport { extractLlmCallEvent } from '../sandbox-events'\nimport { createSandboxLineage, type SandboxLineageHandle } from '../sandbox-lineage'\nimport type { AgentRunSpec, ExecCtx, SandboxClient } from '../types'\nimport { zeroTokenUsage } from '../util'\nimport type { Inbox } from './inbox'\nimport {\n type ActivityLog,\n type ActivityNote,\n createActivityLog,\n type ExecutorProgress,\n} from './progress'\nimport { createPushTraceSource, decodeToolPart, type TraceSource } from './trace-source'\nimport type { Spend, UsageEvent } from './types'\n\n/** Ceiling on continuation turns. Turn 0 is the task; every later turn is a folded steer, so\n * this bounds how many times a supervisor may redirect ONE worker before it must respawn. */\nexport const DEFAULT_SANDBOX_STEERING_MAX_TURNS = 24\n\n/** Opt-in configuration for the steerable sandbox worker (`SandboxSeam.steering`). Absent, the\n * sandbox executor keeps its historical single-shot `runAgentRounds` composition verbatim. */\nexport interface SandboxSteeringOptions {\n /** Max turns for one worker (turn 0 + folded steers). Default {@link DEFAULT_SANDBOX_STEERING_MAX_TURNS}. */\n readonly maxTurns?: number\n /** How many recent tool/turn notes `progress()` reports. Default 12. */\n readonly activityWindow?: number\n /** Per-turn wall-clock ceiling; the turn's stream is aborted when it elapses. */\n readonly turnTimeoutMs?: number\n}\n\n/** What the steerable session exposes to its executor: the usage stream plus the live reads. */\nexport interface SteerableSandboxSession {\n /** Drive the worker to settlement. `signal` is the spawn-scoped abort handed to `execute`. */\n stream(task: unknown, signal: AbortSignal): AsyncIterable<UsageEvent>\n progress(): ExecutorProgress\n traceSource(): TraceSource\n artifact(): { outRef: string; out: unknown; spent: Spend } | undefined\n teardown(): Promise<void>\n}\n\nexport interface SteerableSandboxArgs {\n readonly controller: AbortController\n readonly profile: AgentProfile\n readonly harness: BackendType\n readonly sandboxClient: SandboxClient\n readonly inbox: Inbox\n readonly taskToPrompt: (task: unknown) => string\n readonly options?: SandboxSteeringOptions\n readonly loopCtx?: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>>\n /**\n * Inherited `TRACE_ID` / `PARENT_SPAN_ID` for the box, merged into `CreateSandboxOptions.env` so\n * the remote worker's own spans join the supervisor's trace under the spawning node's span.\n * Absent when the run records no spans — the create options are then untouched.\n */\n readonly traceEnv?: Record<string, string>\n readonly contentRef: (prefix: string, value: unknown) => string\n readonly now?: () => number\n}\n\n/** One steerable sandbox worker. The returned session is inert until `stream()` is drained. */\nexport function createSteerableSandboxSession(args: SteerableSandboxArgs): SteerableSandboxSession {\n const now = args.now ?? Date.now\n const maxTurns = Math.max(\n 1,\n Math.floor(args.options?.maxTurns ?? DEFAULT_SANDBOX_STEERING_MAX_TURNS),\n )\n const activity: ActivityLog = createActivityLog(args.options?.activityWindow ?? 12)\n const trace = createPushTraceSource({ runId: `sandbox-${args.harness}-${now()}`, now })\n\n const state = {\n turns: 0,\n lastText: '',\n seenToolCalls: new Set<string>(),\n artifact: undefined as { outRef: string; out: unknown; spent: Spend } | undefined,\n teardown: undefined as (() => Promise<void>) | undefined,\n note: 'starting',\n }\n\n const recordEvent = (event: SandboxEvent): void => {\n const at = now()\n const data = (event as { data?: unknown }).data\n const part = data && typeof data === 'object' ? (data as { part?: unknown }).part : undefined\n if (part !== undefined) {\n const step = decodeToolPart(part, args.harness)\n if (step) {\n // The same call streams several frames; count it once so the detector panel and the\n // driver's activity window both see ONE entry per real tool call.\n const key = step.callId ?? `${step.toolName}:${activity.size()}`\n if (!state.seenToolCalls.has(key)) {\n state.seenToolCalls.add(key)\n trace.record(step)\n const note: ActivityNote = {\n at,\n kind: 'tool',\n label: step.toolName,\n ...(step.status ? { status: step.status } : {}),\n ...(describeArgs(step.args) ? { detail: describeArgs(step.args) } : {}),\n }\n activity.push(note)\n }\n }\n }\n const text = readFinalText(event)\n if (text) state.lastText = text\n }\n\n async function* stream(task: unknown, signal: AbortSignal): AsyncIterable<UsageEvent> {\n const capabilities = await probeSandboxCapabilities(args.sandboxClient)\n const lineage = createSandboxLineage(args.sandboxClient, capabilities, { maxConcurrency: 1 })\n state.teardown = () => lineage.teardown()\n\n const spec: AgentRunSpec<unknown> = {\n profile: args.profile,\n taskToPrompt: args.taskToPrompt,\n name: args.profile.name ?? String(args.harness),\n sandboxOverrides: {\n backend: { type: args.harness },\n ...(args.traceEnv && Object.keys(args.traceEnv).length > 0 ? { env: args.traceEnv } : {}),\n },\n }\n const promptOptions = readPromptOptions(args.loopCtx)\n\n const started = now()\n const tokens = zeroTokenUsage()\n let usd = 0\n let handle: SandboxLineageHandle | undefined\n let nextPrompt: string | undefined = args.taskToPrompt(task)\n\n try {\n for (let turn = 0; turn < maxTurns; turn += 1) {\n // Drain the down-leg FIRST. On turn 0 a steer that landed during box acquisition is\n // appended to the task; on later turns the steer IS the whole prompt, because the\n // worker's prior context lives server-side in the session.\n const pending = args.inbox.drain()\n if (pending.length > 0) {\n const folded = args.inbox.fold(pending)\n nextPrompt = turn === 0 && nextPrompt ? `${nextPrompt}\\n\\n${folded}` : folded\n activity.push({\n at: now(),\n kind: 'note',\n label: 'steer-folded',\n detail: `${pending.length} message(s)`,\n })\n }\n if (nextPrompt === undefined) break\n\n const prompt = nextPrompt\n nextPrompt = undefined\n state.note = `turn ${turn}`\n\n const interruptSig = args.inbox.freshInterrupt()\n const turnController = new AbortController()\n const abortTurn = () => turnController.abort()\n if (signal.aborted || args.controller.signal.aborted) turnController.abort()\n else {\n signal.addEventListener('abort', abortTurn)\n args.controller.signal.addEventListener('abort', abortTurn)\n }\n interruptSig.addEventListener('abort', abortTurn, { once: true })\n const timer = args.options?.turnTimeoutMs\n ? setTimeout(abortTurn, args.options.turnTimeoutMs)\n : undefined\n const cleanup = () => {\n signal.removeEventListener('abort', abortTurn)\n args.controller.signal.removeEventListener('abort', abortTurn)\n if (timer) clearTimeout(timer)\n }\n\n let events: AsyncIterable<SandboxEvent>\n try {\n if (!handle) {\n const opened = await lineage.start(spec, prompt, turnController.signal, promptOptions)\n handle = opened.handle\n events = opened.events\n } else {\n events = await lineage.continue(handle, prompt, turnController.signal, promptOptions)\n }\n for await (const event of events) {\n recordEvent(event)\n const call = extractLlmCallEvent(event, spec.name ?? String(args.harness))\n if (!call) continue\n const input = call.tokensIn ?? 0\n const output = call.tokensOut ?? 0\n if (input || output) {\n tokens.input += input\n tokens.output += output\n yield { kind: 'tokens', input, output }\n }\n if (typeof call.costUsd === 'number' && call.costUsd > 0) {\n usd += call.costUsd\n yield { kind: 'cost', usd: call.costUsd }\n }\n }\n } catch (e) {\n cleanup()\n // Re-plan ONLY when a forceful steer (not external teardown) aborted the turn: the\n // steer is already queued, so loop back and fold it. Anything else is fatal.\n if (isInterruptAbort(e, interruptSig, signal, args.controller.signal)) {\n activity.push({ at: now(), kind: 'note', label: 'interrupted', detail: 'replanning' })\n continue\n }\n throw e\n }\n cleanup()\n\n state.turns += 1\n activity.push({ at: now(), kind: 'turn', label: `turn ${turn}` })\n yield { kind: 'iteration' }\n\n // A worker may NOT settle while a delivered steer is unread — that is the whole\n // contract `steer_agent` reports back to the driver. Loop instead of breaking.\n if (args.inbox.pending() === 0) break\n }\n } finally {\n state.note = 'settled'\n await lineage.teardown().catch(() => {})\n state.teardown = undefined\n }\n\n const spent: Spend = { iterations: state.turns, tokens, usd, ms: now() - started }\n const out = {\n content: state.lastText,\n turns: state.turns,\n toolCalls: activity\n .read()\n .filter((n) => n.kind === 'tool')\n .map((n) => n.label),\n }\n state.artifact = {\n outRef: args.contentRef('sandbox-steerable', { harness: args.harness, out }),\n out,\n spent,\n }\n }\n\n return {\n stream,\n progress: (): ExecutorProgress => ({\n turns: state.turns,\n pendingMessages: args.inbox.pending(),\n recentActivity: activity.read(),\n note: state.note,\n }),\n traceSource: () => trace.source,\n artifact: () => state.artifact,\n async teardown() {\n await state.teardown?.().catch(() => {})\n },\n }\n}\n\n/** A forceful steer aborted this turn (and NOT an external teardown), so the loop re-plans. */\nfunction isInterruptAbort(\n err: unknown,\n interrupt: AbortSignal,\n external: AbortSignal,\n owned: AbortSignal,\n): boolean {\n const aborted =\n (err instanceof DOMException && err.name === 'AbortError') ||\n (typeof err === 'object' && err !== null && (err as { name?: unknown }).name === 'AbortError')\n return aborted && interrupt.aborted && !external.aborted && !owned.aborted\n}\n\n/** The terminal text a sandbox `result` event carries, when it carries one. */\nfunction readFinalText(event: SandboxEvent): string | undefined {\n const data = (event as { data?: unknown }).data\n if (!data || typeof data !== 'object') return undefined\n const text = (data as { finalText?: unknown; text?: unknown }).finalText\n if (typeof text === 'string' && text.length > 0) return text\n const alt = (data as { text?: unknown }).text\n return typeof alt === 'string' && alt.length > 0 ? alt : undefined\n}\n\n/** A short, already-truncated descriptor of a tool call's target — the file/command a driver\n * needs to tell \"editing the right module\" from \"re-reading the same file for the fifth time\",\n * without pulling the worker's transcript across the wire. */\nfunction describeArgs(argsValue: unknown): string | undefined {\n if (!argsValue || typeof argsValue !== 'object') return undefined\n const a = argsValue as Record<string, unknown>\n for (const key of ['filePath', 'file_path', 'path', 'file', 'command', 'cmd', 'pattern']) {\n const v = a[key]\n if (typeof v === 'string' && v.length > 0) return v.length > 120 ? `${v.slice(0, 117)}...` : v\n }\n return undefined\n}\n\n/** Prompt options the composed loop context already carries (agent profile / cwd), forwarded so\n * a steerable worker runs with the same box configuration as the single-shot path. */\nfunction readPromptOptions(\n loopCtx: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>> | undefined,\n): Omit<PromptOptions, 'signal' | 'sessionId'> | undefined {\n const opts = (loopCtx as { promptOptions?: unknown } | undefined)?.promptOptions\n if (!opts || typeof opts !== 'object') return undefined\n return opts as Omit<PromptOptions, 'signal' | 'sessionId'>\n}\n\n/** Fail loud on a steering config that cannot work, before any box is created. */\nexport function assertSteerable(client: SandboxClient | undefined): void {\n if (!client || typeof client.create !== 'function') {\n throw new ValidationError('steerable sandbox worker: SandboxSeam.sandboxClient.create required')\n }\n}\n","/**\n *\n * The worktree-CLI leaf executor — a supervisor-authored `AgentProfile` driving a local\n * coding-harness CLI (claude / codex / opencode) on its OWN git worktree, surfaced as the open\n * `Executor<Out>` port (`./types`). It is a LEAF executor: it plugs straight into the\n * `Scope`/`Supervisor` recursion and `gateOnDeliverable`, so it IS the canonical recursive path\n * (no `runAgentRounds`/virtual-SandboxInstance shim in between).\n *\n * This is a THIN adapter: the physical act (worktree → profile-aware harness invocation → diff →\n * checks → cleanup) lives ONCE in `runWorktreeHarness` (`../../mcp/worktree-harness`), shared with\n * the `runAgentRounds`/coder-delegate `createInProcessExecutor`. This executor only projects that core's\n * result onto the `Executor` port (artifact + spend) and owns the teardown point. The complete\n * profile delivery — direct prompt/model plus materialized file-backed resources — lives there.\n *\n * Token accounting: ordinary harness CLI runs remain `budgetExempt`. Reproducible Codex mode\n * parses the CLI's terminal JSONL usage and is metered by default; an absent usage event fails the\n * run instead of recording fabricated zero tokens. Codex does not report dollar cost, so that\n * channel is explicitly marked unknown on the resulting `Spend`.\n *\n * @experimental\n */\n\nimport { randomUUID } from 'node:crypto'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { contentAddress } from '../../durable/spawn-journal'\nimport { ValidationError } from '../../errors'\nimport type { LocalHarness, runLocalHarness } from '../../mcp/local-harness'\nimport type { GitRunner } from '../../mcp/worktree'\nimport {\n runWorktreeHarness,\n type WorktreeCheckRunner,\n type WorktreeCommandResult,\n type WorktreeHarnessResult,\n type WorktreeHarnessRun,\n type WorktreeProfileMaterializationReceipt,\n} from '../../mcp/worktree-harness'\nimport type { Executor, ExecutorResult, Spend } from './types'\n\nexport type { WorktreeCommandResult, WorktreeProfileMaterializationReceipt }\n/** Terminal artifact of one worktree-CLI run — the canonical worktree-harness result (the captured\n * diff + the harness's run record + the derived checks). */\nexport type WorktreePatchArtifact = WorktreeHarnessResult\n\n/** @experimental */\nexport interface WorktreeCliExecutorOptions {\n /** Absolute path to the git checkout the worktree is cut from. */\n repoRoot: string\n /**\n * The supervisor-authored prompt/model plus materializable structural resources.\n * `model.default` selects the one-shot model; `small`, `provider`, and `metadata` remain hints.\n * Resource failures are fatal regardless of `resources.failOnError`.\n * Tools, permissions, connections, confidential execution, modes, and extensions fail closed.\n * Harness-specific nested controls that the pinned materializer cannot preserve also fail closed.\n */\n profile: AgentProfile\n /** Local CLI for this leaf. This explicit choice overrides `profile.harness`. */\n harness: LocalHarness\n /** The per-task instruction handed to the harness (composed under the system prompt). */\n taskPrompt: string\n /** Unique id for the worktree path + branch. Defaults to a fresh UUID. */\n runId?: string\n /** Override the base ref the worktree is cut from (default `HEAD`). */\n baseRef?: string\n /** Wall-clock cap per harness subprocess (ms). Default 5 min (the `runLocalHarness` default). */\n harnessTimeoutMs?: number\n /** Run Codex with an ephemeral session, isolated config/instructions, network disabled, and\n * JSONL usage capture. Requires `harness: 'codex'`; metered by default. */\n codexReproducible?: boolean\n /** Absolute host paths denied to reproducible Codex (for benchmark answer copies, credentials,\n * or other task-specific ambient state). */\n codexReadDeniedPaths?: ReadonlyArray<string>\n /**\n * Shell command run in the live worktree to derive the tests-PASS signal (e.g. `pnpm test`).\n * Its exit code becomes `artifact.checks.tests.passed`. Omit to skip (no signal derived).\n */\n testCmd?: string\n /** Shell command run in the live worktree to derive the typecheck-PASS signal (e.g. `pnpm typecheck`). */\n typecheckCmd?: string\n /** Wall-clock cap per verification command (ms). Default = `harnessTimeoutMs` or 5 min. */\n checkTimeoutMs?: number\n /** Cap on each check's captured output. Default 16k. */\n checkOutputCap?: number\n /** Test seam — inject a git runner so unit tests drive the worktree helpers without git. */\n runGit?: GitRunner\n /** Test seam — inject the harness runner so unit tests script a `LocalHarnessResult`. */\n runHarness?: typeof runLocalHarness\n /** Test seam — inject the verification-command runner so unit tests script test/typecheck\n * outcomes without spawning a real shell. Defaults to a `/bin/sh -c` spawn in the worktree. */\n runCommand?: WorktreeCheckRunner\n /**\n * Exclude this leaf's spend from accounting. Defaults to `true` for ordinary CLI runs and\n * `false` for `codexReproducible`, which captures real token usage. A metered custom runner must\n * likewise return `LocalHarnessResult.usage`.\n */\n budgetExempt?: boolean\n}\n\n/**\n * Build a worktree-CLI leaf `Executor`. Per-spawn (a fresh worktree + abort + teardown each), so a\n * fanout of N profiles = N parallel worktrees that never clobber each other.\n *\n * Fail-loud: an empty `repoRoot`/`harness`/`taskPrompt` throws at construction. `resultArtifact()`\n * before `execute()` resolves throws.\n *\n * @experimental\n */\nexport function createWorktreeCliExecutor(\n options: WorktreeCliExecutorOptions,\n): Executor<WorktreePatchArtifact> {\n if (!options.repoRoot) {\n throw new ValidationError('createWorktreeCliExecutor: repoRoot required')\n }\n if (!options.harness) {\n throw new ValidationError('createWorktreeCliExecutor: harness required')\n }\n if (typeof options.taskPrompt !== 'string' || options.taskPrompt.length === 0) {\n throw new ValidationError('createWorktreeCliExecutor: taskPrompt required')\n }\n if (options.codexReproducible && options.harness !== 'codex') {\n throw new ValidationError(\n 'createWorktreeCliExecutor: codexReproducible requires harness \"codex\"',\n )\n }\n if (options.codexReproducible && options.budgetExempt === true) {\n throw new ValidationError('createWorktreeCliExecutor: codexReproducible cannot be budgetExempt')\n }\n if (options.codexReadDeniedPaths !== undefined && !options.codexReproducible) {\n throw new ValidationError(\n 'createWorktreeCliExecutor: codexReadDeniedPaths requires codexReproducible',\n )\n }\n\n const runId = options.runId ?? randomUUID()\n const controller = new AbortController()\n const budgetExempt = options.budgetExempt ?? !options.codexReproducible\n\n let run: WorktreeHarnessRun | undefined\n let artifact: ExecutorResult<WorktreePatchArtifact> | undefined\n\n return {\n runtime: 'cli',\n budgetExempt,\n async execute(_task, signal): Promise<ExecutorResult<WorktreePatchArtifact>> {\n const linked = linkSignals(signal, controller.signal)\n const started = Date.now()\n\n run = await runWorktreeHarness({\n repoRoot: options.repoRoot,\n profile: options.profile,\n harness: options.harness,\n taskPrompt: options.taskPrompt,\n runId,\n ...(options.baseRef ? { baseRef: options.baseRef } : {}),\n ...(options.testCmd !== undefined ? { testCmd: options.testCmd } : {}),\n ...(options.typecheckCmd !== undefined ? { typecheckCmd: options.typecheckCmd } : {}),\n ...(options.harnessTimeoutMs !== undefined\n ? { harnessTimeoutMs: options.harnessTimeoutMs }\n : {}),\n ...(options.codexReproducible ? { codexReproducible: true } : {}),\n ...(options.codexReadDeniedPaths\n ? { codexReadDeniedPaths: options.codexReadDeniedPaths }\n : {}),\n ...(options.checkTimeoutMs !== undefined ? { checkTimeoutMs: options.checkTimeoutMs } : {}),\n ...(options.checkOutputCap !== undefined ? { checkOutputCap: options.checkOutputCap } : {}),\n ...(linked ? { signal: linked } : {}),\n ...(options.runGit ? { runGit: options.runGit } : {}),\n ...(options.runHarness ? { runHarness: options.runHarness } : {}),\n ...(options.runCommand ? { runCommand: options.runCommand } : {}),\n })\n\n const usage = run.result.harness.usage\n if (!budgetExempt && !usage) {\n const completed = run\n run = undefined\n await completed.cleanup()\n throw new ValidationError(\n 'createWorktreeCliExecutor: metered harness run returned no token usage',\n )\n }\n const spent: Spend = {\n iterations: 1,\n tokens: usage\n ? { input: usage.inputTokens, output: usage.outputTokens }\n : { input: 0, output: 0 },\n usd: 0,\n ...(usage ? { usdKnown: false } : {}),\n ms: Date.now() - started,\n }\n artifact = { outRef: contentAddress(run.result), out: run.result, spent }\n return artifact\n },\n async teardown(_grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n // The loser of a fanout (or any settled run) is dirty — remove its worktree. A run that\n // THREW already cleaned itself up in the core, so `run` stays undefined and this is a no-op.\n if (run) {\n const r = run\n run = undefined\n await r.cleanup()\n }\n return { destroyed: true }\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError(\n 'createWorktreeCliExecutor: resultArtifact() read before execute() resolved',\n )\n }\n return artifact\n },\n }\n}\n\n/** Link two abort signals into one that fires when either does. Returns `undefined` when neither\n * is present so the harness runner gets no signal at all. */\nfunction linkSignals(a: AbortSignal, b: AbortSignal): AbortSignal | undefined {\n if (a.aborted || b.aborted) {\n const c = new AbortController()\n c.abort()\n return c.signal\n }\n const c = new AbortController()\n const onAbort = () => c.abort()\n a.addEventListener('abort', onAbort, { once: true })\n b.addEventListener('abort', onAbort, { once: true })\n return c.signal\n}\n","/**\n *\n * The leaf runtime — the built-in `Executor` IMPLEMENTATIONS behind the ONE\n * open interface frozen in `./types`, plus the open resolver/registry that maps\n * an `AgentSpec` to one of them OR accepts a bring-your-own executor verbatim.\n *\n * The interface is the extension point, not a closed `inline|sandbox|cli` union:\n * - router/inline : a direct OpenAI-compatible Router call, no box (one-shot).\n * - sandbox : COMPOSES the existing `runAgentRounds` kernel as a single-task\n * leaf and surfaces its token/cost usage as `UsageEvent`s;\n * forwards PR #150's optional `lineage` passthrough WITHOUT\n * reinventing checkpoint/fork (streaming).\n * - cli : a Halo/RLM subprocess; `budgetExempt` (no token accounting),\n * excluded from the equal-k arms by construction (streaming).\n * Every metered runtime reports through the SAME normalized `UsageEvent` channel\n * so the conserved budget pool meters them identically. A user's own agent is\n * first-class the moment it implements `Executor` — register it by name or\n * pass it as `AgentSpec.executor`.\n *\n * Layering: `estimateCost`/`isModelPriced` are substrate primitives from\n * `@tangle-network/agent-eval`; `runAgentRounds`/`acquireSandbox` are runtime kernels\n * from this package. No per-vendor adapters live here.\n *\n * @experimental\n */\n\nimport { spawn } from 'node:child_process'\nimport { randomUUID } from 'node:crypto'\nimport { request as httpRequest } from 'node:http'\nimport { request as httpsRequest } from 'node:https'\nimport { Readable } from 'node:stream'\nimport { estimateCost, isModelPriced } from '@tangle-network/agent-eval'\nimport type { BackendType, SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../../errors'\nimport type { LocalHarness } from '../../mcp/local-harness'\nimport {\n captureWorktreeDiff,\n createWorktree,\n type GitRunner,\n removeWorktree,\n type WorktreeHandle,\n} from '../../mcp/worktree'\nimport {\n runWorktreeChecks,\n type WorktreeCheckRunner,\n type WorktreeHarnessResult,\n} from '../../mcp/worktree-harness'\nimport {\n type AgentEnvironmentProvider,\n type AgentEnvironmentProviderRegistry,\n type ProviderExecutorOptions,\n providerAsExecutor,\n resolveAgentEnvironmentProvider,\n} from '../environment-provider'\nimport { routerChatWithUsage, type ToolSpec } from '../router-client'\nimport type { RunAgentRoundsOptions } from '../run-loop'\nimport { runAgentRounds } from '../run-loop'\nimport type {\n AgentRunSpec,\n Driver,\n ExecCtx,\n Iteration,\n OutputAdapter,\n SandboxClient,\n} from '../types'\nimport { zeroTokenUsage } from '../util'\nimport { createInbox, type Inbox } from './inbox'\nimport { PI_RUNTIME, type PiSeam, piExecutor } from './pi-executor'\nimport type { ExecutorProgress } from './progress'\nimport { createSteerableSandboxSession, type SandboxSteeringOptions } from './sandbox-session'\nimport type { TraceSource } from './trace-source'\nimport type {\n AgentSpec,\n DefaultVerdict,\n Executor,\n ExecutorContext,\n ExecutorFactory,\n ExecutorRegistry,\n ExecutorResult,\n Runtime,\n Spend,\n UsageEvent,\n} from './types'\nimport { workerTraceEnv } from './worker-trace'\nimport { createWorktreeCliExecutor } from './worktree-cli-executor'\n\n// ── Seam contracts (read off ExecutorContext.seams, narrowed per built-in) ─────\n\n/**\n * Router/inline connection seam. A direct OpenAI-compatible Router endpoint —\n * the cheapest leaf, no box, no tools. `model` overrides the profile's model\n * hint when present; otherwise the profile's `model.default` is required.\n */\nexport interface RouterSeam {\n routerBaseUrl: string\n routerKey: string\n model?: string\n}\n\n/**\n * Sandbox executor seam. The `sandboxClient` the composed `runAgentRounds` creates\n * boxes through, plus the optional trace/run/lineage wiring forwarded into the\n * loop. `lineage` is opaque here (PR #150's `RunAgentRoundsOptions.lineage`): forwarded\n * forward-compatibly, never inspected — this executor does NOT reinvent\n * checkpoint/fork.\n */\nexport interface SandboxSeam {\n sandboxClient: SandboxClient\n /** Forwarded into the composed `runAgentRounds`'s `ctx` (trace emitter, run handle, etc.). */\n loopCtx?: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>>\n /** PR #150 `RunAgentRoundsOptions.lineage` passthrough — opaque; forwarded, not parsed. */\n lineage?: unknown\n /** Hard cap on the composed loop's iterations. The budget pool reserves against\n * the spawn `Budget.maxIterations`; this is the leaf's own ceiling. Default 1. */\n maxIterations?: number\n /**\n * OPT-IN: run this worker as a multi-turn, STEERABLE session instead of the historical\n * single-shot `runAgentRounds` composition. Setting it gives the sandbox worker an `Executor.deliver`\n * inbox (so `Scope.send` / `steer_agent` actually reach it), a live tool-activity trace, and a\n * `progress()` read — turning the default cloud worker from something a supervisor can only\n * wait on into something it can watch and correct.\n *\n * Absent, nothing changes: the same `runAgentRounds` leaf, no inbox, `steer_agent` still reports\n * `delivered:false`. Opt-in because a steerable worker holds ONE box across several turns,\n * which is a different resource profile from a fire-and-forget shot.\n */\n steering?: SandboxSteeringOptions\n}\n\n/** CLI subprocess seam. `bin` + `args` describe the Halo/RLM process to spawn. */\nexport interface CliSeam {\n bin: string\n args?: string[]\n /** Extra environment for the subprocess (merged over `process.env`). */\n env?: Record<string, string>\n /** Working directory for the subprocess. */\n cwd?: string\n}\n\n/**\n * cli-worktree seam. A supervisor-authored `AgentProfile` driving a local coding-harness CLI\n * (claude / codex / opencode) on its own git worktree — the leaf `createWorktreeCliExecutor`\n * named as data. `harness` + `repoRoot` + `taskPrompt` are required; the authored\n * `profile.prompt.systemPrompt` + `profile.model.default` reach the harness via the §1.5\n * `harnessInvocation` mapper. Everything else mirrors `WorktreeCliExecutorOptions`.\n */\nexport interface CliWorktreeSeam {\n repoRoot: string\n /** Local CLI harness transport. Omit when `bridge` is set. */\n harness?: LocalHarness\n taskPrompt: string\n runId?: string\n baseRef?: string\n harnessTimeoutMs?: number\n /** Isolated, network-off Codex execution with terminal JSONL usage capture. */\n codexReproducible?: boolean\n /** Absolute host paths denied to reproducible Codex. */\n codexReadDeniedPaths?: ReadonlyArray<string>\n testCmd?: string\n typecheckCmd?: string\n checkTimeoutMs?: number\n checkOutputCap?: number\n budgetExempt?: boolean\n /** Live cli-bridge transport inside the worktree. When set, the worktree leaf accepts\n * `deliver()` messages and resumes the same bridge session in this worktree cwd. */\n bridge?: CliWorktreeBridgeSeam\n /** Test seam — forwarded to worktree helpers. */\n runGit?: GitRunner\n /** Test seam — forwarded to verification checks. */\n runCommand?: WorktreeCheckRunner\n}\n\nexport interface CliWorktreeBridgeSeam {\n bridgeUrl: string\n bridgeBearer: string\n /** Bridge model/harness id. Defaults to the profile's model hint when omitted. */\n model?: string\n agentProfile?: Record<string, unknown>\n timeoutMs?: number\n /** Stable cli-bridge session id. Defaults to `bridge-worktree-${runId}`. */\n sessionId?: string\n maxTurns?: number\n}\n\n/**\n * cli-bridge seam. A local OpenAI-compatible bridge that fronts harness CLIs\n * (claude-code / opencode / kimi / pi) behind one HTTP surface; `model` doubles\n * as the harness selector (e.g. `claude-code/sonnet`, `opencode/<provider>/<model>`).\n * `agentProfile` is the bridge-dialect profile (metadata.disallowedTools, mcp)\n * forwarded verbatim per request — how an arm disables native tools or injects\n * a provider search MCP.\n *\n * The executor opens a RESUMABLE cli-bridge session — structurally identical to the\n * sandbox executor's persistent box, just local. `sessionId` is the stable\n * caller-owned id cli-bridge maps to the harness's internal conversation id; a\n * follow-up steer/resume on the SAME id continues the SAME harness session (opencode\n * `-s`, claude `--resume`, …). Omit it and the executor mints a stable one per spawn.\n */\nexport interface BridgeSeam {\n bridgeUrl: string\n bridgeBearer: string\n model: string\n /** Optional working directory forwarded to cli-bridge and persisted with the session. */\n cwd?: string\n agentProfile?: Record<string, unknown>\n timeoutMs?: number\n /** Stable, caller-owned cli-bridge session id for harness-side resume. Defaults\n * to a freshly minted per-spawn id so each worker is its own resumable session. */\n sessionId?: string\n /** Per-resume-turn inference cap before the worker settles on its last output.\n * Mirrors `routerToolsInlineExecutor.maxTurns`; default 200 (runaway backstop). */\n maxTurns?: number\n}\n\n/** Generic environment provider executor config. External packages implement\n * `AgentEnvironmentProvider`; this built-in wrapper lets `createExecutor`\n * consume them as backend data while preserving the existing usage channel. */\nexport interface ProviderSeam extends ProviderExecutorOptions {\n provider: AgentEnvironmentProvider | string\n registry?: AgentEnvironmentProviderRegistry\n}\n\nconst routerSeamKey = 'router'\nconst sandboxSeamKey = 'sandbox'\nconst cliSeamKey = 'cli'\nconst bridgeSeamKey = 'bridge'\nconst cliWorktreeSeamKey = 'cli-worktree'\nconst providerSeamKey = 'provider'\n\n// ── Content-addressed result pointers (the B1 replay source) ───────────────────\n\n/** Deterministic content hash for an `outRef`. FNV-1a 32-bit over the canonical\n * JSON of the result — not cryptographic, sufficient for content-addressing the\n * replay blob so two identical outputs collapse to one pointer. */\nfunction contentRef(prefix: string, value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(value) ?? String(value)\n } catch {\n str = String(value)\n }\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return `${prefix}:${(h >>> 0).toString(16).padStart(8, '0')}`\n}\n\nfunction zeroSpend(): Spend {\n return { iterations: 0, tokens: zeroTokenUsage(), usd: 0, ms: 0 }\n}\n\n// ── router/inline executor (harness === null) ──────────────────────────────────\n\n/**\n * A direct OpenAI-compatible Router chat-completion. One-shot: resolves a\n * `ExecutorResult` and reports its terminal usage as `UsageEvent`s through the\n * conserved pool. Reports REAL token usage — when the provider omits `usage`,\n * the spend records zero tokens but the call still counts one iteration (a\n * phantom fabricated 0 is never emitted as a priced cost).\n *\n * Transport = `routerChatWithUsage` (`../router-client`): transient router\n * failures (429/5xx/Cloudflare-origin) retry with backoff before the executor\n * fails the task.\n */\nexport const routerInlineExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n const seam = readSeam<RouterSeam>(ctx, routerSeamKey, 'router/inline')\n const model = seam.model ?? spec.profile.model?.default\n if (!model) {\n throw new ValidationError(\n 'routerInlineExecutor: no model — set RouterSeam.model or AgentProfile.model.default',\n )\n }\n if (!seam.routerBaseUrl || !seam.routerKey) {\n throw new ValidationError('routerInlineExecutor: RouterSeam.routerBaseUrl + routerKey required')\n }\n\n const controller = new AbortController()\n const abortIfSignalled = () => {\n if (ctx.signal.aborted) controller.abort()\n }\n abortIfSignalled()\n if (!ctx.signal.aborted) ctx.signal.addEventListener('abort', abortIfSignalled, { once: true })\n\n let artifact: ExecutorResult<unknown> | undefined\n\n return {\n runtime: 'router' as Runtime,\n async execute(task, signal): Promise<ExecutorResult<unknown>> {\n const messages = taskToMessages(task, spec)\n const started = Date.now()\n const linked = linkSignals(signal, controller.signal)\n const r = await routerChatWithUsage(\n { routerBaseUrl: seam.routerBaseUrl, routerKey: seam.routerKey, model },\n messages,\n linked ? { signal: linked } : {},\n )\n const spent: Spend = {\n iterations: 1,\n tokens: r.usage ? { input: r.usage.input, output: r.usage.output } : zeroTokenUsage(),\n usd: r.costUsd ?? 0,\n ms: Date.now() - started,\n }\n const out = { content: r.content } as unknown\n artifact = { outRef: contentRef('router', { model, content: r.content }), out, spent }\n return artifact\n },\n teardown(_grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n return Promise.resolve({ destroyed: true })\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError('routerInlineExecutor: resultArtifact() read before execute()')\n }\n return { ...artifact, spent: artifact.spent }\n },\n }\n}\n\nexport type { ToolSpec }\n\n/**\n * Router seam WITH tool use — the tool-using router backend. Same direct\n * OpenAI-compatible endpoint as `RouterSeam`, but each turn passes `tools`; when\n * the model emits tool_calls they run via `executeToolCall` ON THIS HOST and the\n * results fold back as `tool` messages, repeating until the model answers without\n * a tool or `maxTurns` is hit. A real agentic loop, OFF-BOX — no sandbox, so it\n * is unaffected by a box's egress allowlist. One turn = one completion = the\n * equal-compute unit. `executeToolCall` receives the task so per-task tool\n * surfaces (e.g. a gym keyed by task) can dispatch correctly.\n */\nexport interface RouterToolsSeam {\n routerBaseUrl: string\n routerKey: string\n model?: string\n tools: ReadonlyArray<ToolSpec>\n executeToolCall: (name: string, args: Record<string, unknown>, task: unknown) => Promise<string>\n /** Online observer of each tool step — the seam a `DetectorMonitor` taps to watch the live pipe\n * (raise a `finding` when the worker loops/errors). Called after every tool call resolves, with\n * real per-call wall-clock (`startedAt`/`endedAt`/`durationMs`) so a push `TraceSource` can carry\n * non-zero span durations onto the unified timeline. */\n onToolStep?: (step: {\n toolName: string\n args: Record<string, unknown>\n status: 'ok' | 'error'\n // Real per-call wall-clock — the owned-loop executor always supplies these. Optional so an\n // external `RouterToolsSeam` that omits timing still satisfies the type (the span then collapses\n // to order + counts, per `toToolSpan`), keeping this an additive, non-breaking field set.\n startedAt?: number\n endedAt?: number\n durationMs?: number\n }) => void\n /** Max inference turns. Default 200 (runaway backstop — set far above any\n * legitimate workflow). For tighter per-workflow limits use a cost budget\n * or wall-clock deadline at the call site. */\n maxTurns?: number\n}\nconst routerToolsSeamKey = 'router-tools'\n\ninterface RouterToolsResponse {\n choices?: Array<{\n message?: {\n content?: string | null\n tool_calls?: Array<{ id?: string; function?: { name?: string; arguments?: string } }>\n }\n }>\n usage?: { prompt_tokens?: number; completion_tokens?: number }\n}\n\n/**\n * The tool-using router executor. Drives the multi-turn tool loop the single-shot\n * `routerInlineExecutor` cannot express; same fail-loud + real-usage discipline.\n */\nexport const routerToolsInlineExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n const seam = readSeam<RouterToolsSeam>(ctx, routerToolsSeamKey, 'router-tools')\n const model = seam.model ?? spec.profile.model?.default\n if (!model) {\n throw new ValidationError(\n 'routerToolsInlineExecutor: no model — set RouterToolsSeam.model or AgentProfile.model.default',\n )\n }\n if (!seam.routerBaseUrl || !seam.routerKey) {\n throw new ValidationError(\n 'routerToolsInlineExecutor: RouterToolsSeam.routerBaseUrl + routerKey required',\n )\n }\n const maxTurns = seam.maxTurns ?? 200\n\n const controller = new AbortController()\n const abortIfSignalled = () => {\n if (ctx.signal.aborted) controller.abort()\n }\n abortIfSignalled()\n if (!ctx.signal.aborted) ctx.signal.addEventListener('abort', abortIfSignalled, { once: true })\n\n // The down-leg receive end: the driver's steer/answer/resume land here via `Scope.send`.\n const inbox = createInbox()\n\n let artifact: ExecutorResult<unknown> | undefined\n\n return {\n runtime: 'router' as Runtime,\n deliver: (m) => inbox.deliver(m),\n async execute(task, signal): Promise<ExecutorResult<unknown>> {\n const started = Date.now()\n const messages: Array<Record<string, unknown>> = [\n ...(taskToMessages(task, spec) as Array<Record<string, unknown>>),\n ]\n const tokens = zeroTokenUsage()\n let turns = 0\n let lastText = ''\n // Fold any queued down-messages into the conversation as one operator turn (the boundary flush).\n const flush = () => {\n const pending = inbox.drain()\n if (pending.length) messages.push({ role: 'user', content: inbox.fold(pending) })\n return pending.length > 0\n }\n\n // The external abort sources (caller signal + executor teardown), merged ONCE — so we don't\n // re-register listeners on these long-lived signals every turn.\n const external = mergeAbortSignals(signal, controller.signal)\n\n for (let t = 0; t < maxTurns; t += 1) {\n // QUEUED messages flush at the step boundary, before this turn's inference.\n flush()\n // A forceful (interrupt) message aborts THIS turn so the worker re-plans immediately. The\n // per-turn controller fires on `external` OR a fresh interrupt; its listener on `external` is\n // removed after the turn (`cleanup`) so nothing accumulates across turns.\n const interruptSig = inbox.freshInterrupt()\n const turnController = new AbortController()\n const abortTurn = () => turnController.abort()\n if (external.aborted) turnController.abort()\n else external.addEventListener('abort', abortTurn)\n interruptSig.addEventListener('abort', abortTurn, { once: true })\n const cleanup = () => external.removeEventListener('abort', abortTurn)\n let res: Response\n try {\n res = await fetch(`${seam.routerBaseUrl.replace(/\\/$/, '')}/chat/completions`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${seam.routerKey}`,\n },\n body: JSON.stringify({\n model,\n messages,\n tools: seam.tools,\n tool_choice: 'auto',\n temperature: 0.2,\n }),\n signal: turnController.signal,\n })\n } catch (e) {\n cleanup()\n // Re-plan ONLY when a forceful inbox message aborted this turn (a real AbortError, with the\n // interrupt — not the external teardown/budget signal). The re-planned turn still consumes a\n // loop slot (so interrupt spam is bounded by maxTurns, not a hang) but does not bill a turn.\n // Any other error — incl. a network fault coincident with an interrupt — is fatal: rethrow.\n const interruptAbort =\n e instanceof DOMException &&\n e.name === 'AbortError' &&\n interruptSig.aborted &&\n !signal.aborted &&\n !controller.signal.aborted\n if (interruptAbort) continue\n throw e\n }\n cleanup()\n // The inference completed — count the turn now (an interrupted, re-planned turn doesn't bill).\n turns += 1\n if (!res.ok) {\n throw new ValidationError(\n `routerToolsInlineExecutor: router ${res.status}: ${(await res.text()).slice(0, 200)}`,\n )\n }\n const data = (await res.json()) as RouterToolsResponse\n const u = data.usage\n if (u && typeof u.prompt_tokens === 'number' && typeof u.completion_tokens === 'number') {\n tokens.input += u.prompt_tokens\n tokens.output += u.completion_tokens\n }\n const msg = data.choices?.[0]?.message\n if (msg?.content) lastText = msg.content\n const toolCalls = msg?.tool_calls ?? []\n if (toolCalls.length === 0) {\n // Before settling, flush once more — a worker may not finish while a steer/answer it never\n // read is still pending. If anything flushed, keep going; otherwise it is truly done.\n if (flush()) continue\n break\n }\n\n // Record the assistant turn verbatim, then run each call on the host and\n // fold the result back as a `tool` message for the next turn.\n messages.push({\n role: 'assistant',\n content: msg?.content ?? '',\n tool_calls: toolCalls.map((tc, i) => ({\n id: tc.id ?? `call_${i}`,\n type: 'function',\n function: { name: tc.function?.name ?? '', arguments: tc.function?.arguments ?? '{}' },\n })),\n })\n for (let i = 0; i < toolCalls.length; i += 1) {\n const tc = toolCalls[i]\n const id = tc?.id ?? `call_${i}`\n let args: Record<string, unknown> = {}\n try {\n args = JSON.parse(tc?.function?.arguments ?? '{}') as Record<string, unknown>\n } catch {\n // Malformed args are a real outcome, not an infra fault — feed the error\n // back so the model can correct, rather than aborting the whole loop.\n messages.push({\n role: 'tool',\n tool_call_id: id,\n content: 'error: tool arguments were not valid JSON',\n })\n continue\n }\n const toolName = tc?.function?.name ?? ''\n let result: string\n let status: 'ok' | 'error' = 'ok'\n const toolStartedAt = Date.now()\n try {\n result = await seam.executeToolCall(toolName, args, task)\n } catch (e) {\n status = 'error'\n result = `error: ${e instanceof Error ? e.message : String(e)}`\n }\n const toolEndedAt = Date.now()\n messages.push({ role: 'tool', tool_call_id: id, content: result })\n // Feed the online detector pipe (stuck-loop / error-streak) — a worker repeating the same\n // call or hammering errors is caught mid-run, not only at settle. This is an observability\n // side-channel: a throwing monitor must never crash the production inference loop.\n try {\n seam.onToolStep?.({\n toolName,\n args,\n status,\n startedAt: toolStartedAt,\n endedAt: toolEndedAt,\n durationMs: toolEndedAt - toolStartedAt,\n })\n } catch {\n // ignore — monitoring must not break the worker\n }\n }\n }\n\n const usd = isModelPriced(model) ? estimateCost(tokens.input, tokens.output, model) : 0\n const spent: Spend = { iterations: turns, tokens, usd, ms: Date.now() - started }\n const out = { content: lastText } as unknown\n artifact = { outRef: contentRef('router-tools', { model, content: lastText }), out, spent }\n return artifact\n },\n teardown(_grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n return Promise.resolve({ destroyed: true })\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError(\n 'routerToolsInlineExecutor: resultArtifact() read before execute()',\n )\n }\n return { ...artifact, spent: artifact.spent }\n },\n }\n}\n\n// ── sandbox executor (harness is a BackendType) ────────────────────────────────\n\n/**\n * COMPOSES `runAgentRounds` as a single-task leaf: one box, a refine driver bounded to\n * the seam's `maxIterations` (default 1), the spec's profile as the agent run.\n * Surfaces the loop's aggregated `tokenUsage` + `costUsd` as `UsageEvent`s after\n * it drains, and yields one `iteration` event per loop iteration. Forwards the\n * optional `lineage` passthrough WITHOUT importing sandbox-lineage / reinventing\n * checkpoint/fork.\n *\n * Streaming shape: the loop runs to completion inside the first `next()`, then\n * the recorded usage events are yielded; the terminal artifact is read from\n * `resultArtifact()` after the stream drains.\n */\nexport const sandboxExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n if (spec.harness === null) {\n throw new ValidationError('sandboxExecutor: harness is null (router/inline) — wrong executor')\n }\n const harness = spec.harness as BackendType\n const seam = readSeam<SandboxSeam>(ctx, sandboxSeamKey, 'sandbox')\n if (!seam.sandboxClient || typeof seam.sandboxClient.create !== 'function') {\n throw new ValidationError('sandboxExecutor: SandboxSeam.sandboxClient.create required')\n }\n const maxIterations = seam.maxIterations ?? 1\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('sandboxExecutor: maxIterations must be > 0')\n }\n // The cross-MACHINE case this exists for: the box gets `TRACE_ID` / `PARENT_SPAN_ID` through\n // `CreateSandboxOptions.env`, so whatever the remote worker emits lands in this run's trace under\n // the spawning node's span. Empty when the run records no spans, and an empty record adds no\n // `env` key to the create options at all.\n const traceEnv = workerTraceEnv(ctx)\n\n const controller = new AbortController()\n const abortIfSignalled = () => {\n if (ctx.signal.aborted) controller.abort()\n }\n abortIfSignalled()\n if (!ctx.signal.aborted) ctx.signal.addEventListener('abort', abortIfSignalled, { once: true })\n\n let artifact: ExecutorResult<unknown> | undefined\n\n // STEERABLE mode (opt-in): the worker becomes a multi-turn session on one box, with a real\n // inbox, so a driver's steer has a turn boundary to be folded into. This is the path that\n // makes `Scope.send` return `true` for the DEFAULT cloud worker.\n if (seam.steering) {\n const inbox = createInbox()\n const session = createSteerableSandboxSession({\n controller,\n profile: spec.profile,\n harness,\n sandboxClient: seam.sandboxClient,\n inbox,\n taskToPrompt: (t) => taskToPrompt(t),\n options: seam.steering,\n ...(seam.loopCtx ? { loopCtx: seam.loopCtx } : {}),\n ...(Object.keys(traceEnv).length > 0 ? { traceEnv } : {}),\n contentRef,\n })\n return {\n runtime: 'sandbox' as Runtime,\n deliver: (m) => inbox.deliver(m),\n progress: (): ExecutorProgress => session.progress(),\n traceSource: (): TraceSource => session.traceSource(),\n execute(task, signal): AsyncIterable<UsageEvent> {\n return session.stream(task, signal)\n },\n async teardown(_grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n await session.teardown()\n return { destroyed: true }\n },\n resultArtifact() {\n const a = session.artifact()\n if (!a) {\n throw new ValidationError(\n 'sandboxExecutor(steering): resultArtifact() read before stream drained',\n )\n }\n return a\n },\n }\n }\n\n // The leaf runs an opaque, self-parallelizing coding harness; the loop just\n // refines once over it. Output is the raw event stream parsed to its tail text.\n const output: OutputAdapter<SandboxLeafOut> = {\n parse(events: SandboxEvent[]): SandboxLeafOut {\n return { events }\n },\n }\n const driver = singleShotDriver<SandboxLeafOut>(maxIterations)\n\n return {\n runtime: 'sandbox' as Runtime,\n execute(task, signal): AsyncIterable<UsageEvent> {\n return streamSandboxLeaf({\n task,\n signal,\n harness,\n spec,\n seam,\n output,\n driver,\n maxIterations,\n controller,\n loopCtx: seam.loopCtx,\n traceEnv,\n onArtifact: (a) => {\n artifact = a\n },\n })\n },\n teardown(_grace): Promise<{ destroyed: boolean }> {\n // The composed runAgentRounds owns its box teardown (finally{allSettled(destroy)});\n // aborting the loop's signal cascades into that barrier.\n controller.abort()\n return Promise.resolve({ destroyed: true })\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError('sandboxExecutor: resultArtifact() read before stream drained')\n }\n return artifact\n },\n }\n}\n\ninterface SandboxLeafOut {\n events: SandboxEvent[]\n}\n\ninterface StreamSandboxArgs {\n task: unknown\n signal: AbortSignal\n harness: BackendType\n spec: AgentSpec\n seam: SandboxSeam\n output: OutputAdapter<SandboxLeafOut>\n driver: Driver<unknown, SandboxLeafOut, string>\n maxIterations: number\n controller: AbortController\n loopCtx?: Partial<Omit<ExecCtx, 'sandboxClient' | 'signal'>>\n /** Inherited `TRACE_ID` / `PARENT_SPAN_ID` for the box; empty when tracing is off. */\n traceEnv: Record<string, string>\n onArtifact: (a: ExecutorResult<unknown>) => void\n}\n\nasync function* streamSandboxLeaf(args: StreamSandboxArgs): AsyncIterable<UsageEvent> {\n const linked = new AbortController()\n const cascade = () => linked.abort()\n if (args.signal.aborted || args.controller.signal.aborted) linked.abort()\n else {\n args.signal.addEventListener('abort', cascade, { once: true })\n args.controller.signal.addEventListener('abort', cascade, { once: true })\n }\n\n const agentRun: AgentRunSpec<unknown> = {\n profile: args.spec.profile,\n taskToPrompt: (t) => taskToPrompt(t),\n name: args.spec.profile.name ?? args.harness,\n sandboxOverrides: {\n backend: { type: args.harness },\n // Absent entirely when tracing is off, so the create options are byte-identical to before.\n ...(Object.keys(args.traceEnv).length > 0 ? { env: args.traceEnv } : {}),\n },\n }\n const started = Date.now()\n\n // `lineage` is a PR #150 RunAgentRoundsOptions field absent on this branch — forwarded\n // forward-compatibly without coupling to its (not-yet-present) static type.\n const loopOptions = {\n driver: args.driver,\n agentRun,\n output: args.output,\n task: args.task,\n maxIterations: args.maxIterations,\n maxConcurrency: 1,\n ctx: {\n ...(args.loopCtx ?? {}),\n sandboxClient: args.seam.sandboxClient,\n signal: linked.signal,\n } as ExecCtx,\n ...(args.seam.lineage !== undefined ? { lineage: args.seam.lineage } : {}),\n } as RunAgentRoundsOptions<unknown, SandboxLeafOut, string>\n\n try {\n const result = await runAgentRounds(loopOptions)\n const out = result.winner?.output ?? { events: [] }\n const verdict = result.winner?.verdict\n const spent: Spend = {\n iterations: result.iterations.length,\n tokens: { input: result.tokenUsage.input, output: result.tokenUsage.output },\n usd: result.costUsd,\n ms: Date.now() - started,\n }\n args.onArtifact({\n outRef: contentRef('sandbox', { harness: args.harness, out }),\n out,\n ...(verdict ? { verdict } : {}),\n spent,\n })\n for (let i = 0; i < result.iterations.length; i += 1) yield { kind: 'iteration' }\n if (result.tokenUsage.input || result.tokenUsage.output) {\n yield { kind: 'tokens', input: result.tokenUsage.input, output: result.tokenUsage.output }\n }\n if (result.costUsd) yield { kind: 'cost', usd: result.costUsd }\n } finally {\n args.signal.removeEventListener('abort', cascade)\n args.controller.signal.removeEventListener('abort', cascade)\n }\n}\n\n// ── cli executor (Halo / external RLM subprocess) ──────────────────────────────\n\n/**\n * Spawns a subprocess (`bin` + `args`). It cannot account tokens, so it is\n * `budgetExempt: true`: its spend is NOT metered against the conserved pool and\n * its iterations are EXCLUDED from the equal-k arms by construction (the\n * resolver/equal-k path checks `budgetExempt`). teardown is SIGTERM → SIGKILL\n * with a grace window. Streaming: yields one `iteration` event on clean exit.\n */\nexport const cliExecutor: ExecutorFactory<unknown> = (_spec, ctx) => {\n const seam = readSeam<CliSeam>(ctx, cliSeamKey, 'cli')\n if (!seam.bin) throw new ValidationError('cliExecutor: CliSeam.bin required')\n // `TRACE_ID` / `PARENT_SPAN_ID` for this worker when the run records spans; `{}` otherwise.\n const traceEnv = workerTraceEnv(ctx)\n\n const controller = new AbortController()\n const abortIfSignalled = () => {\n if (ctx.signal.aborted) controller.abort()\n }\n abortIfSignalled()\n if (!ctx.signal.aborted) ctx.signal.addEventListener('abort', abortIfSignalled, { once: true })\n\n let proc: ReturnType<typeof spawn> | undefined\n let artifact: ExecutorResult<unknown> | undefined\n\n return {\n runtime: 'cli' as Runtime,\n budgetExempt: true,\n execute(task, signal): AsyncIterable<UsageEvent> {\n return streamCliLeaf({\n task,\n signal,\n traceEnv,\n seam,\n controller,\n onProc: (p) => {\n proc = p\n },\n onArtifact: (a) => {\n artifact = a\n },\n })\n },\n async teardown(grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n if (!proc || proc.exitCode !== null || proc.killed) return { destroyed: true }\n return killWithGrace(proc, grace)\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError('cliExecutor: resultArtifact() read before stream drained')\n }\n return artifact\n },\n }\n}\n\ninterface StreamCliArgs {\n task: unknown\n signal: AbortSignal\n seam: CliSeam\n /** Inherited `TRACE_ID` / `PARENT_SPAN_ID` for the subprocess; empty when tracing is off. */\n traceEnv: Record<string, string>\n controller: AbortController\n onProc: (p: ReturnType<typeof spawn>) => void\n onArtifact: (a: ExecutorResult<unknown>) => void\n}\n\nasync function* streamCliLeaf(args: StreamCliArgs): AsyncIterable<UsageEvent> {\n const prompt = taskToPrompt(args.task)\n const proc = spawn(args.seam.bin, args.seam.args ?? [], {\n ...(args.seam.cwd ? { cwd: args.seam.cwd } : {}),\n // Trace context above ambient `process.env` (whose ids describe the SUPERVISOR's place in an\n // outer trace, not this child's) and below `seam.env` (a deliberate operator declaration).\n env: { ...process.env, ...args.traceEnv, ...(args.seam.env ?? {}) },\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n args.onProc(proc)\n\n const onAbort = () => killWithGrace(proc, 'brutalKill')\n if (args.signal.aborted || args.controller.signal.aborted) onAbort()\n else {\n args.signal.addEventListener('abort', onAbort, { once: true })\n args.controller.signal.addEventListener('abort', onAbort, { once: true })\n }\n\n // Feed the task on stdin; the subprocess owns its own tool/agent loop.\n if (proc.stdin) {\n proc.stdin.write(prompt)\n proc.stdin.end()\n }\n const chunks: string[] = []\n const errChunks: string[] = []\n if (proc.stdout) proc.stdout.on('data', (d: Buffer) => chunks.push(d.toString('utf8')))\n if (proc.stderr) proc.stderr.on('data', (d: Buffer) => errChunks.push(d.toString('utf8')))\n\n const exit = await new Promise<{ code: number | null; error?: Error }>((resolve) => {\n proc.once('error', (err) => resolve({ code: null, error: err }))\n proc.once('close', (code) => resolve({ code }))\n })\n args.signal.removeEventListener('abort', onAbort)\n args.controller.signal.removeEventListener('abort', onAbort)\n\n if (exit.error) {\n throw new ValidationError(`cliExecutor: spawn failed: ${exit.error.message}`, {\n cause: exit.error,\n })\n }\n if (exit.code !== 0) {\n throw new ValidationError(\n `cliExecutor: ${args.seam.bin} exited ${exit.code}: ${errChunks.join('').slice(0, 200)}`,\n )\n }\n const out = { content: chunks.join('') } as unknown\n // budgetExempt: spend is recorded zero (not metered) — never a fabricated cost.\n args.onArtifact({ outRef: contentRef('cli', out), out, spent: zeroSpend() })\n yield { kind: 'iteration' }\n}\n\n/** SIGTERM, then SIGKILL after `grace` ms (`'brutalKill'` = immediate SIGKILL,\n * `'infinity'` = await clean exit, never escalate). */\nfunction killWithGrace(\n proc: ReturnType<typeof spawn>,\n grace: number | 'brutalKill' | 'infinity',\n): Promise<{ destroyed: boolean }> {\n if (proc.exitCode !== null || proc.killed) return Promise.resolve({ destroyed: true })\n return new Promise((resolve) => {\n let timer: ReturnType<typeof setTimeout> | undefined\n proc.once('close', () => {\n if (timer) clearTimeout(timer)\n resolve({ destroyed: true })\n })\n if (grace === 'brutalKill') {\n proc.kill('SIGKILL')\n return\n }\n proc.kill('SIGTERM')\n if (grace === 'infinity') return\n timer = setTimeout(() => {\n if (proc.exitCode === null && !proc.killed) proc.kill('SIGKILL')\n }, grace)\n })\n}\n\n// ── bridge executor (harness CLIs behind the local cli-bridge) ──────────────────\n\n/**\n * A worker as a RESUMABLE cli-bridge harness session — the local twin of the\n * sandbox executor. Both are a persistent, streamed agent session the driver\n * spawns, watches stream `UsageEvent`s, then STEERS/RESUMES out-of-band; the only\n * difference is where the harness runs (local cli-bridge vs a cloud box).\n *\n * Structure mirrors `streamSandboxLeaf` + `routerToolsInlineExecutor`:\n * - STREAMED: `execute` returns an `AsyncIterable<UsageEvent>`; the SSE chunks\n * cli-bridge emits (`stream:true`) are parsed into incremental usage + a tail\n * artifact read via `resultArtifact()` after the stream drains.\n * - RESUMABLE: every turn carries a stable `session_id`. cli-bridge maps it to the\n * harness's internal conversation id (SQLite `SessionStore`), so a steer delivered\n * via `deliver` re-calls the SAME session id — opencode `-s <id>`, claude\n * `--resume`, … — continuing the SAME harness session, not a fresh one.\n * - STEERABLE: the down-leg `inbox` is drained at each turn boundary; a queued\n * steer becomes the next turn's prompt on the same session, and the worker can't\n * settle while a steer it never read is pending (the sandbox/router contract).\n * - ABORT: the caller signal + teardown fold into the per-turn fetch signal; a\n * forceful (`interrupt`) steer aborts the in-flight turn so the worker re-plans.\n *\n * Reports REAL usage when the bridge surfaces it, never a fabricated cost.\n */\n/** Resolve the bridge wire model for this spawn: a per-create `backend` override\n * (harness + model) wins over the seam default, encoded as `${harness}/${model}`.\n * Absent an override the seam `model` is used verbatim. */\nfunction bridgeCellModel(seamModel: string, ctx: ExecutorContext): string {\n const create = ctx.seams.createOptions as\n | { backend?: { type?: string; model?: { model?: string } } }\n | undefined\n const backend = create?.backend\n const harness = backend?.type\n const model = backend?.model?.model\n if (!harness && !model) return seamModel\n const h = harness ?? ''\n const m = model ?? seamModel\n if (!h) return m\n return m.startsWith(`${h}/`) ? m : `${h}/${m}`\n}\n\nexport const bridgeExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n const base = readSeam<BridgeSeam>(ctx, bridgeSeamKey, 'bridge')\n // A per-create `backend` override (threaded by `inlineSandboxClient` as\n // `seams.createOptions`) targets the bridge model per cell without a second\n // client: `backend.type` is the harness, `backend.model.model` the model, and\n // the wire id is `${harness}/${model}` (an already-`${harness}/`-prefixed model\n // passes through). This is how ONE bridge `SandboxClient` drives every\n // harness×model cell of a matrix — the seam `model` is the fixed default.\n const seam = { ...base, model: bridgeCellModel(base.model, ctx) }\n if (!seam.bridgeUrl || !seam.bridgeBearer || !seam.model) {\n throw new ValidationError(\n 'bridgeExecutor: BridgeSeam.bridgeUrl + bridgeBearer + model required',\n )\n }\n const maxTurns = seam.maxTurns ?? 200\n // A stable per-spawn session id (caller can pin one) — cli-bridge keys harness\n // resume off this exactly as a box id keys a sandbox session.\n const sessionId = seam.sessionId ?? `bridge-${spec.profile.name ?? 'worker'}-${randomUUID()}`\n\n const controller = new AbortController()\n const abortIfSignalled = () => {\n if (ctx.signal.aborted) controller.abort()\n }\n abortIfSignalled()\n if (!ctx.signal.aborted) ctx.signal.addEventListener('abort', abortIfSignalled, { once: true })\n\n // The down-leg receive end: the driver's steer/answer/resume land here via `Scope.send`.\n const inbox = createInbox()\n let artifact: ExecutorResult<unknown> | undefined\n\n return {\n runtime: 'cli' as Runtime,\n deliver: (m) => inbox.deliver(m),\n execute(task, signal): AsyncIterable<UsageEvent> {\n return streamBridgeSession({\n task,\n signal,\n spec,\n seam,\n sessionId,\n maxTurns,\n inbox,\n controller,\n onArtifact: (a) => {\n artifact = a\n },\n })\n },\n teardown(_grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n return Promise.resolve({ destroyed: true })\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError('bridgeExecutor: resultArtifact() read before stream drained')\n }\n return { ...artifact, spent: artifact.spent }\n },\n }\n}\n\ninterface StreamBridgeArgs {\n task: unknown\n signal: AbortSignal\n spec: AgentSpec\n seam: BridgeSeam\n sessionId: string\n maxTurns: number\n inbox: Inbox\n controller: AbortController\n onArtifact: (a: ExecutorResult<unknown>) => void\n}\n\n/**\n * One resumable cli-bridge session, run as a streamed turn loop. Turn 0 sends the\n * task; each subsequent turn fires ONLY when the inbox has a steer/answer to fold —\n * re-calling the SAME `session_id` so cli-bridge resumes the harness conversation.\n * Mirrors `routerToolsInlineExecutor`'s drain→turn→settle loop, but each turn is a\n * full streamed harness session call rather than a single chat round.\n */\nasync function* streamBridgeSession(args: StreamBridgeArgs): AsyncIterable<UsageEvent> {\n const { seam, inbox } = args\n const started = Date.now()\n const external = mergeAbortSignals(args.signal, args.controller.signal)\n const tokens = zeroTokenUsage()\n let usd = 0\n let turns = 0\n let lastText = ''\n const toolCalls: string[] = []\n\n // Turn 0 is the task; later turns carry the folded steer/answer as the next prompt\n // on the SAME session. `nextPrompt` is undefined once there's nothing pending.\n let nextPrompt: string | undefined = taskToPrompt(args.task)\n const system = args.spec.profile.prompt?.systemPrompt\n\n for (let t = 0; t < args.maxTurns; t += 1) {\n // Drain queued down-messages; on turns > 0 they ARE the prompt (resume content).\n const pending = inbox.drain()\n if (pending.length) {\n const folded = inbox.fold(pending)\n nextPrompt = t === 0 && nextPrompt ? `${nextPrompt}\\n\\n${folded}` : folded\n }\n if (nextPrompt === undefined) break\n\n // Each turn sends ONLY the new prompt — cli-bridge's session resume replays the\n // harness's own history server-side (opencode `-s`), so re-sending it would\n // double the conversation. Turn 0 may include the system preamble.\n const messages: Array<{ role: string; content: string }> = []\n if (t === 0 && typeof system === 'string' && system.length > 0) {\n messages.push({ role: 'system', content: system })\n }\n messages.push({ role: 'user', content: nextPrompt })\n nextPrompt = undefined\n\n // Per-turn signal: external teardown/abort OR a forceful interrupt steer.\n const interruptSig = inbox.freshInterrupt()\n const turnController = new AbortController()\n const abortTurn = () => turnController.abort()\n if (external.aborted) turnController.abort()\n else external.addEventListener('abort', abortTurn)\n interruptSig.addEventListener('abort', abortTurn, { once: true })\n const timer = seam.timeoutMs ? setTimeout(abortTurn, seam.timeoutMs) : undefined\n const cleanup = () => {\n external.removeEventListener('abort', abortTurn)\n if (timer) clearTimeout(timer)\n }\n\n let res: BridgeResponse\n try {\n res = await bridgeStreamPost(seam.bridgeUrl, {\n bearer: seam.bridgeBearer,\n sessionId: args.sessionId,\n body: {\n model: seam.model,\n stream: true,\n session_id: args.sessionId,\n ...(seam.cwd ? { cwd: seam.cwd } : {}),\n ...(seam.agentProfile ? { agent_profile: seam.agentProfile } : {}),\n messages,\n },\n signal: turnController.signal,\n })\n } catch (e) {\n cleanup()\n // Re-plan ONLY when a forceful steer (not external teardown) aborted the turn —\n // the steer is already queued, so loop back and fold it. Anything else is fatal.\n const interruptAbort =\n e instanceof DOMException &&\n e.name === 'AbortError' &&\n interruptSig.aborted &&\n !args.signal.aborted &&\n !args.controller.signal.aborted\n if (interruptAbort) continue\n throw e\n }\n if (!res.ok) {\n cleanup()\n throw new ValidationError(\n `bridgeExecutor: bridge ${res.status}: ${(await res.text()).slice(0, 300)}`,\n )\n }\n if (!res.body) {\n cleanup()\n throw new ValidationError('bridgeExecutor: bridge response had no body to stream')\n }\n\n let turnText = ''\n try {\n for await (const chunk of parseSseChatStream(res.body)) {\n if (chunk.content) {\n turnText += chunk.content\n }\n if (chunk.toolCall) toolCalls.push(chunk.toolCall)\n if (chunk.usage) {\n tokens.input += chunk.usage.input\n tokens.output += chunk.usage.output\n yield { kind: 'tokens', input: chunk.usage.input, output: chunk.usage.output }\n }\n if (typeof chunk.cost === 'number' && chunk.cost > 0) {\n usd += chunk.cost\n yield { kind: 'cost', usd: chunk.cost }\n }\n }\n } finally {\n cleanup()\n }\n turns += 1\n yield { kind: 'iteration' }\n if (turnText) lastText = turnText\n\n // Before settling, drain once more — the worker can't finish while a steer it\n // never read is pending (the sandbox/router settle contract). A pending steer\n // becomes the next resume turn; otherwise the session is truly done.\n if (inbox.pending() === 0) break\n }\n\n const spent: Spend = {\n iterations: turns,\n tokens,\n usd,\n ms: Date.now() - started,\n }\n const out = { content: lastText, toolCalls } as unknown\n args.onArtifact({\n outRef: contentRef('bridge', { model: seam.model, session: args.sessionId, content: lastText }),\n out,\n spent,\n })\n}\n\n/** The subset of `Response` `streamBridgeSession` consumes: status gate, an error\n * body reader, and a web `ReadableStream` the SSE parser drains. */\ninterface BridgeResponse {\n ok: boolean\n status: number\n text: () => Promise<string>\n body: ReadableStream<Uint8Array> | null\n}\n\ninterface BridgeStreamPostArgs {\n bearer: string\n sessionId: string\n body: unknown\n signal: AbortSignal\n}\n\n/**\n * POST one streamed turn to the cli-bridge over the `node:http(s)` core client\n * instead of global `fetch`. The bridge runs a harness CLI and streams SSE only\n * once that harness starts producing — first byte routinely arrives >5 min into a\n * heavy turn. `fetch` (undici) caps the wait for response headers at a fixed\n * `headersTimeout` (~300s) that no per-request option or `AbortSignal` overrides,\n * so it aborts a live-but-slow bridge with an opaque \"Headers Timeout Error\". The\n * core client has no such cap; the turn's `AbortSignal` (external teardown, a\n * forceful steer, or `seam.timeoutMs`) is the sole deadline. The response's\n * `IncomingMessage` (a Node `Readable`) is adapted to a web `ReadableStream` so the\n * shared `parseSseChatStream` consumes it unchanged.\n */\nfunction bridgeStreamPost(url: string, args: BridgeStreamPostArgs): Promise<BridgeResponse> {\n const target = new URL(`${url.replace(/\\/$/, '')}/v1/chat/completions`)\n const payload = JSON.stringify(args.body)\n const requestFn = target.protocol === 'https:' ? httpsRequest : httpRequest\n return new Promise<BridgeResponse>((resolve, reject) => {\n if (args.signal.aborted) {\n reject(new DOMException('bridgeExecutor: aborted before request', 'AbortError'))\n return\n }\n const req = requestFn(\n target,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${args.bearer}`,\n 'x-session-id': args.sessionId,\n 'content-length': Buffer.byteLength(payload),\n },\n // No header/body idle timeout: a slow bridge is a live bridge; the abort\n // signal is the sole deadline.\n timeout: 0,\n },\n (res) => {\n const status = res.statusCode ?? 0\n const ok = status >= 200 && status < 300\n const body = Readable.toWeb(res) as ReadableStream<Uint8Array>\n resolve({\n ok,\n status,\n body,\n text: async () => {\n const chunks: Buffer[] = []\n for await (const c of res) chunks.push(c as Buffer)\n return Buffer.concat(chunks).toString('utf8')\n },\n })\n },\n )\n const onAbort = (): void => {\n req.destroy(new DOMException('bridgeExecutor: turn aborted', 'AbortError'))\n }\n if (args.signal.aborted) onAbort()\n else args.signal.addEventListener('abort', onAbort, { once: true })\n req.on('error', (e) => {\n args.signal.removeEventListener('abort', onAbort)\n reject(e)\n })\n req.on('close', () => args.signal.removeEventListener('abort', onAbort))\n req.write(payload)\n req.end()\n })\n}\n\ninterface BridgeStreamChunk {\n content?: string\n toolCall?: string\n usage?: { input: number; output: number }\n cost?: number\n}\n\n/**\n * Parse cli-bridge's OpenAI-compatible SSE stream into normalized chunks. Each\n * `data:` line is an OpenAI chat-completion chunk (`choices[].delta`); `[DONE]`\n * and SSE comments (`:` keepalives) terminate/skip. Mirrors how `streamSandboxLeaf`\n * folds a box's event stream — same `UsageEvent` currency, different wire shape.\n */\nasync function* parseSseChatStream(\n body: ReadableStream<Uint8Array>,\n): AsyncIterable<BridgeStreamChunk> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n // SSE frames are separated by a blank line; split on it and keep the tail.\n let sep = buf.indexOf('\\n\\n')\n while (sep !== -1) {\n const frame = buf.slice(0, sep)\n buf = buf.slice(sep + 2)\n const chunk = parseSseFrame(frame)\n if (chunk === 'done') return\n if (chunk) yield chunk\n sep = buf.indexOf('\\n\\n')\n }\n }\n // Upstream failures routinely arrive UNTERMINATED: a final `data:` frame\n // with no trailing blank line, or a bare JSON error body with no SSE\n // framing at all (kimi's access_terminated_error). Dropping the tail here\n // ends the stream as one empty zero-token turn — the integrity guard still\n // fails the run, but the diagnostic dies with the buffer. Parse the tail so\n // the upstream error message rides the thrown event instead.\n const tail = parseSseStreamTail(buf)\n if (tail !== undefined && tail !== 'done') yield tail\n } finally {\n reader.releaseLock()\n }\n}\n\n/** Parse the stream's unterminated tail: an SSE frame missing its trailing\n * blank line, or a bare (non-SSE) JSON body — the shape bridge upstreams use\n * for terminal failures. Throws `ValidationError` on an error payload; returns\n * `undefined` for keepalive noise or non-JSON leftovers. */\nfunction parseSseStreamTail(buf: string): BridgeStreamChunk | 'done' | undefined {\n const tail = buf.trim()\n if (!tail) return undefined\n const framed = parseSseFrame(tail)\n if (framed !== undefined) return framed\n let parsed: { error?: { message?: string; type?: string } }\n try {\n parsed = JSON.parse(tail)\n } catch {\n return undefined\n }\n if (parsed.error) {\n throw new ValidationError(\n `bridgeExecutor: bridge upstream error: ${parsed.error.message ?? parsed.error.type ?? 'unknown'}`,\n )\n }\n return undefined\n}\n\n/** Parse one SSE frame (possibly multi-line `data:`/comment) into a chunk, `'done'`,\n * or undefined (comment/keepalive/empty). */\nfunction parseSseFrame(frame: string): BridgeStreamChunk | 'done' | undefined {\n const dataLines: string[] = []\n for (const rawLine of frame.split('\\n')) {\n const line = rawLine.replace(/\\r$/, '')\n if (!line || line.startsWith(':')) continue // comment / keepalive\n if (line.startsWith('data:')) dataLines.push(line.slice('data:'.length).trimStart())\n }\n if (dataLines.length === 0) return undefined\n const data = dataLines.join('\\n')\n if (data === '[DONE]') return 'done'\n let parsed: {\n choices?: Array<{\n delta?: {\n content?: string | null\n tool_calls?: Array<{ function?: { name?: string } }>\n }\n message?: { content?: string | null }\n }>\n error?: { message?: string; type?: string }\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number }\n }\n try {\n parsed = JSON.parse(data)\n } catch {\n return undefined\n }\n if (parsed.error) {\n // `type` is the upstream's error class (e.g. kimi's access_terminated_error)\n // — carry it when the payload has no message, never collapse to 'unknown'.\n throw new ValidationError(\n `bridgeExecutor: bridge stream error: ${parsed.error.message ?? parsed.error.type ?? 'unknown'}`,\n )\n }\n const out: BridgeStreamChunk = {}\n const choice = parsed.choices?.[0]\n const content = choice?.delta?.content ?? choice?.message?.content\n if (typeof content === 'string' && content.length > 0) out.content = content\n const toolName = choice?.delta?.tool_calls?.[0]?.function?.name\n if (typeof toolName === 'string' && toolName.length > 0) out.toolCall = toolName\n const u = parsed.usage\n if (u && (typeof u.prompt_tokens === 'number' || typeof u.completion_tokens === 'number')) {\n out.usage = { input: u.prompt_tokens ?? 0, output: u.completion_tokens ?? 0 }\n }\n if (typeof u?.cost === 'number') out.cost = u.cost\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nfunction bridgeWorktreeExecutor(\n spec: AgentSpec,\n ctx: ExecutorContext,\n seam: CliWorktreeSeam,\n): Executor<WorktreeHarnessResult> {\n const bridge = seam.bridge\n if (!bridge) {\n throw new ValidationError('cliWorktreeExecutor: bridge transport missing')\n }\n if (!bridge.bridgeUrl || !bridge.bridgeBearer) {\n throw new ValidationError(\n 'cliWorktreeExecutor: bridge.bridgeUrl + bridge.bridgeBearer required',\n )\n }\n\n const runId = seam.runId ?? randomUUID()\n const sessionId = bridge.sessionId ?? `bridge-worktree-${runId}`\n const controller = new AbortController()\n const pending: unknown[] = []\n let inner: Executor<unknown> | undefined\n let worktree: WorktreeHandle | undefined\n let removed = false\n let artifact: ExecutorResult<WorktreeHarnessResult> | undefined\n\n const cleanupWorktree = async (): Promise<void> => {\n if (!worktree || removed) return\n const target = worktree\n removed = true\n worktree = undefined\n await removeWorktree({\n worktree: target,\n repoRoot: seam.repoRoot,\n ...(seam.runGit ? { runGit: seam.runGit } : {}),\n }).catch(() => undefined)\n }\n\n const deliver = (msg: unknown): void => {\n if (inner?.deliver) {\n inner.deliver(msg)\n return\n }\n pending.push(msg)\n }\n\n return {\n runtime: 'cli' as Runtime,\n budgetExempt: seam.budgetExempt ?? false,\n deliver,\n execute(_task, signal): AsyncIterable<UsageEvent> {\n return (async function* bridgeWorktreeStream() {\n const started = Date.now()\n const linked = mergeAbortSignals(signal, controller.signal)\n let bridgeArtifact: ExecutorResult<unknown> | undefined\n\n try {\n worktree = await createWorktree({\n repoRoot: seam.repoRoot,\n runId,\n ...(seam.baseRef ? { baseRef: seam.baseRef } : {}),\n ...(seam.runGit ? { runGit: seam.runGit } : {}),\n })\n removed = false\n\n const bridgeSeam: BridgeSeam = {\n bridgeUrl: bridge.bridgeUrl,\n bridgeBearer: bridge.bridgeBearer,\n model: resolveBridgeWorktreeModel(spec, bridge),\n cwd: worktree.path,\n sessionId,\n ...(bridge.agentProfile\n ? { agentProfile: bridge.agentProfile }\n : { agentProfile: spec.profile as unknown as Record<string, unknown> }),\n ...(bridge.timeoutMs !== undefined ? { timeoutMs: bridge.timeoutMs } : {}),\n ...(bridge.maxTurns !== undefined ? { maxTurns: bridge.maxTurns } : {}),\n }\n const bridgeCtx: ExecutorContext = {\n ...ctx,\n signal: linked,\n seams: { ...ctx.seams, [bridgeSeamKey]: bridgeSeam },\n }\n inner = bridgeExecutor(spec, bridgeCtx)\n for (const msg of pending.splice(0)) inner.deliver?.(msg)\n\n const run = inner.execute(seam.taskPrompt, linked)\n if (isAsyncIterable<UsageEvent>(run)) {\n for await (const event of run) yield event\n bridgeArtifact = inner.resultArtifact()\n } else {\n bridgeArtifact = await run\n }\n\n const diff = await captureWorktreeDiff({\n worktree,\n ...(seam.runGit ? { runGit: seam.runGit } : {}),\n })\n const checks = await runWorktreeChecks({\n worktreePath: worktree.path,\n ...(seam.testCmd !== undefined ? { testCmd: seam.testCmd } : {}),\n ...(seam.typecheckCmd !== undefined ? { typecheckCmd: seam.typecheckCmd } : {}),\n timeoutMs:\n seam.checkTimeoutMs ?? seam.harnessTimeoutMs ?? bridge.timeoutMs ?? 5 * 60 * 1000,\n cap: seam.checkOutputCap ?? 16_000,\n ...(seam.runCommand ? { runCommand: seam.runCommand } : {}),\n signal: linked,\n })\n\n const result: WorktreeHarnessResult = {\n branch: worktree.branch,\n patch: diff.patch,\n stats: diff.stats,\n harness: {\n name: 'bridge',\n exitCode: null,\n timedOut: false,\n killedBySignal: null,\n durationMs: bridgeArtifact.spent.ms || Date.now() - started,\n stdout: bridgeOutputText(bridgeArtifact.out),\n stderr: '',\n },\n ...(checks ? { checks } : {}),\n }\n const spent: Spend = {\n ...bridgeArtifact.spent,\n ms: bridgeArtifact.spent.ms || Date.now() - started,\n }\n artifact = {\n outRef: contentRef('bridge-worktree', { sessionId, result }),\n out: result,\n spent,\n }\n } catch (err) {\n controller.abort()\n await inner?.teardown('brutalKill').catch(() => undefined)\n await cleanupWorktree()\n throw err\n }\n })()\n },\n async teardown(grace): Promise<{ destroyed: boolean }> {\n controller.abort()\n let destroyed = true\n try {\n if (inner) {\n destroyed = (await inner.teardown(grace)).destroyed\n }\n } finally {\n await cleanupWorktree()\n }\n return { destroyed }\n },\n resultArtifact() {\n if (!artifact) {\n throw new ValidationError(\n 'cliWorktreeExecutor: bridge resultArtifact() read before stream drained',\n )\n }\n return artifact\n },\n }\n}\n\nfunction resolveBridgeWorktreeModel(spec: AgentSpec, bridge: CliWorktreeBridgeSeam): string {\n if (bridge.model) return bridge.model\n const model = spec.profile.model?.default\n if (typeof model === 'string' && model.length > 0) return model\n throw new ValidationError(\n 'cliWorktreeExecutor: bridge.model or AgentProfile.model.default required',\n )\n}\n\nfunction bridgeOutputText(out: unknown): string {\n if (typeof out === 'string') return out\n if (out && typeof out === 'object') {\n const content = (out as { content?: unknown }).content\n if (typeof content === 'string') return content\n }\n try {\n return JSON.stringify(out) ?? String(out)\n } catch {\n return String(out)\n }\n}\n\nfunction isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> {\n return (\n value !== null &&\n typeof value === 'object' &&\n typeof (value as { [Symbol.asyncIterator]?: unknown })[Symbol.asyncIterator] === 'function'\n )\n}\n\n// ── cli-worktree executor (authored profile → harness CLI on a git worktree) ────\n\n/**\n * The leaf `createWorktreeCliExecutor` as a backend-as-data factory: a supervisor-authored\n * `AgentProfile` driving claude / codex / opencode on its own worktree. `budgetExempt` like\n * the other CLI leaves; the authored systemPrompt + model reach the harness via §1.5.\n */\nexport const cliWorktreeExecutor: ExecutorFactory<unknown> = (spec, ctx) => {\n const seam = readSeam<CliWorktreeSeam>(ctx, cliWorktreeSeamKey, 'cli-worktree')\n if (!seam.repoRoot || !seam.taskPrompt) {\n throw new ValidationError('cliWorktreeExecutor: CliWorktreeSeam.repoRoot + taskPrompt required')\n }\n if (seam.bridge) return bridgeWorktreeExecutor(spec, ctx, seam)\n if (!seam.harness) {\n throw new ValidationError(\n 'cliWorktreeExecutor: CliWorktreeSeam.harness required when bridge is not set',\n )\n }\n return createWorktreeCliExecutor({\n repoRoot: seam.repoRoot,\n profile: spec.profile,\n harness: seam.harness,\n taskPrompt: seam.taskPrompt,\n ...(seam.runId ? { runId: seam.runId } : {}),\n ...(seam.baseRef ? { baseRef: seam.baseRef } : {}),\n ...(seam.harnessTimeoutMs !== undefined ? { harnessTimeoutMs: seam.harnessTimeoutMs } : {}),\n ...(seam.codexReproducible ? { codexReproducible: true } : {}),\n ...(seam.codexReadDeniedPaths ? { codexReadDeniedPaths: seam.codexReadDeniedPaths } : {}),\n ...(seam.testCmd !== undefined ? { testCmd: seam.testCmd } : {}),\n ...(seam.typecheckCmd !== undefined ? { typecheckCmd: seam.typecheckCmd } : {}),\n ...(seam.checkTimeoutMs !== undefined ? { checkTimeoutMs: seam.checkTimeoutMs } : {}),\n ...(seam.checkOutputCap !== undefined ? { checkOutputCap: seam.checkOutputCap } : {}),\n ...(seam.runGit ? { runGit: seam.runGit } : {}),\n ...(seam.runCommand ? { runCommand: seam.runCommand } : {}),\n ...(seam.budgetExempt !== undefined ? { budgetExempt: seam.budgetExempt } : {}),\n }) as Executor<unknown>\n}\n\n// ── createExecutor: the ONE built-in factory (backend as data) ──────────────────\n\n/**\n * Config for {@link createExecutor}: the backend is DATA — the cost dial a profile,\n * an experiment config, or a replay journal can name — not an import choice. Each\n * variant carries its backend's seam (router/router-tools/bridge/cli/cli-worktree/sandbox).\n */\nexport type ExecutorConfig =\n | ({ backend: 'router' } & RouterSeam)\n | ({ backend: 'router-tools' } & RouterToolsSeam)\n | ({ backend: 'bridge' } & BridgeSeam)\n | ({ backend: 'cli' } & CliSeam)\n | ({ backend: 'cli-worktree' } & CliWorktreeSeam)\n | ({ backend: 'provider' } & ProviderSeam)\n | ({ backend: 'pi' } & PiSeam)\n | ({ backend: 'sandbox'; harness?: BackendType } & SandboxSeam)\n\n/**\n * The single built-in executor factory. Picks a leaf backend by data (`config.backend`),\n * injects the matching seam, and delegates to that backend's built-in implementation.\n * The `Executor` port stays OPEN: bring-your-own agents implement `Executor` directly\n * and never pass through here. Use this (or `createExecutorRegistry`) instead of a\n * per-vendor adapter or a closed `inline|sandbox|cli` switch — those bypass the\n * `UsageEvent` reporting channel.\n */\nexport function createExecutor(config: ExecutorConfig): ExecutorFactory<unknown> {\n return (spec, ctx) => {\n const { backend, ...seam } = config as ExecutorConfig & Record<string, unknown>\n const seamed: ExecutorContext = { ...ctx, seams: { ...ctx.seams, [backend]: seam } }\n switch (config.backend) {\n case 'router':\n return routerInlineExecutor(spec, seamed)\n case 'router-tools':\n return routerToolsInlineExecutor(spec, seamed)\n case 'bridge':\n return bridgeExecutor(spec, seamed)\n case 'cli':\n return cliExecutor(spec, seamed)\n case 'cli-worktree':\n return cliWorktreeExecutor(spec, seamed)\n case 'pi':\n return piExecutor(spec, seamed)\n case 'provider': {\n const providerSeam = readSeam<ProviderSeam>(seamed, providerSeamKey, 'provider')\n const provider = resolveAgentEnvironmentProvider(\n providerSeam.provider,\n providerSeam.registry,\n )\n return providerAsExecutor(provider, providerSeam)(spec, seamed)\n }\n case 'sandbox': {\n // The sandbox executor requires a concrete harness; a spec-level harness\n // wins, else the config names it (fail-loud inside if both are absent).\n const harness = spec.harness ?? config.harness ?? null\n return sandboxExecutor({ ...spec, harness }, seamed)\n }\n }\n }\n}\n\n// ── The open registry ──────────────────────────────────────────────────────────\n\n/**\n * The open resolver/registry. Pre-registers the three built-ins under their\n * runtime tags (`'router'`, `'sandbox'`, `'cli'`) and accepts `register(name,\n * factory)` for any additional runtime — and a BYO `AgentSpec.executor` resolves\n * without touching the registry at all. NOT a closed switch; registration + BYO\n * ARE the extension points.\n *\n * `resolve` precedence (frozen in `ExecutorRegistry`): a BYO `spec.executor` →\n * `harness === null` → the `'router'` factory; else a registered factory for the\n * harness-derived runtime (`'sandbox'` for any `BackendType`); else fail loud.\n */\nexport function createExecutorRegistry(): ExecutorRegistry {\n const factories = new Map<Runtime, ExecutorFactory<unknown>>()\n factories.set('router', routerInlineExecutor)\n factories.set('inline', routerInlineExecutor)\n factories.set('sandbox', sandboxExecutor)\n factories.set('cli', cliExecutor)\n // pi is wrapped, not forked: `piExecutor` speaks pi's own out-of-process RPC protocol, so its\n // steering queue / session persistence / abort stay upstream's. Registered here through the\n // documented extension point so a spec can select it by `AgentSpec.executor` or by name.\n factories.set(PI_RUNTIME, piExecutor)\n\n return {\n register<Out>(runtime: Runtime, factory: ExecutorFactory<Out>): void {\n if (factories.has(runtime)) {\n throw new ValidationError(`executor registry: runtime \"${runtime}\" already registered`)\n }\n factories.set(runtime, factory as ExecutorFactory<unknown>)\n },\n resolve<Out>(\n spec: AgentSpec,\n ): { succeeded: true; value: ExecutorFactory<Out> } | { succeeded: false; error: string } {\n // BYO: a caller-supplied executor wins, wrapped in a trivial per-spawn factory.\n if (spec.executor) {\n const byo = spec.executor\n return { succeeded: true, value: (() => byo) as ExecutorFactory<Out> }\n }\n // router/inline: an agent with no harness is a direct Router call.\n if (spec.harness === null) {\n const f = factories.get('router')\n if (!f) return { succeeded: false, error: 'executor registry: no \"router\" factory' }\n return { succeeded: true, value: f as ExecutorFactory<Out> }\n }\n // sandbox: any BackendType maps to the sandbox-composing-runAgentRounds executor.\n const runtimeTag: Runtime = 'sandbox'\n const f = factories.get(runtimeTag)\n if (!f) {\n return {\n succeeded: false,\n error: `executor registry: no factory for runtime \"${runtimeTag}\" (harness \"${spec.harness}\") and no BYO executor`,\n }\n }\n return { succeeded: true, value: f as ExecutorFactory<Out> }\n },\n }\n}\n\n// ── Shared helpers ──────────────────────────────────────────────────────────────\n\n/** Narrow a named seam off the `ExecutorContext`, failing loud when absent — no\n * silent default for a required external-boundary seam. */\nfunction readSeam<T>(ctx: ExecutorContext, key: string, who: string): T {\n const seam = ctx.seams[key]\n if (seam === undefined || seam === null) {\n throw new ValidationError(`${who} executor: missing required seam \"${key}\" on ExecutorContext`)\n }\n return seam as T\n}\n\n/** A leaf task is opaque (`unknown`). A string is the prompt verbatim; an object\n * with a `prompt`/`content`/`task` string field uses it; otherwise it serializes. */\nfunction taskToPrompt(task: unknown): string {\n if (typeof task === 'string') return task\n if (task && typeof task === 'object') {\n const obj = task as Record<string, unknown>\n for (const k of ['prompt', 'content', 'task', 'message']) {\n if (typeof obj[k] === 'string') return obj[k] as string\n }\n }\n return JSON.stringify(task)\n}\n\n/** Router messages from the opaque task + the profile's system prompt, when set. */\nfunction taskToMessages(task: unknown, spec: AgentSpec): Array<{ role: string; content: string }> {\n const messages: Array<{ role: string; content: string }> = []\n const system = spec.profile.prompt?.systemPrompt\n if (typeof system === 'string' && system.length > 0) {\n messages.push({ role: 'system', content: system })\n }\n messages.push({ role: 'user', content: taskToPrompt(task) })\n return messages\n}\n\n/** A driver that refines a single task up to `maxIterations` times then stops —\n * the minimal policy that lets the sandbox executor run `runAgentRounds` as one leaf. */\nfunction singleShotDriver<Out>(maxIterations: number): Driver<unknown, Out, string> {\n return {\n name: 'leaf',\n plan(task, history): Promise<unknown[]> {\n return Promise.resolve(history.length >= maxIterations ? [] : [task])\n },\n decide(history: ReadonlyArray<Iteration<unknown, Out>>): string {\n return history.length >= maxIterations ? 'stop' : 'continue'\n },\n }\n}\n\n/** Link two abort signals into one that fires when either does. Returns\n * `undefined` when neither is present so `fetch` gets no signal at all. */\nfunction linkSignals(a: AbortSignal, b: AbortSignal): AbortSignal | undefined {\n if (a.aborted || b.aborted) {\n const c = new AbortController()\n c.abort()\n return c.signal\n }\n const c = new AbortController()\n const onAbort = () => c.abort()\n a.addEventListener('abort', onAbort, { once: true })\n b.addEventListener('abort', onAbort, { once: true })\n return c.signal\n}\n\n/** Combine N abort signals into one that fires when ANY does. Node-portable (no `AbortSignal.any`,\n * which needs >=20.3 — the package floor is >=20). */\nfunction mergeAbortSignals(...signals: AbortSignal[]): AbortSignal {\n const c = new AbortController()\n const onAbort = () => c.abort()\n for (const s of signals) {\n if (s.aborted) {\n c.abort()\n break\n }\n s.addEventListener('abort', onAbort, { once: true })\n }\n return c.signal\n}\n\n// Re-export the verdict + spend surface so a consumer importing the runtime\n// built-ins gets the budget vocabulary from one place.\nexport type { DefaultVerdict, Executor, ExecutorResult, Spend, UsageEvent }\n","/**\n *\n * `createInMemoryRunContext` — the one-call bundle of the in-memory stores a\n * `createSupervisor().run(root, task, opts)` needs: a fresh `InMemorySpawnJournal`\n * (the event-sourced spawn log), a fresh `InMemoryResultBlobStore` (the\n * content-addressed `outRef` payload store the driver's `observe`/`finalize` reads\n * settled outputs through), and a fresh `createExecutorRegistry()` (the open\n * `AgentSpec → Executor` resolver).\n *\n * It exists to kill the boilerplate every offline/local supervised run repeats by\n * hand — three constructors threaded into `SupervisorOpts` — and to single-source the\n * ONE wiring invariant that is easy to get wrong: when the root is the recursive\n * `driverAgent` LLM-driver brain AND it may spawn DRIVER children (agents\n * driving agents), the registry MUST be wrapped with `withDriverExecutor` so a\n * `role: 'driver'` child resolves to the nested-scope executor — and that SAME blob\n * store MUST be the one passed to `driverAgent({ blobs })`, or the driver\n * reads from a different store than the scope writes to. Pass `{ withDriver: true }`\n * and reuse the returned `blobs` for both.\n *\n * The spread shape matches `SupervisorOpts` exactly, so the call site reads:\n * const run = createInMemoryRunContext()\n * await createSupervisor().run(root, task, { budget, runId, ...run })\n *\n * @experimental\n */\n\nimport {\n FileResultBlobStore,\n FileSpawnJournal,\n InMemoryResultBlobStore,\n InMemorySpawnJournal,\n} from '../../durable/spawn-journal'\nimport { type CoordinationLog, FileCoordinationLog } from './coordination-log'\nimport { withDriverExecutor } from './driver-executor'\nimport { createExecutorRegistry } from './runtime'\nimport type { ExecutorRegistry, ResultBlobStore, SpawnJournal } from './types'\n\n/** Options for a supervised run context. */\nexport interface InMemoryRunContextOptions {\n /**\n * Wrap the executor registry with `withDriverExecutor` so a spawned child marked\n * `role: 'driver'` resolves to the recursive driver-executor (agents driving agents\n * over a nested `Scope` on the same conserved pool). Leave `false` for a flat tree of\n * leaf workers. Default `false`.\n */\n readonly withDriver?: boolean\n}\n\n/**\n * The bundle of stores a supervised run needs, shaped to spread into `SupervisorOpts`.\n * The fields are exactly `SupervisorOpts`' `journal` / `blobs` / `executors`.\n */\nexport interface InMemoryRunContext {\n readonly journal: SpawnJournal\n readonly blobs: ResultBlobStore\n readonly executors: ExecutorRegistry\n /**\n * Present (and `true`) only on a DURABLE context (`createFileRunContext`), so spreading the\n * context into `SupervisorOpts` also opts the run into resume-first. An in-memory context\n * leaves it undefined: there is never a prior tree to resume, and the default stays fresh-run.\n */\n readonly resume?: boolean\n /**\n * Present only on a DURABLE context: the coordination side-log (questions + analyst findings —\n * the bus messages the spawn journal does not record). `supervise({ runDir })` appends to it as\n * they publish and replays it on resume, so a restarted coordinator keeps them. In-memory\n * contexts have none: nothing outlives the process to replay into.\n */\n readonly coordinationLog?: CoordinationLog\n}\n\n/** The stores a supervised run needs, in-memory or file-backed. `InMemoryRunContext` is the\n * historical name for the same shape. */\nexport type RunContext = InMemoryRunContext\n\n/**\n * Build a fresh in-memory run context. Every call returns NEW stores (no shared global\n * state between runs), so two runs never cross-contaminate their journals/blobs.\n */\nexport function createInMemoryRunContext(opts: InMemoryRunContextOptions = {}): InMemoryRunContext {\n const base = createExecutorRegistry()\n return {\n journal: new InMemorySpawnJournal(),\n blobs: new InMemoryResultBlobStore(),\n executors: opts.withDriver ? withDriverExecutor(base) : base,\n }\n}\n\n/**\n * Build a DURABLE run context: the spawn journal and the result blobs are file-backed (fsynced\n * per append/write) under `dir`, and the context carries `resume: true` so spreading it into\n * `SupervisorOpts` makes the supervisor `loadTree`-first. A run that dies mid-flight therefore\n * resumes when it is re-run with the SAME `runId` and the SAME `dir`: the committed children come\n * back on `Scope.resume` (rehydrated by `replaySpawnTree`) instead of being re-executed.\n *\n * Layout: `${dir}/spawn-journal.jsonl` (one JSONL record per event), `${dir}/blobs/` (one\n * content-addressed JSON file per settled result), and `${dir}/coordination-log.jsonl` (questions\n * + findings, replayed into a resumed driver). The directory is created on first write.\n *\n * Opt-in by construction — `createInMemoryRunContext()` is unchanged and stays the default, so no\n * existing consumer writes to disk or resumes unless it asks for this.\n */\nexport function createFileRunContext(\n dir: string,\n opts: InMemoryRunContextOptions = {},\n): RunContext {\n const base = createExecutorRegistry()\n return {\n journal: new FileSpawnJournal(`${dir}/spawn-journal.jsonl`),\n blobs: new FileResultBlobStore(`${dir}/blobs`),\n executors: opts.withDriver ? withDriverExecutor(base) : base,\n resume: true,\n coordinationLog: new FileCoordinationLog(`${dir}/coordination-log.jsonl`),\n }\n}\n","/**\n *\n * The ONLINE analyst: watch a `TraceSource` and fold each tool span through agent-eval's published\n * streaming detector kernel (`repeatedActionDetector`/`errorStreakDetector` — the SAME kernel the\n * control loop folds), firing `onSignal` the moment a worker loops or error-storms. Substrate-\n * agnostic: it consumes spans from any source (owned router/bridge loop OR a sandbox box session),\n * never the raw tool seam. Detection logic + the failure taxonomy live in agent-eval; not reimplemented.\n *\n * @experimental\n */\n\nimport {\n argHash,\n type DetectorSignal,\n errorStreakDetector,\n observeAll,\n repeatedActionDetector,\n type StreamingDetector,\n type ToolSpan,\n} from '@tangle-network/agent-eval'\nimport type { TraceSource } from './trace-source'\n\nexport interface WatchTraceOptions {\n /** The detectors to run online. Defaults to a stuck-loop + error-streak panel. */\n readonly detectors?: ReadonlyArray<StreamingDetector>\n /** Fired for each signal a detector raises — the seam that raises a `finding` on the bus. */\n readonly onSignal?: (signal: DetectorSignal, span: ToolSpan) => void | Promise<void>\n}\n\n/** The default online panel for a tool-call pipe: a worker repeating the same call, or hammering\n * consecutive errors. (No-progress needs a domain progress-probe, so it is opt-in, not default.)\n *\n * Coverage note: `repeated-action` works for EVERY harness (it needs only tool name + args, which\n * every adapter provides). `error-streak` needs per-call status — opencode carries it inline\n * (`state.status`, VALIDATED live), but claude-code/codex tool-call parts do NOT (their errors live\n * in separate result blocks not yet decoded), so error-streak is silent for those until result-block\n * decoding is added + live-validated. It is in the panel because it is correct where status exists. */\nexport function defaultToolDetectors(): StreamingDetector[] {\n return [repeatedActionDetector({ maxRepeated: 3 }), errorStreakDetector({ maxErrors: 3 })]\n}\n\n/** Subscribe to a `TraceSource` and run the streaming detectors over its live spans. Returns an\n * unsubscribe. A defensive `argHash` failure (circular args) never throws out of the side-channel. */\nexport function watchTrace(source: TraceSource, opts: WatchTraceOptions = {}): () => void {\n const detectors = opts.detectors ?? defaultToolDetectors()\n return source.onSpan((span) => {\n let fingerprint: string\n try {\n // Same fingerprint scheme as agent-eval's batch stuck-loop view: tool name + hashed args.\n fingerprint = `${span.toolName}|${argHash(span.args)}`\n } catch {\n fingerprint = `${span.toolName}|<unhashable>`\n }\n const signals = observeAll(detectors, {\n actionFingerprint: fingerprint,\n ...(span.status ? { status: span.status } : {}),\n label: span.toolName,\n })\n for (const s of signals) void opts.onSignal?.(s, span)\n })\n}\n","/**\n *\n * `rollingDispatch` — the REFILLING dispatch policy over a `Scope`. It keeps `width` children in\n * flight and admits the next queued unit of work the instant one settles, instead of waiting for\n * a whole round to drain (`fanout`) or for a driver to decide again (`spawn → await → spawn`).\n *\n * The gap it closes: `fanout` opens every item at once and then drains — one round, no refill —\n * and a driver brain's manual loop opens one worker per model turn. Between those two there was\n * nothing that holds N slots full, which is why a 5-worker run can peak at 2 live workers and sit\n * ~50% idle. This is a policy over the EXISTING `Scope.spawn` / `Scope.next` primitives: it adds\n * no second admission path, so the conserved budget pool stays the only fence on total work and\n * `width` is only a fence on simultaneous work.\n *\n * Fail-closed by construction: an admission rejection (`budget-exhausted` / `depth-exceeded`) is\n * recorded and STOPS further admission — the loop then drains what is already live and returns.\n * It never retries a rejected spawn against the same pool, and it never spawns past `width`.\n *\n * ── The concurrency-cap ledger (read this before adding a fourth cap) ──────────────────────────\n *\n * Three unrelated caps bound \"how much runs at once\" in this stack, at three different layers.\n * They are NOT aware of each other, and the smallest one silently wins:\n *\n * 1. `CoordinationToolsOptions.maxLiveWorkers` (`src/mcp/tools/coordination.ts`) — supervisor\n * level. How many workers may be spawned-but-not-settled at once; `spawn_agent` fails closed\n * with `error: 'max-live-workers'` past it. Unset by default ⇒ NO cap at this layer.\n * 2. `SandboxLineage`'s `maxConcurrency` / `DEFAULT_FORK_CONCURRENCY = 4`\n * (`src/runtime/sandbox-lineage.ts`) — kernel level. How many BOXES one `runAgentRounds` fork wave\n * provisions at once. It bounds a single leaf's fanout, not the supervisor's worker count.\n * 3. A host's own live-box governor (e.g. the kernel's `ComputeGovernor`, `maxSandboxes = 4`) — fleet\n * level. How many sandboxes may exist across the whole host process.\n *\n * The honest effective limit on simultaneous WORKERS is the minimum of the caps that apply to the\n * worker layer — (1) and (3). (2) is a different unit (boxes per fork wave inside one leaf) and\n * must not be min'd into it, or a 4-way fork inside one worker reads as a 4-worker ceiling.\n * `effectiveConcurrency` computes that minimum in one place so a host derives ONE number and\n * passes it to BOTH `maxLiveWorkers` and this dispatcher's `width`, instead of leaving a fleet\n * governor of 4 and an unset worker fence as unrelated numbers.\n *\n * ── Why this is not a copy of the kernel's batch loop ──────────────────────────────────────────\n *\n * `runBatch` (`src/runtime/run-loop.ts`) runs the same hold-N-slots-full shape over the KERNEL's\n * substrate: bare promises in a `Set`, raced with `Promise.race`, bounded by `maxConcurrency`.\n * This one runs it over the SUPERVISOR's substrate — `Scope.spawn`'s atomic reservation against\n * the conserved pool, `Scope.next`'s journaled settlement cursor, and the blob store behind each\n * result. Neither can be expressed in the other's terms without dragging its whole substrate\n * along: the kernel loop has no budget to reserve and no cursor to order settlements by, and this\n * one cannot race raw promises because a settlement is only real once it is journaled. The shape\n * repeating across the two deliberate layers is resonance, not duplication — do not \"unify\" them\n * into a shared helper that would have to know about both.\n *\n * @experimental\n */\n\nimport { ValidationError } from '../../errors'\nimport type { Agent, Budget, NodeId, Scope, Settled, SpawnOpts } from './types'\n\n/** One unit of queued work: the agent to run, its task, and the spawn options (budget + label).\n * `nextUnit` mints these lazily so a queue can be generated, re-ordered, or grown while the\n * dispatcher runs. */\nexport interface DispatchUnit<Out> {\n readonly agent: Agent<unknown, Out>\n readonly task: unknown\n readonly opts: SpawnOpts\n}\n\n/** Why the dispatcher stopped admitting work. `drained` = the queue ran dry (the ordinary end);\n * `not-admitted` = the conserved pool or the depth ceiling refused a spawn; `stopped` = the\n * caller's `shouldStop` returned true; `aborted` = the scope's signal fired. */\nexport type DispatchStopReason = 'drained' | 'not-admitted' | 'stopped' | 'aborted'\n\nexport interface RollingDispatchOptions<Out> {\n /**\n * How many children to hold in flight. Must be a positive integer. This is a SIMULTANEITY fence\n * only — the conserved pool still bounds total work, and a `width` larger than the pool can\n * afford simply hits `not-admitted` sooner. Derive it with `effectiveConcurrency` when the host\n * also runs a fleet-level box governor.\n */\n readonly width: number\n /**\n * Produce the next unit of work, or `undefined` when the queue is dry. Called only when a slot\n * is free, so a caller may compute the next unit from what has already settled (the point of a\n * refilling dispatcher: the queue is allowed to react). Never called after a stop.\n */\n nextUnit(): DispatchUnit<Out> | undefined | Promise<DispatchUnit<Out> | undefined>\n /**\n * Called once per settlement, in cursor order, BEFORE the freed slot is refilled — so an\n * `onSettled` that appends to the caller's queue is visible to the very next `nextUnit`.\n */\n onSettled?(settled: Settled<Out>): void | Promise<void>\n /**\n * Consulted before each admission. `true` stops admitting; the already-live children are still\n * drained to completion (no orphan, no lost settlement). Use it for a progress/plateau rule.\n */\n shouldStop?(): boolean\n}\n\nexport interface DispatchReport<Out> {\n /** Every settlement, in the order `scope.next()` yielded them. */\n readonly settled: ReadonlyArray<Settled<Out>>\n /** How many children this dispatcher admitted. */\n readonly admitted: number\n /** Admission rejections, in order — `label: reason`. Non-empty ⇒ the pool or depth fenced. */\n readonly rejected: ReadonlyArray<string>\n readonly stopReason: DispatchStopReason\n /** The highest simultaneous live count actually reached — the number to compare against\n * `width` when asking \"did the slots really stay full?\" */\n readonly peakLive: number\n}\n\n/**\n * Run the refilling dispatch loop over `scope` until the queue is dry (or a stop fires) and every\n * admitted child has settled. Returns the settlements in cursor order plus the admission ledger.\n *\n * The loop is: fill free slots from `nextUnit` → `await scope.next()` → deliver the settlement →\n * refill → repeat. Because the refill happens immediately after each settlement rather than after\n * a whole round, a slow child never idles the other slots.\n */\nexport async function rollingDispatch<Out>(\n scope: Scope<Out>,\n opts: RollingDispatchOptions<Out>,\n): Promise<DispatchReport<Out>> {\n if (!Number.isInteger(opts.width) || opts.width < 1) {\n throw new ValidationError(\n `rollingDispatch: width must be a positive integer, got ${String(opts.width)}`,\n )\n }\n\n const settled: Settled<Out>[] = []\n const rejected: string[] = []\n const live = new Set<NodeId>()\n let admitted = 0\n let peakLive = 0\n let queueDry = false\n let stopReason: DispatchStopReason = 'drained'\n\n // Fill every free slot from the queue. Returns false when nothing further may be admitted\n // (queue dry, caller stop, pool/depth rejection, or abort) — the caller then only drains.\n const fill = async (): Promise<void> => {\n while (live.size < opts.width) {\n if (queueDry) return\n if (scope.signal.aborted) {\n stopReason = 'aborted'\n queueDry = true\n return\n }\n if (opts.shouldStop?.() === true) {\n stopReason = 'stopped'\n queueDry = true\n return\n }\n const unit = await opts.nextUnit()\n if (unit === undefined) {\n queueDry = true\n return\n }\n // The ONE admission path: the scope's own atomic reservation. A rejection is terminal for\n // this dispatcher — the pool is conserved, so retrying the same spawn cannot succeed until\n // a live child refunds, and admitting a DIFFERENT unit past a rejection would silently\n // reorder the caller's queue.\n const res = scope.spawn(unit.agent, unit.task, unit.opts)\n if (!res.ok) {\n rejected.push(`${unit.opts.label}: ${res.reason}`)\n stopReason = 'not-admitted'\n queueDry = true\n return\n }\n live.add(res.handle.id)\n admitted += 1\n if (live.size > peakLive) peakLive = live.size\n }\n }\n\n await fill()\n while (live.size > 0) {\n const s = await scope.next()\n // `next()` is null only when the scope's live set is empty; this dispatcher may share the\n // scope with children it did not admit, so treat null as \"nothing of ours left to await\".\n if (s === null) break\n live.delete(s.handle.id)\n settled.push(s)\n await opts.onSettled?.(s)\n await fill()\n }\n\n return { settled, admitted, rejected, stopReason, peakLive }\n}\n\n/**\n * Free worker slots under a simultaneity cap: `cap - live`, floored at 0, or `null` when there is\n * no cap (the conserved pool is then the only fence and \"free slots\" is not a finite number).\n * The one place the answer is computed, so the driver-facing tool payload and a dispatcher agree.\n */\nexport function freeSlots(liveCount: number, cap: number | undefined): number | null {\n if (cap === undefined || cap <= 0) return null\n return Math.max(0, cap - liveCount)\n}\n\n/** The caps a host can set on simultaneous work. See the ledger in this module's header for what\n * each one actually bounds. */\nexport interface ConcurrencyCaps {\n /** Supervisor level: max spawned-but-unsettled workers. */\n readonly maxLiveWorkers?: number\n /** Fleet level: max live sandboxes/boxes across the host process (a `ComputeGovernor`-style\n * cap). Applies to the worker layer, so it participates in the minimum. */\n readonly maxSandboxes?: number\n}\n\n/**\n * The ONE honest effective limit on simultaneous workers: the minimum of the caps that actually\n * bound the worker layer. Ignores unset/non-positive caps; returns `undefined` when no cap applies\n * (uncapped — the conserved pool remains the only fence).\n *\n * Deliberately does NOT fold in `SandboxLineage`'s fork concurrency: that bounds boxes inside ONE\n * leaf's fork wave, a different unit. Folding it in would report a 4-worker ceiling for what is\n * really a 4-box fanout inside a single worker.\n *\n * Use it once, at the top of a run, and pass the result to BOTH `maxLiveWorkers` and a\n * dispatcher's `width` — that is what turns three unrelated numbers into one.\n */\nexport function effectiveConcurrency(caps: ConcurrencyCaps): number | undefined {\n const applicable = [caps.maxLiveWorkers, caps.maxSandboxes].filter(\n (c): c is number => typeof c === 'number' && c > 0,\n )\n if (applicable.length === 0) return undefined\n return Math.min(...applicable)\n}\n\n/** Convenience: a `DispatchUnit` factory over a fixed array of tasks, for the common case where\n * the queue is known up front and only the refill behavior is wanted. */\nexport function queueOf<Out>(\n units: ReadonlyArray<{ agent: Agent<unknown, Out>; task: unknown; label: string }>,\n budget: Budget,\n): () => DispatchUnit<Out> | undefined {\n let i = 0\n return () => {\n const u = units[i]\n if (u === undefined) return undefined\n i += 1\n return { agent: u.agent, task: u.task, opts: { budget, label: u.label } }\n }\n}\n","/**\n *\n * The child→parent message bus: the ONE pipe carrying every message a worker, sub-driver, or\n * analyst sends up to the driver — settled outputs, questions, and trace-analyst findings. It\n * unifies channels that were ad-hoc before (the settled-worker cursor, the ask-parent question\n * channel, and analyst results) into a single typed primitive with two lanes:\n *\n * - PASS-THROUGH (`subscribe`): every published event reaches subscribers immediately — the\n * express lane for online steering and live observation (a UI, a hook, the parent's box).\n * - STANDBY (`pull`): events also queue so the driver consumes them on its own cadence. The queue\n * is PRIORITY-ordered: a higher-`priority` event (a blocking question) is bumped ahead of\n * queued settles/findings so the driver sees it first; ties resolve FIFO by publish order.\n *\n * Observability is first-class (A++): every event is stamped with a monotonic `seq` and wall-clock\n * `at`, the full ordered `history()` is retained as an audit/replay trail, and `stats()` exposes\n * published/pulled counts by kind. Subscribers receive the stamped record, not a bare event.\n *\n * The interface is transport-agnostic on purpose. Same box → this in-process queue. Cross box →\n * the SAME publish/pull/subscribe surface backed by a durable mailbox on the parent's box (children\n * POST events with at-least-once retry; payloads are blob refs so the event stays small). Consumers\n * depend only on this interface, so distribution is a transport swap, never an architecture change.\n *\n * @experimental\n */\n\n/** Every bus event is a discriminated union member keyed by `type`. */\nexport interface BusEvent {\n readonly type: string\n}\n\n/** A published event stamped for ordering and observability. `seq` is the monotonic publish index;\n * `priority` drives pull order (higher = bumped ahead); `at` is the wall-clock publish time (ms). */\nexport interface BusRecord<E extends BusEvent> {\n readonly seq: number\n readonly at: number\n readonly priority: number\n readonly event: E\n}\n\nexport interface PublishOptions {\n /** Higher = pulled ahead of lower-priority queued events (default 0). A blocking question sets\n * this so it bumps to the front of the driver's inbox. */\n readonly priority?: number\n /** Whether the event enters the pull queue (default true). Set `false` for record-only events —\n * the parent→child down-leg (steer / answer / resume): they belong in `history()` and reach\n * `subscribe` observers, but the parent must never `pull` its own outbound message back. */\n readonly queue?: boolean\n}\n\nexport interface BusStats {\n readonly published: number\n readonly pulled: number\n /** Count published per event `type`. */\n readonly byKind: Readonly<Record<string, number>>\n}\n\nexport interface EventBus<E extends BusEvent> {\n /** Stamp + queue the event, then deliver the stamped record to every subscriber in order.\n * Returns the stamped record. */\n publish(event: E, opts?: PublishOptions): Promise<BusRecord<E>>\n /** Remove and return the highest-priority QUEUED event whose type is in `kinds` (any if omitted),\n * ties broken FIFO by `seq`; `undefined` when nothing matches. */\n pull(kinds?: ReadonlyArray<E['type']>): E | undefined\n /** Register a pass-through handler; it receives the stamped record of every event published after\n * registration. Returns an unsubscribe fn. */\n subscribe(handler: (record: BusRecord<E>) => void | Promise<void>): () => void\n /** Count of queued, not-yet-pulled events (filtered by `kinds` when given). */\n pending(kinds?: ReadonlyArray<E['type']>): number\n /** The full ordered log of every event ever published (the audit/replay trail). */\n history(): ReadonlyArray<BusRecord<E>>\n /** Throughput counters for observability dashboards. */\n stats(): BusStats\n}\n\n/** Create the child→parent coordination bus: one typed pipe for settled outputs, questions, and analyst findings, with a priority-ordered pull queue and a pass-through subscribe lane. */\nexport function createEventBus<E extends BusEvent>(now: () => number = Date.now): EventBus<E> {\n const queue: BusRecord<E>[] = []\n const log: BusRecord<E>[] = []\n const subscribers: Array<(record: BusRecord<E>) => void | Promise<void>> = []\n const byKind: Record<string, number> = {}\n let seq = 0\n let pulled = 0\n\n const matches = (r: BusRecord<E>, kinds?: ReadonlyArray<E['type']>) =>\n !kinds || kinds.includes(r.event.type)\n\n // Index of the highest-priority matching record; ties resolve to the earliest `seq` (the queue is\n // maintained in publish order, so the first scan hit at the max priority is the oldest).\n const bestIndex = (kinds?: ReadonlyArray<E['type']>): number => {\n let best = -1\n let bestPriority = Number.NEGATIVE_INFINITY\n for (let i = 0; i < queue.length; i++) {\n const r = queue[i]\n if (!r || !matches(r, kinds)) continue\n if (r.priority > bestPriority) {\n best = i\n bestPriority = r.priority\n }\n }\n return best\n }\n\n return {\n async publish(event, opts) {\n const record: BusRecord<E> = { seq: seq++, at: now(), priority: opts?.priority ?? 0, event }\n // Record-only events (the down-leg) skip the pull queue but still hit the log + subscribers.\n if (opts?.queue !== false) queue.push(record)\n log.push(record)\n byKind[event.type] = (byKind[event.type] ?? 0) + 1\n // Sequential, not Promise.all: a subscriber that steers off this event must observe a\n // consistent order, and a throwing subscriber must not silently drop siblings' delivery.\n for (const handler of subscribers) await handler(record)\n return record\n },\n pull(kinds) {\n const i = bestIndex(kinds)\n if (i < 0) return undefined\n pulled++\n return queue.splice(i, 1)[0]?.event\n },\n subscribe(handler) {\n subscribers.push(handler)\n return () => {\n const i = subscribers.indexOf(handler)\n if (i >= 0) subscribers.splice(i, 1)\n }\n },\n pending(kinds) {\n return kinds ? queue.filter((r) => matches(r, kinds)).length : queue.length\n },\n history() {\n return log\n },\n stats() {\n return { published: seq, pulled, byKind: { ...byKind } }\n },\n }\n}\n","/**\n *\n * MCP binding for a live `Scope`. A sandbox driver gets the same small verbs\n * the in-process driver has: spawn, observe, await, steer, ask/answer, analyze,\n * and stop. Settled outputs remain Scope artifacts; product code can project\n * them into any UI/report envelope it needs.\n *\n * @experimental\n */\n\nimport { agentProfileSchema } from '@tangle-network/agent-interface'\nimport type {\n Budget,\n ResultBlobStore,\n Scope,\n Settled,\n Agent as SuperviseAgent,\n} from '../../runtime'\nimport type { DeliverableSpec } from '../../runtime/supervise/completion-gate'\nimport { type WatchTraceOptions, watchTrace } from '../../runtime/supervise/detector-monitor'\nimport { freeSlots } from '../../runtime/supervise/dispatch'\nimport { type BusRecord, type BusStats, createEventBus } from '../../runtime/supervise/event-bus'\nimport type { WorkerProgress } from '../../runtime/supervise/progress'\nimport type { McpToolDescriptor } from '../server'\n\n/** A worker the driver has drained via `await_event`. */\nexport interface SettledWorker {\n readonly id: string\n readonly status: 'done' | 'down'\n readonly score?: number\n readonly valid?: boolean\n readonly outRef?: string\n readonly reason?: string\n /** Epoch ms the ledger recorded this settlement — the resolution a progress-based stop rule\n * needs to answer \"how long since anything landed?\" without inventing a timestamp at read\n * time. Stamped when the cursor yields the settlement, not when a reader first looks. */\n readonly settledAt?: number\n}\n\nexport type QuestionLevel = 'worker' | 'driver' | 'loop'\nexport type QuestionUrgency = 'continue-without' | 'blocks-step' | 'blocks-run'\n\nexport interface QuestionOption {\n readonly label: string\n readonly tradeoff: string\n}\n\nexport interface Question {\n readonly id: string\n readonly from: string\n readonly level: QuestionLevel\n readonly question: string\n readonly reason: string\n readonly urgency: QuestionUrgency\n readonly options?: ReadonlyArray<QuestionOption>\n}\n\nexport type QuestionDecision =\n | { readonly kind: 'answer'; readonly answer: string; readonly by: string }\n | { readonly kind: 'defer'; readonly reason: string }\n | { readonly kind: 'escalate'; readonly to: 'parent' | 'user' | string; readonly reason: string }\n\nexport interface QuestionRecord extends Question {\n readonly status: 'open' | 'answered' | 'deferred' | 'escalated'\n readonly decision?: QuestionDecision\n readonly openedAt: number\n}\n\ntype QuestionInput = Omit<Question, 'id'> & { readonly id?: string }\nexport type QuestionPolicy = 'auto' | 'mustDecide' | 'bubble' | 'failClosed'\n\nexport interface AnalystRegistry {\n readonly kinds: ReadonlyArray<{ id: string; description: string; area: string }>\n readonly run: (kindId: string, trace: unknown) => Promise<unknown>\n}\n\n/** A trace-analyst result re-entered as a message on the bus (the `finding` event kind). */\nexport interface AnalystFindingEvent {\n readonly fromWorker: string\n readonly analyst: string\n readonly findings: unknown\n}\n\n/** A parent→child message (the down-leg): recorded for observability, delivered via the child inbox,\n * never pulled back by the parent. `delivered` mirrors whether the live child accepted it. */\nexport interface DownMessageEvent {\n readonly toWorker: string\n readonly instruction: string\n readonly delivered: boolean\n}\n\n/** Every message on the one typed pipe. UP (child→parent): question / settled / finding — queued for\n * the driver to `pull`. DOWN (parent→child): steer / answer — record-only (history + subscribers),\n * routed to the child inbox. New kinds are additive. */\nexport type CoordinationEvent =\n | { readonly type: 'question'; readonly question: QuestionRecord }\n | { readonly type: 'settled'; readonly worker: SettledWorker }\n | { readonly type: 'finding'; readonly finding: AnalystFindingEvent }\n | { readonly type: 'steer'; readonly down: DownMessageEvent }\n | { readonly type: 'answer'; readonly down: DownMessageEvent; readonly questionId: string }\n\nexport type MakeWorkerAgent = (profile: unknown) => SuperviseAgent<unknown, unknown>\n\nexport interface CoordinationToolsOptions {\n readonly scope: Scope<unknown>\n readonly blobs: ResultBlobStore\n readonly makeWorkerAgent: MakeWorkerAgent\n readonly perWorker: Budget\n /**\n * The same independent completion check used for workers. When present, the driver receives a\n * `submit_result` tool and may finish work itself instead of being forced to delegate it. The\n * first passing submission is retained; a false or throwing check fails closed.\n */\n readonly deliverable?: DeliverableSpec<unknown>\n readonly analysts?: AnalystRegistry\n readonly onEvent?: (event: CoordinationEvent) => void | Promise<void>\n readonly questionPolicy?: QuestionPolicy\n /** Analyst kind ids to run AUTOMATICALLY when a worker settles `done` (the analyst-on-settle\n * hook). Each result is published as a `finding` event on the bus — pass-through to subscribers\n * and queued for the driver to pull via `await_event`. Omit/empty = no auto-analysis (default;\n * the driver can still run lenses on demand via `run_analyst`). Requires `analysts`. */\n readonly analyzeOnSettle?: ReadonlyArray<string>\n /** Hard cap on how many workers may be LIVE (spawned but not yet settled) at once. `spawn_agent`\n * counts the scope's non-terminal nodes and fails closed (`error: 'max-live-workers'`) BEFORE\n * reserving from the pool when the cap is already met — a concurrency fence on top of the\n * conserved-budget fence (the pool bounds total work; this bounds simultaneous work, e.g. live\n * sandboxes/boxes). Omit or `<= 0` = no cap (the prior behavior; the pool stays the only fence). */\n readonly maxLiveWorkers?: number\n /** Max wall-clock ms a single `await_event` call may block waiting on a live worker to settle\n * before it returns a non-error `{ pending: true, live }` snapshot and lets the caller re-poll.\n * The underlying `scope.next()` blocks for the WHOLE (multi-minute) worker run; over a remote MCP\n * transport that block outlives the client's per-request timeout, so an unbounded await surfaces\n * to the supervisor as a hard tool ERROR on every call — the exact failure that leaves it flying\n * blind. Bounding the wait converts that error into a re-pollable liveness signal. The background\n * drain keeps running, so a settlement that lands after the bound is published to the bus and\n * pulled by the next call — nothing is lost. Omit = {@link DEFAULT_AWAIT_EVENT_TIMEOUT_MS}; `<= 0`\n * restores the prior UNBOUNDED block (only safe for in-process drivers with no transport timeout). */\n readonly awaitTimeoutMs?: number\n /**\n * OPT-IN: run the ONLINE detector panel over each spawned worker's live tool trace and raise a\n * `finding` on the bus the moment a detector fires — so the driver learns \"this worker is\n * looping\" mid-run, from `await_event`, instead of at settle.\n *\n * This closes the `watchTrace` → `raiseFinding` wire whose own docstring already described it\n * (\"the seam an ONLINE detector uses to tell the driver 'this worker is looping/erroring' the\n * moment it happens\") but which nothing connected. Workers whose executor exposes no\n * `traceSource` are simply not watched; nothing fails.\n *\n * Omit = no online watching (the settle-time analysts are unaffected).\n */\n readonly watchWorkers?: WorkerWatchOptions\n /**\n * How long a worker may go without metered activity before `observe_agent` reports it as\n * `stalled`. A derived read at observation time, never a background watchdog — nothing is\n * killed or retried. Omit = the runtime default.\n */\n readonly stallAfterMs?: number\n /**\n * Questions carried over from a prior process of the SAME run (a durable coordination log a\n * resuming caller replays). Seeded into the question ledger verbatim — `list_questions` shows\n * them, the stop policy counts the still-blocking ones, and `answer_question` can decide them.\n * Omit/empty = fresh ledger (every run that is not a resume).\n */\n readonly priorQuestions?: ReadonlyArray<QuestionRecord>\n}\n\n/** Online-detector wiring for spawned workers (`CoordinationToolsOptions.watchWorkers`). */\nexport interface WorkerWatchOptions {\n /** Detector panel; omit for the default stuck-loop + error-streak pair. */\n readonly detectors?: WatchTraceOptions['detectors']\n /** Raise at most this many findings per worker, so one pathological worker cannot flood the\n * driver's inbox with the same signal every span. Default 3; `<= 0` = unlimited. */\n readonly maxFindingsPerWorker?: number\n}\n\n/** Default ceiling for a single `await_event` block (ms). Chosen well under any reasonable remote\n * MCP client request timeout so the call returns a `pending` liveness snapshot instead of erroring;\n * the supervisor re-polls until the worker settles. */\nexport const DEFAULT_AWAIT_EVENT_TIMEOUT_MS = 15_000\n\n/**\n * The supervisor-side toolbox returned by {@link createCoordinationTools}: the MCP tool\n * descriptors a driver `AgentProfile` calls to spawn, steer, observe, and settle workers\n * over a live `Scope`, plus the typed accessors (`settled`/`questions`/`history`/`stats`/\n * `raiseFinding`) for the bidirectional coordination bus. This is the live, backend-of-your-\n * choice, steerable counterpart to the one-shot own-sandbox delegation MCP.\n */\nexport interface CoordinationTools {\n readonly tools: McpToolDescriptor[]\n isStopped(): boolean\n stopReason(): string | undefined\n /** The first result whose injected independent check passed, if the driver submitted one. */\n submittedResult(): { readonly result: unknown } | undefined\n settled(): ReadonlyArray<SettledWorker>\n questions(): ReadonlyArray<QuestionRecord>\n /** The full ordered log of every bus event — UP (settled / question / finding) and DOWN\n * (steer / answer) — the observability audit + replay trail. Each record carries seq,\n * timestamp, and priority. */\n history(): ReadonlyArray<BusRecord<CoordinationEvent>>\n /** Bus throughput counters (published / pulled / by-kind) for live dashboards. */\n stats(): BusStats\n /** Raise a `finding` on the bus from outside the settle hook — the seam an ONLINE detector\n * (mid-run, on the worker pipe) uses to tell the driver \"this worker is looping/erroring\" the\n * moment it happens, instead of only at settle. Queued for `await_event` + pass-through. */\n raiseFinding(finding: AnalystFindingEvent): Promise<void>\n /**\n * Post-loop drain: pull every ALREADY-settled, unpulled child into the ledger (publishing each\n * as a `settled` bus event for the audit trail) WITHOUT awaiting live children. The driver\n * calls this once its brain loop ends, so a delivered child the brain never awaited still\n * reaches `finalizeBestDelivered` — a gate-verified delivery must never be lost to the\n * driver's pull discipline. Analyst-on-settle hooks do NOT fire here (the driver has stopped;\n * nobody is left to read a finding, and analysts spend real compute). Returns the count.\n */\n drainResolved(): Promise<number>\n}\n\n/** The reserved coordination verb names — the complete set `createCoordinationTools` can emit\n * (the analyst pair is conditional but still reserved). A driver's extra WORK tools must not\n * collide with any of these, or it could no longer coordinate; callers validate eagerly against\n * this set so the conflict fails loud at construction, not buried in a swallowed `act()` throw. */\nexport const coordinationVerbNames = [\n 'spawn_agent',\n 'observe_agent',\n 'steer_agent',\n 'await_event',\n 'list_questions',\n 'answer_question',\n 'ask_parent',\n 'submit_result',\n 'stop',\n 'list_analysts',\n 'run_analyst',\n] as const\n\nconst idArg = { type: 'string', description: 'The workerId returned by spawn_agent.' } as const\n\n/**\n * Strip zod's object-KEY CODEC artifact from a derived JSON Schema, at every depth.\n *\n * `z.record(z.string(), …)` converts to `propertyNames: { type: 'string', pattern:\n * '^u(?:[0-9a-f]{4})*$' }` — a marker of the lossy key round-trip, not a constraint anything\n * enforces: `agentProfileSchema.safeParse({ name: 'r', tools: { bash: true, Read: false } })`\n * succeeds with those plain keys. Published verbatim it reads to a model as \"every key must be a\n * run of hex quads\", and the model either emits hex-encoded garbage keys or drops the field —\n * on `tools`, `permissions`, `metadata`, `mcp`, `mcp.*.env`, and `model.metadata`, which is most\n * of what a parent actually configures.\n *\n * Every `propertyNames` in the canonical profile schema is this artifact (25 of 25 at Interface\n * 0.40), and the canonical schema constrains no key by pattern, so dropping the keyword outright\n * loses nothing real and cannot be defeated by zod changing the encoding's exact regex.\n *\n * Rebuilds rather than mutates: the canonical conversion output must stay untouched for callers\n * that compare against it.\n */\nconst stripKeyCodecArtifacts = (node: unknown): unknown => {\n if (Array.isArray(node)) return node.map(stripKeyCodecArtifacts)\n if (!node || typeof node !== 'object') return node\n return Object.fromEntries(\n Object.entries(node as Record<string, unknown>)\n .filter(([key]) => key !== 'propertyNames')\n .map(([key, value]) => [key, stripKeyCodecArtifacts(value)]),\n )\n}\n\n/** One field of the published child-profile shape: the canonical field it mirrors, the one-line\n * description a model can act on (what it is, what a child typically sets), and — for the two\n * fields whose canonical sub-tree dwarfs the rest of the tool surface — the BRIEF schema published\n * in place of that sub-tree. */\ninterface PublishedProfileField {\n readonly name: string\n readonly description: string\n readonly brief?: Record<string, unknown>\n}\n\n/** The canonical profile fields a spawning parent actually sets on a child, in the order a reader\n * needs them, each with the description published alongside it. Everything else stays legal to\n * pass — see {@link deriveSpawnProfileArg}.\n *\n * Why these eleven, with the measured numbers (serialized JSON bytes, Interface 0.40). The\n * canonical `properties` map is 10629 bytes, against 2424 bytes for every argument of every other\n * coordination tool COMBINED — publishing it whole makes one parameter four times the rest of the\n * surface a driver re-reads each turn. Of the seven omitted fields (tags, connections, subagents,\n * hooks, modes, confidential, extensions) none is something a parent hands a worker; `permissions`\n * (321 bytes) IS, so it is published — a child that must not touch the network or the filesystem\n * is fenced there and nowhere else. `mcp` (2663 bytes) and `resources` (3122 bytes) are the two a\n * parent is least likely to author inline and were together 85% of the published cost, so they\n * carry a brief shape plus a description naming the full form instead of the canonical sub-tree. */\nconst spawnProfileFields: readonly PublishedProfileField[] = [\n {\n name: 'name',\n description:\n 'Short identifier for this child, e.g. \"researcher\" or \"patch-writer\". A child normally ' +\n 'sets it to its role; it shows up in traces and worker labels.',\n },\n {\n name: 'description',\n description:\n 'One line saying what this child is for. Read by humans and by a parent listing its workers.',\n },\n {\n name: 'version',\n description:\n 'Optional version string for this profile, so two revisions of the same role are ' +\n 'distinguishable in evidence. A child usually omits it.',\n },\n {\n name: 'harness',\n description:\n 'Which coding backend runs the child. Omit to inherit the run default; set it only when ' +\n 'this child needs a specific backend (e.g. a long refactor on \"claude-code\").',\n },\n {\n name: 'model',\n description:\n 'Model routing: `default` model id, optional `small` for cheap sub-calls, `provider`, and ' +\n '`reasoningEffort`. A child typically sets `default` and `reasoningEffort` — raise effort ' +\n 'for a hard reasoning task, lower it for bulk mechanical work.',\n },\n {\n name: 'prompt',\n description:\n \"The child's standing instructions: `systemPrompt` (who it is and how it works) and \" +\n '`instructions` (durable rules). This is the role; the separate `task` argument carries ' +\n 'what to do right now. A child with no systemPrompt has no role — always set one.',\n },\n {\n name: 'tools',\n description:\n 'Per-tool on/off map keyed by tool name, e.g. `{ \"bash\": true, \"webfetch\": false }`. Omit ' +\n \"to inherit the backend's default tool set; set it to narrow a child to the tools its task \" +\n 'needs. Keys are plain tool names.',\n },\n {\n name: 'permissions',\n description:\n 'Per-tool permission decisions: each tool name maps to \"allow\", \"deny\", or \"ask\", or to a ' +\n 'nested map of finer-grained rules. This is where a parent fences a child it does not fully ' +\n 'trust — a read-only child denies write and network tools here, not in `tools`.',\n },\n {\n name: 'mcp',\n description:\n 'MCP tool servers to mount for the child, keyed by server name. Brief form: each value is ' +\n 'either `{ transport: \"stdio\", command, args?, env?, cwd? }` or ' +\n '`{ transport: \"sse\" | \"http\", url, headers? }`. A child normally sets this only when it ' +\n 'needs a tool server the task requires; the canonical AgentProfile schema carries the full ' +\n 'form (secret-ref values for env/headers, per-server metadata) and governs validation.',\n brief: { type: 'object', additionalProperties: { type: 'object' } },\n },\n {\n name: 'resources',\n description:\n 'Files, tools, skills, and agents materialized into the child workspace before it starts. ' +\n 'Brief form: `{ files?, tools?, skills?, agents? }`, each an array whose entries are ' +\n '`{ kind: \"inline\", name, content }` or `{ kind: \"github\", repository?, path, ref? }` ' +\n '(`files` entries wrap that as `{ path, resource, executable? }`). A child typically gets ' +\n '`files` for seed inputs and `skills` for a procedure it must follow; the canonical ' +\n 'AgentProfile schema carries the full form and governs validation.',\n brief: {\n type: 'object',\n properties: {\n files: { type: 'array', items: { type: 'object' } },\n tools: { type: 'array', items: { type: 'object' } },\n skills: { type: 'array', items: { type: 'object' } },\n agents: { type: 'array', items: { type: 'object' } },\n },\n additionalProperties: true,\n },\n },\n {\n name: 'metadata',\n description:\n 'Free-form key/value bag carried with the profile (plain string keys). Use it for run ' +\n 'bookkeeping a reader will want later; it does not change how the child executes.',\n },\n]\n\n/**\n * Build the published shape of `spawn_agent`'s `profile` argument from the canonical\n * `agentProfileSchema` conversion's `properties` map, so it cannot drift from the profile the\n * runtime materializes.\n *\n * DEGRADES, never throws. A canonical field that is absent — renamed or removed upstream — is\n * simply omitted from the published shape, and a canonical schema that is no longer an object\n * publishes no properties at all. This function is reached from a statically-imported module, so a\n * throw here bricks `import '@tangle-network/agent-runtime/kernel'` for every consumer over an\n * upstream rename that costs them, at worst, one advisory field. The drift itself is still caught\n * loudly — as a test assertion in `tests/kernel/coordination.test.ts`, in CI, where it is our\n * problem rather than at a consumer's import, where it is theirs.\n *\n * Permissive on purpose: `additionalProperties: true` with no `required` list, so every canonical\n * field this shape omits stays legal to pass. This tool layer performs no profile validation.\n *\n * @internal exported for the drift and degradation tests; not part of the package's public API.\n */\nexport function deriveSpawnProfileArg(\n canonicalProperties: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const published: Array<[string, unknown]> = []\n for (const field of spawnProfileFields) {\n const canonical = canonicalProperties?.[field.name]\n if (canonical === undefined) continue\n const shape = field.brief ?? (stripKeyCodecArtifacts(canonical) as Record<string, unknown>)\n published.push([field.name, { ...shape, description: field.description }])\n }\n return {\n type: 'object',\n description:\n 'The child agent profile to run — this is the shape the DEFAULT worker seam accepts; a run ' +\n 'wired with a custom makeWorkerAgent may accept a different one. The properties below are ' +\n 'derived from the canonical AgentProfile schema and reduced to what a spawning parent sets ' +\n '(`mcp` and `resources` in a brief form); every other canonical field — tags, connections, ' +\n 'subagents, hooks, modes, confidential, extensions — may still be passed. This tool does ' +\n 'not validate the profile: the canonical AgentProfile schema governs validation downstream.',\n properties: Object.fromEntries(published),\n additionalProperties: true,\n }\n}\n\n/** The canonical field names this module publishes, in published order — the drift test's input.\n *\n * @internal */\nexport const spawnProfileFieldNames: readonly string[] = spawnProfileFields.map((f) => f.name)\n\nlet spawnProfileArgCache: Record<string, unknown> | undefined\n\n/** The published `profile` shape, computed on FIRST tool-definition access and memoized — not at\n * module load. The conversion walks the whole canonical profile tree, and the strip walk rebuilds\n * it: 3.5ms on the first `createCoordinationTools`, 0.017ms on every later one (measured, Interface\n * 0.40, node 24). `src/runtime/index.ts` imports this module statically, so paying that at import\n * taxes every consumer of the kernel entrypoint — including the ones that never build a\n * coordination toolbox. The memo keeps it at once per process for the ones that do.\n *\n * Conversion choices. `io: 'input'` is the CALLER's view — pre-default, pre-transform — which is\n * what a spawning parent may pass, not what the runtime ends up holding. `unrepresentable: 'any'`\n * keeps the conversion total: the canonical schema contains transforms with no JSON Schema form,\n * and zod's default is to throw on them, which would leave the tool with no published shape. */\nfunction spawnProfileArg(): Record<string, unknown> {\n if (!spawnProfileArgCache) {\n const canonical = agentProfileSchema.toJSONSchema({\n io: 'input',\n target: 'draft-07',\n unrepresentable: 'any',\n })\n // Deep-frozen because ONE memoized object is handed to every coordination toolbox in the\n // process: an unfrozen shared schema lets one consumer's mutation corrupt every later one.\n spawnProfileArgCache = deepFreeze(deriveSpawnProfileArg(canonical.properties))\n }\n return spawnProfileArgCache\n}\n\n/** Freeze a JSON-Schema tree. The derived schema is plain JSON data with no cycles. */\nfunction deepFreeze<T>(value: T): T {\n if (value && typeof value === 'object' && !Object.isFrozen(value)) {\n Object.freeze(value)\n for (const nested of Object.values(value)) deepFreeze(nested)\n }\n return value\n}\n\n/** Build the driver's MCP tools over a live scope. */\nexport function createCoordinationTools(opts: CoordinationToolsOptions): CoordinationTools {\n const deliverable = opts.deliverable\n let stopped = false\n let reason: string | undefined\n let submitted: { readonly result: unknown } | undefined\n let questionSeq = 0\n const ledger: SettledWorker[] = []\n const questions: QuestionRecord[] = [...(opts.priorQuestions ?? [])]\n const questionPolicy = opts.questionPolicy ?? 'auto'\n\n // Keyed-assignment bookkeeping for the live-worker fence. `completedKeys` is every key this run\n // can already answer from committed work — seeded from the prior journal on a resume, extended as\n // keyed workers deliver in THIS process. A spawn under such a key starts nothing and occupies no\n // slot, so the fence must not hold it back. `keyByWorker` is what lets a settlement find its key.\n const completedKeys = new Set<string>()\n const keyByWorker = new Map<string, string>()\n for (const [key, prior] of opts.scope.resume?.keys ?? []) {\n if (prior.state === 'completed') completedKeys.add(key)\n }\n\n // A resumed scope's replayed settlements enter the ledger AT CONSTRUCTION, so `settled()` — and\n // therefore the finalize that reads it — spans processes exactly as the journal does. They are\n // NOT re-published on the bus: the driver's resume brief already lists them, and the scope\n // cursor only yields THIS process's children, so nothing double-counts.\n for (const s of opts.scope.resume?.settled ?? []) {\n ledger.push(\n s.kind === 'done'\n ? {\n id: s.handle.id,\n status: 'done',\n score: s.verdict?.score ?? 0,\n valid: s.verdict?.valid ?? false,\n outRef: s.outRef,\n }\n : { id: s.handle.id, status: 'down', reason: s.reason },\n )\n }\n\n // The one child→parent pipe. `onEvent` (back-compat) becomes a pass-through subscriber receiving\n // the bare event, so every kind — question, settled, finding — reaches it immediately, and the\n // driver pulls queued findings / questions via `await_event`.\n const bus = createEventBus<CoordinationEvent>()\n if (opts.onEvent) {\n const cb = opts.onEvent\n bus.subscribe((rec) => cb(rec.event))\n }\n\n // Urgency → bus priority: a blocking question is bumped ahead of queued settles/findings so the\n // driver sees it FIRST when it drains the inbox (and pass-through already delivered it the instant\n // it was raised). Non-blocking messages share priority 0 and resolve FIFO.\n const urgencyPriority = (u: QuestionUrgency): number =>\n u === 'blocks-run' ? 20 : u === 'blocks-step' ? 10 : 0\n\n const str = (v: unknown, field: string): string => {\n if (typeof v !== 'string' || v.length === 0)\n throw new Error(`coordination tools: \"${field}\" must be a non-empty string`)\n return v\n }\n const obj = (raw: unknown): Record<string, unknown> => {\n if (!raw || typeof raw !== 'object')\n throw new Error('coordination tools: arguments must be an object')\n return raw as Record<string, unknown>\n }\n // Parse a per-spawn `budget` override and merge it over the per-worker default (per field).\n // Fails loud on a non-object or a non-finite numeric field — a malformed budget must never\n // silently fall back to the default and run a sub-task on a ceiling nobody chose.\n const mergeBudget = (base: Budget, raw: unknown): Budget => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n throw new Error('coordination tools: \"budget\" must be an object')\n const o = raw as Record<string, unknown>\n const field = (name: keyof Budget): number | undefined => {\n const v = o[name]\n if (v === undefined) return undefined\n if (typeof v !== 'number' || !Number.isFinite(v))\n throw new Error(`coordination tools: \"budget.${name}\" must be a finite number`)\n return v\n }\n const maxIterations = field('maxIterations')\n const maxTokens = field('maxTokens')\n const maxUsd = field('maxUsd')\n const deadlineMs = field('deadlineMs')\n return {\n maxIterations: maxIterations ?? base.maxIterations,\n maxTokens: maxTokens ?? base.maxTokens,\n ...((maxUsd ?? base.maxUsd) === undefined ? {} : { maxUsd: maxUsd ?? base.maxUsd }),\n ...((deadlineMs ?? base.deadlineMs) === undefined\n ? {}\n : { deadlineMs: deadlineMs ?? base.deadlineMs }),\n }\n }\n const level = (v: unknown): Question['level'] => {\n if (v === 'worker' || v === 'driver' || v === 'loop') return v\n throw new Error('coordination tools: \"level\" must be worker, driver, or loop')\n }\n const urgency = (v: unknown): Question['urgency'] => {\n if (v === 'continue-without' || v === 'blocks-step' || v === 'blocks-run') return v\n throw new Error(\n 'coordination tools: \"urgency\" must be continue-without, blocks-step, or blocks-run',\n )\n }\n\n const recordSettled = (s: Settled<unknown>): SettledWorker => {\n const settledAt = Date.now()\n // A keyed assignment that just delivered is complete for the rest of this run, so a later\n // spawn under the same key resolves for free instead of being held behind the live-worker\n // fence (it starts no worker, so it occupies no slot).\n const settledKey = keyByWorker.get(s.handle.id)\n if (settledKey !== undefined && s.kind === 'done') completedKeys.add(settledKey)\n const w: SettledWorker =\n s.kind === 'done'\n ? {\n id: s.handle.id,\n status: 'done',\n score: s.verdict?.score ?? 0,\n valid: s.verdict?.valid ?? false,\n outRef: s.outRef,\n settledAt,\n }\n : { id: s.handle.id, status: 'down', reason: s.reason, settledAt }\n ledger.push(w)\n // A settled worker's trace source is finished; drop the online subscription with it.\n unwatchWorker(w.id)\n return w\n }\n\n // Producer: drain exactly one settlement from the scope cursor onto the bus (a `settled` event),\n // then fire the analyst-on-settle hook — auto-run each configured lens over the worker's trace and\n // publish its result as a `finding`. Returns false when the cursor is idle (no live workers). The\n // cursor is a once-per-child source, so a settlement is produced at most once.\n const drainSettlement = async (): Promise<boolean> => {\n const s = await opts.scope.next()\n if (!s) return false\n const w = recordSettled(s)\n await bus.publish({ type: 'settled', worker: w })\n if (w.status === 'done' && w.outRef && opts.analysts && opts.analyzeOnSettle?.length) {\n const trace = await opts.blobs.get(w.outRef)\n for (const analyst of opts.analyzeOnSettle) {\n const findings = await opts.analysts.run(analyst, trace)\n await bus.publish({ type: 'finding', finding: { fromWorker: w.id, analyst, findings } })\n }\n }\n return true\n }\n\n // Post-loop drain: every ALREADY-settled, unpulled child enters the ledger + audit trail. No\n // analyst-on-settle here — the driver has stopped, so a finding has no reader and an analyst\n // spawn would spend real compute for nothing.\n const drainResolved = async (): Promise<number> => {\n let drained = 0\n for (;;) {\n const s = await opts.scope.nextResolved()\n if (!s) return drained\n const w = recordSettled(s)\n await bus.publish({ type: 'settled', worker: w })\n drained += 1\n }\n }\n\n // The down-leg: record a parent→child message on the bus for the audit trail (history +\n // subscribers) WITHOUT enqueuing it — the parent must never pull its own outbound message back.\n // Overloaded so the `answer` kind REQUIRES a questionId (no silent `?? ''` fallback to mask a bug).\n function sendDown(type: 'steer', down: DownMessageEvent): Promise<void>\n function sendDown(type: 'answer', down: DownMessageEvent, questionId: string): Promise<void>\n async function sendDown(\n type: 'steer' | 'answer',\n down: DownMessageEvent,\n questionId?: string,\n ): Promise<void> {\n await bus.publish(\n type === 'answer'\n ? { type, down, questionId: str(questionId, 'questionId') }\n : { type, down },\n { queue: false },\n )\n }\n\n // Consumer projection: the wire shape the driver sees for a pulled bus event.\n const projectEvent = (ev: CoordinationEvent): Record<string, unknown> => {\n if (ev.type === 'settled') {\n const w = ev.worker\n return w.status === 'done'\n ? {\n type: 'settled',\n settled: w.id,\n status: 'done',\n score: w.score,\n valid: w.valid,\n outRef: w.outRef,\n }\n : { type: 'settled', settled: w.id, status: 'down', reason: w.reason }\n }\n if (ev.type === 'question') return { type: 'question', question: ev.question }\n if (ev.type === 'finding') return { type: 'finding', ...ev.finding }\n if (ev.type === 'answer') return { type: 'answer', ...ev.down, questionId: ev.questionId }\n // Down-leg `steer` is record-only (never queued), so the driver never pulls it; project\n // defensively for completeness.\n return { type: ev.type, ...ev.down }\n }\n\n const nextQuestionId = (from: string): string => `${from}:q${questionSeq++}`\n const normalizeQuestion = (q: QuestionInput, fallbackFrom: string): Question => {\n const from = str(q.from ?? fallbackFrom, 'from')\n return {\n id: typeof q.id === 'string' && q.id.length > 0 ? q.id : nextQuestionId(from),\n from,\n level: level(q.level),\n question: str(q.question, 'question'),\n reason: str(q.reason, 'reason'),\n ...(q.options ? { options: q.options } : {}),\n urgency: urgency(q.urgency),\n }\n }\n const addQuestion = (\n raw: QuestionInput,\n fallbackFrom: string,\n decision?: QuestionDecision,\n ): { question: QuestionRecord; added: boolean } => {\n const q = normalizeQuestion(raw, fallbackFrom)\n const existing = questions.find((x) => x.id === q.id)\n if (existing) return { question: existing, added: false }\n const effectiveDecision =\n decision ??\n (questionPolicy === 'bubble'\n ? ({\n kind: 'escalate',\n to: 'parent',\n reason: 'question policy bubbled to parent',\n } as const)\n : undefined)\n const status: QuestionRecord['status'] =\n effectiveDecision?.kind === 'answer'\n ? 'answered'\n : effectiveDecision?.kind === 'defer'\n ? 'deferred'\n : effectiveDecision?.kind === 'escalate'\n ? 'escalated'\n : 'open'\n const record: QuestionRecord = {\n ...q,\n status,\n openedAt: Date.now(),\n ...(effectiveDecision ? { decision: effectiveDecision } : {}),\n }\n questions.push(record)\n return { question: record, added: true }\n }\n const emitNewQuestion = async (record: {\n question: QuestionRecord\n added: boolean\n }): Promise<QuestionRecord> => {\n if (record.added)\n await bus.publish(\n { type: 'question', question: record.question },\n { priority: urgencyPriority(record.question.urgency) },\n )\n return record.question\n }\n const decideQuestion = (questionId: string, decision: QuestionDecision): QuestionRecord => {\n const idx = questions.findIndex((q) => q.id === questionId)\n if (idx < 0) throw new Error(`unknown questionId ${JSON.stringify(questionId)}`)\n const prior = questions[idx] as QuestionRecord\n const status: QuestionRecord['status'] =\n decision.kind === 'answer' ? 'answered' : decision.kind === 'defer' ? 'deferred' : 'escalated'\n const next: QuestionRecord = { ...prior, status, decision }\n questions[idx] = next\n return next\n }\n const blockingQuestionsForStop = (): QuestionRecord[] => {\n if (questionPolicy === 'auto' || questionPolicy === 'bubble') return []\n return questions.filter((q) => {\n const blocking = q.urgency === 'blocks-step' || q.urgency === 'blocks-run'\n if (!blocking) return false\n if (questionPolicy === 'mustDecide') return q.status === 'open'\n return q.status !== 'answered' && q.status !== 'deferred'\n })\n }\n\n // Count workers that are LIVE — spawned but not yet settled — off the scope's in-memory live set\n // (O(live), synchronous). The terminal statuses are done/failed/cancelled; everything else\n // (pending/acquiring/running) is still in flight. This is the concurrency fence's input.\n const maxLiveWorkers = opts.maxLiveWorkers\n const isLive = (status: string): boolean =>\n status !== 'done' && status !== 'failed' && status !== 'cancelled'\n const liveWorkerCount = (): number => opts.scope.view.nodes.filter((n) => isLive(n.status)).length\n\n // A snapshot of every still-in-flight worker — the liveness signal a bounded `await_event`\n // returns when its wait elapses, so the supervisor can tell \"worker still running, keep waiting\"\n // apart from \"nothing is happening\" (the distinction it lost when the unbounded await erred out).\n const liveSnapshot = (): Array<{ id: string; status: string; spent: unknown }> =>\n opts.scope.view.nodes\n .filter((n) => isLive(n.status))\n .map((n) => ({ id: n.id, status: n.status, spent: n.spent }))\n\n // How many workers the driver could open RIGHT NOW without hitting the simultaneity fence, or\n // `null` when no cap is set (the conserved pool is then the only fence, so there is no finite\n // slot count). Without this the brain could see WHO is running but never that capacity was idle,\n // so filling N slots meant emitting N blind tool calls with no feedback telling it to — the\n // mechanical reason a 5-worker run peaked at 2 live workers. Policy (whether to fill) stays with\n // the driver; this is only the reading.\n const freeWorkerSlots = (): number | null => freeSlots(liveWorkerCount(), maxLiveWorkers)\n\n // The LIVE read of one worker. Guarded because `createCoordinationTools` is bound to a `Scope`\n // it did not construct — an older or hand-rolled scope may not implement `progress` at all, and\n // an observation must degrade to \"no progress available\", never throw at the driver.\n const readProgress = (id: string): WorkerProgress | undefined => {\n const scope = opts.scope as Partial<Scope<unknown>>\n if (typeof scope.progress !== 'function') return undefined\n try {\n return scope.progress(\n id,\n opts.stallAfterMs !== undefined ? { stallAfterMs: opts.stallAfterMs } : {},\n )\n } catch {\n return undefined\n }\n }\n\n // ONLINE detection: subscribe the streaming detector panel to a freshly-spawned worker's live\n // tool trace, and turn each signal into a `finding` the driver pulls from `await_event`. The\n // unsubscribe fires on the worker's settle (its trace source is dead from then on) and the\n // per-worker cap stops one looping worker from flooding the bus.\n const watchers = new Map<string, () => void>()\n const watchWorker = (id: string): void => {\n const watch = opts.watchWorkers\n if (!watch) return\n const scope = opts.scope as Partial<Scope<unknown>>\n if (typeof scope.traceSource !== 'function') return\n let source: ReturnType<NonNullable<Scope<unknown>['traceSource']>>\n try {\n source = scope.traceSource(id)\n } catch {\n return\n }\n if (!source) return\n const cap = watch.maxFindingsPerWorker ?? 3\n let raised = 0\n const unsub = watchTrace(source, {\n ...(watch.detectors ? { detectors: watch.detectors } : {}),\n onSignal: async (signal, span) => {\n if (cap > 0 && raised >= cap) return\n raised += 1\n await bus.publish({\n type: 'finding',\n finding: {\n fromWorker: id,\n analyst: `online:${signal.detector}`,\n findings: {\n detector: signal.detector,\n severity: signal.severity,\n reason: signal.reason,\n streak: signal.streak,\n ...(signal.failureClass ? { failureClass: signal.failureClass } : {}),\n toolName: span.toolName,\n at: span.endedAt,\n progress: readProgress(id),\n },\n },\n })\n },\n })\n watchers.set(id, unsub)\n }\n const unwatchWorker = (id: string): void => {\n const unsub = watchers.get(id)\n if (!unsub) return\n watchers.delete(id)\n try {\n unsub()\n } catch {\n // an unsubscribe that throws must never break the settle path\n }\n }\n\n // The blocking `scope.next()` (via `drainSettlement`) waits on a LIVE worker for its whole run.\n // Keep at most ONE such drain in flight and let every concurrent `await_event` race THAT single\n // promise against a timeout — so a bounded call never starts a second unbounded block, and the\n // one drain still delivers the settlement (exactly-once via the scope cursor) whenever it lands.\n const awaitTimeoutMs = opts.awaitTimeoutMs ?? DEFAULT_AWAIT_EVENT_TIMEOUT_MS\n let inFlightDrain: Promise<boolean> | null = null\n const ensureDrain = (): Promise<boolean> => {\n if (!inFlightDrain)\n inFlightDrain = drainSettlement().finally(() => {\n inFlightDrain = null\n })\n return inFlightDrain\n }\n // Resolve `{ drained }` if the drain wins, or `undefined` if the bound elapses first. A `<= 0`\n // bound restores the prior unbounded block (no timer): the caller opted out of the fence.\n const raceDrainWithTimeout = async (\n drain: Promise<boolean>,\n ): Promise<{ drained: boolean } | undefined> => {\n if (awaitTimeoutMs <= 0) return { drained: await drain }\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), awaitTimeoutMs)\n // Never let this fence-timer alone keep the process alive (e.g. at teardown).\n if (typeof timer?.unref === 'function') timer.unref()\n })\n try {\n return await Promise.race([drain.then((drained) => ({ drained })), timeout])\n } finally {\n if (timer) clearTimeout(timer)\n }\n }\n\n const tools: McpToolDescriptor[] = [\n {\n name: 'spawn_agent',\n description:\n 'Start a worker the driver will drive. `profile` is the worker or another driver; ' +\n '`task` is what it should do. Reserves budget from the conserved pool and fails closed. ' +\n 'Pass an optional `budget` (per-field) to give a hard sub-task more than the default — it ' +\n 'merges over the per-worker default; the conserved pool is still the hard fence. When a ' +\n 'max-live-workers cap is set it also fails closed (`error: \"max-live-workers\"`) while that ' +\n 'many workers are still in flight — settle or steer one before spawning another. ' +\n 'Pass a `key` naming the assignment to make it run-once ACROSS restarts: a key that ' +\n 'already completed returns the finished result (`resumed: \"completed\"` — no work re-runs, ' +\n 'nothing is spent), a key whose prior attempt failed or was lost with a dead process ' +\n 'spawns fresh and says so (`resumed: \"retried\" | \"lost\"`), and a key still running is ' +\n 'refused (`error: \"duplicate-key\"`). ' +\n 'Returns `freeSlots`: how many MORE workers you can start right now (`null` = uncapped). ' +\n 'While `freeSlots > 0` there is idle capacity — call this again to fill it rather than ' +\n 'waiting; parallel workers finish the run sooner than one at a time.',\n inputSchema: {\n type: 'object',\n properties: {\n profile: spawnProfileArg(),\n task: { description: 'The task the worker should perform.' },\n label: { type: 'string', description: 'Optional trace label.' },\n key: {\n type: 'string',\n description:\n 'Optional semantic name for this assignment (e.g. \"summarize-ch3\"). The same key ' +\n 'never runs twice: completed keys return their committed result, even after a ' +\n 'coordinator restart.',\n },\n budget: {\n type: 'object',\n description:\n 'Optional per-spawn budget that merges over the per-worker default (per field). ' +\n 'Only set the ceilings this sub-task needs raised; the conserved pool still fences.',\n properties: {\n maxIterations: { type: 'number' },\n maxTokens: { type: 'number' },\n maxUsd: { type: 'number' },\n deadlineMs: { type: 'number' },\n },\n },\n },\n required: ['profile', 'task'],\n },\n handler: (raw) => {\n const a = obj(raw)\n const key = a.key === undefined ? undefined : str(a.key, 'key')\n // A key already proven complete — by the resumed journal or by a delivery earlier in this\n // run — resolves to committed work and starts no live worker, so the concurrency fence\n // does not apply to it.\n const keyCompleted = key !== undefined && completedKeys.has(key)\n // Concurrency fence FIRST — fail closed before reserving budget, so a rejected spawn never\n // touches the pool. The conserved pool bounds TOTAL work; this bounds SIMULTANEOUS work.\n if (\n !keyCompleted &&\n maxLiveWorkers !== undefined &&\n maxLiveWorkers > 0 &&\n liveWorkerCount() >= maxLiveWorkers\n )\n return Promise.resolve({\n error: 'max-live-workers' as const,\n live: liveWorkerCount(),\n freeSlots: freeWorkerSlots(),\n })\n const agent = opts.makeWorkerAgent(a.profile)\n const budget =\n a.budget === undefined ? opts.perWorker : mergeBudget(opts.perWorker, a.budget)\n const res = opts.scope.spawn(agent, a.task, {\n budget,\n label: typeof a.label === 'string' ? a.label : 'worker',\n ...(key !== undefined ? { key } : {}),\n })\n // A keyed spawn that resolved to committed work: NOTHING ran — return the finished result\n // (it is already in the settled ledger, seeded from the resumed scope or recorded when the\n // cursor yielded it), so the driver folds it in without an await_event round-trip.\n if (res.ok && res.prior?.state === 'completed') {\n const s = res.prior.settled\n if (key !== undefined) completedKeys.add(key)\n return Promise.resolve({\n workerId: s.handle.id,\n resumed: 'completed' as const,\n status: 'done' as const,\n score: s.verdict?.score ?? 0,\n valid: s.verdict?.valid ?? false,\n outRef: s.outRef,\n live: liveWorkerCount(),\n freeSlots: freeWorkerSlots(),\n })\n }\n if (res.ok) {\n watchWorker(res.handle.id)\n // Bind the new worker to its key so its settlement can mark the key complete.\n if (key !== undefined) keyByWorker.set(res.handle.id, key)\n }\n // A `completed` key returned above, so any prior still attached here is a real re-run:\n // `retried` (the prior attempt failed) or `lost` (it died in flight with its process).\n const priorHistory =\n res.ok && res.prior !== undefined && res.prior.state !== 'completed'\n ? {\n resumed: res.prior.state,\n priorWorkerId: res.prior.priorId,\n ...(res.prior.state === 'retried' ? { priorReason: res.prior.reason } : {}),\n }\n : {}\n // Report the REMAINING capacity alongside the spawn, so one tool call tells the driver\n // both \"it started\" and \"you can still open N more\" — the feedback that lets it fill\n // slots instead of opening one worker per turn. `null` = uncapped. A fresh spawn under a\n // key with a failed/lost prior attempt carries that history (`resumed`/`priorWorkerId`),\n // so a re-run is always explicit, never a silent duplicate.\n return Promise.resolve(\n res.ok\n ? {\n workerId: res.handle.id,\n live: liveWorkerCount(),\n freeSlots: freeWorkerSlots(),\n ...priorHistory,\n }\n : {\n error: res.reason,\n // A refusal a driver can ACT on. `usd-unbudgeted` is the one rejection that no\n // retry can clear, so it says so: without this, a driver reads \"budget\" and walks\n // its request down until it gives up.\n ...(res.reason === 'usd-unbudgeted'\n ? {\n hint:\n \"This run's root budget declares no maxUsd, so a child budget naming maxUsd \" +\n 'can never be admitted — at any amount. Retrying with a smaller maxUsd will ' +\n 'fail identically. Spawn with a budget that omits maxUsd, or ask the caller ' +\n 'to give the run a root maxUsd.',\n }\n : {}),\n live: liveWorkerCount(),\n freeSlots: freeWorkerSlots(),\n },\n )\n },\n },\n {\n name: 'observe_agent',\n description:\n 'Inspect a worker WHILE IT RUNS, not only after it finishes: status, spend so far, and ' +\n '`progress` — how long since it last did anything (`idleMs`), whether that counts as ' +\n 'stalled, how many turns it has taken, the last tools/files it touched ' +\n '(`recentActivity`), what its executor CHANGED about the profile you gave it ' +\n '(`derived` — an MCP config it materialized, an extension it had to add), whether a ' +\n 'steer can even reach it (`steerable`), and how many ' +\n 'steers it has not yet read (`pendingMessages`). Returns the settled output artifact ' +\n 'once it exists. Use this BEFORE steer_agent: a steer is only worth sending when the ' +\n 'progress says the worker is on the wrong path or has stopped making any.',\n inputSchema: { type: 'object', properties: { workerId: idArg }, required: ['workerId'] },\n handler: async (raw) => {\n const id = str(obj(raw).workerId, 'workerId')\n const node = opts.scope.view.nodes.find((n) => n.id === id)\n if (!node) {\n // A worker from a PRIOR process of this run: not in the live nursery, but its committed\n // record is on the resumed view — observable like any settled worker, marked `resumed`.\n const resumed = opts.scope.resume?.view.nodes.find((n) => n.id === id)\n if (!resumed) return { error: `unknown workerId ${JSON.stringify(id)}` }\n const output = resumed.outRef ? await opts.blobs.get(resumed.outRef) : undefined\n return {\n status: resumed.status,\n spent: resumed.spent,\n outRef: resumed.outRef ?? null,\n output: output ?? null,\n progress: null,\n resumed: true,\n }\n }\n const output = node.outRef ? await opts.blobs.get(node.outRef) : undefined\n const progress = readProgress(id)\n return {\n status: node.status,\n spent: node.spent,\n outRef: node.outRef ?? null,\n output: output ?? null,\n progress: progress ?? null,\n }\n },\n },\n {\n name: 'steer_agent',\n description:\n 'Send a message DOWN to a still-LIVE worker (parent→child): a new instruction, a course ' +\n 'correction, or a continuation. The worker drains it at its next step boundary — and before ' +\n 'it may settle, so it cannot finish while a message it never read is pending. A worker that ' +\n 'already settled is gone (returns delivered:false) — spawn a fresh one instead.',\n inputSchema: {\n type: 'object',\n properties: {\n workerId: idArg,\n instruction: { type: 'string', description: 'What the worker should do next.' },\n interrupt: {\n type: 'boolean',\n description:\n 'true = forceful: abort the worker’s in-flight inference so it re-plans on the NEXT ' +\n 'turn (a tool already mid-execution finishes first; only the owned tool-loop honors this). ' +\n 'false/omitted = queued: it flushes at the next step boundary (and before it may settle).',\n },\n },\n required: ['workerId', 'instruction'],\n },\n handler: async (raw) => {\n const a = obj(raw)\n const workerId = str(a.workerId, 'workerId')\n const instruction = str(a.instruction, 'instruction')\n const interrupt = a.interrupt === true\n const delivered = opts.scope.send(workerId, { steer: instruction, interrupt })\n await sendDown('steer', { toWorker: workerId, instruction, delivered })\n if (delivered) return { delivered, progress: readProgress(workerId) ?? null }\n // Say WHY nothing landed. A silent `delivered:false` is how steering became a no-op:\n // the driver could not tell \"already finished\" from \"this runtime has no inbox at all\".\n const progress = readProgress(workerId)\n const reason = !progress\n ? 'unknown-worker'\n : !progress.live\n ? 'already-settled'\n : 'runtime-has-no-inbox'\n return { delivered, reason, progress: progress ?? null }\n },\n },\n {\n name: 'await_event',\n description:\n 'Wait for and pull the next message a worker, sub-driver, or analyst sent up — the unified ' +\n \"inbox. An event is one of: a settled worker output ('settled'), a question needing your \" +\n \"answer ('question', from ask_parent / the worker's ask-user), or a trace-analyst finding \" +\n \"('finding', from analyze-on-settle). Pass kinds:['settled'] for just the next finished \" +\n 'worker; omit `kinds` to also receive questions and findings. Returns { idle: true } when ' +\n 'nothing is queued and no workers are live. If a worker is still running when the wait ' +\n 'elapses, returns { pending: true, live: [...] } (the workers still in flight) instead of ' +\n 'blocking indefinitely — call await_event again to keep waiting; the settlement is not lost. ' +\n 'Every reply carries `freeSlots`: how many more workers you can start right now (`null` = ' +\n 'uncapped). A settled worker frees its slot, so `freeSlots > 0` means capacity is sitting ' +\n 'idle — spawn into it before waiting again.',\n inputSchema: {\n type: 'object',\n properties: {\n kinds: {\n type: 'array',\n items: { type: 'string', enum: ['settled', 'question', 'finding'] },\n description: 'Restrict to these event kinds (any if omitted).',\n },\n },\n },\n handler: async (raw) => {\n const k = obj(raw).kinds\n const kinds = Array.isArray(k)\n ? (k.filter((x) => x === 'settled' || x === 'question' || x === 'finding') as Array<\n CoordinationEvent['type']\n >)\n : undefined\n // Already-queued async messages (findings, questions) first — a fast, non-blocking pull.\n let ev = bus.pull(kinds)\n // Every return from this verb carries `freeSlots` — a settlement is exactly the moment\n // capacity frees up, so the answer travels with the event that freed it.\n if (ev) return { ...projectEvent(ev), freeSlots: freeWorkerSlots() }\n // Else drive the cursor to produce the next settlement — but BOUND the block. `scope.next()`\n // waits on a live worker for its entire (multi-minute) run; unbounded, that outlives a remote\n // MCP client's request timeout and surfaces as a hard tool error, leaving the supervisor with\n // no working \"wait for the worker\" primitive. Race the single in-flight drain against the\n // fence: if it settles in time, re-pull and return the event (or idle when the cursor is dry);\n // if the fence wins, return a non-error liveness snapshot the supervisor can re-poll on.\n const raced = await raceDrainWithTimeout(ensureDrain())\n if (raced === undefined)\n return { pending: true, live: liveSnapshot(), freeSlots: freeWorkerSlots() }\n ev = bus.pull(kinds)\n if (!ev) return { idle: !raced.drained, freeSlots: freeWorkerSlots() }\n return { ...projectEvent(ev), freeSlots: freeWorkerSlots() }\n },\n },\n {\n name: 'list_questions',\n description:\n 'List questions raised by workers, drivers, or analysts. Blocking stop behavior follows questionPolicy.',\n inputSchema: { type: 'object', properties: {} },\n handler: () => Promise.resolve({ questions }),\n },\n {\n name: 'answer_question',\n description: 'Record an answer, deferral, or escalation for a loop question.',\n inputSchema: {\n type: 'object',\n properties: {\n questionId: { type: 'string' },\n answer: { type: 'string' },\n by: { type: 'string', description: 'Node id or \"user\".' },\n deferReason: { type: 'string' },\n escalateTo: { type: 'string', enum: ['parent', 'user'] },\n escalateReason: { type: 'string' },\n },\n required: ['questionId'],\n },\n handler: async (raw) => {\n const a = obj(raw)\n const questionId = str(a.questionId, 'questionId')\n if (typeof a.answer === 'string' && a.answer.length > 0) {\n const answer = a.answer\n const question = decideQuestion(questionId, {\n kind: 'answer',\n answer,\n by: typeof a.by === 'string' && a.by.length > 0 ? a.by : 'user',\n })\n // Route the answer DOWN to the worker that asked, unparking it, and record the down-leg.\n // A blocking question parked the worker, so deliver forcefully — it should resume on the\n // answer immediately, not wait for its next step boundary.\n const interrupt = question.urgency === 'blocks-run' || question.urgency === 'blocks-step'\n const delivered = opts.scope.send(question.from, { answer, questionId, interrupt })\n await sendDown(\n 'answer',\n { toWorker: question.from, instruction: answer, delivered },\n questionId,\n )\n // Surface `delivered` like steer_agent — the caller must see whether the answer actually\n // reached a live worker (false when it already settled or has no inbox).\n return { question, delivered }\n }\n if (typeof a.deferReason === 'string' && a.deferReason.length > 0) {\n return Promise.resolve({\n question: decideQuestion(questionId, {\n kind: 'defer',\n reason: a.deferReason,\n }),\n })\n }\n if (a.escalateTo === 'parent' || a.escalateTo === 'user') {\n const escalateReason =\n typeof a.escalateReason === 'string' && a.escalateReason.length > 0\n ? a.escalateReason\n : 'driver escalated'\n return Promise.resolve({\n question: decideQuestion(questionId, {\n kind: 'escalate',\n to: a.escalateTo,\n reason: escalateReason,\n }),\n })\n }\n throw new Error('answer_question: provide answer, deferReason, or escalateTo')\n },\n },\n {\n name: 'ask_parent',\n description: 'Raise a question to the parent driver/Pi/user when this driver cannot decide.',\n inputSchema: {\n type: 'object',\n properties: {\n from: { type: 'string' },\n level: { type: 'string', enum: ['worker', 'driver', 'loop'] },\n question: { type: 'string' },\n reason: { type: 'string' },\n urgency: { type: 'string', enum: ['continue-without', 'blocks-step', 'blocks-run'] },\n },\n required: ['from', 'level', 'question', 'reason', 'urgency'],\n },\n handler: async (raw) => {\n const a = obj(raw)\n const from = str(a.from, 'from')\n const q = await emitNewQuestion(\n addQuestion(\n {\n from,\n level: level(a.level),\n question: str(a.question, 'question'),\n reason: str(a.reason, 'reason'),\n urgency: urgency(a.urgency),\n },\n from,\n { kind: 'escalate', to: 'parent', reason: 'asked parent' },\n ),\n )\n return { question: q }\n },\n },\n ...(deliverable\n ? [\n {\n name: 'submit_result',\n description: [\n 'Submit the complete result to the injected independent check.',\n 'The first passing result is retained; stop work when accepted.',\n ...(deliverable.describe ? [`Expected result: ${deliverable.describe}`] : []),\n ].join(' '),\n inputSchema: {\n type: 'object',\n properties: {\n result: {\n description: 'The complete result in the form requested by the task.',\n },\n },\n required: ['result'],\n additionalProperties: false,\n },\n handler: async (raw: unknown) => {\n if (submitted) {\n return {\n accepted: true,\n retained: 'earlier-passing-result',\n stop: true,\n }\n }\n const a = obj(raw)\n if (!Object.hasOwn(a, 'result')) {\n throw new Error('submit_result: \"result\" is required')\n }\n\n // Copy once at intake so the value checked below is the exact value retained after\n // acceptance, even when this handler is called directly rather than through JSON-RPC.\n const result = structuredClone(a.result)\n let accepted = false\n try {\n accepted = (await deliverable.check(result)) === true\n } catch {\n accepted = false\n }\n if (!accepted) return { accepted: false, stop: false }\n // Two remote callers may submit concurrently. Whichever passing check completes\n // first owns the retained result; a later completion must never overwrite it.\n if (submitted) {\n return {\n accepted: true,\n retained: 'earlier-passing-result',\n stop: true,\n }\n }\n\n submitted = Object.freeze({ result })\n stopped = true\n reason = 'result-accepted'\n return { accepted: true, retained: 'this-result', stop: true }\n },\n } satisfies McpToolDescriptor,\n ]\n : []),\n {\n name: 'stop',\n description: 'Declare the run complete.',\n inputSchema: {\n type: 'object',\n properties: { reason: { type: 'string', description: 'Why you are stopping.' } },\n },\n handler: (raw) => {\n const blocking = blockingQuestionsForStop()\n if (blocking.length) {\n return Promise.resolve({\n stopped: false,\n error: 'unresolved-blocking-questions',\n questions: blocking,\n })\n }\n stopped = true\n const r = obj(raw).reason\n reason = typeof r === 'string' ? r : undefined\n return Promise.resolve({ stopped: true })\n },\n },\n ]\n\n if (opts.analysts) {\n tools.push({\n name: 'list_analysts',\n description: 'List trace-analyst lenses available to run over a settled worker.',\n inputSchema: { type: 'object', properties: {} },\n handler: () => Promise.resolve({ analysts: opts.analysts?.kinds }),\n })\n tools.push({\n name: 'run_analyst',\n description: 'Apply an analyst lens to a settled worker trace.',\n inputSchema: {\n type: 'object',\n properties: {\n kind: { type: 'string', description: 'The analyst kind id.' },\n workerId: idArg,\n },\n required: ['kind', 'workerId'],\n },\n handler: async (raw) => {\n const a = obj(raw)\n const id = str(a.workerId, 'workerId')\n const node = opts.scope.view.nodes.find((n) => n.id === id)\n if (!node) return { error: `unknown workerId ${JSON.stringify(id)}` }\n if (!node.outRef)\n return { error: `worker ${JSON.stringify(id)} has not settled — no trace to analyze yet` }\n const trace = await opts.blobs.get(node.outRef)\n return { findings: await opts.analysts?.run(str(a.kind, 'kind'), trace) }\n },\n })\n }\n\n return {\n tools,\n history: () => bus.history(),\n raiseFinding: (finding) => bus.publish({ type: 'finding', finding }).then(() => undefined),\n stats: () => bus.stats(),\n isStopped: () => stopped,\n stopReason: () => reason,\n submittedResult: () => submitted,\n settled: () => ledger,\n questions: () => questions,\n drainResolved,\n }\n}\n","/**\n * anytimeReport — time-to-satisfactory-output metrics, derived entirely from the\n * waterfall's spans (no new instrumentation): per task, the best-so-far score after each\n * shot with its elapsed wall-clock and cumulative spend; per strategy, the standard\n * anytime-optimization metrics:\n *\n * TTT time-to-target — elapsed ms until best-so-far ≥ the target (per task; median\n * over tasks that reached it)\n * STT shots-to-target — attempts until best-so-far ≥ target\n * ERT expected running time (the COCO benchmarking convention): TOTAL time spent\n * across all tasks — including failures' full budgets — divided by the number of\n * tasks that reached the target. The honest \"how long per success, all-in\".\n * AUC the anytime curve's area (mean best-so-far score across the budget, per shot\n * index) — higher = climbs earlier.\n *\n * The \"satisfactory\" bar follows the COCO/BBOB convention: a SET of satisficing targets\n * (e.g. [0.5, 0.8, 1.0] on the normalized check score), each measured independently —\n * runtime-to-target per (task, target) pair — optionally overridden per task\n * (`targetFor`) when satisfaction is task-specific. Spans come from\n * `createWaterfallCollector().report()`; tasks are grouped by the supervisor runId\n * (`agentic:<strategy>:<taskId>`); shot spans are `shot:N` labels.\n */\nimport type { WaterfallSpan } from './waterfall'\n\nexport interface AnytimeTaskCurve {\n taskId: string\n strategy: string\n /** Best-so-far after each settled shot: elapsed ms from the task's first spawn,\n * cumulative usd, and the running max score. */\n points: Array<{ elapsedMs: number; cumUsd: number; best: number }>\n /** Per satisficing target (keyed by the target value as a string): the first point\n * where best ≥ target, or null when never reached within budget. */\n hits: Record<string, { ms: number; shots: number; usd: number } | null>\n}\n\nexport interface AnytimeStrategySummary {\n strategy: string\n /** The satisficing target this row summarizes. */\n target: number\n tasks: number\n reachedTarget: number\n /** Median time-to-target over the tasks that reached it (null when none did). */\n medianTttMs: number | null\n medianShotsToTarget: number | null\n /** COCO ERT: Σ all task wall-time (incl. failures) / #successes. Null when 0 succeed. */\n ertMs: number | null\n /** Same construction over dollars: Σ all spend / #successes. */\n erUsd: number | null\n /** Mean best-so-far score by shot index (the anytime curve, averaged over tasks). */\n curveByShot: number[]\n /** Area under the per-shot anytime curve, normalized to [0,1]. */\n auc: number\n}\n\nexport interface AnytimeReport {\n targets: number[]\n perTask: AnytimeTaskCurve[]\n /** One summary per (strategy, target) pair — the COCO-style multi-target view. */\n perStrategy: AnytimeStrategySummary[]\n}\n\n/**\n * The best-so-far fold — the ONE definition of \"how good was the run after k results\", shared by\n * the post-run anytime report below and by the LIVE progress-based stop rules\n * (`supervise/stop-rules.ts`). Given the observed objective per settled result in order, it returns\n * the running maximum. A result with no objective (`undefined` — it failed, or it was never\n * scored) carries the previous best forward rather than resetting it.\n *\n * It is extracted rather than duplicated on purpose: a stop rule that decides a run has plateaued\n * must agree, number for number, with the report that later says whether stopping was right.\n */\nexport function bestSoFar(values: ReadonlyArray<number | undefined>): number[] {\n const out: number[] = []\n let best = 0\n for (const v of values) {\n if (typeof v === 'number' && v > best) best = v\n out.push(best)\n }\n return out\n}\n\n/** Mean of a best-so-far curve — the anytime AUC when the curve is normalized to [0,1]. Higher =\n * the run climbed earlier. Shared with the stop rules so \"improving\" means one thing. */\nexport function areaUnderCurve(curve: ReadonlyArray<number>): number {\n if (curve.length === 0) return 0\n return curve.reduce((s, v) => s + v, 0) / curve.length\n}\n\n/**\n * How many trailing entries of a best-so-far curve are within `minDelta` of the curve's value\n * `window` steps back — i.e. the length of the current PLATEAU, in settles. `0` means the most\n * recent settle improved the best by more than `minDelta`.\n *\n * The plateau math the live stop rules read. Defined here, beside the report that measures whether\n * the plateau was real, so there is exactly one notion of \"not improving\".\n */\nexport function plateauLength(curve: ReadonlyArray<number>, minDelta: number): number {\n if (curve.length === 0) return 0\n const last = curve[curve.length - 1] as number\n let i = curve.length - 1\n while (i > 0 && last - (curve[i - 1] as number) <= minDelta) i -= 1\n return curve.length - 1 - i\n}\n\nconst median = (xs: number[]): number | null => {\n if (xs.length === 0) return null\n const s = [...xs].sort((a, b) => a - b)\n const mid = Math.floor(s.length / 2)\n return s.length % 2 === 1 ? (s[mid] as number) : ((s[mid - 1] as number) + (s[mid] as number)) / 2\n}\n\n/** Derive anytime metrics from waterfall spans. `targets` are the satisficing score\n * bars (default [1] = fully resolved; COCO-style multi-target: [0.5, 0.8, 1]);\n * `targetFor` overrides the bar per task (task-specific satisfaction) — when set, the\n * per-task bar replaces every entry of `targets` for that task. */\nexport function anytimeReport(\n spans: WaterfallSpan[],\n opts?: { targets?: number[]; targetFor?: (taskId: string) => number },\n): AnytimeReport {\n const targets = opts?.targets ?? [1]\n const byRun = new Map<string, WaterfallSpan[]>()\n for (const s of spans) {\n if (!s.label.startsWith('shot:')) continue\n const list = byRun.get(s.runId) ?? []\n list.push(s)\n byRun.set(s.runId, list)\n }\n\n const perTask: AnytimeTaskCurve[] = []\n for (const [runId, shots] of byRun) {\n const m = runId.match(/^agentic:(.+):(.+)$/)\n const strategy = m?.[1] ?? runId\n const taskId = m?.[2] ?? runId\n const ordered = [...shots].sort((a, b) => (a.endMs ?? a.startMs) - (b.endMs ?? b.startMs))\n const t0 = Math.min(...ordered.map((s) => s.startMs))\n const taskTargets = opts?.targetFor ? [opts.targetFor(taskId)] : targets\n // ONE best-so-far definition, shared with the live stop rules.\n const bests = bestSoFar(ordered.map((s) => (typeof s.score === 'number' ? s.score : undefined)))\n let cumUsd = 0\n const points: AnytimeTaskCurve['points'] = []\n const hits: AnytimeTaskCurve['hits'] = {}\n for (const t of taskTargets) hits[String(t)] = null\n for (const [i, s] of ordered.entries()) {\n cumUsd += s.usd\n const best = bests[i] as number\n const elapsedMs = (s.endMs ?? s.startMs) - t0\n points.push({ elapsedMs, cumUsd, best })\n for (const t of taskTargets) {\n if (hits[String(t)] === null && best >= t) {\n hits[String(t)] = { ms: elapsedMs, shots: points.length, usd: cumUsd }\n }\n }\n }\n perTask.push({ taskId, strategy, points, hits })\n }\n\n const byStrategy = new Map<string, AnytimeTaskCurve[]>()\n for (const t of perTask) {\n const list = byStrategy.get(t.strategy) ?? []\n list.push(t)\n byStrategy.set(t.strategy, list)\n }\n\n const perStrategy: AnytimeStrategySummary[] = []\n for (const [strategy, tasks] of byStrategy) {\n const totalMs = tasks.reduce((s, t) => s + (t.points[t.points.length - 1]?.elapsedMs ?? 0), 0)\n const totalUsd = tasks.reduce((s, t) => s + (t.points[t.points.length - 1]?.cumUsd ?? 0), 0)\n const maxShots = Math.max(0, ...tasks.map((t) => t.points.length))\n const curveByShot: number[] = []\n for (let i = 0; i < maxShots; i += 1) {\n // A task with fewer shots carries its final best forward (it stopped — its\n // best-so-far is what an operator would have at that point).\n const vals = tasks.map(\n (t) => (t.points[Math.min(i, t.points.length - 1)] as { best: number }).best,\n )\n curveByShot.push(vals.reduce((s, v) => s + v, 0) / vals.length)\n }\n const auc = areaUnderCurve(curveByShot)\n const summaryTargets = opts?.targetFor ? [Number.NaN] : targets\n for (const t of summaryTargets) {\n const key = (\n taskCurve: AnytimeTaskCurve,\n ): { ms: number; shots: number; usd: number } | null =>\n opts?.targetFor\n ? (Object.values(taskCurve.hits)[0] ?? null)\n : (taskCurve.hits[String(t)] ?? null)\n const reached = tasks.filter((x) => key(x) !== null)\n perStrategy.push({\n strategy,\n target: t,\n tasks: tasks.length,\n reachedTarget: reached.length,\n medianTttMs: median(reached.map((x) => (key(x) as { ms: number }).ms)),\n medianShotsToTarget: median(reached.map((x) => (key(x) as { shots: number }).shots)),\n ertMs: reached.length > 0 ? totalMs / reached.length : null,\n erUsd: reached.length > 0 ? totalUsd / reached.length : null,\n curveByShot,\n auc,\n })\n }\n }\n perStrategy.sort((a, b) => a.strategy.localeCompare(b.strategy) || a.target - b.target)\n return { targets, perTask, perStrategy }\n}\n\n/** One row per (strategy, satisficing target): the shareable time-to-satisfactory table. */\nexport function renderAnytimeTable(report: AnytimeReport): string {\n const lines = [\n `anytime metrics · satisficing targets [${report.targets.join(', ')}] · ERT = Σ all wall-time / #successes (COCO)`,\n 'strategy ≥tgt reach med-TTT med-shots ERT(all-in) $/success AUC curve',\n ]\n for (const s of report.perStrategy) {\n const curve = s.curveByShot.map((v) => '▁▂▃▄▅▆▇█'[Math.min(7, Math.floor(v * 8))]).join('')\n const tgt = Number.isNaN(s.target) ? 'task' : s.target.toFixed(2)\n lines.push(\n `${s.strategy.padEnd(19)} ${tgt.padStart(4)} ${String(s.reachedTarget).padStart(4)}/${String(s.tasks).padEnd(3)} ` +\n `${s.medianTttMs === null ? ' —' : `${(s.medianTttMs / 1000).toFixed(1).padStart(6)}s`} ` +\n `${s.medianShotsToTarget === null ? ' —' : String(s.medianShotsToTarget).padStart(5)} ` +\n `${s.ertMs === null ? ' —' : `${(s.ertMs / 1000).toFixed(1).padStart(9)}s`} ` +\n `${s.erUsd === null ? ' —' : `$${s.erUsd.toFixed(4)}`} ${s.auc.toFixed(2)} ${curve}`,\n )\n }\n return lines.join('\\n')\n}\n","/**\n *\n * PROGRESS-BASED STOP RULES — end a long-horizon run for the right reason.\n *\n * Every existing bound is a CEILING: iterations, tokens, dollars, an absolute deadline, a turn\n * cap. A ceiling answers \"may this run continue?\" and never \"is this run still getting anywhere?\".\n * So a supervision tree that stopped learning at settle 4 keeps buying workers until it hits a\n * wall — the run ends on exhaustion, and the operator cannot tell a run that finished from a run\n * that ran out.\n *\n * A stop rule reads the run's own PROGRESS and decides. Three signals feed it:\n * - the objective curve over settled work (best-so-far, from `anytime.ts` — see below),\n * - the LIVE worker feed (`WorkerProgress`: `idleMs`, `stalled`, `turns`, `tokens`),\n * - tree-level shape (how many are in flight, how many are waiting, when the last settle landed).\n *\n * ── Two boundaries this module holds deliberately ───────────────────────────────────────────────\n *\n * ENFORCEMENT lives here; THRESHOLDS do not. \"Stop after 5 settles with no improvement\" is a\n * judgment about a domain — how noisy its scores are, how expensive a worker is, how much a late\n * breakthrough is worth. That belongs to the caller (a loop, a bench, a product). Every rule below\n * takes its thresholds as required options with no hidden defaults for the numbers that decide;\n * the module ships the MECHANISM and refuses to ship the judgment.\n *\n * A stop rule can only ADD a stop, never remove one. The driver evaluates the hard ceilings\n * (`poolStarved`, `deadlinePassed`, abort, the driver's own stop) FIRST and independently; the\n * rule is consulted only when they all say \"continue\". So no rule can talk a run past its budget.\n *\n * ── What is reused, not re-derived ──────────────────────────────────────────────────────────────\n *\n * `anytime.ts` already computed best-so-far curves, their area, and plateau detection — but only\n * after a run was over, from waterfall spans. Rather than write a second copy for the live path,\n * `bestSoFar` / `areaUnderCurve` / `plateauLength` were extracted there and are imported here. A\n * stop rule that calls a run plateaued therefore agrees, number for number, with the report that\n * later judges whether stopping was right.\n *\n * @experimental\n */\n\nimport { ValidationError } from '../../errors'\nimport { areaUnderCurve, bestSoFar, plateauLength } from '../anytime'\nimport type { WorkerProgress } from './progress'\nimport type { Scope, Settled } from './types'\n\n/** One settled unit of work, reduced to what a stop rule reads. `objective` is the run's own\n * quality signal (a verdict score, a test pass-rate, a judge rating); `undefined` = this\n * settlement produced no measurable objective (it failed, or nothing scored it). */\nexport interface ProgressSample {\n readonly id: string\n /** Epoch ms the settlement was observed. */\n readonly at: number\n readonly objective?: number\n /** True when the settlement passed its deliverable check — a scored-but-undelivered result is\n * not progress. */\n readonly delivered: boolean\n}\n\n/** The read-model a `StopRule` decides from — the run's progress, not its budget. */\nexport interface ProgressView {\n readonly now: number\n /** Settlements observed so far, in the order they landed. */\n readonly settles: number\n /** Of those, how many passed their deliverable check. */\n readonly delivered: number\n /** Best-so-far objective after each settlement (`anytime.bestSoFar`). */\n readonly curve: ReadonlyArray<number>\n /** The current best objective; `0` when nothing has scored. */\n readonly best: number\n /** Mean of the best-so-far curve — how EARLY the run climbed (`anytime.areaUnderCurve`). */\n readonly auc: number\n /** Epoch ms of the most recent settlement; `0` when none has landed. */\n readonly lastSettleAt: number\n /** Epoch ms of the most recent improvement in best-so-far; `0` when none. */\n readonly lastImprovementAt: number\n /** Settlements since the last improvement — `0` right after one improves. */\n readonly settlesSinceImprovement: number\n /** Live read of every non-terminal worker (the `Scope.progress` feed). Empty when the caller\n * supplied no scope. */\n readonly workers: ReadonlyArray<WorkerProgress>\n /** Nodes running or acquiring. */\n readonly inFlight: number\n /** Armed wait-state nodes — deliberately separate from `inFlight`: a tree whose only remaining\n * nodes are waits is NOT stalled, it is waiting on the world. */\n readonly waiting: number\n}\n\n/** A stop rule's answer. `reason` is required when stopping — a run that ends must be able to say\n * why in the result, and an unexplained early stop is indistinguishable from a bug. */\nexport type StopDecision =\n | { readonly stop: false }\n | { readonly stop: true; readonly reason: string }\n\n/** Evaluated from the progress feed, never from the budget. Pure and synchronous: it is called on\n * the driver's hot path, once per turn. */\nexport type StopRule = (view: ProgressView) => StopDecision\n\nconst CONTINUE: StopDecision = { stop: false }\n\n/** Accumulates settlements and materializes a `ProgressView`. Idempotent by settlement id, so a\n * caller may re-push its whole roster every turn (the driver does exactly that) without\n * double-counting or moving a recorded timestamp. */\nexport interface ProgressTracker {\n /** Record a settlement. A second call with the same `id` is ignored. Returns true when it was\n * new. */\n record(sample: ProgressSample): boolean\n /** Materialize the view. Pass the live `Scope` to include the worker feed and tree shape. */\n view(scope?: Scope<unknown>, opts?: { readonly stallAfterMs?: number }): ProgressView\n /** Evaluate a rule against the current view. */\n evaluate(\n rule: StopRule,\n scope?: Scope<unknown>,\n opts?: { readonly stallAfterMs?: number },\n ): StopDecision\n /** The samples recorded so far, in order. */\n samples(): ReadonlyArray<ProgressSample>\n}\n\nexport interface ProgressTrackerOptions {\n /** Clock for `view().now`. Defaults to `Date.now`. */\n readonly now?: () => number\n /** Treat a settlement that did NOT pass its deliverable check as having no objective. Default\n * true — \"scored 0.9 but never delivered\" is not progress, and counting it as progress is the\n * exact way a plateau rule gets talked out of firing. */\n readonly requireDelivered?: boolean\n /** How much the best-so-far must rise for a settlement to count as an IMPROVEMENT. Default 0\n * (any strict rise counts). Raise it to ignore score noise. */\n readonly minImprovement?: number\n}\n\n/** Build the settled-work ledger a `StopRule` decides from: record each settlement (idempotent by\n * id) and materialize a `ProgressView` combining the best-so-far curve with the live worker feed. */\nexport function createProgressTracker(opts: ProgressTrackerOptions = {}): ProgressTracker {\n const now = opts.now ?? Date.now\n const requireDelivered = opts.requireDelivered ?? true\n const minImprovement = opts.minImprovement ?? 0\n const seen = new Set<string>()\n const recorded: ProgressSample[] = []\n\n return {\n record(sample) {\n if (seen.has(sample.id)) return false\n seen.add(sample.id)\n recorded.push(sample)\n return true\n },\n samples: () => [...recorded],\n view(scope, viewOpts) {\n const objectives = recorded.map((s) =>\n requireDelivered && !s.delivered ? undefined : s.objective,\n )\n const curve = bestSoFar(objectives)\n const best = curve.length > 0 ? (curve[curve.length - 1] as number) : 0\n let lastImprovementAt = 0\n let lastImprovementIdx = -1\n let prev = 0\n for (const [i, value] of curve.entries()) {\n if (value - prev > minImprovement) {\n lastImprovementAt = (recorded[i] as ProgressSample).at\n lastImprovementIdx = i\n }\n prev = value\n }\n const treeView = scope?.view\n const workers: WorkerProgress[] = []\n if (scope && treeView) {\n for (const node of treeView.nodes) {\n if (node.status === 'done' || node.status === 'failed' || node.status === 'cancelled') {\n continue\n }\n // A wait-state is not a worker. It produces no metered activity by design, so including\n // it here would make every waiting tree read as a fleet of stalled workers — the exact\n // false positive `allWorkersStalled` exists to avoid. It is counted in `waiting` instead.\n if (node.status === 'waiting') continue\n const p = scope.progress(\n node.id,\n viewOpts?.stallAfterMs !== undefined\n ? { now: now(), stallAfterMs: viewOpts.stallAfterMs }\n : { now: now() },\n )\n if (p) workers.push(p)\n }\n }\n return {\n now: now(),\n settles: recorded.length,\n delivered: recorded.filter((s) => s.delivered).length,\n curve,\n best,\n auc: areaUnderCurve(curve),\n lastSettleAt:\n recorded.length > 0 ? (recorded[recorded.length - 1] as ProgressSample).at : 0,\n lastImprovementAt,\n settlesSinceImprovement:\n lastImprovementIdx < 0 ? recorded.length : recorded.length - 1 - lastImprovementIdx,\n workers,\n inFlight: treeView?.inFlight ?? 0,\n waiting: treeView?.waiting ?? 0,\n }\n },\n evaluate(rule, scope, viewOpts) {\n return rule(this.view(scope, viewOpts))\n },\n }\n}\n\n/** Build a `ProgressSample` from a scope settlement. The objective is the verdict score and\n * `delivered` is the verdict's `valid` — the SAME single delivery signal `finalizeBestDelivered`\n * and `defaultSelectWinner` use, so \"progress\" and \"winner\" cannot disagree. */\nexport function sampleFromSettled(settled: Settled<unknown>, at: number): ProgressSample {\n if (settled.kind === 'down') {\n return { id: settled.handle.id, at, delivered: false }\n }\n return {\n id: settled.handle.id,\n at,\n ...(settled.verdict?.score !== undefined ? { objective: settled.verdict.score } : {}),\n delivered: settled.verdict?.valid === true,\n }\n}\n\n// ── The default rules ────────────────────────────────────────────────────────────────────────\n//\n// Each takes its thresholds as REQUIRED options. A default number here would be this module\n// deciding a domain's judgment for it — which is the boundary the header states.\n\nexport interface NoProgressForOptions {\n /** Stop when this many ms have passed since the last SETTLEMENT. Omit to not bound on time. */\n readonly ms?: number\n /** Stop when this many settlements have landed with no improvement in best-so-far. Omit to not\n * bound on settles. */\n readonly settles?: number\n /** Never stop before this many settlements have landed — the warm-up that stops a rule from\n * firing on an empty run. Default 1. */\n readonly minSettles?: number\n}\n\n/**\n * \"Nothing new has happened.\" Fires when the run has produced no new settled work for `ms`, or no\n * IMPROVEMENT over the last `settles` settlements.\n *\n * A tree whose only remaining nodes are armed WAITS is exempt from the time bound: a run waiting\n * on CI is not a run that stopped making progress, and killing it there would defeat mechanic C.\n */\nexport function noProgressFor(opts: NoProgressForOptions): StopRule {\n if (opts.ms === undefined && opts.settles === undefined) {\n throw new ValidationError('noProgressFor: set at least one of { ms, settles }')\n }\n if (opts.ms !== undefined && opts.ms <= 0) {\n throw new ValidationError('noProgressFor: ms must be > 0')\n }\n if (opts.settles !== undefined && opts.settles < 1) {\n throw new ValidationError('noProgressFor: settles must be >= 1')\n }\n const minSettles = opts.minSettles ?? 1\n return (v) => {\n if (v.settles < minSettles) return CONTINUE\n if (opts.settles !== undefined && v.settlesSinceImprovement >= opts.settles) {\n return {\n stop: true,\n reason: `no-progress: ${v.settlesSinceImprovement} settles with no improvement (limit ${opts.settles}), best=${v.best}`,\n }\n }\n if (opts.ms !== undefined && v.waiting === 0 && v.lastSettleAt > 0) {\n const idle = v.now - v.lastSettleAt\n if (idle >= opts.ms) {\n return {\n stop: true,\n reason: `no-progress: ${idle}ms since the last settlement (limit ${opts.ms}ms)`,\n }\n }\n }\n return CONTINUE\n }\n}\n\nexport interface PlateauOptions {\n /** How many trailing settlements to judge. The rule fires when the whole window failed to lift\n * the best-so-far by more than `minDelta`. */\n readonly window: number\n /** The rise that counts as an improvement — the domain's noise floor. `0` means any strict rise\n * counts. */\n readonly minDelta: number\n /** Never fire before this many settlements. Defaults to `window` (so the first decision is made\n * on a full window, not on a partial one). */\n readonly minSettles?: number\n}\n\n/**\n * \"The objective has stopped climbing.\" Fires when the best-so-far curve has risen by no more than\n * `minDelta` across the last `window` settlements.\n *\n * Built on `anytime.plateauLength` — the same plateau math the post-run anytime report uses, so a\n * rule that stops a run and a report that grades the decision cannot disagree about whether the\n * run was flat.\n */\nexport function plateau(opts: PlateauOptions): StopRule {\n if (!Number.isInteger(opts.window) || opts.window < 1) {\n throw new ValidationError('plateau: window must be a positive integer')\n }\n if (!Number.isFinite(opts.minDelta) || opts.minDelta < 0) {\n throw new ValidationError('plateau: minDelta must be >= 0')\n }\n const minSettles = opts.minSettles ?? opts.window\n return (v) => {\n if (v.settles < minSettles) return CONTINUE\n const flat = plateauLength(v.curve, opts.minDelta)\n if (flat >= opts.window) {\n return {\n stop: true,\n reason: `plateau: best-so-far rose <= ${opts.minDelta} over the last ${flat} settles (window ${opts.window}), best=${v.best}, auc=${v.auc.toFixed(3)}`,\n }\n }\n return CONTINUE\n }\n}\n\nexport interface AllWorkersStalledOptions {\n /** Require at least this many live workers before the rule can fire — one stalled worker in a\n * one-worker tree is a weaker signal than a whole fleet going quiet. Default 1. */\n readonly minWorkers?: number\n /** Idle time that counts as stalled, passed through to the live progress read. Omit = the\n * runtime default (`DEFAULT_STALL_AFTER_MS`). */\n readonly stallAfterMs?: number\n}\n\n/**\n * \"Everyone is stuck.\" Fires when every live worker reads `stalled` — no metered activity for\n * longer than the stall threshold — and none of the tree is merely waiting.\n *\n * `stalled` is a derived read at observation time, never a background watchdog; this rule only\n * reads it. A tree with armed waits never fires: waiting is not stalling.\n */\nexport function allWorkersStalled(opts: AllWorkersStalledOptions = {}): StopRule {\n const minWorkers = opts.minWorkers ?? 1\n return (v) => {\n if (v.waiting > 0) return CONTINUE\n if (v.workers.length < minWorkers) return CONTINUE\n if (!v.workers.every((w) => w.stalled)) return CONTINUE\n const worst = Math.max(...v.workers.map((w) => w.idleMs))\n return {\n stop: true,\n reason: `all-stalled: ${v.workers.length} live workers idle, worst ${worst}ms`,\n }\n }\n}\n\n/** Stop when ANY rule stops — the ordinary composition (each rule is a separate reason to end). */\nexport function anyOf(...rules: ReadonlyArray<StopRule>): StopRule {\n return (v) => {\n for (const rule of rules) {\n const d = rule(v)\n if (d.stop) return d\n }\n return CONTINUE\n }\n}\n\n/** Stop only when EVERY rule stops — for a conservative gate that needs corroboration. */\nexport function allOf(...rules: ReadonlyArray<StopRule>): StopRule {\n if (rules.length === 0) throw new ValidationError('allOf: needs at least one rule')\n return (v) => {\n const reasons: string[] = []\n for (const rule of rules) {\n const d = rule(v)\n if (!d.stop) return CONTINUE\n reasons.push(d.reason)\n }\n return { stop: true, reason: reasons.join(' AND ') }\n }\n}\n","/**\n *\n * `driverAgent` — the driver's BRAIN.\n *\n * The recursive driver-executor (`driver-executor.ts`) runs a driver `Agent.act` inside a\n * nested `Scope`; this is the intelligent `act`: it mounts the coordination MCP verbs\n * (`createCoordinationTools`) over that scope and runs an LLM tool-loop, so the driver\n * REASONS — spawn / observe / steer / await / stop — about how to drive its children,\n * instead of running a fixed script. Each turn: ask the driver LLM for tool calls, run them\n * against the live scope, fold the results back, repeat until the driver stops (no tool\n * calls) or the turn cap forces a keep-best finalize.\n *\n * Recursion composes through `makeWorkerAgent`: `spawn_agent` resolves a `profile` to a\n * worker LEAF or — when the profile is a driver — a `driverChild` wrapping ANOTHER\n * `driverAgent` over its own nested scope (see `driver-executor.ts`). So an agent\n * drives an agent that drives an agent, each an LLM tool-loop, all on one conserved-budget\n * tree.\n *\n * Two seams are INJECTED so the loop runs offline with no creds and stays decoupled:\n * - `brain` (`ToolLoopChat`) — one driver-LLM turn over the canonical tool-loop seam; a test\n * drives a scripted mock, production passes the router's tool-calling (`routerBrain`), a\n * sandboxed harness drives the verbs as MCP tools. The same seam every tool-loop uses.\n * - `systemPrompt` — the driver's stance (the agent-eval worker-driver prompt / the prompt\n * generator). Injected, never hardcoded — the prompt is a pluggable role.\n *\n * @experimental\n */\n\nimport { RuntimeRunStateError, ValidationError } from '../../errors'\nimport type { McpToolDescriptor } from '../../mcp/server'\nimport {\n type AnalystRegistry,\n type CoordinationEvent,\n coordinationVerbNames,\n createCoordinationTools,\n type MakeWorkerAgent,\n type SettledWorker,\n type WorkerWatchOptions,\n} from '../../mcp/tools/coordination'\nimport type { ToolSpec } from '../router-client'\nimport {\n runBrainLoop,\n type ToolLoopChat,\n type ToolLoopCompaction,\n type ToolLoopCompactionOptions,\n} from '../tool-loop'\nimport type { DeliverableSpec } from './completion-gate'\nimport type { PriorCoordination } from './coordination-log'\nimport {\n bestDelivered,\n pickBestDelivered,\n runFinalizer,\n runTree,\n type SupervisorFinalizer,\n} from './finalizer'\nimport {\n createProgressTracker,\n type ProgressTracker,\n type StopDecision,\n type StopRule,\n} from './stop-rules'\nimport type {\n Agent,\n Budget,\n NodeSnapshot,\n ResultBlobStore,\n ResumedWork,\n Scope,\n Spend,\n TreeView,\n} from './types'\n\nexport interface DriverAgentOptions {\n readonly name: string\n /** The driver-LLM seam — ONE inference turn over the conversation + the coordination tool specs\n * (the canonical `ToolLoopChat`): a scripted mock offline, the router's tool-calling in\n * production, or a sandboxed harness. The same seam every tool-loop uses; no bespoke shape. */\n readonly brain: ToolLoopChat\n /** Shared blob store — `observe_agent` reads settled outputs through it. */\n readonly blobs: ResultBlobStore\n /** Resolve a spawned `profile` to a worker LEAF or a driver child (the recursion seam). */\n readonly makeWorkerAgent: MakeWorkerAgent\n /** Per-child budget reserved from the conserved pool on each spawn. */\n readonly perWorker: Budget\n /** Independent completion check for work the driver performs itself. When present, the driver\n * receives `submit_result`; the first passing submission ends the loop and becomes the output. */\n readonly deliverable?: DeliverableSpec<unknown>\n /** Hard cap on simultaneously-LIVE workers — `spawn_agent` fails closed once this many are in\n * flight (a concurrency fence on top of the conserved-pool fence). Omit/`<= 0` = no cap. */\n readonly maxLiveWorkers?: number\n /** The analyst lenses available to the driver. Required for `analyzeOnSettle` (and `run_analyst`).\n * Unset → no analyst feed (status quo: the driver gets settled outputs, no findings). */\n readonly analysts?: AnalystRegistry\n /** Analyst kind ids run AUTOMATICALLY when a worker settles `done` — each result re-enters as a\n * `finding` the driver pulls and composes its next steer from. The UP-leg of the self-improving\n * loop. Omit/empty = no auto-analysis (status quo). Requires `analysts`. */\n readonly analyzeOnSettle?: ReadonlyArray<string>\n /** Run the ONLINE detector panel over each worker's LIVE tool trace and raise a `finding` the\n * moment it loops/error-storms — mid-run evidence to steer on, not a settle-time post-mortem.\n * Omit = no online watching. */\n readonly watchWorkers?: WorkerWatchOptions\n /** Idle time after which `observe_agent` reports a worker as stalled (a derived read; nothing is\n * killed). Omit = the runtime default. */\n readonly stallAfterMs?: number\n /** The driver's stance — a string, or built from the task (the worker-driver prompt /\n * the generator). INJECTED so the prompt is a pluggable, optimizable role. */\n readonly systemPrompt: string | ((task: unknown) => string)\n /** WORK tools the driver may call DIRECTLY (alongside the coordination verbs) — so the driver is\n * not a pure manager but a full agent that can ACT (do simple work itself) OR SPAWN (delegate).\n * Each is a router tool spec; their names must not collide with the coordination verbs. Pair with\n * `executeExtraTool`. Unset → coordination-only (the prior behavior). */\n readonly extraTools?: ReadonlyArray<{\n readonly name: string\n readonly description?: string\n readonly parameters: Record<string, unknown>\n }>\n /** Runs an `extraTools` call. Returns a string result, or null/undefined to signal \"not handled\"\n * so the call falls through to the coordination dispatch. Required iff `extraTools` is set. */\n readonly executeExtraTool?: (\n name: string,\n args: Record<string, unknown>,\n ) => Promise<string | null | undefined>\n /** Max driver turns before the loop force-finalizes on the best settled child. Default 16.\n * `0` lifts the turn-COUNT cap: the loop is bounded instead by the conserved budget pool,\n * an absolute deadline, the driver's own stop, and abort (checked in-loop). A finite\n * anti-runaway tripwire still guards a degenerate driver that loops on a no-spawn tool. */\n readonly maxTurns?: number\n /** Injected clock for the in-loop absolute-deadline guard — keeps the deadline check\n * deterministic in tests. Defaults to `Date.now`. */\n readonly now?: () => number\n /**\n * PROGRESS-derived stop (mechanic D). Today a run ends on a ceiling — iterations, tokens,\n * dollars, deadline, turn cap — which answers \"may it continue?\" and never \"is it still getting\n * anywhere?\". A stop rule reads the run's own progress (best-so-far over settled work, time\n * since the last settle, the live worker feed) and ends a run that has stopped learning BEFORE\n * it exhausts a budget.\n *\n * Composes with, and can never override, the hard guards: `poolStarved` / `deadlinePassed` /\n * abort / the driver's own stop are evaluated first, so a rule can only ADD a stop.\n *\n * THRESHOLDS are the caller's judgment, not this module's — build the rule with\n * `plateau({window, minDelta})` / `noProgressFor({...})` / `allWorkersStalled({...})` from\n * `supervise/stop-rules`. Omit ⇒ ceilings only (unchanged behavior).\n */\n readonly stopRule?: StopRule\n /** Called once with the rule's reason when a `stopRule` ends the run — so a caller can record\n * WHY a run stopped early instead of inferring it from an unexhausted budget. */\n readonly onProgressStop?: (reason: string) => void\n /** Give the driver brain a chapter-lifecycle on its OWN context window. The LLM-brain front doors\n * lose to a dumb-Ralph respawn because the brain re-bills its whole coordination transcript every\n * turn — the same context overflow a single steered agent suffers, one level up. With this set,\n * once the brain's running conversation exceeds `thresholdTokens` it distills the accumulated\n * history to a compact progress note and continues fresh: the supervisor analog of respawning\n * against external tracking state, except the live `Scope` roster IS the durable state. Default\n * off (no behavior change). `distill` defaults to a self-summary authored by the brain combined\n * with the factual settled-worker roster; override to supply your own. */\n readonly compaction?: ToolLoopCompactionOptions\n /** Pass-through subscriber for every coordination bus event (settled / question / finding /\n * steer / answer) — what a durable caller hooks its coordination log onto. Omit = no observer. */\n readonly onEvent?: (event: CoordinationEvent) => void | Promise<void>\n /** Questions + findings a durable coordination log replayed from a prior process of this run.\n * Questions seed the ledger (`list_questions`, blocking-stop policy); both feed the resume\n * brief. Omit = fresh (every run that is not a resume). */\n readonly priorCoordination?: PriorCoordination\n /** How the settled-worker ledger becomes the run's output. Default `bestDelivered` — the single\n * highest-scoring DELIVERED child (the exact keep-best every existing caller had). Runs under\n * the delivered-only invariant (`runFinalizer`): whatever the finalizer, an undelivered or\n * invalid child's output stays unreachable. */\n readonly finalizer?: SupervisorFinalizer\n}\n\n/** The default chapter-close prompt: the brain summarizes its OWN progress for its future self before\n * the detailed history is dropped. Emphasis on PENDING work — the part a too-eager chapter-close\n * loses (the coding-burn counter-finding: closing after one fix leaves integration bugs uncircled). */\nconst distillInstruction =\n 'CONTEXT COMPACTION. Your detailed turn-by-turn history is about to be discarded to free your context window. Write a COMPLETE, compact handoff note for your future self so you can keep going without it. Cover: (1) what you have accomplished; (2) every worker you spawned and its current status/result; (3) what subtasks remain unfinished, failing, or unverified — be specific and exhaustive here, this is the part you must not lose; (4) your immediate next action. Do not call any tools; respond with the note only.'\n\n/** Factual ground truth for the digest — the live worker roster from Scope plus the delivered-result\n * ledger, independent of whatever the brain's prose summary captures. */\nfunction summarizeRoster(view: TreeView, settled: ReadonlyArray<SettledWorker>): string {\n if (view.nodes.length === 0) return 'Workers in current live scope: none yet.'\n const settledById = new Map(settled.map((w) => [w.id, w]))\n const lines = view.nodes.map((node) => formatRosterNode(node, settledById.get(node.id)))\n return `Workers in current live scope (ground truth from the run, ${view.nodes.length} total, ${view.inFlight} in flight):\\n${lines.join('\\n')}`\n}\n\nfunction formatRosterNode(node: NodeSnapshot, settled?: SettledWorker): string {\n const result =\n settled?.status === 'done'\n ? `, delivered=${settled.valid ?? false}${\n settled.score !== undefined ? `, score=${settled.score}` : ''\n }${settled.outRef ? `, outRef=${settled.outRef}` : ''}`\n : settled?.status === 'down'\n ? `, reason=${settled.reason ?? 'unknown'}`\n : node.outRef\n ? `, outRef=${node.outRef}`\n : ''\n return `- ${node.id}: ${node.status}, label=${node.label}, runtime=${node.runtime}${result}`\n}\n\n/** maxTurns=0 anti-runaway tripwire: a finite ceiling for the ONE case the conserved pool can't\n * bound — a driver whose chat seam reports NO usage (so `scope.meter`/`pool.observe` is never\n * called and its turns don't drain the pool). With a usage-reporting seam, driver inference now\n * meters into the pool and `poolStarved` halts it; the pool + deadline + abort are the real bounds\n * and no healthy run approaches this. */\nconst runawayTripwireTurns = 2000\n\n/** Spawn-progress is impossible: the pool can't afford another worker AND nothing is in flight to\n * await. A long-horizon driver bounded by the conserved pool stops here instead of spinning (the\n * in-loop budget guard the turn cap alone never provided). Checks BOTH conserved channels: tokens\n * (can't afford a worker) and usd (a usd-capped pool whose ceiling the driver's own metered\n * inference has drained — `meter` debits usd, so without this a huge-token/small-usd pool would\n * overspend usd up to the turn tripwire). */\nfunction poolStarved(scope: Scope<unknown>, perWorker: Budget): boolean {\n const b = scope.budget\n if (b.reservedTokens > 0) return false // a child is in flight — await it, don't finalize early\n const tokenStarved = b.tokensLeft < perWorker.maxTokens\n const usdStarved = b.usdCapped && b.usdLeft <= 0\n return tokenStarved || usdStarved\n}\n\n/** The absolute wall-clock deadline (when the root set one) has passed. */\nfunction deadlinePassed(scope: Scope<unknown>, now: () => number): boolean {\n const b = scope.budget\n return b.deadlineMs > 0 && now() >= b.deadlineMs\n}\n\n/**\n * The PROGRESS-derived stop, evaluated strictly AFTER the hard ceilings above.\n *\n * Ordering is the contract, not a detail: `poolStarved` / `deadlinePassed` / abort / the driver's\n * own stop are checked first and independently, so a stop rule can only ever ADD a stop — it can\n * never keep a run alive past a budget it has exhausted. The rule reads the settled-work ledger\n * (via the tracker) plus the live worker feed off the scope; it spends nothing to do so.\n */\nfunction progressStop(\n tracker: ProgressTracker,\n rule: StopRule,\n coord: { settled(): ReadonlyArray<SettledWorker> },\n scope: Scope<unknown>,\n now: () => number,\n stallAfterMs: number | undefined,\n): StopDecision {\n // Fold every settlement the coordination ledger has recorded. `record` is idempotent by worker\n // id, so pushing the whole roster each turn costs O(settled) and never double-counts. The\n // timestamp is when the DRIVER observed the settlement, which is the resolution a per-turn guard\n // has; `SettledWorker.settledAt` carries the real instant when the ledger recorded one.\n for (const w of coord.settled()) {\n tracker.record({\n id: w.id,\n at: w.settledAt ?? now(),\n ...(w.score !== undefined ? { objective: w.score } : {}),\n delivered: w.status === 'done' && w.valid === true,\n })\n }\n return tracker.evaluate(rule, scope, stallAfterMs !== undefined ? { stallAfterMs } : undefined)\n}\n\n/**\n * Build the intelligent recursive driver. Its `act` is the LLM tool-loop; spawn it as a\n * `driverChild` (`driver-executor.ts`) to run it inside a nested scope, recursively.\n */\nexport function driverAgent(opts: DriverAgentOptions): Agent<unknown, unknown> {\n if (typeof opts.brain !== 'function') {\n throw new ValidationError('driverAgent: opts.brain must be a function')\n }\n // Fail loud on a half-wired work-tool seam: extra tool specs with no executor (or an executor\n // with no specs the model can see) is a silent no-op the house rules forbid.\n if ((opts.extraTools?.length ?? 0) > 0 && typeof opts.executeExtraTool !== 'function') {\n throw new ValidationError(\n 'driverAgent: extraTools requires executeExtraTool (how to run a work-tool call)',\n )\n }\n // Fail loud on a half-wired analyst seam (matches the extraTools pattern): analyze-on-settle with no\n // lens registry is a silent no-op the house rules forbid — the driver would get no findings, no error.\n if ((opts.analyzeOnSettle?.length ?? 0) > 0 && !opts.analysts) {\n throw new ValidationError(\n 'driverAgent: analyzeOnSettle requires analysts (the lens registry the kinds resolve against)',\n )\n }\n // A work tool that shadows a coordination verb would leave the driver unable to coordinate.\n // Validate against the reserved verb set HERE (construction), so the conflict fails loud — not\n // buried inside act() where the supervisor would swallow the throw into a quiet no-winner.\n const reserved = new Set<string>(coordinationVerbNames)\n for (const t of opts.extraTools ?? []) {\n if (reserved.has(t.name)) {\n throw new ValidationError(\n `driverAgent: extra work tool \"${t.name}\" collides with a coordination verb`,\n )\n }\n }\n // Fail loud on a nonsensical cap: a negative maxTurns would silently run zero turns and\n // finalize an empty no-winner — a silent zero the house rules forbid.\n if (opts.maxTurns !== undefined && opts.maxTurns < 0) {\n throw new ValidationError(\n 'driverAgent: maxTurns must be >= 0 (0 lifts the turn cap; bounds become the conserved pool + deadline + abort)',\n )\n }\n // maxTurns=0 lifts the turn-COUNT cap: a long-horizon decomposition must not die on an\n // arbitrary number of turns. It is bounded instead by the conserved budget pool, an absolute\n // deadline, the driver's own stop, and abort — all checked in-loop below. The tripwire is a\n // pure anti-runaway guard, NOT the intended limit.\n const maxTurns = opts.maxTurns === 0 ? runawayTripwireTurns : (opts.maxTurns ?? 16)\n const now = opts.now ?? Date.now\n\n return {\n name: opts.name,\n async act(task, scope: Scope<unknown>): Promise<unknown> {\n const coord = createCoordinationTools({\n scope,\n blobs: opts.blobs,\n makeWorkerAgent: opts.makeWorkerAgent,\n perWorker: opts.perWorker,\n ...(opts.deliverable ? { deliverable: opts.deliverable } : {}),\n ...(opts.maxLiveWorkers !== undefined ? { maxLiveWorkers: opts.maxLiveWorkers } : {}),\n ...(opts.analysts ? { analysts: opts.analysts } : {}),\n ...(opts.analyzeOnSettle ? { analyzeOnSettle: opts.analyzeOnSettle } : {}),\n ...(opts.watchWorkers ? { watchWorkers: opts.watchWorkers } : {}),\n ...(opts.stallAfterMs !== undefined ? { stallAfterMs: opts.stallAfterMs } : {}),\n ...(opts.onEvent ? { onEvent: opts.onEvent } : {}),\n ...(opts.priorCoordination?.questions.length\n ? { priorQuestions: opts.priorCoordination.questions }\n : {}),\n })\n // Resume-first: re-establish the prior process's supervision state BEFORE the first brain\n // turn — its armed-but-never-woken waits become live again on their ORIGINAL deadlines\n // (they settle through the same cursor `await_event` drains). Fail loud on a wait that\n // cannot be re-armed: silently dropping supervision state is worse than stopping.\n for (const w of scope.resume?.waits ?? []) {\n const rearmed = scope.wait(w.spec, { label: w.label })\n if (!rearmed.ok) {\n throw new RuntimeRunStateError(\n `driverAgent: cannot re-arm resumed wait '${w.label}' (${rearmed.reason})`,\n )\n }\n }\n const byName = new Map<string, McpToolDescriptor>(coord.tools.map((t) => [t.name, t]))\n const toolSpecs: ToolSpec[] = [\n ...coord.tools.map((t) => ({\n type: 'function' as const,\n function: { name: t.name, description: t.description, parameters: t.inputSchema },\n })),\n // Work tools the driver calls DIRECTLY — so it can ACT, not only delegate.\n ...(opts.extraTools ?? []).map((t) => ({\n type: 'function' as const,\n function: { name: t.name, description: t.description, parameters: t.parameters },\n })),\n ]\n const system =\n typeof opts.systemPrompt === 'function' ? opts.systemPrompt(task) : opts.systemPrompt\n\n // Built only when a rule is configured, so a run without one allocates and evaluates nothing.\n const tracker = opts.stopRule ? createProgressTracker({ now }) : undefined\n let progressStopReason: string | undefined\n\n // Meter the driver's OWN inference on EVERY turn into the conserved pool — the largest single\n // token consumer in the loop, and what makes maxTurns=0 genuinely bounded (a thinking driver\n // drains the pool → poolStarved). iterations:0 — the conserved iteration channel budgets\n // CHILD rounds, not driver turns.\n //\n // There is deliberately no branch that skips `scope.meter`. A turn whose brain reported no\n // usage is metered as an UNKNOWN turn (`tokensKnown: false`), not omitted: omitting it let the\n // pool and the journal record a turn that ran as a turn that cost nothing, which is the one\n // thing this package forbids — a missing measurement is never zero. The unknown turn debits\n // the zero it actually knows and permanently marks `pool.readout().tokensKnown` false, so a\n // reader of `tokensLeft` can see the balance is a ceiling rather than a measurement. A\n // scripted/mock turn takes this path too, so offline equal-k still debits exactly zero tokens.\n let driverTurn = 0\n const meteredBrain = async (\n messages: ReadonlyArray<Record<string, unknown>>,\n tools: ReadonlyArray<ToolSpec>,\n detail: Record<string, unknown>,\n ) => {\n // KNOWN LIMITATION (pre-existing, predates the streamed transport): a turn that THROWS is\n // never metered at all. The throw propagates out of `meteredBrain` before `scope.meter`\n // below, so a brain call that burned prefill and then failed (a 5xx after generation, an\n // abort mid-completion) leaves NO record — not even an unknown-marked one — and the pool's\n // `tokensKnown` stays true while real tokens were spent. Deferred deliberately: metering\n // the throw path means deciding what a partial turn debits and re-throwing after the meter\n // in every driver exit, which changes error-handling semantics across this file and belongs\n // in its own change. Filed separately; do not fix inline.\n const res = await opts.brain(messages, tools)\n // Nothing at all came back about what the turn cost: neither tokens nor dollars. Both\n // channels are marked unknown, mirroring how the pool already represents unknown dollars.\n //\n // KNOWN LIMITATION (pre-existing): \"a turn that reported tokens but no price is a\n // known-ZERO dollar turn\" is true for a genuinely free model and WRONG for an UNPRICED one.\n // `meterTurn` in `router-client.ts` returns `costUsd: undefined` both when a model costs\n // nothing and when it is simply missing from the price table, and the two are\n // indistinguishable here — so an unpriced model's real dollars are recorded as a measured\n // $0 with `usdKnown` left true, and a dollar-denominated cap under-counts. Fixing it means\n // the router result must distinguish \"free\" from \"unpriced\", which is an upstream contract\n // change. Filed separately; do not fix inline.\n const nothingReported = res.usage === undefined && res.costUsd === undefined\n const turnSpend: Spend = {\n iterations: 0,\n tokens: { input: res.usage?.input ?? 0, output: res.usage?.output ?? 0 },\n ...(res.usage === undefined ? { tokensKnown: false } : {}),\n usd: res.costUsd ?? 0,\n ...(nothingReported ? { usdKnown: false } : {}),\n ms: 0,\n }\n await scope.meter(turnSpend, {\n driver: opts.name,\n toolCalls: (res.toolCalls ?? []).map((c) => c.name),\n // The streamed transport says explicitly when it finished with no usage chunk (a broken\n // `include_usage` contract), which is a different fact from a brain that never reports\n // usage at all. Recorded on the turn so the journal distinguishes them.\n ...(res.usageUnknown === true ? { streamUsageMissing: true } : {}),\n ...detail,\n })\n return res\n }\n const chat: ToolLoopChat = async (messages, tools) => {\n const turn = driverTurn\n const res = await meteredBrain(messages, tools, {\n kind: 'driver-inference',\n turn,\n })\n driverTurn += 1\n return res\n }\n\n // Chapter-close on the brain's own window. The default distiller pairs the factual settled-worker\n // roster (from the live scope) with a brain-authored progress note; the brain call runs through\n // the metered `chat`, so the one-time O(history) distill cost debits the conserved pool like any\n // turn. It replaces the per-turn O(history) re-billing it removes.\n const compaction: ToolLoopCompaction | undefined = opts.compaction\n ? {\n thresholdTokens: opts.compaction.thresholdTokens,\n distill:\n opts.compaction.distill ??\n (async (msgs) => {\n const roster = summarizeRoster(scope.view, coord.settled())\n // KNOWN LIMITATION (pre-existing, predates the streamed transport): this `catch`\n // degrades a failed distill to a roster-only summary, which is the right product\n // behavior — compaction must not kill the run — but it also SWALLOWS the turn's\n // cost. `meteredBrain` throws before reaching `scope.meter`, so a distill that\n // burned a full O(history) prefill and then failed debits nothing and leaves the\n // pool's `tokensKnown` true. It is the same unmetered-throw gap as the main loop\n // (see `meteredBrain` above), reached through a different exit; both are deferred\n // to one change that decides what a thrown turn debits. Filed separately.\n try {\n const res = await meteredBrain(\n [...msgs, { role: 'user', content: distillInstruction }],\n [],\n { kind: 'driver-compaction', compactingTurn: driverTurn },\n )\n const narrative = (res.content ?? '').trim()\n return narrative ? `${roster}\\n\\n## Progress notes\\n${narrative}` : roster\n } catch (e) {\n return `${roster}\\n\\n## Progress notes\\nSummary unavailable: ${errMessage(e)}`\n }\n }),\n ...(opts.compaction.onCompact ? { onCompact: opts.compaction.onCompact } : {}),\n ...(opts.compaction.preserveHead !== undefined\n ? { preserveHead: opts.compaction.preserveHead }\n : {}),\n ...(opts.compaction.estimateTokens\n ? { estimateTokens: opts.compaction.estimateTokens }\n : {}),\n }\n : undefined\n\n await runBrainLoop({\n chat,\n tools: toolSpecs,\n ...(compaction ? { compaction } : {}),\n execute: async (name, args) => {\n // WORK FIRST: a work tool the driver runs itself (act). A non-null return is handled here;\n // null/undefined means \"not mine\" → fall through to the coordination dispatch (spawn/await/…).\n if (opts.executeExtraTool) {\n const worked = await runExtraTool(opts.executeExtraTool, name, args)\n if (worked !== null && worked !== undefined) return worked\n }\n const tool = byName.get(name)\n const result = tool ? await runTool(tool, args) : { error: `unknown tool: ${name}` }\n return safeJson(result)\n },\n initialMessages: [\n { role: 'system', content: system },\n { role: 'user', content: stringifyTask(task) },\n // The resume brief: on a resumed run the brain's FIRST context already carries the\n // committed settlements, the key states, the re-armed waits, carried-over questions/\n // findings, and the spend the run already paid — so it continues from the unresolved\n // work instead of re-planning (and re-paying) from scratch.\n ...(scope.resume\n ? [{ role: 'user', content: resumeBrief(scope.resume, opts.priorCoordination) }]\n : []),\n ],\n maxTurns,\n // The conserved-pool + deadline + external-stop bound (what maxTurns=0 relies on): a driver\n // that can no longer spawn (pool starved) or has run past the deadline stops here instead of\n // burning turns. Checked before each inference turn.\n hooks: {\n stopBefore: () => {\n // HARD CEILINGS FIRST, and independently — a progress rule may never keep a run alive\n // past one, so they are not folded into the same expression.\n if (\n coord.isStopped() ||\n scope.signal.aborted ||\n poolStarved(scope, opts.perWorker) ||\n deadlinePassed(scope, now)\n ) {\n return true\n }\n if (!opts.stopRule || !tracker) return false\n const decision = progressStop(\n tracker,\n opts.stopRule,\n coord,\n scope,\n now,\n opts.stallAfterMs,\n )\n if (!decision.stop) return false\n // `stopBefore` is a predicate the loop may consult more than once; the callback is a\n // one-shot notification, so it fires on the FIRST stop only.\n if (progressStopReason === undefined) {\n progressStopReason = decision.reason\n opts.onProgressStop?.(decision.reason)\n }\n return true\n },\n },\n })\n // Drain every already-settled child the brain never pulled — a gate-verified delivery must\n // never be lost to the driver's pull discipline (e.g. a brain that spawned and stopped\n // without awaiting). Non-blocking: live children are the supervisor's to tear down.\n await coord.drainResolved()\n // Direct work is eligible only through `submit_result`, after the same injected independent\n // check workers face. Raw driver prose remains ineligible. The first passing submission wins;\n // otherwise finalize over delivered children as before.\n const submitted = coord.submittedResult()\n if (submitted) return submitted.result\n return runFinalizer(opts.finalizer ?? bestDelivered, {\n settled: coord.settled(),\n blobs: opts.blobs,\n tree: runTree(scope),\n budget: scope.budget,\n })\n },\n }\n}\n\n/**\n * The factual context a resumed driver starts from — everything the durable stores prove about\n * the prior process(es): committed settlements, per-key states (completed / lost / failed),\n * re-armed waits, carried-over questions and findings, and the spend already paid. Injected as\n * the brain's first user-context on a resumed run so it continues from the unresolved work.\n */\nfunction resumeBrief(resume: ResumedWork<unknown>, prior?: PriorCoordination): string {\n const lines: string[] = [\n 'RESUME: this run continues a prior coordinator process. Its committed work is restored',\n 'below and already counts toward the deliverable — do NOT redo it. Continue from the',\n 'unresolved work only.',\n '',\n `Committed workers (${resume.settled.length}):`,\n ]\n if (resume.settled.length === 0) lines.push('- none')\n for (const s of resume.settled) {\n lines.push(\n s.kind === 'done'\n ? `- ${s.handle.id} (${s.handle.label}): done, score=${s.verdict?.score ?? 0}, valid=${\n s.verdict?.valid ?? false\n }, outRef=${s.outRef}`\n : `- ${s.handle.id} (${s.handle.label}): down, reason=${s.reason}`,\n )\n }\n const byState = (state: 'completed' | 'in-doubt' | 'down') =>\n [...resume.keys].filter(([, v]) => v.state === state)\n const completed = byState('completed')\n const lost = byState('in-doubt')\n const failed = byState('down')\n if (completed.length > 0) {\n lines.push(\n '',\n 'COMPLETED keys — spawn_agent with the same key returns the finished result, spending nothing:',\n ...completed.map(([k, v]) => `- ${k} → ${v.id} (${v.label})`),\n )\n }\n if (lost.length > 0) {\n lines.push(\n '',\n 'Keys LOST in flight with the prior process — this is the unresolved work; spawn_agent with the same key starts a fresh attempt:',\n ...lost.map(([k, v]) => `- ${k} (prior attempt ${v.id}, ${v.label})`),\n )\n }\n if (failed.length > 0) {\n lines.push(\n '',\n 'Keys whose prior attempt FAILED (settled down) — spawn_agent with the same key retries:',\n ...failed.map(([k, v]) => `- ${k} (prior attempt ${v.id}, ${v.label})`),\n )\n }\n if (resume.waits.length > 0) {\n lines.push(\n '',\n 'Pending waits RE-ARMED on their original deadlines (they settle through await_event):',\n ...resume.waits.map((w) => `- ${w.label} (${w.spec.kind})`),\n )\n }\n const openQuestions = (prior?.questions ?? []).filter(\n (q) => q.status === 'open' || q.status === 'escalated',\n )\n if (openQuestions.length > 0) {\n lines.push(\n '',\n 'Questions carried over, still undecided (answer_question decides them; list_questions shows all):',\n ...openQuestions.map(\n (q) => `- [${q.id}] from=${q.from}, urgency=${q.urgency}: ${q.question}`,\n ),\n )\n }\n if ((prior?.findings.length ?? 0) > 0) {\n lines.push(\n '',\n 'Analyst findings from the prior process:',\n ...(prior?.findings ?? []).map(\n (f) => `- ${f.analyst} on ${f.fromWorker}: ${safeJson(f.findings)}`,\n ),\n )\n }\n const spent = resume.priorSpend\n lines.push(\n '',\n 'Budget the run ALREADY spent before this process (it counts toward the run total):',\n `- child work: tokens in=${spent.childWork.tokens.input} out=${spent.childWork.tokens.output}, usd=${spent.childWork.usd}, iterations=${spent.childWork.iterations}`,\n `- driver inference: tokens in=${spent.driverInference.tokens.input} out=${spent.driverInference.tokens.output}, usd=${spent.driverInference.usd}`,\n )\n return lines.join('\\n')\n}\n\n/** Run a work tool. A throw is data to the driver (it can recover next turn), not a crash — fold\n * the error back as a string result. null/undefined passes through (the caller treats it as \"not\n * handled\" and falls to the coordination dispatch). */\nasync function runExtraTool(\n execute: (name: string, args: Record<string, unknown>) => Promise<string | null | undefined>,\n name: string,\n args: Record<string, unknown>,\n): Promise<string | null | undefined> {\n try {\n return await execute(name, args)\n } catch (e) {\n return `error: ${e instanceof Error ? e.message : String(e)}`\n }\n}\n\nasync function runTool(tool: McpToolDescriptor, args: Record<string, unknown>): Promise<unknown> {\n try {\n return await tool.handler(args)\n } catch (e) {\n // A tool throw is data to the driver (it can recover), not a crash — fold it back.\n return { error: e instanceof Error ? e.message : String(e) }\n }\n}\n\n/** Keep-best finalize under the completion-oracle: return the highest-scoring DELIVERED child's\n * output (settled `done` AND `valid` — its deliverable check passed). Returns undefined when no\n * child delivered — an honest \"the driver produced nothing\", never a high-scoring result that\n * ran without passing its check (Foreman's 0/18 lesson). `valid` is the single delivery signal,\n * matching `defaultSelectWinner`'s valid-first rule; the oracle just doesn't fall back to an\n * unchecked best-effort. The same argmax as the `bestDelivered` finalizer (`pickBestDelivered`);\n * this direct form serves callers that hold a bare ledger + blob store. */\nexport async function finalizeBestDelivered(\n settled: ReadonlyArray<{ status: string; score?: number; valid?: boolean; outRef?: string }>,\n blobs: ResultBlobStore,\n): Promise<unknown> {\n const delivered = settled.filter((w) => w.status === 'done' && w.valid === true)\n const best = pickBestDelivered(delivered)\n if (best === undefined) return undefined\n return best.outRef ? await blobs.get(best.outRef) : undefined\n}\n\nfunction stringifyTask(task: unknown): string {\n return typeof task === 'string' ? task : safeJson(task)\n}\n\nfunction safeJson(v: unknown): string {\n try {\n return JSON.stringify(v) ?? String(v)\n } catch {\n return String(v)\n }\n}\n\nfunction errMessage(e: unknown): string {\n return e instanceof Error ? e.message : String(e)\n}\n","/**\n *\n * Feedback persistence surface for the MCP layer.\n *\n * Feedback storage is product policy, so the MCP layer depends on this narrow\n * interface instead of choosing a knowledge store. The default implementation\n * is in-memory; consumers wire their own durable adapter via\n * `createMcpServer({ feedbackStore })`.\n *\n * Feedback events are append-only: every rating is a new event with a\n * fresh id, even when the same delegation is rated multiple times. The\n * caller decides how to roll up scores downstream.\n *\n * @experimental\n */\n\nimport type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types'\n\n/** @experimental */\nexport interface FeedbackEvent {\n id: string\n refersTo: DelegateFeedbackArgs['refersTo']\n rating: DelegateFeedbackArgs['rating']\n by: DelegateFeedbackArgs['by']\n capturedAt: string\n namespace?: string\n}\n\n/** @experimental */\nexport interface FeedbackStore {\n /** Append a new event. Never dedupes — every rating is its own event. */\n put(event: FeedbackEvent): Promise<void>\n /**\n * List events filtered by `namespace`. When `namespace` is omitted, list\n * across all namespaces. Returns events in insertion order.\n */\n list(filter?: { namespace?: string; refersToRef?: string }): Promise<FeedbackEvent[]>\n}\n\n/** In-memory `FeedbackStore` — suitable for single-process use and tests. @experimental */\nexport class InMemoryFeedbackStore implements FeedbackStore {\n private readonly events: FeedbackEvent[] = []\n\n async put(event: FeedbackEvent): Promise<void> {\n this.events.push({ ...event })\n }\n\n async list(filter: { namespace?: string; refersToRef?: string } = {}): Promise<FeedbackEvent[]> {\n let out = this.events\n if (filter.namespace !== undefined) {\n out = out.filter((event) => event.namespace === filter.namespace)\n }\n if (filter.refersToRef !== undefined) {\n out = out.filter((event) => event.refersTo.ref === filter.refersToRef)\n }\n return out.map((event) => ({ ...event }))\n }\n}\n\n/**\n * Project a `FeedbackEvent` down to the snapshot shape carried on\n * `delegation_history` entries.\n *\n * @experimental\n */\nexport function eventToSnapshot(event: FeedbackEvent): DelegationFeedbackSnapshot {\n const snap: DelegationFeedbackSnapshot = {\n id: event.id,\n score: event.rating.score,\n by: event.by,\n notes: event.rating.notes,\n capturedAt: event.capturedAt,\n }\n if (event.rating.label) snap.label = event.rating.label\n return snap\n}\n","/**\n *\n * Persistence port for the MCP delegation queue.\n *\n * `DelegationTaskQueue` keeps its working set in memory (status/history\n * reads stay synchronous) and journals every record mutation through a\n * `DelegationStore`. `DelegationTaskQueue.restore({ store })` is the load\n * path: it reads the full record set once at construction and rehydrates\n * the queue from it. After that the store only sees writes.\n *\n * Records MUST be JSON-safe — `FileDelegationStore` round-trips them\n * through `JSON.stringify`/`JSON.parse`, so a `Date`, `Map`, or function\n * smuggled into `args`/`result` would corrupt the journal.\n *\n * @experimental\n */\n\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { AgentEvalError } from '../errors'\nimport type { DelegationRecord } from './task-queue'\n\n/** @experimental */\nexport interface DelegationStore {\n /**\n * Read every persisted record. Called once, by\n * `DelegationTaskQueue.restore`, before any write. A missing backing\n * file is an empty store; an unparseable one throws\n * `DelegationStateCorruptError`.\n */\n loadAll(): Promise<DelegationRecord[]>\n /** Insert or replace the record keyed by `record.taskId`. */\n upsert(record: DelegationRecord): Promise<void>\n /**\n * Resolve an idempotency key to the taskId that claimed it, if any.\n * The queue serves submit-time dedupe from its rehydrated in-memory\n * index; this read exists for consumers that share a store across\n * processes without holding the full record set.\n */\n lookupIdempotencyKey(key: string): Promise<string | undefined>\n /** Delete the named records — the retention-cap eviction path. */\n remove(taskIds: readonly string[]): Promise<void>\n}\n\n/**\n * The persisted delegation state exists but cannot be parsed into\n * records. Fail loud: silently starting empty over a corrupt journal\n * would erase delegation history and re-run idempotent work. Opt into\n * recovery explicitly via `FileDelegationStoreOptions.recoverCorrupt`\n * (the bin maps `AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1` onto it),\n * which archives the corrupt file and starts fresh.\n *\n * @experimental\n */\nexport class DelegationStateCorruptError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n\n/**\n * A delegation-store read or write failed (filesystem error, store\n * called before `loadAll`, ...). Once the queue observes one, it stops\n * accepting new submissions — accepting work it cannot journal would\n * silently demote durable mode to in-memory mode.\n *\n * @experimental\n */\nexport class DelegationPersistenceError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('config', message, options)\n }\n}\n\n/** In-memory `DelegationStore` — suitable for single-process use and tests. @experimental */\nexport class InMemoryDelegationStore implements DelegationStore {\n private readonly records = new Map<string, DelegationRecord>()\n\n async loadAll(): Promise<DelegationRecord[]> {\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.records.set(record.taskId, cloneRecord(record))\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n for (const taskId of taskIds) this.records.delete(taskId)\n }\n}\n\n/** @experimental */\nexport interface FileDelegationStoreOptions {\n /** Absolute path of the JSON state file. Parent directories are created on first write. */\n filePath: string\n /**\n * When the state file exists but cannot be parsed, archive it to\n * `<filePath>.corrupt-<timestamp>` and start empty instead of\n * throwing `DelegationStateCorruptError`. Default false.\n */\n recoverCorrupt?: boolean\n}\n\ninterface PersistedDelegationState {\n version: 1\n records: DelegationRecord[]\n}\n\nconst STATE_FORMAT_VERSION = 1\n\n/**\n * JSON-file persistence for the delegation queue. Each write serializes\n * the full record set and lands it atomically (write to a sibling tmp\n * file, then `rename`), so readers never observe a torn file — a crash\n * mid-write leaves the previous snapshot intact. Writes are serialized\n * internally; concurrent `upsert`/`remove` calls cannot interleave.\n *\n * Built for the MCP server's scale (one stdio process, hundreds of\n * records): full-snapshot writes keep the format trivially inspectable\n * and corruption-detectable without a database dependency.\n *\n * @experimental\n */\nexport class FileDelegationStore implements DelegationStore {\n private readonly filePath: string\n private readonly recoverCorrupt: boolean\n private readonly records = new Map<string, DelegationRecord>()\n private loaded = false\n private writeTail: Promise<void> = Promise.resolve()\n private tmpSeq = 0\n\n constructor(options: FileDelegationStoreOptions) {\n this.filePath = options.filePath\n this.recoverCorrupt = options.recoverCorrupt ?? false\n }\n\n async loadAll(): Promise<DelegationRecord[]> {\n let raw: string\n try {\n raw = await readFile(this.filePath, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n this.loaded = true\n return []\n }\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to read ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n let state: PersistedDelegationState\n try {\n state = parsePersistedState(raw)\n } catch (err) {\n if (!this.recoverCorrupt) {\n throw new DelegationStateCorruptError(\n `FileDelegationStore: state file ${this.filePath} is corrupt (${errorMessage(err)}). ` +\n 'Repair or archive the file, or opt into automatic recovery ' +\n '(recoverCorrupt / AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1) to archive it and start empty.',\n { cause: err },\n )\n }\n const archivePath = `${this.filePath}.corrupt-${Date.now()}`\n await rename(this.filePath, archivePath)\n this.loaded = true\n return []\n }\n this.records.clear()\n for (const record of state.records) this.records.set(record.taskId, record)\n this.loaded = true\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.assertLoaded('upsert')\n this.records.set(record.taskId, cloneRecord(record))\n await this.enqueueWrite()\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n this.assertLoaded('lookupIdempotencyKey')\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n this.assertLoaded('remove')\n let changed = false\n for (const taskId of taskIds) {\n if (this.records.delete(taskId)) changed = true\n }\n if (changed) await this.enqueueWrite()\n }\n\n private assertLoaded(op: string): void {\n if (this.loaded) return\n // Writing before load would snapshot only the new records and clobber\n // whatever the file already holds.\n throw new DelegationPersistenceError(\n `FileDelegationStore: ${op} called before loadAll() — the on-disk state has not been read yet`,\n )\n }\n\n private enqueueWrite(): Promise<void> {\n const write = this.writeTail.then(() => this.writeSnapshot())\n this.writeTail = write.catch(() => {})\n return write\n }\n\n private async writeSnapshot(): Promise<void> {\n const state: PersistedDelegationState = {\n version: STATE_FORMAT_VERSION,\n records: [...this.records.values()],\n }\n const payload = `${JSON.stringify(state)}\\n`\n this.tmpSeq += 1\n const tmpPath = `${this.filePath}.tmp-${process.pid}-${this.tmpSeq}`\n try {\n await mkdir(dirname(this.filePath), { recursive: true })\n await writeFile(tmpPath, payload, 'utf8')\n await rename(tmpPath, this.filePath)\n } catch (err) {\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to write ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n }\n}\n\nfunction parsePersistedState(raw: string): PersistedDelegationState {\n const parsed: unknown = JSON.parse(raw)\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('top-level value is not an object')\n }\n const state = parsed as Record<string, unknown>\n if (state.version !== STATE_FORMAT_VERSION) {\n throw new Error(`unsupported state version ${JSON.stringify(state.version)}`)\n }\n if (!Array.isArray(state.records)) {\n throw new Error('`records` is not an array')\n }\n for (const record of state.records) {\n if (record === null || typeof record !== 'object') {\n throw new Error('a record entry is not an object')\n }\n const candidate = record as Record<string, unknown>\n if (typeof candidate.taskId !== 'string' || typeof candidate.status !== 'string') {\n throw new Error('a record entry is missing `taskId`/`status`')\n }\n }\n return { version: STATE_FORMAT_VERSION, records: state.records as DelegationRecord[] }\n}\n\nfunction cloneRecord(record: DelegationRecord): DelegationRecord {\n return structuredClone(record)\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n","/**\n *\n * Compact loop-trace tee for the delegation journal.\n *\n * The OTEL exporter ({@link createPropagatingTraceEmitter}) is a no-op\n * without `OTEL_EXPORTER_OTLP_ENDPOINT`, which leaves delegated work streams\n * dark in practice. This module derives the same loop → round → branch span\n * tree (via the shared {@link buildLoopSpanNodes} builder) into a small,\n * JSON-safe shape persisted directly on the `DelegationRecord` — observable\n * through `delegation_status` with no collector infrastructure. Both sinks\n * coexist: the OTEL export path is unchanged.\n *\n * Payload discipline: a record's trace is hard-capped (spans + serialized\n * bytes). Past the cap the OLDEST spans are dropped and the record carries a\n * `traceTruncated: true` marker — truncation is never silent.\n *\n * @experimental\n */\n\nimport { buildLoopSpanNodes } from '../otel-export'\nimport type { LoopTraceEmitter, LoopTraceEvent } from '../runtime/types'\n\n/**\n * One span of a delegation's compact trace. Flat (parent linkage by id), all\n * values JSON-safe scalars — `FileDelegationStore` round-trips records\n * through `JSON.stringify`. `meta` carries the span's attributes (GenAI\n * semconv keys + `tangle.loop.*` extensions) exactly as the OTEL sink emits\n * them, so a consumer can re-export journal traces losslessly.\n *\n * @experimental\n */\nexport interface DelegationTraceSpan {\n spanId: string\n /** Absent on the tree root. */\n parentSpanId?: string\n /** `'loop'` | `'loop.round'` | `'loop.iteration'` (or a sink-specific name). */\n name: string\n /** Topology level: loop root, plan round, or iteration branch. */\n kind: 'loop' | 'round' | 'branch'\n startMs: number\n endMs: number\n meta?: Record<string, string | number | boolean>\n}\n\n/** Default cap on spans retained per delegation record. @experimental */\nexport const DELEGATION_TRACE_MAX_SPANS = 512\n\n/** Default cap on the serialized trace payload per record, in bytes. @experimental */\nexport const DELEGATION_TRACE_MAX_BYTES = 256 * 1024\n\n/** @experimental */\nexport interface DelegationTraceCaps {\n /** Default {@link DELEGATION_TRACE_MAX_SPANS}. */\n maxSpans?: number\n /** Default {@link DELEGATION_TRACE_MAX_BYTES}. Approximate — measured as the\n * sum of per-span `JSON.stringify` lengths. */\n maxBytes?: number\n}\n\n/** @experimental */\nexport interface CappedDelegationTrace {\n trace: DelegationTraceSpan[]\n /** True when oldest spans were dropped to honor the caps. */\n truncated: boolean\n}\n\n/**\n * Derive the compact span tree for ONE loop run from its buffered\n * `LoopTraceEvent` stream. Same reconstruction as the OTEL exporter\n * ({@link buildLoopSpanNodes}); tolerates partial streams.\n *\n * @experimental\n */\nexport function buildDelegationTraceSpans(\n events: ReadonlyArray<LoopTraceEvent>,\n): DelegationTraceSpan[] {\n return buildLoopSpanNodes(events).map((node) => ({\n spanId: node.spanId,\n ...(node.parentSpanId !== undefined ? { parentSpanId: node.parentSpanId } : {}),\n name: node.name,\n kind: node.kind,\n startMs: node.startMs,\n endMs: node.endMs,\n ...(Object.keys(node.attrs).length > 0 ? { meta: node.attrs } : {}),\n }))\n}\n\n/**\n * Enforce the trace caps over an ordered (oldest-first) span list. Drops the\n * OLDEST spans first and reports `truncated: true` when anything was dropped;\n * the newest span always survives, so a non-empty input never caps to empty.\n * Dropping a parent may orphan surviving children's `parentSpanId` references\n * — acceptable for the flat journal shape; consumers treat unresolved parents\n * as roots.\n *\n * @experimental\n */\nexport function capDelegationTrace(\n spans: ReadonlyArray<DelegationTraceSpan>,\n caps?: DelegationTraceCaps,\n): CappedDelegationTrace {\n const maxSpans = caps?.maxSpans ?? DELEGATION_TRACE_MAX_SPANS\n const maxBytes = caps?.maxBytes ?? DELEGATION_TRACE_MAX_BYTES\n let start = Math.max(0, spans.length - maxSpans)\n const sizes = spans.map((span) => JSON.stringify(span).length + 1)\n let total = 0\n for (let i = start; i < sizes.length; i += 1) total += sizes[i]!\n while (start < spans.length - 1 && total > maxBytes) {\n total -= sizes[start]!\n start += 1\n }\n return { trace: spans.slice(start), truncated: start > 0 }\n}\n\n/**\n * Per-delegation trace collector. Buffers `LoopTraceEvent`s per runId\n * (mirroring the OTEL emitter's buffering) and hands the derived compact\n * spans to `onSpans` when a run reaches `loop.ended`. `settle()` drains runs\n * that never ended — a hard-aborted loop still leaves its partial tree in the\n * journal, unlike the OTEL path which drops it.\n *\n * @experimental\n */\nexport interface DelegationTraceCollector {\n emitter: LoopTraceEmitter\n /** Flush buffered events of runs that never reached `loop.ended`. */\n settle(): void\n}\n\n/** Build a `DelegationTraceCollector` that buffers loop-trace events and converts them to spans on settle. @experimental */\nexport function createDelegationTraceCollector(\n onSpans: (spans: DelegationTraceSpan[]) => void,\n): DelegationTraceCollector {\n const buffers = new Map<string, LoopTraceEvent[]>()\n const flush = (events: LoopTraceEvent[]): void => {\n const spans = buildDelegationTraceSpans(events)\n if (spans.length > 0) onSpans(spans)\n }\n return {\n emitter: {\n emit(event: LoopTraceEvent): void {\n const buf = buffers.get(event.runId)\n if (buf) buf.push(event)\n else buffers.set(event.runId, [event])\n if (event.kind === 'loop.ended') {\n const events = buffers.get(event.runId) ?? [event]\n buffers.delete(event.runId)\n flush(events)\n }\n },\n },\n settle(): void {\n for (const events of buffers.values()) flush(events)\n buffers.clear()\n },\n }\n}\n\n/**\n * 16-hex-char span id for journal spans synthesized outside the shared loop\n * builder (e.g. the queue's detached-resume segment).\n *\n * @experimental\n */\nexport function generateDelegationSpanId(): string {\n const bytes = new Uint8Array(8)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 8; i += 1) bytes[i] = Math.floor(Math.random() * 256)\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Fan one `LoopTraceEvent` stream into several emitters — e.g. the\n * process-wide OTEL exporter AND the per-delegation journal collector.\n * `undefined` entries are skipped; returns `undefined` when nothing is left\n * so callers keep the kernel's \"no emitter, no events\" fast path.\n *\n * @experimental\n */\nexport function composeLoopTraceEmitters(\n ...emitters: ReadonlyArray<LoopTraceEmitter | undefined>\n): LoopTraceEmitter | undefined {\n const live = emitters.filter((e): e is LoopTraceEmitter => e !== undefined)\n if (live.length === 0) return undefined\n if (live.length === 1) return live[0]\n return {\n emit(event: LoopTraceEvent): void | Promise<void> {\n const pending: Promise<void>[] = []\n for (const emitter of live) {\n const result = emitter.emit(event)\n if (result) pending.push(result)\n }\n if (pending.length > 0) return Promise.all(pending).then(() => undefined)\n },\n }\n}\n","/**\n *\n * State machine for async MCP delegations:\n *\n * pending → running → completed | failed\n * ↘ cancelled (from any non-terminal state via cancel())\n *\n * Each `submit` returns a `taskId` immediately and kicks the work off in the\n * background. The work function receives an `AbortSignal` the queue fires\n * when `cancel(taskId)` is called. The queue does NOT supervise runtime\n * timeouts — the underlying `runAgentRounds` driver / sandbox imposes those.\n *\n * Idempotency: callers may supply an `idempotencyKey` (hash of the input).\n * A duplicate `submit` with a known key returns the existing task instead of\n * starting a new one. Mutated input → different key → different task.\n *\n * Durability: the working set lives in memory (reads stay synchronous) and\n * every record mutation is journaled through a `DelegationStore`. The default\n * `InMemoryDelegationStore` keeps today's semantics — a process restart drops\n * all state. Construct via `DelegationTaskQueue.restore({ store })` with a\n * `FileDelegationStore` to reload prior records on startup: terminal records\n * stay queryable, in-flight records either re-attach through the\n * `resumeDelegate` seam (when they carry a `detachedSessionRef`) or fail\n * loud with a driver-restart error so `delegation_status` tells the truth.\n *\n * @experimental\n */\n\nimport { ValidationError } from '../errors'\nimport type { LoopTraceEmitter } from '../runtime/types'\nimport {\n DelegationPersistenceError,\n type DelegationStore,\n InMemoryDelegationStore,\n} from './delegation-store'\nimport {\n capDelegationTrace,\n createDelegationTraceCollector,\n type DelegationTraceSpan,\n generateDelegationSpanId,\n} from './delegation-trace'\nimport type { TraceContext } from './trace-propagation'\nimport type {\n DelegateCodeArgs,\n DelegateResearchArgs,\n DelegateUiAuditArgs,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusResult,\n} from './types'\n\n/** Arguments accepted by the durable delegation queue. @experimental */\nexport type DelegationArgs = DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs\n\n/**\n * Must be JSON-safe end to end (`args`, `result`, `error`, `feedback`) —\n * persistent stores round-trip records through `JSON.stringify`.\n *\n * @experimental\n */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegationArgs\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Sha-prefix hash of the canonical input — used for idempotency lookup. */\n idempotencyKey?: string\n /**\n * Caller-generated deterministic id of a detached run (e.g. the sandbox\n * session id a single-tick driver resumes by). Presence is what makes a\n * restored in-flight record resumable via `resumeDelegate`; without it a\n * restart settles the record as failed.\n */\n detachedSessionRef?: string\n /** Feedback events keyed by this delegation's taskId. */\n feedback: DelegationFeedbackSnapshot[]\n /**\n * Compact loop-trace span tree teed from the delegation's run, oldest\n * spans first. Appended when a delegated loop reaches `loop.ended` and\n * settled (partial buffers included) at the terminal transition. Capped\n * via `capDelegationTrace` — see `traceTruncated`.\n */\n trace?: DelegationTraceSpan[]\n /** Present when oldest trace spans were dropped to honor the trace caps. */\n traceTruncated?: true\n /**\n * Inherited trace identity (the queue's `traceContext` at submit time —\n * typically `readTraceContextFromEnv()`), distinct from the span payload:\n * a journal consumer joins records into the parent trace by these ids\n * without parsing spans. Restored records keep their persisted identity.\n */\n traceId?: string\n /** Caller span that dispatched the delegation, when one was inherited. */\n parentSpanId?: string\n}\n\n/** @experimental */\nexport interface SubmitInput<Args extends DelegationArgs> {\n profile: DelegationProfile\n args: Args\n namespace?: string\n idempotencyKey?: string\n /**\n * Records the detached-run resume key on the new record. The submitted\n * `run` function still executes in-process exactly as without it — the\n * ref only matters after a restart, when `DelegationTaskQueue.restore`\n * hands it to the `resumeDelegate` seam instead of failing the record.\n */\n detachedSessionRef?: string\n /**\n * Runs the underlying delegation. The queue passes a fresh `AbortSignal`\n * and a `report` channel for incremental progress updates. The function\n * MUST resolve with the typed `DelegationResultPayload['output']`; the\n * queue wraps it with the profile tag.\n */\n run: (ctx: DelegationRunContext) => Promise<DelegationResultPayload['output']>\n}\n\n/** @experimental Context handed to a `SubmitInput.run` function. */\nexport interface DelegationRunContext {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** The `detachedSessionRef` recorded at submit, when one was supplied. */\n detachedSessionRef?: string\n /**\n * Replace the record's detached-run resume key — the detached dispatch path\n * calls this once the sandbox id is known so the persisted ref names a\n * resolvable box. Ignored after the record settles (a cancel racing the\n * rebind is legitimate; the ref no longer matters then). Throws on an empty\n * ref — erasing the resume key would silently make the record unresumable.\n */\n updateDetachedSessionRef(ref: string): void\n /**\n * Per-delegation loop-trace sink, always provided by the queue. Events\n * emitted here are journaled onto the record as a compact span tree\n * (`record.trace`) when each loop run ends and at the delegation's\n * terminal transition. Delegates forward it into their `runAgentRounds` ctx,\n * composed with any process-wide OTEL emitter\n * (`composeLoopTraceEmitters`). Optional in the type so consumer-built\n * contexts stay source-compatible.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @experimental */\nexport interface SubmitOutput {\n taskId: string\n /** True when a prior matching `idempotencyKey` returned an existing record. */\n reused: boolean\n}\n\n/**\n * One observation of a detached run, mapped 1:1 from a single-tick driver\n * (e.g. the sandbox SDK's `driveTurn`, which reports\n * completed | running | failed per pass). `running` schedules another tick\n * after `intervalMs`; `completed` / `failed` settle the record.\n *\n * @experimental\n */\nexport type DelegationResumeTick =\n | { state: 'running' }\n | { state: 'completed'; output: DelegationResultPayload['output']; costUsd?: number }\n | { state: 'failed'; error: DelegationError }\n\n/** @experimental */\nexport interface DelegationResumeContext {\n /** Fired by `cancel(taskId)`; the driver should stop the remote run when it can. */\n signal: AbortSignal\n report(progress: DelegationProgress): void\n}\n\n/**\n * Re-attaches restored in-flight records to their detached runs. The queue\n * calls `tick` repeatedly — it never awaits a whole run — so the driver can\n * be a thin wrapper over a one-pass primitive: resolve the run named by\n * `detachedSessionRef`, advance/poll it once, report where it stands. A\n * thrown error settles the record as failed; `failed` ticks are treated as\n * terminal and are not retried.\n *\n * @experimental\n */\nexport interface DelegationResumeDriver {\n tick(\n task: { record: DelegationRecord; detachedSessionRef: string },\n ctx: DelegationResumeContext,\n ): Promise<DelegationResumeTick>\n /** Delay between `running` ticks, in milliseconds. Default 5000. */\n intervalMs?: number\n}\n\n/** @experimental */\nexport interface DelegationTaskQueueOptions {\n /** ID generator override; default `randomTaskId`. */\n generateId?: () => string\n /** Clock override; default `() => new Date().toISOString()`. */\n now?: () => string\n /**\n * Journal for record mutations and the `restore()` load source. Default\n * `InMemoryDelegationStore` — observably identical to an unjournaled\n * queue. Pass a `FileDelegationStore` through\n * `DelegationTaskQueue.restore` for state that survives a restart;\n * constructing with `new` never loads prior state.\n */\n store?: DelegationStore\n /** Resume seam for restored in-flight records that carry a `detachedSessionRef`. */\n resumeDelegate?: DelegationResumeDriver\n /**\n * Maximum number of terminal (completed | failed | cancelled) records\n * retained; the oldest (by `completedAt`) are evicted from memory and\n * store once the cap is exceeded. Default unbounded.\n */\n maxTerminalRecords?: number\n /**\n * Observes the first store failure. After it fires, the queue refuses\n * new submissions and `flush()` rejects with the same error. Default:\n * rethrow on a microtask — an unhandled crash — because silently\n * degrading durable mode to memory-only would lie to the caller.\n */\n onPersistError?: (error: DelegationPersistenceError) => void\n /**\n * Inherited trace identity stamped on every submitted record\n * (`traceId` / `parentSpanId`). The bin passes\n * `readTraceContextFromEnv()` so journal consumers can join delegation\n * records into the caller's trace. Restored records keep the identity\n * they were persisted with.\n */\n traceContext?: TraceContext\n}\n\n/** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @experimental */\nexport class DelegationTaskQueue {\n private readonly records = new Map<string, DelegationRecord>()\n private readonly controllers = new Map<string, AbortController>()\n private readonly byIdempotencyKey = new Map<string, string>()\n private readonly generateId: () => string\n private readonly now: () => string\n private readonly store: DelegationStore\n private readonly resumeDelegate?: DelegationResumeDriver\n private readonly maxTerminalRecords: number\n private readonly onPersistError: (error: DelegationPersistenceError) => void\n private readonly traceContext: TraceContext | undefined\n private persistTail: Promise<void> = Promise.resolve()\n private persistFailure: DelegationPersistenceError | undefined\n\n constructor(options: DelegationTaskQueueOptions = {}) {\n this.generateId = options.generateId ?? randomTaskId\n this.now = options.now ?? (() => new Date().toISOString())\n this.store = options.store ?? new InMemoryDelegationStore()\n this.resumeDelegate = options.resumeDelegate\n if (options.maxTerminalRecords !== undefined) {\n if (!Number.isInteger(options.maxTerminalRecords) || options.maxTerminalRecords < 1) {\n throw new ValidationError(\n `DelegationTaskQueue: maxTerminalRecords must be a positive integer, got ${String(options.maxTerminalRecords)}`,\n )\n }\n }\n this.maxTerminalRecords = options.maxTerminalRecords ?? Number.POSITIVE_INFINITY\n this.traceContext = options.traceContext\n this.onPersistError =\n options.onPersistError ??\n ((error) => {\n queueMicrotask(() => {\n throw error\n })\n })\n }\n\n /**\n * Construct a queue from previously-persisted state. Loads every record\n * from `options.store`, rebuilds the idempotency index (so a re-submitted\n * identical task returns the prior taskId and its terminal state), then:\n *\n * - terminal records stay queryable via `status()` / `history()`\n * - in-flight records with a `detachedSessionRef` re-attach through\n * `options.resumeDelegate` and report `running`\n * - other in-flight records settle as failed — their driver died with\n * the previous process and the result is unrecoverable\n *\n * The retention cap applies to the loaded set as well.\n */\n static async restore(options: DelegationTaskQueueOptions = {}): Promise<DelegationTaskQueue> {\n const queue = new DelegationTaskQueue(options)\n const loaded = await queue.store.loadAll()\n await queue.rehydrate(loaded)\n return queue\n }\n\n /**\n * Kick off a delegation in the background. Returns immediately. The\n * `taskId` is queryable via `status` once this method returns. Throws\n * the recorded `DelegationPersistenceError` once the store has failed —\n * the queue does not accept work it cannot journal.\n */\n submit<Args extends DelegationArgs>(input: SubmitInput<Args>): SubmitOutput {\n if (this.persistFailure) throw this.persistFailure\n if (input.idempotencyKey) {\n const existing = this.byIdempotencyKey.get(input.idempotencyKey)\n if (existing && this.records.has(existing)) {\n return { taskId: existing, reused: true }\n }\n }\n const taskId = this.generateId()\n const controller = new AbortController()\n const record: DelegationRecord = {\n taskId,\n profile: input.profile,\n namespace: input.namespace,\n args: input.args,\n status: 'pending',\n startedAt: this.now(),\n feedback: [],\n idempotencyKey: input.idempotencyKey,\n detachedSessionRef: input.detachedSessionRef,\n ...(this.traceContext !== undefined\n ? {\n traceId: this.traceContext.traceId,\n ...(this.traceContext.parentSpanId !== undefined\n ? { parentSpanId: this.traceContext.parentSpanId }\n : {}),\n }\n : {}),\n }\n this.records.set(taskId, record)\n this.controllers.set(taskId, controller)\n if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId)\n this.persist(record)\n\n // Fire-and-forget the run function. Errors flow into the record so the\n // status poll surfaces them; the promise itself is intentionally\n // unobserved by the queue.\n queueMicrotask(() => {\n this.execute(taskId, input, controller)\n })\n\n return { taskId, reused: false }\n }\n\n /**\n * Snapshot the current state of a delegation. Returns `undefined` for\n * unknown ids so callers can distinguish missing from terminal.\n * `includeTrace` attaches the journaled loop-trace span tree — off by\n * default so status polls stay light.\n */\n status(taskId: string, opts?: { includeTrace?: boolean }): DelegationStatusResult | undefined {\n const record = this.records.get(taskId)\n if (!record) return undefined\n return toStatusResult(record, opts)\n }\n\n /**\n * Abort an in-flight delegation. Returns `false` if the task is unknown\n * or already terminal. The underlying `run` function MUST honor the\n * abort signal for the cancel to take effect; the queue marks the\n * record `cancelled` regardless so a misbehaving runner cannot pin the\n * UI on `running` forever.\n */\n cancel(taskId: string): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n if (isTerminal(record.status)) return false\n const controller = this.controllers.get(taskId)\n controller?.abort()\n record.status = 'cancelled'\n record.completedAt = this.now()\n record.error = { message: 'cancelled by caller', kind: 'CancelledError' }\n this.persist(record)\n this.enforceRetention()\n return true\n }\n\n /**\n * Append a feedback event to the matching delegation. Returns `false`\n * when `ref` does not name a known taskId — the caller should still\n * record the feedback through a different surface (artifact/outcome\n * kinds are not queue-bound).\n */\n attachFeedback(taskId: string, snapshot: DelegationFeedbackSnapshot): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n record.feedback.push(snapshot)\n this.persist(record)\n return true\n }\n\n /**\n * Query the recorded delegations. Returns entries newest-first (by\n * `startedAt`), truncated to `limit`.\n */\n history(args: DelegationHistoryArgs = {}): DelegationHistoryEntry[] {\n const limit = clampLimit(args.limit)\n const since = args.since ? Date.parse(args.since) : Number.NEGATIVE_INFINITY\n const out: DelegationHistoryEntry[] = []\n for (const record of this.records.values()) {\n if (args.namespace && record.namespace !== args.namespace) continue\n if (args.profile && record.profile !== args.profile) continue\n if (Number.isFinite(since) && Date.parse(record.startedAt) < since) continue\n out.push(toHistoryEntry(record))\n }\n out.sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n return out.slice(0, limit)\n }\n\n /**\n * Await every journal write issued so far. Rejects with the recorded\n * `DelegationPersistenceError` when any of them failed. Call before\n * handing the store's backing file to another process.\n */\n async flush(): Promise<void> {\n // Drain to quiescence: a write that completes while we await the tail can\n // chain another (the resume loop persisting a settle, a late `report`,\n // retention removals). Awaiting a single snapshot of `persistTail` would\n // miss those follow-on writes, letting a `store.upsert` land after the\n // caller has torn the backing dir down. Re-await until the tail stops\n // advancing.\n let tail: typeof this.persistTail | undefined\n while (this.persistTail !== tail) {\n tail = this.persistTail\n await tail\n }\n if (this.persistFailure) throw this.persistFailure\n }\n\n /** Test-only — number of in-flight (non-terminal) records. */\n inflightCount(): number {\n let n = 0\n for (const record of this.records.values()) {\n if (!isTerminal(record.status)) n += 1\n }\n return n\n }\n\n private async execute<Args extends DelegationArgs>(\n taskId: string,\n input: SubmitInput<Args>,\n controller: AbortController,\n ): Promise<void> {\n const record = this.records.get(taskId)\n if (!record) return\n record.status = 'running'\n this.persist(record)\n // Journal tee: each finished loop run inside the delegation appends its\n // compact span tree to the record immediately (a long delegation's trace\n // is durable before the terminal transition); `settle()` below drains\n // partial buffers from runs that never reached `loop.ended`.\n const traceCollector = createDelegationTraceCollector((spans) => {\n if (isTerminal(currentStatus(record))) return\n this.appendTrace(record, spans)\n this.persist(record)\n })\n try {\n const output = await input.run({\n signal: controller.signal,\n report: (progress) => {\n if (record.status === 'running') {\n record.progress = progress\n this.persist(record)\n }\n },\n traceEmitter: traceCollector.emitter,\n ...(record.detachedSessionRef !== undefined\n ? { detachedSessionRef: record.detachedSessionRef }\n : {}),\n updateDetachedSessionRef: (ref) => {\n if (typeof ref !== 'string' || ref.length === 0) {\n throw new ValidationError(\n 'DelegationTaskQueue: updateDetachedSessionRef requires a non-empty ref',\n )\n }\n if (isTerminal(currentStatus(record))) return\n record.detachedSessionRef = ref\n this.persist(record)\n },\n })\n traceCollector.settle()\n // `cancel()` may have flipped the status to `cancelled` while the\n // run promise was pending. Read the field through a widening\n // helper so the narrowed `'running'` type from the assignment\n // above does not exclude that case at compile time.\n if (currentStatus(record) === 'cancelled') return\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = { profile: input.profile, output } as DelegationResultPayload\n this.persist(record)\n this.enforceRetention()\n } catch (err) {\n traceCollector.settle()\n if (currentStatus(record) === 'cancelled') return\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(taskId)\n }\n }\n\n private appendTrace(record: DelegationRecord, spans: DelegationTraceSpan[]): void {\n if (spans.length === 0) return\n const { trace, truncated } = capDelegationTrace([...(record.trace ?? []), ...spans])\n record.trace = trace\n if (truncated) record.traceTruncated = true\n }\n\n private async rehydrate(loaded: DelegationRecord[]): Promise<void> {\n const records = [...loaded].sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n for (const record of records) {\n this.records.set(record.taskId, record)\n if (record.idempotencyKey) this.byIdempotencyKey.set(record.idempotencyKey, record.taskId)\n }\n const restoreWrites: Promise<void>[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) continue\n if (record.detachedSessionRef && this.resumeDelegate) {\n record.status = 'running'\n restoreWrites.push(this.persist(record))\n this.startResume(record, record.detachedSessionRef, this.resumeDelegate)\n continue\n }\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = {\n message: record.detachedSessionRef\n ? `delegation driver restarted while the task was in flight; detached session \"${record.detachedSessionRef}\" needs a resumeDelegate to be resumed`\n : 'delegation driver restarted while the task was in flight; the run was not detached and cannot be resumed',\n kind: 'DriverRestartError',\n }\n restoreWrites.push(this.persist(record))\n }\n const retentionWrite = this.enforceRetention()\n if (retentionWrite) restoreWrites.push(retentionWrite)\n await Promise.all(restoreWrites)\n if (this.persistFailure) throw this.persistFailure\n }\n\n private startResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n ): void {\n const controller = new AbortController()\n this.controllers.set(record.taskId, controller)\n void this.driveResume(record, detachedSessionRef, driver, controller)\n }\n\n private async driveResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n controller: AbortController,\n ): Promise<void> {\n const intervalMs = driver.intervalMs ?? 5000\n const resumeStartMs = Date.parse(this.now())\n const ctx: DelegationResumeContext = {\n signal: controller.signal,\n report: (progress) => {\n if (currentStatus(record) !== 'running') return\n record.progress = progress\n this.persist(record)\n },\n }\n try {\n while (!controller.signal.aborted && currentStatus(record) === 'running') {\n const tick = await driver.tick({ record: structuredClone(record), detachedSessionRef }, ctx)\n if (currentStatus(record) === 'cancelled') return\n if (tick.state === 'completed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs)\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = {\n profile: record.profile,\n output: tick.output,\n } as DelegationResultPayload\n if (tick.costUsd !== undefined) record.costUsd = tick.costUsd\n this.persist(record)\n this.enforceRetention()\n return\n }\n if (tick.state === 'failed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, tick.error.message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = tick.error\n this.persist(record)\n this.enforceRetention()\n return\n }\n await abortableDelay(intervalMs, controller.signal)\n }\n } catch (err) {\n if (currentStatus(record) === 'cancelled') return\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, errorToShape(err).message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(record.taskId)\n }\n }\n\n /**\n * Journal the resumed segment of a detached run as one compact span. The\n * resume driver re-attaches after a process restart, so the original\n * process's loop events are gone — this span records the post-restart\n * observation window (re-attach → terminal tick) under the\n * `'detached-resume'` driver tag, keeping restored delegations observable\n * in the journal alongside trace-carrying live runs.\n */\n private appendResumeSpan(\n record: DelegationRecord,\n detachedSessionRef: string,\n startMs: number,\n error?: string,\n ): void {\n this.appendTrace(record, [\n {\n spanId: generateDelegationSpanId(),\n name: 'loop',\n kind: 'loop',\n startMs,\n endMs: Date.parse(this.now()),\n meta: {\n 'tangle.loop.driver': 'detached-resume',\n 'tangle.loop.detached_session_ref': detachedSessionRef,\n ...(error !== undefined ? { 'tangle.loop.error': error } : {}),\n },\n },\n ])\n }\n\n private persist(record: DelegationRecord): Promise<void> {\n if (this.persistFailure) return Promise.resolve()\n const snapshot = structuredClone(record)\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.upsert(snapshot)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private persistRemoval(taskIds: string[]): Promise<void> | undefined {\n if (this.persistFailure || taskIds.length === 0) return undefined\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.remove(taskIds)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private failPersistence(cause: unknown): void {\n if (this.persistFailure) return\n const error =\n cause instanceof DelegationPersistenceError\n ? cause\n : new DelegationPersistenceError(\n `DelegationTaskQueue: store write failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n this.persistFailure = error\n this.onPersistError(error)\n }\n\n private enforceRetention(): Promise<void> | undefined {\n if (!Number.isFinite(this.maxTerminalRecords)) return undefined\n const terminal: DelegationRecord[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) terminal.push(record)\n }\n const excess = terminal.length - this.maxTerminalRecords\n if (excess <= 0) return undefined\n terminal.sort((a, b) =>\n (a.completedAt ?? a.startedAt).localeCompare(b.completedAt ?? b.startedAt),\n )\n const evicted = terminal.slice(0, excess)\n for (const record of evicted) {\n this.records.delete(record.taskId)\n if (\n record.idempotencyKey &&\n this.byIdempotencyKey.get(record.idempotencyKey) === record.taskId\n ) {\n this.byIdempotencyKey.delete(record.idempotencyKey)\n }\n }\n return this.persistRemoval(evicted.map((record) => record.taskId))\n }\n}\n\nfunction isTerminal(status: DelegationStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled'\n}\n\nfunction currentStatus(record: DelegationRecord): DelegationStatus {\n return record.status\n}\n\nfunction clampLimit(raw: number | undefined): number {\n if (!Number.isFinite(raw)) return 50\n const n = Math.trunc(raw as number)\n if (n <= 0) return 50\n return Math.min(n, 500)\n}\n\nfunction abortableDelay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) {\n resolve()\n return\n }\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nfunction toStatusResult(\n record: DelegationRecord,\n opts?: { includeTrace?: boolean },\n): DelegationStatusResult {\n const out: DelegationStatusResult = {\n taskId: record.taskId,\n profile: record.profile,\n status: record.status,\n startedAt: record.startedAt,\n }\n if (record.progress) out.progress = record.progress\n if (record.result) out.result = record.result\n if (record.error) out.error = record.error\n if (record.costUsd !== undefined) out.costUsd = record.costUsd\n if (record.completedAt) out.completedAt = record.completedAt\n if (record.traceId !== undefined) out.traceId = record.traceId\n if (record.parentSpanId !== undefined) out.parentSpanId = record.parentSpanId\n if (opts?.includeTrace === true && record.trace && record.trace.length > 0) {\n out.trace = record.trace.map((span) => ({ ...span }))\n if (record.traceTruncated) out.traceTruncated = true\n }\n return out\n}\n\nfunction toHistoryEntry(record: DelegationRecord): DelegationHistoryEntry {\n const entry: DelegationHistoryEntry = {\n taskId: record.taskId,\n profile: record.profile,\n args: record.args,\n status: record.status,\n startedAt: record.startedAt,\n hasTrace: record.trace !== undefined && record.trace.length > 0,\n }\n if (record.namespace) entry.namespace = record.namespace\n if (record.completedAt) entry.completedAt = record.completedAt\n if (record.costUsd !== undefined) entry.costUsd = record.costUsd\n if (record.feedback.length > 0) entry.feedback = [...record.feedback]\n if (record.traceId !== undefined) entry.traceId = record.traceId\n return entry\n}\n\nfunction errorToShape(err: unknown): DelegationError {\n if (err instanceof Error) {\n return { message: err.message, kind: err.name || 'Error' }\n }\n return { message: String(err), kind: 'NonError' }\n}\n\nfunction randomTaskId(): string {\n // Caller-stable id: `dlg-${timestamp}-${random}`. The timestamp portion\n // makes lexicographic sort match chronological order in history queries\n // even when the system clock skews under the second.\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `dlg-${t}-${r}`\n}\n\n/**\n * Best-effort stable hash for use as `idempotencyKey`. Not cryptographic;\n * collisions only affect dedupe, never correctness.\n *\n * @experimental\n */\nexport function hashIdempotencyInput(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(canonicalize(value))\n } catch {\n str = String(value)\n }\n // FNV-1a 32-bit\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n const out: Record<string, unknown> = {}\n for (const [k, v] of entries) out[k] = canonicalize(v)\n return out\n}\n\n// Re-exports re-used by the feedback-store + handler glue. Kept local so\n// consumers of the queue don't have to import from `./types` separately.\nexport type {\n DelegateCodeArgs,\n DelegateCodeResult,\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n DelegateResearchArgs,\n DelegateResearchResult,\n DelegateUiAuditArgs,\n DelegateUiAuditConfig,\n DelegateUiAuditResult,\n DelegateUiAuditRoute,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\n UiAuditorDelegationOutput,\n} from './types'\n","/**\n *\n * The supervisor's intelligence is AUTHORING the agents it spawns — not pressing buttons.\n *\n * Every agent here is three things: instructions (system prompt), tools, and a model — its\n * `AgentProfile`. The supervisor's job is to WRITE those profiles: read the task, decompose it,\n * and for each sub-task author a tailored worker recipe. `supervisorInstructions` is the how-to the\n * supervisor reads (its system prompt); `authoredWorker` builds a worker AGENT from a profile the\n * supervisor authored — the authored systemPrompt + model shape the worker's call.\n *\n * The skill is the single OPTIMIZABLE surface: edit it → the supervisor designs better agents.\n * That is the self-improvement lever (the prompt/skill lever), not the execution plumbing.\n *\n * @experimental\n */\n\nimport { type AnalystFinding, computeFindingId, makeFinding } from '@tangle-network/agent-eval'\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { contentAddress } from '../../durable/spawn-journal'\nimport { type RouterConfig, routerChatWithUsage } from '../router-client'\nimport { type DeliverableSpec, gateOnDeliverable } from './completion-gate'\nimport type { Agent, AgentSpec, Executor, ExecutorResult } from './types'\n\n/** What the supervisor AUTHORS per sub-task — a worker recipe (a partial `AgentProfile`). */\nexport interface AuthoredProfile {\n name: string\n /** The rich, task-specific instructions the supervisor wrote for THIS worker. */\n systemPrompt: string\n /** The model the supervisor chose for this sub-task (falls back to the run default). */\n model?: string\n}\n\n/** Narrow an untyped `spawn_agent` profile argument to an `AuthoredProfile`, or null if the\n * supervisor failed to author one (empty/placeholder profile — a skill violation worth catching). */\nexport function asAuthoredProfile(raw: unknown): AuthoredProfile | null {\n const p = raw as Partial<AuthoredProfile> | undefined\n if (!p || typeof p.systemPrompt !== 'string' || p.systemPrompt.trim().length === 0) return null\n return {\n name: typeof p.name === 'string' && p.name.length > 0 ? p.name : 'worker',\n systemPrompt: p.systemPrompt,\n ...(typeof p.model === 'string' ? { model: p.model } : {}),\n }\n}\n\n/** The supervisor SKILL — the how-to the supervisor reads (its system prompt). THE optimizable\n * surface: editing this changes how the supervisor designs every agent it spawns. */\nexport function supervisorInstructions(opts?: { goal?: string }): string {\n return [\n 'You are a SUPERVISOR. You do NOT do the work yourself — your job is to DESIGN and DRIVE specialist worker agents.',\n '',\n 'For the task you are given:',\n '1. DECOMPOSE it into the smallest set of sub-tasks a single focused worker can each deliver.',\n '2. For EACH sub-task, AUTHOR a worker by calling spawn_agent with a COMPLETE `profile`:',\n ' • name: a short id for the worker.',\n ' • systemPrompt: rich, specific instructions for THIS sub-task — tell the worker exactly what to produce, how to use its tools fully, and what \"done\" means. Never a one-liner; write the prompt a power-user would write.',\n ' • model: the model best suited to this sub-task (omit to use the default).',\n ' NEVER spawn a worker with an empty profile. The quality of the worker IS the quality of the profile you write.',\n \"3. await_event (kinds:['settled']) to collect each worker. Its result says valid:true only if the deployable check passed.\",\n '4. If a worker did NOT deliver, AUTHOR A NEW worker whose systemPrompt names the SPECIFIC failure and how to fix it — never just retry the same prompt.',\n '5. Stop (reply with no tool call) once the work is delivered. You cannot declare done yourself — only a delivered (valid:true) worker counts.',\n ...(opts?.goal ? ['', `The goal: ${opts.goal}`] : []),\n ].join('\\n')\n}\n\n/** Build a worker AGENT from a profile the supervisor authored: the authored `systemPrompt` +\n * `model` shape the worker's one model call; the deliverable gates settlement (valid ⟺ delivered). */\nexport function authoredWorker(\n profile: AuthoredProfile,\n opts: {\n cfg: RouterConfig\n taskPrompt: string\n deliverable: DeliverableSpec\n temperature?: number\n },\n): Agent<unknown, unknown> {\n let artifact: ExecutorResult<unknown> | undefined\n const model = profile.model ?? opts.cfg.model\n const inner: Executor<unknown> = {\n runtime: 'router',\n async execute(_t, signal) {\n const res = await routerChatWithUsage(\n { ...opts.cfg, model },\n [\n { role: 'system', content: profile.systemPrompt },\n { role: 'user', content: opts.taskPrompt },\n ],\n { temperature: opts.temperature ?? 0.4, ...(signal ? { signal } : {}) },\n )\n artifact = {\n outRef: contentAddress(res.content),\n out: res.content,\n spent: {\n iterations: 1,\n tokens: res.usage ?? { input: 0, output: 0 },\n usd: res.costUsd ?? 0,\n ms: 0,\n },\n }\n return artifact\n },\n teardown: () => Promise.resolve({ destroyed: true }),\n resultArtifact: () => {\n if (!artifact) throw new Error('authoredWorker: resultArtifact read before execute')\n return artifact\n },\n }\n const gated = gateOnDeliverable(inner, opts.deliverable)\n const spec: AgentSpec = {\n profile: { name: profile.name } as AgentProfile,\n harness: null,\n executor: gated,\n }\n return { name: profile.name, act: async () => '', executorSpec: spec } as Agent<\n unknown,\n unknown\n > & {\n executorSpec: AgentSpec\n }\n}\n\n// ── Profile-richness gate ────────────────────────────────────────────────────\n//\n// The supervisor's product is the worker PROFILE it authors. The failure mode the existing\n// gates miss: `asAuthoredProfile` / `local-harness` only reject a FULLY EMPTY system prompt —\n// a two-sentence stub passes. `assessAuthoredProfile` OBSERVES the authored artifact (it reads\n// no judge verdict, so it steers cleanly past `assertTraceDerivedFindings`) and flags THIN:\n// a short/few-line system prompt, OR no tools, OR no skills, OR no MCP when the task needs one.\n// It emits a real `AnalystFinding` so it rides the SAME coordination bus the driver pulls via\n// `await_event({kinds:['finding']})` — the supervisor can self-correct and re-author richer.\n\n/** Thresholds below which a system prompt is treated as a thin stub. Tunable per call. */\nexport interface ProfileRichnessThresholds {\n /** A prompt shorter than this many characters is thin (default 600). */\n readonly minSystemPromptChars: number\n /** A prompt with fewer than this many non-blank lines is thin (default 6). */\n readonly minSystemPromptLines: number\n}\n\n/** Default thresholds for `ProfileRichnessThresholds` — 600 chars / 6 lines minimum system prompt. */\nexport const defaultProfileRichnessThresholds: ProfileRichnessThresholds = {\n minSystemPromptChars: 600,\n minSystemPromptLines: 6,\n}\n\n/** Per-field verdict on one authored profile — the raw material the bench renders + scores. */\nexport interface ProfileRichness {\n readonly name: string\n /** The resolved system prompt (canonical `prompt.systemPrompt`, the sandbox `prompt.system`\n * convention, or a bare-string prompt — whichever the author used). */\n readonly systemPrompt: string\n readonly systemPromptChars: number\n readonly systemPromptLines: number\n readonly sentenceCount: number\n readonly hasDescription: boolean\n readonly hasTools: boolean\n readonly hasSkills: boolean\n readonly hasMcp: boolean\n readonly hasSubagents: boolean\n /** 0..1 — fraction of richness signals present (prompt-depth + the four levers). */\n readonly richness: number\n /** True when the supervisor authored a stub instead of a real profile. */\n readonly thin: boolean\n /** The specific reasons it is thin (empty when rich) — used in the finding's action. */\n readonly reasons: string[]\n}\n\n/** Read the system prompt from any authored shape: canonical `prompt.systemPrompt`, the sandbox\n * `prompt.system` convention, or a bare-string `prompt`. */\nfunction resolveSystemPrompt(profile: AgentProfile): string {\n const pr = (profile as { prompt?: unknown }).prompt\n if (typeof pr === 'string') return pr\n if (pr && typeof pr === 'object') {\n const o = pr as { systemPrompt?: unknown; system?: unknown }\n if (typeof o.systemPrompt === 'string') return o.systemPrompt\n if (typeof o.system === 'string') return o.system\n }\n return ''\n}\n\n/** OBSERVE one authored `AgentProfile` and score its richness (no judge verdict is read). The task\n * context (`needsMcp`) lets a domain say \"this work needs a data/tool MCP\" so a missing MCP counts. */\nexport function assessAuthoredProfile(\n profile: AgentProfile,\n opts?: { needsMcp?: boolean; thresholds?: Partial<ProfileRichnessThresholds> },\n): ProfileRichness {\n const th = { ...defaultProfileRichnessThresholds, ...(opts?.thresholds ?? {}) }\n const systemPrompt = resolveSystemPrompt(profile)\n const trimmed = systemPrompt.trim()\n const systemPromptChars = trimmed.length\n const systemPromptLines = trimmed\n ? trimmed.split('\\n').filter((l) => l.trim().length > 0).length\n : 0\n const sentenceCount = trimmed\n ? (trimmed.match(/[.!?](\\s|$)/g) ?? []).length || (trimmed ? 1 : 0)\n : 0\n const hasDescription =\n typeof profile.description === 'string' && profile.description.trim().length > 0\n const tools = (profile as { tools?: Record<string, unknown> }).tools\n const hasTools = !!tools && Object.keys(tools).length > 0\n const skills = (profile.resources as { skills?: unknown[] } | undefined)?.skills\n const hasSkills = Array.isArray(skills) && skills.length > 0\n const mcp = (profile as { mcp?: Record<string, unknown> }).mcp\n const hasMcp = !!mcp && Object.keys(mcp).length > 0\n const subagents = (profile as { subagents?: Record<string, unknown> }).subagents\n const hasSubagents = !!subagents && Object.keys(subagents).length > 0\n\n const reasons: string[] = []\n const promptThin =\n systemPromptChars < th.minSystemPromptChars || systemPromptLines < th.minSystemPromptLines\n if (promptThin)\n reasons.push(\n `system prompt is thin (${systemPromptChars} chars, ${systemPromptLines} lines; need ≥${th.minSystemPromptChars} chars and ≥${th.minSystemPromptLines} lines)`,\n )\n if (!hasTools)\n reasons.push('no tools granted (a worker can only act through the tools you grant it)')\n if (!hasSkills) reasons.push('no skills attached (no reusable how-to notes injected)')\n if (opts?.needsMcp && !hasMcp) reasons.push('no MCP server, but the task needs data/tool access')\n\n // Richness = fraction of signals present. Prompt-depth is one signal; the four levers are the rest.\n const signals = [!promptThin, hasTools, hasSkills, hasDescription, opts?.needsMcp ? hasMcp : true]\n const richness = signals.filter(Boolean).length / signals.length\n // THIN ⟺ the prompt is a stub OR the worker has no levers at all (no tools AND no skills AND no mcp).\n const thin = promptThin || (!hasTools && !hasSkills && !hasMcp)\n\n return {\n name: profile.name ?? 'worker',\n systemPrompt,\n systemPromptChars,\n systemPromptLines,\n sentenceCount,\n hasDescription,\n hasTools,\n hasSkills,\n hasMcp,\n hasSubagents,\n richness,\n thin,\n reasons,\n }\n}\n\n/** Turn a {@link ProfileRichness} verdict into a bus-routable `AnalystFinding` (area `profile-quality`).\n * Severity scales with thinness; the recommended action names the MISSING lever so the supervisor can\n * re-author. `subject` = the worker name so per-worker findings diff cleanly across re-authors. */\nexport function profileRichnessFinding(\n richness: ProfileRichness,\n opts?: { analystId?: string; runId?: string },\n): AnalystFinding {\n const analyst_id = opts?.analystId ?? 'profile-richness'\n const subject = richness.name\n const claim = richness.thin\n ? `Worker \"${richness.name}\" was authored as a THIN profile: ${richness.reasons.join('; ')}.`\n : `Worker \"${richness.name}\" was authored as a rich profile (richness ${(richness.richness * 100).toFixed(0)}%).`\n const severity: AnalystFinding['severity'] = richness.thin\n ? richness.richness < 0.25\n ? 'high'\n : 'medium'\n : 'info'\n return makeFinding({\n analyst_id,\n severity,\n area: 'profile-quality',\n claim,\n subject,\n confidence: 0.9,\n evidence_refs: [\n {\n kind: 'metric',\n uri: `profile:${subject}`,\n excerpt: `chars=${richness.systemPromptChars} lines=${richness.systemPromptLines} tools=${richness.hasTools} skills=${richness.hasSkills} mcp=${richness.hasMcp} richness=${richness.richness.toFixed(2)}`,\n },\n ],\n ...(richness.thin\n ? { recommended_action: `Re-author \"${richness.name}\" with: ${richness.reasons.join('; ')}.` }\n : {}),\n id_basis: computeFindingId({\n analyst_id,\n area: 'profile-quality',\n subject,\n claim: `richness:${richness.thin ? 'thin' : 'rich'}`,\n }),\n })\n}\n","/**\n *\n * `delegate` — the one generic delegation verb. You hand it an INTENT (what you want done) and it\n * hands that intent to a default AUTHORING supervisor: a router-brained supervisor whose standing\n * instruction is `supervisorInstructions()` (the authoring-agent-profiles skill). The supervisor\n * DECOMPOSES the intent and AUTHORS the worker profile it needs per sub-task — there is NO hardcoded\n * coder/researcher profile here. That is the whole point: `delegate('fix the failing test', …)` and\n * `delegate('research X and cite sources', …)` route through the SAME front door; the supervisor\n * writes a code-shaped or research-shaped worker on its own.\n *\n * It is a thin wrapper over `supervise()` — the one front door — so the conserved-budget pool, the\n * completion oracle (`deliverable`), the coordination toolbox, and equal-compute accounting all come\n * for free; nothing is hand-rolled. The result is `supervise()`'s `SupervisedResult` returned\n * UNCHANGED, so its `spentTotal` (`{ iterations, tokens, usd, ms }`) rides straight back to the\n * caller on BOTH paths — a `winner` carries the delivered worker's spend, a `no-winner` carries the\n * spend incurred before it failed. That cost channel means a `delegate()` caller always learns what\n * the delegation actually spent.\n *\n * @experimental\n */\n\nimport { ConfigError } from '../../errors'\nimport type { RouterConfig } from '../router-client'\nimport type { ToolLoopChat } from '../tool-loop'\nimport { supervisorInstructions } from './authoring'\nimport type { DeliverableSpec } from './completion-gate'\nimport type { ExecutorConfig } from './runtime'\nimport { supervise } from './supervise'\nimport type { SupervisorProfile } from './supervisor-agent'\nimport type { Budget, SupervisedResult } from './types'\n\n/** The conserved pool a `delegate()` call applies when the caller does not pass its own `budget`.\n * A modest token ceiling + a small iteration ceiling — generous enough for a few-worker decompose,\n * bounded enough that an unsupervised intent cannot run away. Callers override via `opts.budget`. */\nexport const defaultDelegateBudget: Budget = { maxIterations: 50, maxTokens: 200_000 }\n\n/** Inputs to {@link delegate}. The intent is the first positional arg; everything here is optional\n * with sensible defaults, so the common call is `delegate(intent, { backend, router })`. */\nexport interface DelegateOptions<Out = unknown> {\n /** The completion oracle (settled ⟺ delivered) the authored workers settle against. Strongly\n * recommended — without it the supervisor trusts a worker's self-report. For a code intent,\n * `patchDelivered()` is the canonical example; for a free-form answer, a content check. */\n readonly deliverable?: DeliverableSpec<Out>\n /** WHERE the authored workers run — the worker-execution backend (`router-tools` / `sandbox` /\n * `cli-worktree` / …). The supervisor authors the worker PROFILE; this is the substrate it runs\n * on. Provide this OR `makeWorkerAgent`-style wiring through `supervise()` is unavailable. */\n readonly backend?: ExecutorConfig\n /** The conserved compute pool for the whole delegation. Defaults to {@link defaultDelegateBudget}. */\n readonly budget?: Budget\n /** The model the supervisor BRAIN runs on (the router model). The brain must tool-call\n * (`spawn_agent` / `await_event`), so a delegator model, not a hidden-reasoning model. */\n readonly model?: string\n /** The supervisor brain's router substrate. REQUIRED for the default router-brained supervisor\n * (the brain is resolved from this), unless a test injects `brain` directly. `model` overrides\n * `router.model`. (Design delta vs the bare `supervise()` profile: the brain needs a router.) */\n readonly router?: RouterConfig\n /** Inject the supervisor brain directly (tests / advanced) instead of resolving it from `router`. */\n readonly brain?: ToolLoopChat\n /** Override the default authoring-supervisor profile (name / extra system-prompt stance). The\n * default already carries the authoring skill; override only to add a goal or rename. */\n readonly supervisor?: Partial<Pick<SupervisorProfile, 'name' | 'systemPrompt'>>\n /** Restrict the run to this subset of models (forwarded to `supervise()`). */\n readonly allowedModels?: readonly string[]\n readonly runId?: string\n}\n\n/** Build the DEFAULT authoring supervisor profile: a router-brained supervisor (`harness: null`)\n * whose standing instruction IS the authoring-agent-profiles skill, so it decomposes the intent and\n * AUTHORS a worker profile per sub-task. No worker profile is baked in here. */\nfunction authoringSupervisorProfile(\n model: string | undefined,\n override?: Partial<Pick<SupervisorProfile, 'name' | 'systemPrompt'>>,\n): SupervisorProfile {\n return {\n name: override?.name ?? 'delegate-supervisor',\n harness: null,\n ...(model ? { model } : {}),\n systemPrompt: override?.systemPrompt ?? supervisorInstructions(),\n }\n}\n\n/**\n * Delegate an INTENT to a default authoring supervisor and return its `SupervisedResult` unchanged.\n *\n * The supervisor authors + spawns whatever worker the intent needs over the conserved-budget pool;\n * `result.spentTotal` reports what the whole delegation actually cost. A `winner` result carries the\n * authored worker's delivered output; a `no-winner` result names why (never a fabricated success).\n */\nexport async function delegate<Out = unknown>(\n intent: string,\n opts: DelegateOptions<Out> = {},\n): Promise<SupervisedResult<Out>> {\n if (typeof intent !== 'string' || intent.trim().length === 0) {\n throw new ConfigError('delegate: `intent` must be a non-empty string')\n }\n if (!opts.brain && !opts.router) {\n throw new ConfigError(\n 'delegate: provide opts.router (the supervisor brain substrate) or opts.brain (tests)',\n )\n }\n\n const profile = authoringSupervisorProfile(opts.model, opts.supervisor)\n\n return supervise(profile, intent, {\n budget: opts.budget ?? defaultDelegateBudget,\n ...(opts.backend ? { backend: opts.backend } : {}),\n ...(opts.deliverable ? { deliverable: opts.deliverable as DeliverableSpec<unknown> } : {}),\n ...(opts.router ? { router: opts.router } : {}),\n ...(opts.brain ? { brain: opts.brain } : {}),\n ...(opts.allowedModels ? { allowedModels: opts.allowedModels } : {}),\n ...(opts.runId ? { runId: opts.runId } : {}),\n }) as Promise<SupervisedResult<Out>>\n}\n","/**\n *\n * `delegate` MCP tool — the ONE generic delegation verb, the agent-facing front door to\n * `delegate()` / `supervise()`. The agent hands it an INTENT (what it wants done); a default\n * authoring supervisor decomposes the intent and AUTHORS the worker profile it needs — there is no\n * hardcoded coder/researcher profile, so one verb covers code, research, and anything else.\n *\n * `delegate` is SYNCHRONOUS: it awaits the full supervised run and returns the delivered output\n * TOGETHER WITH `spentTotal` — the conserved cost of the whole delegation (`iterations` / `tokens` /\n * `usd` / `ms`), so the caller always learns what the delegation actually spent.\n *\n * The supervisor's substrate (its brain `router`, the worker `backend`, the completion `deliverable`)\n * is INJECTED at server construction — never an agent-supplied arg. The agent supplies only the\n * intent (+ an optional per-call `model` / `runId`).\n *\n * @experimental\n */\n\nimport type { RouterConfig } from '../../runtime/router-client'\nimport type { DeliverableSpec } from '../../runtime/supervise/completion-gate'\nimport { type DelegateOptions, delegate } from '../../runtime/supervise/delegate'\nimport type { ExecutorConfig } from '../../runtime/supervise/runtime'\nimport type { Spend, SupervisedResult } from '../../runtime/supervise/types'\n\n/** MCP tool name for the `delegate` generic-delegation tool. @experimental */\nexport const DELEGATE_TOOL_NAME = 'delegate'\n\n/** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATE_DESCRIPTION = [\n 'Delegate an INTENT to a supervisor that AUTHORS and drives whatever worker the intent needs.',\n '',\n 'Use when: you want a task done but do not want to specify HOW. State the outcome — \"fix the',\n 'failing auth test\", \"research competitor pricing with citations\", \"refactor the parser for',\n 'clarity\" — and the supervisor decomposes it, writes a tailored worker profile per sub-task, runs',\n 'the workers over a conserved compute budget, and settles only when a deployable check passes.',\n '',\n 'There is no fixed worker type: this ONE verb replaces separate code / research delegation. The',\n 'supervisor picks the worker shape from your intent.',\n '',\n 'Returns synchronously with the delivered result AND the real cost of the whole delegation',\n '(spentTotal: iterations, input/output tokens, usd, ms) — so you always know what it spent. A run',\n 'that produced no delivered worker returns status \"no-winner\" with the reason; it never fabricates',\n 'a success.',\n].join('\\n')\n\n/** JSON Schema for `delegate` tool arguments (`intent` + optional `model` and `runId`). @experimental */\nexport const DELEGATE_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n intent: {\n type: 'string',\n description: 'What you want accomplished, as an outcome. The supervisor authors the worker.',\n },\n model: {\n type: 'string',\n description: 'Optional per-call override for the supervisor brain model.',\n },\n runId: {\n type: 'string',\n description: 'Optional trace-correlation id for this delegation.',\n },\n },\n required: ['intent'],\n additionalProperties: false,\n} as const\n\n/** Parsed `delegate` tool arguments. */\nexport interface DelegateArgs {\n intent: string\n model?: string\n runId?: string\n}\n\n/** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegateArgs(raw: unknown): DelegateArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const intent = value.intent\n if (typeof intent !== 'string' || intent.trim().length === 0) {\n throw new TypeError('delegate: `intent` must be a non-empty string')\n }\n const args: DelegateArgs = { intent: intent.trim() }\n if (value.model !== undefined) {\n if (typeof value.model !== 'string') throw new TypeError('delegate: `model` must be a string')\n args.model = value.model\n }\n if (value.runId !== undefined) {\n if (typeof value.runId !== 'string') throw new TypeError('delegate: `runId` must be a string')\n args.runId = value.runId\n }\n return args\n}\n\n/** The synchronous result the `delegate` tool returns to the calling agent: the delivered output (or\n * the no-winner reason) PLUS the conserved spend of the whole delegation. */\nexport type DelegateResult =\n | { status: 'winner'; out: unknown; outRef: string; spentTotal: Spend }\n | { status: 'no-winner'; reason: string; spentTotal: Spend }\n\n/** @experimental */\nexport interface DelegateHandlerOptions {\n /** The supervisor brain's router substrate (REQUIRED — the default supervisor is router-brained). */\n router: RouterConfig\n /** WHERE the authored workers run. Required for `supervise()` to spawn anything. */\n backend: ExecutorConfig\n /** The completion oracle the authored workers settle against (settled ⟺ delivered). */\n deliverable?: DeliverableSpec\n /** Default supervisor brain model when a call omits `model`. */\n model?: string\n /** Restrict the run to this subset of models. */\n allowedModels?: readonly string[]\n}\n\n/** Project a `SupervisedResult` onto the tool's flat `DelegateResult`. Both variants carry the real\n * conserved `spentTotal`, so the agent always learns the cost — even on a no-winner, never a faked\n * output and never a fabricated zero spend. */\nfunction toDelegateResult(result: SupervisedResult<unknown>): DelegateResult {\n if (result.kind === 'no-winner') {\n return { status: 'no-winner', reason: result.reason, spentTotal: result.spentTotal }\n }\n return {\n status: 'winner',\n out: result.out,\n outRef: result.outRef,\n spentTotal: result.spentTotal,\n }\n}\n\n/**\n * Build the `delegate` tool handler. Closes over the injected supervisor substrate (`router` /\n * `backend` / `deliverable`); each call routes the agent's intent to `delegate()` and returns the\n * delivered output with its conserved cost.\n */\nexport function createDelegateHandler(\n options: DelegateHandlerOptions,\n): (raw: unknown) => Promise<DelegateResult> {\n return async (raw) => {\n const args = validateDelegateArgs(raw)\n const opts: DelegateOptions = {\n backend: options.backend,\n router: options.router,\n model: args.model ?? options.model,\n ...(options.deliverable ? { deliverable: options.deliverable } : {}),\n ...(options.allowedModels ? { allowedModels: options.allowedModels } : {}),\n ...(args.runId ? { runId: args.runId } : {}),\n }\n const result = await delegate(args.intent, opts)\n return toDelegateResult(result)\n }\n}\n","/**\n *\n * `delegate_feedback` MCP tool — synchronous record of agent / user /\n * downstream-judge feedback on a delegation, artifact, or outcome.\n *\n * The store is append-only. Every rating is its own event; no dedupe.\n * When `refersTo.kind === 'delegation'`, the snapshot is also attached\n * to the matching queue record so `delegation_history` surfaces it\n * inline without a join.\n *\n * @experimental\n */\n\nimport type { FeedbackStore } from '../feedback-store'\nimport { eventToSnapshot } from '../feedback-store'\nimport type { DelegationTaskQueue } from '../task-queue'\nimport type {\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n FeedbackRating,\n FeedbackRefersTo,\n} from '../types'\n\n/** MCP tool name for the `delegate_feedback` feedback-recording tool. @experimental */\nexport const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback'\n\n/** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATE_FEEDBACK_DESCRIPTION = [\n 'Record feedback on a delegation, artifact, or outcome. Synchronous — the',\n 'event is durably stored when this call returns.',\n '',\n 'Use when: you (the agent), the user, or a downstream judge has formed an',\n 'opinion about a piece of work and want it persisted for calibration,',\n 'pricing, or future routing. Every call is a new event — multiple ratings',\n 'on the same target are expected and never deduped.',\n '',\n '`refersTo.kind`:',\n ' - \"delegation\": ref is a taskId returned by delegate_ui_audit',\n ' - \"artifact\": ref is a URI/path/git-sha — anything you can dereference',\n ' - \"outcome\": ref is a free-form description of a downstream result',\n '',\n '`by`:',\n ' - \"agent\": the agent itself rated the work',\n ' - \"user\": the human user rated it',\n ' - \"downstream-judge\": an automated evaluator emitted the rating',\n '',\n 'When ref names a known taskId, the rating is also attached to the',\n 'delegation record so delegation_history surfaces it inline.',\n].join('\\n')\n\n/** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @experimental */\nexport const DELEGATE_FEEDBACK_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n refersTo: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['delegation', 'artifact', 'outcome'] },\n ref: { type: 'string' },\n },\n required: ['kind', 'ref'],\n additionalProperties: false,\n },\n rating: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n label: { type: 'string', enum: ['good', 'bad', 'neutral', 'mixed'] },\n notes: { type: 'string' },\n },\n required: ['score', 'notes'],\n additionalProperties: false,\n },\n by: { type: 'string', enum: ['agent', 'user', 'downstream-judge'] },\n capturedAt: { type: 'string' },\n namespace: { type: 'string' },\n },\n required: ['refersTo', 'rating', 'by'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegateFeedbackArgs(raw: unknown): DelegateFeedbackArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const refersTo = validateRefersTo(value.refersTo)\n const rating = validateRating(value.rating)\n const by = value.by\n if (by !== 'agent' && by !== 'user' && by !== 'downstream-judge') {\n throw new TypeError(\n 'delegate_feedback: `by` must be one of \"agent\" | \"user\" | \"downstream-judge\"',\n )\n }\n const args: DelegateFeedbackArgs = { refersTo, rating, by }\n if (value.capturedAt !== undefined) {\n if (typeof value.capturedAt !== 'string' || Number.isNaN(Date.parse(value.capturedAt))) {\n throw new TypeError('delegate_feedback: `capturedAt` must be an ISO datetime')\n }\n args.capturedAt = value.capturedAt\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateRefersTo(raw: unknown): FeedbackRefersTo {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `refersTo` must be an object')\n }\n const value = raw as Record<string, unknown>\n const kind = value.kind\n if (kind !== 'delegation' && kind !== 'artifact' && kind !== 'outcome') {\n throw new TypeError(\n 'delegate_feedback: `refersTo.kind` must be one of \"delegation\" | \"artifact\" | \"outcome\"',\n )\n }\n const ref = value.ref\n if (typeof ref !== 'string' || ref.trim().length === 0) {\n throw new TypeError('delegate_feedback: `refersTo.ref` must be a non-empty string')\n }\n return { kind, ref: ref.trim() }\n}\n\nfunction validateRating(raw: unknown): FeedbackRating {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `rating` must be an object')\n }\n const value = raw as Record<string, unknown>\n const score = Number(value.score)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new RangeError('delegate_feedback: `rating.score` must be a number in [0, 1]')\n }\n const notes = value.notes\n if (typeof notes !== 'string') {\n throw new TypeError('delegate_feedback: `rating.notes` must be a string')\n }\n const rating: FeedbackRating = { score, notes }\n const label = value.label\n if (label !== undefined) {\n if (label !== 'good' && label !== 'bad' && label !== 'neutral' && label !== 'mixed') {\n throw new TypeError(\n 'delegate_feedback: `rating.label` must be one of \"good\" | \"bad\" | \"neutral\" | \"mixed\"',\n )\n }\n rating.label = label\n }\n return rating\n}\n\n/** @experimental */\nexport interface DelegateFeedbackHandlerOptions {\n queue: DelegationTaskQueue\n store: FeedbackStore\n generateId?: () => string\n now?: () => string\n}\n\n/** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @experimental */\nexport function createDelegateFeedbackHandler(\n options: DelegateFeedbackHandlerOptions,\n): (raw: unknown) => Promise<DelegateFeedbackResult> {\n const generateId = options.generateId ?? randomFeedbackId\n const now = options.now ?? (() => new Date().toISOString())\n return async (raw) => {\n const args = validateDelegateFeedbackArgs(raw)\n const id = generateId()\n const event = {\n id,\n refersTo: args.refersTo,\n rating: args.rating,\n by: args.by,\n capturedAt: args.capturedAt ?? now(),\n namespace: args.namespace,\n }\n await options.store.put(event)\n if (args.refersTo.kind === 'delegation') {\n options.queue.attachFeedback(args.refersTo.ref, eventToSnapshot(event))\n }\n return { recorded: true, id }\n }\n}\n\nfunction randomFeedbackId(): string {\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `fbk-${t}-${r}`\n}\n","/**\n *\n * `delegate_ui_audit` MCP tool — async kickoff for UI audit runs. Validates\n * the input, computes an idempotency key over the canonical fields, hands\n * the task to the queue, and returns a taskId. Identical inputs return\n * the same taskId.\n *\n * The handler does not import the auditor profile directly — consumers\n * inject a `UiAuditorDelegate` via `createMcpServer({ uiAuditorDelegate })`.\n * The delegate is the seam where the consumer chooses the judge (vision\n * model) and the `SandboxClient` (in-process Playwright vs fleet vs\n * remote browser). agent-runtime ships the in-process client under\n * `./profiles` so consumers who want the canonical setup can wire it\n * with a few lines.\n *\n * @experimental\n */\n\nimport path from 'node:path'\nimport { UI_LENSES, type UiLens } from '../../profiles/ui-auditor/substrate'\nimport type { UiAuditorDelegate } from '../delegates'\nimport {\n type DelegateUiAuditArgs,\n type DelegateUiAuditResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\n\n/** MCP tool name for the `delegate_ui_audit` async kickoff tool. @experimental */\nexport const DELEGATE_UI_AUDIT_TOOL_NAME = 'delegate_ui_audit'\n\n/** Human-readable description of the `delegate_ui_audit` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATE_UI_AUDIT_DESCRIPTION = [\n 'Delegate a UI/UX audit to a vision-driven auditor that produces self-contained',\n 'GitHub-issue-ready Markdown findings — one file per finding, with embedded',\n 'screenshot evidence and a suggested fix.',\n '',\n 'Use when: you want a thorough pass over a running web app for consistency,',\n 'hierarchy, layout, ux-flow, duplication, accessibility, responsive, states,',\n 'content, interaction, or perceived-performance issues. The auditor iterates',\n 'lens-by-lens so each pass finds new classes of issues; the workspace registry',\n 'deduplicates across iterations.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'workspace path + indexed findings (typically minutes per audited route).',\n 'Identical inputs return the same taskId — safe to retry.',\n '',\n 'Output layout under workspaceDir:',\n ' registry.json — finding index + capture sidecar',\n ' index.md — human-readable rollup',\n ' issues/NNN--<lens>--<slug>.md — one self-contained GitHub-issue',\n ' screenshots/<route>--<viewport>.png — capture archive',\n '',\n 'Multi-tenant isolation: every finding is scoped to `namespace` when set.',\n \"Never pass another tenant's namespace.\",\n].join('\\n')\n\nconst VIEWPORT_SCHEMA = {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1 },\n height: { type: 'integer', minimum: 1 },\n },\n required: ['width', 'height'],\n additionalProperties: false,\n} as const\n\nconst ROUTE_SCHEMA = {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Stable route name (used in screenshot filenames).' },\n url: { type: 'string', description: 'Fully-qualified URL.' },\n viewports: {\n type: 'array',\n items: VIEWPORT_SCHEMA,\n description: 'Viewports to capture at. Default [{1280, 800}].',\n },\n fullPage: { type: 'boolean' },\n waitFor: { type: 'string', description: 'CSS selector to wait for before capturing.' },\n },\n required: ['name', 'url'],\n additionalProperties: false,\n} as const\n\n/** JSON Schema for `delegate_ui_audit` tool arguments (`workspaceDir`, `routes`, optional config). @experimental */\nexport const DELEGATE_UI_AUDIT_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n workspaceDir: { type: 'string', description: 'Absolute path for the audit workspace.' },\n routes: { type: 'array', items: ROUTE_SCHEMA, minItems: 1 },\n namespace: { type: 'string', description: 'Multi-tenant scope.' },\n config: {\n type: 'object',\n properties: {\n lenses: {\n type: 'array',\n items: { type: 'string', enum: [...UI_LENSES] },\n description: 'Lenses to iterate. Default: every lens except \"other\".',\n },\n maxIterations: { type: 'integer', minimum: 1 },\n maxConcurrency: { type: 'integer', minimum: 1 },\n productContext: { type: 'string' },\n },\n additionalProperties: false,\n },\n },\n required: ['workspaceDir', 'routes'],\n additionalProperties: false,\n} as const\n\nconst PER_LENS_PER_ROUTE_ESTIMATE_MS = 45_000\n\n/** Parse and validate raw MCP tool input into typed `DelegateUiAuditArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegateUiAuditArgs(raw: unknown): DelegateUiAuditArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const workspaceDir = value.workspaceDir\n if (typeof workspaceDir !== 'string' || workspaceDir.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `workspaceDir` must be a non-empty string')\n }\n // Reject relative paths at the boundary. Without this, the writer joins a\n // relative workspaceDir against the process CWD, so the same MCP call\n // produces different file layouts depending on where the server was\n // launched — a silent fail-loud violation for a public API.\n const trimmedWs = workspaceDir.trim()\n if (!path.isAbsolute(trimmedWs)) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must be an absolute path (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n // Reject `..` segments. An absolute path like `/tmp/../../etc` passes\n // `isAbsolute`, then `path.join(workspaceDir, 'issues', …)` normalises it\n // to `/etc/issues/…`, escaping the intended workspace. Check the RAW\n // input split on the platform separator; `path.resolve` already collapses\n // `..` and would silently launder a traversal attempt past us.\n if (trimmedWs.split(path.sep).includes('..')) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must not contain '..' segments (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n const routesRaw = value.routes\n if (!Array.isArray(routesRaw) || routesRaw.length === 0) {\n throw new TypeError('delegate_ui_audit: `routes` must be a non-empty array')\n }\n const routes = routesRaw.map((r, i) => validateRoute(r, i))\n const args: DelegateUiAuditArgs = { workspaceDir: workspaceDir.trim(), routes }\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string' || value.namespace.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `namespace` must be a non-empty string when set')\n }\n args.namespace = value.namespace.trim()\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n return args\n}\n\nfunction validateRoute(raw: unknown, index: number): DelegateUiAuditArgs['routes'][number] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(`delegate_ui_audit: routes[${index}] must be an object`)\n }\n const v = raw as Record<string, unknown>\n if (typeof v.name !== 'string' || v.name.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].name must be a non-empty string`)\n }\n // Defense-in-depth: the slug helpers downstream strip non-alphanumerics, so\n // a route name with `..`, `/`, `\\`, or NUL cannot actually escape the\n // workspace. Rejecting them at the wire boundary keeps the invariant\n // explicit and matches the lens-allowlist style of validation.\n const trimmedName = v.name.trim()\n if (/[./\\\\]/.test(trimmedName) || trimmedName.includes('\\u0000')) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].name must not contain path separators, dots, or NUL (got ${JSON.stringify(v.name)})`,\n )\n }\n if (typeof v.url !== 'string' || v.url.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].url must be a non-empty string`)\n }\n // Parse + restrict to http/https. The in-process auditor client navigates\n // to whatever URL the MCP caller supplies; permitting `file://`, `data:`,\n // `javascript:` would let an attacker controlling the tool input pull\n // local files or run inline scripts.\n let parsedUrl: URL\n try {\n parsedUrl = new URL(v.url)\n } catch {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url is not a parseable URL (got ${JSON.stringify(v.url)})`,\n )\n }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url must use http or https (got ${parsedUrl.protocol})`,\n )\n }\n const out: DelegateUiAuditArgs['routes'][number] = { name: v.name.trim(), url: v.url.trim() }\n if (v.viewports !== undefined) {\n if (!Array.isArray(v.viewports) || v.viewports.length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].viewports must be a non-empty array when set`,\n )\n }\n out.viewports = v.viewports.map((vp, j) => validateViewport(vp, index, j))\n }\n if (v.fullPage !== undefined) {\n if (typeof v.fullPage !== 'boolean') {\n throw new TypeError(`delegate_ui_audit: routes[${index}].fullPage must be a boolean`)\n }\n out.fullPage = v.fullPage\n }\n if (v.waitFor !== undefined) {\n if (typeof v.waitFor !== 'string' || v.waitFor.trim().length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].waitFor must be a non-empty string when set`,\n )\n }\n out.waitFor = v.waitFor.trim()\n }\n return out\n}\n\nfunction validateViewport(\n raw: unknown,\n routeIndex: number,\n viewportIndex: number,\n): { width: number; height: number } {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must be an object`,\n )\n }\n const v = raw as Record<string, unknown>\n const w = Number(v.width)\n const h = Number(v.height)\n if (!Number.isInteger(w) || w <= 0 || !Number.isInteger(h) || h <= 0) {\n throw new RangeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must have positive integer width/height`,\n )\n }\n return { width: w, height: h }\n}\n\nfunction validateConfig(raw: unknown): DelegateUiAuditArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: `config` must be an object')\n }\n const v = raw as Record<string, unknown>\n const out: NonNullable<DelegateUiAuditArgs['config']> = {}\n if (v.lenses !== undefined) {\n if (!Array.isArray(v.lenses) || v.lenses.length === 0) {\n throw new TypeError('delegate_ui_audit: `config.lenses` must be a non-empty array when set')\n }\n const knownSet = new Set<string>(UI_LENSES)\n const lenses: UiLens[] = []\n for (let i = 0; i < v.lenses.length; i += 1) {\n const lens = v.lenses[i]\n if (typeof lens !== 'string' || !knownSet.has(lens)) {\n throw new TypeError(\n `delegate_ui_audit: config.lenses[${i}] must be one of ${UI_LENSES.join('|')}`,\n )\n }\n lenses.push(lens as UiLens)\n }\n out.lenses = lenses\n }\n if (v.maxIterations !== undefined) {\n const n = Number(v.maxIterations)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxIterations` must be a positive integer')\n }\n out.maxIterations = n\n }\n if (v.maxConcurrency !== undefined) {\n const n = Number(v.maxConcurrency)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxConcurrency` must be a positive integer')\n }\n out.maxConcurrency = n\n }\n if (v.productContext !== undefined) {\n if (typeof v.productContext !== 'string') {\n throw new TypeError('delegate_ui_audit: `config.productContext` must be a string')\n }\n out.productContext = v.productContext\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegateUiAuditHandlerOptions {\n queue: DelegationTaskQueue\n delegate: UiAuditorDelegate\n estimateDurationMs?: (args: DelegateUiAuditArgs) => number\n}\n\n/** Build the MCP tool handler that validates input, deduplicates via idempotency key, and enqueues a UI audit. @experimental */\nexport function createDelegateUiAuditHandler(\n options: DelegateUiAuditHandlerOptions,\n): (raw: unknown) => Promise<DelegateUiAuditResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateUiAuditArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'ui-auditor',\n workspaceDir: args.workspaceDir,\n routes: args.routes,\n namespace: args.namespace,\n config: args.config,\n })\n const submitted = options.queue.submit<DelegateUiAuditArgs>({\n profile: 'ui-auditor',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: DelegateUiAuditArgs): number {\n const lenses = args.config?.lenses?.length ?? UI_LENSES.length - 1\n const routes = args.routes.length\n return PER_LENS_PER_ROUTE_ESTIMATE_MS * lenses * routes\n}\n","/**\n *\n * `delegation_history` MCP tool — synchronous read of past delegations.\n * The agent uses this for self-introspection — \"have I delegated this\n * kind of task before? did it work?\" — and calibration.\n *\n * @experimental\n */\n\nimport type {\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** MCP tool name for the `delegation_history` read-past-delegations tool. @experimental */\nexport const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history'\n\n/** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATION_HISTORY_DESCRIPTION = [\n 'Read past delegations newest-first. Each entry carries the original',\n 'arguments, current status, cost, and any feedback attached via',\n 'delegate_feedback.',\n '',\n 'Use when: you want to introspect prior decisions — \"have I asked this',\n 'question before?',\n 'did the last patch land?',\n \"what's the historical\",\n 'success rate of coder delegations on this repo?\". Feed the results back',\n 'into your own routing and calibration.',\n '',\n 'Each entry carries `hasTrace` — when true, the full loop-trace span tree',\n 'is retrievable via delegation_status { taskId, includeTrace: true }.',\n '',\n 'Filters: `namespace` (multi-tenant scope), `profile` (\"coder\" | \"researcher\"),',\n '`since` (ISO date — only delegations started at-or-after). `limit` defaults',\n 'to 50, capped at 500.',\n].join('\\n')\n\n/** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @experimental */\nexport const DELEGATION_HISTORY_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n namespace: { type: 'string' },\n profile: { type: 'string', enum: ['coder', 'researcher'] },\n since: { type: 'string', description: 'ISO datetime — earliest startedAt to include.' },\n limit: { type: 'integer', minimum: 1, maximum: 500 },\n },\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryArgs {\n if (raw === undefined || raw === null) return {}\n if (typeof raw !== 'object') {\n throw new TypeError('delegation_history: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: DelegationHistoryArgs = {}\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string') {\n throw new TypeError('delegation_history: `namespace` must be a string')\n }\n out.namespace = value.namespace\n }\n if (value.profile !== undefined) {\n if (value.profile !== 'coder' && value.profile !== 'researcher') {\n throw new TypeError('delegation_history: `profile` must be \"coder\" or \"researcher\"')\n }\n out.profile = value.profile as DelegationProfile\n }\n if (value.since !== undefined) {\n if (typeof value.since !== 'string' || Number.isNaN(Date.parse(value.since))) {\n throw new TypeError('delegation_history: `since` must be an ISO datetime')\n }\n out.since = value.since\n }\n if (value.limit !== undefined) {\n const n = Number(value.limit)\n if (!Number.isFinite(n) || n < 1 || n > 500) {\n throw new RangeError('delegation_history: `limit` must be an integer in [1, 500]')\n }\n out.limit = Math.trunc(n)\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegationHistoryHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @experimental */\nexport function createDelegationHistoryHandler(\n options: DelegationHistoryHandlerOptions,\n): (raw: unknown) => Promise<DelegationHistoryResult> {\n return async (raw) => {\n const args = validateDelegationHistoryArgs(raw)\n return { delegations: options.queue.history(args) }\n }\n}\n","/**\n *\n * `delegation_status` MCP tool — synchronous poll. Returns the current\n * state machine + optional progress + final result (when terminal).\n *\n * @experimental\n */\n\nimport { NotFoundError } from '../../errors'\nimport type {\n DelegationStatusArgs,\n DelegationStatusResult,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** MCP tool name for the `delegation_status` synchronous-poll tool. @experimental */\nexport const DELEGATION_STATUS_TOOL_NAME = 'delegation_status'\n\n/** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATION_STATUS_DESCRIPTION = [\n 'Poll the status of an async delegation. Returns the current state',\n '(pending | running | completed | failed | cancelled), optional progress,',\n 'and the final result when status === \"completed\".',\n '',\n 'Use when: you previously kicked off an async delegation (delegate_ui_audit)',\n \"and need to know whether the work is done. The agent's right rhythm is to\",\n 'call this every minute or two while waiting; do not busy-poll.',\n '',\n 'For a completed delegate_ui_audit run, `result.output` is the array of UI',\n 'findings — one self-contained Markdown finding per issue, each with an',\n 'embedded screenshot and a suggested fix.',\n '',\n 'Pass includeTrace: true to also receive the journaled loop-trace span',\n 'tree (loop → round → iteration, with placement/cost/verdict metadata).',\n 'Default false — keep routine polls light.',\n '',\n 'Throws NotFoundError when taskId is unknown — never silently returns',\n '`pending` for a typo.',\n].join('\\n')\n\n/** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @experimental */\nexport const DELEGATION_STATUS_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n taskId: { type: 'string', description: 'Returned by delegate_ui_audit.' },\n includeTrace: {\n type: 'boolean',\n description:\n 'Also return the journaled loop-trace span tree for this delegation. Default false.',\n },\n },\n required: ['taskId'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegation_status: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const taskId = value.taskId\n if (typeof taskId !== 'string' || taskId.trim().length === 0) {\n throw new TypeError('delegation_status: `taskId` must be a non-empty string')\n }\n const out: DelegationStatusArgs = { taskId: taskId.trim() }\n if (value.includeTrace !== undefined) {\n if (typeof value.includeTrace !== 'boolean') {\n throw new TypeError('delegation_status: `includeTrace` must be a boolean')\n }\n out.includeTrace = value.includeTrace\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegationStatusHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. @experimental */\nexport function createDelegationStatusHandler(\n options: DelegationStatusHandlerOptions,\n): (raw: unknown) => Promise<DelegationStatusResult> {\n return async (raw) => {\n const args = validateDelegationStatusArgs(raw)\n const status = options.queue.status(\n args.taskId,\n args.includeTrace !== undefined ? { includeTrace: args.includeTrace } : undefined,\n )\n if (!status) {\n throw new NotFoundError(`delegation_status: unknown taskId \"${args.taskId}\"`)\n }\n return status\n }\n}\n","/**\n *\n * Stdio JSON-RPC MCP server exposing the delegation tools to sandbox\n * coding-harness agents (claude-code, codex, opencode, ...): the generic\n * `delegate` verb plus the queue-bound `delegate_feedback`,\n * `delegation_status`, and `delegation_history`. `delegate_ui_audit` is served\n * when a `uiAuditorDelegate` is wired.\n *\n * The server is transport-bound but topology-free: tool execution is\n * delegated to handler functions composed from a queue, a feedback\n * store, and the wired run delegates. Consumers wire those at\n * construction time. The `agent-runtime-mcp` bin serves the generic\n * `delegate` verb over a real sandbox client when `MCP_ENABLE_DELEGATE=1`.\n *\n * Wire protocol: line-delimited JSON-RPC 2.0 over stdio. Each line is\n * one request; each response is one line. `tools/list` and `tools/call`\n * mirror the MCP 2024-11-05 spec; we do not pull in\n * `@modelcontextprotocol/sdk` to keep the dependency footprint zero.\n *\n * @experimental\n */\n\nimport { Readable, Writable } from 'node:stream'\nimport { ValidationError } from '../errors'\nimport type { UiAuditorDelegate } from './delegates'\nimport { type FeedbackStore, InMemoryFeedbackStore } from './feedback-store'\nimport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\nimport { DelegationTaskQueue } from './task-queue'\nimport { createStdioToolServer } from './tool-server'\nimport {\n createDelegateHandler,\n DELEGATE_DESCRIPTION,\n DELEGATE_INPUT_SCHEMA,\n DELEGATE_TOOL_NAME,\n type DelegateHandlerOptions,\n} from './tools/delegate'\nimport {\n createDelegateFeedbackHandler,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n createDelegateUiAuditHandler,\n DELEGATE_UI_AUDIT_DESCRIPTION,\n DELEGATE_UI_AUDIT_INPUT_SCHEMA,\n DELEGATE_UI_AUDIT_TOOL_NAME,\n} from './tools/delegate-ui-audit'\nimport {\n createDelegationHistoryHandler,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n createDelegationStatusHandler,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\nimport type { TraceContext } from './trace-propagation'\n\nexport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\n\n/** @experimental */\nexport interface McpServerOptions {\n /**\n * Required to enable `delegate` — the ONE generic delegation verb. Inject the supervisor\n * substrate: its brain `router`, the worker `backend`, and the completion `deliverable`. The\n * supervisor AUTHORS its own worker from the agent's intent, so there is no worker profile to\n * wire here.\n */\n delegateSupervisor?: DelegateHandlerOptions\n /**\n * Required to enable delegate_ui_audit. Wire one that closes over your\n * `runAgentRounds` + `uiAuditorProfile` + a `SandboxClient` (the\n * canonical in-process choice is `createInProcessUiAuditClient` from\n * `@tangle-network/agent-runtime/profiles`) + your vision judge.\n */\n uiAuditorDelegate?: UiAuditorDelegate\n /** Override the default in-memory feedback store. */\n feedbackStore?: FeedbackStore\n /** Override the default in-memory task queue. */\n queue?: DelegationTaskQueue\n /**\n * Extra tools to serve alongside the delegation tools, for example\n * `createCoordinationTools(...).tools`. Registered after the built-ins; a\n * duplicate name throws so delegation tools cannot be shadowed silently.\n */\n extraTools?: McpToolDescriptor[]\n /**\n * Inherited trace identity (`readTraceContextFromEnv()`) stamped on every\n * record the DEFAULT queue creates. Ignored when `queue` is supplied —\n * pass `traceContext` to that queue's constructor instead.\n */\n traceContext?: TraceContext\n /** Server display name surfaced via `initialize`. Default `'agent-runtime-mcp'`. */\n serverName?: string\n /** Server version surfaced via `initialize`. Default = the package version baked at build time. */\n serverVersion?: string\n}\n\n/** @experimental */\nexport interface McpServer {\n /** Tools currently registered (depend on which delegates were wired). */\n readonly tools: ReadonlyMap<string, McpToolDescriptor>\n /** The underlying queue — exposed so tests can introspect it. */\n readonly queue: DelegationTaskQueue\n /** The feedback store — exposed for the same reason. */\n readonly feedbackStore: FeedbackStore\n /** Handle a single parsed JSON-RPC message. Returns the response object (or `null` for notifications). */\n handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null>\n /** Drive the server on a stdio-shaped transport until `stop()` is called. */\n serve(transport?: McpTransport): Promise<void>\n /** Stop a `serve` call. Subsequent requests are rejected. */\n stop(): void\n}\n\nconst DEFAULT_SERVER_NAME = 'agent-runtime-mcp'\nconst DEFAULT_SERVER_VERSION = '0.22.0'\n\n/**\n * Stdio JSON-RPC MCP server exposing the delegation tools (`delegate`, `delegate_feedback`, `delegation_status`, `delegation_history`, optional `delegate_ui_audit`) to sandbox coding-harness agents.\n *\n * @experimental\n */\nexport function createMcpServer(options: McpServerOptions = {}): McpServer {\n const queue =\n options.queue ??\n new DelegationTaskQueue(\n options.traceContext !== undefined ? { traceContext: options.traceContext } : {},\n )\n const feedbackStore = options.feedbackStore ?? new InMemoryFeedbackStore()\n const serverName = options.serverName ?? DEFAULT_SERVER_NAME\n const serverVersion = options.serverVersion ?? DEFAULT_SERVER_VERSION\n\n const tools = new Map<string, McpToolDescriptor>()\n\n if (options.delegateSupervisor) {\n tools.set(DELEGATE_TOOL_NAME, {\n name: DELEGATE_TOOL_NAME,\n description: DELEGATE_DESCRIPTION,\n inputSchema: DELEGATE_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateHandler(options.delegateSupervisor),\n })\n }\n if (options.uiAuditorDelegate) {\n tools.set(DELEGATE_UI_AUDIT_TOOL_NAME, {\n name: DELEGATE_UI_AUDIT_TOOL_NAME,\n description: DELEGATE_UI_AUDIT_DESCRIPTION,\n inputSchema: DELEGATE_UI_AUDIT_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateUiAuditHandler({ queue, delegate: options.uiAuditorDelegate }),\n })\n }\n tools.set(DELEGATE_FEEDBACK_TOOL_NAME, {\n name: DELEGATE_FEEDBACK_TOOL_NAME,\n description: DELEGATE_FEEDBACK_DESCRIPTION,\n inputSchema: DELEGATE_FEEDBACK_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateFeedbackHandler({ queue, store: feedbackStore }),\n })\n tools.set(DELEGATION_STATUS_TOOL_NAME, {\n name: DELEGATION_STATUS_TOOL_NAME,\n description: DELEGATION_STATUS_DESCRIPTION,\n inputSchema: DELEGATION_STATUS_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationStatusHandler({ queue }),\n })\n tools.set(DELEGATION_HISTORY_TOOL_NAME, {\n name: DELEGATION_HISTORY_TOOL_NAME,\n description: DELEGATION_HISTORY_DESCRIPTION,\n inputSchema: DELEGATION_HISTORY_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationHistoryHandler({ queue }),\n })\n for (const tool of options.extraTools ?? []) {\n if (tools.has(tool.name)) {\n throw new ValidationError(\n `createMcpServer: extra tool \"${tool.name}\" shadows a built-in tool`,\n )\n }\n tools.set(tool.name, tool)\n }\n\n const stdio = createStdioToolServer({\n serverName,\n serverVersion,\n tools: [...tools.values()],\n })\n\n return {\n tools: stdio.tools,\n queue,\n feedbackStore,\n handle: stdio.handle,\n serve: stdio.serve,\n stop: stdio.stop,\n }\n}\n\n/**\n * In-process pair of `Readable` + `Writable` streams suitable for driving\n * `server.serve(...)` from a test. Returns the agent-side stream (the\n * client writes to it) and the server-side stream (the test reads from it).\n *\n * @experimental\n */\nexport function createInProcessTransport(): {\n transport: McpTransport\n clientWrite(line: string): void\n clientClose(): void\n readServer(): Promise<JsonRpcResponse[]>\n} {\n const responses: JsonRpcResponse[] = []\n const input = new Readable({ read() {} })\n const output = new Writable({\n write(chunk, _enc, cb) {\n const text = chunk.toString('utf8')\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n responses.push(JSON.parse(trimmed) as JsonRpcResponse)\n } catch {\n // Non-JSON output should never appear; drop it silently in the\n // test transport rather than crashing.\n }\n }\n cb()\n },\n })\n return {\n transport: { input, output },\n clientWrite(line: string) {\n input.push(`${line}\\n`)\n },\n clientClose() {\n input.push(null)\n },\n async readServer() {\n // Yield to the event loop a few times so async handlers drain.\n for (let i = 0; i < 5; i += 1) await new Promise((r) => setImmediate(r))\n return [...responses]\n },\n }\n}\n","/**\n *\n * Serve the coordination verbs (spawn_agent / await_event / observe_agent / steer_agent / stop)\n * as a real HTTP MCP server over a LIVE `Scope`. This is the keystone that lets a coding-harness\n * agent (opencode via the cli-bridge, claude-code, codex) BE the supervisor: it mounts this MCP\n * (`mcp.mcpServers.coordination`) and calls `spawn_agent` as a native tool, which lands on\n * `Scope.spawn` — a real box driving real boxes, not emulated function-tools.\n *\n * Coordination vs DELEGATION (`../../mcp/delegates.ts`): coordination SPAWNS workers in a CHOSEN\n * backend (`createExecutor({ backend })` — sandbox OR cli-bridge) and live-drives them — observe /\n * steer / resume, recursive sub-drivers, one conserved budget. To instead delegate a coding task\n * INSIDE the agent's OWN sandbox (a durable fire-and-poll job that survives an MCP restart), use the\n * delegation MCP. Coordination is the live, cross-backend supervisor; delegation is own-sandbox async.\n *\n * Transport: JSON-RPC over HTTP POST (the MCP streamable-HTTP shape — `application/json` for a\n * single response). The server is created INSIDE an agent's `act(task, scope)` so it fronts that\n * agent's live scope; tear it down when the act returns.\n *\n * @experimental\n */\n\nimport { createServer, type Server } from 'node:http'\nimport { ConfigError } from '../../errors'\nimport { createMcpServer } from '../../mcp/server'\nimport {\n type AnalystRegistry,\n type CoordinationEvent,\n type CoordinationTools,\n createCoordinationTools,\n DEFAULT_AWAIT_EVENT_TIMEOUT_MS,\n type MakeWorkerAgent,\n type QuestionPolicy,\n type QuestionRecord,\n type SettledWorker,\n type WorkerWatchOptions,\n} from '../../mcp/tools/coordination'\nimport type { DeliverableSpec } from './completion-gate'\nimport type { Budget, ResultBlobStore, Scope } from './types'\n\nexport interface CoordinationMcpHandle {\n /** The URL an in-box harness mounts as `mcp.mcpServers.coordination.url`. */\n readonly url: string\n readonly port: number\n /** The coordination tools' settled-worker ledger (for the driver's finalize). */\n settled(): ReadonlyArray<SettledWorker>\n /** The first driver-authored result whose injected independent check passed. */\n submittedResult: CoordinationTools['submittedResult']\n /** Post-loop drain of already-settled, unpulled children into the ledger — call before reading\n * `settled()` for a finalize, so a delivered child the harness never awaited is not lost. */\n drainResolved: CoordinationTools['drainResolved']\n isStopped(): boolean\n /** The full ordered bus-event log — observability audit + replay trail. */\n history: CoordinationTools['history']\n /** Bus throughput counters for live dashboards. */\n stats: CoordinationTools['stats']\n /** Raise a `finding` on the bus from an online detector watching a worker's live pipe. */\n raiseFinding: CoordinationTools['raiseFinding']\n close(): Promise<void>\n}\n\n/** Hosts that reach only this machine, including the IPv4-mapped and bracketed IPv6 spellings a\n * caller may pass through from config. A name that is not recognizably loopback counts as REMOTE:\n * whether it resolves to a loopback interface is not knowable here, and the safe direction of that\n * doubt is \"exposed\". */\nexport function isLoopbackHost(host: string): boolean {\n const h = host.trim().toLowerCase().replace(/^\\[/, '').replace(/\\]$/, '')\n if (h === 'localhost' || h === '::1' || h === '0:0:0:0:0:0:0:1' || h === '::ffff:127.0.0.1') {\n return true\n }\n return /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)\n}\n\n/** Stand up the coordination MCP over a live scope. The HOST address is `127.0.0.1` (the bridge runs\n * opencode locally, same host); pass `host` to bind elsewhere when the harness is remote — a\n * non-loopback host additionally requires `allowUnauthenticatedRemote`. */\nexport async function serveCoordinationMcp(opts: {\n scope: Scope<unknown>\n blobs: ResultBlobStore\n makeWorkerAgent: MakeWorkerAgent\n perWorker: Budget\n /** Independent completion check exposed to the driver as `submit_result`. */\n deliverable?: DeliverableSpec<unknown>\n /** Hard cap on simultaneously-LIVE workers — `spawn_agent` fails closed once this many are in\n * flight (a concurrency fence on top of the conserved-pool fence). Omit/`<= 0` = no cap. */\n maxLiveWorkers?: number\n /** Max wall-clock ms a single `await_event` may block before returning a re-pollable\n * `{ pending, live }` snapshot instead of erroring on the client's request timeout. Omit =\n * {@link DEFAULT_AWAIT_EVENT_TIMEOUT_MS}; `<= 0` = prior unbounded block (in-process only). */\n awaitTimeoutMs?: number\n port?: number\n /** Bind address. Omit = `127.0.0.1`. A non-loopback host is REFUSED unless\n * `allowUnauthenticatedRemote` acknowledges the exposure. */\n host?: string\n /** Explicit acknowledgment that binding a non-loopback `host` publishes UNAUTHENTICATED\n * spawn_agent / steer_agent / stop to everyone who can reach the port. Required for any\n * non-loopback bind; ignored for loopback ones. */\n allowUnauthenticatedRemote?: boolean\n /** Trace-analyst lenses the driver can run (`run_analyst`) or auto-fire on settle. */\n analysts?: AnalystRegistry\n /** Analyst kinds to auto-run when a worker settles `done` — findings flow up the bus. */\n analyzeOnSettle?: ReadonlyArray<string>\n /** Run the ONLINE detector panel over each worker's live tool trace (raises `finding` events). */\n watchWorkers?: WorkerWatchOptions\n /** Idle time after which `observe_agent` reports a worker as stalled. */\n stallAfterMs?: number\n /** Pass-through subscriber for every bus event (settled / question / finding). */\n onEvent?: (event: CoordinationEvent) => void | Promise<void>\n questionPolicy?: QuestionPolicy\n /** Questions replayed from a prior process of this run — seeds the question ledger. */\n priorQuestions?: ReadonlyArray<QuestionRecord>\n}): Promise<CoordinationMcpHandle> {\n const host = opts.host ?? '127.0.0.1'\n // Fail closed on a non-loopback bind HERE, in the primitive, not only at the composition sites\n // that happen to call it. This function is a public export taking `host` directly, and it mounts\n // spawn_agent / steer_agent / stop as a bare JSON-RPC-over-HTTP handler with NO authentication of\n // any kind — so a caller reaching it without going through `supervise`/`supervisorAgent` would\n // otherwise stand up unauthenticated spawn/steer/stop on every interface. There is no token to\n // require yet, so the only honest options are a loopback bind or an explicit, recorded\n // acknowledgment. The check runs before anything is constructed or listening.\n if (!isLoopbackHost(host) && opts.allowUnauthenticatedRemote !== true) {\n throw new ConfigError(\n `coordination host=${JSON.stringify(host)} is not a loopback address and the coordination ` +\n 'MCP has no authentication: any client that can reach the port could call ' +\n \"spawn_agent/steer_agent and spend this run's budget. Bind a loopback host \" +\n '(\"127.0.0.1\", \"localhost\", \"::1\"), or set allowUnauthenticatedRemote: true to accept ' +\n 'that exposure explicitly.',\n )\n }\n const coord = createCoordinationTools({\n scope: opts.scope,\n blobs: opts.blobs,\n makeWorkerAgent: opts.makeWorkerAgent,\n perWorker: opts.perWorker,\n ...(opts.deliverable ? { deliverable: opts.deliverable } : {}),\n ...(opts.maxLiveWorkers !== undefined ? { maxLiveWorkers: opts.maxLiveWorkers } : {}),\n awaitTimeoutMs: opts.awaitTimeoutMs ?? DEFAULT_AWAIT_EVENT_TIMEOUT_MS,\n ...(opts.analysts ? { analysts: opts.analysts } : {}),\n ...(opts.analyzeOnSettle ? { analyzeOnSettle: opts.analyzeOnSettle } : {}),\n ...(opts.watchWorkers ? { watchWorkers: opts.watchWorkers } : {}),\n ...(opts.stallAfterMs !== undefined ? { stallAfterMs: opts.stallAfterMs } : {}),\n ...(opts.onEvent ? { onEvent: opts.onEvent } : {}),\n ...(opts.questionPolicy ? { questionPolicy: opts.questionPolicy } : {}),\n ...(opts.priorQuestions?.length ? { priorQuestions: opts.priorQuestions } : {}),\n })\n const mcp = createMcpServer({ extraTools: coord.tools, serverName: 'coordination' })\n\n const server: Server = createServer((req, res) => {\n if (req.method !== 'POST') {\n res.writeHead(405, { allow: 'POST' })\n res.end()\n return\n }\n let body = ''\n req.on('data', (c) => {\n body += c\n })\n req.on('end', () => {\n void (async () => {\n try {\n const message = JSON.parse(body) as Parameters<typeof mcp.handle>[0]\n const response = await mcp.handle(message)\n if (response === null) {\n res.writeHead(202).end() // a notification — no body\n return\n }\n res.writeHead(200, { 'content-type': 'application/json' })\n res.end(JSON.stringify(response))\n } catch (e) {\n // A malformed request is the client's to recover from — a typed JSON-RPC error, not a crash.\n res.writeHead(200, { 'content-type': 'application/json' })\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32700, message: e instanceof Error ? e.message : 'parse error' },\n }),\n )\n }\n })()\n })\n })\n\n const port = await new Promise<number>((resolve, reject) => {\n server.once('error', reject)\n server.listen(opts.port ?? 0, host, () => {\n const addr = server.address()\n resolve(typeof addr === 'object' && addr ? addr.port : (opts.port ?? 0))\n })\n })\n\n return {\n url: `http://${host}:${port}/mcp`,\n port,\n settled: () => coord.settled(),\n submittedResult: () => coord.submittedResult(),\n drainResolved: () => coord.drainResolved(),\n isStopped: () => coord.isStopped(),\n history: () => coord.history(),\n stats: () => coord.stats(),\n raiseFinding: (finding) => coord.raiseFinding(finding),\n close: () =>\n new Promise<void>((resolve) => {\n server.close(() => resolve())\n }),\n }\n}\n","/**\n * `supervisorAgent` — build a supervisor `Agent` FROM its profile. The brain is resolved from\n * `profile.harness` exactly as `createExecutor({ backend })` resolves a worker: backend-as-data,\n * no hand-built brain. The supervisor stops being special — it's one profile, materialized by the\n * same resolution rule as every other agent.\n *\n * - `harness` null/undefined → the in-process router tool-loop: `driverAgent` over the\n * canonical `ToolLoopChat`, built by `routerBrain` from the profile's model + the router seam.\n * - `harness` a coding CLI (`claude-code`/`opencode`/`codex`/…) → a SANDBOXED harness drives the\n * coordination verbs: `serveCoordinationMcp` exposes spawn/await/steer/stop over the live scope,\n * and the caller's `driveHarness` runs the harness with that MCP mounted. The harness IS the brain.\n *\n * Both arms spawn children through the SAME `makeWorkerAgent` seam and apply the SAME independent\n * deliverable check to direct submissions. Raw driver prose is never eligible.\n */\nimport type {\n AgentProfileModelHints,\n AgentProfilePrompt,\n AgentProfileResources,\n} from '@tangle-network/agent-interface'\nimport { ConfigError, ValidationError } from '../../errors'\nimport type {\n AnalystRegistry,\n CoordinationEvent,\n MakeWorkerAgent,\n WorkerWatchOptions,\n} from '../../mcp/tools/coordination'\nimport { type RouterConfig, routerBrain } from '../router-client'\nimport type { ToolLoopChat, ToolLoopCompactionOptions } from '../tool-loop'\nimport type { DeliverableSpec } from './completion-gate'\nimport { driverAgent } from './coordination-driver'\nimport type { PriorCoordination } from './coordination-log'\nimport { isLoopbackHost, serveCoordinationMcp } from './coordination-mcp'\nimport { bestDelivered, runFinalizer, runTree, type SupervisorFinalizer } from './finalizer'\nimport type { StopRule } from './stop-rules'\nimport type { Agent, Budget, ResultBlobStore, Scope } from './types'\n\n/** The standing strategy a router-brained supervisor runs with when its profile names no\n * `systemPrompt`. The brain's competence IS this prompt: without it the brain has the coordination\n * verbs but no policy for WHEN to use them, and either over-spawns or stalls. A profile may override\n * it for a specific topology. */\nexport const defaultSupervisorPrompt = [\n 'You are a supervisor accountable for DELIVERING the task — not for looking busy. You succeed only',\n 'when the deliverable is actually produced and verified, never on a worker reporting \"done\".',\n '',\n 'Spawning a worker spends the shared, conserved budget — so delegate with intent, not by reflex:',\n '- Do small, sequential work YOURSELF when you have work tools; spawn a worker when a sub-task is',\n ' large, independent (parallelizable), or needs a clean context the current one has filled.',\n '- Prefer the FEWEST workers that deliver. Over-spawning burns the budget and rarely helps.',\n '',\n 'Manage the context lifecycle on long work: give each spawned worker a BOUNDED brief — the specific',\n 'sub-task plus only the interfaces/state it needs — never your whole history. When one chapter is',\n 'done, distill what the next chapter needs and spawn fresh, rather than steering one worker until',\n 'its context fills and degrades.',\n '',\n 'Wait on real signals (await a settle, answer a blocking question), integrate the result, and stop',\n 'as soon as the deliverable is met.',\n].join('\\n')\n\n/**\n * The supervisor's profile — the subset of an `AgentProfile` that selects + shapes its brain.\n * `harness` is the backend-as-data discriminant; `systemPrompt` is the standing instruction.\n *\n * A canonical `AgentProfile` from `@tangle-network/agent-interface` satisfies this interface\n * structurally: its `model` is a hints OBJECT and its system prompt lives at `prompt.systemPrompt`,\n * so both spellings are accepted here and reduced by {@link resolveSupervisorProfile}. Before that,\n * a canonical profile's model object reached `RouterConfig.model` (a string) as an object and its\n * `prompt.systemPrompt` was dropped — a request the provider rejects, and a supervisor running the\n * default strategy while its profile named another.\n *\n * WHAT EACH ARM HONORS — the two brains read different amounts of a profile, so state it rather\n * than let a caller infer that a field took effect:\n *\n * - ROUTER arm (`harness` null): only `name`, the resolved model id (`model`, or\n * `model.default`), and the resolved system prompt (`prompt.systemPrompt`/`systemPrompt` plus\n * `prompt.instructions` and `resources.instructions`) reach the brain. A full `AgentProfile`'s\n * `tools`, `mcp`, `permissions`, `resources.skills`/`files`, `hooks`, `modes`, `subagents`,\n * `model.provider`, `model.small` and `model.reasoningEffort` are NOT honored here: the router\n * brain is one `ToolLoopChat` over the coordination verbs, and neither of its two tool-calling\n * transports (`routerChatWithTools` buffered, `streamRouterChatWithTools` when\n * `RouterConfig.stream` is set) has a parameter for any of them.\n * - HARNESS arm (`harness` set): the WHOLE profile object is handed to `deps.driveHarness`\n * untouched, plus the resolved system prompt as a separate argument. Everything the profile\n * declares is the harness's to materialize; this module changes none of it.\n */\nexport interface SupervisorProfile {\n readonly name?: string\n /** null/undefined → router brain (in-process tool-loop); a coding-CLI harness → sandboxed brain. */\n readonly harness?: string | null\n /** The router model when the brain is router-driven: a model id, or a canonical profile's model\n * hints whose `default` IS the id. Absent (including a hints object with no `default`) → the\n * deps router config's model applies. Other hints (`small`, `provider`, `reasoningEffort`) are\n * harness-arm material only. */\n readonly model?: string | AgentProfileModelHints\n /** Canonical `AgentProfile` prompt shaping. `prompt.systemPrompt` and the top-level `systemPrompt`\n * are the same standing instruction in two spellings; disagreeing values are a fault, not a pick.\n * `prompt.instructions` lines are appended to the resolved prompt, one per line. */\n readonly prompt?: AgentProfilePrompt\n /** Canonical `AgentProfile` resources. Only `instructions` shapes the brain here (appended to the\n * resolved system prompt); every other resource is the harness's to materialize. */\n readonly resources?: AgentProfileResources\n /** The standing instructions (\"you delegate, you do not solve\"). */\n readonly systemPrompt?: string\n}\n\n/** A `SupervisorProfile` reduced to the scalars the two brain arms consume. `modelId`/`systemPrompt`\n * stay `undefined` when the profile named none — the caller's fallback (`deps.router.model`,\n * the built-in default supervisor prompt) then applies, and this type cannot hide which happened.\n *\n * There is deliberately no `reasoningEffort` here: the router brain runs on `chatWithTools` (the\n * buffered/streamed switch in the router client), and neither transport has a `reasoning_effort`\n * parameter — only the chat-only `routerChatWithUsage` does — so a field carrying it would be a\n * public promise nothing keeps. `model.reasoningEffort` still reaches the harness arm inside the\n * profile. */\nexport interface ResolvedSupervisorProfile {\n readonly name: string\n readonly harness: string | null\n readonly modelId?: string\n readonly systemPrompt?: string\n}\n\n/** Longest prompt excerpt an error message may carry. A supervisor system prompt is routinely\n * thousands of characters; two of them interpolated whole turn a configuration fault into an\n * unreadable wall, so a fault reports each prompt's LENGTH plus a leading excerpt instead. */\nconst PROMPT_EXCERPT_CHARS = 60\n\n/** `<n> chars starting \"<first 60>…\"` — enough to tell two prompts apart without printing either. */\nfunction describePrompt(value: string): string {\n const head = value.slice(0, PROMPT_EXCERPT_CHARS)\n return `${value.length} chars starting ${JSON.stringify(head)}${value.length > PROMPT_EXCERPT_CHARS ? '…' : ''}`\n}\n\n/**\n * The instruction lines a canonical `resources.instructions` contributes. A plain string and an\n * `inline` resource are their own text; a `github` reference names bytes that live elsewhere and\n * cannot be fetched while building a supervisor synchronously — that fails loud rather than\n * dropping instructions the profile says the agent runs under (the same rule\n * `improve()`'s memory surface applies to the same field).\n */\nfunction resourceInstructionLines(\n instructions: AgentProfileResources['instructions'],\n): readonly string[] {\n if (instructions === undefined) return []\n if (typeof instructions === 'string') return instructions.length > 0 ? [instructions] : []\n if (instructions.kind === 'inline') {\n return instructions.content.length > 0 ? [instructions.content] : []\n }\n throw new ConfigError(\n 'supervisorAgent: profile.resources.instructions is a github resource reference ' +\n `(${JSON.stringify(instructions.path)}), which cannot be fetched while the supervisor is ` +\n 'built — pass the instruction text as a string or an inline resource',\n )\n}\n\n/**\n * The standing instruction both arms run under, assembled from every canonical spelling that\n * carries one: the system prompt (`prompt.systemPrompt` or the top-level `systemPrompt`), then the\n * `prompt.instructions` lines, then `resources.instructions` — each on its own line, in that order.\n * `undefined` only when the profile names none at all.\n *\n * Two disagreeing system prompts throw: they are the same standing instruction in two spellings, so\n * picking one silently changes what the supervisor runs and there is no defensible winner.\n */\nfunction resolveSupervisorSystemPrompt(\n profile: SupervisorProfile,\n activePrompt?: string,\n): string | undefined {\n const promptSystem = profile.prompt?.systemPrompt\n const topSystem = profile.systemPrompt\n if (promptSystem !== undefined && topSystem !== undefined && promptSystem !== topSystem) {\n throw new ValidationError(\n 'supervisorAgent: profile.prompt.systemPrompt and profile.systemPrompt are both set and ' +\n 'differ — they are the same standing instruction, so keep exactly one ' +\n `(prompt.systemPrompt: ${describePrompt(promptSystem)}; ` +\n `systemPrompt: ${describePrompt(topSystem)})`,\n )\n }\n // Instruction lines are APPENDED to the active prompt, so a profile that names only\n // instructions keeps whatever prompt the arm would otherwise run — never replaces it.\n const base = promptSystem ?? topSystem ?? activePrompt\n const lines = [\n ...(profile.prompt?.instructions ?? []),\n ...resourceInstructionLines(profile.resources?.instructions),\n ]\n if (lines.length === 0) return base\n return (base !== undefined ? [base, ...lines] : lines).join('\\n')\n}\n\n/**\n * The router model id, or `undefined` when the profile names none. A string `model` IS the id; an\n * object `model` is canonical model hints and `default` is the id. `AgentProfileModelHints.default`\n * is OPTIONAL upstream (`{ provider: 'anthropic' }` is a valid canonical profile), so hints without\n * a resolvable id are the documented \"profile names no model\" case: the router config's own model\n * applies, exactly as when `model` is absent.\n */\nexport function resolveSupervisorModelId(profile: SupervisorProfile): string | undefined {\n if (typeof profile.model === 'string') return profile.model\n const fromHints = profile.model?.default\n return typeof fromHints === 'string' && fromHints.length > 0 ? fromHints : undefined\n}\n\n/**\n * Reduce either profile spelling — a hand-written `SupervisorProfile` or a canonical `AgentProfile`\n * — to the scalars the brain arms consume:\n *\n * - `modelId`: a string `model` verbatim, else `model.default`. Absent or unresolvable → the\n * router config's own model applies unchanged.\n * - `systemPrompt`: the system prompt plus the `prompt.instructions` and `resources.instructions`\n * lines, one per line.\n *\n * `supervisorAgent` resolves each piece only where it is consumed (the model id on the router arm\n * only); this whole-profile reduction is the caller-facing view of the same rules.\n */\nexport function resolveSupervisorProfile(profile: SupervisorProfile): ResolvedSupervisorProfile {\n const systemPrompt = resolveSupervisorSystemPrompt(profile)\n const modelId = resolveSupervisorModelId(profile)\n return {\n name: profile.name ?? 'supervisor',\n harness: profile.harness ?? null,\n ...(modelId !== undefined ? { modelId } : {}),\n ...(systemPrompt !== undefined ? { systemPrompt } : {}),\n }\n}\n\n/** Where the coordination MCP binds. Omit = an ephemeral port on `127.0.0.1` (the local-harness\n * default); set `host` when the root or the harness runs off-host. */\nexport interface CoordinationBinding {\n readonly host?: string\n readonly port?: number\n /** Explicit acknowledgment required to bind a NON-loopback host — see\n * {@link assertCoordinationBinding} for what is being accepted. */\n readonly allowUnauthenticatedRemote?: boolean\n}\n\n/**\n * Fail closed on a non-loopback coordination bind. `serveCoordinationMcp` mounts spawn_agent /\n * steer_agent / stop with NO authentication of any kind (it is a bare JSON-RPC-over-HTTP handler),\n * so a non-loopback bind lets anyone who can reach the port spawn agents and spend the run's\n * conserved budget. There is no token to require yet, so the only honest options are loopback or an\n * explicit, recorded acknowledgment — never a silent bind.\n */\nexport function assertCoordinationBinding(binding: CoordinationBinding | undefined): void {\n const host = binding?.host\n if (host === undefined || isLoopbackHost(host)) return\n if (binding?.allowUnauthenticatedRemote === true) return\n throw new ConfigError(\n `supervisorAgent: coordination.host=${JSON.stringify(host)} is not a loopback address and the coordination MCP ` +\n 'has no authentication: any client that can reach the port could call spawn_agent/steer_agent ' +\n 'and spend this run\\'s budget. Bind a loopback host (\"127.0.0.1\", \"localhost\", \"::1\"), or set ' +\n 'coordination.allowUnauthenticatedRemote: true to accept that exposure explicitly.',\n )\n}\n\n/** How to run a sandboxed harness as the DRIVER, with the coordination verbs mounted — the substrate\n * seam the caller supplies (mirrors `makeWorkerAgent` for spawned children). It runs `profile` on\n * `task` in its backend (sandbox / cli-bridge) with `coordinationMcpUrl` mounted as an MCP server,\n * so the harness calls spawn_agent / await_event / stop as native tools over the live scope. */\nexport type DriveHarness = (args: {\n /** The caller's profile, EXACTLY as passed to `supervisorAgent` — never rewritten. A canonical\n * `AgentProfile` stays schema-valid here (the canonical schema rejects unknown top-level keys,\n * so hoisting a resolved prompt onto it would make a profile its own validator refuses). */\n readonly profile: SupervisorProfile\n /** The standing instruction assembled from the profile: its system prompt in either spelling,\n * plus the `prompt.instructions` and `resources.instructions` lines. Absent when the profile\n * names none — the harness's own default then applies. This, not `profile.systemPrompt`, is what\n * the harness should run under. */\n readonly systemPrompt?: string\n readonly task: unknown\n readonly scope: Scope<unknown>\n readonly coordinationMcpUrl: string\n}) => Promise<void>\n\nexport interface SupervisorAgentDeps {\n readonly blobs: ResultBlobStore\n /** Resolve a spawned worker `profile` to a leaf agent — the recursion seam (same for both arms). */\n readonly makeWorkerAgent: MakeWorkerAgent\n /** Per-child budget reserved from the conserved pool on each spawn. */\n readonly perWorker: Budget\n /** Independent completion check for direct driver work (`submit_result`). */\n readonly deliverable?: DeliverableSpec<unknown>\n /** Hard cap on simultaneously-LIVE workers across both arms — `spawn_agent` fails closed once\n * this many are in flight (a concurrency fence on top of the conserved-pool fence; bounds live\n * boxes/sandboxes, not total work). Omit/`<= 0` = no cap. */\n readonly maxLiveWorkers?: number\n /** Router substrate for a router-brained supervisor (`harness` null). The profile's model wins. */\n readonly router?: RouterConfig\n /** Inject the brain directly (tests / advanced) instead of resolving `routerBrain` from the profile. */\n readonly brain?: ToolLoopChat\n /** Required for a sandboxed-harness supervisor (`harness` set): runs the harness as the driver. */\n readonly driveHarness?: DriveHarness\n /** WORK tools the supervisor may call DIRECTLY (router arm) — so it can do simple work ITSELF and\n * only delegate when it needs parallelism. Pair with `executeExtraTool`. */\n readonly extraTools?: ReadonlyArray<{\n readonly name: string\n readonly description?: string\n readonly parameters: Record<string, unknown>\n }>\n /** Runs an `extraTools` call; null/undefined falls through to the coordination dispatch. */\n readonly executeExtraTool?: (\n name: string,\n args: Record<string, unknown>,\n ) => Promise<string | null | undefined>\n /** Analyst lenses available to the driver (both arms). Required for `analyzeOnSettle`. */\n readonly analysts?: AnalystRegistry\n /** Analyst kinds run on each worker-settle → a `finding` the driver composes its next steer from\n * (the self-improving UP-leg). Unset/empty = status quo (no analyst feed). Requires `analysts`. */\n readonly analyzeOnSettle?: ReadonlyArray<string>\n /** Run the ONLINE detector panel over each worker's LIVE tool trace (both arms) so the driver\n * learns a worker is looping mid-run instead of at settle. Omit = no online watching. */\n readonly watchWorkers?: WorkerWatchOptions\n /** Idle time after which `observe_agent` reports a worker as stalled. Omit = runtime default. */\n readonly stallAfterMs?: number\n /** PROGRESS-derived stop rule (router arm). Ends a run that has stopped learning BEFORE it\n * exhausts a ceiling; it can never keep a run alive past one. Build it with `plateau` /\n * `noProgressFor` / `allWorkersStalled` from `supervise/stop-rules` — the thresholds are the\n * caller's judgment. Omit = ceilings only. */\n readonly stopRule?: StopRule\n /** One-shot notification of WHY a `stopRule` ended the run. */\n readonly onProgressStop?: (reason: string) => void\n readonly maxTurns?: number\n /** Give the supervisor brain a chapter-lifecycle on its OWN context window (router arm only) — it\n * distills its coordination transcript to a compact progress note once it exceeds the threshold,\n * instead of re-billing the whole thing every turn. See `DriverAgentOptions.compaction`. */\n readonly compaction?: ToolLoopCompactionOptions\n /** Pass-through subscriber for every coordination bus event (both arms) — the seam a durable\n * caller hooks its coordination log onto. */\n readonly onEvent?: (event: CoordinationEvent) => void | Promise<void>\n /** Questions + findings replayed from a prior process of this run (a durable coordination log).\n * Router arm: seeds the question ledger + the resume brief. Sandbox arm: seeds the ledger. */\n readonly priorCoordination?: PriorCoordination\n /** How the settled ledger becomes the run's output (both arms). Default `bestDelivered` — the\n * exact keep-best every existing caller had. Always runs under the delivered-only invariant. */\n readonly finalizer?: SupervisorFinalizer\n /** Where the coordination MCP binds (sandbox arm). Omit = an ephemeral loopback port, which is\n * unreachable from an off-host harness. A non-loopback host fails closed — see\n * {@link assertCoordinationBinding}. */\n readonly coordination?: CoordinationBinding\n}\n\n/** Build a supervisor `Agent` from its profile: the brain resolves from `profile.harness` (backend-as-data), the same resolution rule as every worker. */\nexport function supervisorAgent(\n profile: SupervisorProfile,\n deps: SupervisorAgentDeps,\n): Agent<unknown, unknown> {\n const name = profile.name ?? 'supervisor'\n const harness = profile.harness ?? null\n // The prompt is consumed by BOTH arms, so it resolves here; the model id is router-arm-only and\n // resolves inside that arm, so a harness supervisor never touches a field it does not use.\n // No fallback at this site: the harness supplies its own standing prompt, and the router arm\n // re-resolves against its default below so instruction lines append to that default.\n const profilePrompt = resolveSupervisorSystemPrompt(profile)\n\n // Bind safety is a BUILD-time fault, not a run-time one: it must throw before any compute, on the\n // same synchronous path as the other configuration guards. The binding is SNAPSHOT here and the\n // snapshot is both what gets checked and what `act()` binds, so a later mutation of\n // `deps.coordination` cannot slip an unchecked host past the guard.\n const coordination: CoordinationBinding | undefined = deps.coordination\n ? { ...deps.coordination }\n : undefined\n assertCoordinationBinding(coordination)\n\n if (harness === null && coordination !== undefined) {\n throw new ConfigError(\n 'supervisorAgent: coordination binding is only meaningful for a harness-brained supervisor ' +\n '(profile.harness set). A router-brained supervisor calls the coordination verbs in ' +\n 'process and serves no MCP, so this binding would be silently ignored.',\n )\n }\n\n if (harness !== null && deps.compaction) {\n throw new ValidationError(\n 'supervisorAgent: compaction is only supported for router-brained supervisors (profile.harness null)',\n )\n }\n\n if (harness === null) {\n // ROUTER arm: the in-process tool-loop. `routerBrain` is now an internal detail — the caller\n // passes a profile, not a hand-built brain (a test may still inject `deps.brain`).\n const brain = deps.brain ?? routerBrainFromProfile(profile, deps)\n return driverAgent({\n name,\n brain,\n blobs: deps.blobs,\n makeWorkerAgent: deps.makeWorkerAgent,\n perWorker: deps.perWorker,\n // Resolved against the router's own default, so a profile naming only instruction\n // lines appends them to that default instead of replacing it.\n systemPrompt:\n resolveSupervisorSystemPrompt(profile, defaultSupervisorPrompt) ?? defaultSupervisorPrompt,\n ...(deps.deliverable ? { deliverable: deps.deliverable } : {}),\n ...(deps.maxLiveWorkers !== undefined ? { maxLiveWorkers: deps.maxLiveWorkers } : {}),\n ...(deps.extraTools ? { extraTools: deps.extraTools } : {}),\n ...(deps.executeExtraTool ? { executeExtraTool: deps.executeExtraTool } : {}),\n ...(deps.analysts ? { analysts: deps.analysts } : {}),\n ...(deps.analyzeOnSettle ? { analyzeOnSettle: deps.analyzeOnSettle } : {}),\n ...(deps.watchWorkers ? { watchWorkers: deps.watchWorkers } : {}),\n ...(deps.stallAfterMs !== undefined ? { stallAfterMs: deps.stallAfterMs } : {}),\n ...(deps.stopRule ? { stopRule: deps.stopRule } : {}),\n ...(deps.onProgressStop ? { onProgressStop: deps.onProgressStop } : {}),\n ...(deps.maxTurns !== undefined ? { maxTurns: deps.maxTurns } : {}),\n ...(deps.compaction ? { compaction: deps.compaction } : {}),\n ...(deps.onEvent ? { onEvent: deps.onEvent } : {}),\n ...(deps.priorCoordination ? { priorCoordination: deps.priorCoordination } : {}),\n ...(deps.finalizer ? { finalizer: deps.finalizer } : {}),\n })\n }\n\n // SANDBOX arm: a sandboxed harness drives the coordination verbs over the live scope.\n const driveHarness = deps.driveHarness\n if (!driveHarness) {\n throw new ValidationError(\n `supervisorAgent: profile.harness=\"${harness}\" needs deps.driveHarness (how to run the harness with the coordination MCP mounted)`,\n )\n }\n return {\n name,\n async act(task, scope) {\n const mcp = await serveCoordinationMcp({\n scope,\n blobs: deps.blobs,\n makeWorkerAgent: deps.makeWorkerAgent,\n perWorker: deps.perWorker,\n ...(coordination?.host !== undefined ? { host: coordination.host } : {}),\n ...(coordination?.port !== undefined ? { port: coordination.port } : {}),\n // `serveCoordinationMcp` enforces the same non-loopback rule itself (it is a public export\n // anyone may call directly), so the caller's acknowledgment has to reach it — not just the\n // `assertCoordinationBinding` above.\n ...(coordination?.allowUnauthenticatedRemote === true\n ? { allowUnauthenticatedRemote: true }\n : {}),\n ...(deps.deliverable ? { deliverable: deps.deliverable } : {}),\n ...(deps.maxLiveWorkers !== undefined ? { maxLiveWorkers: deps.maxLiveWorkers } : {}),\n ...(deps.analysts ? { analysts: deps.analysts } : {}),\n ...(deps.analyzeOnSettle ? { analyzeOnSettle: deps.analyzeOnSettle } : {}),\n ...(deps.watchWorkers ? { watchWorkers: deps.watchWorkers } : {}),\n ...(deps.stallAfterMs !== undefined ? { stallAfterMs: deps.stallAfterMs } : {}),\n ...(deps.onEvent ? { onEvent: deps.onEvent } : {}),\n ...(deps.priorCoordination?.questions.length\n ? { priorQuestions: deps.priorCoordination.questions }\n : {}),\n })\n try {\n try {\n await driveHarness({\n profile,\n ...(profilePrompt !== undefined ? { systemPrompt: profilePrompt } : {}),\n task,\n scope,\n coordinationMcpUrl: mcp.url,\n })\n } catch (error) {\n // Once the injected check has accepted a result, a later backend shutdown/timeout cannot\n // erase that completed work. Without an accepted submission, preserve the backend error.\n if (!mcp.submittedResult()) throw error\n }\n // Drain settled-but-unpulled children first — a gate-verified delivery the harness never\n // awaited must still reach the finalize ledger.\n await mcp.drainResolved()\n // Direct work is eligible only through `submit_result`, after the injected independent\n // check passes. Raw harness prose remains ineligible.\n const submitted = mcp.submittedResult()\n if (submitted) return submitted.result\n return await runFinalizer(deps.finalizer ?? bestDelivered, {\n settled: mcp.settled(),\n blobs: deps.blobs,\n tree: runTree(scope),\n budget: scope.budget,\n })\n } finally {\n await mcp.close()\n }\n },\n }\n}\n\nfunction routerBrainFromProfile(\n profile: SupervisorProfile,\n deps: SupervisorAgentDeps,\n): ToolLoopChat {\n if (!deps.router) {\n throw new ValidationError(\n 'supervisorAgent: a router-brained supervisor (harness null) needs deps.router (or deps.brain)',\n )\n }\n // The model id is resolved HERE, the one place it is consumed. `model.reasoningEffort` is not\n // carried with it: `routerBrain` runs on `chatWithTools` — `routerChatWithTools` buffered, or\n // `streamRouterChatWithTools` when the spread `deps.router` sets `stream` — and neither transport\n // has a `reasoning_effort` parameter (only the chat-only `routerChatWithUsage` does), so\n // forwarding it would need a router-client change, not a local workaround.\n const modelId = resolveSupervisorModelId(profile)\n return routerBrain({\n ...deps.router,\n ...(modelId !== undefined ? { model: modelId } : {}),\n })\n}\n","/**\n * `supervise` — the one-call \"just invoke the supervisor\". Builds + runs a supervisor from its\n * profile with sensible defaults, so the common case is `supervise(profile, task, { backend, budget })`\n * instead of hand-wiring `blobs` / `perWorker` / `journal` / `executors` / `maxDepth`. The raw seams\n * (`supervisorAgent` + `createSupervisor().run`) stay available for power use.\n *\n * `workerFromBackend` derives the worker seam (`makeWorkerAgent`) from a backend config + an optional\n * completion oracle — so \"where the workers run\" is one data choice, not a hand-rolled factory.\n */\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ConfigError, ValidationError } from '../../errors'\nimport type {\n AnalystRegistry,\n MakeWorkerAgent,\n WorkerWatchOptions,\n} from '../../mcp/tools/coordination'\nimport { composeRuntimeHooks, type RuntimeHooks } from '../../runtime-hooks'\nimport type { RouterConfig } from '../router-client'\nimport type { ToolLoopChat, ToolLoopCompactionOptions } from '../tool-loop'\nimport { type DeliverableSpec, gateOnDeliverable } from './completion-gate'\nimport type { SupervisorFinalizer } from './finalizer'\nimport { assertModelAllowed } from './model-policy'\nimport {\n createSupervisorSpanRecorder,\n type SupervisorSpanOptions,\n type SupervisorSpanRecorder,\n} from './otel-spans'\nimport { createFileRunContext, createInMemoryRunContext } from './run-context'\nimport { createExecutor, type ExecutorConfig } from './runtime'\nimport type { StopRule } from './stop-rules'\nimport { createSupervisor } from './supervisor'\nimport {\n assertCoordinationBinding,\n type CoordinationBinding,\n type DriveHarness,\n resolveSupervisorModelId,\n type SupervisorProfile,\n supervisorAgent,\n} from './supervisor-agent'\nimport type {\n Agent,\n AgentSpec,\n Budget,\n ExecutorContext,\n ResultBlobStore,\n SpawnJournal,\n} from './types'\nimport type { WaitProbeRegistry } from './wait'\nimport { workerTraceSeamKey } from './worker-trace'\n\n/**\n * Build the worker seam from a backend (WHERE workers run) + an optional completion oracle (the\n * deliverable check that makes \"settled ⟺ delivered\" true — the guard against \"ran but didn't\n * deliver\"). The ONE place a backend becomes a spawnable worker.\n *\n * `seams` exists because this path builds the leaf executor EAGERLY and hands it back as a BYO\n * `executorSpec.executor`. The registry resolves a BYO executor without ever consulting the\n * per-child `ExecutorContext` the `Scope` seeds, so anything the scope would have supplied is\n * invisible here and has to be passed in. It is a FUNCTION because it is resolved once per worker\n * construction, so a caller may hand back something the run only learns later — which is exactly how\n * `supervise()` gives a traced run's workers their trace context without ordering the span recorder\n * ahead of the worker seam.\n */\nexport function workerFromBackend(\n backend: ExecutorConfig,\n deliverable?: DeliverableSpec<unknown>,\n seams?: () => Readonly<Record<string, unknown>>,\n): MakeWorkerAgent {\n return (rawProfile) => {\n const p = (rawProfile ?? {}) as { name?: unknown }\n const name = typeof p.name === 'string' && p.name.length > 0 ? p.name : 'worker'\n // harness:null — createExecutor(backend) carries the harness in its config (the sandbox case-arm\n // reads config.harness when the spec leaves it null); the BYO executor below resolves the leaf.\n const spec: AgentSpec = { profile: rawProfile as AgentProfile, harness: null }\n const ctx: ExecutorContext = { signal: new AbortController().signal, seams: seams?.() ?? {} }\n const built = createExecutor(backend)(spec, ctx)\n const executor = deliverable ? gateOnDeliverable(built, deliverable) : built\n return { name, act: async () => '', executorSpec: { ...spec, executor } } as Agent<\n unknown,\n unknown\n > & { executorSpec: AgentSpec }\n }\n}\n\n/** A name→value table, in this package's resolver-port shape (the same one `WaitProbeRegistry`\n * uses): construction stays the caller's, lookup stays lazy, and a table backed by a file, a\n * plugin loader, or a plain object all satisfy one interface. */\nexport interface SuperviseRegistryTable<T> {\n resolve(name: string): T | undefined\n}\n\n/**\n * The name→value tables that make the four CODE-valued options expressible as run DATA.\n *\n * `deliverable` / `finalizer` / `analysts` / `probes` are functions and registries, so a recorded\n * run configuration (a JSON row, a campaign spec, a resumed run's options) cannot carry them — and\n * a run with no `deliverable` cannot return a `winner` at all outside the sandbox backend, because\n * the finalizer keeps only children whose oracle passed and nothing else writes that verdict. A\n * caller that owns the code registers it here once and names it from data thereafter.\n */\nexport interface SuperviseRegistry {\n readonly deliverables?: SuperviseRegistryTable<DeliverableSpec<unknown>>\n readonly finalizers?: SuperviseRegistryTable<SupervisorFinalizer>\n readonly analysts?: SuperviseRegistryTable<AnalystRegistry>\n readonly probes?: SuperviseRegistryTable<WaitProbeRegistry>\n}\n\n/** Which registry table each nameable option resolves against. Indexing this map inside\n * {@link resolveNamed} makes the pairing a type error to get wrong: `resolveNamed('probes',\n * 'deliverables', …)` does not compile. */\ninterface SuperviseRegistryTableFor {\n readonly deliverable: 'deliverables'\n readonly finalizer: 'finalizers'\n readonly analysts: 'analysts'\n readonly probes: 'probes'\n}\n\n/** Resolve one option that may be given as a value OR as a name into `opts.registry`. Both failure\n * modes name the option, the requested name, and the table it was looked up in — a typo must not\n * degrade into a silently unconfigured run (which for `deliverable` means \"no run can ever\n * deliver\"). A resolver port cannot enumerate its names, so the message names the table instead of\n * listing what was in it. */\nfunction resolveNamed<K extends keyof SuperviseRegistryTableFor, T extends object>(\n option: K,\n table: SuperviseRegistryTableFor[K],\n value: T | string | undefined,\n registry: SuperviseRegistryTable<T> | undefined,\n): T | undefined {\n if (typeof value !== 'string') return value\n if (!registry) {\n throw new ConfigError(\n `supervise: opts.${option} = ${JSON.stringify(value)} names a registry entry, but no ` +\n `opts.registry.${table} was provided to resolve it against`,\n )\n }\n const entry = registry.resolve(value)\n if (entry === undefined) {\n throw new ConfigError(\n `supervise: opts.${option} = ${JSON.stringify(value)} is not in opts.registry.${table} — ` +\n 'the table resolved no entry under that name',\n )\n }\n return entry\n}\n\nexport interface SuperviseOptions {\n /** The conserved compute pool for the whole run. */\n readonly budget: Budget\n /** WHERE workers run — derives the worker seam. Provide this OR an explicit `makeWorkerAgent`. */\n readonly backend?: ExecutorConfig\n /** The independent completion check for backend-derived workers and direct supervisor\n * submissions. Strongly recommended: without it the supervisor cannot submit its own work and\n * backend-derived workers fall back to their own validity signal. A `string` names an entry in\n * `registry.deliverables`. */\n readonly deliverable?: DeliverableSpec<unknown> | string\n /** Name→value tables for the four code-valued options, so a recorded run configuration can name\n * them instead of carrying closures. See {@link SuperviseRegistry}. */\n readonly registry?: SuperviseRegistry\n /** Where the coordination MCP binds when the supervisor is harness-driven. Omit = an ephemeral\n * port on `127.0.0.1`, which an off-host root cannot reach. A non-loopback host is refused\n * unless `allowUnauthenticatedRemote` acknowledges that the verbs are unauthenticated. */\n readonly coordination?: CoordinationBinding\n /** Override the worker seam directly (tests / advanced) instead of deriving it from `backend`. */\n readonly makeWorkerAgent?: MakeWorkerAgent\n /** The supervisor's router substrate (`harness` null). The profile's model wins. */\n readonly router?: RouterConfig\n /** Inject the supervisor brain directly (tests / advanced). */\n readonly brain?: ToolLoopChat\n /** Run a sandboxed-harness supervisor (`harness` set). */\n readonly driveHarness?: DriveHarness\n /** WORK tools the supervisor may call DIRECTLY — so a recursive atom can ACT (do simple work\n * itself) OR SPAWN (delegate when it needs parallelism), not be a pure manager. Pair with\n * `executeExtraTool`. Router arm only (`harness` null). */\n readonly extraTools?: ReadonlyArray<{\n readonly name: string\n readonly description?: string\n readonly parameters: Record<string, unknown>\n }>\n /** Runs an `extraTools` call; null/undefined falls through to the coordination dispatch. */\n readonly executeExtraTool?: (\n name: string,\n args: Record<string, unknown>,\n ) => Promise<string | null | undefined>\n /** Per-child budget reserved on each spawn. Defaults to a quarter of the pool's tokens. */\n readonly perWorker?: Budget\n /** Hard cap on simultaneously-LIVE workers — `spawn_agent` fails closed once this many are in\n * flight. The conserved pool bounds TOTAL work; this bounds SIMULTANEOUS work (live boxes/\n * sandboxes a real fleet runs at once). Omit/`<= 0` = no cap (the pool stays the only fence). */\n readonly maxLiveWorkers?: number\n /** Analyst lenses available to the driver. Required for `analyzeOnSettle`. Unset → status quo\n * (the driver receives settled worker outputs, no analyst findings). A `string` names an entry in\n * `registry.analysts`. */\n readonly analysts?: AnalystRegistry | string\n /** Analyst kind ids run AUTOMATICALLY when a worker settles `done` — each re-enters as a `finding`\n * the driver pulls (`await_event`) and composes its next steer from. The self-improving UP-leg,\n * threaded to the driver at this level (propagate to sub-drivers via a recursive `makeWorkerAgent`).\n * Omit/empty = status quo (no analyst feed). Requires `analysts`. */\n readonly analyzeOnSettle?: ReadonlyArray<string>\n /**\n * Watch every worker's LIVE tool trace with the online detector panel and raise a `finding` the\n * moment one loops or error-storms — so the supervisor learns it mid-run (via `await_event`)\n * instead of at settle. Pairs with a steerable worker: the finding is the evidence, `steer_agent`\n * is the correction. Requires a backend whose executor exposes a trace source (the steerable\n * sandbox worker and the pi wrapper do); other runtimes are simply not watched.\n *\n * Omit = off (status quo — no online watching, no extra events).\n */\n readonly watchWorkers?: WorkerWatchOptions\n /** Idle time after which `observe_agent` reports a running worker as `stalled`. A derived read\n * at observation time — nothing is killed or retried. Omit = the runtime default. */\n readonly stallAfterMs?: number\n /** Worker output store. Defaults to in-memory. */\n readonly blobs?: ResultBlobStore\n /**\n * Make the run DURABLE: journal + result blobs + the coordination side-log are file-backed under\n * this directory (`createFileRunContext`), fsynced per write, and the supervisor reads the prior\n * tree first. Re-running with the same `runDir` AND the same `runId` resumes, and the built-in\n * driver is resume-AWARE out of the box: the children that already settled are replayed onto\n * `Scope.resume` (and into the driver's settled ledger + its first context), keyed assignments\n * (`spawn_agent`'s `key`) resolve to their committed results instead of re-running, pending\n * waits re-arm on their original deadlines, prior questions/findings replay from the\n * coordination log, and the finalize spans both processes' work. Unset = in-memory, fresh\n * every call.\n *\n * The boundary that remains: work that was IN FLIGHT when the process died is not recovered —\n * the built-in executors cannot re-attach to a dead process's executions, so those assignments\n * resume as explicitly lost/in-doubt and re-run (reported, never silent).\n *\n * `runId` matters here: it defaults to the constant `'supervise'`, which is fine for a single\n * resumable run per directory but collides across concurrent runs sharing one `runDir`.\n */\n readonly runDir?: string\n /** Override the spawn journal directly (advanced; `runDir` is the ordinary durable path). Pair\n * with `blobs` — a journal whose result payloads live in a different store cannot replay. */\n readonly journal?: SpawnJournal\n /** Predicate registry for `poll` wait-states (`Scope.wait`). A `poll` names its predicate so the\n * wait survives a restart; this is what the name resolves against. Unset ⇒ `poll` waits are\n * refused `unknown-probe` and `timer` waits still work. A `string` names an entry in\n * `registry.probes`. */\n readonly probes?: WaitProbeRegistry | string\n /**\n * PROGRESS-derived stop rule (router-brained supervisor). Ends a run that has stopped LEARNING\n * before it exhausts a ceiling — the answer to \"a run should end because it is done or stuck,\n * not because it ran out\". It composes with the budget guards and can never override one.\n *\n * Build it from `supervise/stop-rules`: `plateau({window, minDelta})`,\n * `noProgressFor({ms, settles})`, `allWorkersStalled({...})`, combined with `anyOf`/`allOf`. The\n * thresholds are policy and stay with you; the enforcement lives in the runtime. Omit = ceilings\n * only (unchanged behavior).\n */\n readonly stopRule?: StopRule\n /** One-shot notification of WHY a `stopRule` ended the run — so a caller records the reason\n * instead of inferring an early stop from an unexhausted budget. */\n readonly onProgressStop?: (reason: string) => void\n readonly maxDepth?: number\n readonly maxTurns?: number\n /** Give the supervisor brain a chapter-lifecycle on its OWN context window (router arm only): once\n * its coordination transcript exceeds `thresholdTokens` it distills to a compact progress note and\n * continues, instead of re-billing the whole transcript every turn (the cost that makes the LLM-brain\n * front door lose to a dumb-Ralph respawn). The live `Scope` roster is the durable state across\n * chapters. Default off. `distill` defaults to a brain self-summary + the settled-worker roster. */\n readonly compaction?: ToolLoopCompactionOptions\n readonly runId?: string\n readonly now?: () => number\n /** Restrict the run to this subset of models. When set, every configured model — the\n * supervisor router model, the profile's model, and the backend's model — must be a member,\n * or `supervise()` throws a `ConfigError` before any compute is spent. Unset = unrestricted. */\n readonly allowedModels?: readonly string[]\n /** How the settled-worker ledger becomes the run's output. Default `bestDelivered` — the single\n * highest-scoring DELIVERED child (the exact behavior every existing caller had). Alternatives:\n * `collectDelivered` (every verified distinct output with provenance — a Pareto set / recorded\n * disagreement) or a custom `SupervisorFinalizer`. Whatever the finalizer, it operates on\n * structurally DELIVERED outputs only — an undelivered or invalid child stays ineligible. A\n * `string` names an entry in `registry.finalizers`. */\n readonly finalizer?: SupervisorFinalizer | string\n /** Lifecycle observers for the whole recursive tree (`Scope` re-seeds them into every nested\n * scope). Composed with the `otel` recorder below when both are set. Omit = no observers, which\n * is the behavior every existing caller has. */\n readonly hooks?: RuntimeHooks\n /**\n * OPT-IN OTLP tracing: emit one span per supervised node (opened at spawn, closed at settle,\n * parented to its parent node's span) plus an `LLM` child span per metered driver turn, so the\n * tree is readable by any trace viewer instead of only by a journal parser. See `otel-spans.ts`.\n *\n * Omit and the run emits nothing, allocates no recorder, and installs no hook — telemetry is\n * never a default. Present with no reachable endpoint (no `exportConfig.endpoint` and no\n * `OTEL_EXPORTER_OTLP_ENDPOINT`) is also a no-op. The spawn journal is untouched either way:\n * spans are telemetry, never the replay/resume record.\n */\n readonly otel?: Omit<SupervisorSpanOptions, 'runId' | 'now'>\n}\n\n/** A quarter of the token pool per worker → ~4 workers fit before `poolStarved` halts spawning. */\nfunction defaultPerWorker(budget: Budget): Budget {\n return {\n maxIterations: budget.maxIterations,\n maxTokens: Math.max(1, Math.floor(budget.maxTokens / 4)),\n }\n}\n\n/** One-call supervisor: build + run a supervisor from its profile with sensible defaults; the raw `supervisorAgent` + `createSupervisor().run` seams stay available for power use. */\nexport function supervise(profile: SupervisorProfile, task: unknown, opts: SuperviseOptions) {\n // Fail loud before any compute: every configured model must be in the allowed subset (no-op\n // when allowedModels is unset). The backend seam carries its own model on most backends. The\n // profile's model is checked as the RESOLVED id, so a canonical AgentProfile's `model.default`\n // is subject to the same policy a plain string model is.\n const backendModel = (opts.backend as { model?: unknown } | undefined)?.model\n assertModelAllowed(opts.router?.model, opts.allowedModels)\n assertModelAllowed(resolveSupervisorModelId(profile), opts.allowedModels)\n assertModelAllowed(\n typeof backendModel === 'string' ? backendModel : undefined,\n opts.allowedModels,\n )\n\n // Named options become values before anything is built or spent — an unknown name is a\n // configuration fault, and a fault that surfaces after a run started has already cost budget.\n const deliverable = resolveNamed(\n 'deliverable',\n 'deliverables',\n opts.deliverable,\n opts.registry?.deliverables,\n )\n const finalizer = resolveNamed(\n 'finalizer',\n 'finalizers',\n opts.finalizer,\n opts.registry?.finalizers,\n )\n const analysts = resolveNamed('analysts', 'analysts', opts.analysts, opts.registry?.analysts)\n const probes = resolveNamed('probes', 'probes', opts.probes, opts.registry?.probes)\n assertCoordinationBinding(opts.coordination)\n\n // `withDriver: true` is the wiring invariant either way (a `role: 'driver'` child must resolve\n // to the nested-scope executor); `runDir` only changes WHERE the journal and blobs live.\n const ctx =\n opts.runDir !== undefined\n ? createFileRunContext(opts.runDir, { withDriver: true })\n : createInMemoryRunContext({ withDriver: true })\n const blobs = opts.blobs ?? ctx.blobs\n const perWorker = opts.perWorker ?? defaultPerWorker(opts.budget)\n\n const runId = opts.runId ?? 'supervise'\n const log = ctx.coordinationLog\n const now = opts.now ?? Date.now\n\n // The span recorder for this run, built inside `start()` so a configuration fault below still\n // throws without leaving an exporter's flush timer behind. The worker seam reads it LAZILY (it is\n // resolved once per spawned worker, long after `start()` assigned this), which is what lets the\n // seam be built here while the recorder is built there.\n let spans: SupervisorSpanRecorder | undefined\n\n let makeWorkerAgent = opts.makeWorkerAgent\n if (!makeWorkerAgent) {\n if (!opts.backend) {\n throw new ValidationError(\n 'supervise: provide opts.backend (where workers run) or opts.makeWorkerAgent',\n )\n }\n // A front-door worker is spawned by the ROOT scope (the supervisor brain drives that scope\n // directly), so the span that parents it is the run's root span — which is exactly what\n // `workerTrace(runId)` resolves to. A caller nesting sub-drivers behind its own recursive\n // `makeWorkerAgent` owns the same wiring one level down, for ITS spawning node.\n makeWorkerAgent = workerFromBackend(opts.backend, deliverable, () =>\n spans ? { [workerTraceSeamKey]: spans.workerTrace(runId) } : {},\n )\n }\n const workerFactory = makeWorkerAgent\n\n // Every configuration fault above throws SYNCHRONOUSLY — a caller that guards with\n // `expect(() => supervise(...)).toThrow` still sees the throw, and no compute starts. Only the\n // durable coordination replay needs to await, so the run begins inside this closure.\n const start = async () => {\n // The durable coordination side-log (file contexts only): replay the prior process's questions\n // and findings into the driver, and append this process's as they publish — so a resumed run\n // keeps the coordination context the spawn journal does not record.\n const priorCoordination = log ? await log.load(runId) : undefined\n\n const agent = supervisorAgent(profile, {\n blobs,\n makeWorkerAgent: workerFactory,\n perWorker,\n ...(deliverable ? { deliverable } : {}),\n ...(log ? { onEvent: (ev) => log.append(runId, ev, new Date(now()).toISOString()) } : {}),\n ...(priorCoordination &&\n (priorCoordination.questions.length > 0 || priorCoordination.findings.length > 0)\n ? { priorCoordination }\n : {}),\n ...(finalizer ? { finalizer } : {}),\n ...(opts.coordination ? { coordination: opts.coordination } : {}),\n ...(opts.maxLiveWorkers !== undefined ? { maxLiveWorkers: opts.maxLiveWorkers } : {}),\n ...(opts.router ? { router: opts.router } : {}),\n ...(opts.brain ? { brain: opts.brain } : {}),\n ...(opts.driveHarness ? { driveHarness: opts.driveHarness } : {}),\n ...(opts.extraTools ? { extraTools: opts.extraTools } : {}),\n ...(opts.executeExtraTool ? { executeExtraTool: opts.executeExtraTool } : {}),\n ...(analysts ? { analysts } : {}),\n ...(opts.analyzeOnSettle ? { analyzeOnSettle: opts.analyzeOnSettle } : {}),\n ...(opts.watchWorkers ? { watchWorkers: opts.watchWorkers } : {}),\n ...(opts.stallAfterMs !== undefined ? { stallAfterMs: opts.stallAfterMs } : {}),\n ...(opts.stopRule ? { stopRule: opts.stopRule } : {}),\n ...(opts.onProgressStop ? { onProgressStop: opts.onProgressStop } : {}),\n ...(opts.maxTurns !== undefined ? { maxTurns: opts.maxTurns } : {}),\n ...(opts.compaction ? { compaction: opts.compaction } : {}),\n })\n\n // Built ONLY when `otel` is configured AND an exporter resolves, so the default path allocates\n // nothing and passes no `hooks` at all — byte-for-byte the wiring every existing caller gets.\n spans = opts.otel ? createSupervisorSpanRecorder({ runId, ...opts.otel, now }) : undefined\n const recorder = spans\n const hooks = recorder ? composeRuntimeHooks(opts.hooks, recorder.hooks) : opts.hooks\n\n const run = createSupervisor<unknown, unknown>().run(agent, task, {\n budget: opts.budget,\n runId,\n journal: opts.journal ?? ctx.journal,\n blobs,\n executors: ctx.executors,\n maxDepth: opts.maxDepth ?? 8,\n ...(probes ? { probes } : {}),\n ...(ctx.resume === true ? { resume: true } : {}),\n ...(opts.now ? { now: opts.now } : {}),\n ...(hooks ? { hooks } : {}),\n // Only a run that actually records spans hands trace context down to its workers; with no\n // recorder this key is absent and no spawned worker's environment is touched.\n ...(recorder ? { workerTrace: recorder.workerTrace } : {}),\n })\n if (!recorder) return run\n // The recorder closes the root span on BOTH exits and never rethrows, so tracing can neither\n // change the result nor swallow the run's own rejection.\n try {\n const result = await run\n await recorder.finish({ result })\n return result\n } catch (error) {\n await recorder.finish({ error })\n throw error\n }\n }\n\n return start()\n}\n"],"mappings":"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"}
|