@tangle-network/agent-runtime 0.301.0 → 0.306.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/{activation-V6aaOlZV.js → activation-C5wesfzd.js} +3 -3
  2. package/dist/{activation-V6aaOlZV.js.map → activation-C5wesfzd.js.map} +1 -1
  3. package/dist/{activation-CRgEJutr.d.ts → activation-wZ-8vOjV.d.ts} +88 -13
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/{bundle-C9v5TH_H.js → bundle-C8EO05u3.js} +2 -2
  7. package/dist/{bundle-C9v5TH_H.js.map → bundle-C8EO05u3.js.map} +1 -1
  8. package/dist/candidate-execution/index.d.ts +3 -26
  9. package/dist/candidate-execution/index.js +6 -6
  10. package/dist/{coordination-driver-vNrdQBSH.js → coordination-driver-yj9HPXef.js} +9 -16
  11. package/dist/coordination-driver-yj9HPXef.js.map +1 -0
  12. package/dist/{delegate-B-jFJcbW.js → delegate-KtrL9HWq.js} +2 -2
  13. package/dist/{delegate-B-jFJcbW.js.map → delegate-KtrL9HWq.js.map} +1 -1
  14. package/dist/durable.d.ts +3 -15
  15. package/dist/durable.js +158 -124
  16. package/dist/durable.js.map +1 -1
  17. package/dist/{graph-Dwv_hQB_.js → graph-DcdyHbgf.js} +4 -5
  18. package/dist/graph-DcdyHbgf.js.map +1 -0
  19. package/dist/{improvement-cycle-Cf37Kexd.js → improvement-cycle-DsN-TVXR.js} +1129 -10
  20. package/dist/improvement-cycle-DsN-TVXR.js.map +1 -0
  21. package/dist/{index-CxBVmgqL.d.ts → index-DflDZq_I.d.ts} +50 -688
  22. package/dist/index.d.ts +378 -12
  23. package/dist/index.js +223 -320
  24. package/dist/index.js.map +1 -1
  25. package/dist/intelligence.d.ts +5 -5
  26. package/dist/intelligence.js +7 -8
  27. package/dist/intelligence.js.map +1 -1
  28. package/dist/kernel.d.ts +4 -4
  29. package/dist/kernel.js +9 -9
  30. package/dist/{loop-runner-bin-DiTNiJNs.d.ts → loop-runner-bin-DZfRUVWy.d.ts} +3 -3
  31. package/dist/{loop-runner-bin-C8MI8N1A.js → loop-runner-bin-rVrSX5l1.js} +3 -3
  32. package/dist/{loop-runner-bin-C8MI8N1A.js.map → loop-runner-bin-rVrSX5l1.js.map} +1 -1
  33. package/dist/loop-runner-bin.d.ts +1 -1
  34. package/dist/loop-runner-bin.js +1 -1
  35. package/dist/mcp/bin.js +3 -3
  36. package/dist/mcp/index.d.ts +6 -35
  37. package/dist/mcp/index.js +311 -364
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/model-policy-DydyWTQg.js.map +1 -1
  40. package/dist/{openai-tools-BeogJ6V8.d.ts → openai-tools-YO30D2s3.d.ts} +2 -2
  41. package/dist/{prepare-CGVNMb1o.js → prepare--nWcazPr.js} +7 -13
  42. package/dist/prepare--nWcazPr.js.map +1 -0
  43. package/dist/{profile-BetOB4_Q.js → profile-h04LDjV6.js} +2 -2
  44. package/dist/{profile-BetOB4_Q.js.map → profile-h04LDjV6.js.map} +1 -1
  45. package/dist/profiles.d.ts +2 -94
  46. package/dist/profiles.js +2 -451
  47. package/dist/profiles.js.map +1 -1
  48. package/dist/{protected-model-port-CAa0t1MT.d.ts → protected-model-port-C9QtEf3y.d.ts} +2 -2
  49. package/dist/{protected-model-port-CuVHkhti.js → protected-model-port-wwalbyXM.js} +4 -4
  50. package/dist/{protected-model-port-CuVHkhti.js.map → protected-model-port-wwalbyXM.js.map} +1 -1
  51. package/dist/{provision-supervisor-CS0fBIhp.js → provision-supervisor-WxFEFQeJ.js} +4 -3
  52. package/dist/{provision-supervisor-CS0fBIhp.js.map → provision-supervisor-WxFEFQeJ.js.map} +1 -1
  53. package/dist/{runtime-6VPSJVeg.js → runtime-B9eBIyws.js} +67 -469
  54. package/dist/runtime-B9eBIyws.js.map +1 -0
  55. package/dist/{search-method-wTTS7mGG.js → search-executor-2tWr38Qw.js} +239 -1132
  56. package/dist/search-executor-2tWr38Qw.js.map +1 -0
  57. package/dist/{server-BfHD5iLD.js → server-CpKcrOPj.js} +5 -12
  58. package/dist/server-CpKcrOPj.js.map +1 -0
  59. package/dist/{stream-agent-turn-B1ipFtOc.d.ts → stream-agent-turn-B1giFgOg.d.ts} +2 -2
  60. package/dist/{substrate-DKBMd0Dl.d.ts → substrate-L_sC7jCD.d.ts} +2 -2
  61. package/dist/{supervise-BJrEC2Mh.js → supervise-DllOHM4M.js} +14 -24
  62. package/dist/supervise-DllOHM4M.js.map +1 -0
  63. package/dist/{supervisor-DA_nvF-h.js → supervisor-gCfG6K1-.js} +488 -1407
  64. package/dist/supervisor-gCfG6K1-.js.map +1 -0
  65. package/dist/testing.d.ts +2 -2
  66. package/dist/testing.js +14 -14
  67. package/dist/tui/index.d.ts +1 -1
  68. package/dist/tui/index.js +1 -1
  69. package/dist/{types-jD9mNnJM.d.ts → types-DeuEkBhI.d.ts} +114 -258
  70. package/dist/{workspace-archive-pz8YJ1fr.d.ts → workspace-streams-CpSmt3zx.d.ts} +67 -3
  71. package/dist/{workspace-streams-D5gHJdTb.js → workspace-streams-ILw0eWZ0.js} +694 -2
  72. package/dist/workspace-streams-ILw0eWZ0.js.map +1 -0
  73. package/package.json +8 -8
  74. package/skills/generate-eval/SKILL.md +1 -1
  75. package/skills/profile-authoring/SKILL.md +2 -2
  76. package/dist/coordination-driver-vNrdQBSH.js.map +0 -1
  77. package/dist/graph-Dwv_hQB_.js.map +0 -1
  78. package/dist/improvement-cycle-Cf37Kexd.js.map +0 -1
  79. package/dist/prepare-CGVNMb1o.js.map +0 -1
  80. package/dist/runtime-6VPSJVeg.js.map +0 -1
  81. package/dist/search-method-wTTS7mGG.js.map +0 -1
  82. package/dist/server-BfHD5iLD.js.map +0 -1
  83. package/dist/supervise-BJrEC2Mh.js.map +0 -1
  84. package/dist/supervisor-DA_nvF-h.js.map +0 -1
  85. package/dist/workspace-streams-D5gHJdTb.js.map +0 -1
