@tangle-network/agent-runtime 0.81.1 → 0.83.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +4 -0
  2. package/dist/agent.d.ts +5 -3
  3. package/dist/agent.js +7 -7
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +3 -2
  6. package/dist/analyst-loop.js +2 -2
  7. package/dist/{chunk-35WXYO26.js → chunk-4WXGK6GV.js} +2 -2
  8. package/dist/chunk-4WXGK6GV.js.map +1 -0
  9. package/dist/{chunk-UZ5SODU7.js → chunk-5IBQAPVB.js} +1 -1
  10. package/dist/chunk-5IBQAPVB.js.map +1 -0
  11. package/dist/{chunk-5JAUQZQA.js → chunk-7LO5GMAO.js} +1 -1
  12. package/dist/chunk-7LO5GMAO.js.map +1 -0
  13. package/dist/{chunk-H7IBHAFT.js → chunk-BZF3KQ6G.js} +1 -1
  14. package/dist/chunk-BZF3KQ6G.js.map +1 -0
  15. package/dist/{chunk-WIR4HOOJ.js → chunk-DPEUKJRO.js} +1 -1
  16. package/dist/chunk-DPEUKJRO.js.map +1 -0
  17. package/dist/{chunk-EAGRBFQF.js → chunk-J3N6GODQ.js} +2 -2
  18. package/dist/chunk-J3N6GODQ.js.map +1 -0
  19. package/dist/{chunk-GRAGM4MC.js → chunk-NURIQBJQ.js} +1 -1
  20. package/dist/chunk-NURIQBJQ.js.map +1 -0
  21. package/dist/{chunk-D6GIWPKD.js → chunk-QDVLTRCP.js} +51 -4
  22. package/dist/chunk-QDVLTRCP.js.map +1 -0
  23. package/dist/{chunk-FNMGYYSS.js → chunk-SGKPNBXE.js} +1 -1
  24. package/dist/chunk-SGKPNBXE.js.map +1 -0
  25. package/dist/{chunk-VHJDS6OR.js → chunk-SSA6OERV.js} +6 -6
  26. package/dist/chunk-SSA6OERV.js.map +1 -0
  27. package/dist/{chunk-BPS254IE.js → chunk-UD4BHQMI.js} +2 -2
  28. package/dist/{chunk-BPS254IE.js.map → chunk-UD4BHQMI.js.map} +1 -1
  29. package/dist/{chunk-OUGNIHDZ.js → chunk-UJ3ONGHR.js} +6 -6
  30. package/dist/chunk-UJ3ONGHR.js.map +1 -0
  31. package/dist/{chunk-LWGVVP2C.js → chunk-VNOOH22O.js} +2 -2
  32. package/dist/chunk-VNOOH22O.js.map +1 -0
  33. package/dist/{chunk-NBV35BR6.js → chunk-YEJR7IXO.js} +1 -1
  34. package/dist/chunk-YEJR7IXO.js.map +1 -0
  35. package/dist/{chunk-C2FZ6GR6.js → chunk-YPA5MLVE.js} +2 -2
  36. package/dist/chunk-YPA5MLVE.js.map +1 -0
  37. package/dist/{coordination-BI9tpcmF.d.ts → coordination-CuDLO8wj.d.ts} +53 -32
  38. package/dist/environment-provider.d.ts +2 -2
  39. package/dist/environment-provider.js +1 -1
  40. package/dist/{improvement-adapter-CioiEE2z.d.ts → improvement-adapter-CDR8QNVM.d.ts} +3 -0
  41. package/dist/index.d.ts +163 -49
  42. package/dist/index.js +43 -13
  43. package/dist/index.js.map +1 -1
  44. package/dist/intelligence.d.ts +14 -8
  45. package/dist/intelligence.js +1 -1
  46. package/dist/intelligence.js.map +1 -1
  47. package/dist/{kb-gate-CuzMYGYM.d.ts → kb-gate-CwHO0vz6.d.ts} +4 -2
  48. package/dist/lifecycle.d.ts +2 -2
  49. package/dist/lifecycle.js +3 -3
  50. package/dist/{local-harness-DU7yV6mG.d.ts → local-harness-sI0S_XNA.d.ts} +2 -1
  51. package/dist/{loop-runner-bin-CBkLsyFg.d.ts → loop-runner-bin-hQDUL8Ld.d.ts} +28 -13
  52. package/dist/loop-runner-bin.d.ts +7 -7
  53. package/dist/loop-runner-bin.js +10 -10
  54. package/dist/loops.d.ts +153 -46
  55. package/dist/loops.js +9 -7
  56. package/dist/mcp/bin.js +8 -8
  57. package/dist/mcp/bin.js.map +1 -1
  58. package/dist/mcp/index.d.ts +44 -38
  59. package/dist/mcp/index.js +11 -11
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-serve-verifier-BvMAV_8U.d.ts → mcp-serve-verifier-FL7-ZEb_.d.ts} +8 -3
  62. package/dist/{openai-tools-B-3v06BE.d.ts → openai-tools-BnrOmGjN.d.ts} +7 -4
  63. package/dist/platform.d.ts +4 -0
  64. package/dist/platform.js.map +1 -1
  65. package/dist/profiles.d.ts +36 -23
  66. package/dist/profiles.js +2 -2
  67. package/dist/profiles.js.map +1 -1
  68. package/dist/{router-client-D6Ocf4jG.d.ts → router-client-r8y_VFVM.d.ts} +1 -0
  69. package/dist/{substrate-rNj6TDc3.d.ts → substrate-DO2GHNg2.d.ts} +5 -3
  70. package/dist/{types-By9LXllv.d.ts → types-Driepl87.d.ts} +3 -2
  71. package/dist/{types-BF-MEsQB.d.ts → types-ESeMOj94.d.ts} +26 -11
  72. package/dist/{worktree-fanout-D9Z2dMS9.d.ts → worktree-fanout-D6xR2CIA.d.ts} +16 -10
  73. package/dist/{worktree-harness-Dx8XULW3.d.ts → worktree-harness-CX_McRLp.d.ts} +11 -8
  74. package/package.json +1 -1
  75. package/dist/chunk-35WXYO26.js.map +0 -1
  76. package/dist/chunk-5JAUQZQA.js.map +0 -1
  77. package/dist/chunk-C2FZ6GR6.js.map +0 -1
  78. package/dist/chunk-D6GIWPKD.js.map +0 -1
  79. package/dist/chunk-EAGRBFQF.js.map +0 -1
  80. package/dist/chunk-FNMGYYSS.js.map +0 -1
  81. package/dist/chunk-GRAGM4MC.js.map +0 -1
  82. package/dist/chunk-H7IBHAFT.js.map +0 -1
  83. package/dist/chunk-LWGVVP2C.js.map +0 -1
  84. package/dist/chunk-NBV35BR6.js.map +0 -1
  85. package/dist/chunk-OUGNIHDZ.js.map +0 -1
  86. package/dist/chunk-UZ5SODU7.js.map +0 -1
  87. package/dist/chunk-VHJDS6OR.js.map +0 -1
  88. package/dist/chunk-WIR4HOOJ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/executor.ts","../../src/mcp/in-process-executor.ts","../../src/mcp/bin-helpers.ts","../../src/mcp/detached-coder.ts","../../src/mcp/detached-turn.ts","../../src/mcp/delegates.ts","../../src/mcp/tools/checks.ts"],"sourcesContent":["/**\n * @experimental\n *\n * Delegation executors — the layer between MCP delegates and the sandbox\n * substrate. Each executor exposes a {@link SandboxClient} the kernel\n * consumes plus a placement tag so the trace pipeline can correlate workers\n * with their physical placement.\n *\n * Two implementations ship in-box:\n *\n * - {@link createSiblingSandboxExecutor} — every delegation spawns a fresh\n * sandbox sibling to the caller. Default when the MCP server runs as a\n * standalone CLI mounted outside a fleet.\n *\n * - {@link createFleetWorkspaceExecutor} — delegations dispatch onto machines\n * in the caller's existing fleet so worker diffs land directly on the\n * caller's filesystem (the fleet's shared workspace). Selected when the\n * parent sandbox passes `TANGLE_FLEET_ID` into the MCP server's env.\n */\n\nimport type { CreateSandboxOptions, SandboxInstance } from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\n\n/** @experimental */\nexport interface DelegationExecutor {\n /** Sandbox client the kernel calls. Returned with `describePlacement` set. */\n readonly client: SandboxClient\n /** Best-effort one-liner used in stderr boot logs and diagnostics. */\n describe(): string\n /**\n * Where delegated work physically runs. `sibling` and `fleet` placements are\n * session-backed (boxes expose `driveTurn`, so detached dispatch + resume\n * apply); `in-process` spawns local harness CLIs with no sandbox session to\n * detach. Optional so consumer-implemented executors stay source-compatible;\n * absent means \"unknown\" and detached dispatch is not enabled for it.\n */\n readonly placement?: 'sibling' | 'fleet' | 'in-process'\n}\n\n/** @experimental */\nexport interface SiblingSandboxExecutorOptions {\n client: SandboxClient\n}\n\n/**\n * Wrap a raw sandbox SDK client so the kernel emits\n * `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.\n *\n * The returned client `.create()` delegates to the underlying client; the\n * only added behavior is a `describePlacement` tag the kernel reads.\n *\n * @experimental\n */\nexport function createSiblingSandboxExecutor(\n options: SiblingSandboxExecutorOptions,\n): DelegationExecutor {\n const underlying = options.client\n const client: SandboxClient = {\n create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n return underlying.create(opts)\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n return { kind: 'sibling', sandboxId: readId(box) }\n },\n }\n return {\n client,\n placement: 'sibling',\n describe(): string {\n return 'sibling-sandbox (each delegation = fresh sandbox via client.create)'\n },\n }\n}\n\n/**\n * Minimal `SandboxFleet` surface the fleet executor calls. Declared\n * structurally so tests can pass an in-memory stub without instantiating the\n * sandbox SDK.\n *\n * @experimental\n */\nexport interface FleetHandle {\n readonly fleetId: string\n /** Machine ids in dispatch-eligible order. The executor round-robins. */\n readonly ids: ReadonlyArray<string>\n /** Resolve a machine id to its `SandboxInstance` — that machine is mounted\n * on the fleet's shared workspace, so any diff the worker writes lands on\n * every other fleet machine's filesystem too. */\n sandbox(machineId: string): Promise<SandboxInstance>\n}\n\n/** @experimental */\nexport interface FleetWorkspaceExecutorOptions {\n fleet: FleetHandle\n /**\n * Override the machine-selection policy. Default = round-robin across\n * `fleet.ids`, skipping the optional `excludeMachineIds` set (typically the\n * coordinator machine the MCP server is running on).\n */\n selectMachine?: (call: { callIndex: number; ids: ReadonlyArray<string> }) => string\n /**\n * Machine ids to skip during default round-robin. Set to the caller's own\n * machineId so workers don't compete with the orchestrator on the same VM.\n */\n excludeMachineIds?: ReadonlyArray<string>\n}\n\n/**\n * Build an executor that resolves each delegated iteration to an existing\n * machine in `fleet`. The fleet's shared-workspace policy means the worker\n * machine sees the caller's filesystem — diffs land in-place with no\n * cross-sandbox copy step.\n *\n * @experimental\n */\nexport function createFleetWorkspaceExecutor(\n options: FleetWorkspaceExecutorOptions,\n): DelegationExecutor {\n const fleet = options.fleet\n const exclude = new Set(options.excludeMachineIds ?? [])\n let callIndex = 0\n // machineId-by-sandboxId, populated as we resolve machines so\n // `describePlacement` can recover the assignment from the SandboxInstance\n // the kernel hands back.\n const placementBySandboxId = new Map<string, { machineId: string }>()\n\n const client: SandboxClient = {\n async create(): Promise<SandboxInstance> {\n const ids = fleet.ids.filter((id) => !exclude.has(id))\n if (ids.length === 0) {\n throw new Error(\n `agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(',')}], excluded=[${[...exclude].join(',')}])`,\n )\n }\n const selector = options.selectMachine\n const machineId = selector ? selector({ callIndex, ids }) : ids[callIndex % ids.length]\n callIndex += 1\n if (typeof machineId !== 'string' || machineId.length === 0) {\n throw new Error('agent-runtime: fleet executor selectMachine returned an empty machine id')\n }\n const box = await fleet.sandbox(machineId)\n const sandboxId = readId(box)\n if (sandboxId) placementBySandboxId.set(sandboxId, { machineId })\n return box\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n const sandboxId = readId(box)\n const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : undefined\n return {\n kind: 'fleet',\n sandboxId,\n fleetId: fleet.fleetId,\n machineId: recorded?.machineId,\n }\n },\n }\n\n return {\n client,\n placement: 'fleet',\n describe(): string {\n const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(',')}])` : ''\n return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(',')}]${excluded})`\n },\n }\n}\n\nfunction readId(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 * @experimental\n *\n * In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image\n * carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness\n * AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling\n * sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel\n * subprocesses in N parallel worktrees (round-robin `harnesses`).\n *\n * This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the\n * `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`\n * port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and\n * `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed\n * patch artifact) on the `result` event. The sandbox-session decode layer\n * (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles\n * the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.\n */\n\nimport { randomUUID } from 'node:crypto'\nimport type {\n AgentProfile,\n CreateSandboxOptions,\n SandboxEvent,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\nimport type { DelegationExecutor } from './executor'\nimport type { LocalHarness } from './local-harness'\nimport type { GitRunner, WorktreeHandle } from './worktree'\nimport { runWorktreeHarness } from './worktree-harness'\n\n/** @experimental */\nexport interface InProcessExecutorOptions {\n /** Absolute path to the git repo (the workspace). Worktrees go under `<repoRoot>/.agent-worktrees/`. */\n repoRoot: string\n /** Harnesses to round-robin across `create()` calls. One entry = no fanout. Default `['claude']`. */\n harnesses?: ReadonlyArray<LocalHarness>\n /** Optional per-delegation test command run in the worktree after the harness exits. */\n testCmd?: string\n /** Optional per-delegation typecheck command. Same shape as `testCmd`. */\n typecheckCmd?: string\n /** Wall-clock cap per harness subprocess (ms). Default 5min. */\n harnessTimeoutMs?: number\n /** Wall-clock cap per test/typecheck subprocess (ms). Default 2min. */\n postCheckTimeoutMs?: number\n /** Test seam — override the git runner used by the worktree helpers. */\n runGit?: GitRunner\n /** Test seam — override the harness runner (defaults to the real CLI via `runLocalHarness`). */\n runHarness?: typeof import('./local-harness').runLocalHarness\n /** Test seam — override the post-check runner (defaults to a `sh -c` spawn). A throw is folded\n * into a non-fatal `{exitCode:-1}` so a broken check command fails the signal, not the run. */\n runPostCheck?: (\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n ) => Promise<{ exitCode: number; stdout: string; stderr: string }>\n}\n\n/** @experimental */\nexport interface InProcessExecutorDescribePlacement extends LoopSandboxPlacement {\n /** Worktree path in the parent sandbox's filesystem (set so traces correlate to on-disk artifacts). */\n worktreePath?: string\n /** Which harness handled this delegation. */\n harness?: LocalHarness\n}\n\ninterface VirtualSandbox extends SandboxInstance {\n __inProcess: {\n runId: string\n harness: LocalHarness\n worktree?: WorktreeHandle\n }\n}\n\nconst DEFAULT_HARNESS_TIMEOUT_MS = 5 * 60 * 1000\nconst DEFAULT_POSTCHECK_TIMEOUT_MS = 2 * 60 * 1000\n\n/**\n * Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`\n * returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which\n * runs the shared worktree-harness core and emits one `result` event whose `data.result` is the\n * raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile\n * (`backend.profile`) threads its systemPrompt + model into the harness via the core.\n *\n * @experimental\n */\nexport function createInProcessExecutor(options: InProcessExecutorOptions): DelegationExecutor {\n const harnesses =\n options.harnesses && options.harnesses.length > 0\n ? [...options.harnesses]\n : (['claude'] as const)\n const runPostCheck = options.runPostCheck ?? defaultRunPostCheck\n // The core speaks one `runCommand` seam ({exitCode, output}); adapt the post-check seam\n // ({exitCode, stdout, stderr}) onto it, folding a throw into a non-fatal failure signal so a\n // broken check command fails the signal rather than aborting the whole delegation.\n const runCommand = async ({\n command,\n cwd,\n signal,\n }: {\n command: string\n cwd: string\n timeoutMs: number\n signal?: AbortSignal\n }): Promise<{ exitCode: number | null; output: string }> => {\n try {\n const r = await runPostCheck(command, cwd, signal)\n return { exitCode: r.exitCode, output: r.stderr || r.stdout }\n } catch (err) {\n return { exitCode: -1, output: err instanceof Error ? err.message : String(err) }\n }\n }\n\n let callIndex = 0\n\n const client: SandboxClient = {\n async create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n const runId = randomUUID()\n const harness = harnesses[callIndex % harnesses.length] as LocalHarness\n callIndex += 1\n // §1.5: the authored profile rides in `backend.profile` (set by `buildBackendOptions`).\n // Without one (a direct test `create()`), fall back to a name-only profile → the harness\n // sees the task prompt with no system prepend, the pre-fix behavior.\n const profile =\n ((opts?.backend as { profile?: AgentProfile } | undefined)?.profile as\n | AgentProfile\n | undefined) ?? ({ name: `in-process-${harness}` } as AgentProfile)\n\n const virtual: VirtualSandbox = {\n id: `in-process-${runId}`,\n __inProcess: { runId, harness },\n async *streamPrompt(\n this: VirtualSandbox,\n message: string | unknown[],\n promptOpts?: { signal?: AbortSignal },\n ): AsyncGenerator<SandboxEvent> {\n const taskPrompt =\n typeof message === 'string'\n ? message\n : message\n .map((p) =>\n typeof p === 'object' && p && 'text' in p\n ? String((p as { text: unknown }).text)\n : '',\n )\n .join('\\n')\n\n // The shared worktree-harness core: worktree → profile-aware harness → diff → checks.\n // A throw cleans up inside the core; on success we own the teardown (the finally).\n const run = await runWorktreeHarness({\n repoRoot: options.repoRoot,\n profile,\n harness,\n taskPrompt,\n runId,\n harnessTimeoutMs: options.harnessTimeoutMs ?? DEFAULT_HARNESS_TIMEOUT_MS,\n checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,\n ...(options.testCmd !== undefined ? { testCmd: options.testCmd } : {}),\n ...(options.typecheckCmd !== undefined ? { typecheckCmd: options.typecheckCmd } : {}),\n ...(options.runGit ? { runGit: options.runGit } : {}),\n ...(options.runHarness ? { runHarness: options.runHarness } : {}),\n runCommand,\n ...(promptOpts?.signal ? { signal: promptOpts.signal } : {}),\n })\n this.__inProcess.worktree = run.worktree\n\n try {\n yield {\n type: 'in_process.harness.started',\n data: { runId, harness, worktreePath: run.worktree.path, command: harness },\n }\n const h = run.result.harness\n yield {\n type: 'in_process.harness.ended',\n data: {\n runId,\n exitCode: h.exitCode,\n durationMs: h.durationMs,\n killedBySignal: h.killedBySignal,\n timedOut: h.timedOut,\n stdoutBytes: h.stdout.length,\n stderrBytes: h.stderr.length,\n },\n }\n yield {\n type: 'result',\n data: {\n result: run.result,\n source: 'in-process-executor',\n harness,\n runId,\n },\n }\n } finally {\n await run.cleanup()\n }\n },\n } as unknown as VirtualSandbox\n\n return virtual\n },\n describePlacement(box: SandboxInstance): InProcessExecutorDescribePlacement {\n const sandboxId = (box as unknown as { id?: string }).id\n const meta = (box as VirtualSandbox).__inProcess\n return {\n kind: 'sibling',\n sandboxId,\n worktreePath: meta?.worktree?.path,\n harness: meta?.harness,\n }\n },\n }\n\n return {\n client,\n placement: 'in-process',\n describe(): string {\n return `in-process (repoRoot=${options.repoRoot}, harnesses=[${harnesses.join(',')}]${\n options.testCmd ? `, testCmd=\"${options.testCmd}\"` : ''\n }${options.typecheckCmd ? `, typecheckCmd=\"${options.typecheckCmd}\"` : ''})`\n },\n }\n}\n\nasync function defaultRunPostCheck(\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve, reject) => {\n const child = spawn('sh', ['-c', cmd], { cwd, stdio: 'pipe' })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (c) => {\n stdout += String(c)\n })\n child.stderr?.on('data', (c) => {\n stderr += String(c)\n })\n if (signal) {\n const onAbort = () => {\n if (!child.killed) child.kill('SIGTERM')\n }\n if (signal.aborted) onAbort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n const killTimer = setTimeout(() => {\n if (!child.killed) child.kill('SIGTERM')\n }, DEFAULT_POSTCHECK_TIMEOUT_MS)\n if (typeof (killTimer as { unref?: () => void }).unref === 'function') {\n ;(killTimer as { unref: () => void }).unref()\n }\n child.on('error', (err) => {\n clearTimeout(killTimer)\n reject(err)\n })\n child.on('close', (code) => {\n clearTimeout(killTimer)\n resolve({ exitCode: code ?? -1, stdout, stderr })\n })\n })\n}\n","/**\n * @experimental\n *\n * Helpers extracted from `bin.ts` so the env-detection + executor-selection\n * logic is unit-testable without spawning a subprocess. The bin imports from\n * here; tests import from here directly.\n */\n\nimport type { SandboxClient } from '../runtime'\nimport {\n createFleetWorkspaceExecutor,\n createSiblingSandboxExecutor,\n type DelegationExecutor,\n type FleetHandle,\n} from './executor'\nimport { createInProcessExecutor } from './in-process-executor'\nimport type { LocalHarness } from './local-harness'\n\n/** @experimental */\nexport interface DetectExecutorArgs {\n sandboxClient: SandboxClient\n /** Raw env (defaults to `process.env`). Pass an explicit map for tests. */\n env?: Record<string, string | undefined>\n /**\n * Override how a fleet handle is resolved from the client + fleet id. The\n * default reads `client.fleets.get(fleetId)` and validates the returned\n * shape against the structural `FleetHandle` contract.\n */\n resolveFleet?: (client: SandboxClient, fleetId: string) => Promise<FleetHandle>\n}\n\n/**\n * Pick the right executor for an MCP server invocation based on env vars.\n *\n * - `TANGLE_FLEET_ID` set → fleet-workspace placement; resolves the handle\n * via `sandboxClient.fleets.get(...)`.\n * - Otherwise → sibling-sandbox placement; each delegation creates a fresh\n * sandbox via `sandboxClient.create(...)`.\n *\n * Fails loud (throws) when fleet mode is requested but the SDK shape is\n * incompatible — the operator chose fleet semantics, silently degrading to\n * sibling mode would lie about workspace topology.\n *\n * @experimental\n */\nexport async function detectExecutor(args: DetectExecutorArgs): Promise<DelegationExecutor> {\n const env = args.env ?? process.env\n\n // In-process (Phase 2.8): parent harness sets AGENT_RUNTIME_IN_SANDBOX=1\n // and points us at the workspace root. Highest-priority — when this is\n // set, delegations spawn local harness CLIs on git worktrees in the\n // SAME filesystem instead of provisioning sibling sandboxes.\n if (env.AGENT_RUNTIME_IN_SANDBOX === '1') {\n const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim()\n if (!repoRoot) {\n throw new Error(\n 'agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root',\n )\n }\n return createInProcessExecutor({\n repoRoot,\n harnesses: parseHarnesses(env.AGENT_RUNTIME_LOCAL_HARNESSES),\n testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || undefined,\n typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || undefined,\n })\n }\n\n const fleetId = parseFleetId(env.TANGLE_FLEET_ID)\n if (!fleetId) {\n return createSiblingSandboxExecutor({ client: args.sandboxClient })\n }\n const resolveFleet = args.resolveFleet ?? defaultResolveFleet\n const fleet = await resolveFleet(args.sandboxClient, fleetId)\n const excludeMachineIds = parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES)\n return createFleetWorkspaceExecutor({\n fleet,\n excludeMachineIds,\n })\n}\n\nconst KNOWN_HARNESSES: ReadonlyArray<LocalHarness> = ['claude', 'codex', 'opencode']\n\nfunction parseHarnesses(raw: string | undefined): ReadonlyArray<LocalHarness> | undefined {\n if (!raw) return undefined\n const parts = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n if (parts.length === 0) return undefined\n for (const part of parts) {\n if (!KNOWN_HARNESSES.includes(part as LocalHarness)) {\n throw new Error(\n `agent-runtime-mcp: AGENT_RUNTIME_LOCAL_HARNESSES contains unknown harness \"${part}\". Expected: ${KNOWN_HARNESSES.join(', ')}.`,\n )\n }\n }\n return parts as LocalHarness[]\n}\n\ninterface FleetsApi {\n get(fleetId: string): Promise<unknown>\n}\n\nasync function defaultResolveFleet(\n sandboxClient: SandboxClient,\n fleetId: string,\n): Promise<FleetHandle> {\n const fleets = (sandboxClient as unknown as { fleets?: FleetsApi }).fleets\n if (!fleets || typeof fleets.get !== 'function') {\n throw new Error(\n 'agent-runtime-mcp: the configured sandbox client does not expose `.fleets.get`; upgrade @tangle-network/sandbox to >= 0.2.1 or unset TANGLE_FLEET_ID.',\n )\n }\n const raw = await fleets.get(fleetId)\n if (!raw || typeof raw !== 'object') {\n throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`)\n }\n const handle = raw as Partial<FleetHandle>\n if (typeof handle.fleetId !== 'string' || !Array.isArray(handle.ids)) {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids — incompatible sandbox SDK shape`,\n )\n }\n if (typeof handle.sandbox !== 'function') {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) — incompatible sandbox SDK shape`,\n )\n }\n return handle as FleetHandle\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseList(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n","/**\n * @experimental\n *\n * Sandbox-session coder decode layer. The sandbox-session delegate (`./delegates`) and the\n * cross-restart resume driver run the in-box harness over a `SandboxClient` and need to\n * (a) build an `AgentRunSpec` from the caller-authored (or minimal model-only default) worker\n * profile, (b) decode the harness event stream into a structured `CoderOutput`, and (c) gate it with\n * the shared mechanical checks. This sandbox-session path is kept separate from the generic recursive\n * path: `worktreeFanout` instead settles the raw `WorktreePatchArtifact` and gates via\n * `patchDelivered`. Prefer `worktreeFanout` / `worktreeLoopRunner` for NEW local-repo coding.\n *\n * The decode tolerates two `result`-event shapes:\n * 1. the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks }`),\n * projected onto `CoderOutput`; and\n * 2. an LLM-emitted JSON block (`{ branch, patch, testResult, typecheckResult, diffStats }`),\n * lifted onto `data.result` or scanned out of the assistant transcript (any harness shape).\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { type CoderTask, coderTaskToPrompt } from '../profiles/coder'\nimport { type CoderCheckConstraints, runCoderChecks } from '../runtime/supervise/patch-checks'\nimport type { AgentRunSpec, Driver, OutputAdapter, Validator } from '../runtime/types'\n\nconst DEFAULT_MAX_DIFF_LINES = 400\n\n/**\n * The minimal default worker profile (§1.5: the system authors profiles — there is no hardcoded\n * coder). Model-only by construction: no skills, no tool grants, no standing prompt. Callers that\n * want a richer worker pass their own `AgentProfile` via `CoderRunSpecOptions.profile`. `harness` /\n * `model` / `systemPrompt` are layered onto whichever profile is used.\n */\nfunction minimalCoderProfile(): AgentProfile {\n return { name: 'coder' }\n}\n\n/** @experimental The structured coder result the sandbox-session path decodes + gates. */\nexport interface CoderOutput {\n /** Branch the agent wrote the patch on. */\n branch: string\n /** Unified diff (`git diff <base>..HEAD`). */\n patch: string\n testResult: { passed: boolean; output: string }\n typecheckResult: { passed: boolean; output: string }\n diffStats: { filesChanged: number; insertions: number; deletions: number }\n /** Optional reviewer commentary surfaced by the agent. */\n reviewerNotes?: string\n}\n\n/** @experimental Overrides for one authored coder run on the sandbox-session path. */\nexport interface CoderRunSpecOptions {\n /**\n * The caller-authored worker `AgentProfile` (§1.5). When omitted, a minimal model-only default is\n * used (no hardcoded skills/tools/prompt). `harness` / `model` / `systemPrompt` are layered onto it.\n */\n profile?: AgentProfile\n /** Sandbox-SDK backend.type. Default `'claude-code'`. */\n harness?: string\n /** Default model id passed in `AgentProfile.model.default`. */\n model?: string\n /** Custom system prompt replacement. Default = the supplied profile's own prompt (or none). */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `coder-${harness}`. */\n name?: string\n}\n\n/** Build the authored `AgentProfile` for one harness on the sandbox-session path: the caller's\n * profile (or the minimal model-only default), with the per-run harness/model/prompt overrides. */\nfunction coderRunProfile(options: CoderRunSpecOptions): AgentProfile {\n const harness = options.harness ?? 'claude-code'\n const name = options.name ?? `coder-${harness}`\n const base = options.profile ?? minimalCoderProfile()\n return {\n ...base,\n name,\n ...(options.systemPrompt ? { prompt: { systemPrompt: options.systemPrompt } } : {}),\n model: options.model ? { default: options.model } : base.model,\n metadata: { ...base.metadata, backendType: harness },\n }\n}\n\n/** @experimental Build the `AgentRunSpec<CoderTask>` the sandbox-session `runLoop` path drives. */\nexport function coderRunSpec(options: CoderRunSpecOptions = {}): AgentRunSpec<CoderTask> {\n return {\n name: options.name ?? `coder-${options.harness ?? 'claude-code'}`,\n profile: coderRunProfile(options),\n taskToPrompt: coderTaskToPrompt,\n }\n}\n\n/** @experimental The output adapter the sandbox-session path decodes the harness stream with. */\nexport const coderOutputAdapter: OutputAdapter<CoderOutput> = { parse: parseCoderEvents }\n\n/** @experimental */\nexport interface MultiHarnessCoderFanoutOptions {\n /**\n * The caller-authored worker `AgentProfile` (§1.5), shared across every parallel harness. When\n * omitted, the minimal model-only default is used.\n */\n profile?: AgentProfile\n /**\n * Sandbox-SDK backend.type identifiers, one per parallel agent. Default:\n * `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']`.\n */\n harnesses?: string[]\n /** Optional per-harness model override. Indexed parallel to `harnesses`. */\n models?: (string | undefined)[]\n}\n\n/**\n * The multi-harness coder fanout driving the sandbox-session delegate's `variants>1` path.\n * (`worktreeFanout` is the local-repo generic counterpart for new code.)\n *\n * @experimental\n */\nexport function multiHarnessCoderFanout(options: MultiHarnessCoderFanoutOptions = {}): {\n agentRuns: AgentRunSpec<CoderTask>[]\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'>\n} {\n const harnesses =\n options.harnesses && options.harnesses.length > 0\n ? options.harnesses\n : ['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']\n const models = options.models ?? []\n const agentRuns = harnesses.map((harness, i) =>\n coderRunSpec({\n ...(options.profile ? { profile: options.profile } : {}),\n harness,\n model: models[i],\n }),\n )\n const driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'> = {\n name: 'fanout',\n plan: async (task, history) => (history.length === 0 ? agentRuns.map(() => task) : []),\n decide: (history) => (history.some((i) => i.verdict?.valid === true) ? 'pick-winner' : 'fail'),\n }\n return { agentRuns, output: coderOutputAdapter, validator: defaultCoderValidator(), driver }\n}\n\n/**\n * The sandbox `CoderOutput` validator. A thin shim over the shared {@link runCoderChecks} gate,\n * adapting the parsed `CoderOutput` into the gate inputs.\n *\n * @experimental\n */\nexport function createCoderValidator(task: CoderTask): Validator<CoderOutput> {\n const constraints: CoderCheckConstraints = {\n maxDiffLines: task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES,\n forbiddenPaths: task.forbiddenPaths ?? [],\n }\n return {\n async validate(output) {\n return runCoderChecks(\n {\n patch: output.patch,\n testsPassed: output.testResult.passed,\n typecheckPassed: output.typecheckResult.passed,\n },\n constraints,\n )\n },\n }\n}\n\nfunction defaultCoderValidator(): Validator<CoderOutput> {\n return createCoderValidator({\n goal: '',\n repoRoot: '',\n forbiddenPaths: [],\n maxDiffLines: DEFAULT_MAX_DIFF_LINES,\n })\n}\n\n/**\n * Walk the event stream and return the structured coder payload.\n *\n * A `result` / `final` event lifts the structured payload onto `data.result`. That payload is\n * either the in-process executor's raw worktree-harness result (projected onto `CoderOutput`) or an\n * LLM-emitted `CoderOutput`-shaped JSON. When neither is present, the scan accumulates ALL assistant\n * text in stream order (any harness shape) and takes the last fenced JSON block that coerces —\n * claude-code lifts whole text onto `data.text`/`data.delta`; opencode streams `message.part.updated`\n * fragments, so the final block is split across many events and never whole in one.\n */\nfunction parseCoderEvents(events: SandboxEvent[]): CoderOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'coder.result') {\n const payload = data.result ?? data.output ?? data\n const projected = projectWorktreeArtifact(payload)\n if (projected) return projected\n const direct = coerceCoderOutput(payload)\n if (direct) return direct\n }\n }\n const transcript = collectAssistantText(events)\n for (const candidate of fencedJsonBlocks(transcript)) {\n const coerced = coerceCoderOutput(candidate)\n if (coerced) return coerced\n }\n return {\n branch: '',\n patch: '',\n testResult: { passed: false, output: '' },\n typecheckResult: { passed: false, output: '' },\n diffStats: { filesChanged: 0, insertions: 0, deletions: 0 },\n }\n}\n\n/** Project the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks,\n * harness }`) onto `CoderOutput`. A check that did not run is treated as passing (the executor\n * simply didn't run that command). Returns undefined when the payload is not a worktree artifact. */\nfunction projectWorktreeArtifact(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const stats = value.stats\n if (!isRecord(stats)) return undefined // not the raw artifact shape\n const branch = pickString(value.branch) ?? ''\n const patch = pickString(value.patch) ?? ''\n const checks = isRecord(value.checks) ? value.checks : {}\n const tests = isRecord(checks.tests) ? checks.tests : undefined\n const typecheck = isRecord(checks.typecheck) ? checks.typecheck : undefined\n const harness = isRecord(value.harness) ? value.harness : undefined\n const exitCode = harness ? toFiniteInt(harness.exitCode) : 0\n const timedOut = harness?.timedOut === true\n const harnessName = harness ? (pickString(harness.name) ?? 'harness') : 'harness'\n return {\n branch,\n patch,\n testResult: {\n passed: tests ? tests.passed === true : true,\n output: tail(pickString(tests?.output) ?? '', 4000),\n },\n typecheckResult: {\n passed: typecheck ? typecheck.passed === true : true,\n output: tail(pickString(typecheck?.output) ?? '', 4000),\n },\n diffStats: {\n filesChanged: toFiniteInt(stats.filesChanged),\n insertions: toFiniteInt(stats.insertions),\n deletions: toFiniteInt(stats.deletions),\n },\n ...(exitCode !== 0\n ? {\n reviewerNotes: `harness ${harnessName} exited ${exitCode}${timedOut ? ' (timed out)' : ''}`,\n }\n : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Keep the last `max` chars of a diagnostic string — harness stdout can be large; the gate reads\n * `passed`, not this text, so only the tail is retained for traces/logs. */\nfunction tail(text: string, max: number): string {\n return text.length <= max ? text : text.slice(text.length - max)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n/**\n * Concatenate assistant text across the event stream in arrival order, tolerating every harness\n * shape: claude-code lifts text onto `data.text`/`data.delta`; opencode streams\n * `message.part.updated` with `data.part.type === 'text'` carrying `data.delta`/`data.part.text`.\n * Reasoning/thinking parts are excluded — only the final answer text carries the result JSON.\n */\nfunction collectAssistantText(events: SandboxEvent[]): string {\n const chunks: string[] = []\n for (const event of events) {\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n if (String(event.type ?? '') === 'message.part.updated') {\n const part = isRecord(data.part) ? data.part : {}\n const partType = String(part.type ?? '')\n if (partType !== 'text' && partType !== '') continue\n const text = pickString(data.delta) ?? pickString(part.text)\n if (text) chunks.push(text)\n continue\n }\n const text = pickString(data.text) ?? pickString(data.delta)\n if (text) chunks.push(text)\n }\n return chunks.join('')\n}\n\n/** All parseable fenced JSON blocks in `text`, last-first (the final result block the agent emits\n * is the one we want). */\nfunction fencedJsonBlocks(text: string): unknown[] {\n const out: unknown[] = []\n const matches = [...text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)```/gi)]\n for (let i = matches.length - 1; i >= 0; i -= 1) {\n const body = (matches[i]?.[1] ?? '').trim()\n if (!body) continue\n try {\n out.push(JSON.parse(body))\n } catch {\n // not JSON — keep scanning earlier blocks\n }\n }\n return out\n}\n\nfunction coerceCoderOutput(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const branch = pickString(value.branch)\n const patch = pickString(value.patch) ?? ''\n if (branch === undefined) return undefined\n return {\n branch,\n patch,\n testResult: coerceCmdResult(value.testResult),\n typecheckResult: coerceCmdResult(value.typecheckResult),\n diffStats: coerceDiffStats(value.diffStats),\n reviewerNotes: pickString(value.reviewerNotes),\n }\n}\n\nfunction coerceCmdResult(value: unknown): { passed: boolean; output: string } {\n if (!isRecord(value)) return { passed: false, output: '' }\n return { passed: value.passed === true, output: pickString(value.output) ?? '' }\n}\n\nfunction coerceDiffStats(value: unknown): {\n filesChanged: number\n insertions: number\n deletions: number\n} {\n if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 }\n return {\n filesChanged: toFiniteInt(value.filesChanged),\n insertions: toFiniteInt(value.insertions),\n deletions: toFiniteInt(value.deletions),\n }\n}\n\nfunction toFiniteInt(value: unknown): number {\n if (typeof value !== 'number') return 0\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.trunc(value))\n}\n","/**\n * @experimental\n *\n * Detached delegation turns over the sandbox SDK's `driveTurn` primitive.\n *\n * Two halves of one story:\n *\n * - {@link runDetachedTurn} — the dispatch side. A single-session delegate\n * (single-variant coder / researcher) acquires a box, binds the sandbox id\n * into the record's `detachedSessionRef`, then advances the turn with\n * repeated `driveTurn` ticks instead of holding a live SSE stream. The\n * session id is deterministic and supplied at submit time, so a process\n * crash between ticks loses nothing — the turn keeps running in the box.\n *\n * - {@link createDetachedTurnResumeDriver} — the resume side. A\n * `DelegationResumeDriver` that re-attaches restored in-flight records to\n * their detached runs: parse the record's ref, resolve the box, advance the\n * turn one `driveTurn` pass per `tick()`, and map the SDK's three states\n * (`completed | running | failed`) onto `DelegationResumeTick`.\n *\n * Both sides type the box structurally ({@link DriveTurnCapableBox}) so tests\n * inject fakes and the module never requires the sandbox SDK at runtime — the\n * SDK stays an optional peer, exactly like the executors' `SandboxClient` seam.\n *\n * Tradeoffs of detached mode (why it is opt-in, not the default): a detached\n * turn yields one terminal payload instead of a live event stream, so kernel\n * token/cost aggregation is not produced for that turn. The trace sinks still\n * observe detached work — `runDetachedTurn` synthesizes a single-iteration\n * loop event stream (see `RunDetachedTurnOptions.traceEmitter`) so the span\n * topology joins the inherited trace context, with cost/tokens reported as 0\n * under the `'detached-turn'` driver tag. Multi-variant fanout stays on the\n * streaming `runLoop` path — N concurrent sessions cannot be expressed as one\n * resume key, and winner selection needs every candidate.\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { AgentRunSpec, LoopTraceEmitter, LoopTraceEvent, SandboxClient } from '../runtime'\nimport { createSandboxForSpec } from '../runtime/run-loop'\nimport { deleteBoxSafe, sleep, throwAbort, throwIfAborted } from '../runtime/util'\nimport type { DelegationRecord, DelegationResumeDriver, DelegationResumeTick } from './task-queue'\nimport type { DelegationProgress, DelegationResultPayload } from './types'\n\nconst DEFAULT_TICK_INTERVAL_MS = 5000\n\n/**\n * Structural mirror of the sandbox SDK's `TurnDriveResult` (>= 0.6).\n * Discriminated on `state`; `failed` is terminal and deterministic per the\n * SDK contract — re-invoking with the same ids returns the same outcome.\n *\n * @experimental\n */\nexport type DriveTurnTick =\n | { state: 'completed'; text: string; result: Record<string, unknown> }\n | { state: 'running'; startedAt?: Date; elapsedMs?: number }\n | { state: 'failed'; error: string }\n\n/**\n * The box surface detached turns need. `SandboxInstance`\n * (`@tangle-network/sandbox` >= 0.6) satisfies it structurally; tests pass\n * in-memory fakes. `_sessionCancel` is the SDK's remote-cancellation surface —\n * optional here because older SDKs / fakes may not expose it; when present it\n * is invoked on abort so the remote run actually stops.\n *\n * @experimental\n */\nexport interface DriveTurnCapableBox {\n driveTurn(\n message: string,\n opts: { sessionId: string; turnId?: string; wallCapMs?: number },\n ): Promise<DriveTurnTick>\n _sessionCancel?(id: string): Promise<void>\n}\n\n/**\n * Decoded `DelegationRecord.detachedSessionRef`. `sandboxId` is absent between\n * submit and box acquisition — a record restored in that window is not\n * resumable (there is no box to resume on) and the resume driver fails it\n * loud rather than dispatching onto a guessed box.\n *\n * @experimental\n */\nexport interface DetachedSessionRefParts {\n sessionId: string\n sandboxId?: string\n}\n\n/**\n * Encode ref parts into the JSON-safe string stored on the record:\n * `session=<id>` before the box exists, `sandbox=<id>;session=<id>` once\n * bound. Ids must not contain the `;`/`=` delimiters.\n *\n * @experimental\n */\nexport function formatDetachedSessionRef(parts: DetachedSessionRefParts): string {\n assertRefComponent('sessionId', parts.sessionId)\n if (parts.sandboxId === undefined) return `session=${parts.sessionId}`\n assertRefComponent('sandboxId', parts.sandboxId)\n return `sandbox=${parts.sandboxId};session=${parts.sessionId}`\n}\n\n/** @experimental Inverse of {@link formatDetachedSessionRef}; throws `ValidationError` on malformed input. */\nexport function parseDetachedSessionRef(raw: string): DetachedSessionRefParts {\n const fields = new Map<string, string>()\n for (const pair of raw.split(';')) {\n const eq = pair.indexOf('=')\n const key = eq === -1 ? '' : pair.slice(0, eq)\n const value = eq === -1 ? '' : pair.slice(eq + 1)\n if ((key !== 'session' && key !== 'sandbox') || value.length === 0 || fields.has(key)) {\n throw new ValidationError(\n `parseDetachedSessionRef: malformed detachedSessionRef ${JSON.stringify(raw)} — expected \"session=<id>\" or \"sandbox=<id>;session=<id>\"`,\n )\n }\n fields.set(key, value)\n }\n const sessionId = fields.get('session')\n if (!sessionId) {\n throw new ValidationError(\n `parseDetachedSessionRef: detachedSessionRef ${JSON.stringify(raw)} carries no session id`,\n )\n }\n const sandboxId = fields.get('sandbox')\n return { sessionId, ...(sandboxId !== undefined ? { sandboxId } : {}) }\n}\n\nfunction assertRefComponent(name: string, value: string): void {\n if (value.length === 0 || value.includes(';') || value.includes('=')) {\n throw new ValidationError(\n `formatDetachedSessionRef: ${name} ${JSON.stringify(value)} must be non-empty and free of \";\" / \"=\"`,\n )\n }\n}\n\n/** @experimental The terminal payload of a finished detached turn. */\nexport interface DetachedTurn {\n /** Final assistant text. */\n text: string\n /** The SDK's cached AgentExecutionResult-shape record for the turn. */\n result: Record<string, unknown>\n}\n\n/**\n * Synthesize the terminal event array a detached turn settles through. Shaped\n * so the existing event-stream output adapters (coder, researcher) parse it:\n * `data.result` for adapters that read a structured terminal record, `data.text`\n * for adapters that scan assistant text for the fenced result block.\n *\n * @experimental\n */\nexport function detachedTurnEvents(sessionId: string, turn: DetachedTurn): SandboxEvent[] {\n return [\n {\n type: 'result',\n id: sessionId,\n data: {\n text: turn.text,\n finalText: turn.text,\n success: true,\n result: turn.result,\n },\n } as SandboxEvent,\n ]\n}\n\n/** @experimental */\nexport interface RunDetachedTurnOptions {\n /** Sandbox client used to acquire the box (the delegate's executor client). */\n client: SandboxClient\n /** Profile + overrides for box acquisition — same spec the streaming path uses. */\n spec: AgentRunSpec<unknown>\n /** The full turn prompt; consumed by `driveTurn`'s dispatch leg. */\n prompt: string\n /** Deterministic resume key, minted at submit time (`parseDetachedSessionRef(ref).sessionId`). */\n sessionId: string\n /**\n * Called once the box exists, with its sandbox id. Callers persist\n * `formatDetachedSessionRef({ sandboxId, sessionId })` onto the record here so\n * a restart can resolve the box again.\n */\n bindSandbox(sandboxId: string): void\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** Delay between `running` ticks (ms). Default 5000. */\n tickIntervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` — the SDK cancels and fails a session past it. */\n wallCapMs?: number\n /**\n * Loop-trace sink. When set, the detached turn synthesizes a\n * single-iteration loop span tree (`runId` = `sessionId`, driver\n * `'detached-turn'`) so trace-context inheritance survives the detached\n * path — the same events the streaming `runLoop` path would emit, minus\n * per-token telemetry: `driveTurn` yields one terminal payload, so token\n * and cost figures are structurally unavailable and reported as 0 under\n * this driver tag.\n */\n traceEmitter?: LoopTraceEmitter\n /** Physical placement stamped on the synthesized dispatch event. Default `'sibling'`. */\n placement?: 'sibling' | 'fleet'\n}\n\n/**\n * Dispatch one detached turn and advance it to a terminal state with\n * `driveTurn` ticks. The first tick dispatches (idempotent on `sessionId`);\n * subsequent ticks poll. On abort the remote session is cancelled via\n * `_sessionCancel` when the box exposes it. The box is torn down on every\n * in-process exit path (success, failure, abort) — only a process death skips\n * teardown, which is exactly the case the resume driver re-attaches to.\n *\n * @experimental\n */\nexport async function runDetachedTurn(options: RunDetachedTurnOptions): Promise<DetachedTurn> {\n const intervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS\n const trace = createDetachedTurnTrace(options)\n trace.started()\n const box = await createSandboxForSpec(options.client, options.spec, options.signal).catch(\n (err) => {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n },\n )\n const drive = box as Partial<DriveTurnCapableBox>\n const onAbort = () => {\n void drive._sessionCancel?.(options.sessionId).catch(() => {})\n }\n try {\n if (typeof drive.driveTurn !== 'function') {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox exposes no driveTurn(message, { sessionId }) — ' +\n 'detached dispatch requires @tangle-network/sandbox >= 0.6 and a session-backed ' +\n 'placement (sibling/fleet); disable detached dispatch for this executor.',\n )\n }\n const sandboxId = (box as { id?: unknown }).id\n if (typeof sandboxId !== 'string' || sandboxId.length === 0) {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox carries no id — without it the detached run ' +\n 'cannot be resumed after a restart, so refusing to dispatch detached.',\n )\n }\n options.bindSandbox(sandboxId)\n trace.dispatched(sandboxId)\n options.signal.addEventListener('abort', onAbort, { once: true })\n for (;;) {\n throwIfAborted(options.signal)\n const tick = await drive.driveTurn(options.prompt, {\n sessionId: options.sessionId,\n turnId: options.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n throwIfAborted(options.signal)\n if (tick.state === 'completed') {\n trace.ended()\n return { text: tick.text, result: tick.result }\n }\n if (tick.state === 'failed') {\n throw new Error(`detached turn ${options.sessionId} failed: ${tick.error}`)\n }\n options.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n await sleep(intervalMs, options.signal)\n }\n } catch (err) {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n } finally {\n options.signal.removeEventListener('abort', onAbort)\n if (options.signal.aborted) onAbort()\n await deleteBoxSafe(box)\n }\n}\n\n/**\n * Synthesize the single-iteration loop event stream for one detached turn so\n * the trace sinks (OTEL exporter, delegation journal) observe detached work\n * exactly like a streamed `runLoop` run. `runId` = the deterministic session\n * id; cost/token figures are structurally unavailable on the `driveTurn`\n * surface and emitted as 0 under the `'detached-turn'` driver tag.\n */\nfunction createDetachedTurnTrace(options: RunDetachedTurnOptions): {\n started(): void\n dispatched(sandboxId: string): void\n ended(error?: string): void\n} {\n const emitter = options.traceEmitter\n if (!emitter) {\n return { started() {}, dispatched() {}, ended() {} }\n }\n const runId = options.sessionId\n const agentRunName = options.spec.name ?? options.spec.profile.name ?? 'detached-turn'\n const startMs = Date.now()\n let done = false\n const emit = (event: LoopTraceEvent): void => {\n void emitter.emit(event)\n }\n return {\n started(): void {\n emit({\n kind: 'loop.started',\n runId,\n timestamp: startMs,\n payload: {\n driver: 'detached-turn',\n agentRunNames: [agentRunName],\n maxIterations: 1,\n maxConcurrency: 1,\n },\n })\n emit({\n kind: 'loop.iteration.started',\n runId,\n timestamp: startMs,\n payload: { iterationIndex: 0, agentRunName, taskHash: options.sessionId },\n })\n },\n dispatched(sandboxId: string): void {\n emit({\n kind: 'loop.iteration.dispatch',\n runId,\n timestamp: Date.now(),\n payload: {\n iterationIndex: 0,\n agentRunName,\n placement: options.placement ?? 'sibling',\n sandboxId,\n },\n })\n },\n ended(error?: string): void {\n if (done) return\n done = true\n const endMs = Date.now()\n emit({\n kind: 'loop.iteration.ended',\n runId,\n timestamp: endMs,\n payload: {\n iterationIndex: 0,\n agentRunName,\n costUsd: 0,\n durationMs: endMs - startMs,\n ...(error !== undefined ? { error } : {}),\n },\n })\n emit({\n kind: 'loop.ended',\n runId,\n timestamp: endMs,\n payload: {\n ...(error === undefined ? { winnerIterationIndex: 0 } : {}),\n totalCostUsd: 0,\n durationMs: endMs - startMs,\n iterations: 1,\n },\n })\n },\n }\n}\n\nfunction detachedRunningPhase(elapsedMs: number | undefined): string {\n return elapsedMs === undefined\n ? 'detached-running'\n : `detached-running ${Math.round(elapsedMs / 1000)}s`\n}\n\n/** @experimental */\nexport interface DetachedTurnResumeDriverOptions {\n /**\n * Resolve the live box owning a detached session. The bin wires this to the\n * sandbox client's `get(sandboxId)`; throw when the box no longer exists —\n * a thrown tick settles the record as failed, which is the truth.\n */\n resolveSandbox(sandboxId: string): Promise<DriveTurnCapableBox>\n /**\n * Rebuild the turn prompt from the persisted record. Only consumed by\n * `driveTurn`'s dispatch leg — i.e. when the previous process died after\n * binding the box but before the session was dispatched. Must reproduce the\n * prompt the delegate would have sent.\n */\n buildMessage(record: DelegationRecord): string\n /**\n * Map a completed turn onto the delegation's typed output payload (parse +\n * validate per profile). Throw when the resumed result does not pass the\n * profile's gate — the queue settles the record as failed with that error.\n */\n settleOutput(\n turn: DetachedTurn,\n record: DelegationRecord,\n ctx: { signal: AbortSignal },\n ): Promise<DelegationResultPayload['output']> | DelegationResultPayload['output']\n /** Delay between `running` ticks (ms). Default 5000. */\n intervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` on every tick. */\n wallCapMs?: number\n}\n\n/**\n * Build the `driveTurn`-backed {@link DelegationResumeDriver}. Each `tick()`\n * is one settle/poll/dispatch pass:\n *\n * - ref without a sandbox binding → `failed` (`DetachedSessionUnboundError`):\n * the previous process died before a box existed; there is nothing to resume.\n * - `driveTurn` `completed` → `settleOutput` → `completed` tick.\n * - `running` → progress via `ctx.report`, `running` tick (queue re-ticks\n * after `intervalMs`).\n * - `failed` → `failed` tick (`DetachedTurnFailedError`) — terminal per the\n * SDK's deterministic-failure contract.\n *\n * Abort: the queue stops ticking once `cancel()` flips the record, so remote\n * cancellation is hooked onto `ctx.signal` (once per task) and fires\n * `_sessionCancel` when the SDK surface exposes it. The driver never deletes\n * boxes — it cannot know whether `sandboxId` is a disposable sibling or a\n * fleet machine, and destroying a fleet machine would be unrecoverable.\n *\n * @experimental\n */\nexport function createDetachedTurnResumeDriver(\n options: DetachedTurnResumeDriverOptions,\n): DelegationResumeDriver {\n const cancelHooked = new Set<string>()\n return {\n intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,\n async tick({ record, detachedSessionRef }, ctx): Promise<DelegationResumeTick> {\n const ref = parseDetachedSessionRef(detachedSessionRef)\n if (ref.sandboxId === undefined) {\n return {\n state: 'failed',\n error: {\n message:\n `detached session \"${ref.sessionId}\" was never bound to a sandbox — the previous ` +\n 'process died before the box was acquired, so the turn was never dispatched and ' +\n 'cannot be resumed',\n kind: 'DetachedSessionUnboundError',\n },\n }\n }\n const box = await options.resolveSandbox(ref.sandboxId)\n if (!cancelHooked.has(record.taskId)) {\n cancelHooked.add(record.taskId)\n ctx.signal.addEventListener(\n 'abort',\n () => {\n void box._sessionCancel?.(ref.sessionId).catch(() => {})\n },\n { once: true },\n )\n }\n if (ctx.signal.aborted) throwAbort()\n const tick = await box.driveTurn(options.buildMessage(record), {\n sessionId: ref.sessionId,\n turnId: ref.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n if (tick.state === 'completed') {\n const output = await options.settleOutput(\n { text: tick.text, result: tick.result },\n record,\n {\n signal: ctx.signal,\n },\n )\n return { state: 'completed', output }\n }\n if (tick.state === 'failed') {\n return {\n state: 'failed',\n error: {\n message: `detached turn ${ref.sessionId} failed: ${tick.error}`,\n kind: 'DetachedTurnFailedError',\n },\n }\n }\n ctx.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n return { state: 'running' }\n },\n }\n}\n","/**\n * @experimental\n *\n * `detachedSessionDelegate` — the sandbox-session coder delegate: a closure that drives `runLoop`\n * against a `SandboxClient` + a caller-supplied (or minimal model-only default) worker profile, to a\n * mechanically-validated `CoderOutput`. The caller invokes the returned delegate directly with its\n * coder args; when wired into a durable queue it also settles cross-restart-resumed records.\n *\n * Delegation vs COORDINATION (`../runtime/supervise/coordination-mcp.ts`): this delegate runs a\n * coding task INSIDE the agent's OWN sandbox environment — a sibling box on its own `SandboxClient`,\n * fresh branch on its repo. It is NOT backend-pluggable. To instead SPAWN + live-drive workers in a\n * CHOSEN backend (sandbox OR cli-bridge, via `createExecutor({ backend })`) with observe/steer/resume\n * + recursion, use `delegate()` / the coordination MCP.\n *\n * The worker profile is a parameter the caller supplies (§1.5: the system authors profiles). When\n * none is passed, a minimal model-only default profile is materialized in `./detached-coder` — no\n * hardcoded skills or tools. For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner`\n * (author one `AgentProfile` per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`).\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { CoderTask } from '../profiles/coder'\nimport type {\n AgentRunSpec,\n Iteration,\n LoopTraceEmitter,\n Outcome,\n SandboxClient,\n WinnerStrategy,\n} from '../runtime'\nimport { runLoop, selectValidWinner } from '../runtime'\nimport { composeLoopTraceEmitters } from './delegation-trace'\nimport {\n type CoderOutput,\n coderOutputAdapter,\n coderRunSpec,\n createCoderValidator,\n multiHarnessCoderFanout,\n} from './detached-coder'\nimport {\n type DetachedTurn,\n detachedTurnEvents,\n formatDetachedSessionRef,\n parseDetachedSessionRef,\n runDetachedTurn,\n} from './detached-turn'\nimport { createSiblingSandboxExecutor, type DelegationExecutor } from './executor'\nimport type {\n DelegateCodeArgs,\n DelegateUiAuditArgs,\n DelegationProgress,\n UiAuditorDelegationOutput,\n} from './types'\n\n/** @experimental */\nexport interface DelegateRunCtx {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /**\n * Detached-run resume key recorded on the queue record at submit time\n * (`formatDetachedSessionRef`). Present only when the submit path requested\n * detached dispatch — its presence is what routes a session-backed delegate\n * onto the `driveTurn` tick path instead of holding a stream.\n */\n detachedSessionRef?: string\n /** Rebind the record's resume key (e.g. once the sandbox id is known). */\n updateDetachedSessionRef?(ref: string): void\n /**\n * Per-delegation trace sink supplied by the queue — loop events emitted\n * here land on the delegation record as a compact span tree. Delegates\n * compose it with their configured OTEL emitter so both sinks observe\n * the same stream.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @experimental The coder delegate closure — given the coder args + run context, drives the\n * sandbox-session coder path to a validated `CoderOutput`. `detachedSessionDelegate` is the\n * built-in implementation; the queue invokes one of these per coder delegation. */\nexport type CoderDelegate = (args: DelegateCodeArgs, ctx: DelegateRunCtx) => Promise<CoderOutput>\n\n/**\n * UI-auditor delegate — fully consumer-injected. agent-runtime ships no\n * default factory because the inputs are workspace path + judge function\n * + (optionally) a `SandboxClient`, and the judge is the consumer's\n * model seam. See `createInProcessUiAuditClient` + `uiAuditorProfile` in\n * `@tangle-network/agent-runtime/profiles` for the canonical wiring.\n *\n * @experimental\n */\nexport type UiAuditorDelegate = (\n args: DelegateUiAuditArgs,\n ctx: DelegateRunCtx,\n) => Promise<UiAuditorDelegationOutput>\n\n/** @experimental Structured review verdict over a coder candidate. */\nexport interface CoderReview {\n /** Gate: only approved candidates are eligible to win. */\n approved: boolean\n /** Reviewer's recommendation — surfaced in traces. */\n recommendation: 'ship' | 'approve-with-nits' | 'changes-requested' | 'reject'\n /** Readiness 0..1, used by the `highest-readiness` winner-selection strategy. */\n readiness: number\n notes?: string\n}\n\n/**\n * @experimental\n *\n * Optional adversarial reviewer over a coder candidate that already passed\n * mechanical validation (tests/typecheck/forbidden/diff/no-op/secrets). Folded\n * from the ai-trading-blueprint delegation MCP: a candidate is only eligible to\n * win if the reviewer approves it. The reviewer is the consumer's seam — an LLM\n * judge, a `pnpm review` command, anything returning a `CoderReview`.\n */\nexport type CoderReviewer = (\n output: CoderOutput,\n task: CoderTask,\n ctx: { signal: AbortSignal },\n) => Promise<CoderReview> | CoderReview\n\n/**\n * @experimental Winner-selection strategy among validated (+ reviewed) candidates on the\n * sandbox-session path. The base strategies (`highest-score` / `smallest-diff` /\n * `first-approved`) delegate to the shared `selectValidWinner`; `highest-readiness` is the\n * reviewer-only strategy this path keeps that the generic selector does not express. Default\n * `highest-score`.\n */\nexport type DetachedWinnerSelection =\n | 'highest-score'\n | 'smallest-diff'\n | 'highest-readiness'\n | 'first-approved'\n\n/** @experimental */\nexport interface DetachedSessionDelegateOptions {\n /**\n * Execution placement. Pass a {@link DelegationExecutor} (sibling or fleet)\n * to control where worker iterations land. `sandboxClient` is a\n * convenience shorthand that wraps the client in a sibling executor — pass\n * one or the other, not both.\n */\n executor?: DelegationExecutor\n /**\n * Convenience shorthand for sibling placement. Equivalent to\n * `executor: createSiblingSandboxExecutor({ client: sandboxClient })`.\n */\n sandboxClient?: SandboxClient\n /**\n * The worker's authored `AgentProfile` (§1.5: the system authors profiles). Spread onto the\n * sandbox-session run spec → `runLoop` → the executor's `harnessInvocation`, so the harness runs\n * under the caller's stance. Omit to use a minimal model-only default (no hardcoded skills/tools);\n * `harness` / `model` / `systemPrompt` below are convenience overrides layered onto whichever\n * profile is used.\n */\n workerProfile?: AgentProfile\n /** Backend harness for the single-coder path (sets `metadata.backendType`). Default `claude-code`. */\n harness?: string\n /** Model override for the single-coder path. */\n model?: string\n /**\n * The worker's authored system prompt (§1.5). Flows onto the run spec's\n * `profile.prompt.systemPrompt` → through `runLoop` → the executor's `harnessInvocation`, so the\n * harness runs under this stance. Omit to keep the profile's own prompt.\n */\n systemPrompt?: string\n /** Default `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']` when variants > 1. */\n fanoutHarnesses?: string[]\n /** Optional per-harness model override for `variants > 1`. */\n fanoutModels?: (string | undefined)[]\n /** Hard cap on the kernel's per-batch concurrency. Default 4. */\n maxConcurrency?: number\n /**\n * Optional adversarial reviewer. When set, a candidate must pass mechanical\n * validation AND `reviewer.approved` to be eligible to win — empty/secret/\n * test-failing patches are already gone; this catches the \"compiles + passes\n * but wrong/unsafe\" class the deterministic validator can't see.\n */\n reviewer?: CoderReviewer\n /** Winner-selection strategy among eligible candidates. Default `highest-score`. */\n winnerSelection?: DetachedWinnerSelection\n /**\n * Loop trace emitter forwarded into every delegated `runLoop`. Wire\n * `createPropagatingTraceEmitter(readTraceContextFromEnv())` here (the bin\n * does) so delegated build-loops export their topology spans to the OTLP /\n * Tangle Intelligence sink when `OTEL_EXPORTER_OTLP_ENDPOINT` is set — and\n * are a cheap no-op when it isn't. Configurable by construction.\n *\n * Detached single-variant turns (taken when `ctx.detachedSessionRef` is set)\n * bypass `runLoop`; `runDetachedTurn` synthesizes a single-iteration loop\n * event stream for them so this emitter observes detached work too.\n */\n traceEmitter?: LoopTraceEmitter\n /** Tick cadence (ms) for the detached single-variant path. Default 5000. */\n detachedTickIntervalMs?: number\n /** Wall-clock cap (ms) forwarded to `driveTurn` for detached turns. */\n detachedWallCapMs?: number\n}\n\n/**\n * Build the sandbox-session coder delegate. It drives `runLoop` against the project's\n * sandbox client + coder profile; when `args.variants > 1` it switches to the multi-harness fanout\n * topology.\n *\n * This is the SANDBOX-SESSION coder path: workers run the in-box harness via the\n * `SandboxClient`'s `streamPrompt`, and single-variant turns can dispatch DETACHED\n * (driveTurn ticks) so a durable queue resumes them across an MCP restart — a substrate\n * the recursive worktree-CLI leaf does not yet have a journal-replay equivalent for.\n *\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner` (author an `AgentProfile`\n * per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`). This delegate runs\n * held-stream by default and only its OPTIONAL cross-restart resume (the `driveTurn` tick) is opt-in\n * behind `MCP_ENABLE_DETACHED_RESUME`.\n *\n * @experimental\n */\nexport function detachedSessionDelegate(options: DetachedSessionDelegateOptions): CoderDelegate {\n const executor = resolveExecutor(options)\n const sandboxClient = executor.client\n const fanoutHarnesses = options.fanoutHarnesses\n const maxConcurrency = options.maxConcurrency ?? 4\n const traceEmitter = options.traceEmitter\n return async (args, ctx) => {\n const task = coderTaskFromArgs(args)\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n const loopEmitter = composeLoopTraceEmitters(traceEmitter, ctx.traceEmitter)\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const agentRunSpec = coderRunSpec({\n ...(options.workerProfile ? { profile: options.workerProfile } : {}),\n ...(options.harness ? { harness: options.harness } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...(options.systemPrompt ? { systemPrompt: options.systemPrompt } : {}),\n })\n const output = coderOutputAdapter\n const validator = createCoderValidator(task)\n // Detached dispatch: one session on one box, driven by `driveTurn` ticks\n // instead of a held stream, so the run survives an MCP-process restart\n // (the resume driver re-attaches via the persisted ref). Only the\n // single-variant path detaches — fanout needs N sessions + winner\n // selection over every candidate, which one resume key cannot express.\n if (ctx.detachedSessionRef !== undefined && ctx.updateDetachedSessionRef) {\n const { sessionId } = parseDetachedSessionRef(ctx.detachedSessionRef)\n const rebind = ctx.updateDetachedSessionRef\n const turn = await runDetachedTurn({\n client: sandboxClient,\n spec: agentRunSpec as AgentRunSpec<unknown>,\n prompt: agentRunSpec.taskToPrompt(task),\n sessionId,\n bindSandbox: (sandboxId) => rebind(formatDetachedSessionRef({ sandboxId, sessionId })),\n signal: ctx.signal,\n report: ctx.report,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n ...(executor.placement === 'fleet' ? { placement: 'fleet' as const } : {}),\n ...(options.detachedTickIntervalMs !== undefined\n ? { tickIntervalMs: options.detachedTickIntervalMs }\n : {}),\n ...(options.detachedWallCapMs !== undefined\n ? { wallCapMs: options.detachedWallCapMs }\n : {}),\n })\n const chosen = await settleDetachedCoderTurn(turn, {\n task,\n sessionId,\n signal: ctx.signal,\n ...(options.harness ? { harness: options.harness } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n })\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const result = await runLoop({\n driver: singleShotDriver,\n agentRun: agentRunSpec,\n output,\n validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: 1,\n maxConcurrency,\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const fanout = multiHarnessCoderFanout({\n ...(options.workerProfile ? { profile: options.workerProfile } : {}),\n ...(fanoutHarnesses && fanoutHarnesses.length > 0\n ? { harnesses: fanoutHarnesses.slice(0, variants) }\n : {}),\n ...(options.fanoutModels ? { models: options.fanoutModels.slice(0, variants) } : {}),\n })\n const agentRuns = fanout.agentRuns.slice(0, variants)\n const result = await runLoop({\n driver: fanout.driver,\n agentRuns,\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: agentRuns.length, phase: 'completed' })\n return chosen\n }\n}\n\ninterface PickCoderWinnerArgs {\n iterations: ReadonlyArray<Iteration<CoderTask, CoderOutput>>\n reviewer: CoderReviewer | undefined\n selection: DetachedWinnerSelection\n task: CoderTask\n signal: AbortSignal\n}\n\n/** A valid (and, when a reviewer is wired, approved) candidate kept for selection. */\ninterface EligibleCandidate {\n iter: Iteration<CoderTask, CoderOutput>\n /** Reviewer readiness (defaults to the verdict score when no reviewer ran). */\n readiness: number\n}\n\n/**\n * Pick the winning coder candidate from a finished loop's iterations:\n * 1. keep only mechanically-VALID candidates (the validator already gated\n * tests/typecheck/forbidden/diff/no-op/secrets),\n * 2. if a `reviewer` is wired, keep only those it APPROVES,\n * 3. select among survivors via the shared `selectValidWinner` (base strategies) or, for the\n * reviewer-only `highest-readiness`, a readiness sort (the one strategy the generic selector\n * does not express — a documented capability of this sandbox-session path).\n * Returns `undefined` when nothing survives — the delegate fails loud.\n */\nasync function pickCoderWinner(args: PickCoderWinnerArgs): Promise<CoderOutput | undefined> {\n const eligible: EligibleCandidate[] = []\n for (const iter of args.iterations) {\n if (iter.output === undefined || iter.error || iter.verdict?.valid !== true) continue\n const readiness = iter.verdict.score ?? 0\n if (args.reviewer) {\n const review = await args.reviewer(iter.output, args.task, { signal: args.signal })\n if (!review.approved) continue\n eligible.push({ iter, readiness: review.readiness })\n } else {\n eligible.push({ iter, readiness })\n }\n }\n if (eligible.length === 0) return undefined\n\n // `highest-readiness` ranks on the reviewer's readiness — a reviewer-only metric the generic\n // valid-only selector does not carry. Ties → earliest iteration.\n if (args.selection === 'highest-readiness') {\n const sorted = [...eligible].sort(\n (a, b) => b.readiness - a.readiness || a.iter.index - b.iter.index,\n )\n return sorted[0]!.iter.output\n }\n\n // Base strategies route through the SHARED valid-only selector. Wrap each survivor's raw\n // `CoderOutput` in the `Outcome<D>` shape `selectValidWinner` reads, preserving verdict/index.\n const wrapped: Iteration<unknown, Outcome<CoderOutput>>[] = eligible.map(({ iter }) => ({\n ...iter,\n output: { kind: 'done', deliverable: iter.output as CoderOutput },\n }))\n const winner = selectValidWinner<CoderOutput>({\n strategy: baseStrategy(args.selection),\n sizeOf: (o) => o.diffStats.insertions + o.diffStats.deletions,\n })(wrapped)\n const out = winner?.output\n if (!out || out.kind !== 'done') return undefined\n return out.deliverable\n}\n\n/** Map the detached-session selection enum onto the shared `WinnerStrategy`. `first-approved`\n * reduces to `first-valid` over the already-approved set; `smallest-diff` to `smallest-artifact`. */\nfunction baseStrategy(\n selection: Exclude<DetachedWinnerSelection, 'highest-readiness'>,\n): WinnerStrategy {\n switch (selection) {\n case 'smallest-diff':\n return 'smallest-artifact'\n case 'first-approved':\n return 'first-valid'\n default:\n return 'highest-score'\n }\n}\n\nfunction noWinnerMessage(reviewer: CoderReviewer | undefined): string {\n return reviewer\n ? 'coder delegate: no candidate passed validation + review'\n : 'coder delegate: no candidate passed validation'\n}\n\n/**\n * Canonical `DelegateCodeArgs` → `CoderTask` mapping — the single source for\n * the delegate's live dispatch AND the resume driver's settle/message\n * rebuilding, so a resumed record reproduces exactly the task the original\n * process dispatched.\n *\n * @experimental\n */\nexport function coderTaskFromArgs(args: DelegateCodeArgs): CoderTask {\n return {\n goal: buildCoderGoal(args),\n repoRoot: args.repoRoot,\n testCmd: args.config?.testCmd,\n typecheckCmd: args.config?.typecheckCmd,\n forbiddenPaths: args.config?.forbiddenPaths,\n maxDiffLines: args.config?.maxDiffLines,\n }\n}\n\n/** @experimental */\nexport interface SettleDetachedCoderTurnOptions {\n task: CoderTask\n /** Session id of the detached turn — used as the synthesized event id. */\n sessionId: string\n signal: AbortSignal\n harness?: string\n model?: string\n /** Same gate as the streaming path: an unapproved candidate cannot win. */\n reviewer?: CoderReviewer\n}\n\n/**\n * Settle a completed detached coder turn through the same gate the streaming\n * path applies: parse the terminal payload with the coder output adapter,\n * run the mechanical validator (tests/typecheck/forbidden/diff/no-op/secrets),\n * then the optional reviewer. Throws when nothing survives — a resumed or\n * detached run must not return an unvalidated patch.\n *\n * SCOPE NOTE (detached/resume): the detached `driveTurn`-tick + cross-restart resume path is\n * bound to the `runLoop` + sandbox-session substrate. The recursive `Scope`/worktree-CLI leaf has\n * journal→replay but no driveTurn-over-a-detached-sandbox-session equivalent yet, so resume is NOT\n * advertised on the generic `worktreeFanout` path. This helper (with `coderTaskFromArgs` and\n * `createDetachedTurnResumeDriver`) stays as the resume seam `bin.ts` wires for in-flight records.\n *\n * @experimental\n */\nexport async function settleDetachedCoderTurn(\n turn: DetachedTurn,\n options: SettleDetachedCoderTurnOptions,\n): Promise<CoderOutput> {\n const parsed = coderOutputAdapter.parse(detachedTurnEvents(options.sessionId, turn))\n const validator = createCoderValidator(options.task)\n const verdict = await validator.validate(parsed, { iteration: 0, signal: options.signal })\n if (verdict.valid !== true) throw new Error(noWinnerMessage(options.reviewer))\n if (options.reviewer) {\n const review = await options.reviewer(parsed, options.task, { signal: options.signal })\n if (!review.approved) throw new Error(noWinnerMessage(options.reviewer))\n }\n return parsed\n}\n\nfunction buildCoderGoal(args: DelegateCodeArgs): string {\n if (!args.contextHint) return args.goal\n return [args.goal, '', '## Context', args.contextHint].join('\\n')\n}\n\nfunction resolveExecutor(options: DetachedSessionDelegateOptions): DelegationExecutor {\n if (options.executor && options.sandboxClient) {\n throw new Error('detachedSessionDelegate: pass exactly one of `executor` or `sandboxClient`')\n }\n if (options.executor) return options.executor\n if (options.sandboxClient) {\n return createSiblingSandboxExecutor({ client: options.sandboxClient })\n }\n throw new Error('detachedSessionDelegate: `executor` or `sandboxClient` is required')\n}\n\n/**\n * Single-shot driver — plan one task on iteration 0, stop after one\n * iteration. Used by the coder delegate when `variants <= 1`. Keeps the\n * runLoop kernel-level accounting (timing, cost, trace emission) while\n * skipping fanout/refine topology overhead.\n */\nconst singleShotDriver = {\n name: 'mcp-single-shot',\n async plan<Task>(task: Task, history: ReadonlyArray<unknown>): Promise<Task[]> {\n return history.length === 0 ? [task] : []\n },\n decide(history: ReadonlyArray<unknown>): 'pick-winner' | 'fail' {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n}\n","/**\n * @experimental\n *\n * The trace-analyst KIND directory — the operator's lenses, as composable DATA.\n *\n * An analyst is not one question. A kind is ONE lens (completeness, correctness, policy, efficiency,\n * tool-use, …); each emits `AnalystFinding`s tagged by its `area`. The driver `list_analysts` to see\n * the menu, `run_analyst(kind, worker)` to apply a lens, and `define_analyst` to author a new one —\n * so at test time you compose the exact lenses a domain needs (maximum specificity), not one generic\n * reviewer. The kinds are data, the runner is generic, and the finding shape + firewall are reused\n * from agent-eval / the keystone — never re-derived.\n *\n * A kind here is a lightweight lens (`Check`); it is a deliberate SUBSET of agent-eval's full\n * `TraceAnalystKindSpec`, so a kind that needs the heavy agentic actor (sub-agent recursion, tools,\n * goldens) upgrades to `createTraceAnalystKind` without changing this directory's surface.\n */\n\nimport {\n type AnalystFinding,\n type AnalystSeverity,\n type EvidenceRef,\n makeFinding,\n} from '@tangle-network/agent-eval'\nimport { assertTraceDerivedFindings } from '../../runtime'\n\n// agent-eval's root entry exports the lift (`makeFinding`) + the `AnalystFinding`/`EvidenceRef` shapes\n// but NOT the raw-row validator / schema prompt (kind-factory-internal). We inline a minimal,\n// equivalent pair so a lens emits the SAME finding shape without reaching into an unstable internal.\nconst ANALYST_SEVERITIES = ['critical', 'high', 'medium', 'low', 'info'] as const\n\nconst FINDING_SCHEMA_PROMPT = [\n 'Each finding is a JSON object with these fields:',\n '- severity: one of \"critical\" | \"high\" | \"medium\" | \"low\" | \"info\"',\n '- claim: one-sentence statement',\n '- evidence_uri: REQUIRED, never blank — exactly one of \"span://<trace>/<span>\", \"artifact://<path>\",',\n ' or \"metric://<name>\"; ALWAYS cite a real id from the trace. No citable id ⇒ omit the finding.',\n '- evidence_excerpt?: a short quote from the cited evidence',\n '- confidence: number 0..1',\n '- rationale?: one sentence of reasoning',\n '- recommended_action?: a concrete imperative (\"Add ...\", \"Replace ...\", \"Stop ...\")',\n 'Emit an empty array when there is nothing to report. Never fabricate evidence.',\n].join('\\n')\n\ninterface RawRow {\n severity: AnalystSeverity\n claim: string\n evidence_uri: string\n confidence: number\n evidence_excerpt?: string\n rationale?: string\n recommended_action?: string\n subject?: string\n}\n\n/** Validate one raw finding row (the lightweight equivalent of agent-eval's `parseRawFinding`):\n * require a claim + a real trace evidence_uri; drop anything else. Returns null to discard. */\nfunction validateRawFinding(row: unknown): RawRow | null {\n if (!row || typeof row !== 'object') return null\n const r = row as Record<string, unknown>\n if (typeof r.claim !== 'string' || r.claim.length === 0) return null\n if (typeof r.evidence_uri !== 'string' || !/^(span|artifact|metric):\\/\\//.test(r.evidence_uri))\n return null\n const sev = (ANALYST_SEVERITIES as readonly string[]).includes(r.severity as string)\n ? (r.severity as AnalystSeverity)\n : 'medium'\n return {\n severity: sev,\n claim: r.claim,\n evidence_uri: r.evidence_uri,\n confidence: typeof r.confidence === 'number' ? r.confidence : 0.5,\n ...(typeof r.evidence_excerpt === 'string' ? { evidence_excerpt: r.evidence_excerpt } : {}),\n ...(typeof r.rationale === 'string' ? { rationale: r.rationale } : {}),\n ...(typeof r.recommended_action === 'string'\n ? { recommended_action: r.recommended_action }\n : {}),\n ...(typeof r.subject === 'string' ? { subject: r.subject } : {}),\n }\n}\n\n/** One lens — a composable analyst kind. Identity fields mirror `TraceAnalystKindSpec` so a kind is\n * upgradeable to the full agentic factory; `lookFor` is the lens question the actor applies. */\nexport interface Check {\n readonly id: string\n readonly description: string\n /** Coarse classification stamped on every finding this kind emits (the renderer groups by it). */\n readonly area: string\n readonly version: string\n /** The lens — what this analyst looks for in the trace. */\n readonly lookFor: string\n}\n\n/** The built-in lens directory. Domain-blind (about any agent trace); compose at test time. */\nexport const defaultChecks: Record<string, Check> = {\n completeness: {\n id: 'completeness',\n description: 'Required work the trace does not yet show done or verified.',\n area: 'failure-mode',\n version: '1',\n lookFor:\n 'every change the task requires that the trace does NOT yet show completed AND verified by a ' +\n 'tool result. One finding per missing/unverified requirement.',\n },\n correctness: {\n id: 'correctness',\n description: 'Tool calls that produced wrong, erroring, or contradicted results.',\n area: 'correctness',\n version: '1',\n lookFor:\n 'tool calls whose RESULT shows an error, a wrong value, or contradicts what the task required ' +\n '(e.g. set the wrong field, value did not take, an error was ignored).',\n },\n policy: {\n id: 'policy',\n description: 'Actions that violate a stated policy, constraint, or allow-list.',\n area: 'safety',\n version: '1',\n lookFor:\n 'actions in the trace that violate a policy/constraint stated in the task or system prompt ' +\n '(forbidden tool, missing approval, out-of-scope mutation, skipped precondition).',\n },\n efficiency: {\n id: 'efficiency',\n description: 'Wasted, redundant, or looping work.',\n area: 'cost',\n version: '1',\n lookFor:\n 'redundant or wasted actions — repeated identical calls, a stalled line retried the same way, ' +\n 'work that produced no progress toward the goal.',\n },\n 'tool-use': {\n id: 'tool-use',\n description: 'Malformed or misused tool calls.',\n area: 'tool-use',\n version: '1',\n lookFor:\n 'tool calls with malformed/invalid arguments, the wrong tool for the intent, or a tool used ' +\n 'against its contract — judged from the call + its result.',\n },\n}\n\n/** Lift validated raw rows into `AnalystFinding`s (agent-eval `makeFinding` stamps `finding_id`/\n * `produced_at`), then enforce the trace-derived firewall (selector ≠ judge). Pure — no LLM. */\nexport function liftFindings(kind: Check, rows: unknown[], producedAt: string): AnalystFinding[] {\n const findings: AnalystFinding[] = []\n for (const row of rows) {\n const raw = validateRawFinding(row)\n if (!raw) continue\n findings.push(\n makeFinding({\n analyst_id: kind.id,\n area: kind.area,\n severity: raw.severity,\n claim: raw.claim,\n confidence: raw.confidence,\n produced_at: producedAt,\n evidence_refs: evidenceRefs(raw.evidence_uri, raw.evidence_excerpt),\n ...(raw.rationale ? { rationale: raw.rationale } : {}),\n ...(raw.recommended_action ? { recommended_action: raw.recommended_action } : {}),\n ...(raw.subject ? { subject: raw.subject } : {}),\n metadata: { kind_version: kind.version },\n }),\n )\n }\n assertTraceDerivedFindings(findings) // throws if a finding cites judge/verdict/score evidence\n return findings\n}\n\n/** Map a raw `evidence_uri` (span:// | artifact:// | metric://<name>) to a typed `EvidenceRef`. A\n * metric ref carries the bare NAME (the firewall checks the metric name for judge/verdict/score —\n * so a finding that cites a judge metric is rejected as not trace-derived). */\nfunction evidenceRefs(uri: string, excerpt?: string): EvidenceRef[] {\n const scheme = uri.split('://', 1)[0]\n if (scheme === 'metric')\n return [\n { kind: 'metric', uri: uri.replace(/^metric:\\/\\//, ''), ...(excerpt ? { excerpt } : {}) },\n ]\n const kind: EvidenceRef['kind'] = scheme === 'span' ? 'span' : 'artifact'\n return [{ kind, uri, ...(excerpt ? { excerpt } : {}) }]\n}\n\n/** Render a worker's trace (tool calls + results) into the text an analyst lens reads. Generic over\n * the trace shape: a `{ messages }` conversation, a bare message array, else stringified. */\nexport function renderTrace(trace: unknown): string {\n const messages = Array.isArray(trace)\n ? trace\n : trace &&\n typeof trace === 'object' &&\n Array.isArray((trace as { messages?: unknown[] }).messages)\n ? (trace as { messages: unknown[] }).messages\n : undefined\n if (!messages) return JSON.stringify(trace ?? {}).slice(0, 8000)\n return messages\n .map((m) => {\n const r = m as {\n role?: string\n content?: unknown\n tool_calls?: Array<{ function?: { name?: string; arguments?: string } }>\n }\n if (r.role === 'tool') return `RESULT ${String(r.content).slice(0, 300)}`\n const calls = r.tool_calls\n ?.map((c) => `${c.function?.name}(${c.function?.arguments})`)\n .join(', ')\n return calls ? `CALL ${calls}` : `SAY ${String(r.content ?? '').slice(0, 200)}`\n })\n .join('\\n')\n .slice(0, 8000)\n}\n\nexport interface CheckRunnerOptions {\n routerBaseUrl: string\n routerKey: string\n model: string\n /** Test/override seam — replace the LLM call. Default: a router chat completion. */\n chat?: (system: string, user: string) => Promise<string>\n}\n\n/** Run ONE lens over a trace → findings. Generic over any kind: prompt = the lens + the agent-eval\n * finding schema; the model's JSON array is parsed (`parseRawFinding`), lifted, and firewalled. */\nexport async function runCheck(\n kind: Check,\n trace: unknown,\n opts: CheckRunnerOptions,\n producedAt: string,\n): Promise<AnalystFinding[]> {\n const sys =\n `You are a trace analyst applying ONE lens: look for ${kind.lookFor}\\n\\n` +\n `${FINDING_SCHEMA_PROMPT}\\n\\nReturn ONLY a fenced \\`\\`\\`json array of finding objects (possibly empty).`\n const user = `WORKER TRACE:\\n${renderTrace(trace)}\\n\\nApply your lens and emit the findings array.`\n const chat = opts.chat ?? defaultChat(opts)\n const content = await chat(sys, user)\n const match = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n let rows: unknown[] = []\n try {\n const parsed = JSON.parse((match?.[1] ?? content).trim())\n rows = Array.isArray(parsed)\n ? parsed\n : Array.isArray((parsed as { findings?: unknown[] })?.findings)\n ? (parsed as { findings: unknown[] }).findings\n : []\n } catch {\n rows = []\n }\n return liftFindings(kind, rows, producedAt)\n}\n\nfunction defaultChat(opts: CheckRunnerOptions): (system: string, user: string) => Promise<string> {\n return async (system, user) => {\n const res = await fetch(`${opts.routerBaseUrl.replace(/\\/$/, '')}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${opts.routerKey}` },\n body: JSON.stringify({\n model: opts.model,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n temperature: 0.3,\n }),\n })\n if (!res.ok) throw new Error(`analyst router ${res.status}`)\n const data = (await res.json()) as { choices?: Array<{ message?: { content?: string } }> }\n return data.choices?.[0]?.message?.content ?? ''\n }\n}\n\n/**\n * Build a `run_analyst` runner over a kind directory.\n * Returns findings, or a typed error for an unknown kind. `producedAt` is\n * passed in because replay-safe paths must not read `Date.now`.\n */\nexport function makeCheckRunner(\n kinds: Record<string, Check>,\n opts: CheckRunnerOptions,\n): (\n kindId: string,\n trace: unknown,\n producedAt: string,\n) => Promise<AnalystFinding[] | { error: string }> {\n return async (kindId, trace, producedAt) => {\n const kind = kinds[kindId]\n if (!kind)\n return {\n error: `unknown analyst kind ${JSON.stringify(kindId)} (have: ${Object.keys(kinds).join(', ')})`,\n }\n return runCheck(kind, trace, opts, producedAt)\n }\n}\n"],"mappings":"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","names":["text","chosen","result"]}
1
+ {"version":3,"sources":["../../src/mcp/executor.ts","../../src/mcp/in-process-executor.ts","../../src/mcp/bin-helpers.ts","../../src/mcp/detached-coder.ts","../../src/mcp/detached-turn.ts","../../src/mcp/delegates.ts","../../src/mcp/tools/checks.ts"],"sourcesContent":["/**\n *\n * Delegation executors — the layer between MCP delegates and the sandbox\n * substrate. Each executor exposes a {@link SandboxClient} the kernel\n * consumes plus a placement tag so the trace pipeline can correlate workers\n * with their physical placement.\n *\n * Two implementations ship in-box:\n *\n * - {@link createSiblingSandboxExecutor} — every delegation spawns a fresh\n * sandbox sibling to the caller. Default when the MCP server runs as a\n * standalone CLI mounted outside a fleet.\n *\n * - {@link createFleetWorkspaceExecutor} — delegations dispatch onto machines\n * in the caller's existing fleet so worker diffs land directly on the\n * caller's filesystem (the fleet's shared workspace). Selected when the\n * parent sandbox passes `TANGLE_FLEET_ID` into the MCP server's env.\n *\n * @experimental\n */\n\nimport type { CreateSandboxOptions, SandboxInstance } from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\n\n/** @experimental */\nexport interface DelegationExecutor {\n /** Sandbox client the kernel calls. Returned with `describePlacement` set. */\n readonly client: SandboxClient\n /** Best-effort one-liner used in stderr boot logs and diagnostics. */\n describe(): string\n /**\n * Where delegated work physically runs. `sibling` and `fleet` placements are\n * session-backed (boxes expose `driveTurn`, so detached dispatch + resume\n * apply); `in-process` spawns local harness CLIs with no sandbox session to\n * detach. Optional so consumer-implemented executors stay source-compatible;\n * absent means \"unknown\" and detached dispatch is not enabled for it.\n */\n readonly placement?: 'sibling' | 'fleet' | 'in-process'\n}\n\n/** @experimental */\nexport interface SiblingSandboxExecutorOptions {\n client: SandboxClient\n}\n\n/**\n * Wrap a raw sandbox SDK client so the kernel emits\n * `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.\n *\n * The returned client `.create()` delegates to the underlying client; the\n * only added behavior is a `describePlacement` tag the kernel reads.\n *\n * @experimental\n */\nexport function createSiblingSandboxExecutor(\n options: SiblingSandboxExecutorOptions,\n): DelegationExecutor {\n const underlying = options.client\n const client: SandboxClient = {\n create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n return underlying.create(opts)\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n return { kind: 'sibling', sandboxId: readId(box) }\n },\n }\n return {\n client,\n placement: 'sibling',\n describe(): string {\n return 'sibling-sandbox (each delegation = fresh sandbox via client.create)'\n },\n }\n}\n\n/**\n * Minimal `SandboxFleet` surface the fleet executor calls. Declared\n * structurally so tests can pass an in-memory stub without instantiating the\n * sandbox SDK.\n *\n * @experimental\n */\nexport interface FleetHandle {\n readonly fleetId: string\n /** Machine ids in dispatch-eligible order. The executor round-robins. */\n readonly ids: ReadonlyArray<string>\n /** Resolve a machine id to its `SandboxInstance` — that machine is mounted\n * on the fleet's shared workspace, so any diff the worker writes lands on\n * every other fleet machine's filesystem too. */\n sandbox(machineId: string): Promise<SandboxInstance>\n}\n\n/** @experimental */\nexport interface FleetWorkspaceExecutorOptions {\n fleet: FleetHandle\n /**\n * Override the machine-selection policy. Default = round-robin across\n * `fleet.ids`, skipping the optional `excludeMachineIds` set (typically the\n * coordinator machine the MCP server is running on).\n */\n selectMachine?: (call: { callIndex: number; ids: ReadonlyArray<string> }) => string\n /**\n * Machine ids to skip during default round-robin. Set to the caller's own\n * machineId so workers don't compete with the orchestrator on the same VM.\n */\n excludeMachineIds?: ReadonlyArray<string>\n}\n\n/**\n * Build an executor that resolves each delegated iteration to an existing\n * machine in `fleet`. The fleet's shared-workspace policy means the worker\n * machine sees the caller's filesystem — diffs land in-place with no\n * cross-sandbox copy step.\n *\n * @experimental\n */\nexport function createFleetWorkspaceExecutor(\n options: FleetWorkspaceExecutorOptions,\n): DelegationExecutor {\n const fleet = options.fleet\n const exclude = new Set(options.excludeMachineIds ?? [])\n let callIndex = 0\n // machineId-by-sandboxId, populated as we resolve machines so\n // `describePlacement` can recover the assignment from the SandboxInstance\n // the kernel hands back.\n const placementBySandboxId = new Map<string, { machineId: string }>()\n\n const client: SandboxClient = {\n async create(): Promise<SandboxInstance> {\n const ids = fleet.ids.filter((id) => !exclude.has(id))\n if (ids.length === 0) {\n throw new Error(\n `agent-runtime: fleet ${fleet.fleetId} has no eligible worker machines (ids=[${fleet.ids.join(',')}], excluded=[${[...exclude].join(',')}])`,\n )\n }\n const selector = options.selectMachine\n const machineId = selector ? selector({ callIndex, ids }) : ids[callIndex % ids.length]\n callIndex += 1\n if (typeof machineId !== 'string' || machineId.length === 0) {\n throw new Error('agent-runtime: fleet executor selectMachine returned an empty machine id')\n }\n const box = await fleet.sandbox(machineId)\n const sandboxId = readId(box)\n if (sandboxId) placementBySandboxId.set(sandboxId, { machineId })\n return box\n },\n describePlacement(box: SandboxInstance): LoopSandboxPlacement {\n const sandboxId = readId(box)\n const recorded = sandboxId ? placementBySandboxId.get(sandboxId) : undefined\n return {\n kind: 'fleet',\n sandboxId,\n fleetId: fleet.fleetId,\n machineId: recorded?.machineId,\n }\n },\n }\n\n return {\n client,\n placement: 'fleet',\n describe(): string {\n const excluded = exclude.size > 0 ? ` (excluded=[${[...exclude].join(',')}])` : ''\n return `fleet-workspace (fleetId=${fleet.fleetId}, machines=[${fleet.ids.join(',')}]${excluded})`\n },\n }\n}\n\nfunction readId(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 * In-process delegation executor — when `agent-runtime-mcp` runs inside a sandbox whose image\n * carries the local coding-harness CLIs (claude / codex / opencode), delegations spawn the harness\n * AS A SUBPROCESS against a git worktree on the SAME filesystem instead of provisioning a sibling\n * sandbox. Zero provisioning latency; worker diffs land in-place; multi-harness fanout = N parallel\n * subprocesses in N parallel worktrees (round-robin `harnesses`).\n *\n * This is a THIN adapter over `runWorktreeHarness` (`./worktree-harness`) — the SAME core the\n * `Scope` leaf `createWorktreeCliExecutor` uses. It only adapts the core to the `SandboxClient`\n * port: `create()` reads the authored profile from `CreateSandboxOptions.backend.profile`, and\n * `streamPrompt` runs the core then emits its raw `WorktreeHarnessResult` (the content-addressed\n * patch artifact) on the `result` event. The sandbox-session decode layer\n * (`./detached-coder`) projects that artifact onto `CoderOutput`; the generic `Scope` path settles\n * the artifact directly. The §1.5 payload (systemPrompt + model) reaches the harness inside the core.\n *\n * @experimental\n */\n\nimport { randomUUID } from 'node:crypto'\nimport type {\n AgentProfile,\n CreateSandboxOptions,\n SandboxEvent,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport type { LoopSandboxPlacement, SandboxClient } from '../runtime'\nimport type { DelegationExecutor } from './executor'\nimport type { LocalHarness } from './local-harness'\nimport type { GitRunner, WorktreeHandle } from './worktree'\nimport { runWorktreeHarness } from './worktree-harness'\n\n/** @experimental */\nexport interface InProcessExecutorOptions {\n /** Absolute path to the git repo (the workspace). Worktrees go under `<repoRoot>/.agent-worktrees/`. */\n repoRoot: string\n /** Harnesses to round-robin across `create()` calls. One entry = no fanout. Default `['claude']`. */\n harnesses?: ReadonlyArray<LocalHarness>\n /** Optional per-delegation test command run in the worktree after the harness exits. */\n testCmd?: string\n /** Optional per-delegation typecheck command. Same shape as `testCmd`. */\n typecheckCmd?: string\n /** Wall-clock cap per harness subprocess (ms). Default 5min. */\n harnessTimeoutMs?: number\n /** Wall-clock cap per test/typecheck subprocess (ms). Default 2min. */\n postCheckTimeoutMs?: number\n /** Test seam — override the git runner used by the worktree helpers. */\n runGit?: GitRunner\n /** Test seam — override the harness runner (defaults to the real CLI via `runLocalHarness`). */\n runHarness?: typeof import('./local-harness').runLocalHarness\n /** Test seam — override the post-check runner (defaults to a `sh -c` spawn). A throw is folded\n * into a non-fatal `{exitCode:-1}` so a broken check command fails the signal, not the run. */\n runPostCheck?: (\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n ) => Promise<{ exitCode: number; stdout: string; stderr: string }>\n}\n\n/** @experimental */\nexport interface InProcessExecutorDescribePlacement extends LoopSandboxPlacement {\n /** Worktree path in the parent sandbox's filesystem (set so traces correlate to on-disk artifacts). */\n worktreePath?: string\n /** Which harness handled this delegation. */\n harness?: LocalHarness\n}\n\ninterface VirtualSandbox extends SandboxInstance {\n __inProcess: {\n runId: string\n harness: LocalHarness\n worktree?: WorktreeHandle\n }\n}\n\nconst DEFAULT_HARNESS_TIMEOUT_MS = 5 * 60 * 1000\nconst DEFAULT_POSTCHECK_TIMEOUT_MS = 2 * 60 * 1000\n\n/**\n * Build an in-process executor. Returns a {@link DelegationExecutor} whose `client.create()`\n * returns a minimal virtual `SandboxInstance`; the kernel calls `streamPrompt(msg)` on it, which\n * runs the shared worktree-harness core and emits one `result` event whose `data.result` is the\n * raw `WorktreeHarnessResult` (the content-addressed patch artifact). The authored profile\n * (`backend.profile`) threads its systemPrompt + model into the harness via the core.\n *\n * @experimental\n */\nexport function createInProcessExecutor(options: InProcessExecutorOptions): DelegationExecutor {\n const harnesses =\n options.harnesses && options.harnesses.length > 0\n ? [...options.harnesses]\n : (['claude'] as const)\n const runPostCheck = options.runPostCheck ?? defaultRunPostCheck\n // The core speaks one `runCommand` seam ({exitCode, output}); adapt the post-check seam\n // ({exitCode, stdout, stderr}) onto it, folding a throw into a non-fatal failure signal so a\n // broken check command fails the signal rather than aborting the whole delegation.\n const runCommand = async ({\n command,\n cwd,\n signal,\n }: {\n command: string\n cwd: string\n timeoutMs: number\n signal?: AbortSignal\n }): Promise<{ exitCode: number | null; output: string }> => {\n try {\n const r = await runPostCheck(command, cwd, signal)\n return { exitCode: r.exitCode, output: r.stderr || r.stdout }\n } catch (err) {\n return { exitCode: -1, output: err instanceof Error ? err.message : String(err) }\n }\n }\n\n let callIndex = 0\n\n const client: SandboxClient = {\n async create(opts?: CreateSandboxOptions): Promise<SandboxInstance> {\n const runId = randomUUID()\n const harness = harnesses[callIndex % harnesses.length] as LocalHarness\n callIndex += 1\n // §1.5: the authored profile rides in `backend.profile` (set by `buildBackendOptions`).\n // Without one (a direct test `create()`), fall back to a name-only profile → the harness\n // sees the task prompt with no system prepend, the pre-fix behavior.\n const profile =\n ((opts?.backend as { profile?: AgentProfile } | undefined)?.profile as\n | AgentProfile\n | undefined) ?? ({ name: `in-process-${harness}` } as AgentProfile)\n\n const virtual: VirtualSandbox = {\n id: `in-process-${runId}`,\n __inProcess: { runId, harness },\n async *streamPrompt(\n this: VirtualSandbox,\n message: string | unknown[],\n promptOpts?: { signal?: AbortSignal },\n ): AsyncGenerator<SandboxEvent> {\n const taskPrompt =\n typeof message === 'string'\n ? message\n : message\n .map((p) =>\n typeof p === 'object' && p && 'text' in p\n ? String((p as { text: unknown }).text)\n : '',\n )\n .join('\\n')\n\n // The shared worktree-harness core: worktree → profile-aware harness → diff → checks.\n // A throw cleans up inside the core; on success we own the teardown (the finally).\n const run = await runWorktreeHarness({\n repoRoot: options.repoRoot,\n profile,\n harness,\n taskPrompt,\n runId,\n harnessTimeoutMs: options.harnessTimeoutMs ?? DEFAULT_HARNESS_TIMEOUT_MS,\n checkTimeoutMs: options.postCheckTimeoutMs ?? DEFAULT_POSTCHECK_TIMEOUT_MS,\n ...(options.testCmd !== undefined ? { testCmd: options.testCmd } : {}),\n ...(options.typecheckCmd !== undefined ? { typecheckCmd: options.typecheckCmd } : {}),\n ...(options.runGit ? { runGit: options.runGit } : {}),\n ...(options.runHarness ? { runHarness: options.runHarness } : {}),\n runCommand,\n ...(promptOpts?.signal ? { signal: promptOpts.signal } : {}),\n })\n this.__inProcess.worktree = run.worktree\n\n try {\n yield {\n type: 'in_process.harness.started',\n data: { runId, harness, worktreePath: run.worktree.path, command: harness },\n }\n const h = run.result.harness\n yield {\n type: 'in_process.harness.ended',\n data: {\n runId,\n exitCode: h.exitCode,\n durationMs: h.durationMs,\n killedBySignal: h.killedBySignal,\n timedOut: h.timedOut,\n stdoutBytes: h.stdout.length,\n stderrBytes: h.stderr.length,\n },\n }\n yield {\n type: 'result',\n data: {\n result: run.result,\n source: 'in-process-executor',\n harness,\n runId,\n },\n }\n } finally {\n await run.cleanup()\n }\n },\n } as unknown as VirtualSandbox\n\n return virtual\n },\n describePlacement(box: SandboxInstance): InProcessExecutorDescribePlacement {\n const sandboxId = (box as unknown as { id?: string }).id\n const meta = (box as VirtualSandbox).__inProcess\n return {\n kind: 'sibling',\n sandboxId,\n worktreePath: meta?.worktree?.path,\n harness: meta?.harness,\n }\n },\n }\n\n return {\n client,\n placement: 'in-process',\n describe(): string {\n return `in-process (repoRoot=${options.repoRoot}, harnesses=[${harnesses.join(',')}]${\n options.testCmd ? `, testCmd=\"${options.testCmd}\"` : ''\n }${options.typecheckCmd ? `, typecheckCmd=\"${options.typecheckCmd}\"` : ''})`\n },\n }\n}\n\nasync function defaultRunPostCheck(\n cmd: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve, reject) => {\n const child = spawn('sh', ['-c', cmd], { cwd, stdio: 'pipe' })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (c) => {\n stdout += String(c)\n })\n child.stderr?.on('data', (c) => {\n stderr += String(c)\n })\n if (signal) {\n const onAbort = () => {\n if (!child.killed) child.kill('SIGTERM')\n }\n if (signal.aborted) onAbort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n const killTimer = setTimeout(() => {\n if (!child.killed) child.kill('SIGTERM')\n }, DEFAULT_POSTCHECK_TIMEOUT_MS)\n if (typeof (killTimer as { unref?: () => void }).unref === 'function') {\n ;(killTimer as { unref: () => void }).unref()\n }\n child.on('error', (err) => {\n clearTimeout(killTimer)\n reject(err)\n })\n child.on('close', (code) => {\n clearTimeout(killTimer)\n resolve({ exitCode: code ?? -1, stdout, stderr })\n })\n })\n}\n","/**\n *\n * Helpers extracted from `bin.ts` so the env-detection + executor-selection\n * logic is unit-testable without spawning a subprocess. The bin imports from\n * here; tests import from here directly.\n *\n * @experimental\n */\n\nimport type { SandboxClient } from '../runtime'\nimport {\n createFleetWorkspaceExecutor,\n createSiblingSandboxExecutor,\n type DelegationExecutor,\n type FleetHandle,\n} from './executor'\nimport { createInProcessExecutor } from './in-process-executor'\nimport type { LocalHarness } from './local-harness'\n\n/** @experimental */\nexport interface DetectExecutorArgs {\n sandboxClient: SandboxClient\n /** Raw env (defaults to `process.env`). Pass an explicit map for tests. */\n env?: Record<string, string | undefined>\n /**\n * Override how a fleet handle is resolved from the client + fleet id. The\n * default reads `client.fleets.get(fleetId)` and validates the returned\n * shape against the structural `FleetHandle` contract.\n */\n resolveFleet?: (client: SandboxClient, fleetId: string) => Promise<FleetHandle>\n}\n\n/**\n * Pick the right executor for an MCP server invocation based on env vars.\n *\n * - `TANGLE_FLEET_ID` set → fleet-workspace placement; resolves the handle\n * via `sandboxClient.fleets.get(...)`.\n * - Otherwise → sibling-sandbox placement; each delegation creates a fresh\n * sandbox via `sandboxClient.create(...)`.\n *\n * Fails loud (throws) when fleet mode is requested but the SDK shape is\n * incompatible — the operator chose fleet semantics, silently degrading to\n * sibling mode would lie about workspace topology.\n *\n * @experimental\n */\nexport async function detectExecutor(args: DetectExecutorArgs): Promise<DelegationExecutor> {\n const env = args.env ?? process.env\n\n // In-process (Phase 2.8): parent harness sets AGENT_RUNTIME_IN_SANDBOX=1\n // and points us at the workspace root. Highest-priority — when this is\n // set, delegations spawn local harness CLIs on git worktrees in the\n // SAME filesystem instead of provisioning sibling sandboxes.\n if (env.AGENT_RUNTIME_IN_SANDBOX === '1') {\n const repoRoot = env.AGENT_RUNTIME_REPO_ROOT?.trim()\n if (!repoRoot) {\n throw new Error(\n 'agent-runtime-mcp: AGENT_RUNTIME_IN_SANDBOX=1 requires AGENT_RUNTIME_REPO_ROOT to point at the workspace root',\n )\n }\n return createInProcessExecutor({\n repoRoot,\n harnesses: parseHarnesses(env.AGENT_RUNTIME_LOCAL_HARNESSES),\n testCmd: env.AGENT_RUNTIME_TEST_CMD?.trim() || undefined,\n typecheckCmd: env.AGENT_RUNTIME_TYPECHECK_CMD?.trim() || undefined,\n })\n }\n\n const fleetId = parseFleetId(env.TANGLE_FLEET_ID)\n if (!fleetId) {\n return createSiblingSandboxExecutor({ client: args.sandboxClient })\n }\n const resolveFleet = args.resolveFleet ?? defaultResolveFleet\n const fleet = await resolveFleet(args.sandboxClient, fleetId)\n const excludeMachineIds = parseList(env.TANGLE_FLEET_EXCLUDE_MACHINES)\n return createFleetWorkspaceExecutor({\n fleet,\n excludeMachineIds,\n })\n}\n\nconst KNOWN_HARNESSES: ReadonlyArray<LocalHarness> = ['claude', 'codex', 'opencode']\n\nfunction parseHarnesses(raw: string | undefined): ReadonlyArray<LocalHarness> | undefined {\n if (!raw) return undefined\n const parts = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n if (parts.length === 0) return undefined\n for (const part of parts) {\n if (!KNOWN_HARNESSES.includes(part as LocalHarness)) {\n throw new Error(\n `agent-runtime-mcp: AGENT_RUNTIME_LOCAL_HARNESSES contains unknown harness \"${part}\". Expected: ${KNOWN_HARNESSES.join(', ')}.`,\n )\n }\n }\n return parts as LocalHarness[]\n}\n\ninterface FleetsApi {\n get(fleetId: string): Promise<unknown>\n}\n\nasync function defaultResolveFleet(\n sandboxClient: SandboxClient,\n fleetId: string,\n): Promise<FleetHandle> {\n const fleets = (sandboxClient as unknown as { fleets?: FleetsApi }).fleets\n if (!fleets || typeof fleets.get !== 'function') {\n throw new Error(\n 'agent-runtime-mcp: the configured sandbox client does not expose `.fleets.get`; upgrade @tangle-network/sandbox to >= 0.2.1 or unset TANGLE_FLEET_ID.',\n )\n }\n const raw = await fleets.get(fleetId)\n if (!raw || typeof raw !== 'object') {\n throw new Error(`agent-runtime-mcp: fleets.get(${fleetId}) returned no handle`)\n }\n const handle = raw as Partial<FleetHandle>\n if (typeof handle.fleetId !== 'string' || !Array.isArray(handle.ids)) {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing fleetId/ids — incompatible sandbox SDK shape`,\n )\n }\n if (typeof handle.sandbox !== 'function') {\n throw new Error(\n `agent-runtime-mcp: fleet handle for ${fleetId} is missing sandbox(machineId) — incompatible sandbox SDK shape`,\n )\n }\n return handle as FleetHandle\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseList(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n","/**\n *\n * Sandbox-session coder decode layer. The sandbox-session delegate (`./delegates`) and the\n * cross-restart resume driver run the in-box harness over a `SandboxClient` and need to\n * (a) build an `AgentRunSpec` from the caller-authored (or minimal model-only default) worker\n * profile, (b) decode the harness event stream into a structured `CoderOutput`, and (c) gate it with\n * the shared mechanical checks. This sandbox-session path is kept separate from the generic recursive\n * path: `worktreeFanout` instead settles the raw `WorktreePatchArtifact` and gates via\n * `patchDelivered`. Prefer `worktreeFanout` / `worktreeLoopRunner` for NEW local-repo coding.\n *\n * The decode tolerates two `result`-event shapes:\n * 1. the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks }`),\n * projected onto `CoderOutput`; and\n * 2. an LLM-emitted JSON block (`{ branch, patch, testResult, typecheckResult, diffStats }`),\n * lifted onto `data.result` or scanned out of the assistant transcript (any harness shape).\n *\n * @experimental\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { type CoderTask, coderTaskToPrompt } from '../profiles/coder'\nimport { type CoderCheckConstraints, runCoderChecks } from '../runtime/supervise/patch-checks'\nimport type { AgentRunSpec, Driver, OutputAdapter, Validator } from '../runtime/types'\n\nconst DEFAULT_MAX_DIFF_LINES = 400\n\n/**\n * The minimal default worker profile (§1.5: the system authors profiles — there is no hardcoded\n * coder). Model-only by construction: no skills, no tool grants, no standing prompt. Callers that\n * want a richer worker pass their own `AgentProfile` via `CoderRunSpecOptions.profile`. `harness` /\n * `model` / `systemPrompt` are layered onto whichever profile is used.\n */\nfunction minimalCoderProfile(): AgentProfile {\n return { name: 'coder' }\n}\n\n/** @experimental The structured coder result the sandbox-session path decodes + gates. */\nexport interface CoderOutput {\n /** Branch the agent wrote the patch on. */\n branch: string\n /** Unified diff (`git diff <base>..HEAD`). */\n patch: string\n testResult: { passed: boolean; output: string }\n typecheckResult: { passed: boolean; output: string }\n diffStats: { filesChanged: number; insertions: number; deletions: number }\n /** Optional reviewer commentary surfaced by the agent. */\n reviewerNotes?: string\n}\n\n/** @experimental Overrides for one authored coder run on the sandbox-session path. */\nexport interface CoderRunSpecOptions {\n /**\n * The caller-authored worker `AgentProfile` (§1.5). When omitted, a minimal model-only default is\n * used (no hardcoded skills/tools/prompt). `harness` / `model` / `systemPrompt` are layered onto it.\n */\n profile?: AgentProfile\n /** Sandbox-SDK backend.type. Default `'claude-code'`. */\n harness?: string\n /** Default model id passed in `AgentProfile.model.default`. */\n model?: string\n /** Custom system prompt replacement. Default = the supplied profile's own prompt (or none). */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `coder-${harness}`. */\n name?: string\n}\n\n/** Build the authored `AgentProfile` for one harness on the sandbox-session path: the caller's\n * profile (or the minimal model-only default), with the per-run harness/model/prompt overrides. */\nfunction coderRunProfile(options: CoderRunSpecOptions): AgentProfile {\n const harness = options.harness ?? 'claude-code'\n const name = options.name ?? `coder-${harness}`\n const base = options.profile ?? minimalCoderProfile()\n return {\n ...base,\n name,\n ...(options.systemPrompt ? { prompt: { systemPrompt: options.systemPrompt } } : {}),\n model: options.model ? { default: options.model } : base.model,\n metadata: { ...base.metadata, backendType: harness },\n }\n}\n\n/** @experimental Build the `AgentRunSpec<CoderTask>` the sandbox-session `runLoop` path drives. */\nexport function coderRunSpec(options: CoderRunSpecOptions = {}): AgentRunSpec<CoderTask> {\n return {\n name: options.name ?? `coder-${options.harness ?? 'claude-code'}`,\n profile: coderRunProfile(options),\n taskToPrompt: coderTaskToPrompt,\n }\n}\n\n/** @experimental The output adapter the sandbox-session path decodes the harness stream with. */\nexport const coderOutputAdapter: OutputAdapter<CoderOutput> = { parse: parseCoderEvents }\n\n/** @experimental */\nexport interface MultiHarnessCoderFanoutOptions {\n /**\n * The caller-authored worker `AgentProfile` (§1.5), shared across every parallel harness. When\n * omitted, the minimal model-only default is used.\n */\n profile?: AgentProfile\n /**\n * Sandbox-SDK backend.type identifiers, one per parallel agent. Default:\n * `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']`.\n */\n harnesses?: string[]\n /** Optional per-harness model override. Indexed parallel to `harnesses`. */\n models?: (string | undefined)[]\n}\n\n/**\n * The multi-harness coder fanout driving the sandbox-session delegate's `variants>1` path.\n * (`worktreeFanout` is the local-repo generic counterpart for new code.)\n *\n * @experimental\n */\nexport function multiHarnessCoderFanout(options: MultiHarnessCoderFanoutOptions = {}): {\n agentRuns: AgentRunSpec<CoderTask>[]\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'>\n} {\n const harnesses =\n options.harnesses && options.harnesses.length > 0\n ? options.harnesses\n : ['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']\n const models = options.models ?? []\n const agentRuns = harnesses.map((harness, i) =>\n coderRunSpec({\n ...(options.profile ? { profile: options.profile } : {}),\n harness,\n model: models[i],\n }),\n )\n const driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'> = {\n name: 'fanout',\n plan: async (task, history) => (history.length === 0 ? agentRuns.map(() => task) : []),\n decide: (history) => (history.some((i) => i.verdict?.valid === true) ? 'pick-winner' : 'fail'),\n }\n return { agentRuns, output: coderOutputAdapter, validator: defaultCoderValidator(), driver }\n}\n\n/**\n * The sandbox `CoderOutput` validator. A thin shim over the shared {@link runCoderChecks} gate,\n * adapting the parsed `CoderOutput` into the gate inputs.\n *\n * @experimental\n */\nexport function createCoderValidator(task: CoderTask): Validator<CoderOutput> {\n const constraints: CoderCheckConstraints = {\n maxDiffLines: task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES,\n forbiddenPaths: task.forbiddenPaths ?? [],\n }\n return {\n async validate(output) {\n return runCoderChecks(\n {\n patch: output.patch,\n testsPassed: output.testResult.passed,\n typecheckPassed: output.typecheckResult.passed,\n },\n constraints,\n )\n },\n }\n}\n\nfunction defaultCoderValidator(): Validator<CoderOutput> {\n return createCoderValidator({\n goal: '',\n repoRoot: '',\n forbiddenPaths: [],\n maxDiffLines: DEFAULT_MAX_DIFF_LINES,\n })\n}\n\n/**\n * Walk the event stream and return the structured coder payload.\n *\n * A `result` / `final` event lifts the structured payload onto `data.result`. That payload is\n * either the in-process executor's raw worktree-harness result (projected onto `CoderOutput`) or an\n * LLM-emitted `CoderOutput`-shaped JSON. When neither is present, the scan accumulates ALL assistant\n * text in stream order (any harness shape) and takes the last fenced JSON block that coerces —\n * claude-code lifts whole text onto `data.text`/`data.delta`; opencode streams `message.part.updated`\n * fragments, so the final block is split across many events and never whole in one.\n */\nfunction parseCoderEvents(events: SandboxEvent[]): CoderOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'coder.result') {\n const payload = data.result ?? data.output ?? data\n const projected = projectWorktreeArtifact(payload)\n if (projected) return projected\n const direct = coerceCoderOutput(payload)\n if (direct) return direct\n }\n }\n const transcript = collectAssistantText(events)\n for (const candidate of fencedJsonBlocks(transcript)) {\n const coerced = coerceCoderOutput(candidate)\n if (coerced) return coerced\n }\n return {\n branch: '',\n patch: '',\n testResult: { passed: false, output: '' },\n typecheckResult: { passed: false, output: '' },\n diffStats: { filesChanged: 0, insertions: 0, deletions: 0 },\n }\n}\n\n/** Project the in-process executor's raw worktree-harness result (`{ branch, patch, stats, checks,\n * harness }`) onto `CoderOutput`. A check that did not run is treated as passing (the executor\n * simply didn't run that command). Returns undefined when the payload is not a worktree artifact. */\nfunction projectWorktreeArtifact(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const stats = value.stats\n if (!isRecord(stats)) return undefined // not the raw artifact shape\n const branch = pickString(value.branch) ?? ''\n const patch = pickString(value.patch) ?? ''\n const checks = isRecord(value.checks) ? value.checks : {}\n const tests = isRecord(checks.tests) ? checks.tests : undefined\n const typecheck = isRecord(checks.typecheck) ? checks.typecheck : undefined\n const harness = isRecord(value.harness) ? value.harness : undefined\n const exitCode = harness ? toFiniteInt(harness.exitCode) : 0\n const timedOut = harness?.timedOut === true\n const harnessName = harness ? (pickString(harness.name) ?? 'harness') : 'harness'\n return {\n branch,\n patch,\n testResult: {\n passed: tests ? tests.passed === true : true,\n output: tail(pickString(tests?.output) ?? '', 4000),\n },\n typecheckResult: {\n passed: typecheck ? typecheck.passed === true : true,\n output: tail(pickString(typecheck?.output) ?? '', 4000),\n },\n diffStats: {\n filesChanged: toFiniteInt(stats.filesChanged),\n insertions: toFiniteInt(stats.insertions),\n deletions: toFiniteInt(stats.deletions),\n },\n ...(exitCode !== 0\n ? {\n reviewerNotes: `harness ${harnessName} exited ${exitCode}${timedOut ? ' (timed out)' : ''}`,\n }\n : {}),\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Keep the last `max` chars of a diagnostic string — harness stdout can be large; the gate reads\n * `passed`, not this text, so only the tail is retained for traces/logs. */\nfunction tail(text: string, max: number): string {\n return text.length <= max ? text : text.slice(text.length - max)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n/**\n * Concatenate assistant text across the event stream in arrival order, tolerating every harness\n * shape: claude-code lifts text onto `data.text`/`data.delta`; opencode streams\n * `message.part.updated` with `data.part.type === 'text'` carrying `data.delta`/`data.part.text`.\n * Reasoning/thinking parts are excluded — only the final answer text carries the result JSON.\n */\nfunction collectAssistantText(events: SandboxEvent[]): string {\n const chunks: string[] = []\n for (const event of events) {\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n if (String(event.type ?? '') === 'message.part.updated') {\n const part = isRecord(data.part) ? data.part : {}\n const partType = String(part.type ?? '')\n if (partType !== 'text' && partType !== '') continue\n const text = pickString(data.delta) ?? pickString(part.text)\n if (text) chunks.push(text)\n continue\n }\n const text = pickString(data.text) ?? pickString(data.delta)\n if (text) chunks.push(text)\n }\n return chunks.join('')\n}\n\n/** All parseable fenced JSON blocks in `text`, last-first (the final result block the agent emits\n * is the one we want). */\nfunction fencedJsonBlocks(text: string): unknown[] {\n const out: unknown[] = []\n const matches = [...text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)```/gi)]\n for (let i = matches.length - 1; i >= 0; i -= 1) {\n const body = (matches[i]?.[1] ?? '').trim()\n if (!body) continue\n try {\n out.push(JSON.parse(body))\n } catch {\n // not JSON — keep scanning earlier blocks\n }\n }\n return out\n}\n\nfunction coerceCoderOutput(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const branch = pickString(value.branch)\n const patch = pickString(value.patch) ?? ''\n if (branch === undefined) return undefined\n return {\n branch,\n patch,\n testResult: coerceCmdResult(value.testResult),\n typecheckResult: coerceCmdResult(value.typecheckResult),\n diffStats: coerceDiffStats(value.diffStats),\n reviewerNotes: pickString(value.reviewerNotes),\n }\n}\n\nfunction coerceCmdResult(value: unknown): { passed: boolean; output: string } {\n if (!isRecord(value)) return { passed: false, output: '' }\n return { passed: value.passed === true, output: pickString(value.output) ?? '' }\n}\n\nfunction coerceDiffStats(value: unknown): {\n filesChanged: number\n insertions: number\n deletions: number\n} {\n if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 }\n return {\n filesChanged: toFiniteInt(value.filesChanged),\n insertions: toFiniteInt(value.insertions),\n deletions: toFiniteInt(value.deletions),\n }\n}\n\nfunction toFiniteInt(value: unknown): number {\n if (typeof value !== 'number') return 0\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.trunc(value))\n}\n","/**\n *\n * Detached delegation turns over the sandbox SDK's `driveTurn` primitive.\n *\n * Two halves of one story:\n *\n * - {@link runDetachedTurn} — the dispatch side. A single-session delegate\n * (single-variant coder / researcher) acquires a box, binds the sandbox id\n * into the record's `detachedSessionRef`, then advances the turn with\n * repeated `driveTurn` ticks instead of holding a live SSE stream. The\n * session id is deterministic and supplied at submit time, so a process\n * crash between ticks loses nothing — the turn keeps running in the box.\n *\n * - {@link createDetachedTurnResumeDriver} — the resume side. A\n * `DelegationResumeDriver` that re-attaches restored in-flight records to\n * their detached runs: parse the record's ref, resolve the box, advance the\n * turn one `driveTurn` pass per `tick()`, and map the SDK's three states\n * (`completed | running | failed`) onto `DelegationResumeTick`.\n *\n * Both sides type the box structurally ({@link DriveTurnCapableBox}) so tests\n * inject fakes and the module never requires the sandbox SDK at runtime — the\n * SDK stays an optional peer, exactly like the executors' `SandboxClient` seam.\n *\n * Tradeoffs of detached mode (why it is opt-in, not the default): a detached\n * turn yields one terminal payload instead of a live event stream, so kernel\n * token/cost aggregation is not produced for that turn. The trace sinks still\n * observe detached work — `runDetachedTurn` synthesizes a single-iteration\n * loop event stream (see `RunDetachedTurnOptions.traceEmitter`) so the span\n * topology joins the inherited trace context, with cost/tokens reported as 0\n * under the `'detached-turn'` driver tag. Multi-variant fanout stays on the\n * streaming `runLoop` path — N concurrent sessions cannot be expressed as one\n * resume key, and winner selection needs every candidate.\n *\n * @experimental\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport type { AgentRunSpec, LoopTraceEmitter, LoopTraceEvent, SandboxClient } from '../runtime'\nimport { createSandboxForSpec } from '../runtime/run-loop'\nimport { deleteBoxSafe, sleep, throwAbort, throwIfAborted } from '../runtime/util'\nimport type { DelegationRecord, DelegationResumeDriver, DelegationResumeTick } from './task-queue'\nimport type { DelegationProgress, DelegationResultPayload } from './types'\n\nconst DEFAULT_TICK_INTERVAL_MS = 5000\n\n/**\n * Structural mirror of the sandbox SDK's `TurnDriveResult` (>= 0.6).\n * Discriminated on `state`; `failed` is terminal and deterministic per the\n * SDK contract — re-invoking with the same ids returns the same outcome.\n *\n * @experimental\n */\nexport type DriveTurnTick =\n | { state: 'completed'; text: string; result: Record<string, unknown> }\n | { state: 'running'; startedAt?: Date; elapsedMs?: number }\n | { state: 'failed'; error: string }\n\n/**\n * The box surface detached turns need. `SandboxInstance`\n * (`@tangle-network/sandbox` >= 0.6) satisfies it structurally; tests pass\n * in-memory fakes. `_sessionCancel` is the SDK's remote-cancellation surface —\n * optional here because older SDKs / fakes may not expose it; when present it\n * is invoked on abort so the remote run actually stops.\n *\n * @experimental\n */\nexport interface DriveTurnCapableBox {\n driveTurn(\n message: string,\n opts: { sessionId: string; turnId?: string; wallCapMs?: number },\n ): Promise<DriveTurnTick>\n _sessionCancel?(id: string): Promise<void>\n}\n\n/**\n * Decoded `DelegationRecord.detachedSessionRef`. `sandboxId` is absent between\n * submit and box acquisition — a record restored in that window is not\n * resumable (there is no box to resume on) and the resume driver fails it\n * loud rather than dispatching onto a guessed box.\n *\n * @experimental\n */\nexport interface DetachedSessionRefParts {\n sessionId: string\n sandboxId?: string\n}\n\n/**\n * Encode ref parts into the JSON-safe string stored on the record:\n * `session=<id>` before the box exists, `sandbox=<id>;session=<id>` once\n * bound. Ids must not contain the `;`/`=` delimiters.\n *\n * @experimental\n */\nexport function formatDetachedSessionRef(parts: DetachedSessionRefParts): string {\n assertRefComponent('sessionId', parts.sessionId)\n if (parts.sandboxId === undefined) return `session=${parts.sessionId}`\n assertRefComponent('sandboxId', parts.sandboxId)\n return `sandbox=${parts.sandboxId};session=${parts.sessionId}`\n}\n\n/** Parse a `detachedSessionRef` string back to parts; throws `ValidationError` on malformed input. @experimental */\nexport function parseDetachedSessionRef(raw: string): DetachedSessionRefParts {\n const fields = new Map<string, string>()\n for (const pair of raw.split(';')) {\n const eq = pair.indexOf('=')\n const key = eq === -1 ? '' : pair.slice(0, eq)\n const value = eq === -1 ? '' : pair.slice(eq + 1)\n if ((key !== 'session' && key !== 'sandbox') || value.length === 0 || fields.has(key)) {\n throw new ValidationError(\n `parseDetachedSessionRef: malformed detachedSessionRef ${JSON.stringify(raw)} — expected \"session=<id>\" or \"sandbox=<id>;session=<id>\"`,\n )\n }\n fields.set(key, value)\n }\n const sessionId = fields.get('session')\n if (!sessionId) {\n throw new ValidationError(\n `parseDetachedSessionRef: detachedSessionRef ${JSON.stringify(raw)} carries no session id`,\n )\n }\n const sandboxId = fields.get('sandbox')\n return { sessionId, ...(sandboxId !== undefined ? { sandboxId } : {}) }\n}\n\nfunction assertRefComponent(name: string, value: string): void {\n if (value.length === 0 || value.includes(';') || value.includes('=')) {\n throw new ValidationError(\n `formatDetachedSessionRef: ${name} ${JSON.stringify(value)} must be non-empty and free of \";\" / \"=\"`,\n )\n }\n}\n\n/** @experimental The terminal payload of a finished detached turn. */\nexport interface DetachedTurn {\n /** Final assistant text. */\n text: string\n /** The SDK's cached AgentExecutionResult-shape record for the turn. */\n result: Record<string, unknown>\n}\n\n/**\n * Synthesize the terminal event array a detached turn settles through. Shaped\n * so the existing event-stream output adapters (coder, researcher) parse it:\n * `data.result` for adapters that read a structured terminal record, `data.text`\n * for adapters that scan assistant text for the fenced result block.\n *\n * @experimental\n */\nexport function detachedTurnEvents(sessionId: string, turn: DetachedTurn): SandboxEvent[] {\n return [\n {\n type: 'result',\n id: sessionId,\n data: {\n text: turn.text,\n finalText: turn.text,\n success: true,\n result: turn.result,\n },\n } as SandboxEvent,\n ]\n}\n\n/** @experimental */\nexport interface RunDetachedTurnOptions {\n /** Sandbox client used to acquire the box (the delegate's executor client). */\n client: SandboxClient\n /** Profile + overrides for box acquisition — same spec the streaming path uses. */\n spec: AgentRunSpec<unknown>\n /** The full turn prompt; consumed by `driveTurn`'s dispatch leg. */\n prompt: string\n /** Deterministic resume key, minted at submit time (`parseDetachedSessionRef(ref).sessionId`). */\n sessionId: string\n /**\n * Called once the box exists, with its sandbox id. Callers persist\n * `formatDetachedSessionRef({ sandboxId, sessionId })` onto the record here so\n * a restart can resolve the box again.\n */\n bindSandbox(sandboxId: string): void\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** Delay between `running` ticks (ms). Default 5000. */\n tickIntervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` — the SDK cancels and fails a session past it. */\n wallCapMs?: number\n /**\n * Loop-trace sink. When set, the detached turn synthesizes a\n * single-iteration loop span tree (`runId` = `sessionId`, driver\n * `'detached-turn'`) so trace-context inheritance survives the detached\n * path — the same events the streaming `runLoop` path would emit, minus\n * per-token telemetry: `driveTurn` yields one terminal payload, so token\n * and cost figures are structurally unavailable and reported as 0 under\n * this driver tag.\n */\n traceEmitter?: LoopTraceEmitter\n /** Physical placement stamped on the synthesized dispatch event. Default `'sibling'`. */\n placement?: 'sibling' | 'fleet'\n}\n\n/**\n * Dispatch one detached turn and advance it to a terminal state with\n * `driveTurn` ticks. The first tick dispatches (idempotent on `sessionId`);\n * subsequent ticks poll. On abort the remote session is cancelled via\n * `_sessionCancel` when the box exposes it. The box is torn down on every\n * in-process exit path (success, failure, abort) — only a process death skips\n * teardown, which is exactly the case the resume driver re-attaches to.\n *\n * @experimental\n */\nexport async function runDetachedTurn(options: RunDetachedTurnOptions): Promise<DetachedTurn> {\n const intervalMs = options.tickIntervalMs ?? DEFAULT_TICK_INTERVAL_MS\n const trace = createDetachedTurnTrace(options)\n trace.started()\n const box = await createSandboxForSpec(options.client, options.spec, options.signal).catch(\n (err) => {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n },\n )\n const drive = box as Partial<DriveTurnCapableBox>\n const onAbort = () => {\n void drive._sessionCancel?.(options.sessionId).catch(() => {})\n }\n try {\n if (typeof drive.driveTurn !== 'function') {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox exposes no driveTurn(message, { sessionId }) — ' +\n 'detached dispatch requires @tangle-network/sandbox >= 0.6 and a session-backed ' +\n 'placement (sibling/fleet); disable detached dispatch for this executor.',\n )\n }\n const sandboxId = (box as { id?: unknown }).id\n if (typeof sandboxId !== 'string' || sandboxId.length === 0) {\n throw new ValidationError(\n 'runDetachedTurn: the acquired sandbox carries no id — without it the detached run ' +\n 'cannot be resumed after a restart, so refusing to dispatch detached.',\n )\n }\n options.bindSandbox(sandboxId)\n trace.dispatched(sandboxId)\n options.signal.addEventListener('abort', onAbort, { once: true })\n for (;;) {\n throwIfAborted(options.signal)\n const tick = await drive.driveTurn(options.prompt, {\n sessionId: options.sessionId,\n turnId: options.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n throwIfAborted(options.signal)\n if (tick.state === 'completed') {\n trace.ended()\n return { text: tick.text, result: tick.result }\n }\n if (tick.state === 'failed') {\n throw new Error(`detached turn ${options.sessionId} failed: ${tick.error}`)\n }\n options.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n await sleep(intervalMs, options.signal)\n }\n } catch (err) {\n trace.ended(err instanceof Error ? err.message : String(err))\n throw err\n } finally {\n options.signal.removeEventListener('abort', onAbort)\n if (options.signal.aborted) onAbort()\n await deleteBoxSafe(box)\n }\n}\n\n/**\n * Synthesize the single-iteration loop event stream for one detached turn so\n * the trace sinks (OTEL exporter, delegation journal) observe detached work\n * exactly like a streamed `runLoop` run. `runId` = the deterministic session\n * id; cost/token figures are structurally unavailable on the `driveTurn`\n * surface and emitted as 0 under the `'detached-turn'` driver tag.\n */\nfunction createDetachedTurnTrace(options: RunDetachedTurnOptions): {\n started(): void\n dispatched(sandboxId: string): void\n ended(error?: string): void\n} {\n const emitter = options.traceEmitter\n if (!emitter) {\n return { started() {}, dispatched() {}, ended() {} }\n }\n const runId = options.sessionId\n const agentRunName = options.spec.name ?? options.spec.profile.name ?? 'detached-turn'\n const startMs = Date.now()\n let done = false\n const emit = (event: LoopTraceEvent): void => {\n void emitter.emit(event)\n }\n return {\n started(): void {\n emit({\n kind: 'loop.started',\n runId,\n timestamp: startMs,\n payload: {\n driver: 'detached-turn',\n agentRunNames: [agentRunName],\n maxIterations: 1,\n maxConcurrency: 1,\n },\n })\n emit({\n kind: 'loop.iteration.started',\n runId,\n timestamp: startMs,\n payload: { iterationIndex: 0, agentRunName, taskHash: options.sessionId },\n })\n },\n dispatched(sandboxId: string): void {\n emit({\n kind: 'loop.iteration.dispatch',\n runId,\n timestamp: Date.now(),\n payload: {\n iterationIndex: 0,\n agentRunName,\n placement: options.placement ?? 'sibling',\n sandboxId,\n },\n })\n },\n ended(error?: string): void {\n if (done) return\n done = true\n const endMs = Date.now()\n emit({\n kind: 'loop.iteration.ended',\n runId,\n timestamp: endMs,\n payload: {\n iterationIndex: 0,\n agentRunName,\n costUsd: 0,\n durationMs: endMs - startMs,\n ...(error !== undefined ? { error } : {}),\n },\n })\n emit({\n kind: 'loop.ended',\n runId,\n timestamp: endMs,\n payload: {\n ...(error === undefined ? { winnerIterationIndex: 0 } : {}),\n totalCostUsd: 0,\n durationMs: endMs - startMs,\n iterations: 1,\n },\n })\n },\n }\n}\n\nfunction detachedRunningPhase(elapsedMs: number | undefined): string {\n return elapsedMs === undefined\n ? 'detached-running'\n : `detached-running ${Math.round(elapsedMs / 1000)}s`\n}\n\n/** @experimental */\nexport interface DetachedTurnResumeDriverOptions {\n /**\n * Resolve the live box owning a detached session. The bin wires this to the\n * sandbox client's `get(sandboxId)`; throw when the box no longer exists —\n * a thrown tick settles the record as failed, which is the truth.\n */\n resolveSandbox(sandboxId: string): Promise<DriveTurnCapableBox>\n /**\n * Rebuild the turn prompt from the persisted record. Only consumed by\n * `driveTurn`'s dispatch leg — i.e. when the previous process died after\n * binding the box but before the session was dispatched. Must reproduce the\n * prompt the delegate would have sent.\n */\n buildMessage(record: DelegationRecord): string\n /**\n * Map a completed turn onto the delegation's typed output payload (parse +\n * validate per profile). Throw when the resumed result does not pass the\n * profile's gate — the queue settles the record as failed with that error.\n */\n settleOutput(\n turn: DetachedTurn,\n record: DelegationRecord,\n ctx: { signal: AbortSignal },\n ): Promise<DelegationResultPayload['output']> | DelegationResultPayload['output']\n /** Delay between `running` ticks (ms). Default 5000. */\n intervalMs?: number\n /** Wall-clock cap forwarded to `driveTurn` on every tick. */\n wallCapMs?: number\n}\n\n/**\n * Build the `driveTurn`-backed {@link DelegationResumeDriver}. Each `tick()`\n * is one settle/poll/dispatch pass:\n *\n * - ref without a sandbox binding → `failed` (`DetachedSessionUnboundError`):\n * the previous process died before a box existed; there is nothing to resume.\n * - `driveTurn` `completed` → `settleOutput` → `completed` tick.\n * - `running` → progress via `ctx.report`, `running` tick (queue re-ticks\n * after `intervalMs`).\n * - `failed` → `failed` tick (`DetachedTurnFailedError`) — terminal per the\n * SDK's deterministic-failure contract.\n *\n * Abort: the queue stops ticking once `cancel()` flips the record, so remote\n * cancellation is hooked onto `ctx.signal` (once per task) and fires\n * `_sessionCancel` when the SDK surface exposes it. The driver never deletes\n * boxes — it cannot know whether `sandboxId` is a disposable sibling or a\n * fleet machine, and destroying a fleet machine would be unrecoverable.\n *\n * @experimental\n */\nexport function createDetachedTurnResumeDriver(\n options: DetachedTurnResumeDriverOptions,\n): DelegationResumeDriver {\n const cancelHooked = new Set<string>()\n return {\n intervalMs: options.intervalMs ?? DEFAULT_TICK_INTERVAL_MS,\n async tick({ record, detachedSessionRef }, ctx): Promise<DelegationResumeTick> {\n const ref = parseDetachedSessionRef(detachedSessionRef)\n if (ref.sandboxId === undefined) {\n return {\n state: 'failed',\n error: {\n message:\n `detached session \"${ref.sessionId}\" was never bound to a sandbox — the previous ` +\n 'process died before the box was acquired, so the turn was never dispatched and ' +\n 'cannot be resumed',\n kind: 'DetachedSessionUnboundError',\n },\n }\n }\n const box = await options.resolveSandbox(ref.sandboxId)\n if (!cancelHooked.has(record.taskId)) {\n cancelHooked.add(record.taskId)\n ctx.signal.addEventListener(\n 'abort',\n () => {\n void box._sessionCancel?.(ref.sessionId).catch(() => {})\n },\n { once: true },\n )\n }\n if (ctx.signal.aborted) throwAbort()\n const tick = await box.driveTurn(options.buildMessage(record), {\n sessionId: ref.sessionId,\n turnId: ref.sessionId,\n ...(options.wallCapMs !== undefined ? { wallCapMs: options.wallCapMs } : {}),\n })\n if (tick.state === 'completed') {\n const output = await options.settleOutput(\n { text: tick.text, result: tick.result },\n record,\n {\n signal: ctx.signal,\n },\n )\n return { state: 'completed', output }\n }\n if (tick.state === 'failed') {\n return {\n state: 'failed',\n error: {\n message: `detached turn ${ref.sessionId} failed: ${tick.error}`,\n kind: 'DetachedTurnFailedError',\n },\n }\n }\n ctx.report({ iteration: 0, phase: detachedRunningPhase(tick.elapsedMs) })\n return { state: 'running' }\n },\n }\n}\n","/**\n *\n * `detachedSessionDelegate` — the sandbox-session coder delegate: a closure that drives `runLoop`\n * against a `SandboxClient` + a caller-supplied (or minimal model-only default) worker profile, to a\n * mechanically-validated `CoderOutput`. The caller invokes the returned delegate directly with its\n * coder args; when wired into a durable queue it also settles cross-restart-resumed records.\n *\n * Delegation vs COORDINATION (`../runtime/supervise/coordination-mcp.ts`): this delegate runs a\n * coding task INSIDE the agent's OWN sandbox environment — a sibling box on its own `SandboxClient`,\n * fresh branch on its repo. It is NOT backend-pluggable. To instead SPAWN + live-drive workers in a\n * CHOSEN backend (sandbox OR cli-bridge, via `createExecutor({ backend })`) with observe/steer/resume\n * + recursion, use `delegate()` / the coordination MCP.\n *\n * The worker profile is a parameter the caller supplies (§1.5: the system authors profiles). When\n * none is passed, a minimal model-only default profile is materialized in `./detached-coder` — no\n * hardcoded skills or tools. For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner`\n * (author one `AgentProfile` per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`).\n *\n * @experimental\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { CoderTask } from '../profiles/coder'\nimport type {\n AgentRunSpec,\n Iteration,\n LoopTraceEmitter,\n Outcome,\n SandboxClient,\n WinnerStrategy,\n} from '../runtime'\nimport { runLoop, selectValidWinner } from '../runtime'\nimport { composeLoopTraceEmitters } from './delegation-trace'\nimport {\n type CoderOutput,\n coderOutputAdapter,\n coderRunSpec,\n createCoderValidator,\n multiHarnessCoderFanout,\n} from './detached-coder'\nimport {\n type DetachedTurn,\n detachedTurnEvents,\n formatDetachedSessionRef,\n parseDetachedSessionRef,\n runDetachedTurn,\n} from './detached-turn'\nimport { createSiblingSandboxExecutor, type DelegationExecutor } from './executor'\nimport type {\n DelegateCodeArgs,\n DelegateUiAuditArgs,\n DelegationProgress,\n UiAuditorDelegationOutput,\n} from './types'\n\n/** @experimental */\nexport interface DelegateRunCtx {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /**\n * Detached-run resume key recorded on the queue record at submit time\n * (`formatDetachedSessionRef`). Present only when the submit path requested\n * detached dispatch — its presence is what routes a session-backed delegate\n * onto the `driveTurn` tick path instead of holding a stream.\n */\n detachedSessionRef?: string\n /** Rebind the record's resume key (e.g. once the sandbox id is known). */\n updateDetachedSessionRef?(ref: string): void\n /**\n * Per-delegation trace sink supplied by the queue — loop events emitted\n * here land on the delegation record as a compact span tree. Delegates\n * compose it with their configured OTEL emitter so both sinks observe\n * the same stream.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @experimental The coder delegate closure — given the coder args + run context, drives the\n * sandbox-session coder path to a validated `CoderOutput`. `detachedSessionDelegate` is the\n * built-in implementation; the queue invokes one of these per coder delegation. */\nexport type CoderDelegate = (args: DelegateCodeArgs, ctx: DelegateRunCtx) => Promise<CoderOutput>\n\n/**\n * UI-auditor delegate — fully consumer-injected. agent-runtime ships no\n * default factory because the inputs are workspace path + judge function\n * + (optionally) a `SandboxClient`, and the judge is the consumer's\n * model seam. See `createInProcessUiAuditClient` + `uiAuditorProfile` in\n * `@tangle-network/agent-runtime/profiles` for the canonical wiring.\n *\n * @experimental\n */\nexport type UiAuditorDelegate = (\n args: DelegateUiAuditArgs,\n ctx: DelegateRunCtx,\n) => Promise<UiAuditorDelegationOutput>\n\n/** @experimental Structured review verdict over a coder candidate. */\nexport interface CoderReview {\n /** Gate: only approved candidates are eligible to win. */\n approved: boolean\n /** Reviewer's recommendation — surfaced in traces. */\n recommendation: 'ship' | 'approve-with-nits' | 'changes-requested' | 'reject'\n /** Readiness 0..1, used by the `highest-readiness` winner-selection strategy. */\n readiness: number\n notes?: string\n}\n\n/**\n *\n * Optional adversarial reviewer over a coder candidate that already passed\n * mechanical validation (tests/typecheck/forbidden/diff/no-op/secrets). Folded\n * from the ai-trading-blueprint delegation MCP: a candidate is only eligible to\n * win if the reviewer approves it. The reviewer is the consumer's seam — an LLM\n * judge, a `pnpm review` command, anything returning a `CoderReview`.\n *\n * @experimental\n */\nexport type CoderReviewer = (\n output: CoderOutput,\n task: CoderTask,\n ctx: { signal: AbortSignal },\n) => Promise<CoderReview> | CoderReview\n\n/**\n * @experimental Winner-selection strategy among validated (+ reviewed) candidates on the\n * sandbox-session path. The base strategies (`highest-score` / `smallest-diff` /\n * `first-approved`) delegate to the shared `selectValidWinner`; `highest-readiness` is the\n * reviewer-only strategy this path keeps that the generic selector does not express. Default\n * `highest-score`.\n */\nexport type DetachedWinnerSelection =\n | 'highest-score'\n | 'smallest-diff'\n | 'highest-readiness'\n | 'first-approved'\n\n/** @experimental */\nexport interface DetachedSessionDelegateOptions {\n /**\n * Execution placement. Pass a {@link DelegationExecutor} (sibling or fleet)\n * to control where worker iterations land. `sandboxClient` is a\n * convenience shorthand that wraps the client in a sibling executor — pass\n * one or the other, not both.\n */\n executor?: DelegationExecutor\n /**\n * Convenience shorthand for sibling placement. Equivalent to\n * `executor: createSiblingSandboxExecutor({ client: sandboxClient })`.\n */\n sandboxClient?: SandboxClient\n /**\n * The worker's authored `AgentProfile` (§1.5: the system authors profiles). Spread onto the\n * sandbox-session run spec → `runLoop` → the executor's `harnessInvocation`, so the harness runs\n * under the caller's stance. Omit to use a minimal model-only default (no hardcoded skills/tools);\n * `harness` / `model` / `systemPrompt` below are convenience overrides layered onto whichever\n * profile is used.\n */\n workerProfile?: AgentProfile\n /** Backend harness for the single-coder path (sets `metadata.backendType`). Default `claude-code`. */\n harness?: string\n /** Model override for the single-coder path. */\n model?: string\n /**\n * The worker's authored system prompt (§1.5). Flows onto the run spec's\n * `profile.prompt.systemPrompt` → through `runLoop` → the executor's `harnessInvocation`, so the\n * harness runs under this stance. Omit to keep the profile's own prompt.\n */\n systemPrompt?: string\n /** Default `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']` when variants > 1. */\n fanoutHarnesses?: string[]\n /** Optional per-harness model override for `variants > 1`. */\n fanoutModels?: (string | undefined)[]\n /** Hard cap on the kernel's per-batch concurrency. Default 4. */\n maxConcurrency?: number\n /**\n * Optional adversarial reviewer. When set, a candidate must pass mechanical\n * validation AND `reviewer.approved` to be eligible to win — empty/secret/\n * test-failing patches are already gone; this catches the \"compiles + passes\n * but wrong/unsafe\" class the deterministic validator can't see.\n */\n reviewer?: CoderReviewer\n /** Winner-selection strategy among eligible candidates. Default `highest-score`. */\n winnerSelection?: DetachedWinnerSelection\n /**\n * Loop trace emitter forwarded into every delegated `runLoop`. Wire\n * `createPropagatingTraceEmitter(readTraceContextFromEnv())` here (the bin\n * does) so delegated build-loops export their topology spans to the OTLP /\n * Tangle Intelligence sink when `OTEL_EXPORTER_OTLP_ENDPOINT` is set — and\n * are a cheap no-op when it isn't. Configurable by construction.\n *\n * Detached single-variant turns (taken when `ctx.detachedSessionRef` is set)\n * bypass `runLoop`; `runDetachedTurn` synthesizes a single-iteration loop\n * event stream for them so this emitter observes detached work too.\n */\n traceEmitter?: LoopTraceEmitter\n /** Tick cadence (ms) for the detached single-variant path. Default 5000. */\n detachedTickIntervalMs?: number\n /** Wall-clock cap (ms) forwarded to `driveTurn` for detached turns. */\n detachedWallCapMs?: number\n}\n\n/**\n * Build the sandbox-session coder delegate. It drives `runLoop` against the project's\n * sandbox client + coder profile; when `args.variants > 1` it switches to the multi-harness fanout\n * topology.\n *\n * This is the SANDBOX-SESSION coder path: workers run the in-box harness via the\n * `SandboxClient`'s `streamPrompt`, and single-variant turns can dispatch DETACHED\n * (driveTurn ticks) so a durable queue resumes them across an MCP restart — a substrate\n * the recursive worktree-CLI leaf does not yet have a journal-replay equivalent for.\n *\n * For NEW local-repo coding use `worktreeFanout` / `worktreeLoopRunner` (author an `AgentProfile`\n * per harness → `createWorktreeCliExecutor` leaves → `gateOnDeliverable`). This delegate runs\n * held-stream by default and only its OPTIONAL cross-restart resume (the `driveTurn` tick) is opt-in\n * behind `MCP_ENABLE_DETACHED_RESUME`.\n *\n * @experimental\n */\nexport function detachedSessionDelegate(options: DetachedSessionDelegateOptions): CoderDelegate {\n const executor = resolveExecutor(options)\n const sandboxClient = executor.client\n const fanoutHarnesses = options.fanoutHarnesses\n const maxConcurrency = options.maxConcurrency ?? 4\n const traceEmitter = options.traceEmitter\n return async (args, ctx) => {\n const task = coderTaskFromArgs(args)\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n const loopEmitter = composeLoopTraceEmitters(traceEmitter, ctx.traceEmitter)\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const agentRunSpec = coderRunSpec({\n ...(options.workerProfile ? { profile: options.workerProfile } : {}),\n ...(options.harness ? { harness: options.harness } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...(options.systemPrompt ? { systemPrompt: options.systemPrompt } : {}),\n })\n const output = coderOutputAdapter\n const validator = createCoderValidator(task)\n // Detached dispatch: one session on one box, driven by `driveTurn` ticks\n // instead of a held stream, so the run survives an MCP-process restart\n // (the resume driver re-attaches via the persisted ref). Only the\n // single-variant path detaches — fanout needs N sessions + winner\n // selection over every candidate, which one resume key cannot express.\n if (ctx.detachedSessionRef !== undefined && ctx.updateDetachedSessionRef) {\n const { sessionId } = parseDetachedSessionRef(ctx.detachedSessionRef)\n const rebind = ctx.updateDetachedSessionRef\n const turn = await runDetachedTurn({\n client: sandboxClient,\n spec: agentRunSpec as AgentRunSpec<unknown>,\n prompt: agentRunSpec.taskToPrompt(task),\n sessionId,\n bindSandbox: (sandboxId) => rebind(formatDetachedSessionRef({ sandboxId, sessionId })),\n signal: ctx.signal,\n report: ctx.report,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n ...(executor.placement === 'fleet' ? { placement: 'fleet' as const } : {}),\n ...(options.detachedTickIntervalMs !== undefined\n ? { tickIntervalMs: options.detachedTickIntervalMs }\n : {}),\n ...(options.detachedWallCapMs !== undefined\n ? { wallCapMs: options.detachedWallCapMs }\n : {}),\n })\n const chosen = await settleDetachedCoderTurn(turn, {\n task,\n sessionId,\n signal: ctx.signal,\n ...(options.harness ? { harness: options.harness } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n })\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const result = await runLoop({\n driver: singleShotDriver,\n agentRun: agentRunSpec,\n output,\n validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: 1,\n maxConcurrency,\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: 1, phase: 'completed' })\n return chosen\n }\n const fanout = multiHarnessCoderFanout({\n ...(options.workerProfile ? { profile: options.workerProfile } : {}),\n ...(fanoutHarnesses && fanoutHarnesses.length > 0\n ? { harnesses: fanoutHarnesses.slice(0, variants) }\n : {}),\n ...(options.fanoutModels ? { models: options.fanoutModels.slice(0, variants) } : {}),\n })\n const agentRuns = fanout.agentRuns.slice(0, variants)\n const result = await runLoop({\n driver: fanout.driver,\n agentRuns,\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: {\n sandboxClient,\n signal: ctx.signal,\n ...(loopEmitter ? { traceEmitter: loopEmitter } : {}),\n },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const chosen = await pickCoderWinner({\n iterations: result.iterations,\n reviewer: options.reviewer,\n selection: options.winnerSelection ?? 'highest-score',\n task,\n signal: ctx.signal,\n })\n if (!chosen) throw new Error(noWinnerMessage(options.reviewer))\n ctx.report({ iteration: agentRuns.length, phase: 'completed' })\n return chosen\n }\n}\n\ninterface PickCoderWinnerArgs {\n iterations: ReadonlyArray<Iteration<CoderTask, CoderOutput>>\n reviewer: CoderReviewer | undefined\n selection: DetachedWinnerSelection\n task: CoderTask\n signal: AbortSignal\n}\n\n/** A valid (and, when a reviewer is wired, approved) candidate kept for selection. */\ninterface EligibleCandidate {\n iter: Iteration<CoderTask, CoderOutput>\n /** Reviewer readiness (defaults to the verdict score when no reviewer ran). */\n readiness: number\n}\n\n/**\n * Pick the winning coder candidate from a finished loop's iterations:\n * 1. keep only mechanically-VALID candidates (the validator already gated\n * tests/typecheck/forbidden/diff/no-op/secrets),\n * 2. if a `reviewer` is wired, keep only those it APPROVES,\n * 3. select among survivors via the shared `selectValidWinner` (base strategies) or, for the\n * reviewer-only `highest-readiness`, a readiness sort (the one strategy the generic selector\n * does not express — a documented capability of this sandbox-session path).\n * Returns `undefined` when nothing survives — the delegate fails loud.\n */\nasync function pickCoderWinner(args: PickCoderWinnerArgs): Promise<CoderOutput | undefined> {\n const eligible: EligibleCandidate[] = []\n for (const iter of args.iterations) {\n if (iter.output === undefined || iter.error || iter.verdict?.valid !== true) continue\n const readiness = iter.verdict.score ?? 0\n if (args.reviewer) {\n const review = await args.reviewer(iter.output, args.task, { signal: args.signal })\n if (!review.approved) continue\n eligible.push({ iter, readiness: review.readiness })\n } else {\n eligible.push({ iter, readiness })\n }\n }\n if (eligible.length === 0) return undefined\n\n // `highest-readiness` ranks on the reviewer's readiness — a reviewer-only metric the generic\n // valid-only selector does not carry. Ties → earliest iteration.\n if (args.selection === 'highest-readiness') {\n const sorted = [...eligible].sort(\n (a, b) => b.readiness - a.readiness || a.iter.index - b.iter.index,\n )\n return sorted[0]!.iter.output\n }\n\n // Base strategies route through the SHARED valid-only selector. Wrap each survivor's raw\n // `CoderOutput` in the `Outcome<D>` shape `selectValidWinner` reads, preserving verdict/index.\n const wrapped: Iteration<unknown, Outcome<CoderOutput>>[] = eligible.map(({ iter }) => ({\n ...iter,\n output: { kind: 'done', deliverable: iter.output as CoderOutput },\n }))\n const winner = selectValidWinner<CoderOutput>({\n strategy: baseStrategy(args.selection),\n sizeOf: (o) => o.diffStats.insertions + o.diffStats.deletions,\n })(wrapped)\n const out = winner?.output\n if (!out || out.kind !== 'done') return undefined\n return out.deliverable\n}\n\n/** Map the detached-session selection enum onto the shared `WinnerStrategy`. `first-approved`\n * reduces to `first-valid` over the already-approved set; `smallest-diff` to `smallest-artifact`. */\nfunction baseStrategy(\n selection: Exclude<DetachedWinnerSelection, 'highest-readiness'>,\n): WinnerStrategy {\n switch (selection) {\n case 'smallest-diff':\n return 'smallest-artifact'\n case 'first-approved':\n return 'first-valid'\n default:\n return 'highest-score'\n }\n}\n\nfunction noWinnerMessage(reviewer: CoderReviewer | undefined): string {\n return reviewer\n ? 'coder delegate: no candidate passed validation + review'\n : 'coder delegate: no candidate passed validation'\n}\n\n/**\n * Canonical `DelegateCodeArgs` → `CoderTask` mapping — the single source for\n * the delegate's live dispatch AND the resume driver's settle/message\n * rebuilding, so a resumed record reproduces exactly the task the original\n * process dispatched.\n *\n * @experimental\n */\nexport function coderTaskFromArgs(args: DelegateCodeArgs): CoderTask {\n return {\n goal: buildCoderGoal(args),\n repoRoot: args.repoRoot,\n testCmd: args.config?.testCmd,\n typecheckCmd: args.config?.typecheckCmd,\n forbiddenPaths: args.config?.forbiddenPaths,\n maxDiffLines: args.config?.maxDiffLines,\n }\n}\n\n/** @experimental */\nexport interface SettleDetachedCoderTurnOptions {\n task: CoderTask\n /** Session id of the detached turn — used as the synthesized event id. */\n sessionId: string\n signal: AbortSignal\n harness?: string\n model?: string\n /** Same gate as the streaming path: an unapproved candidate cannot win. */\n reviewer?: CoderReviewer\n}\n\n/**\n * Settle a completed detached coder turn through the same gate the streaming\n * path applies: parse the terminal payload with the coder output adapter,\n * run the mechanical validator (tests/typecheck/forbidden/diff/no-op/secrets),\n * then the optional reviewer. Throws when nothing survives — a resumed or\n * detached run must not return an unvalidated patch.\n *\n * SCOPE NOTE (detached/resume): the detached `driveTurn`-tick + cross-restart resume path is\n * bound to the `runLoop` + sandbox-session substrate. The recursive `Scope`/worktree-CLI leaf has\n * journal→replay but no driveTurn-over-a-detached-sandbox-session equivalent yet, so resume is NOT\n * advertised on the generic `worktreeFanout` path. This helper (with `coderTaskFromArgs` and\n * `createDetachedTurnResumeDriver`) stays as the resume seam `bin.ts` wires for in-flight records.\n *\n * @experimental\n */\nexport async function settleDetachedCoderTurn(\n turn: DetachedTurn,\n options: SettleDetachedCoderTurnOptions,\n): Promise<CoderOutput> {\n const parsed = coderOutputAdapter.parse(detachedTurnEvents(options.sessionId, turn))\n const validator = createCoderValidator(options.task)\n const verdict = await validator.validate(parsed, { iteration: 0, signal: options.signal })\n if (verdict.valid !== true) throw new Error(noWinnerMessage(options.reviewer))\n if (options.reviewer) {\n const review = await options.reviewer(parsed, options.task, { signal: options.signal })\n if (!review.approved) throw new Error(noWinnerMessage(options.reviewer))\n }\n return parsed\n}\n\nfunction buildCoderGoal(args: DelegateCodeArgs): string {\n if (!args.contextHint) return args.goal\n return [args.goal, '', '## Context', args.contextHint].join('\\n')\n}\n\nfunction resolveExecutor(options: DetachedSessionDelegateOptions): DelegationExecutor {\n if (options.executor && options.sandboxClient) {\n throw new Error('detachedSessionDelegate: pass exactly one of `executor` or `sandboxClient`')\n }\n if (options.executor) return options.executor\n if (options.sandboxClient) {\n return createSiblingSandboxExecutor({ client: options.sandboxClient })\n }\n throw new Error('detachedSessionDelegate: `executor` or `sandboxClient` is required')\n}\n\n/**\n * Single-shot driver — plan one task on iteration 0, stop after one\n * iteration. Used by the coder delegate when `variants <= 1`. Keeps the\n * runLoop kernel-level accounting (timing, cost, trace emission) while\n * skipping fanout/refine topology overhead.\n */\nconst singleShotDriver = {\n name: 'mcp-single-shot',\n async plan<Task>(task: Task, history: ReadonlyArray<unknown>): Promise<Task[]> {\n return history.length === 0 ? [task] : []\n },\n decide(history: ReadonlyArray<unknown>): 'pick-winner' | 'fail' {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n}\n","/**\n *\n * The trace-analyst KIND directory — the operator's lenses, as composable DATA.\n *\n * An analyst is not one question. A kind is ONE lens (completeness, correctness, policy, efficiency,\n * tool-use, …); each emits `AnalystFinding`s tagged by its `area`. The driver `list_analysts` to see\n * the menu, `run_analyst(kind, worker)` to apply a lens, and `define_analyst` to author a new one —\n * so at test time you compose the exact lenses a domain needs (maximum specificity), not one generic\n * reviewer. The kinds are data, the runner is generic, and the finding shape + firewall are reused\n * from agent-eval / the keystone — never re-derived.\n *\n * A kind here is a lightweight lens (`Check`); it is a deliberate SUBSET of agent-eval's full\n * `TraceAnalystKindSpec`, so a kind that needs the heavy agentic actor (sub-agent recursion, tools,\n * goldens) upgrades to `createTraceAnalystKind` without changing this directory's surface.\n *\n * @experimental\n */\n\nimport {\n type AnalystFinding,\n type AnalystSeverity,\n type EvidenceRef,\n makeFinding,\n} from '@tangle-network/agent-eval'\nimport { assertTraceDerivedFindings } from '../../runtime'\n\n// agent-eval's root entry exports the lift (`makeFinding`) + the `AnalystFinding`/`EvidenceRef` shapes\n// but NOT the raw-row validator / schema prompt (kind-factory-internal). We inline a minimal,\n// equivalent pair so a lens emits the SAME finding shape without reaching into an unstable internal.\nconst ANALYST_SEVERITIES = ['critical', 'high', 'medium', 'low', 'info'] as const\n\nconst FINDING_SCHEMA_PROMPT = [\n 'Each finding is a JSON object with these fields:',\n '- severity: one of \"critical\" | \"high\" | \"medium\" | \"low\" | \"info\"',\n '- claim: one-sentence statement',\n '- evidence_uri: REQUIRED, never blank — exactly one of \"span://<trace>/<span>\", \"artifact://<path>\",',\n ' or \"metric://<name>\"; ALWAYS cite a real id from the trace. No citable id ⇒ omit the finding.',\n '- evidence_excerpt?: a short quote from the cited evidence',\n '- confidence: number 0..1',\n '- rationale?: one sentence of reasoning',\n '- recommended_action?: a concrete imperative (\"Add ...\", \"Replace ...\", \"Stop ...\")',\n 'Emit an empty array when there is nothing to report. Never fabricate evidence.',\n].join('\\n')\n\ninterface RawRow {\n severity: AnalystSeverity\n claim: string\n evidence_uri: string\n confidence: number\n evidence_excerpt?: string\n rationale?: string\n recommended_action?: string\n subject?: string\n}\n\n/** Validate one raw finding row (the lightweight equivalent of agent-eval's `parseRawFinding`):\n * require a claim + a real trace evidence_uri; drop anything else. Returns null to discard. */\nfunction validateRawFinding(row: unknown): RawRow | null {\n if (!row || typeof row !== 'object') return null\n const r = row as Record<string, unknown>\n if (typeof r.claim !== 'string' || r.claim.length === 0) return null\n if (typeof r.evidence_uri !== 'string' || !/^(span|artifact|metric):\\/\\//.test(r.evidence_uri))\n return null\n const sev = (ANALYST_SEVERITIES as readonly string[]).includes(r.severity as string)\n ? (r.severity as AnalystSeverity)\n : 'medium'\n return {\n severity: sev,\n claim: r.claim,\n evidence_uri: r.evidence_uri,\n confidence: typeof r.confidence === 'number' ? r.confidence : 0.5,\n ...(typeof r.evidence_excerpt === 'string' ? { evidence_excerpt: r.evidence_excerpt } : {}),\n ...(typeof r.rationale === 'string' ? { rationale: r.rationale } : {}),\n ...(typeof r.recommended_action === 'string'\n ? { recommended_action: r.recommended_action }\n : {}),\n ...(typeof r.subject === 'string' ? { subject: r.subject } : {}),\n }\n}\n\n/** One lens — a composable analyst kind. Identity fields mirror `TraceAnalystKindSpec` so a kind is\n * upgradeable to the full agentic factory; `lookFor` is the lens question the actor applies. */\nexport interface Check {\n readonly id: string\n readonly description: string\n /** Coarse classification stamped on every finding this kind emits (the renderer groups by it). */\n readonly area: string\n readonly version: string\n /** The lens — what this analyst looks for in the trace. */\n readonly lookFor: string\n}\n\n/** The built-in lens directory. Domain-blind (about any agent trace); compose at test time. */\nexport const defaultChecks: Record<string, Check> = {\n completeness: {\n id: 'completeness',\n description: 'Required work the trace does not yet show done or verified.',\n area: 'failure-mode',\n version: '1',\n lookFor:\n 'every change the task requires that the trace does NOT yet show completed AND verified by a ' +\n 'tool result. One finding per missing/unverified requirement.',\n },\n correctness: {\n id: 'correctness',\n description: 'Tool calls that produced wrong, erroring, or contradicted results.',\n area: 'correctness',\n version: '1',\n lookFor:\n 'tool calls whose RESULT shows an error, a wrong value, or contradicts what the task required ' +\n '(e.g. set the wrong field, value did not take, an error was ignored).',\n },\n policy: {\n id: 'policy',\n description: 'Actions that violate a stated policy, constraint, or allow-list.',\n area: 'safety',\n version: '1',\n lookFor:\n 'actions in the trace that violate a policy/constraint stated in the task or system prompt ' +\n '(forbidden tool, missing approval, out-of-scope mutation, skipped precondition).',\n },\n efficiency: {\n id: 'efficiency',\n description: 'Wasted, redundant, or looping work.',\n area: 'cost',\n version: '1',\n lookFor:\n 'redundant or wasted actions — repeated identical calls, a stalled line retried the same way, ' +\n 'work that produced no progress toward the goal.',\n },\n 'tool-use': {\n id: 'tool-use',\n description: 'Malformed or misused tool calls.',\n area: 'tool-use',\n version: '1',\n lookFor:\n 'tool calls with malformed/invalid arguments, the wrong tool for the intent, or a tool used ' +\n 'against its contract — judged from the call + its result.',\n },\n}\n\n/** Lift validated raw rows into `AnalystFinding`s (agent-eval `makeFinding` stamps `finding_id`/\n * `produced_at`), then enforce the trace-derived firewall (selector ≠ judge). Pure — no LLM. */\nexport function liftFindings(kind: Check, rows: unknown[], producedAt: string): AnalystFinding[] {\n const findings: AnalystFinding[] = []\n for (const row of rows) {\n const raw = validateRawFinding(row)\n if (!raw) continue\n findings.push(\n makeFinding({\n analyst_id: kind.id,\n area: kind.area,\n severity: raw.severity,\n claim: raw.claim,\n confidence: raw.confidence,\n produced_at: producedAt,\n evidence_refs: evidenceRefs(raw.evidence_uri, raw.evidence_excerpt),\n ...(raw.rationale ? { rationale: raw.rationale } : {}),\n ...(raw.recommended_action ? { recommended_action: raw.recommended_action } : {}),\n ...(raw.subject ? { subject: raw.subject } : {}),\n metadata: { kind_version: kind.version },\n }),\n )\n }\n assertTraceDerivedFindings(findings) // throws if a finding cites judge/verdict/score evidence\n return findings\n}\n\n/** Map a raw `evidence_uri` (span:// | artifact:// | metric://<name>) to a typed `EvidenceRef`. A\n * metric ref carries the bare NAME (the firewall checks the metric name for judge/verdict/score —\n * so a finding that cites a judge metric is rejected as not trace-derived). */\nfunction evidenceRefs(uri: string, excerpt?: string): EvidenceRef[] {\n const scheme = uri.split('://', 1)[0]\n if (scheme === 'metric')\n return [\n { kind: 'metric', uri: uri.replace(/^metric:\\/\\//, ''), ...(excerpt ? { excerpt } : {}) },\n ]\n const kind: EvidenceRef['kind'] = scheme === 'span' ? 'span' : 'artifact'\n return [{ kind, uri, ...(excerpt ? { excerpt } : {}) }]\n}\n\n/** Render a worker's trace (tool calls + results) into the text an analyst lens reads. Generic over\n * the trace shape: a `{ messages }` conversation, a bare message array, else stringified. */\nexport function renderTrace(trace: unknown): string {\n const messages = Array.isArray(trace)\n ? trace\n : trace &&\n typeof trace === 'object' &&\n Array.isArray((trace as { messages?: unknown[] }).messages)\n ? (trace as { messages: unknown[] }).messages\n : undefined\n if (!messages) return JSON.stringify(trace ?? {}).slice(0, 8000)\n return messages\n .map((m) => {\n const r = m as {\n role?: string\n content?: unknown\n tool_calls?: Array<{ function?: { name?: string; arguments?: string } }>\n }\n if (r.role === 'tool') return `RESULT ${String(r.content).slice(0, 300)}`\n const calls = r.tool_calls\n ?.map((c) => `${c.function?.name}(${c.function?.arguments})`)\n .join(', ')\n return calls ? `CALL ${calls}` : `SAY ${String(r.content ?? '').slice(0, 200)}`\n })\n .join('\\n')\n .slice(0, 8000)\n}\n\nexport interface CheckRunnerOptions {\n routerBaseUrl: string\n routerKey: string\n model: string\n /** Test/override seam — replace the LLM call. Default: a router chat completion. */\n chat?: (system: string, user: string) => Promise<string>\n}\n\n/** Run ONE lens over a trace → findings. Generic over any kind: prompt = the lens + the agent-eval\n * finding schema; the model's JSON array is parsed (`parseRawFinding`), lifted, and firewalled. */\nexport async function runCheck(\n kind: Check,\n trace: unknown,\n opts: CheckRunnerOptions,\n producedAt: string,\n): Promise<AnalystFinding[]> {\n const sys =\n `You are a trace analyst applying ONE lens: look for ${kind.lookFor}\\n\\n` +\n `${FINDING_SCHEMA_PROMPT}\\n\\nReturn ONLY a fenced \\`\\`\\`json array of finding objects (possibly empty).`\n const user = `WORKER TRACE:\\n${renderTrace(trace)}\\n\\nApply your lens and emit the findings array.`\n const chat = opts.chat ?? defaultChat(opts)\n const content = await chat(sys, user)\n const match = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n let rows: unknown[] = []\n try {\n const parsed = JSON.parse((match?.[1] ?? content).trim())\n rows = Array.isArray(parsed)\n ? parsed\n : Array.isArray((parsed as { findings?: unknown[] })?.findings)\n ? (parsed as { findings: unknown[] }).findings\n : []\n } catch {\n rows = []\n }\n return liftFindings(kind, rows, producedAt)\n}\n\nfunction defaultChat(opts: CheckRunnerOptions): (system: string, user: string) => Promise<string> {\n return async (system, user) => {\n const res = await fetch(`${opts.routerBaseUrl.replace(/\\/$/, '')}/chat/completions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${opts.routerKey}` },\n body: JSON.stringify({\n model: opts.model,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n temperature: 0.3,\n }),\n })\n if (!res.ok) throw new Error(`analyst router ${res.status}`)\n const data = (await res.json()) as { choices?: Array<{ message?: { content?: string } }> }\n return data.choices?.[0]?.message?.content ?? ''\n }\n}\n\n/**\n * Build a `run_analyst` runner over a kind directory.\n * Returns findings, or a typed error for an unknown kind. `producedAt` is\n * passed in because replay-safe paths must not read `Date.now`.\n */\nexport function makeCheckRunner(\n kinds: Record<string, Check>,\n opts: CheckRunnerOptions,\n): (\n kindId: string,\n trace: unknown,\n producedAt: string,\n) => Promise<AnalystFinding[] | { error: string }> {\n return async (kindId, trace, producedAt) => {\n const kind = kinds[kindId]\n if (!kind)\n return {\n error: `unknown analyst kind ${JSON.stringify(kindId)} (have: ${Object.keys(kinds).join(', ')})`,\n }\n return runCheck(kind, trace, opts, producedAt)\n }\n}\n"],"mappings":"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","names":["text","chosen","result"]}