@tangle-network/agent-runtime 0.271.0 → 0.273.3

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 (67) hide show
  1. package/dist/{activation-DGbFPGR3.js → activation-Cx2dKA_l.js} +2 -2
  2. package/dist/{activation-DGbFPGR3.js.map → activation-Cx2dKA_l.js.map} +1 -1
  3. package/dist/{activation-BrJmwTLB.d.ts → activation-IfDlhR3J.d.ts} +2 -2
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/candidate-execution/index.js +2 -2
  7. package/dist/{coordination-driver-iBGMKDvB.js → coordination-driver-CkcW4dxU.js} +155 -80
  8. package/dist/coordination-driver-CkcW4dxU.js.map +1 -0
  9. package/dist/{delegate-DOqUvaIz.js → delegate-Dvb1-mE-.js} +2 -2
  10. package/dist/{delegate-DOqUvaIz.js.map → delegate-Dvb1-mE-.js.map} +1 -1
  11. package/dist/durable.d.ts +3 -572
  12. package/dist/durable.js +92 -18
  13. package/dist/durable.js.map +1 -1
  14. package/dist/{graph-DnMcepkN.js → graph-C69Uxtzt.js} +14 -8
  15. package/dist/graph-C69Uxtzt.js.map +1 -0
  16. package/dist/{improvement-cycle-1IyRJo5h.js → improvement-cycle-CO2HRCQq.js} +4 -4
  17. package/dist/{improvement-cycle-1IyRJo5h.js.map → improvement-cycle-CO2HRCQq.js.map} +1 -1
  18. package/dist/{index-CL1dduJd.d.ts → index-D2ipSqkP.d.ts} +4318 -3102
  19. package/dist/index.d.ts +6 -450
  20. package/dist/index.js +14 -11
  21. package/dist/index.js.map +1 -1
  22. package/dist/intelligence.d.ts +3 -3
  23. package/dist/intelligence.js +5 -5
  24. package/dist/kernel.d.ts +4 -4
  25. package/dist/kernel.js +9 -9
  26. package/dist/{loop-runner-bin-BPZ9tt1W.js → loop-runner-bin-B9MIq9O7.js} +3 -3
  27. package/dist/{loop-runner-bin-BPZ9tt1W.js.map → loop-runner-bin-B9MIq9O7.js.map} +1 -1
  28. package/dist/{loop-runner-bin-O_vM1w8Y.d.ts → loop-runner-bin-ThlwVkvo.d.ts} +3 -3
  29. package/dist/loop-runner-bin.d.ts +1 -1
  30. package/dist/loop-runner-bin.js +1 -1
  31. package/dist/mcp/bin.js +3 -3
  32. package/dist/mcp/index.d.ts +5 -5
  33. package/dist/mcp/index.js +4 -4
  34. package/dist/{openai-tools-DWHxpwx2.d.ts → openai-tools-Bb0mAr5z.d.ts} +2 -2
  35. package/dist/{prepare-oHUQdC5-.js → prepare-DVlvGP7V.js} +2 -2
  36. package/dist/{prepare-oHUQdC5-.js.map → prepare-DVlvGP7V.js.map} +1 -1
  37. package/dist/profiles.d.ts +2 -2
  38. package/dist/{protected-model-port-DqF0qDU6.js → protected-model-port-BrWgsCnl.js} +2 -2
  39. package/dist/{protected-model-port-DqF0qDU6.js.map → protected-model-port-BrWgsCnl.js.map} +1 -1
  40. package/dist/{protected-redaction--F3v1oo8.js → protected-redaction-DylCC_ot.js} +14 -20
  41. package/dist/protected-redaction-DylCC_ot.js.map +1 -0
  42. package/dist/{provision-supervisor-Cy8pqE95.js → provision-supervisor-BKAvsDtP.js} +3 -3
  43. package/dist/{provision-supervisor-Cy8pqE95.js.map → provision-supervisor-BKAvsDtP.js.map} +1 -1
  44. package/dist/{runtime-DVjIH1eo.js → runtime-CHxXrUeZ.js} +2079 -1441
  45. package/dist/runtime-CHxXrUeZ.js.map +1 -0
  46. package/dist/{server-CN9vzbSe.js → server-2OeFrEVG.js} +3 -3
  47. package/dist/{server-CN9vzbSe.js.map → server-2OeFrEVG.js.map} +1 -1
  48. package/dist/{stream-agent-turn-DbEsKgb_.d.ts → stream-agent-turn-ewm3BZAp.d.ts} +15 -16
  49. package/dist/{structural-rollout-I92sIfNl.js → structural-rollout-DCUprNpH.js} +2 -2
  50. package/dist/{structural-rollout-I92sIfNl.js.map → structural-rollout-DCUprNpH.js.map} +1 -1
  51. package/dist/{substrate-CbC03Vzo.d.ts → substrate-VKjmrksz.d.ts} +2 -2
  52. package/dist/{supervise-DJ_1i9vj.js → supervise-Dej5aSDa.js} +211 -48
  53. package/dist/supervise-Dej5aSDa.js.map +1 -0
  54. package/dist/{supervisor-Cvd5mf7x.js → supervisor-DdKPGluv.js} +952 -221
  55. package/dist/supervisor-DdKPGluv.js.map +1 -0
  56. package/dist/testing.d.ts +2 -2
  57. package/dist/testing.js +60 -60
  58. package/dist/tui/index.d.ts +1 -1
  59. package/dist/tui/index.js +1 -1
  60. package/dist/{types-Bo7z5aG5.d.ts → types-DMRc3jru.d.ts} +356 -64
  61. package/package.json +5 -5
  62. package/dist/coordination-driver-iBGMKDvB.js.map +0 -1
  63. package/dist/graph-DnMcepkN.js.map +0 -1
  64. package/dist/protected-redaction--F3v1oo8.js.map +0 -1
  65. package/dist/runtime-DVjIH1eo.js.map +0 -1
  66. package/dist/supervise-DJ_1i9vj.js.map +0 -1
  67. package/dist/supervisor-Cvd5mf7x.js.map +0 -1
@@ -15,6 +15,7 @@ import { applyWorkspacePlan, hashWorkspacePlan, materializeProfile, resolveAgent
15
15
  import { homedir, hostname, tmpdir } from "node:os";
16
16
  import { stripVTControlCharacters } from "node:util";
17
17
  import { ATTR, deriveHexId, isW3CSpanId, isW3CTraceId } from "@tangle-network/agent-trace-contract";
18
+ import { REDACTION_VERSION as REDACTION_VERSION$1, redact } from "@tangle-network/agent-eval/traces";
18
19
  import { SDKError, generateIdempotencyKey, withRetry } from "@tangle-network/agent-core";
19
20
  import { collectAgentFinalMessageText, collectAgentResponseText } from "@tangle-network/sandbox";
20
21
  import { request } from "node:http";
@@ -4797,7 +4798,7 @@ function sanitizeAgentRuntimeEvent(event, options = {}) {
4797
4798
  if (event.type === "questions_end") return {
4798
4799
  ...base,
4799
4800
  questions: event.questions.map((question) => sanitizeQuestion(question, options)),
4800
- userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
4801
+ userAnswers: options.includeUserAnswers ? included(event.userAnswers) : redactRecord(event.userAnswers)
4801
4802
  };
4802
4803
  if (event.type === "acquisition_start") return {
4803
4804
  ...base,
@@ -4845,7 +4846,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4845
4846
  ...withTask,
4846
4847
  timestamp: event.timestamp,
4847
4848
  questions: event.questions.map((question) => sanitizeQuestion(question, options)),
4848
- userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers)
4849
+ userAnswers: options.includeUserAnswers ? included(event.userAnswers) : redactRecord(event.userAnswers)
4849
4850
  };
4850
4851
  if (event.type === "acquisition_start") return {
4851
4852
  type: event.type,
@@ -4868,7 +4869,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4868
4869
  timestamp: event.timestamp,
4869
4870
  toolName: event.toolName,
4870
4871
  toolCallId: event.toolCallId,
4871
- args: options.includeControlPayloads ? event.args : void 0
4872
+ args: options.includeControlPayloads ? included(event.args) : void 0
4872
4873
  };
4873
4874
  if (event.type === "tool_result") return {
4874
4875
  type: event.type,
@@ -4877,7 +4878,7 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4877
4878
  timestamp: event.timestamp,
4878
4879
  toolName: event.toolName,
4879
4880
  toolCallId: event.toolCallId,
4880
- result: options.includeControlPayloads ? event.result : void 0
4881
+ result: options.includeControlPayloads ? included(event.result) : void 0
4881
4882
  };
4882
4883
  if (event.type === "llm_call") return {
4883
4884
  type: event.type,
@@ -4900,8 +4901,8 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4900
4901
  name: event.name,
4901
4902
  mimeType: event.mimeType,
4902
4903
  uri: options.includeEvidenceIds ? event.uri : void 0,
4903
- content: options.includeControlPayloads ? event.content : void 0,
4904
- metadata: options.includeMetadata ? event.metadata : void 0
4904
+ content: options.includeControlPayloads ? included(event.content) : void 0,
4905
+ metadata: options.includeMetadata ? included(event.metadata) : void 0
4905
4906
  };
4906
4907
  if (event.type === "proposal_created") return {
4907
4908
  type: event.type,
@@ -4909,16 +4910,16 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4909
4910
  ...withSession,
4910
4911
  timestamp: event.timestamp,
4911
4912
  proposalId: event.proposalId,
4912
- title: options.includeControlPayloads ? event.title : void 0,
4913
- content: options.includeControlPayloads ? event.content : void 0,
4913
+ title: options.includeControlPayloads ? included(event.title) : void 0,
4914
+ content: options.includeControlPayloads ? included(event.content) : void 0,
4914
4915
  status: event.status
4915
4916
  };
4916
4917
  if (event.type === "final") {
4917
4918
  const sanitizedError = event.error !== void 0 ? {
4918
4919
  kind: event.error.kind,
4919
- message: event.error.message,
4920
+ message: included(event.error.message),
4920
4921
  status: event.error.status,
4921
- body: options.includeControlPayloads ? event.error.body : void 0
4922
+ body: options.includeControlPayloads ? included(event.error.body) : void 0
4922
4923
  } : void 0;
4923
4924
  return {
4924
4925
  type: event.type,
@@ -4927,8 +4928,8 @@ function sanitizeRuntimeStreamEvent(event, options = {}) {
4927
4928
  timestamp: event.timestamp,
4928
4929
  status: event.status,
4929
4930
  reason: event.reason,
4930
- text: options.includeControlPayloads ? event.text : void 0,
4931
- metadata: options.includeMetadata ? event.metadata : void 0,
4931
+ text: options.includeControlPayloads ? included(event.text) : void 0,
4932
+ metadata: options.includeMetadata ? included(event.metadata) : void 0,
4932
4933
  ...sanitizedError !== void 0 ? { error: sanitizedError } : {}
4933
4934
  };
4934
4935
  }
@@ -4945,9 +4946,9 @@ function sanitizeTask(task, options) {
4945
4946
  id: task.id,
4946
4947
  intent: task.intent,
4947
4948
  domain: task.domain,
4948
- inputs: options.includeInputs ? task.inputs : task.inputs ? "[redacted]" : void 0,
4949
+ inputs: options.includeInputs ? included(task.inputs) : task.inputs ? "[redacted]" : void 0,
4949
4950
  requiredKnowledge: task.requiredKnowledge?.map((requirement) => sanitizeKnowledgeRequirement(requirement, options)),
4950
- metadata: options.includeMetadata ? task.metadata : task.metadata ? "[redacted]" : void 0
4951
+ metadata: options.includeMetadata ? included(task.metadata) : task.metadata ? "[redacted]" : void 0
4951
4952
  };
4952
4953
  }
4953
4954
  function sanitizeRuntimeSession(session, options) {
@@ -4958,7 +4959,7 @@ function sanitizeRuntimeSession(session, options) {
4958
4959
  hasResumeToken: Boolean(session.resumeToken),
4959
4960
  createdAt: session.createdAt,
4960
4961
  updatedAt: session.updatedAt,
4961
- metadata: options.includeMetadata ? session.metadata : session.metadata ? "[redacted]" : void 0
4962
+ metadata: options.includeMetadata ? included(session.metadata) : session.metadata ? "[redacted]" : void 0
4962
4963
  };
4963
4964
  }
4964
4965
  function sanitizeKnowledgeRequirement(requirement, options) {
@@ -5007,8 +5008,8 @@ function sanitizeControlStep(step, options) {
5007
5008
  index: step.index,
5008
5009
  decisionType: step.decision.type,
5009
5010
  reason: step.decision.reason,
5010
- action: options.includeControlPayloads && step.decision.type === "continue" ? step.decision.action : void 0,
5011
- result: options.includeControlPayloads && actionOutcome?.ok ? actionOutcome.result : void 0,
5011
+ action: options.includeControlPayloads && step.decision.type === "continue" ? included(step.decision.action) : void 0,
5012
+ result: options.includeControlPayloads && actionOutcome?.ok ? included(actionOutcome.result) : void 0,
5012
5013
  actionOk: actionOutcome?.ok,
5013
5014
  actionError: actionOutcome?.ok === false ? actionOutcome.error : void 0,
5014
5015
  durationMs: actionOutcome?.durationMs,
@@ -5041,10 +5042,17 @@ function summarizeEvals(evals, options) {
5041
5042
  score: evalResult.score,
5042
5043
  severity: evalResult.severity,
5043
5044
  objective: evalResult.objective,
5044
- detail: options.includeEvalDetails ? evalResult.detail : void 0,
5045
- evidence: options.includeEvalDetails ? evalResult.evidence : void 0
5045
+ detail: options.includeEvalDetails ? included(evalResult.detail) : void 0,
5046
+ evidence: options.includeEvalDetails ? included(evalResult.evidence) : void 0
5046
5047
  }));
5047
5048
  }
5049
+ /**
5050
+ * An opted-in payload still goes through agent-eval's redaction core: the
5051
+ * flags decide whether content is shared, never whether credentials are.
5052
+ */
5053
+ function included(value) {
5054
+ return value === void 0 ? value : redact(value).value;
5055
+ }
5048
5056
  function redactRecord(record) {
5049
5057
  return Object.fromEntries(Object.keys(record).map((key) => [key, "[redacted]"]));
5050
5058
  }
@@ -5058,7 +5066,7 @@ function pickPublicStreamFields(event) {
5058
5066
  } : void 0;
5059
5067
  return {
5060
5068
  backend: event.backend,
5061
- message: event.message,
5069
+ message: included(event.message),
5062
5070
  recoverable: event.recoverable,
5063
5071
  ...sanitizedError !== void 0 ? { error: sanitizedError } : {}
5064
5072
  };
@@ -5491,9 +5499,10 @@ function buildRuntimeEventOtelSpans(events, traceId, parentSpanId, options = {})
5491
5499
  "tangle.runtime.event": serialized(record)
5492
5500
  };
5493
5501
  let name = `tangle.runtime.${event.type}`;
5502
+ if (parentSpanId) attrs[ATTR.parentConfidence] = "explicit";
5494
5503
  if (event.type === "tool_call" || event.type === "tool_result") {
5495
5504
  name = `agent.${event.type}`;
5496
- attrs[ATTR.spanKind] = "TOOL";
5505
+ if (event.type === "tool_call") attrs[ATTR.spanKind] = "TOOL";
5497
5506
  attrs["tool.name"] = event.toolName;
5498
5507
  if (event.toolCallId) attrs["tool.call_id"] = event.toolCallId;
5499
5508
  const mcp = mcpIdentity(event.toolName);
@@ -5559,7 +5568,8 @@ function buildLoopOtelSpans(events, traceId, rootParentSpanId) {
5559
5568
  endTimeUnixNano: msToNs(node.endMs),
5560
5569
  attributes: toOtelAttributes({
5561
5570
  ...node.attrs,
5562
- [ATTR.spanKind]: LOOP_SPAN_KIND[node.kind]
5571
+ [ATTR.spanKind]: LOOP_SPAN_KIND[node.kind],
5572
+ ...node.parentSpanId === void 0 && rootParentSpanId ? { [ATTR.parentConfidence]: "explicit" } : {}
5563
5573
  }),
5564
5574
  status: { code: node.error ? 2 : 1 }
5565
5575
  }));