@@ -1,3 +1,5 @@
1
+ import { m as ValidationError } from "./errors-DodWX-cb.js";
2
+ import { runTaskQueue } from "./task-queue.js";
1
3
  import { agentCandidateArtifactRefSchema, canonicalCandidateBytes as canonicalCandidateBytes$1 } from "@tangle-network/agent-interface";
2
4
  import { createHash, randomUUID } from "node:crypto";
3
5
  import { spawn } from "node:child_process";
@@ -9,6 +11,618 @@ import { Readable } from "node:stream";
9
11
  import { pipeline } from "node:stream/promises";
10
12
  import { extract, pack } from "tar-stream";
11
13
  import { isAnyArrayBuffer, isSharedArrayBuffer } from "node:util/types";
14
+ //#region src/runtime/supervise/deadline.ts
15
+ const MAX_TIMER_DELAY_MS = 2147483647;
16
+ const DEFAULT_SUCCESSFUL_SHUTDOWN_MS = 5e3;
17
+ /** The abort reason a child's own deadline carries. */
18
+ const CHILD_DEADLINE_REASON = "child deadline exceeded";
19
+ /** The abort reason the root's budget deadline cascades to every node. */
20
+ const ROOT_DEADLINE_REASON = "root budget deadline exceeded";
21
+ /**
22
+ * How long an abort waits for a manager whose result was already accepted to end the turn that
23
+ * submitted it. Acceptance asks the turn's harness to stop; what remains is the turn's final
24
+ * session copy (a bounded native capture), metering its usage and committing its result. Its
25
+ * workspace capture is not part of it: the manager's owner runs that after the result.
26
+ */
27
+ const ACCEPTED_RESULT_GRACE_MS = 5 * 6e4;
28
+ /** Whether an abort reason is a deadline: the child's own or the root budget's. */
29
+ function isDeadlineAbortReason(reason) {
30
+ return reason === "child deadline exceeded" || reason === "root budget deadline exceeded";
31
+ }
32
+ const TEARDOWN_ACKNOWLEDGEMENT_MS = 250;
33
+ /** Arm a finite wall-clock deadline in safe chunks. Resource deadlines unref by default;
34
+ * a standalone wait opts into keeping the process alive until it settles or is cancelled. */
35
+ function armDeadlineTimer(delayMs, onDeadline, keepAlive = false) {
36
+ const deadlineAtMs = Date.now() + Math.max(0, delayMs);
37
+ if (!Number.isFinite(delayMs) || !Number.isSafeInteger(Math.ceil(deadlineAtMs))) throw new ValidationError("timer delay must produce a finite safe deadline");
38
+ let cleared = false;
39
+ let timer;
40
+ const arm = () => {
41
+ if (cleared) return;
42
+ const remainingMs = Math.max(0, deadlineAtMs - Date.now());
43
+ timer = setTimeout(() => {
44
+ if (cleared) return;
45
+ if (Date.now() >= deadlineAtMs) onDeadline();
46
+ else arm();
47
+ }, Math.min(remainingMs, MAX_TIMER_DELAY_MS));
48
+ if (!keepAlive && typeof timer.unref === "function") timer.unref();
49
+ };
50
+ arm();
51
+ return () => {
52
+ cleared = true;
53
+ if (timer !== void 0) clearTimeout(timer);
54
+ };
55
+ }
56
+ /**
57
+ * Resolve a spawned child's duration into one absolute cutoff. An omitted child deadline inherits
58
+ * the parent cutoff; an explicit child duration may shorten, but never extend, that cutoff.
59
+ */
60
+ function boundedChildDeadlineAt(parentDeadlineAtMs, childDeadlineMs, nowMs) {
61
+ const parent = parentDeadlineAtMs > 0 ? parentDeadlineAtMs : void 0;
62
+ const child = childDeadlineMs === void 0 ? void 0 : nowMs + childDeadlineMs;
63
+ if (parent === void 0) return child;
64
+ if (child === void 0) return parent;
65
+ return Math.min(parent, child);
66
+ }
67
+ /** Invoke teardown once and bound how long the runtime waits for its acknowledgement. A hard
68
+ * execution deadline always wins; without one, numeric grace gets a short acknowledgement
69
+ * allowance and a brutal kill gets only that allowance. Explicit `infinity` remains unbounded
70
+ * only when no execution deadline exists. The losing promise stays observed. `ask` issues the
71
+ * request; a scope passes its per-child single-flight asker (see `singleFlightTeardown`). */
72
+ async function teardownExecutor(executor, grace, deadlineAtMs, now, ask = (requested) => Promise.resolve(executor.teardown(requested))) {
73
+ const work = Promise.resolve(ask(grace));
74
+ const requestedWaitMs = grace === "infinity" ? void 0 : grace === "brutalKill" ? executor.teardownTimeoutMs ?? TEARDOWN_ACKNOWLEDGEMENT_MS : grace + TEARDOWN_ACKNOWLEDGEMENT_MS;
75
+ const deadlineWaitMs = deadlineAtMs === void 0 ? void 0 : Math.max(0, deadlineAtMs - now()) + TEARDOWN_ACKNOWLEDGEMENT_MS;
76
+ const waitMs = requestedWaitMs === void 0 ? deadlineWaitMs : deadlineWaitMs === void 0 ? requestedWaitMs : Math.min(requestedWaitMs, deadlineWaitMs);
77
+ let receipt;
78
+ if (waitMs === void 0) receipt = await work;
79
+ else if (waitMs <= 0) {
80
+ work.catch(() => void 0);
81
+ throw new ValidationError("executor teardown did not acknowledge before its deadline");
82
+ } else {
83
+ let clearTimer;
84
+ const timedOut = new Promise((_resolve, reject) => {
85
+ clearTimer = armDeadlineTimer(waitMs, () => reject(new ValidationError(`executor teardown did not acknowledge within ${waitMs}ms`)), true);
86
+ });
87
+ try {
88
+ receipt = await Promise.race([work, timedOut]);
89
+ } finally {
90
+ clearTimer?.();
91
+ }
92
+ }
93
+ if (!receipt.destroyed) throw new ValidationError(`executor teardown reported destroyed=false${receipt.detail ? `: ${receipt.detail}` : ""}`);
94
+ }
95
+ /**
96
+ * The optional teardown surfaces a wrapping executor forwards, so wrapping never changes how a
97
+ * child is released: the acknowledgement window a remote teardown needs, the release of a
98
+ * retained execution at root settlement, and the environments an unconfirmed teardown names for
99
+ * a sweeper. A wrapper that dropped `releaseRetained` left every retained child it wrapped
100
+ * running after settlement. Each surface is present only when the inner executor implements it.
101
+ */
102
+ function teardownSurfaces(inner) {
103
+ return {
104
+ ...inner.teardownTimeoutMs === void 0 ? {} : { teardownTimeoutMs: inner.teardownTimeoutMs },
105
+ ...inner.releaseRetained === void 0 ? {} : { releaseRetained: (signal) => inner.releaseRetained(signal) },
106
+ ...inner.heldEnvironments === void 0 ? {} : { heldEnvironments: () => inner.heldEnvironments() }
107
+ };
108
+ }
109
+ /**
110
+ * An asker that sends an executor at most one teardown at a time. While a request is still
111
+ * running, every later ask returns that same request instead of sending another beside it.
112
+ *
113
+ * A settlement's own teardown has a short acknowledgement window, and a request that misses it
114
+ * keeps running. Without this, the first settlement retry sent a second teardown next to the
115
+ * first. An executor that does not deduplicate internally, such as one that re-issues its
116
+ * cancels, then ran two teardowns at once. `onRequest` runs once for each request actually sent.
117
+ */
118
+ function singleFlightTeardown(executor, onRequest) {
119
+ let inFlight;
120
+ return (grace) => {
121
+ if (inFlight !== void 0) return inFlight;
122
+ onRequest();
123
+ let request;
124
+ try {
125
+ request = Promise.resolve(executor.teardown(grace));
126
+ } catch (error) {
127
+ request = Promise.reject(error);
128
+ }
129
+ inFlight = request;
130
+ const settle = () => {
131
+ if (inFlight === request) inFlight = void 0;
132
+ };
133
+ request.then(settle, settle);
134
+ return request;
135
+ };
136
+ }
137
+ //#endregion
138
+ //#region src/runtime/supervise/resources.ts
139
+ /** Validate caller-owned names and units without assigning domain meaning to them. */
140
+ function assertResources(resources, kind, label) {
141
+ if (resources === void 0) return;
142
+ if (resources === null || typeof resources !== "object" || Array.isArray(resources)) throw new Error(`${label} must be a resource map`);
143
+ for (const [name, resource] of Object.entries(resources)) {
144
+ if (!name.trim() || !resource || typeof resource !== "object" || typeof resource.unit !== "string" || !resource.unit.trim()) throw new Error(`${label}: resource names and units must be non-empty strings`);
145
+ const value = kind === "limit" ? "limit" in resource ? resource.limit : void 0 : "amount" in resource ? resource.amount : void 0;
146
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) throw new Error(`${label}.${name}.${kind} must be a non-negative safe integer`);
147
+ if (kind === "amount" && (!("known" in resource) || typeof resource.known !== "boolean")) throw new Error(`${label}.${name}.known must be a boolean`);
148
+ }
149
+ }
150
+ /** Missing contributors are not usage claims; enforced omissions are marked before aggregation.
151
+ * Overflow retains a safe lower bound and marks it unknown, preserving readable component receipts. */
152
+ function addResourceSpend(...maps) {
153
+ const totals = /* @__PURE__ */ new Map();
154
+ for (const resources of maps) {
155
+ assertResources(resources, "amount", "resource spend");
156
+ for (const [name, resource] of Object.entries(resources ?? {})) {
157
+ const prior = totals.get(name);
158
+ if (prior && prior.unit !== resource.unit) throw new Error(`resource ${name}: unit mismatch`);
159
+ const amount = (prior?.amount ?? 0) + resource.amount;
160
+ totals.set(name, {
161
+ unit: resource.unit,
162
+ amount: Math.min(amount, Number.MAX_SAFE_INTEGER),
163
+ known: (prior?.known ?? true) && resource.known && Number.isSafeInteger(amount)
164
+ });
165
+ }
166
+ }
167
+ return totals.size ? { resources: Object.fromEntries(totals) } : {};
168
+ }
169
+ /** A terminal omission under an enforced ceiling is unknown, never measured zero. */
170
+ function withBudgetResources(spend, budget, notStarted = false) {
171
+ const resources = new Map(Object.entries(addResourceSpend(spend.resources).resources ?? {}));
172
+ for (const [name, limit] of Object.entries(budget.resources ?? {})) {
173
+ const observed = resources.get(name);
174
+ if (observed && observed.unit !== limit.unit) throw new Error(`resource ${name}: unit mismatch`);
175
+ if (!observed) resources.set(name, {
176
+ unit: limit.unit,
177
+ amount: 0,
178
+ known: notStarted
179
+ });
180
+ }
181
+ return resources.size ? {
182
+ ...spend,
183
+ resources: Object.fromEntries(resources)
184
+ } : spend;
185
+ }
186
+ /** Stream increments and a terminal total describe the same work; never sum them twice. */
187
+ function resourceTelemetry(streamed, terminal) {
188
+ const resources = new Map(Object.entries(addResourceSpend(terminal.resources).resources ?? {}));
189
+ for (const [name, value] of Object.entries(streamed.resources ?? {})) {
190
+ const other = resources.get(name);
191
+ if (other && other.unit !== value.unit) throw new Error(`resource ${name}: unit mismatch`);
192
+ resources.set(name, {
193
+ ...value,
194
+ amount: Math.max(value.amount, other?.amount ?? 0),
195
+ known: value.known && (other?.known ?? true) && (other === void 0 || other.amount === value.amount)
196
+ });
197
+ }
198
+ return addResourceSpend(Object.fromEntries(resources));
199
+ }
200
+ //#endregion
201
+ //#region src/runtime/util.ts
202
+ /**
203
+ * Best-effort sandbox delete. Skips instances without a `delete` (test fakes);
204
+ * swallows errors (the platform reaps on expiry). Returns `false` when delete
205
+ * threw, `true` otherwise, so callers can surface a leak if they choose.
206
+ */
207
+ async function deleteBoxSafe(box) {
208
+ if (!box || typeof box.delete !== "function") return true;
209
+ try {
210
+ await box.delete();
211
+ return true;
212
+ } catch {
213
+ return false;
214
+ }
215
+ }
216
+ /** Short base36 id for trace correlation. Not cryptographic, not collision-free. */
217
+ function randomSuffix(len = 8) {
218
+ return Math.random().toString(36).slice(2, 2 + len);
219
+ }
220
+ /** Collision-resistant id for sandbox naming (find-by-name recovery must be unique). */
221
+ function randomUuid() {
222
+ return crypto.randomUUID();
223
+ }
224
+ /** Construct an AbortError. Downstream code pattern-matches on `err.name`. */
225
+ function abortError() {
226
+ const err = /* @__PURE__ */ new Error("aborted");
227
+ err.name = "AbortError";
228
+ return err;
229
+ }
230
+ /** Throw an AbortError. */
231
+ function throwAbort() {
232
+ throw abortError();
233
+ }
234
+ /** Throw if the signal is already aborted; otherwise no-op. */
235
+ function throwIfAborted(signal) {
236
+ if (signal?.aborted) throw abortError();
237
+ }
238
+ /** True for any error whose `name` is `AbortError` (the cross-kernel abort contract). */
239
+ function isAbortError(err) {
240
+ return err instanceof Error && err.name === "AbortError";
241
+ }
242
+ /**
243
+ * Sleep that resolves early on abort and always clears its timer so it never
244
+ * keeps the event loop alive. Resolves (does not reject) on abort — callers
245
+ * re-check the signal explicitly after the sleep.
246
+ */
247
+ function sleep(ms, signal, keepAlive = true) {
248
+ if (signal?.aborted) return Promise.resolve();
249
+ return new Promise((resolve) => {
250
+ const done = () => {
251
+ clearTimer();
252
+ signal?.removeEventListener("abort", done);
253
+ resolve();
254
+ };
255
+ const clearTimer = armDeadlineTimer(ms, done, keepAlive);
256
+ signal?.addEventListener("abort", done, { once: true });
257
+ });
258
+ }
259
+ /**
260
+ * Race a promise against a timeout. Resolves with the value if it settles in
261
+ * time, otherwise resolves with `undefined`. Always clears the timer.
262
+ */
263
+ function withTimeout(promise, ms) {
264
+ return new Promise((resolve) => {
265
+ const clearTimer = armDeadlineTimer(ms, () => resolve(void 0), true);
266
+ promise.then((value) => {
267
+ clearTimer();
268
+ resolve(value);
269
+ }, () => {
270
+ clearTimer();
271
+ resolve(void 0);
272
+ });
273
+ });
274
+ }
275
+ /**
276
+ * `JSON.stringify` with a `String()` fallback on throw (cyclic / non-JSON).
277
+ * Strings pass through unstringified so a preview of a string output is the
278
+ * string itself, not a quoted re-encoding.
279
+ */
280
+ function stringifySafe(value, opts = {}) {
281
+ let s;
282
+ try {
283
+ if (typeof value === "string") s = value;
284
+ else s = (opts.pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value)) ?? String(value);
285
+ } catch {
286
+ s = String(value);
287
+ }
288
+ if (opts.max !== void 0 && s.length > opts.max) return `${s.slice(0, opts.max)}…`;
289
+ return s;
290
+ }
291
+ /** A fresh zero token-usage accumulator. */
292
+ function zeroTokenUsage() {
293
+ return {
294
+ input: 0,
295
+ output: 0
296
+ };
297
+ }
298
+ /**
299
+ * Sum the catalog-priced part of a dollar total across spends, as a field to spread.
300
+ *
301
+ * Returns nothing when no input carried one. A fold of pure provider receipts must not gain a
302
+ * `usdEstimated: 0`, which would read as "this runtime checked and priced none" on a path that
303
+ * never prices at all.
304
+ */
305
+ function usdEstimatedOf(...spends) {
306
+ let total = 0;
307
+ let priced = false;
308
+ for (const spend of spends) {
309
+ if (spend.usdEstimated === void 0) continue;
310
+ priced = true;
311
+ total += spend.usdEstimated;
312
+ }
313
+ return priced ? { usdEstimated: total } : {};
314
+ }
315
+ /** A conserved spend with every channel at zero and no completeness claim on it. */
316
+ function zeroSpend() {
317
+ return {
318
+ iterations: 0,
319
+ tokens: zeroTokenUsage(),
320
+ usd: 0,
321
+ ms: 0
322
+ };
323
+ }
324
+ /**
325
+ * The spend of work that HAPPENED and reported no usage receipt.
326
+ *
327
+ * Not the same value as {@link zeroSpend} even though both carry `{0,0}` tokens and `$0`. A bare
328
+ * zero asserts a MEASUREMENT — "this ran and cost nothing" — and every consumer downstream reads it
329
+ * that way: the pool keeps reporting `readout().tokensKnown === true`, the journal totals stay
330
+ * clean, the OTEL span records a priced zero, and a caller's token-denominated ceiling can never
331
+ * fire no matter how much the work really burned. A ceiling that cannot fire is worse than no
332
+ * ceiling, because it reads as protection.
333
+ *
334
+ * `tokensKnown` is the marker the substrate already threads end to end for exactly this case
335
+ * (`budget.ts`, `otel-spans.ts`, `spawn-journal.ts`, `supervisor.ts`): the work is recorded, the
336
+ * zero is labelled a floor rather than a total, and every rollup that touches it reports its
337
+ * balance as a ceiling rather than a measurement. Use this — never a bare zero — whenever a runtime
338
+ * cannot see what its worker spent.
339
+ *
340
+ * The same rule applies to dollars. A dollar-capped run must refuse an executor whose billed spend
341
+ * is unknowable; `budgetExempt` does not authorize Runtime to relabel unknown spend as a measured
342
+ * zero. Callers that require dollar accounting must use a backend with a trusted billing receipt.
343
+ */
344
+ function unmeteredSpend(ms) {
345
+ return {
346
+ iterations: 0,
347
+ tokens: zeroTokenUsage(),
348
+ tokensKnown: false,
349
+ usd: 0,
350
+ usdKnown: false,
351
+ ms
352
+ };
353
+ }
354
+ /** Copy a conserved spend without dropping a completeness marker or the catalog-priced part. */
355
+ function cloneSpend(spend) {
356
+ return {
357
+ ...addResourceSpend(spend.resources),
358
+ iterations: spend.iterations,
359
+ tokens: cloneTokenUsage(spend.tokens),
360
+ ...spend.tokensKnown === false ? { tokensKnown: false } : {},
361
+ usd: spend.usd,
362
+ ...spend.usdKnown === false ? { usdKnown: false } : {},
363
+ ...spend.usdEstimated !== void 0 ? { usdEstimated: spend.usdEstimated } : {},
364
+ ms: spend.ms,
365
+ ...boxMinutesOf(spend),
366
+ ...spend.tokensProvenance === void 0 ? {} : { tokensProvenance: spend.tokensProvenance }
367
+ };
368
+ }
369
+ /**
370
+ * Sum two conserved spends per channel. Tokens and dollars never fold into each other, an
371
+ * incomplete input keeps the sum incomplete on that channel, and the catalog-priced part of the
372
+ * dollar total is summed separately so `usd - usdEstimated` still names what a provider billed.
373
+ */
374
+ function addSpend(a, b) {
375
+ const tokens = cloneTokenUsage(a.tokens);
376
+ addTokenUsage(tokens, b.tokens);
377
+ return {
378
+ ...addResourceSpend(a.resources, b.resources),
379
+ iterations: a.iterations + b.iterations,
380
+ tokens,
381
+ ...a.tokensKnown === false || b.tokensKnown === false ? { tokensKnown: false } : {},
382
+ usd: a.usd + b.usd,
383
+ ...a.usdKnown === false || b.usdKnown === false ? { usdKnown: false } : {},
384
+ ...usdEstimatedOf(a, b),
385
+ ms: a.ms + b.ms,
386
+ ...boxMinutesOf(a, b),
387
+ ...tokensProvenanceOf(a, b)
388
+ };
389
+ }
390
+ /**
391
+ * Fold the token-provenance channel across spends, as a field to spread.
392
+ *
393
+ * Returns nothing when no contributor stated one, because ABSENT already means "the executor's own
394
+ * live stream", which is what every path reported before a harness store was readable. A
395
+ * contributor that stated one and a contributor that did not therefore disagree, and the sum is
396
+ * `'mixed'` — the honest answer for a tree whose spend came from two kinds of receipt.
397
+ */
398
+ function tokensProvenanceOf(...spends) {
399
+ let folded;
400
+ let sawStated = false;
401
+ for (const spend of spends) {
402
+ const stated = spend.tokensProvenance ?? "stream-receipt";
403
+ if (spend.tokensProvenance !== void 0) sawStated = true;
404
+ folded = folded === void 0 || folded === stated ? stated : "mixed";
405
+ }
406
+ return !sawStated || folded === void 0 || folded === "stream-receipt" ? {} : { tokensProvenance: folded };
407
+ }
408
+ /**
409
+ * Fold the platform box-time channel across spends, as a field to spread.
410
+ *
411
+ * Returns nothing when no input carried the channel, so a fold over router or cli-bridge work —
412
+ * which runs no box at all — never gains a `boxMinutesProvenance: 'uncaptured'` that would claim
413
+ * a box ran and went unmetered.
414
+ *
415
+ * Three rules, one per field:
416
+ * - `boxMinutes` sums the numbers that are present, and stays ABSENT when none is. A missing
417
+ * measurement never enters the sum as a zero.
418
+ * - `boxMinutesKnown` is sticky-false, like `tokensKnown`: one contributor that could not state
419
+ * its box time makes the whole sum a floor.
420
+ * - `boxMinutesProvenance` degrades. `'observed'` survives only when every contributor that
421
+ * carried a number was observed; one derived number makes the sum `'estimated'`; no number at
422
+ * all is `'uncaptured'`.
423
+ */
424
+ function boxMinutesOf(...spends) {
425
+ const present = spends.filter((spend) => spend.boxMinutesProvenance !== void 0);
426
+ if (present.length === 0) return {};
427
+ let minutes = 0;
428
+ let sawNumber = false;
429
+ let known = true;
430
+ let observedOnly = true;
431
+ for (const spend of present) {
432
+ if (typeof spend.boxMinutes === "number" && Number.isFinite(spend.boxMinutes)) {
433
+ minutes += spend.boxMinutes;
434
+ sawNumber = true;
435
+ if (spend.boxMinutesProvenance !== "observed") observedOnly = false;
436
+ }
437
+ if (spend.boxMinutesKnown !== true) known = false;
438
+ }
439
+ return {
440
+ ...sawNumber ? { boxMinutes: roundBoxMinutes(minutes) } : {},
441
+ boxMinutesKnown: known,
442
+ boxMinutesProvenance: sawNumber ? observedOnly ? "observed" : "estimated" : "uncaptured"
443
+ };
444
+ }
445
+ /**
446
+ * Box minutes at four decimals — a tenth of a second.
447
+ *
448
+ * Fine enough that a box alive for two seconds reports `0.0333` instead of a zero that would read
449
+ * as a measured free box, and coarse enough that summing floats does not print
450
+ * `1.5000000000000002`.
451
+ */
452
+ function roundBoxMinutes(minutes) {
453
+ return Number(minutes.toFixed(4));
454
+ }
455
+ /** Copy a token subtotal without dropping optional provider cache telemetry. */
456
+ function cloneTokenUsage(usage) {
457
+ const cacheBreakdownUnknown = usage.cacheBreakdownKnown === false || usage.input > 0 && !hasClassifiedCacheBreakdown(usage);
458
+ return {
459
+ input: usage.input,
460
+ output: usage.output,
461
+ ...usage.tokensKnown === false ? { tokensKnown: false } : {},
462
+ ...usage.freshInput !== void 0 ? { freshInput: usage.freshInput } : {},
463
+ ...usage.cacheRead !== void 0 ? { cacheRead: usage.cacheRead } : {},
464
+ ...usage.cacheWrite !== void 0 ? { cacheWrite: usage.cacheWrite } : {},
465
+ ...cacheBreakdownUnknown ? { cacheBreakdownKnown: false } : {}
466
+ };
467
+ }
468
+ /** True only when every positive prompt token has a consistent cache classification. */
469
+ function hasCompleteCacheBreakdown(usage) {
470
+ if (usage.cacheBreakdownKnown === false) return false;
471
+ return hasClassifiedCacheBreakdown(usage);
472
+ }
473
+ function hasClassifiedCacheBreakdown(usage) {
474
+ if (usage.input === 0) return true;
475
+ if (usage.freshInput === void 0 || usage.cacheRead === void 0 || usage.cacheWrite === void 0) return false;
476
+ return usage.freshInput + usage.cacheRead + usage.cacheWrite === usage.input;
477
+ }
478
+ /**
479
+ * The token charge for one observation: every token counted ONCE, at the moment it first enters
480
+ * the context — `input − cacheRead + output`.
481
+ *
482
+ * `input` is a rolled-up prompt total that re-counts a cached prefix on every turn that reads it,
483
+ * so charging `input` makes a 100K prefix read 40 times cost 4.1M for content authored once. A
484
+ * cache read is content that was already charged when it was written, so it is the one class the
485
+ * charge subtracts. Under a complete split the result is exactly `freshInput + cacheWrite`. No
486
+ * price weight is involved: this counts work, and money is a separate channel.
487
+ *
488
+ * The subtraction form is what makes the charge ADDITIVE. `input` and `cacheRead` both accumulate
489
+ * through `addTokenUsage`, so the charge on an aggregate equals the sum of the charges on the
490
+ * records that built it — including an aggregate that mixes classified and unclassified turns,
491
+ * where the unclassified remainder is charged in full and only the reported cache reads are
492
+ * credited. A form that read `freshInput + cacheWrite` directly loses that: one unclassified turn
493
+ * would drop the whole aggregate to `input + output` and over-charge every classified turn with it.
494
+ *
495
+ * The one arithmetic guarantee: a set of classes that does not FIT inside the prompt total it
496
+ * partitions credits nothing, so the charge is never below `output` and a class that overflows its
497
+ * own total buys no tokens. It is not a guarantee against a provider that reports a cache read it
498
+ * never served — that provider can under-report `input` just as easily, and the token channel is an
499
+ * accounting unit, not a trust boundary. Prompt tokens the provider left unclassified are charged
500
+ * in full, so a spend with no readable split charges an upper bound on newly-presented work rather
501
+ * than a measurement, and every caller that enforces a ceiling must report the difference
502
+ * (`BudgetPool` does it through `readout().cacheBreakdownKnown`).
503
+ */
504
+ function chargedTokens(usage) {
505
+ return usage.input - creditedCacheRead(usage) + usage.output;
506
+ }
507
+ /** `cacheRead` if the reported classes fit inside `input`, else nothing. */
508
+ function creditedCacheRead(usage) {
509
+ const { cacheRead } = usage;
510
+ if (cacheRead === void 0) return 0;
511
+ return classifiedTotal(usage, cacheRead) > usage.input ? 0 : cacheRead;
512
+ }
513
+ function classifiedTotal(usage, cacheRead) {
514
+ return (usage.freshInput ?? 0) + cacheRead + (usage.cacheWrite ?? 0);
515
+ }
516
+ /**
517
+ * Translate one provider prompt-cache report into the prompt token classes `addTokenUsage` folds
518
+ * and `chargedTokens` credits.
519
+ *
520
+ * The input is the open `promptCache` record an `llm_call` carries, keyed by the `PromptCacheUsage`
521
+ * vocabulary (`readTokens`, `writeTokens`). Providers report that vocabulary unevenly, and the
522
+ * three outcomes are different facts that must not collapse into one another:
523
+ *
524
+ * - **Nothing reported** — no classes and no marker. The caller's own unknown handling decides,
525
+ * because a provider that says nothing about caching has not said the split is unknowable.
526
+ * - **Read and write both reported, and fitting inside `input`** — a complete partition, so
527
+ * `freshInput` is the remainder and the split is known.
528
+ * - **One counter reported, or classes that overflow `input`** — the counters that ARE measured
529
+ * pass through and `cacheBreakdownKnown` is false. A read with no write counter (OpenAI reports
530
+ * no write) still credits the read it measured, while declaring the rest unclassified so the
531
+ * charge stays a declared upper bound. An overflowing claim buys nothing: it cannot be a
532
+ * partition of a total it exceeds.
533
+ *
534
+ * A counter the provider did not report stays absent. A zero would claim the provider measured no
535
+ * cache, which is a different fact from a provider that did not report.
536
+ */
537
+ function promptCacheTokenClasses(input, promptCache) {
538
+ if (promptCache === void 0) return {};
539
+ const read = tokenCount(promptCache.readTokens);
540
+ const write = tokenCount(promptCache.writeTokens);
541
+ if (read === void 0 && write === void 0) return {};
542
+ if (input === void 0 || (read ?? 0) + (write ?? 0) > input) return { cacheBreakdownKnown: false };
543
+ if (read !== void 0 && write !== void 0) return {
544
+ freshInput: input - read - write,
545
+ cacheRead: read,
546
+ cacheWrite: write
547
+ };
548
+ return {
549
+ ...read !== void 0 ? { cacheRead: read } : {},
550
+ ...write !== void 0 ? { cacheWrite: write } : {},
551
+ cacheBreakdownKnown: false
552
+ };
553
+ }
554
+ function tokenCount(value) {
555
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
556
+ }
557
+ /**
558
+ * Add the observed subtotal into `acc`; token and cache incompleteness are sticky.
559
+ *
560
+ * A delta whose classes do not FIT inside its own `input` contributes its prompt total and NO
561
+ * classes. Folding them in would hide the overflow: the accumulator's larger `input` can absorb a
562
+ * class total that overflowed the one delta that reported it, and `chargedTokens` would then credit
563
+ * at the aggregate a cache read it refuses at the record. That is the one way the charge could come
564
+ * out below the sum of the charges on the records that built it.
565
+ */
566
+ function addTokenUsage(acc, delta) {
567
+ acc.input += delta.input ?? 0;
568
+ acc.output += delta.output ?? 0;
569
+ if (delta.tokensKnown === false) acc.tokensKnown = false;
570
+ const input = delta.input ?? 0;
571
+ const fits = classifiedTotal(delta, delta.cacheRead ?? 0) <= input;
572
+ if (fits) {
573
+ if (delta.freshInput !== void 0) acc.freshInput = (acc.freshInput ?? 0) + delta.freshInput;
574
+ if (delta.cacheRead !== void 0) acc.cacheRead = (acc.cacheRead ?? 0) + delta.cacheRead;
575
+ if (delta.cacheWrite !== void 0) acc.cacheWrite = (acc.cacheWrite ?? 0) + delta.cacheWrite;
576
+ }
577
+ const classified = fits && delta.freshInput !== void 0 && delta.cacheRead !== void 0 && delta.cacheWrite !== void 0 && delta.freshInput + delta.cacheRead + delta.cacheWrite === input;
578
+ if (delta.cacheBreakdownKnown === false || input > 0 && !classified) acc.cacheBreakdownKnown = false;
579
+ }
580
+ /**
581
+ * Map `items` through `fn` with at most `limit` calls in flight at once,
582
+ * preserving input order in the result. On the first `fn` rejection no NEW
583
+ * items are picked up; already-in-flight calls are awaited, then the first
584
+ * error is rethrown. `limit` is clamped to ≥ 1.
585
+ *
586
+ * Used where a burst of provisioning (e.g. forking N child boxes) must respect
587
+ * the loop's concurrency bound instead of firing all N at once.
588
+ */
589
+ async function mapWithConcurrency(items, limit, fn) {
590
+ const results = new Array(items.length);
591
+ let next = 0;
592
+ for await (const settled of runTaskQueue({
593
+ concurrency: Math.max(1, Math.min(Math.floor(limit), items.length)),
594
+ take: () => {
595
+ const index = next++;
596
+ return index < items.length ? {
597
+ id: String(index),
598
+ value: index
599
+ } : void 0;
600
+ },
601
+ execute: ({ value: index }) => fn(items[index], index)
602
+ })) {
603
+ if (settled.status === "rejected") throw settled.reason;
604
+ results[settled.task.value] = settled.value;
605
+ }
606
+ return results;
607
+ }
608
+ /** The message of a thrown value: an `Error`'s own message, anything else stringified. */
609
+ function errorMessage(error) {
610
+ return error instanceof Error ? error.message : String(error);
611
+ }
612
+ /** True for an object whose `Symbol.asyncIterator` is callable, so `for await` can consume it. */
613
+ function isAsyncIterable(value) {
614
+ return value !== null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
615
+ }
616
+ /** 32-bit FNV-1a over a string's UTF-16 code units, as eight lowercase hex digits. */
617
+ function fnv1a32Hex(text) {
618
+ let h = 2166136261;
619
+ for (let i = 0; i < text.length; i += 1) {
620
+ h ^= text.charCodeAt(i);
621
+ h = Math.imul(h, 16777619);
622
+ }
623
+ return (h >>> 0).toString(16).padStart(8, "0");
624
+ }
625
+ //#endregion
12
626
  //#region src/candidate-execution/digest.ts
13
627
  /** Use native hashing for workspace archives. */
14
628
  function sha256Bytes$1(bytes) {
@@ -256,6 +870,7 @@ async function walkWorkspace(root, options, keepBytes) {
256
870
  for (const entry of entries) {
257
871
  options.signal?.throwIfAborted();
258
872
  if (directory === absoluteRoot && ignoredProtectedRootEntries.has(entry.name)) continue;
873
+ if (options.skipPythonBytecode === true && (entry.isDirectory() && entry.name === "__pycache__" || entry.isFile() && entry.name.endsWith(".pyc"))) continue;
259
874
  const absolute = resolve(directory, entry.name);
260
875
  const relPath = relative(absoluteRoot, absolute).split(sep).join("/");
261
876
  if (!relPath || relPath.startsWith("../") || relPath.includes("/../")) throw new Error(`workspace entry escapes root: ${relPath}`);
@@ -1307,6 +1922,83 @@ async function captureAgentCandidateWorkspaceToArtifacts(rootInput, options) {
1307
1922
  archive: archiveArtifact
1308
1923
  }) });
1309
1924
  }
1925
+ /**
1926
+ * Store a workspace as a tree: each regular file the store does not already hold, then the
1927
+ * manifest. The store must find objects by content (`locate`) and stream them.
1928
+ */
1929
+ async function captureAgentCandidateWorkspaceTreeToArtifacts(rootInput, options) {
1930
+ const { outputArtifacts, executionId, signal } = options.artifactPersistence;
1931
+ if (!outputArtifacts.putStream || !outputArtifacts.readStream || !outputArtifacts.locate) throw new Error("workspace tree persistence requires putStream, readStream and locate");
1932
+ if (!executionId.trim()) throw new Error("candidate workspace artifact persistence requires an executionId");
1933
+ signal?.throwIfAborted();
1934
+ const limits = workspaceLimits(options.limits);
1935
+ const material = await scanMaterializedWorkspaceManifest(rootInput, {
1936
+ limits,
1937
+ signal
1938
+ });
1939
+ validateManifest(material, limits);
1940
+ const root = await realpath(resolve(rootInput));
1941
+ let bytes = 0;
1942
+ let storedBytes = 0;
1943
+ for (const file of material.files) {
1944
+ signal?.throwIfAborted();
1945
+ bytes += file.byteLength;
1946
+ if (await outputArtifacts.locate({
1947
+ sha256: file.sha256,
1948
+ byteLength: file.byteLength
1949
+ }, signal === void 0 ? void 0 : { signal }) !== void 0) continue;
1950
+ const stored = await persistCandidateOutputArtifactStream(outputArtifacts, {
1951
+ executionId,
1952
+ purpose: "candidate-workspace-file",
1953
+ chunks: workspaceFileChunks(root, file, signal),
1954
+ maxBytes: file.byteLength,
1955
+ signal
1956
+ });
1957
+ if (stored.sha256 !== file.sha256 || stored.byteLength !== file.byteLength) throw new Error(`workspace file changed during capture: ${file.path}`);
1958
+ storedBytes += file.byteLength;
1959
+ }
1960
+ const manifestBytes = canonicalCandidateBytes$1(material);
1961
+ const manifest = await persistCandidateOutputArtifactStream(outputArtifacts, {
1962
+ executionId,
1963
+ purpose: "candidate-workspace-manifest",
1964
+ chunks: oneChunk(manifestBytes),
1965
+ maxBytes: manifestBytes.byteLength,
1966
+ signal
1967
+ });
1968
+ const digest = canonicalCandidateDigest$1(material);
1969
+ if (manifest.sha256 !== digest) throw new Error("candidate workspace manifest digest does not name its stored bytes");
1970
+ return deepFreezeCandidate({
1971
+ kind: "agent-candidate-workspace-tree",
1972
+ digest,
1973
+ manifest,
1974
+ files: material.files.length,
1975
+ bytes,
1976
+ storedBytes
1977
+ });
1978
+ }
1979
+ /**
1980
+ * Read a tree back by its digest and confirm the store holds every file it names. Returns the
1981
+ * manifest; reading a file is `artifacts.read` of what `locate` returns for its digest.
1982
+ */
1983
+ async function verifyAgentCandidateWorkspaceTree(tree, artifacts, options = {}) {
1984
+ const { signal } = options;
1985
+ if (!artifacts.locate) throw new Error("workspace tree verification requires locate");
1986
+ if (tree.manifest.sha256 !== tree.digest) throw new Error("workspace tree digest does not name its manifest");
1987
+ signal?.throwIfAborted();
1988
+ const bytes = await artifacts.read(tree.manifest);
1989
+ verifyBytes(bytes, tree.manifest.sha256, tree.manifest.byteLength, "workspace tree manifest");
1990
+ const material = JSON.parse(Buffer.from(bytes).toString("utf8"));
1991
+ validateManifest(material, workspaceLimits(options.limits));
1992
+ if (canonicalCandidateDigest$1(material) !== tree.digest) throw new Error("workspace tree manifest is not canonical");
1993
+ for (const file of material.files) {
1994
+ signal?.throwIfAborted();
1995
+ if (await artifacts.locate({
1996
+ sha256: file.sha256,
1997
+ byteLength: file.byteLength
1998
+ }, signal === void 0 ? void 0 : { signal }) === void 0) throw new Error(`workspace tree file is not in the store: ${file.path}`);
1999
+ }
2000
+ return material;
2001
+ }
1310
2002
  /** Verify durable regular-file workspace evidence without retaining archive or file contents. */