@@ -5630,10 +5640,15 @@ function buildLoopSpanNodes(events) {
5630
5640
  const iterStartTs = /* @__PURE__ */ new Map();
5631
5641
  const placementByIdx = /* @__PURE__ */ new Map();
5632
5642
  let currentRoundId;
5643
+ /** Plan round index → its span id, so an iteration joins the round it records (`groupId`). */
5644
+ const roundIdByIndex = /* @__PURE__ */ new Map();
5633
5645
  let pendingRound;
5634
5646
  const flushRound = (endMs) => {
5635
5647
  if (!pendingRound) return;
5636
- out.push(make(pendingRound.id, rootId, "loop.round", "round", pendingRound.start, endMs, pendingRound.attrs));
5648
+ out.push(make(pendingRound.id, rootId, "loop.round", "round", pendingRound.start, endMs, {
5649
+ ...pendingRound.attrs,
5650
+ [ATTR.parentConfidence]: "explicit"
5651
+ }));
5637
5652
  pendingRound = void 0;
5638
5653
  };
5639
5654
  for (const e of events) {
@@ -5661,6 +5676,7 @@ function buildLoopSpanNodes(events) {
5661
5676
  attrs
5662
5677
  };
5663
5678
  currentRoundId = id;
5679
+ roundIdByIndex.set(roundIdx, id);
5664
5680
  break;
5665
5681
  }
5666
5682
  case "loop.iteration.started": {
@@ -5707,6 +5723,8 @@ function buildLoopSpanNodes(events) {
5707
5723
  if (err) attrs["tangle.loop.error"] = err;
5708
5724
  const gid = num(p.groupId);
5709
5725
  if (gid !== void 0) attrs["tangle.loop.iteration.group_id"] = gid;
5726
+ const recordedRoundId = gid === void 0 ? void 0 : roundIdByIndex.get(gid);
5727
+ attrs[ATTR.parentConfidence] = recordedRoundId ? "explicit" : "heuristic";
5710
5728
  const par = num(p.parentIndex);
5711
5729
  if (par !== void 0) attrs["tangle.loop.iteration.parent_index"] = par;
5712
5730
  const dur = num(p.durationMs);
@@ -5714,7 +5732,7 @@ function buildLoopSpanNodes(events) {
5714
5732
  const preview = str(p.outputPreview);
5715
5733
  if (preview) attrs["tangle.loop.iteration.output_preview"] = preview;
5716
5734
  Object.assign(attrs, placementByIdx.get(idx) ?? {});
5717
- out.push(make(generateSpanId(), currentRoundId ?? rootId, "loop.iteration", "branch", start, e.timestamp, attrs, err !== void 0));
5735
+ out.push(make(generateSpanId(), recordedRoundId ?? currentRoundId ?? rootId, "loop.iteration", "branch", start, e.timestamp, attrs, err !== void 0));
5718
5736
  break;
5719
5737
  }
5720
5738
  case "loop.decision":
@@ -6055,11 +6073,11 @@ const HARNESS_ROOTS = Object.freeze({
6055
6073
  ]),
6056
6074
  codex: Object.freeze([".codex/sessions", ".codex/history.jsonl"]),
6057
6075
  opencode: Object.freeze([
6058
- ".local/share/opencode/storage",
6059
- ".local/share/opencode/export",
6060
- ".local/share/opencode/log",
6061
6076
  ".opencode/sessions",
6062
- ".opencode/messages"
6077
+ ".opencode/messages",
6078
+ ".local/share/opencode/export",
6079
+ ".local/share/opencode/storage",
6080
+ ".local/share/opencode/log"
6063
6081
  ]),
6064
6082
  pi: Object.freeze([".pi/agent/sessions"])
6065
6083
  });
@@ -6097,6 +6115,126 @@ function harnessTranscriptUnavailable(reason) {
6097
6115
  return unavailable$2(reason);
6098
6116
  }
6099
6117
  /**
6118
+ * Read one executor's harness-transcript receipt without letting a broken port escape.
6119
+ *
6120
+ * The three answers this has to keep apart, because #1214 and #1244 are both about an artifact
6121
+ * that reads as coverage without being coverage:
6122
+ * - `available` the transcript survived;
6123
+ * - a reason the CAPTURE produced a box existed and could not be read;
6124
+ * - `executor-exposes-no-transcript` this runtime has no transcript to offer at all;
6125
+ * - `execution-never-started` no environment was ever created (the executor's
6126
+ * own seed, set before `create`);
6127
+ * - `capture-did-not-run` the port answered nothing, so the capture was
6128
+ * skipped rather than attempted and failed.
6129
+ *
6130
+ * Mirrors the supervise scope's `readInteractiveSession`: an absence is always a named reason,
6131
+ * never `undefined`. The scope reads each child with it, and `supervise` reads the root with it.
6132
+ */
6133
+ function readHarnessTranscript(executor) {
6134
+ if (!executor.harnessTranscript) return harnessTranscriptUnavailable("executor-exposes-no-transcript");
6135
+ let reported;
6136
+ try {
6137
+ reported = executor.harnessTranscript();
6138
+ } catch {
6139
+ return harnessTranscriptUnavailable("executor-exposes-no-transcript");
6140
+ }
6141
+ if (reported === void 0) return harnessTranscriptUnavailable("capture-did-not-run");
6142
+ const capture = reported;
6143
+ if (capture.status === "captured" && capture.artifact) return capture;
6144
+ if (capture.status === "unavailable" && capture.reason) return capture;
6145
+ return harnessTranscriptUnavailable("executor-exposes-no-transcript");
6146
+ }
6147
+ /**
6148
+ * Bounds on the subagent export, per capture. The capture runs after every turn and again at
6149
+ * release, so they bound how long a turn's end or a teardown can wait on it; each session they
6150
+ * leave out is named in `skipped`.
6151
+ */
6152
+ const MAX_SUBAGENT_EXPORTS = 32;
6153
+ const SUBAGENT_EXPORT_SECONDS = 120;
6154
+ /** The script starts no export after SUBAGENT_EXPORT_SECONDS and bounds each one at 30 s, so it
6155
+ * ends inside this. It is passed to `exec`, because the Sandbox SDK's default is 30 s. */
6156
+ const SUBAGENT_EXPORT_EXEC_MS = 180 * 1e3;
6157
+ const SUBAGENT_EXPORT_DIR = "~/.local/share/opencode/export";
6158
+ /**
6159
+ * The export, run in the box. For each sidecar record it reads the runtime home and the parent
6160
+ * session, collects the subagent sessions its messages name, and writes `opencode export` of each
6161
+ * one under `export`, where the capture reads it. It prints one `<state> <sessionId>` line per
6162
+ * subagent: `exported`, `failed`, or `unexported` (over a bound), then `done`. Every capture exports again,
6163
+ * because a later turn can continue a subagent and the store changes with every turn; an export
6164
+ * takes about 2 s in a Tangle box. Each export goes to a temporary file first, so a failed or
6165
+ * interrupted export never leaves a partial file for the capture to read.
6166
+ */
6167
+ const SUBAGENT_EXPORT_SCRIPT = String.raw`cd "$HOME" 2>/dev/null || exit 0
6168
+ out="$HOME/.local/share/opencode/export"
6169
+ t=""; command -v timeout >/dev/null 2>&1 && t="timeout 30"
6170
+ start=$(date +%s); n=0
6171
+ for rec in .opencode/sessions/*.json; do
6172
+ [ -f "$rec" ] || continue
6173
+ h=$(sed -n 's/.*"providerSessionHome"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$rec" | head -n 1)
6174
+ p=$(sed -n 's/.*"providerSessionId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$rec" | head -n 1)
6175
+ db="$h/.local/share/opencode/opencode.db"
6176
+ case "$h" in /*) [ -f "$db" ] || continue ;; *) continue ;; esac
6177
+ ids=$(grep -rhoE '<task id=\\?"ses_[A-Za-z0-9]+|task_id: ses_[A-Za-z0-9]+|"sessionId"[[:space:]]*:[[:space:]]*"ses_[A-Za-z0-9]+' ".opencode/messages/$(basename "$rec" .json)" 2>/dev/null | grep -oE 'ses_[A-Za-z0-9]+' | sort -u)
6178
+ for id in $ids; do
6179
+ [ "$id" = "$p" ] && continue
6180
+ n=$((n + 1))
6181
+ if [ "$n" -gt ${MAX_SUBAGENT_EXPORTS} ] || [ $(($(date +%s) - start)) -ge ${SUBAGENT_EXPORT_SECONDS} ]; then echo "unexported $id"; continue; fi
6182
+ mkdir -p "$out" && tmp=$(mktemp) || { echo "failed $id"; continue; }
6183
+ if HOME="$h" XDG_DATA_HOME="$h/.local/share" XDG_CONFIG_HOME="$h/.config" XDG_STATE_HOME="$h/.local/state" XDG_CACHE_HOME="$h/.cache" OPENCODE_DISABLE_AUTOUPDATE=1 OPENCODE_DISABLE_MODELS_FETCH=1 $t opencode export "$id" > "$tmp" 2>/dev/null && [ -s "$tmp" ]; then
6184
+ mv "$tmp" "$out/$id.json" && echo "exported $id"
6185
+ else
6186
+ rm -f "$tmp"; echo "failed $id"
6187
+ fi
6188
+ done
6189
+ done
6190
+ echo done`;
6191
+ /**
6192
+ * Export each opencode subagent session a Tangle box's sidecar names, so the capture carries the
6193
+ * subagent's own steps (#1264).
6194
+ *
6195
+ * The sidecar runs opencode under a private runtime home and records the parent session under
6196
+ * `.opencode/sessions` and `.opencode/messages`. A `task` subagent runs in a child session, and
6197
+ * those records name it only in the tool's result (`<task id="ses_…">`, or `task_id: ses_…` on a
6198
+ * failure). Its steps are only in the runtime home's `opencode.db`, which a text capture cannot
6199
+ * carry. Each sidecar record names that home as `providerSessionHome`, so `opencode export` reads
6200
+ * the child from there. A shared-box worker exports its own subagents after each turn (#1371) and
6201
+ * keeps no sidecar record, so the export finds nothing to do for it.
6202
+ *
6203
+ * Returns the sessions it could not export, as `skipped` entries. An export that did not run, or
6204
+ * stopped before its `done` line, is named once, because the subagents it did not reach are
6205
+ * unknown.
6206
+ */
6207
+ async function exportSubagentSessions(environment, signal) {
6208
+ if (!environment.exec || signal?.aborted) return [];
6209
+ let stdout;
6210
+ try {
6211
+ stdout = (await environment.exec(SUBAGENT_EXPORT_SCRIPT, {
6212
+ timeoutMs: SUBAGENT_EXPORT_EXEC_MS,
6213
+ ...signal ? { signal } : {}
6214
+ })).stdout ?? "";
6215
+ } catch {
6216
+ return [{
6217
+ path: SUBAGENT_EXPORT_DIR,
6218
+ reason: "subagent-export-did-not-run"
6219
+ }];
6220
+ }
6221
+ const lines = stdout.split("\n").map((line) => line.trim());
6222
+ const gaps = [];
6223
+ for (const line of lines) {
6224
+ const match = /^(failed|unexported) (ses_[A-Za-z0-9]+)$/u.exec(line);
6225
+ if (match === null) continue;
6226
+ gaps.push({
6227
+ path: `${SUBAGENT_EXPORT_DIR}/${match[2]}.json`,
6228
+ reason: match[1] === "failed" ? "subagent-export-failed" : "subagent-export-over-bound"
6229
+ });
6230
+ }
6231
+ if (!lines.includes("done")) gaps.push({
6232
+ path: SUBAGENT_EXPORT_DIR,
6233
+ reason: "subagent-export-incomplete"
6234
+ });
6235
+ return gaps;
6236
+ }
6237
+ /**
6100
6238
  * Enumerate candidate transcript paths inside the environment.
6101
6239
  *
6102
6240
  * `find -printf` is given the roots and prints one `size<TAB>path` line per file. A missing root
@@ -6157,12 +6295,13 @@ async function captureHarnessTranscript(environment, harness, signal) {
6157
6295
  if (harness === void 0) return unavailable$2("unknown-harness");
6158
6296
  const roots = HARNESS_ROOTS[harness];
6159
6297
  if (!roots) return unavailable$2("unknown-harness");
6298
+ const unexported = harness === "opencode" ? await exportSubagentSessions(environment, signal) : [];
6160
6299
  const enumerated = await enumerate(environment, roots, signal);
6161
6300
  if (enumerated === void 0) return unavailable$2("enumeration-failed");
6162
6301
  const { paths } = enumerated;
6163
- if (paths.length === 0 && enumerated.omitted.length === 0) return unavailable$2("no-transcript");
6302
+ if (paths.length === 0 && enumerated.omitted.length === 0 && unexported.length === 0) return unavailable$2("no-transcript");
6164
6303
  const files = [];
6165
- const skipped = [...enumerated.omitted];
6304
+ const skipped = [...unexported, ...enumerated.omitted];
6166
6305
  let total = 0;
6167
6306
  for (const path of paths) {
6168
6307
  if (signal?.aborted) {
@@ -6236,6 +6375,73 @@ async function captureHarnessTranscript(environment, harness, signal) {
6236
6375
  });
6237
6376
  }
6238
6377
  /**
6378
+ * A transcript this process holds in memory, one JSON line per record, as a capture under the same
6379
+ * bounds a box's session files get: each file at most MAX_FILE_BYTES, all files together at most
6380
+ * MAX_TOTAL_BYTES. Lines fill `<name>-000.jsonl`, `<name>-001.jsonl`, ... in order, and a line is
6381
+ * never split. A line longer than one file, and every line past the total, is named in `skipped`
6382
+ * with its line number, so a cut transcript never reads as the whole one.
6383
+ */
6384
+ function harnessTranscriptFromLines(harness, name, lines) {
6385
+ if (lines.length === 0) return unavailable$2("no-transcript");
6386
+ const files = [];
6387
+ const skipped = [];
6388
+ let total = 0;
6389
+ let chunk = [];
6390
+ let chunkBytes = 0;
6391
+ const flush = () => {
6392
+ if (chunk.length === 0) return;
6393
+ const content = `${chunk.join("\n")}\n`;
6394
+ files.push(Object.freeze({
6395
+ path: `${name}-${String(files.length).padStart(3, "0")}.jsonl`,
6396
+ bytes: Buffer.byteLength(content, "utf8"),
6397
+ content
6398
+ }));
6399
+ chunk = [];
6400
+ chunkBytes = 0;
6401
+ };
6402
+ lines.forEach((line, index) => {
6403
+ const bytes = Buffer.byteLength(line, "utf8") + 1;
6404
+ const where = `${name} line ${index + 1}`;
6405
+ if (bytes > MAX_FILE_BYTES) {
6406
+ skipped.push({
6407
+ path: where,
6408
+ reason: "file-exceeds-byte-bound"
6409
+ });
6410
+ return;
6411
+ }
6412
+ if (total + bytes > MAX_TOTAL_BYTES) {
6413
+ skipped.push({
6414
+ path: where,
6415
+ reason: "total-byte-budget-exhausted"
6416
+ });
6417
+ return;
6418
+ }
6419
+ if (chunkBytes + bytes > MAX_FILE_BYTES) flush();
6420
+ chunk.push(line);
6421
+ chunkBytes += bytes;
6422
+ total += bytes;
6423
+ });
6424
+ flush();
6425
+ if (files.length === 0) return Object.freeze({
6426
+ status: "unavailable",
6427
+ reason: "nothing-carried",
6428
+ skipped: Object.freeze(skipped)
6429
+ });
6430
+ const artifact = Object.freeze({
6431
+ schemaVersion: 1,
6432
+ harness,
6433
+ files: Object.freeze(files),
6434
+ skipped: Object.freeze(skipped)
6435
+ });
6436
+ return Object.freeze({
6437
+ status: "captured",
6438
+ artifact,
6439
+ fileCount: files.length,
6440
+ totalBytes: total,
6441
+ skippedCount: skipped.length
6442
+ });
6443
+ }
6444
+ /**
6239
6445
  * Persist a capture under its own content ref and return the receipt a settlement carries.
6240
6446
  *
6241
6447
  * The scope calls this, not the executor: storage stays out of every provider and destroy site,
@@ -6391,81 +6597,40 @@ function publicCreateOptions(create) {
6391
6597
  }
6392
6598
  //#endregion
6393
6599
  //#region src/redact.ts
6394
- const redactedMarker = "[redacted]";
6395
- /** Secret-bearing key names: when an object key matches, its value is fully
6396
- * replaced regardless of the value's own content. Lowercased compare. */
6397
- const secretKeyPattern = /(api[-_]?key|secret|token|password|passwd|authorization|auth|private[-_]?key|credential|access[-_]?key|client[-_]?secret|session[-_]?(id|token)|cookie|bearer)/i;
6398
- /** AgentProfile's numeric model limits describe compute, not credentials. */
6399
- const tokenLimitKeyPattern = /^max(?:VisibleOutput|Reasoning|TotalOutput)Tokens$/;
6400
- /** In-value secret/PII patterns scrubbed from any string, regardless of key. */
6401
- const valuePatterns = [
6402
- /\bBearer\s+[A-Za-z0-9._\-+/=]{8,}/gi,
6403
- /\b(?:sk|pk|rk|ak)[-_][A-Za-z0-9_-]{12,}/g,
6404
- /\bgh[pousr]_[A-Za-z0-9]{20,}/g,
6405
- /\bAKIA[0-9A-Z]{16}\b/g,
6406
- /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
6407
- /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g
6408
- ];
6409
- /** Secret assignments embedded inside an otherwise opaque string, including
6410
- * serialized JSON and log-style `key=value` text. */
6411
- const secretAssignmentPattern = /((?:"|')?(?:api[-_]?key|secret|token|password|passwd|authorization|auth|private[-_]?key|credential|access[-_]?key|client[-_]?secret|session[-_]?(?:id|token)|cookie|bearer)(?:"|')?\s*[:=]\s*)(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;}]+)/gi;
6412
- /** Scrub a single string of in-value secret/PII patterns. */
6413
- function scrubString(input) {
6414
- let out = input;
6415
- for (const pattern of valuePatterns) out = out.replace(pattern, redactedMarker);
6416
- return out.replace(secretAssignmentPattern, `$1${redactedMarker}`);
6417
- }
6418
6600
  /**
6419
- * The built-in redactor. Walks objects and arrays; replaces values under
6420
- * secret-bearing keys wholesale; scrubs in-value patterns from every string.
6421
- * Cycle-safe (a seen-set short-circuits self-referential payloads to
6422
- * `'[circular]'`), depth-bounded, and total — never throws on customer input.
6601
+ * Redaction for values that may leave the Runtime process. The built-in
6602
+ * redactor is agent-eval's redaction core (`@tangle-network/agent-eval/traces`,
6603
+ * default profile): credentials found by field name or value shape are
6604
+ * replaced whole, email, card, SSN and phone values in place, and token counts
6605
+ * such as `inputTokens` or `max_tokens` are kept. A customer with
6606
+ * domain-specific PII supplies their own `redact` hook.
6607
+ *
6608
+ * This is narrower than `src/sanitize.ts`, which drops fields of the runtime's
6609
+ * *event envelope* unless the caller opts in: here the value is opaque customer
6610
+ * payload, so the scrub is value-shaped, not schema-shaped.
6611
+ *
6612
+ * @experimental
6613
+ */
6614
+ /**
6615
+ * The built-in redactor. Cycle-safe, depth-bounded and total: it never throws
6616
+ * on customer input and never mutates it.
6423
6617
  */
6424
6618
  function defaultRedactor(value) {
6425
- return walk(value, /* @__PURE__ */ new WeakSet(), 0);
6426
- }
6427
- const maxDepth = 32;
6428
- function walk(value, seen, depth) {
6429
- if (depth > maxDepth) return "[truncated]";
6430
- if (typeof value === "string") return scrubString(value);
6431
- if (value === null || typeof value !== "object") return value;
6432
- if (seen.has(value)) return "[circular]";
6433
- seen.add(value);
6434
- if (Array.isArray(value)) return value.map((item) => walk(item, seen, depth + 1));
6435
- const out = {};
6436
- for (const [key, v] of Object.entries(value)) {
6437
- const tokenLimit = tokenLimitKeyPattern.test(key) && typeof v === "number" && Number.isSafeInteger(v) && v >= 0;
6438
- if (secretKeyPattern.test(key) && !tokenLimit) {
6439
- out[key] = redactedMarker;
6440
- continue;
6441
- }
6442
- out[key] = walk(v, seen, depth + 1);
6443
- }
6444
- return out;
6619
+ return redact(value).value;
6445
6620
  }
6446
6621
  /** Stable identity input for saved work that depends on built-in redaction behavior. */
6447
6622
  function defaultRedactorIdentityMaterial() {
6448
- const patternIdentity = (pattern) => ({
6449
- source: pattern.source,
6450
- flags: pattern.flags
6451
- });
6452
6623
  return {
6453
- marker: redactedMarker,
6454
- secretKeyPattern: patternIdentity(secretKeyPattern),
6455
- tokenLimitKeyPattern: patternIdentity(tokenLimitKeyPattern),
6456
- valuePatterns: valuePatterns.map(patternIdentity),
6457
- secretAssignmentPattern: patternIdentity(secretAssignmentPattern),
6458
- maxDepth,
6459
- scrubString: Function.prototype.toString.call(scrubString),
6460
- walk: Function.prototype.toString.call(walk),
6461
- defaultRedactor: Function.prototype.toString.call(defaultRedactor)
6624
+ core: "@tangle-network/agent-eval/traces redact",
6625
+ profile: "default",
6626
+ version: REDACTION_VERSION$1
6462
6627
  };
6463
6628
  }
6464
6629
  /**
6465
6630
  * Resolve the redactor a client uses. A caller-supplied hook handles
6466
6631
  * domain-specific values first, then the built-in scrubber still removes
6467
- * common credentials and email addresses. Returning `false` is the explicit
6468
- * opt-out for already-reviewed public values.
6632
+ * credentials and personal data. Returning `false` is the explicit opt-out for
6633
+ * already-reviewed public values.
6469
6634
  */
6470
6635
  function resolveRedactor(redact) {
6471
6636
  if (redact === false) return (value) => value;
@@ -9097,7 +9262,7 @@ async function providerExecutionSource(args, turn, signal) {
9097
9262
  const dispatched = [...admissions].reverse().find((admission) => admission.phase === "dispatched");
9098
9263
  const intent = admissions.find((admission) => admission.phase === "intent");
9099
9264
  const environmentAdmission = admissions.find((admission) => admission.phase === "environment");
9100
- if (args.recovering) {
9265
+ if (args.recovering && admissions.length > 0) {
9101
9266
  if (!intent) throw new Error("retained provider execution has no original intent");
9102
9267
  assertRetainedRunReplayMaterial(args.provider, material, intent);
9103
9268
  }
@@ -9145,7 +9310,7 @@ async function providerExecutionSource(args, turn, signal) {
9145
9310
  if (recovered.outcome !== "recovered") throw new Error(`retained provider execution is ${recovered.outcome}`);
9146
9311
  handle = recovered.handle;
9147
9312
  } else {
9148
- if (args.recovering) throw new Error("retained provider execution has no durable admission");
9313
+ if (args.recovering && admissions.length > 0) throw new Error("retained provider execution has no durable admission");
9149
9314
  handle = await startRetainedRun({
9150
9315
  provider: args.provider,
9151
9316
  ...material,
@@ -16786,6 +16951,15 @@ function assertContentAddress(outRef, artifact) {
16786
16951
  if (outRef !== expected) throw new Error(`blob outRef '${outRef}' does not match the artifact content hash '${expected}'; a content-addressed store refuses a mismatched ref (breaks the replay invariant)`);
16787
16952
  }
16788
16953
  /**
16954
+ * Append every event as one grouped publication where the journal supports it (`appendEvents`),
16955
+ * preserving legacy per-event appends otherwise — the SQL contexts' fenced head advances once.
16956
+ * @internal
16957
+ */
16958
+ async function appendSpawnEvents(journal, root, events) {
16959
+ if (journal.appendEvents !== void 0) return journal.appendEvents(root, events);
16960
+ for (const event of events) await journal.appendEvent(root, event);
16961
+ }
16962
+ /**
16789
16963
  * In-memory `SpawnJournal`. Appends are observed-committed only; the impl enforces
16790
16964
  * the corruption guards a durable replay rests on:
16791
16965
  * - an event before `beginTree` is a corrupted tree (fail loud),
@@ -17886,6 +18060,96 @@ function executionTaskPrompt$1(task, configuredPrompt) {
17886
18060
  return prompt;
17887
18061
  }
17888
18062
  //#endregion
18063
+ //#region src/runtime/supervise/router-transcript.ts
18064
+ /**
18065
+ * The conversation of a router-brained agent, kept as it happens.
18066
+ *
18067
+ * A router-brained agent (`harness` omitted or `cli-base`) runs its tool loop in this process, so
18068
+ * its whole conversation is in the loop's `messages` and nowhere else. Before this, Runtime
18069
+ * metered each turn's usage and tool-call names and kept nothing the agent said, saw, or asked a
18070
+ * tool to do: a 316-agent tree on 2026-09-24 settled with 0 of 316 transcripts, and the 37 agents
18071
+ * still running when its driver process stopped left no record at all (agent-runtime#1377).
18072
+ *
18073
+ * The recorder keeps each message once, in the order the model saw it, and serves two readers:
18074
+ * - each turn's `agent.turn` event carries the messages that turn added (the loop's inputs since
18075
+ * the previous turn, then the reply), so an observer journal holds every agent's conversation
18076
+ * while the run is live;
18077
+ * - `capture()` returns the whole conversation as a harness transcript, so the agent settles
18078
+ * with an `available` receipt instead of `executor-exposes-no-transcript`.
18079
+ *
18080
+ * The loop mutates `messages` in place: it appends the reply it was given, each tool result, and
18081
+ * any inbox message, and a compaction replaces the middle with a distilled note. The recorder
18082
+ * therefore reads new messages twice per turn, before compaction can remove them and again when
18083
+ * the model is called, and it identifies a message by object identity. The loop's own copy of a
18084
+ * reply is skipped, because the recorder already kept the reply when the model returned it.
18085
+ */
18086
+ /** The harness name a router-brained agent's transcript carries. */
18087
+ const ROUTER_TRANSCRIPT_HARNESS = "router";
18088
+ /**
18089
+ * The most bytes of one message's `content` a turn event carries. A longer content is cut, and
18090
+ * the message says so with its full length, so a reader never takes a cut message for the whole.
18091
+ * The settled transcript keeps the full content, within the bounds of `harnessTranscriptFromLines`.
18092
+ */
18093
+ const TURN_CONTENT_BYTES = 256 * 1024;
18094
+ function createRouterTranscript() {
18095
+ const kept = [];
18096
+ const seen = /* @__PURE__ */ new WeakSet();
18097
+ let turnStart = 0;
18098
+ let replyEchoPending = false;
18099
+ let live;
18100
+ const observe = (messages) => {
18101
+ live = messages;
18102
+ for (const message of messages) {
18103
+ if (message === null || typeof message !== "object" || seen.has(message)) continue;
18104
+ seen.add(message);
18105
+ if (replyEchoPending) {
18106
+ replyEchoPending = false;
18107
+ if (message.role === "assistant") continue;
18108
+ }
18109
+ kept.push(message);
18110
+ }
18111
+ };
18112
+ return {
18113
+ observe,
18114
+ reply(reply) {
18115
+ const message = {
18116
+ role: "assistant",
18117
+ content: reply.content ?? "",
18118
+ ...reply.toolCalls && reply.toolCalls.length > 0 ? { tool_calls: reply.toolCalls.map((call) => ({
18119
+ id: call.id,
18120
+ type: "function",
18121
+ function: {
18122
+ name: call.name,
18123
+ arguments: call.arguments
18124
+ }
18125
+ })) } : {}
18126
+ };
18127
+ kept.push(message);
18128
+ replyEchoPending = true;
18129
+ const added = kept.slice(turnStart).map(forTurnEvent);
18130
+ turnStart = kept.length;
18131
+ return added;
18132
+ },
18133
+ capture() {
18134
+ if (live !== void 0) observe(live);
18135
+ if (kept.length === 0) return harnessTranscriptUnavailable("execution-never-started");
18136
+ return harnessTranscriptFromLines(ROUTER_TRANSCRIPT_HARNESS, "conversation", kept.map((message) => JSON.stringify(message)));
18137
+ }
18138
+ };
18139
+ }
18140
+ function forTurnEvent(message) {
18141
+ const content = message.content;
18142
+ if (typeof content !== "string") return message;
18143
+ const bytes = Buffer.byteLength(content);
18144
+ if (bytes <= 262144) return message;
18145
+ return {
18146
+ ...message,
18147
+ content: Buffer.from(content).subarray(0, TURN_CONTENT_BYTES).toString("utf8"),
18148
+ contentBytes: bytes,
18149
+ contentCut: true
18150
+ };
18151
+ }
18152
+ //#endregion
17889
18153
  //#region src/runtime/supervise/sandbox-session.ts
17890
18154
  /** Ceiling on continuation turns. Turn 0 is the task; every later turn is a folded steer, so
17891
18155
  * this bounds how many times a supervisor may redirect ONE worker before it must respawn. */
@@ -18497,6 +18761,7 @@ const routerInlineExecutor = (spec, ctx) => {
18497
18761
  const requestIdentity = routerRequestIdentity(ctx);
18498
18762
  const controller = linkAbort(ctx.signal);
18499
18763
  let artifact;
18764
+ const transcript = createRouterTranscript();
18500
18765
  const executionId = ctx.node?.nodeId ?? `router-request-${randomUUID()}`;
18501
18766
  const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
18502
18767
  let executor;
@@ -18504,6 +18769,7 @@ const routerInlineExecutor = (spec, ctx) => {
18504
18769
  runtime: "router",
18505
18770
  async execute(task, signal) {
18506
18771
  const messages = taskToMessages(task, spec, profileExecution.systemPrompt);
18772
+ transcript.observe(messages);
18507
18773
  const started = Date.now();
18508
18774
  const linked = linkAbort(signal, controller.signal).signal;
18509
18775
  const extraBody = {
@@ -18541,6 +18807,10 @@ const routerInlineExecutor = (spec, ctx) => {
18541
18807
  ...requestIdentity
18542
18808
  }));
18543
18809
  if (r.model !== void 0) recordRuntimeOwnedProviderModel(executor, r.model);
18810
+ transcript.reply({
18811
+ content: r.content,
18812
+ toolCalls: "toolCalls" in r ? r.toolCalls : []
18813
+ });
18544
18814
  const spent = {
18545
18815
  ...addResourceSpend(r.resources),
18546
18816
  iterations: 1,
@@ -18576,6 +18846,7 @@ const routerInlineExecutor = (spec, ctx) => {
18576
18846
  };
18577
18847
  return artifact;
18578
18848
  },
18849
+ harnessTranscript: () => transcript.capture(),
18579
18850
  cancel(_request) {
18580
18851
  controller.abort("executor cancelled");
18581
18852
  return Promise.resolve(localAbortCancellation("the Router chat-completions API exposes no cancel operation; the local request was aborted and the provider may still bill the completion"));
@@ -18676,12 +18947,14 @@ const routerToolsInlineExecutor = (spec, ctx) => {
18676
18947
  const controller = linkAbort(ctx.signal);
18677
18948
  const inbox = createInbox();
18678
18949
  let artifact;
18950
+ const transcript = createRouterTranscript();
18679
18951
  const executionId = ctx.node?.nodeId ?? `router-tools-run-${randomUUID()}`;
18680
18952
  const attemptId = ctx.node?.attemptId ?? newExecutionAttemptId(executionId);
18681
18953
  let executor;
18682
18954
  executor = attestRuntimeOwnedExecutor({
18683
18955
  runtime: "router",
18684
18956
  deliver: (m) => inbox.deliver(m),
18957
+ harnessTranscript: () => transcript.capture(),
18685
18958
  async execute(task, signal) {
18686
18959
  const started = Date.now();
18687
18960
  const messages = seam.initialMessages ? taskToMessages({ messages: [...seam.initialMessages, {
@@ -18720,6 +18993,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
18720
18993
  interruptSig.addEventListener("abort", abortTurn, { once: true });
18721
18994
  const cleanup = () => external.removeEventListener("abort", abortTurn);
18722
18995
  let res;
18996
+ transcript.observe(messages);
18723
18997
  try {
18724
18998
  recordRuntimeOwnedProviderAttemptStart(executor);
18725
18999
  res = await (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)({
@@ -18756,6 +19030,10 @@ const routerToolsInlineExecutor = (spec, ctx) => {
18756
19030
  }
18757
19031
  cleanup();
18758
19032
  turns += 1;
19033
+ transcript.reply({
19034
+ content: res.content,
19035
+ toolCalls: res.toolCalls
19036
+ });
18759
19037
  const priorResources = resources;
18760
19038
  resources = addResourceSpend(resources, res.resources).resources;
18761
19039
  resources = addResourceSpend(Object.fromEntries(Object.entries(resources ?? {}).map(([name, value]) => [name, {
@@ -21315,7 +21593,7 @@ async function prepareInterruptedExecutors(opts, events, signal, now, parentId =
21315
21593
  continue;
21316
21594
  }
21317
21595
  const admissions = current.flatMap((event) => event.kind === "execution-admitted" ? [event.admission] : []);
21318
- if (!opts.recoverExecutor || admissions.length === 0 && !node.ownedTreeRoot) continue;
21596
+ if (!opts.recoverExecutor || admissions.length === 0 && !node.ownedTreeRoot && (opts.journal.appendEvents === void 0 || latestInput === void 0)) continue;
21319
21597
  const taskRef = inputs[0]?.taskRef;
21320
21598
  if (!node.profileRef || !taskRef || !node.identity?.profileDigest || !node.identity.taskDigest) throw new RuntimeRunStateError(`cannot recover '${node.id}' without exact profile and task bytes`);
21321
21599
  const profile = agentProfileSchema.parse(await opts.blobs.get(node.profileRef));
@@ -23415,29 +23693,31 @@ function createScope(args) {
23415
23693
  });
23416
23694
  const profileRef = contentAddress(spec.profile);
23417
23695
  const taskRef = identity?.taskDigest === void 0 ? void 0 : contentAddress(task);
23418
- const spawnCommitted = recovery ? Promise.resolve() : args.blobs.put(profileRef, spec.profile).then(() => taskRef === void 0 ? void 0 : args.blobs.put(taskRef, task)).then(() => args.journal.appendEvent(args.root, {
23419
- kind: "spawned",
23420
- id,
23421
- parent: args.parentId,
23422
- label: opts.label,
23423
- ...opts.key !== void 0 ? { key: opts.key } : {},
23424
- ...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
23425
- ...opts.successorOf === void 0 ? {} : { successorOf: opts.successorOf },
23426
- budget: opts.budget,
23427
- runtime: executor.runtime,
23428
- ...ownedTreeRoot === void 0 ? {} : { ownedTreeRoot },
23429
- ...identity ? { identity } : {},
23430
- profileRef,
23431
- seq: ordinal,
23432
- at: new Date(now()).toISOString()
23433
- })).then(async () => {
23434
- if (taskRef !== void 0) await args.journal.appendEvent(args.root, {
23696
+ const spawnCommitted = recovery ? Promise.resolve() : args.blobs.put(profileRef, spec.profile).then(() => taskRef === void 0 ? void 0 : args.blobs.put(taskRef, task)).then(async () => {
23697
+ const events = [{
23698
+ kind: "spawned",
23699
+ id,
23700
+ parent: args.parentId,
23701
+ label: opts.label,
23702
+ ...opts.key !== void 0 ? { key: opts.key } : {},
23703
+ ...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
23704
+ ...opts.successorOf === void 0 ? {} : { successorOf: opts.successorOf },
23705
+ budget: opts.budget,
23706
+ runtime: executor.runtime,
23707
+ ...ownedTreeRoot === void 0 ? {} : { ownedTreeRoot },
23708
+ ...identity ? { identity } : {},
23709
+ profileRef,
23710
+ seq: ordinal,
23711
+ at: new Date(now()).toISOString()
23712
+ }];
23713
+ if (taskRef !== void 0) events.push({
23435
23714
  kind: "execution-input",
23436
23715
  id,
23437
23716
  taskRef,
23438
23717
  seq: ordinal,
23439
23718
  at: new Date(now()).toISOString()
23440
23719
  });
23720
+ await appendSpawnEvents(args.journal, args.root, events);
23441
23721
  }).then(async () => {
23442
23722
  if (args.workerTraceUnpropagated === void 0 || workerTrace === void 0) return;
23443
23723
  await args.journal.appendEvent(args.root, {
@@ -23567,6 +23847,7 @@ function createScope(args) {
23567
23847
  childId: id,
23568
23848
  label: opts.label,
23569
23849
  ...opts.assignmentId === void 0 ? {} : { assignmentId: opts.assignmentId },
23850
+ ...opts.key === void 0 ? {} : { key: opts.key },
23570
23851
  ...opts.successorOf === void 0 ? {} : { successorOf: opts.successorOf },
23571
23852
  runtime: executor.runtime,
23572
23853
  ...identity ? { identity } : {},
@@ -24227,7 +24508,7 @@ async function recordScopeOwnerMaterialization(scope, runtime, declaration, bind
24227
24508
  /** @internal Kernel identity for constructing the exact deferred owner executor. */
24228
24509
  /**
24229
24510
  * @internal Each driver attempt of the scope owner is its own execution attempt. A driver retry
24230
- * after a failed drive, and the `repromptOnUnmet` re-entry after an unmet completion check, both
24511
+ * after a failed drive, and the continuation re-entry after an unmet completion check, both
24231
24512
  * run the harness again and report a new execution binding; the journal keys owner bindings by
24232
24513
  * attempt id, so every attempt after the first is given a fresh kernel-minted id and its
24233
24514
  * published flags are cleared, and the new binding lands beside the earlier ones. The first
@@ -25233,35 +25514,6 @@ function downRecord(reason, infra, trace, metered, providerModel, outRef, harnes
25233
25514
  ...outRef === void 0 ? {} : { outRef }
25234
25515
  };
25235
25516
  }
25236
- /**
25237
- * Read one executor's harness-transcript receipt without letting a broken port escape.
25238
- *
25239
- * The three answers this has to keep apart, because #1214 and #1244 are both about an artifact
25240
- * that reads as coverage without being coverage:
25241
- * - `available` the transcript survived;
25242
- * - a reason the CAPTURE produced a box existed and could not be read;
25243
- * - `executor-exposes-no-transcript` this runtime has no transcript to offer at all;
25244
- * - `execution-never-started` no environment was ever created (the executor's
25245
- * own seed, set before `create`);
25246
- * - `capture-did-not-run` the port answered nothing, so the capture was
25247
- * skipped rather than attempted and failed.
25248
- *
25249
- * Mirrors `readInteractiveSession` above: an absence is always a named reason, never `undefined`.
25250
- */
25251
- function readHarnessTranscript(executor) {
25252
- if (!executor.harnessTranscript) return harnessTranscriptUnavailable("executor-exposes-no-transcript");
25253
- let reported;
25254
- try {
25255
- reported = executor.harnessTranscript();
25256
- } catch {
25257
- return harnessTranscriptUnavailable("executor-exposes-no-transcript");
25258
- }
25259
- if (reported === void 0) return harnessTranscriptUnavailable("capture-did-not-run");
25260
- const capture = reported;
25261
- if (capture.status === "captured" && capture.artifact) return capture;
25262
- if (capture.status === "unavailable" && capture.reason) return capture;
25263
- return harnessTranscriptUnavailable("executor-exposes-no-transcript");
25264
- }
25265
25517
  /** The one place an absent interactive process is spelled, so every refusal reads the same. */
25266
25518
  function noInteractiveSession(reason) {
25267
25519
  return Object.freeze({
@@ -25681,6 +25933,493 @@ function unreportedSpend(total, prior) {
25681
25933
  };
25682
25934
  }
25683
25935
  //#endregion
25936
+ //#region src/runtime/supervise/continuation.ts
25937
+ /**
25938
+ * The continuation: what a manager with a completion check is told when its turn ends and the
25939
+ * check is unmet, and the one rule that decides whether it is sent back.
25940
+ *
25941
+ * Measured on discovery-lab before this module (2026-09-24, 670 settled runs, 1,596 re-entries):
25942
+ * 1,565 re-entries followed a failed turn and resent the original task, and 31 carried note text.
25943
+ * The note Runtime wrote itself held seven fixed lines and no field for the check's verdict. Of 40
25944
+ * episodes where the director ended on its own and the outside check disagreed, 33 were told
25945
+ * nothing before they ended. 100 of 236 resubmits sent the identical packet. So the director
25946
+ * mostly graded itself, and when it was wrong it heard nothing it could use.
25947
+ *
25948
+ * The design (discovery `docs/38-one-loop-and-continuation.md`) makes three things single, and
25949
+ * this module holds the part Runtime owns:
25950
+ *
25951
+ * - ONE CHECK. A check reading is a {@link CheckVerdict}: pass, the items it read, the composite,
25952
+ * and one `FAIL <item> <where>: <reason>` line per failed item. The same check decides
25953
+ * `submit_result`, runs when a turn ends without an accepted result, scores the finished run,
25954
+ * and ranks versions. A check that could not run gives no verdict ({@link CheckUnavailableError}),
25955
+ * and the loop pauses instead of blaming the director.
25956
+ * - ONE RESEND RULE. {@link ContinuationPolicy} is required for a manager with a check. It holds a
25957
+ * deadline and `maxBarren`, the re-entered turns in a row that may end without progress. There
25958
+ * is no re-prompt count and no default: a retry default in source is a research decision.
25959
+ * - ONE NOTE. {@link composeContinuationNote} writes it. Runtime owns the facts and their order;
25960
+ * the {@link ContinuationProfile} owns every instruction word, so an optimizer can change the
25961
+ * words without touching code. A play may append a section, never remove or rewrite one.
25962
+ *
25963
+ * Evidence behind the note's shape: located errors help (given the first mistake's true location,
25964
+ * fix rates rose 23.5 to 43.9 points, Tyen 2023); unsupported pressure does not (threats and tips
25965
+ * had no significant effect, Wharton 2025; challenges without evidence flipped correct answers,
25966
+ * FlipFlop); repeated summaries drop detail while itemized additions do not (ACE). So the note is
25967
+ * a list of located facts, findings are added and marked resolved rather than rewritten, and the
25968
+ * profile, not this file, decides how blunt the words are.
25969
+ */
25970
+ /**
25971
+ * The check could not run: its box did not start, its judge's provider refused, its program
25972
+ * crashed. It is not a verdict on the result. Inside a run the loop pauses, as it does for an
25973
+ * unavailable upstream, and the refusal tells the director its result was not judged.
25974
+ */
25975
+ var CheckUnavailableError = class extends Error {
25976
+ constructor(message, options) {
25977
+ super(message, options);
25978
+ this.name = "CheckUnavailableError";
25979
+ }
25980
+ };
25981
+ /** Read a check function's return value into a verdict. Anything but `true` or a passing verdict
25982
+ * is a failure: a check fails closed. */
25983
+ function checkVerdictOf(outcome) {
25984
+ if (outcome === true) return { pass: true };
25985
+ if (typeof outcome !== "object" || outcome === null || Array.isArray(outcome)) return { pass: false };
25986
+ const raw = outcome;
25987
+ const items = typeof raw.items === "object" && raw.items !== null && !Array.isArray(raw.items) ? Object.fromEntries(Object.entries(raw.items).filter((entry) => typeof entry[1] === "number" && Number.isFinite(entry[1]))) : void 0;
25988
+ const failures = Array.isArray(raw.failures) ? raw.failures.filter((line) => typeof line === "string" && line.trim() !== "") : void 0;
25989
+ return Object.freeze({
25990
+ pass: raw.pass === true,
25991
+ ...items === void 0 ? {} : { items: Object.freeze(items) },
25992
+ ...finite(raw.composite) ? { composite: raw.composite } : {},
25993
+ ...finite(raw.threshold) ? { threshold: raw.threshold } : {},
25994
+ ...failures === void 0 ? {} : { failures: Object.freeze(failures) },
25995
+ ...typeof raw.review === "string" && raw.review.trim() !== "" ? { review: raw.review.trim() } : {}
25996
+ });
25997
+ }
25998
+ /**
25999
+ * Read an agent-eval `JudgeScore` from a check program into a verdict.
26000
+ *
26001
+ * Each dimension is a checked item. `notes` lines that start with `FAIL ` are the failures; the
26002
+ * remaining lines are the check's review. The verdict passes when `composite >= threshold` and the
26003
+ * score is not marked `failed`; a `failed` score means the judge itself did not run, which is
26004
+ * {@link CheckUnavailableError}, not a verdict.
26005
+ */
26006
+ function verdictFromJudgeScore(score, threshold) {
26007
+ if (score.failed === true) throw new CheckUnavailableError(`the check's judge did not run: ${score.notes}`);
26008
+ const lines = score.notes.split("\n").map((line) => line.trimEnd());
26009
+ const failures = lines.filter((line) => line.startsWith("FAIL "));
26010
+ const review = lines.filter((line) => !line.startsWith("FAIL ") && line.trim() !== "").join("\n");
26011
+ return checkVerdictOf({
26012
+ pass: score.composite >= threshold,
26013
+ items: score.dimensions,
26014
+ composite: score.composite,
26015
+ threshold,
26016
+ failures,
26017
+ ...review === "" ? {} : { review }
26018
+ });
26019
+ }
26020
+ /** Items that fail in `verdict`: every item below 1, or the named items of its FAIL lines. */
26021
+ function failedItems(verdict) {
26022
+ if (verdict.items !== void 0) return Object.entries(verdict.items).filter(([, value]) => value < 1).map(([name]) => name);
26023
+ return (verdict.failures ?? []).map((line) => line.slice(5).split(/[\s:]/u)[0] ?? "");
26024
+ }
26025
+ /** Items that pass in `verdict`. */
26026
+ function passedItems(verdict) {
26027
+ return Object.entries(verdict.items ?? {}).filter(([, value]) => value >= 1).map(([name]) => name);
26028
+ }
26029
+ /** Resolve and check a policy before any compute. Returns the deadline in epoch ms. */
26030
+ function admitContinuationPolicy(policy, context) {
26031
+ if (typeof policy !== "object" || policy === null) throw new ValidationError$1(`${context}: continuation must be an object`);
26032
+ const deadlineMs = typeof policy.deadline === "string" ? Date.parse(policy.deadline) : policy.deadline;
26033
+ if (typeof deadlineMs !== "number" || !Number.isFinite(deadlineMs) || deadlineMs <= 0) throw new ValidationError$1(`${context}: continuation.deadline must be a finite time (epoch ms or ISO 8601)`);
26034
+ if (!Number.isInteger(policy.maxBarren) || policy.maxBarren < 1) throw new ValidationError$1(`${context}: continuation.maxBarren must be an integer >= 1`);
26035
+ if (policy.failures !== "verbatim" && policy.failures !== "off") throw new ValidationError$1(`${context}: continuation.failures must be 'verbatim' or 'off'`);
26036
+ if (policy.panel !== "on" && policy.panel !== "off") throw new ValidationError$1(`${context}: continuation.panel must be 'on' or 'off'`);
26037
+ if (policy.bar !== "on" && policy.bar !== "off") throw new ValidationError$1(`${context}: continuation.bar must be 'on' or 'off'`);
26038
+ if (policy.panel === "on") {
26039
+ if (typeof policy.runPanel !== "function") throw new ValidationError$1(`${context}: continuation.panel 'on' needs runPanel`);
26040
+ const usd = policy.panelUsd;
26041
+ if (usd === void 0 || !finite(usd.perContinuation) || !finite(usd.perRun) || usd.perContinuation <= 0 || usd.perRun < usd.perContinuation) throw new ValidationError$1(`${context}: continuation.panel 'on' needs panelUsd with 0 < perContinuation <= perRun`);
26042
+ }
26043
+ if (policy.append !== void 0 && typeof policy.append !== "function") throw new ValidationError$1(`${context}: continuation.append must be a function`);
26044
+ admitContinuationProfile(policy.profile, context);
26045
+ return deadlineMs;
26046
+ }
26047
+ /** The facts a profile template may name. */
26048
+ const CONTINUATION_FACTS = [
26049
+ "composite",
26050
+ "threshold",
26051
+ "failed",
26052
+ "total",
26053
+ "reads",
26054
+ "owed",
26055
+ "settled",
26056
+ "delivered",
26057
+ "continuation"
26058
+ ];
26059
+ const factNames = new Set(CONTINUATION_FACTS);
26060
+ const placeholder = /\{([a-zA-Z]+)\}/gu;
26061
+ function admitContinuationProfile(profile, context) {
26062
+ if (typeof profile !== "object" || profile === null) throw new ValidationError$1(`${context}: continuation.profile must be an object`);
26063
+ if (typeof profile.id !== "string" || profile.id.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.id must be non-empty`);
26064
+ const texts = [
26065
+ ["opening", profile.opening],
26066
+ ["plan", profile.plan],
26067
+ ["rules", profile.rules],
26068
+ ...Object.entries(profile.headings ?? {}).map(([key, value]) => [`headings.${key}`, value]),
26069
+ ...profile.barRule === void 0 ? [] : [["barRule", profile.barRule]]
26070
+ ];
26071
+ for (const key of [
26072
+ "failures",
26073
+ "protected",
26074
+ "changed",
26075
+ "findings",
26076
+ "bar",
26077
+ "plan",
26078
+ "rules"
26079
+ ]) if (typeof profile.headings?.[key] !== "string") throw new ValidationError$1(`${context}: continuation.profile.headings.${key} must be a string`);
26080
+ for (const [key, text] of texts) {
26081
+ if (typeof text !== "string") throw new ValidationError$1(`${context}: continuation.profile.${key} must be a string`);
26082
+ for (const match of text.matchAll(placeholder)) if (!factNames.has(match[1] ?? "")) throw new ValidationError$1(`${context}: continuation.profile.${key} names {${match[1]}}, which is not a fact Runtime supplies (${CONTINUATION_FACTS.join(", ")})`);
26083
+ }
26084
+ if (profile.review !== void 0) {
26085
+ if (typeof profile.review !== "string" || profile.review.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.review must be non-empty`);
26086
+ for (const match of profile.review.matchAll(placeholder)) if (![
26087
+ "version",
26088
+ "path",
26089
+ "score"
26090
+ ].includes(match[1] ?? "")) throw new ValidationError$1(`${context}: continuation.profile.review names {${match[1]}}; it may name {version}, {path} and {score}`);
26091
+ }
26092
+ if (profile.opening.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.opening must be non-empty`);
26093
+ for (const [index, question] of (profile.questions ?? []).entries()) if (typeof question !== "string" || question.trim() === "") throw new ValidationError$1(`${context}: continuation.profile.questions[${index}] must be a non-empty string`);
26094
+ }
26095
+ /** Findings reach the note only when every citation resolves, at least two distinct spans are
26096
+ * cited, and the independent verifier agreed. The best method in Who&When found the failing step
26097
+ * 14.2% of the time, so an unverified finding is noise with a citation. */
26098
+ function admitFinding(finding) {
26099
+ if (!finding.verified) return false;
26100
+ if (finding.citations.length === 0) return false;
26101
+ if (!finding.citations.every((citation) => citation.resolved)) return false;
26102
+ return new Set(finding.citations.map((citation) => citation.uri)).size >= 2;
26103
+ }
26104
+ /** About 1,500 tokens of findings. */
26105
+ const FINDINGS_CHAR_CAP = 6e3;
26106
+ /**
26107
+ * Rank the admitted findings by how many failed items they explain, drop repeats, and keep them
26108
+ * within the note's cap. Earlier findings stay as they were written (ACE: itemized additions keep
26109
+ * detail that repeated rewrites lose); a finding whose items all pass now is marked resolved.
26110
+ */
26111
+ function distillFindings(prior, proposed, failing, continuation) {
26112
+ const key = (claim) => claim.toLowerCase().replace(/\s+/gu, " ").trim();
26113
+ const known = new Set(prior.map((finding) => key(finding.claim)));
26114
+ const carried = prior.map((finding) => finding.resolvedAt === void 0 && (finding.items?.length ?? 0) > 0 && (finding.items ?? []).every((item) => !failing.has(item)) ? {
26115
+ ...finding,
26116
+ resolvedAt: continuation
26117
+ } : finding);
26118
+ const fresh = proposed.filter(admitFinding).filter((finding) => {
26119
+ const k = key(finding.claim);
26120
+ if (known.has(k)) return false;
26121
+ known.add(k);
26122
+ return true;
26123
+ }).map((finding) => ({
26124
+ finding,
26125
+ links: (finding.items ?? []).filter((item) => failing.has(item)).length
26126
+ })).sort((a, b) => b.links - a.links);
26127
+ const out = [...carried];
26128
+ let used = carried.filter((finding) => finding.resolvedAt === void 0).reduce((sum, finding) => sum + finding.claim.length, 0);
26129
+ for (const { finding } of fresh) {
26130
+ if (used + finding.claim.length > FINDINGS_CHAR_CAP) break;
26131
+ used += finding.claim.length;
26132
+ out.push({
26133
+ ...finding,
26134
+ admittedAt: continuation
26135
+ });
26136
+ }
26137
+ return out;
26138
+ }
26139
+ /** Expand the profile's question templates over the failed items and the settled workers. */
26140
+ function expandQuestions(templates, failing, workers) {
26141
+ const out = [];
26142
+ for (const template of templates) {
26143
+ const hasItem = template.includes("{item}");
26144
+ const hasWorker = template.includes("{worker}");
26145
+ if (!hasItem && !hasWorker) {
26146
+ out.push(template);
26147
+ continue;
26148
+ }
26149
+ const items = hasItem ? failing : [""];
26150
+ const each = hasWorker ? workers.map((worker) => `${worker.id} (${worker.label})`) : [""];
26151
+ for (const item of items) for (const worker of each) out.push(template.replaceAll("{item}", item).replaceAll("{worker}", worker));
26152
+ }
26153
+ return out;
26154
+ }
26155
+ /**
26156
+ * Write one continuation note, sections 1 to 8 of docs/38. Section 9, the run's state, is
26157
+ * `composeReentryTask`, which wraps this text. Pure: the same input writes the same note.
26158
+ */
26159
+ function composeContinuationNote(input) {
26160
+ const { profile, verdict } = input;
26161
+ const items = verdict?.items ?? {};
26162
+ const total = Object.keys(items).length;
26163
+ const failing = verdict === void 0 ? [] : failedItems(verdict);
26164
+ const facts = {
26165
+ composite: verdict?.composite === void 0 ? "unknown" : format(verdict.composite),
26166
+ threshold: verdict?.threshold === void 0 ? "unknown" : format(verdict.threshold),
26167
+ failed: verdict === void 0 || total === 0 && (verdict.failures?.length ?? 0) === 0 ? "unknown" : String(failing.length),
26168
+ total: total === 0 ? "unknown" : String(total),
26169
+ reads: String(input.reads),
26170
+ owed: input.owed?.trim() || "not described",
26171
+ settled: String(input.progress.settledCount),
26172
+ delivered: String(input.progress.deliveredCount ?? 0),
26173
+ continuation: String(input.continuation)
26174
+ };
26175
+ const fill = (text) => text.replace(placeholder, (_, name) => facts[name] ?? `{${name}}`);
26176
+ const sections = [verdict === void 0 ? "No result has reached the check yet. The run ends only when a result passes it through submit_result." : verdict.pass ? "The check passes on the current state, but no result was submitted. Call submit_result to end the run." : fill(profile.opening).trim()];
26177
+ const section = (heading, body) => {
26178
+ if (body.length === 0) return;
26179
+ sections.push([...heading.trim() === "" ? [] : [`## ${fill(heading)}`], ...body].join("\n"));
26180
+ };
26181
+ if (input.failures === "verbatim" && verdict !== void 0) {
26182
+ const lines = verdict.failures ?? [];
26183
+ const shown = lines.slice(0, 40);
26184
+ const more = lines.length - shown.length;
26185
+ section(profile.headings.failures, [...shown, ...more > 0 ? [input.canReadMore ? `${more} more failure lines: call read_continuation with continuation ${input.continuation}.` : `${more} more failure lines are not shown.`] : []]);
26186
+ const passing = passedItems(verdict);
26187
+ section(profile.headings.protected, passing.length === 0 ? [] : [passing.join(", ")]);
26188
+ if (input.previous !== void 0) {
26189
+ const before = new Set(failedItems(input.previous));
26190
+ const now = new Set(failing);
26191
+ const fixed = [...before].filter((item) => !now.has(item));
26192
+ const broke = [...now].filter((item) => !before.has(item));
26193
+ section(profile.headings.changed, [
26194
+ ...fixed.length === 0 ? [] : [`Now passing: ${fixed.join(", ")}.`],
26195
+ ...broke.length === 0 ? [] : [`Newly failing: ${broke.join(", ")}.`],
26196
+ ...fixed.length === 0 && broke.length === 0 ? ["No item changed since the last note."] : [],
26197
+ ...input.previous.composite !== void 0 && verdict.composite !== void 0 ? [`Composite: ${format(input.previous.composite)} then ${format(verdict.composite)}.`] : []
26198
+ ]);
26199
+ }
26200
+ }
26201
+ if (input.findings !== void 0) {
26202
+ const open = input.findings.filter((finding) => finding.resolvedAt === void 0);
26203
+ const resolved = input.findings.filter((finding) => finding.resolvedAt === input.continuation);
26204
+ section(profile.headings.findings, [...open.map((finding) => `- [hypothesis] ${finding.claim}` + (finding.items?.length ? ` (items: ${finding.items.join(", ")})` : "") + ` Evidence: ${finding.citations.map((citation) => citation.uri).join(", ")}`), ...resolved.map((finding) => `- [resolved] ${finding.claim}`)]);
26205
+ }
26206
+ if (input.bar !== void 0 && verdict !== void 0) {
26207
+ const body = [];
26208
+ if (profile.barRule?.trim()) body.push(fill(profile.barRule).trim());
26209
+ for (const [item, value] of Object.entries(items)) {
26210
+ const best = input.bar.best?.verdict.items?.[item];
26211
+ body.push(`- ${item}: ${value >= 1 ? "passes" : `fails (${format(value)})`}` + (best === void 0 ? "" : ` / ${input.bar.best?.label}: ${best >= 1 ? "passes" : `fails (${format(best)})`}`));
26212
+ }
26213
+ if (input.bar.best?.verdict.composite !== void 0) body.push(`Best version ${input.bar.best.label}: composite ${format(input.bar.best.verdict.composite)}.`);
26214
+ if (input.bar.reference?.trim()) body.push(`Reference result: ${input.bar.reference.trim()}`);
26215
+ if (verdict.review?.trim()) body.push(`The check's review: ${verdict.review.trim()}`);
26216
+ section(profile.headings.bar, body);
26217
+ }
26218
+ section(profile.headings.plan, profile.plan.trim() === "" ? [] : [fill(profile.plan).trim()]);
26219
+ section(profile.headings.rules, [...profile.rules.trim() === "" ? [] : [fill(profile.rules).trim()], ...input.sealed ? ["The score comes from cases you cannot see."] : []]);
26220
+ for (const appended of input.appended ?? []) section(appended.heading, appended.text.trim() === "" ? [] : [appended.text.trim()]);
26221
+ return sections.join("\n\n");
26222
+ }
26223
+ function summarizeVerdict(verdict) {
26224
+ if (verdict === void 0) return null;
26225
+ const total = Object.keys(verdict.items ?? {}).length;
26226
+ return {
26227
+ pass: verdict.pass,
26228
+ ...verdict.composite === void 0 ? {} : { composite: verdict.composite },
26229
+ ...total === 0 ? {} : {
26230
+ failed: failedItems(verdict).length,
26231
+ total
26232
+ }
26233
+ };
26234
+ }
26235
+ function noteDigest(note) {
26236
+ return `sha256:${createHash("sha256").update(note).digest("hex")}`;
26237
+ }
26238
+ /** A run directory's continuation files: the root's at `<runDir>/continuations/<n>/`, a nested
26239
+ * manager's at `<runDir>/continuations/managers/<owner>/<n>/`. */
26240
+ const CONTINUATIONS_DIR = "continuations";
26241
+ /**
26242
+ * Write one continuation's files under `<dir>/<n>/`: `note.md`, `verdict.json`, and
26243
+ * `panel.jsonl` when the panel ran. The director reads them through `read_continuation`, because
26244
+ * its box cannot read the driver's run directory.
26245
+ */
26246
+ async function writeContinuationFiles(dir, continuation, files) {
26247
+ const at = join(dir, String(continuation));
26248
+ await mkdir(at, { recursive: true });
26249
+ await writeFile(join(at, "note.md"), `${files.note}\n`, "utf8");
26250
+ await writeFile(join(at, "verdict.json"), `${JSON.stringify(files.verdict ?? null, null, 2)}\n`, "utf8");
26251
+ if (files.panel !== void 0) await writeFile(join(at, "panel.jsonl"), files.panel.map((line) => JSON.stringify(line)).join("\n") + (files.panel.length ? "\n" : ""), "utf8");
26252
+ }
26253
+ /** The best composite across `reads`, or `undefined` when no read scored. */
26254
+ function bestComposite(reads) {
26255
+ let best;
26256
+ for (const read of reads) {
26257
+ const value = read.verdict?.composite;
26258
+ if (value !== void 0 && (best === void 0 || value > best)) best = value;
26259
+ }
26260
+ return best;
26261
+ }
26262
+ function finite(value) {
26263
+ return typeof value === "number" && Number.isFinite(value);
26264
+ }
26265
+ function format(value) {
26266
+ return Number.isInteger(value) ? String(value) : value.toFixed(3).replace(/0+$/u, "");
26267
+ }
26268
+ /** Build the continuation state for one manager with a check. */
26269
+ function createContinuationKeeper(input) {
26270
+ const { policy } = input;
26271
+ const failures = input.feedback === "pass-only" ? "off" : policy.failures;
26272
+ const entries = [];
26273
+ const notes = [];
26274
+ let findings = [];
26275
+ let panelUsd = 0;
26276
+ let panelUsdKnown = true;
26277
+ const latestVerdict = () => {
26278
+ const reads = input.reads();
26279
+ for (let i = reads.length - 1; i >= 0; i -= 1) {
26280
+ const read = reads[i];
26281
+ if (read?.verdict !== void 0) return {
26282
+ verdict: read.verdict,
26283
+ read: read.read
26284
+ };
26285
+ }
26286
+ return { read: 0 };
26287
+ };
26288
+ const closePrevious = () => {
26289
+ const last = entries.at(-1);
26290
+ const lastNote = notes.at(-1);
26291
+ if (last === void 0 || lastNote === void 0) return;
26292
+ const latest = latestVerdict();
26293
+ entries[entries.length - 1] = {
26294
+ ...last,
26295
+ after: latest.read > lastNote.read ? summarizeVerdict(latest.verdict) : null
26296
+ };
26297
+ };
26298
+ return {
26299
+ async compose(context) {
26300
+ closePrevious();
26301
+ const continuation = entries.length + 1;
26302
+ const { verdict, read } = latestVerdict();
26303
+ const failing = verdict === void 0 ? [] : failedItems(verdict);
26304
+ let panelRecord;
26305
+ let panelLines;
26306
+ if (policy.panel === "on" && policy.runPanel !== void 0 && policy.panelUsd !== void 0) {
26307
+ const workers = input.workers();
26308
+ const questions = expandQuestions(policy.profile.questions ?? [], failing, workers);
26309
+ const left = policy.panelUsd.perRun - panelUsd;
26310
+ const usdCap = Math.min(policy.panelUsd.perContinuation, left);
26311
+ if (questions.length > 0 && usdCap > 0 && panelUsdKnown) {
26312
+ const result = await policy.runPanel({
26313
+ continuation,
26314
+ task: input.task,
26315
+ ...verdict === void 0 ? {} : { verdict },
26316
+ reads: input.reads(),
26317
+ questions,
26318
+ ...input.rootStreamPath === void 0 ? {} : { rootStreamPath: input.rootStreamPath },
26319
+ workers,
26320
+ ...policy.best === void 0 ? {} : { bar: policy.best },
26321
+ ...policy.reference === void 0 ? {} : { reference: policy.reference },
26322
+ usdCap,
26323
+ signal: context.signal
26324
+ });
26325
+ if (result.usd === null) panelUsdKnown = false;
26326
+ else panelUsd += result.usd;
26327
+ findings = distillFindings(findings, result.findings, new Set(failing), continuation);
26328
+ panelRecord = {
26329
+ asked: questions.length,
26330
+ proposed: result.findings.length,
26331
+ admitted: findings.filter((finding) => finding.admittedAt === continuation).length,
26332
+ usd: result.usd
26333
+ };
26334
+ panelLines = [...result.findings.map((finding) => ({
26335
+ kind: "finding",
26336
+ admitted: admitFinding(finding),
26337
+ ...finding
26338
+ })), ...result.receipts === void 0 ? [] : [{
26339
+ kind: "receipts",
26340
+ receipts: result.receipts
26341
+ }]];
26342
+ } else panelRecord = {
26343
+ asked: 0,
26344
+ proposed: 0,
26345
+ admitted: 0,
26346
+ usd: 0
26347
+ };
26348
+ }
26349
+ const appended = policy.append ? await policy.append({
26350
+ continuation,
26351
+ ...verdict === void 0 ? {} : { verdict },
26352
+ reads: input.reads(),
26353
+ signal: context.signal
26354
+ }) : void 0;
26355
+ const note = composeContinuationNote({
26356
+ profile: policy.profile,
26357
+ continuation,
26358
+ ...verdict === void 0 ? {} : { verdict },
26359
+ ...notes.at(-1)?.verdict === void 0 ? {} : { previous: notes.at(-1)?.verdict },
26360
+ reads: input.reads().length,
26361
+ failures,
26362
+ ...policy.panel === "on" ? { findings } : {},
26363
+ ...policy.bar === "on" ? { bar: {
26364
+ ...policy.best === void 0 ? {} : { best: policy.best },
26365
+ ...policy.reference === void 0 ? {} : { reference: policy.reference }
26366
+ } } : {},
26367
+ ...appended === void 0 ? {} : { appended: [appended] },
26368
+ ...input.owed === void 0 ? {} : { owed: input.owed },
26369
+ progress: context.progress,
26370
+ canReadMore: input.canReadMore,
26371
+ ...input.sealed === true ? { sealed: true } : {}
26372
+ });
26373
+ notes.push({
26374
+ note,
26375
+ ...verdict === void 0 ? {} : { verdict },
26376
+ ...panelLines === void 0 ? {} : { panel: panelLines },
26377
+ read
26378
+ });
26379
+ entries.push({
26380
+ continuation,
26381
+ attempt: context.attempt,
26382
+ noteDigest: noteDigest(note),
26383
+ profile: policy.profile.id,
26384
+ switches: {
26385
+ failures,
26386
+ panel: policy.panel,
26387
+ bar: policy.bar
26388
+ },
26389
+ before: summarizeVerdict(verdict),
26390
+ after: null,
26391
+ ...panelRecord === void 0 ? {} : { panel: panelRecord },
26392
+ appended: appended === void 0 ? 0 : 1
26393
+ });
26394
+ if (input.dir !== void 0) await writeContinuationFiles(input.dir, continuation, {
26395
+ note,
26396
+ ...verdict === void 0 ? {} : { verdict },
26397
+ ...panelLines === void 0 ? {} : { panel: panelLines }
26398
+ });
26399
+ return note;
26400
+ },
26401
+ read(continuation) {
26402
+ const index = continuation === void 0 ? notes.length - 1 : continuation - 1;
26403
+ const entry = notes[index];
26404
+ if (entry === void 0) return {
26405
+ found: false,
26406
+ reason: notes.length === 0 ? "no continuation has been sent in this run" : `continuations run from 1 to ${notes.length}`
26407
+ };
26408
+ return {
26409
+ found: true,
26410
+ continuation: index + 1,
26411
+ note: entry.note,
26412
+ verdict: failures === "off" && entry.verdict !== void 0 ? { pass: entry.verdict.pass } : entry.verdict ?? null,
26413
+ findings: findings.filter((finding) => finding.admittedAt <= index + 1)
26414
+ };
26415
+ },
26416
+ entries() {
26417
+ closePrevious();
26418
+ return entries.map((entry) => ({ ...entry }));
26419
+ }
26420
+ };
26421
+ }
26422
+ //#endregion
25684
26423
  //#region src/runtime/supervise/driver-retry.ts
25685
26424
  /**
25686
26425
  * Root-driver retry — the root gets the same second chance a worker's transport already has.
@@ -25728,22 +26467,21 @@ function unreportedSpend(total, prior) {
25728
26467
  * driver that RETURNED with the contract unmet ended the run silently — 376 of 376 winning lab runs
25729
26468
  * ended on this loop's own `stop: 'completed'`, with the completion gate left to label the result
25730
26469
  * rather than to change it. A completed drive whose contract is unmet is now a first-class moment:
25731
- * `reprompt.maxReprompts` re-enters the driver with the unmet items, and every re-entry crosses the
25732
- * same budget, deadline, and abort bounds. Successful continuations do not consume the failure
25733
- * retry allowance.
26470
+ * the manager's `continuation` policy (`./continuation.ts`) re-enters the driver with Runtime's
26471
+ * continuation note, and every re-entry crosses the same budget, deadline, and abort bounds.
26472
+ * Successful continuations do not consume the failure retry allowance.
25734
26473
  *
25735
26474
  * This loop decides WHETHER to re-enter; it does not know WHERE the next drive runs. Whether the
25736
26475
  * re-entered driver continues the same harness session, the same environment, or a replacement is
25737
26476
  * the drive harness's fact, and the caller composes the re-entry task from it (see
25738
- * `./reentry.ts`). A re-prompt re-enters the same session only on a backend that proves it.
26477
+ * `./reentry.ts`). A continuation re-enters the same session only on a backend that proves it.
25739
26478
  *
25740
- * Progress bounds the re-prompts too. The same delivery reading that resets the barren failure
25741
- * counter decides whether a re-prompted drive earned another: `reprompt.maxBarren` consecutive
25742
- * re-entered drives that completed without a delivery end the loop with `repromptRefusedBy:
25743
- * 'no-progress'`. Before this, a completed drive reset the barren counter and `decideReprompt`
25744
- * read only the count cap, budget, and deadline, so a director with `repromptOnUnmet: 100` or
25745
- * `'until-complete'` that delivered nothing was re-prompted until the budget or deadline ended it;
25746
- * the old prompt-owned loop logged 896 of 1,011 rounds with no progress.
26479
+ * Progress bounds the continuations, and nothing else counts them. The same delivery reading that
26480
+ * resets the barren failure counter decides whether a continued drive earned another:
26481
+ * `continuation.maxBarren` consecutive re-entered drives that completed without progress end the
26482
+ * loop with `repromptRefusedBy: 'no-progress'`. Progress is a delivery or a rise in the check's
26483
+ * best composite. There is no count cap and no caller veto: the old prompt-owned loop logged 896
26484
+ * of 1,011 rounds with no progress, and 650 recorded inputs chose seven different re-prompt counts.
25747
26485
  *
25748
26486
  * A THIRD CLASS sits between the two: the upstream said "not now". A model provider's exhausted
25749
26487
  * quota, a rate limit, or an overloaded service (HTTP 429, 503, 529, or the router's own codes for
@@ -25755,28 +26493,8 @@ function unreportedSpend(total, prior) {
25755
26493
  * the router answered some turns in between (one lead spent 1.7M and 3.3M input tokens on two of
25756
26494
  * them) and each run's budget and 8-hour deadline were almost untouched.
25757
26495
  */
25758
- /**
25759
- * The instruction a completed-but-undelivered drive is re-entered with when the caller supplies no
25760
- * `onUnmetContract`. It states the verdict, names what is owed, reports the ledger, and gives the
25761
- * three steps — the same shape `depthStrategy` re-prompts a resumed session with, said in the
25762
- * driver's own terms.
25763
- */
25764
- function defaultUnmetContractSteer(context) {
25765
- const owed = context.describe?.trim();
25766
- return [
25767
- "The completion check has not passed. This run has delivered nothing yet.",
25768
- owed === void 0 || owed.length === 0 ? "The deliverable this run owes is still missing." : `The deliverable this run owes: ${owed}`,
25769
- `Workers settled: ${context.progress.settledCount}. Workers that passed the check: ${context.progress.deliveredCount ?? 0}.`,
25770
- "Do the unfinished work with the tools.",
25771
- "Verify that the check passes.",
25772
- "Then submit the result.",
25773
- "Do not restate work you already did."
25774
- ].join("\n");
25775
- }
25776
26496
  const DEFAULT_MAX_CONSECUTIVE_FAILURES = 3;
25777
26497
  const DEFAULT_MAX_ATTEMPTS = 8;
25778
- /** Two re-prompted drives in a row that deliver nothing end the re-prompts. */
25779
- const DEFAULT_MAX_BARREN_REPROMPTS = 2;
25780
26498
  const DEFAULT_INITIAL_BACKOFF_MS = 2e3;
25781
26499
  const DEFAULT_MAX_BACKOFF_MS = 3e4;
25782
26500
  /**
@@ -25822,6 +26540,7 @@ var HarnessTurnFailedError = class extends Error {
25822
26540
  */
25823
26541
  function upstreamUnavailableSignal(error) {
25824
26542
  if (!(error instanceof Error)) return void 0;
26543
+ if (error instanceof CheckUnavailableError) return "check-unavailable";
25825
26544
  if (error instanceof HarnessTurnFailedError) return unavailableSignalOfFailure({
25826
26545
  error: error.message,
25827
26546
  ...error.errorCode === void 0 ? {} : { errorCode: error.errorCode }
@@ -25905,13 +26624,15 @@ function contractOf(mark) {
25905
26624
  /**
25906
26625
  * Did this attempt move the run toward its DELIVERABLE?
25907
26626
  *
25908
- * A delivery always counts: an accepted submission, one more child that passed the check, or the
25909
- * contract turning met. Spend and settlements count only while no declared check is outstanding —
25910
- * with a check unmet they are the burn-rate reading this module's header measures and rejects.
26627
+ * A delivery always counts: an accepted submission, one more child that passed the check, the
26628
+ * contract turning met, or a rise in the check's best composite. Spend and settlements count only
26629
+ * while no declared check is outstanding — with a check unmet they are the burn-rate reading this
26630
+ * module's header measures and rejects.
25911
26631
  */
25912
26632
  function madeProgress(before, after) {
25913
26633
  if (after.submitted && !before.submitted) return true;
25914
26634
  if ((after.deliveredCount ?? 0) > (before.deliveredCount ?? 0)) return true;
26635
+ if (after.composite !== void 0 && after.composite > (before.composite ?? -Infinity)) return true;
25915
26636
  if (contractOf(before) !== "met" && contractOf(after) === "met") return true;
25916
26637
  if (contractOf(after) === "unmet") return false;
25917
26638
  return after.poolTokensSpent > before.poolTokensSpent || after.settledCount > before.settledCount;
@@ -25957,10 +26678,11 @@ async function defaultSleep(ms, signal) {
25957
26678
  /**
25958
26679
  * Run the driver until it completes WITH ITS CONTRACT MET, or until the budget, the deadline, an
25959
26680
  * abort, a terminal error, or a ceiling stops it. Transient failures are retried. A drive that
25960
- * returns with its completion check unmet is re-entered on the same live session with the unmet
25961
- * items, up to `reprompt.maxReprompts`. Throws `DriverAttemptsExhaustedError` (cause = the last
25962
- * real failure) when a FAILURE ends the loop; a completed drive returns, met contract or not,
25963
- * because deciding what an undelivered run is worth belongs to the finalizer, not to this loop.
26681
+ * returns with its completion check unmet is re-entered with Runtime's continuation note until the
26682
+ * continuation's deadline or `maxBarren` turns without progress. Throws
26683
+ * `DriverAttemptsExhaustedError` (cause = the last real failure) when a FAILURE ends the loop; a
26684
+ * completed drive returns, met contract or not, because deciding what an undelivered run is worth
26685
+ * belongs to the finalizer, not to this loop.
25964
26686
  */
25965
26687
  async function runDriverWithRetry(run) {
25966
26688
  const now = run.now ?? Date.now;
@@ -25971,19 +26693,18 @@ async function runDriverWithRetry(run) {
25971
26693
  const maxAttempts = Math.max(1, policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
25972
26694
  const initialBackoff = Math.max(0, policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS);
25973
26695
  const maxBackoff = Math.max(initialBackoff, policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS);
25974
- const maxReprompts = run.reprompt?.maxReprompts ?? 0;
25975
- if (maxReprompts === "until-complete") {
25976
- const deadline = run.budget().deadlineMs;
25977
- if (!Number.isFinite(deadline) || deadline <= 0) throw new ValidationError$1("runDriverWithRetry: until-complete requires a finite positive deadline");
26696
+ const continuation = run.continuation;
26697
+ if (continuation !== void 0) {
26698
+ if (!Number.isFinite(continuation.deadlineMs) || continuation.deadlineMs <= 0) throw new ValidationError$1("runDriverWithRetry: a continuation needs a finite positive deadline");
26699
+ if (!Number.isInteger(continuation.maxBarren) || continuation.maxBarren < 1) throw new ValidationError$1("runDriverWithRetry: continuation.maxBarren must be an integer >= 1");
25978
26700
  }
25979
- const maxBarren = Math.max(1, run.reprompt?.maxBarren ?? 2);
25980
26701
  const attempts = [];
25981
26702
  let consecutiveBarren = 0;
25982
26703
  let barrenReentries = 0;
25983
26704
  let failures = 0;
25984
26705
  let consecutivePauses = 0;
25985
26706
  let pauses = 0;
25986
- let reprompts = 0;
26707
+ let continuations = 0;
25987
26708
  let reentry;
25988
26709
  const emit = async (record) => {
25989
26710
  const entered = reentry === void 0 ? {} : { reentry: reentry.reason };
@@ -25995,32 +26716,33 @@ async function runDriverWithRetry(run) {
25995
26716
  await run.onAttempt?.(stamped);
25996
26717
  };
25997
26718
  /**
25998
- * Decide what a completed-but-undelivered drive does next. Every bound the FAILURE path applies
25999
- * is applied here too — that is the fix for `budgetStop` having lived only in the catch arm — and
26000
- * the caller's hook is consulted last, so no hook can talk the loop past a deadline.
26719
+ * Decide what a completed drive with its check unmet does next. Every bound the FAILURE path
26720
+ * applies is applied here too — that is the fix for `budgetStop` having lived only in the catch
26721
+ * arm — and they are read again after the note is composed, because composing may run the
26722
+ * question panel.
26001
26723
  */
26002
- const decideReprompt = async (attempt, after) => {
26003
- if (maxReprompts !== "until-complete" && reprompts >= maxReprompts) return { refusedBy: "reprompts-exhausted" };
26004
- if (barrenReentries >= maxBarren) return { refusedBy: "no-progress" };
26005
- if (run.signal.aborted) return { refusedBy: "aborted" };
26006
- const byBudget = budgetStop(run.budget(), now());
26007
- if (byBudget === "deadline" || byBudget === "budget-exhausted") return { refusedBy: byBudget };
26008
- const context = {
26724
+ const decideContinuation = async (policy, attempt, after) => {
26725
+ const bounds = () => {
26726
+ if (policy.closed()) return "closed";
26727
+ if (run.signal.aborted) return "aborted";
26728
+ if (now() >= policy.deadlineMs) return "deadline";
26729
+ const byBudget = budgetStop(run.budget(), now());
26730
+ return byBudget === "deadline" || byBudget === "budget-exhausted" ? byBudget : void 0;
26731
+ };
26732
+ if (barrenReentries >= policy.maxBarren) return { refusedBy: "no-progress" };
26733
+ const before = bounds();
26734
+ if (before !== void 0) return { refusedBy: before };
26735
+ const steer = (await policy.compose({
26009
26736
  attempt,
26010
- reprompts,
26011
- maxReprompts,
26737
+ continuations,
26012
26738
  progress: after,
26013
26739
  budget: run.budget(),
26014
- ...run.reprompt?.describe === void 0 ? {} : { describe: run.reprompt.describe },
26015
- barrenReentries
26016
- };
26017
- const decision = await run.reprompt?.onUnmetContract?.(context) ?? { steer: defaultUnmetContractSteer(context) };
26018
- if (decision === "stop") return { refusedBy: "caller-stop" };
26019
- if (run.signal.aborted) return { refusedBy: "aborted" };
26020
- const afterHook = budgetStop(run.budget(), now());
26021
- if (afterHook === "deadline" || afterHook === "budget-exhausted") return { refusedBy: afterHook };
26022
- const steer = typeof decision.steer === "string" ? decision.steer.trim() : "";
26023
- if (steer.length === 0) throw new ValidationError$1("runDriverWithRetry: onUnmetContract returned an empty steer — return a non-empty instruction or 'stop'");
26740
+ barrenReentries,
26741
+ signal: run.signal
26742
+ })).trim();
26743
+ const afterCompose = bounds();
26744
+ if (afterCompose !== void 0) return { refusedBy: afterCompose };
26745
+ if (steer.length === 0) throw new ValidationError$1("runDriverWithRetry: the continuation note is empty");
26024
26746
  return { steer };
26025
26747
  };
26026
26748
  for (let attempt = 1;; attempt += 1) {
@@ -26134,10 +26856,10 @@ async function runDriverWithRetry(run) {
26134
26856
  const contractField = contract === "none" ? {} : { contract };
26135
26857
  if (progressed) barrenReentries = 0;
26136
26858
  else if (reentry !== void 0 && contract === "unmet") barrenReentries += 1;
26137
- if (contract === "unmet" && (maxReprompts === "until-complete" || maxReprompts > 0)) {
26138
- const decision = await decideReprompt(attempt, after);
26859
+ if (contract === "unmet" && continuation !== void 0) {
26860
+ const decision = await decideContinuation(continuation, attempt, after);
26139
26861
  if ("steer" in decision) {
26140
- reprompts += 1;
26862
+ continuations += 1;
26141
26863
  await emit({
26142
26864
  attempt,
26143
26865
  durationMs,
@@ -26149,7 +26871,7 @@ async function runDriverWithRetry(run) {
26149
26871
  reentry = {
26150
26872
  reason: "unmet-contract",
26151
26873
  steer: decision.steer,
26152
- reprompt: reprompts
26874
+ continuation: continuations
26153
26875
  };
26154
26876
  continue;
26155
26877
  }
@@ -26277,8 +26999,9 @@ async function runFinalizer(finalizer, args) {
26277
26999
  if (candidate === void 0) return false;
26278
27000
  if (args.deliverable === void 0) return true;
26279
27001
  try {
26280
- return await args.deliverable.check(candidate) === true;
27002
+ return checkVerdictOf(await args.deliverable.check(candidate)).pass;
26281
27003
  } catch (error) {
27004
+ if (error instanceof CheckUnavailableError) throw error;
26282
27005
  throw new ValidationError$1(`finalizer: parent completion check threw: ${error instanceof Error ? error.message : String(error)}`);
26283
27006
  }
26284
27007
  };
@@ -26543,10 +27266,10 @@ function createSupervisor() {
26543
27266
  pool = createBudgetPool(opts.budget, runEpochMs, restored.poolRestore);
26544
27267
  } else {
26545
27268
  pool = createBudgetPool(opts.budget, runStartedAtMs);
26546
- await opts.journal.beginTree(opts.runId, runStartedAt);
27269
+ if (existing === void 0) await opts.journal.beginTree(opts.runId, runStartedAt);
26547
27270
  const rootReceipt = rootMaterializationReceipt(opts);
26548
27271
  const rootRuntime = opts.rootMaterialization?.runtime ?? "inline";
26549
- await opts.journal.appendEvent(opts.runId, {
27272
+ const rootEvents = [{
26550
27273
  kind: "spawned",
26551
27274
  id: opts.runId,
26552
27275
  label: "root",
@@ -26556,14 +27279,15 @@ function createSupervisor() {
26556
27279
  ...opts.rootIdentity ? { identity: opts.rootIdentity } : {},
26557
27280
  seq: 0,
26558
27281
  at: runStartedAt
26559
- });
26560
- if (rootReceipt !== void 0) await opts.journal.appendEvent(opts.runId, {
27282
+ }];
27283
+ if (rootReceipt !== void 0) rootEvents.push({
26561
27284
  kind: "materialized",
26562
27285
  id: opts.runId,
26563
27286
  receipt: rootReceipt,
26564
27287
  seq: 0,
26565
27288
  at: runStartedAt
26566
27289
  });
27290
+ await appendSpawnEvents(opts.journal, opts.runId, rootEvents);
26567
27291
  }
26568
27292
  const stableRootReceipt = resuming ? prior?.find((event) => event.kind === "materialized" && event.id === opts.runId)?.receipt : rootMaterializationReceipt(opts);
26569
27293
  if (stableRootReceipt !== void 0) {
@@ -26901,11 +27625,18 @@ function createIntensityBreaker(opts, trip) {
26901
27625
  * settlement either (it writes no `settled` record then), so `downCount` stays what it was:
26902
27626
  * ordinary downs only; `fleetYield.down` is where a retained child is counted. */
26903
27627
  function wrapJournalForBreaker(journal, breaker) {
27628
+ const recordDown = (ev) => {
27629
+ if (ev.kind === "settled" && ev.status === "down" && ev.retainedExecution === void 0) breaker.recordDown(Date.parse(ev.at));
27630
+ };
26904
27631
  return {
26905
27632
  loadTree: (root) => journal.loadTree(root),
26906
27633
  beginTree: (root, at) => journal.beginTree(root, at),
27634
+ ...journal.appendEvents === void 0 ? {} : { appendEvents: (root, events) => {
27635
+ for (const event of events) recordDown(event);
27636
+ return journal.appendEvents?.(root, events) ?? Promise.resolve();
27637
+ } },
26907
27638
  appendEvent: (root, ev) => {
26908
- if (ev.kind === "settled" && ev.status === "down" && ev.retainedExecution === void 0) breaker.recordDown(Date.parse(ev.at));
27639
+ recordDown(ev);
26909
27640
  return journal.appendEvent(root, ev);
26910
27641
  }
26911
27642
  };
@@ -27199,6 +27930,6 @@ function isNonEmptySpend(s) {
27199
27930
  return s.iterations > 0 || s.tokens.input > 0 || s.tokens.output > 0 || s.usd > 0 || s.ms > 0 || s.tokensKnown === false || s.usdKnown === false || Object.values(s.resources ?? {}).some((resource) => resource.amount > 0 || !resource.known);
27200
27931
  }
27201
27932
  //#endregion
27202
- export { interactiveAdmissionSeamKey as $, sumSandboxUsage as $i, recoverRetainedRun as $n, controlProfileMaterialization as $r, taskToPrompt as $t, restoreScopeOwnerAcceptedExecution as A, runtimeOwnedExecutorMaterialization as Ai, acquireSandbox as An, padSpanId as Ar, insideCursorNamespace as At, bindScopeRetainedOwnerEnvironmentId as B, projectSandboxOutcome as Bi, providerAsExecutor as Bn, captureWorktreeDiff as Br, BudgetReconcileFault as Bt, beginScopeOwnerAttempt as C, teardownExecutor as Ca, knownExecutionBindingReceipt as Ci, TERMINAL_DECISIONS as Cn, buildRuntimeEventOtelSpans as Cr, FileResultBlobStore as Ct, meterRuntimeOwnedProviderAttempt as D, providerMessageText as Da, recordRuntimeOwnedDriveHarnessProviderEvidence as Di, runAgentRounds as Dn, flatOtelSpan as Dr, SpawnEventIndex as Dt, meterRuntimeOwnedAccounting as E, promptOptionsFromAgentTurnInput as Ea, providerAttemptEvidence as Ei, isTerminalDecision as En, exportEvalRuns as Er, InMemorySpawnJournal as Et, isWaitOutcome as F, unknownMaterializationReceipt as Fi, canonicalObservedModelParts as Fn, sanitizeAgentRuntimeEvent as Fr, WORKER_TOOL_TRACE_SCHEMA_VERSION as Ft, scopeRetainedOwnerContext as G, createSandboxUsageLedger as Gi, unavailableSignalOfFailure as Gn, harnessInvocation as Gr, newUsageTotals as Gt, consumeScopeRetainedOwnerResult as H, assertSandboxServedModel as Hi, resolveAgentEnvironmentProvider as Hn, removeWorktree as Hr, assertValidBudget as Ht, pollFor as I, executableAgentProfileSnapshot as Ii, observedModelMatchesDeclared as In, sanitizeKnowledgeReadinessReport as Ir, captureWorkerTraceEvidence as It, scopeRetainedOwnerResult as J, mapSandboxEvent as Ji, sandboxSessionTraceSource as Jn, parseCodexTokenUsage as Jr, WORKER_TRACE_PROPAGATION as Jt, scopeRetainedOwnerPriorSpend as K, extractLlmCallEvent as Ki, createPushTraceSource as Kn, harnessSupportsReasoningEffort as Kr, spendFromUsageEvents as Kt, timerAt as L, executableAgentSpecSnapshot as Li, DEFAULT_SANDBOX_IDLE_TIMEOUT_SECONDS as Ln, sanitizeRuntimeStreamEvent as Lr, isTraceAnalysisStore as Lt, settledToIteration as M, runtimeOwnedPendingExecutorMaterialization as Mi, readPromptOptions as Mn, toOtelAttributes as Mr, materializeTreeView as Mt, createWorkerSlots as N, runtimeOwnedScopeOwnerRuntime as Ni, routerBrain as Nn, createRuntimeEventCollector as Nr, pendingWaits as Nt, recordScopeOwnerMaterialization as O, runtimeOwnedDriveHarnessProviderEvidence as Oi, createSandboxLineage as On, generateSpanId as Or, assertContentAddress as Ot, createWaitProbes as P, unknownExecutionBindingReceipt as Pi, runBrainLoop as Pn, createRuntimeStreamEventCollector as Pr, replaySpawnTree as Pt, resolveSpawnResourcePaths as Q, sandboxProgressEvents as Qi, reconnectRetainedRun as Qn, assertProfileMaterialization as Qr, workerTraceSeamKey as Qt, validateWaitSpec as R, detachedFrozen as Ri, LEAF_CONTINUATION_TASK as Rn, runSettledCommand as Rr, parseWorkerToolTraceArtifact as Rt, assertRecursiveReservationPolicy as S, armDeadlineTimer as Sa, inheritRuntimeOwnedExecutorAttestation as Si, bridgeStopSignalKey as Sn, buildLoopSpanNodes as Sr, createInPlaceCliExecutor as St, deriveNodeExecutionIdentity as T, promptFromAgentTurnInput as Ta, newExecutionAttemptId as Ti, defaultSelectWinner as Tn, createOtelExporter as Tr, InMemoryResultBlobStore as Tt, prepareScopeRetainedOwnerTask as U, canonicalStreamEventFromSandboxEvent as Ui, sandboxClientAsProvider as Un, DEFAULT_LOCAL_HARNESS as Ur, createBudgetPool as Ut, bindScopeRetainedOwnerProvider as V, readSandboxOutcome as Vi, providerAsSandboxClient as Vn, createWorktree as Vr, ReservationWaitRefused as Vt, reconcileScopeRetainedOwnerEnvironment as W, createSandboxToolPartState as Wi, unavailablePauseMs as Wn, LOCAL_HARNESSES as Wr, meterUsageEvent as Wt, environmentReader as X, notifySandboxEventObserver as Xi, retainedExecutorSeamKey as Xn, terminateProcessTreeAndConfirm as Xr, workerTraceEnv as Xt, SPAWN_RESOURCE_PATH_MAX_BYTES as Y, mapSandboxToolEvent as Yi, registerRetainedExecutorPreparation as Yn, CodexExecutionDiagnosticError as Yr, readWorkerTraceContext as Yt, hostDirectoryReader as Z, sandboxEventServedBackend as Zi, errMessage as Zn, AGENT_PROFILE_MATERIALIZATION_AXES as Zr, workerTraceHeaders as Zt, driverChild as _, withBudgetResources as _a, writeAllBytes as _i, addHarnessUsage as _n, mergeTraceEnv as _r, createExecutorRegistry as _t, collectDelivered as a, isAbortError$2 as aa, promptOnlyProfileMaterialization as ai, DEFAULT_PEER_MAIL_LIMITS as an, RunCancellationReason as ar, workerInteractiveBindingsDir as at, withDriverExecutor as b, awaitAbortable$1 as ba, authoredProfileDigest as bi, readCodexRolloutSession as bn, INTELLIGENCE_WIRE_VERSION as br, DEFAULT_SANDBOX_STEERING_MAX_TURNS as bt, runTree as c, sleep as ca, renderUnsupported as ci, createPeerMailbox as cn, runAbortable as cr, startRetainedInteractiveRun as ct, HarnessTurnFailedError as d, throwIfAborted as da, validateProfileMaterialization as di, peerMailVerbNames as dn, resolveRedactor as dr, rollingDispatch as dt, addSpend as ea, defineProfileMaterializationContract as ei, DEFAULT_STALL_AFTER_MS as en, startRetainedRun as er, readWorkerInteractiveAdmissions as et, classifyDriverFailure as f, unmeteredSpend as fa, worktreeCliProfileMaterialization as fi, isLiveNodeStatus as fn, captureHarnessTranscript as fr, bindReusableExecutorExecutionId as ft, upstreamUnavailableSignal as g, resourceTelemetry as ga, readCommittedJsonLines as gi, bridgeModelRouteRefusal as gn, createPropagatingTraceEmitter as gr, createExecutor as gt, summarizeDriverAttempts as h, addResourceSpend as ha, prepareJsonlAppend as hi, bridgeAdmissionRefusal as hn, contentAddress as hr, cliWorktreeExecutor as ht, bestDelivered as i, hasCompleteCacheBreakdown as ia, promptModelProfileMaterialization as ii, AUTHORITY_MARKERS as in, environmentGone as ir, workerInteractiveBindingFile as it, scopeOwnerExecutorNodeContext as j, runtimeOwnedExecutorProviderEvidence as ji, assertBoxlessPromptOptions as jn, padTraceId as jr, loadSpawnForest as jt, recordScopeOwnerPause as k, runtimeOwnedExecutorExecutionBinding as ki, probeSandboxCapabilities as kn, loopEventToOtelSpan as kr, encodeResultBlob as kt, DEFAULT_MAX_BARREN_REPROMPTS as l, stringifySafe as la, sandboxActProfileMaterialization as li, isPeerMailEnvelope as ln, defaultRedactor as lr, freeSlots as lt, runDriverWithRetry as m, zeroSpend as ma, parseCommittedJsonLines as mi, executorFailure as mn, persistHarnessTranscript as mr, cliInPlaceExecutor as mt, createRootHandle as n, cloneSpend as na, profileMaterializationAxes$1 as ni, readWorkerProgress as nn, retainedCreateMaterial as nr, attachWorker as nt, pickBestDelivered as o, promptCacheTokenClasses as oa, promptResourceProfileMaterialization as oi, PEER_MAIL_WIRE_KEY as on, abortError as or, reconnectRetainedInteractiveRun as ot, defaultUnmetContractSteer as p, withTimeout as pa, isNoEntError as pi, isTerminalNodeStatus as pn, harnessTranscriptArtifact as pr, captureReusableExecutorConfig as pt, scopeRetainedOwnerResourceReader as q, isSandboxTerminalEvent as qi, decodeToolPart as qn, localHarnessExecutable as qr, spendFromUsageTotals as qt, createSupervisor as r, deleteBoxSafe as ra, promptControlProfileMaterialization as ri, createInbox as rn, destroyInteractiveEnvironment as rr, readWorkerInteractiveBinding as rt, runFinalizer as s, randomSuffix as sa, renderProfileMaterializationIssues as si, claimsAuthority as sn, linkAbort as sr, recoverRetainedInteractiveRun as st, DEFAULT_MAX_DEPTH as t, chargedTokens as ta, fullProfileMaterialization as ti, createActivityLog as tn, startRetainedRunInEnvironment as tr, workerInteractiveAdmissionFile as tt, DriverAttemptsExhaustedError as u, throwAbort as ua, unsupportedProfileDimensions as ui, peerMailTools as un, defaultRedactorIdentityMaterial as ur, queueOf as ut, driverExecutorFactory as v, decodeHarnessUsage as va, attestRuntimeOwnedPendingExecutor as vi, createCodexRolloutStoreReader as vn, readTraceContextFromEnv as vr, snapshotExecutorConfig as vt, createScope as w, teardownSurfaces as wa, knownMaterializationReceipt as wi, createSandboxForSpec as wn, createOpenInferenceFileExporter as wr, FileSpawnJournal as wt, SUBTREE_RESULT_LIMIT as x, DEFAULT_SUCCESSFUL_SHUTDOWN_MS as xa, finalizeRuntimeOwnedPendingExecutor as xi, bridgeRuntimeAttachmentsKey as xn, buildLoopOtelSpans as xr, createSteerableSandboxSession as xt, isDriverSpec as y, abortError$2 as ya, attestRuntimeOwnedScopeOwner as yi, harnessUsageIsEmpty as yn, traceContextToEnv as yr, createWorktreeCliExecutor as yt, waitUntil as z, detachedSnapshot as zi, createAgentEnvironmentProviderRegistry as zn, runWorktreeHarness as zr, workerTraceAnalysisStore as zt };
27933
+ export { bindScopeRetainedOwnerProvider as $, detachedSnapshot as $i, providerAsExecutor as $n, runWorktreeHarness as $r, BudgetReconcileFault as $t, driverExecutorFactory as A, resourceTelemetry as Aa, readCommittedJsonLines as Ai, addHarnessUsage as An, createPropagatingTraceEmitter as Ar, snapshotExecutorConfig as At, recordScopeOwnerMaterialization as B, promptOptionsFromAgentTurnInput as Ba, providerAttemptEvidence as Bi, runAgentRounds as Bn, exportEvalRuns as Br, SpawnEventIndex as Bt, createContinuationKeeper as C, stringifySafe as Ca, sandboxActProfileMaterialization as Ci, peerMailTools as Cn, defaultRedactorIdentityMaterial as Cr, rollingDispatch as Ct, passedItems as D, withTimeout as Da, isNoEntError as Di, executorFailure as Dn, persistHarnessTranscript as Dr, cliWorktreeExecutor as Dt, failedItems as E, unmeteredSpend as Ea, worktreeCliProfileMaterialization as Ei, isTerminalNodeStatus as En, harnessTranscriptArtifact as Er, cliInPlaceExecutor as Et, beginScopeOwnerAttempt as F, DEFAULT_SUCCESSFUL_SHUTDOWN_MS as Fa, finalizeRuntimeOwnedPendingExecutor as Fi, bridgeStopSignalKey as Fn, buildLoopOtelSpans as Fr, createInPlaceCliExecutor as Ft, createWorkerSlots as G, runtimeOwnedExecutorProviderEvidence as Gi, readPromptOptions as Gn, padTraceId as Gr, materializeTreeView as Gt, restoreScopeOwnerAcceptedExecution as H, runtimeOwnedDriveHarnessProviderEvidence as Hi, probeSandboxCapabilities as Hn, generateSpanId as Hr, encodeResultBlob as Ht, createScope as I, armDeadlineTimer as Ia, inheritRuntimeOwnedExecutorAttestation as Ii, TERMINAL_DECISIONS as In, buildLoopSpanNodes as Ir, FileResultBlobStore as It, pollFor as J, unknownExecutionBindingReceipt as Ji, canonicalObservedModelParts as Jn, createRuntimeStreamEventCollector as Jr, WORKER_TOOL_TRACE_SCHEMA_VERSION as Jt, createWaitProbes as K, runtimeOwnedPendingExecutorMaterialization as Ki, routerBrain as Kn, toOtelAttributes as Kr, pendingWaits as Kt, deriveNodeExecutionIdentity as L, teardownExecutor as La, knownExecutionBindingReceipt as Li, createSandboxForSpec as Ln, buildRuntimeEventOtelSpans as Lr, FileSpawnJournal as Lt, withDriverExecutor as M, decodeHarnessUsage as Ma, attestRuntimeOwnedPendingExecutor as Mi, harnessUsageIsEmpty as Mn, readTraceContextFromEnv as Mr, DEFAULT_SANDBOX_STEERING_MAX_TURNS as Mt, SUBTREE_RESULT_LIMIT as N, abortError$2 as Na, attestRuntimeOwnedScopeOwner as Ni, readCodexRolloutSession as Nn, traceContextToEnv as Nr, createSteerableSandboxSession as Nt, verdictFromJudgeScore as O, zeroSpend as Oa, parseCommittedJsonLines as Oi, bridgeAdmissionRefusal as On, readHarnessTranscript as Or, createExecutor as Ot, assertRecursiveReservationPolicy as P, awaitAbortable$1 as Pa, authoredProfileDigest as Pi, bridgeRuntimeAttachmentsKey as Pn, INTELLIGENCE_WIRE_VERSION as Pr, createRouterTranscript as Pt, bindScopeRetainedOwnerEnvironmentId as Q, detachedFrozen as Qi, createAgentEnvironmentProviderRegistry as Qn, runSettledCommand as Qr, workerTraceAnalysisStore as Qt, meterRuntimeOwnedAccounting as R, teardownSurfaces as Ra, knownMaterializationReceipt as Ri, defaultSelectWinner as Rn, createOpenInferenceFileExporter as Rr, InMemoryResultBlobStore as Rt, composeContinuationNote as S, sleep as Sa, renderUnsupported as Si, isPeerMailEnvelope as Sn, defaultRedactor as Sr, queueOf as St, expandQuestions as T, throwIfAborted as Ta, validateProfileMaterialization as Ti, isLiveNodeStatus as Tn, captureHarnessTranscript as Tr, captureReusableExecutorConfig as Tt, scopeOwnerExecutorNodeContext as U, runtimeOwnedExecutorExecutionBinding as Ui, acquireSandbox as Un, loopEventToOtelSpan as Ur, insideCursorNamespace as Ut, recordScopeOwnerPause as V, providerMessageText as Va, recordRuntimeOwnedDriveHarnessProviderEvidence as Vi, createSandboxLineage as Vn, flatOtelSpan as Vr, assertContentAddress as Vt, settledToIteration as W, runtimeOwnedExecutorMaterialization as Wi, assertBoxlessPromptOptions as Wn, padSpanId as Wr, loadSpawnForest as Wt, validateWaitSpec as X, executableAgentProfileSnapshot as Xi, DEFAULT_SANDBOX_IDLE_TIMEOUT_SECONDS as Xn, sanitizeKnowledgeReadinessReport as Xr, isTraceAnalysisStore as Xt, timerAt as Y, unknownMaterializationReceipt as Yi, observedModelMatchesDeclared as Yn, sanitizeAgentRuntimeEvent as Yr, captureWorkerTraceEvidence as Yt, waitUntil as Z, executableAgentSpecSnapshot as Zi, LEAF_CONTINUATION_TASK as Zn, sanitizeRuntimeStreamEvent as Zr, parseWorkerToolTraceArtifact as Zt, CheckUnavailableError as _, deleteBoxSafe as _a, promptControlProfileMaterialization as _i, AUTHORITY_MARKERS as _n, environmentGone as _r, workerInteractiveBindingsDir as _t, collectDelivered as a, createSandboxUsageLedger as aa, harnessInvocation as ai, spendFromUsageEvents as an, createPushTraceSource as ar, scopeRetainedOwnerResourceReader as at, bestComposite as b, promptCacheTokenClasses as ba, promptResourceProfileMaterialization as bi, claimsAuthority as bn, linkAbort as br, startRetainedInteractiveRun as bt, runTree as c, mapSandboxEvent as ca, parseCodexTokenUsage as ci, readWorkerTraceContext as cn, registerRetainedExecutorPreparation as cr, environmentReader as ct, classifyDriverFailure as d, sandboxEventServedBackend as da, AGENT_PROFILE_MATERIALIZATION_AXES as di, workerTraceSeamKey as dn, reconnectRetainedRun as dr, interactiveAdmissionSeamKey as dt, projectSandboxOutcome as ea, captureWorktreeDiff as ei, ReservationWaitRefused as en, providerAsSandboxClient as er, consumeScopeRetainedOwnerResult as et, runDriverWithRetry as f, sandboxProgressEvents as fa, assertProfileMaterialization as fi, taskToPrompt as fn, recoverRetainedRun as fr, readWorkerInteractiveAdmissions as ft, CONTINUATION_FACTS as g, cloneSpend as ga, profileMaterializationAxes$1 as gi, createInbox as gn, destroyInteractiveEnvironment as gr, workerInteractiveBindingFile as gt, CONTINUATIONS_DIR as h, chargedTokens as ha, fullProfileMaterialization as hi, readWorkerProgress as hn, retainedCreateMaterial as hr, readWorkerInteractiveBinding as ht, bestDelivered as i, createSandboxToolPartState as ia, LOCAL_HARNESSES as ii, newUsageTotals as in, unavailableSignalOfFailure as ir, scopeRetainedOwnerPriorSpend as it, isDriverSpec as j, withBudgetResources as ja, writeAllBytes as ji, createCodexRolloutStoreReader as jn, mergeTraceEnv as jr, createWorktreeCliExecutor as jt, driverChild as k, addResourceSpend as ka, prepareJsonlAppend as ki, bridgeModelRouteRefusal as kn, contentAddress as kr, createExecutorRegistry as kt, DriverAttemptsExhaustedError as l, mapSandboxToolEvent as la, CodexExecutionDiagnosticError as li, workerTraceEnv as ln, retainedExecutorSeamKey as lr, hostDirectoryReader as lt, upstreamUnavailableSignal as m, addSpend as ma, defineProfileMaterializationContract as mi, createActivityLog as mn, startRetainedRunInEnvironment as mr, attachWorker as mt, createRootHandle as n, assertSandboxServedModel as na, removeWorktree as ni, createBudgetPool as nn, sandboxClientAsProvider as nr, reconcileScopeRetainedOwnerEnvironment as nt, pickBestDelivered as o, extractLlmCallEvent as oa, harnessSupportsReasoningEffort as oi, spendFromUsageTotals as on, decodeToolPart as or, scopeRetainedOwnerResult as ot, summarizeDriverAttempts as p, sumSandboxUsage as pa, controlProfileMaterialization as pi, DEFAULT_STALL_AFTER_MS as pn, startRetainedRun as pr, workerInteractiveAdmissionFile as pt, isWaitOutcome as q, runtimeOwnedScopeOwnerRuntime as qi, runBrainLoop as qn, createRuntimeEventCollector as qr, replaySpawnTree as qt, createSupervisor as r, canonicalStreamEventFromSandboxEvent as ra, DEFAULT_LOCAL_HARNESS as ri, meterUsageEvent as rn, unavailablePauseMs as rr, scopeRetainedOwnerContext as rt, runFinalizer as s, isSandboxTerminalEvent as sa, localHarnessExecutable as si, WORKER_TRACE_PROPAGATION as sn, sandboxSessionTraceSource as sr, SPAWN_RESOURCE_PATH_MAX_BYTES as st, DEFAULT_MAX_DEPTH as t, readSandboxOutcome as ta, createWorktree as ti, assertValidBudget as tn, resolveAgentEnvironmentProvider as tr, prepareScopeRetainedOwnerTask as tt, HarnessTurnFailedError as u, notifySandboxEventObserver as ua, terminateProcessTreeAndConfirm as ui, workerTraceHeaders as un, errMessage as ur, resolveSpawnResourcePaths as ut, admitContinuationPolicy as v, hasCompleteCacheBreakdown as va, promptModelProfileMaterialization as vi, DEFAULT_PEER_MAIL_LIMITS as vn, RunCancellationReason as vr, reconnectRetainedInteractiveRun as vt, distillFindings as w, throwAbort as wa, unsupportedProfileDimensions as wi, peerMailVerbNames as wn, resolveRedactor as wr, bindReusableExecutorExecutionId as wt, checkVerdictOf as x, randomSuffix as xa, renderProfileMaterializationIssues as xi, createPeerMailbox as xn, runAbortable as xr, freeSlots as xt, admitFinding as y, isAbortError$2 as ya, promptOnlyProfileMaterialization as yi, PEER_MAIL_WIRE_KEY as yn, abortError as yr, recoverRetainedInteractiveRun as yt, meterRuntimeOwnedProviderAttempt as z, promptFromAgentTurnInput as za, newExecutionAttemptId as zi, isTerminalDecision as zn, createOtelExporter as zr, InMemorySpawnJournal as zt };
27203
27934
 
27204
- //# sourceMappingURL=supervisor-Cvd5mf7x.js.map
27935
+ //# sourceMappingURL=supervisor-DdKPGluv.js.map