1311
2003
  async function verifyAgentCandidateWorkspaceArtifacts(input) {
1312
2004
  await consumeWorkspaceArtifacts(input);
@@ -1510,6 +2202,6 @@ function asError(error) {
1510
2202
  return error instanceof Error ? error : new Error(String(error));
1511
2203
  }
1512
2204
  //#endregion
1513
- export { canonicalCandidateDocument as A, verifyBytes as C, verifiedArtifactChunks as D, verifyWorkspaceSnapshotArtifacts as E, sha256Bytes$1 as F, verifyCanonicalCandidateDocument as I, embeddedCandidateArtifact as M, immutableCandidateValue as N, canonicalCandidateBytes$1 as O, omitTopLevelDigest as P, scanMaterializedWorkspaceManifest as S, verifyMaterializedWorkspace as T, artifactCacheKey as _, captureAgentCandidateWorkspace as a, readMaterializedWorkspaceFiles as b, verifyAgentCandidateWorkspaceArchive as c, verifyCandidateCode as d, verifyTaskCheckout as f, WorkspaceScanLimitError as g, isWellFormedUnicode as h, verifyAgentCandidateWorkspaceArtifacts as i, deepFreezeCandidate as j, canonicalCandidateDigest$1 as k, persistCandidateOutputArtifact as l, assertExactObjectKeys as m, materializeAgentCandidateWorkspaceFromArtifacts as n, captureAgentCandidateWorkspaceFiles as o, verifyTaskOutcomePatch as p, readAgentCandidateWorkspaceArtifactFiles as r, createAgentCandidateWorkspacePort as s, captureAgentCandidateWorkspaceToArtifacts as t, readCandidateGitHubResource as u, candidateWorkspaceManifest as v, verifyMaterializedProfileWorkspace as w, readVerifiedArtifact as x, captureMaterializedWorkspace as y };
2205
+ export { randomUuid as $, canonicalCandidateBytes$1 as A, addTokenUsage as B, readVerifiedArtifact as C, verifyMaterializedWorkspace as D, verifyMaterializedProfileWorkspace as E, immutableCandidateValue as F, errorMessage as G, cloneSpend as H, omitTopLevelDigest as I, isAbortError as J, fnv1a32Hex as K, sha256Bytes$1 as L, canonicalCandidateDocument as M, deepFreezeCandidate as N, verifyWorkspaceSnapshotArtifacts as O, embeddedCandidateArtifact as P, randomSuffix as Q, verifyCanonicalCandidateDocument as R, readMaterializedWorkspaceFiles as S, teardownSurfaces as St, verifyBytes as T, cloneTokenUsage as U, chargedTokens as V, deleteBoxSafe as W, mapWithConcurrency as X, isAsyncIterable as Y, promptCacheTokenClasses as Z, isWellFormedUnicode as _, armDeadlineTimer as _t, verifyAgentCandidateWorkspaceArtifacts as a, unmeteredSpend as at, candidateWorkspaceManifest as b, singleFlightTeardown as bt, captureAgentCandidateWorkspaceFiles as c, zeroTokenUsage as ct, persistCandidateOutputArtifact as d, resourceTelemetry as dt, roundBoxMinutes as et, readCandidateGitHubResource as f, withBudgetResources as ft, assertExactObjectKeys as g, ROOT_DEADLINE_REASON as gt, verifyTaskOutcomePatch as h, DEFAULT_SUCCESSFUL_SHUTDOWN_MS as ht, readAgentCandidateWorkspaceArtifactFiles as i, throwIfAborted as it, canonicalCandidateDigest$1 as j, verifiedArtifactChunks as k, createAgentCandidateWorkspacePort as l, addResourceSpend as lt, verifyTaskCheckout as m, CHILD_DEADLINE_REASON as mt, captureAgentCandidateWorkspaceTreeToArtifacts as n, stringifySafe as nt, verifyAgentCandidateWorkspaceTree as o, withTimeout as ot, verifyCandidateCode as p, ACCEPTED_RESULT_GRACE_MS as pt, hasCompleteCacheBreakdown as q, materializeAgentCandidateWorkspaceFromArtifacts as r, throwAbort as rt, captureAgentCandidateWorkspace as s, zeroSpend as st, captureAgentCandidateWorkspaceToArtifacts as t, sleep as tt, verifyAgentCandidateWorkspaceArchive as u, assertResources as ut, WorkspaceScanLimitError as v, boundedChildDeadlineAt as vt, scanMaterializedWorkspaceManifest as w, captureMaterializedWorkspace as x, teardownExecutor as xt, artifactCacheKey as y, isDeadlineAbortReason as yt, addSpend as z };
1514
2206
 
1515
- //# sourceMappingURL=workspace-streams-D5gHJdTb.js.map
2207
+ //# sourceMappingURL=workspace-streams-ILw0eWZ0.js.map