@tangle-network/agent-runtime 0.338.0 → 0.340.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/dist/{activation-kbkAuSmY.js → activation-D2PVljaw.js} +5 -18
  2. package/dist/{activation-kbkAuSmY.js.map → activation-D2PVljaw.js.map} +1 -1
  3. package/dist/{activation-CsbNax2X.d.ts → activation-DGDl4wwI.d.ts} +4 -24
  4. package/dist/agent.d.ts +4 -18
  5. package/dist/agent.js +3 -21
  6. package/dist/agent.js.map +1 -1
  7. package/dist/analyst-loop.d.ts +2 -2
  8. package/dist/{bundle-DM60AI2B.js → bundle-DNUq-OPW.js} +2 -2
  9. package/dist/{bundle-DM60AI2B.js.map → bundle-DNUq-OPW.js.map} +1 -1
  10. package/dist/candidate-execution/index.d.ts +4 -101
  11. package/dist/candidate-execution/index.js +10 -395
  12. package/dist/candidate-execution/index.js.map +1 -1
  13. package/dist/{delegate-Se1YZKMb.js → delegate-CtJIS-tp.js} +2 -2
  14. package/dist/{delegate-Se1YZKMb.js.map → delegate-CtJIS-tp.js.map} +1 -1
  15. package/dist/{driver-control-acknowledgers-T2a1Ouay.js → driver-control-acknowledgers-MTrs8HAF.js} +15 -11
  16. package/dist/driver-control-acknowledgers-MTrs8HAF.js.map +1 -0
  17. package/dist/{durable-file-B_eJr6Mb.js → durable-file-gNI9ILAn.js} +1 -3
  18. package/dist/durable-file-gNI9ILAn.js.map +1 -0
  19. package/dist/durable.d.ts +3 -35
  20. package/dist/durable.js +10 -10
  21. package/dist/durable.js.map +1 -1
  22. package/dist/{graph-CY0wH838.js → graph-DfWqp_1e.js} +4 -4
  23. package/dist/graph-DfWqp_1e.js.map +1 -0
  24. package/dist/{graph-registry-By0tUj4S.js → graph-registry-BnO64cn8.js} +3 -3
  25. package/dist/{graph-registry-By0tUj4S.js.map → graph-registry-BnO64cn8.js.map} +1 -1
  26. package/dist/{improve-CWGBT13K.js → improve-CKRVQqzt.js} +8 -35
  27. package/dist/improve-CKRVQqzt.js.map +1 -0
  28. package/dist/{improvement-adapter-D5gwwoXQ.d.ts → improvement-adapter-sIthWkcN.d.ts} +3 -21
  29. package/dist/index.d.ts +10 -215
  30. package/dist/index.js +91 -302
  31. package/dist/index.js.map +1 -1
  32. package/dist/intelligence.d.ts +11 -143
  33. package/dist/intelligence.js +7 -81
  34. package/dist/intelligence.js.map +1 -1
  35. package/dist/{jsonl-file-DBv31uPi.js → jsonl-file-C9Kde_0Z.js} +2 -2
  36. package/dist/{jsonl-file-DBv31uPi.js.map → jsonl-file-C9Kde_0Z.js.map} +1 -1
  37. package/dist/kernel.d.ts +4 -3
  38. package/dist/kernel.js +12 -14
  39. package/dist/loop-runner-C4EWEcXf.d.ts +32 -0
  40. package/dist/loop-runner-DNWbTcVm.js +59 -0
  41. package/dist/loop-runner-DNWbTcVm.js.map +1 -0
  42. package/dist/loop-runner-bin.d.ts +32 -2
  43. package/dist/loop-runner-bin.js +93 -1
  44. package/dist/loop-runner-bin.js.map +1 -0
  45. package/dist/mcp/bin.js +3 -3
  46. package/dist/mcp/index.d.ts +99 -418
  47. package/dist/mcp/index.js +121 -203
  48. package/dist/mcp/index.js.map +1 -1
  49. package/dist/mcp/memory-bin.js +231 -1
  50. package/dist/mcp/memory-bin.js.map +1 -1
  51. package/dist/model-policy-CyCUwHed.js.map +1 -1
  52. package/dist/placement.d.ts +2 -33
  53. package/dist/placement.js +1 -35
  54. package/dist/placement.js.map +1 -1
  55. package/dist/platform.d.ts +188 -1
  56. package/dist/platform.js +129 -1
  57. package/dist/platform.js.map +1 -1
  58. package/dist/{prepare-Bt0IouPq.js → prepare-FzJoS68l.js} +8 -160
  59. package/dist/prepare-FzJoS68l.js.map +1 -0
  60. package/dist/{profile-Do-5xO_D.js → profile-DToH0XEs.js} +2 -2
  61. package/dist/profile-DToH0XEs.js.map +1 -0
  62. package/dist/profile-materialization-bPm0gGLO.d.ts +49 -0
  63. package/dist/profiles.d.ts +2 -2
  64. package/dist/profiles.js +3 -40
  65. package/dist/profiles.js.map +1 -1
  66. package/dist/{protected-model-port-DGxQ8_YM.d.ts → protected-model-port-DVVh-hEk.d.ts} +3 -33
  67. package/dist/protected-redaction-DFCeo4vg.js.map +1 -1
  68. package/dist/{provision-supervisor-0jMufp4h.js → provision-supervisor-DqvWXmAE.js} +6 -6
  69. package/dist/{provision-supervisor-0jMufp4h.js.map → provision-supervisor-DqvWXmAE.js.map} +1 -1
  70. package/dist/{run-cancellation-BoW5Sg9Y.js → run-cancellation-C9oL62sW.js} +3 -7
  71. package/dist/{run-cancellation-BoW5Sg9Y.js.map → run-cancellation-C9oL62sW.js.map} +1 -1
  72. package/dist/{runtime-D37zRSs7.js → runtime-C55Zgo1R.js} +2531 -2889
  73. package/dist/runtime-C55Zgo1R.js.map +1 -0
  74. package/dist/{runtime-hooks-Bj6wJHlH.d.ts → runtime-hooks-nsqxSUFL.d.ts} +2 -6
  75. package/dist/{sandbox-profile-compat-xSoVtdWw.js → sandbox-profile-compat-DRr3JwDx.js} +2 -4
  76. package/dist/sandbox-profile-compat-DRr3JwDx.js.map +1 -0
  77. package/dist/{search-executor-DmgUm5p7.js → search-executor-ChOlRBgg.js} +3 -3
  78. package/dist/search-executor-ChOlRBgg.js.map +1 -0
  79. package/dist/{server-DQHJszfk.js → server-DkVBSN_S.js} +362 -67
  80. package/dist/server-DkVBSN_S.js.map +1 -0
  81. package/dist/{structural-rollout-DAvIE8mw.js → structural-rollout-C1LEk_zq.js} +80 -80
  82. package/dist/structural-rollout-C1LEk_zq.js.map +1 -0
  83. package/dist/{substrate-B0TYNrXn.js → substrate-CGDFTSRh.js} +2 -9
  84. package/dist/substrate-CGDFTSRh.js.map +1 -0
  85. package/dist/{supervise-WuPAwfPh.js → supervise-CaUAxZZP.js} +92 -75
  86. package/dist/supervise-CaUAxZZP.js.map +1 -0
  87. package/dist/{supervisor-CPG1I9UN.js → supervisor-VXuN2OHT.js} +205 -319
  88. package/dist/supervisor-VXuN2OHT.js.map +1 -0
  89. package/dist/testing.d.ts +2 -2
  90. package/dist/testing.js +13 -13
  91. package/dist/testing.js.map +1 -1
  92. package/dist/tool-loop.d.ts +1 -1
  93. package/dist/{tool-server-Dqer2M4_.js → tool-server-XV4aJwoQ.js} +2 -2
  94. package/dist/tool-server-XV4aJwoQ.js.map +1 -0
  95. package/dist/top-snapshot-CbZE1JsU.js +502 -0
  96. package/dist/top-snapshot-CbZE1JsU.js.map +1 -0
  97. package/dist/tui/bin.js +711 -1
  98. package/dist/tui/bin.js.map +1 -1
  99. package/dist/tui/index.d.ts +2 -70
  100. package/dist/tui/index.js +3 -3
  101. package/dist/{types-zWfqDjeL.d.ts → types-Cwrea-bU.d.ts} +2 -17
  102. package/dist/{types-CrNWif8-.d.ts → types-DZ6L0Bv3.d.ts} +765 -2152
  103. package/dist/workspace-store/index.d.ts +1 -107
  104. package/dist/workspace-store/index.js +1 -415
  105. package/dist/workspace-store/index.js.map +1 -1
  106. package/dist/{workspace-streams-BZZds1Fw.d.ts → workspace-streams-BiS4ABah.d.ts} +3 -18
  107. package/package.json +1 -1
  108. package/skills/agent-graphs/references/authoring.md +3 -2
  109. package/dist/coder-yhVWbdWc.js +0 -40
  110. package/dist/coder-yhVWbdWc.js.map +0 -1
  111. package/dist/delegation-status-CF4D0NZ_.js +0 -358
  112. package/dist/delegation-status-CF4D0NZ_.js.map +0 -1
  113. package/dist/driver-control-acknowledgers-T2a1Ouay.js.map +0 -1
  114. package/dist/durable-file-B_eJr6Mb.js.map +0 -1
  115. package/dist/graph-CY0wH838.js.map +0 -1
  116. package/dist/improve-CWGBT13K.js.map +0 -1
  117. package/dist/integrations-6xttbPi9.d.ts +0 -190
  118. package/dist/integrations-dFi-ALk7.js +0 -132
  119. package/dist/integrations-dFi-ALk7.js.map +0 -1
  120. package/dist/kb-gate-C8z2juK8.d.ts +0 -80
  121. package/dist/kb-gate-DpaSwXVx.js +0 -80
  122. package/dist/kb-gate-DpaSwXVx.js.map +0 -1
  123. package/dist/loop-runner-bin-CFnrAHpl.d.ts +0 -164
  124. package/dist/loop-runner-bin-CdPlhy9g.js +0 -246
  125. package/dist/loop-runner-bin-CdPlhy9g.js.map +0 -1
  126. package/dist/memory-server-DXQ8IxGR.js +0 -234
  127. package/dist/memory-server-DXQ8IxGR.js.map +0 -1
  128. package/dist/openai-tools-DoQ32vpe.js +0 -44
  129. package/dist/openai-tools-DoQ32vpe.js.map +0 -1
  130. package/dist/openai-tools-zh2I_uD7.d.ts +0 -24
  131. package/dist/prepare-Bt0IouPq.js.map +0 -1
  132. package/dist/profile-Do-5xO_D.js.map +0 -1
  133. package/dist/profile-materialization-BnoEf1co.d.ts +0 -96
  134. package/dist/runtime-D37zRSs7.js.map +0 -1
  135. package/dist/sandbox-profile-compat-xSoVtdWw.js.map +0 -1
  136. package/dist/search-executor-DmgUm5p7.js.map +0 -1
  137. package/dist/server-DQHJszfk.js.map +0 -1
  138. package/dist/structural-rollout-DAvIE8mw.js.map +0 -1
  139. package/dist/substrate-B0TYNrXn.js.map +0 -1
  140. package/dist/supervise-WuPAwfPh.js.map +0 -1
  141. package/dist/supervisor-CPG1I9UN.js.map +0 -1
  142. package/dist/tool-server-Dqer2M4_.js.map +0 -1
  143. package/dist/top-app-C55Wa7uy.js +0 -1214
  144. package/dist/top-app-C55Wa7uy.js.map +0 -1
@@ -1,12 +1,12 @@
1
- import { A as verifyMaterializedWorkspace, C as candidateWorkspaceManifest, D as scanMaterializedWorkspaceManifest, E as readVerifiedArtifact, L as deepFreezeCandidate, N as verifiedArtifactChunks, P as canonicalCandidateBytes$1, R as embeddedCandidateArtifact, _ as workspaceLimits, a as materializeAgentCandidateWorkspaceFromArtifacts, c as verifyAgentCandidateWorkspaceTree, h as captureAgentCandidateWorkspaceFiles, i as captureAgentCandidateWorkspaceTreeToArtifacts, l as captureAgentCandidateWorkspace, r as captureAgentCandidateWorkspaceToArtifacts, s as verifyAgentCandidateWorkspaceArtifacts, u as createAgentCandidateWorkspacePort, v as persistCandidateOutputArtifact } from "../sandbox-profile-compat-xSoVtdWw.js";
2
- import { a as applyExactAgentProfileDiff, b as parseExactCandidateProfile, g as omitUndefinedObjectFields, i as agentCandidateProfileAsAgentProfile, o as assertCandidateProfileBinding, p as freezeGenericAgentCandidateProfile, v as parseExactAgentProfile, y as parseExactAgentProfileDiff } from "../profile-Do-5xO_D.js";
3
- import { t as sealAgentCandidateBundle } from "../bundle-DM60AI2B.js";
4
- import { A as candidateKnowledgeExecutionPaths, C as sealTerminalDigest, D as exactProcessProviderAsCandidateExecutor, E as sealAgentCandidateModelSettlement, F as CANDIDATE_TRACE_TAGS, N as verifyAgentCandidateBundle, O as CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV, P as CANDIDATE_TRACE_ENV, S as requireStagedTerminal, T as createProtectedAgentCandidateModelPort, _ as assertTerminalMatchesClaim, a as sealAgentCandidateExecutorStopAcknowledgement, b as rejectedFinish, c as beginPreparedCandidateDisposal, d as candidateClaimFileInternals, f as candidateCleanupDeadline, g as assertTerminalAllowedInPhase, h as assertRecoveryMatchesStaged, i as persistCandidateModelSettlementEvidence, j as AGENT_CANDIDATE_EXECUTION_SUPPORT, k as CANDIDATE_KNOWLEDGE_ROOT_ENV, l as consumePreparedCandidateExecution, m as withinCandidateCleanupDeadline, n as executePreparedAgentCandidate, o as candidateExecutionClaim, p as candidateCleanupTimeout, r as RecoveryAgentCandidateTraceStore, s as assertPreparedCandidateIntegrity, t as prepareAgentCandidateExecution, u as InMemoryAgentCandidateExecutionClaimStore, v as assertTerminalMatchesStaged, w as terminalRecord, x as rejectedStage, y as recoveredTerminalRecord } from "../prepare-Bt0IouPq.js";
5
- import { agentCandidateArtifactRefSchema, agentCandidateExecutionPlanMaterialSchema, agentCandidateMaterializationReceiptSchema, agentCandidateWorkspaceManifestMaterialSchema, agentCandidateWorkspaceSnapshotEvidenceSchema } from "@tangle-network/agent-interface";
6
- import { createHash, randomUUID } from "node:crypto";
7
- import { constants, linkSync } from "node:fs";
8
- import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
9
- import { cp, lstat, mkdir, open, readdir, readlink, realpath, unlink } from "node:fs/promises";
1
+ import { C as candidateWorkspaceManifest, I as deepFreezeCandidate, L as embeddedCandidateArtifact, M as verifiedArtifactChunks, N as canonicalCandidateBytes$1, _ as workspaceLimits, a as materializeAgentCandidateWorkspaceFromArtifacts, c as verifyAgentCandidateWorkspaceTree, h as captureAgentCandidateWorkspaceFiles, i as captureAgentCandidateWorkspaceTreeToArtifacts, l as captureAgentCandidateWorkspace, r as captureAgentCandidateWorkspaceToArtifacts, s as verifyAgentCandidateWorkspaceArtifacts, u as createAgentCandidateWorkspacePort } from "../sandbox-profile-compat-DRr3JwDx.js";
2
+ import { a as applyExactAgentProfileDiff, b as parseExactCandidateProfile, i as agentCandidateProfileAsAgentProfile, o as assertCandidateProfileBinding, p as freezeGenericAgentCandidateProfile, v as parseExactAgentProfile, y as parseExactAgentProfileDiff } from "../profile-DToH0XEs.js";
3
+ import { t as sealAgentCandidateBundle } from "../bundle-DNUq-OPW.js";
4
+ import { _ as sealTerminalDigest, a as consumePreparedCandidateExecution, b as sealAgentCandidateModelSettlement, c as withinCandidateCleanupDeadline, d as assertTerminalMatchesClaim, f as assertTerminalMatchesStaged, g as requireStagedTerminal, h as rejectedStage, i as beginPreparedCandidateDisposal, l as assertRecoveryMatchesStaged, m as rejectedFinish, n as executePreparedAgentCandidate, o as candidateClaimFileInternals, p as recoveredTerminalRecord, r as assertPreparedCandidateIntegrity, s as candidateCleanupDeadline, t as prepareAgentCandidateExecution, u as assertTerminalAllowedInPhase, v as terminalRecord, w as verifyAgentCandidateBundle, x as exactProcessProviderAsCandidateExecutor, y as createProtectedAgentCandidateModelPort } from "../prepare-FzJoS68l.js";
5
+ import { agentCandidateArtifactRefSchema, agentCandidateWorkspaceManifestMaterialSchema, agentCandidateWorkspaceSnapshotEvidenceSchema } from "@tangle-network/agent-interface";
6
+ import { randomUUID } from "node:crypto";
7
+ import { linkSync } from "node:fs";
8
+ import { isAbsolute, join, resolve } from "node:path";
9
+ import { lstat, mkdir, open, unlink } from "node:fs/promises";
10
10
  import { verifyCodeSurface } from "@tangle-network/agent-eval/campaign";
11
11
  //#region src/candidate-execution/builder.ts
12
12
  /**
@@ -439,145 +439,6 @@ function isCandidateGrantDrainingError(error) {
439
439
  return typeof candidate.message === "string" && /\bcandidate_grant_draining\b/u.test(candidate.message);
440
440
  }
441
441
  //#endregion
442
- //#region src/candidate-execution/recover.ts
443
- /** Close an expired crashed attempt from persisted non-secret handles, then record failure. */
444
- async function recoverExpiredAgentCandidateExecution(options) {
445
- const record = await options.claimStore.getAttempt(options.attempt);
446
- if (!record) throw new Error("candidate execution recovery attempt is missing");
447
- if (record.terminal) return Object.freeze({
448
- finished: false,
449
- terminal: record.terminal,
450
- exactReplay: true
451
- });
452
- const cleanupTimeoutMs = candidateCleanupTimeout(options.cleanupTimeoutMs ?? record.claim.cleanup.cleanupTimeoutMs);
453
- if (cleanupTimeoutMs > record.claim.cleanup.cleanupTimeoutMs) throw new Error("recovery cleanup timeout exceeds the frozen preparation bound");
454
- if ((options.now ?? Date.now)() < record.claim.leaseExpiresAtMs) throw new Error("candidate execution lease has not expired");
455
- const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs);
456
- const recoveryTraceStore = new RecoveryAgentCandidateTraceStore(options.traceStore);
457
- const preparation = withinCandidateCleanupDeadline(() => readRecoveryPreparation(record.claim, options.outputArtifacts), cleanupDeadlineAtMs, "expired candidate preparation evidence read");
458
- const processClosure = withinCandidateCleanupDeadline(async (cleanupSignal) => {
459
- sealAgentCandidateExecutorStopAcknowledgement(await options.executor.stop({
460
- executionId: record.claim.executionId,
461
- executionPlanDigest: record.claim.executionPlanDigest
462
- }, {
463
- traceStore: recoveryTraceStore,
464
- reason: "failed",
465
- signal: cleanupSignal,
466
- deadlineAtMs: cleanupDeadlineAtMs
467
- }));
468
- if (options.executor.dispose) {
469
- const disposed = await options.executor.dispose({
470
- executionId: record.claim.executionId,
471
- executionPlanDigest: record.claim.executionPlanDigest
472
- }, { signal: cleanupSignal });
473
- if (disposed.disposed !== true || Object.keys(disposed).some((key) => key !== "disposed")) throw new Error("expired candidate executor did not acknowledge resource disposal");
474
- }
475
- return { stopped: true };
476
- }, cleanupDeadlineAtMs, "expired candidate process termination");
477
- const modelClosure = withinCandidateCleanupDeadline(async () => sealAgentCandidateModelSettlement(await options.ports.models.settleGrant({
478
- executionId: record.claim.executionId,
479
- preparationId: record.claim.cleanup.preparationId,
480
- grantDigest: record.claim.cleanup.modelGrantDigest,
481
- resolved: record.claim.cleanup.resolvedModel,
482
- reason: "failed"
483
- }), {
484
- preparationId: record.claim.cleanup.preparationId,
485
- grantDigest: record.claim.cleanup.modelGrantDigest,
486
- model: record.claim.cleanup.resolvedModel.model
487
- }), cleanupDeadlineAtMs, "expired candidate model settlement");
488
- const memoryClosure = record.claim.cleanup.memory ? withinCandidateCleanupDeadline(async () => {
489
- const memory = record.claim.cleanup.memory;
490
- if (!memory) throw new Error("expired candidate memory handle is missing");
491
- const closed = await options.ports.memory.close({
492
- executionId: record.claim.executionId,
493
- preparationId: record.claim.cleanup.preparationId,
494
- accessDigest: memory.accessDigest,
495
- effectiveNamespace: memory.effectiveNamespace,
496
- reason: "failed"
497
- });
498
- if (closed.closed !== true || Object.keys(closed).some((key) => key !== "closed")) throw new Error("expired candidate memory did not acknowledge closure");
499
- return { closed: true };
500
- }, cleanupDeadlineAtMs, "expired candidate memory closure") : void 0;
501
- const closureOutcomes = Promise.allSettled([modelClosure, memoryClosure ?? Promise.resolve(void 0)]);
502
- const [preparationOutcome, processOutcome] = await Promise.allSettled([preparation, processClosure]);
503
- const failures = [preparationOutcome, processOutcome].filter((outcome) => outcome.status === "rejected").map((outcome) => outcome.reason);
504
- const [modelOutcome, memoryOutcome] = await closureOutcomes;
505
- for (const outcome of [modelOutcome, memoryOutcome]) if (outcome.status === "rejected") failures.push(outcome.reason);
506
- if (failures.length > 0) throw new AggregateError(failures, "expired candidate cleanup could not be proven");
507
- if (modelOutcome.status !== "fulfilled") throw new Error("expired candidate model settlement was not recovered");
508
- const model = modelOutcome.value;
509
- const modelSettlement = await withinCandidateCleanupDeadline(() => persistCandidateModelSettlementEvidence({
510
- executionId: record.claim.executionId,
511
- executionPlanDigest: record.claim.executionPlanDigest,
512
- resolvedModel: record.claim.cleanup.resolvedModel
513
- }, model, options.outputArtifacts), cleanupDeadlineAtMs, "expired candidate model-settlement persistence");
514
- const failureClass = record.phase === "claimed" && model.usage.modelCalls === 0 ? "pre-model-infrastructure" : "unknown";
515
- const failureEvidence = await withinCandidateCleanupDeadline(() => persistCandidateOutputArtifact(options.outputArtifacts, {
516
- executionId: record.claim.executionId,
517
- purpose: "failure-evidence",
518
- bytes: canonicalCandidateBytes$1({
519
- kind: "agent-candidate-recovery-failure",
520
- executionId: record.claim.executionId,
521
- attempt: record.claim.attempt,
522
- bundleDigest: record.claim.bundleDigest,
523
- executionPlanDigest: record.claim.executionPlanDigest,
524
- materializationReceiptDigest: record.claim.preparationEvidence.materializationReceipt.sha256,
525
- failureClass,
526
- processStopped: true,
527
- modelSettlementDigest: modelSettlement.digest,
528
- memoryClosed: record.claim.cleanup.memory !== void 0
529
- })
530
- }), cleanupDeadlineAtMs, "expired candidate failure-evidence persistence");
531
- const memory = record.claim.cleanup.memory;
532
- return await options.claimStore.recoverExpired(options.attempt, {
533
- failureClass,
534
- usage: model.usage,
535
- modelSettlement: modelSettlement.artifact,
536
- failureEvidence,
537
- process: {
538
- stopped: true,
539
- executionPlanDigest: record.claim.executionPlanDigest
540
- },
541
- model: {
542
- closed: true,
543
- preparationId: record.claim.cleanup.preparationId,
544
- grantDigest: record.claim.cleanup.modelGrantDigest
545
- },
546
- ...memory ? { memory: {
547
- closed: true,
548
- preparationId: record.claim.cleanup.preparationId,
549
- accessDigest: memory.accessDigest,
550
- effectiveNamespace: memory.effectiveNamespace
551
- } } : {}
552
- });
553
- }
554
- async function readRecoveryPreparation(claim, artifacts) {
555
- const [planBytes, receiptBytes] = await Promise.all([readVerifiedArtifact(claim.preparationEvidence.executionPlan, artifacts), readVerifiedArtifact(claim.preparationEvidence.materializationReceipt, artifacts)]);
556
- const plan = agentCandidateExecutionPlanMaterialSchema.parse(parseCanonicalBytes(planBytes, "plan"));
557
- if (claim.preparationEvidence.executionPlan.sha256 !== claim.executionPlanDigest) throw new Error("recovery execution plan artifact does not match the claimed digest");
558
- const receiptMaterial = parseCanonicalBytes(receiptBytes, "materialization receipt");
559
- const receipt = agentCandidateMaterializationReceiptSchema.parse({
560
- ...receiptMaterial,
561
- digest: claim.preparationEvidence.materializationReceipt.sha256
562
- });
563
- if (receipt.bundleDigest !== claim.bundleDigest || receipt.executionPlan.digest !== claim.executionPlanDigest || plan.runCell.bundleDigest !== claim.bundleDigest || plan.executionId !== claim.executionId) throw new Error("recovery preparation evidence does not match the durable claim");
564
- return {
565
- plan,
566
- receipt
567
- };
568
- }
569
- function parseCanonicalBytes(bytes, label) {
570
- let parsed;
571
- try {
572
- parsed = JSON.parse(Buffer.from(bytes).toString("utf8"));
573
- } catch (error) {
574
- throw new Error(`candidate recovery ${label} is not JSON`, { cause: error });
575
- }
576
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`candidate recovery ${label} must be an object`);
577
- if (!Buffer.from(canonicalCandidateBytes$1(parsed)).equals(Buffer.from(bytes))) throw new Error(`candidate recovery ${label} bytes are not canonical`);
578
- return parsed;
579
- }
580
- //#endregion
581
442
  //#region src/candidate-execution/workspace-transfer.ts
582
443
  /**
583
444
  * Capture through the canonical archive owner and return references only.
@@ -657,252 +518,6 @@ async function assertAbsentDestination(destination) {
657
518
  throw new Error("portable workspace destination already exists");
658
519
  }
659
520
  //#endregion
660
- //#region src/candidate-execution/workspace-tree.ts
661
- /**
662
- * A content digest over a DIRECTORY TREE, and the per-file seed that fills one.
663
- *
664
- * The question this answers is "is this workspace the same workspace" — the question every launch
665
- * and every close of a branchable run has to answer, about a tree that a live process is still
666
- * writing to. That is a different question from the one
667
- * {@link scanMaterializedWorkspaceManifest} answers, and the difference decides the policies here:
668
- *
669
- * - A candidate manifest describes ONE EXACT regular-file workspace. It refuses a symbolic link
670
- * outright, because `AgentCandidateWorkspaceManifestMaterial` has no representation for one, and
671
- * it refuses an entry that disappears, because a signed manifest describes a settled tree.
672
- * - A tree descriptor describes what a RUN PRODUCED. A python venv writes
673
- * `bin/python -> /usr/bin/python3` as a matter of course, and a work directory can lose an entry
674
- * between two directory reads. Refusing on either aborts the close, and a run that never wrote
675
- * its digest can never be branched from.
676
- *
677
- * So the two policies are the caller's, one for links and one for vanishing entries, and both
678
- * default to `'refuse'` — the strict reading, correct for an INPUT seed, where a link that leaves
679
- * the tree means the seed describes bytes it does not contain. `'exclude'` is the reading a close
680
- * needs: the entry is never followed, it is recorded, and the exclusion itself is hashed, so two
681
- * trees that differ only in an excluded entry cannot share a digest.
682
- *
683
- * NOTHING is held in memory. A file reaches the tree digest as its own streamed sha-256 plus its
684
- * length, so the largest file in the tree does not decide whether the tree can be described:
685
- * `readFile` refuses anything above 2 GiB with `ERR_FS_FILE_TOO_LARGE`, and a single multi-gigabyte
686
- * artifact is exactly what a run leaves behind.
687
- *
688
- * @module
689
- * @experimental
690
- */
691
- const TREE_ALGORITHMS = /* @__PURE__ */ new Set(["tree-v1", "portable-tree-v1"]);
692
- const ENTRY_POLICIES = /* @__PURE__ */ new Set(["refuse", "exclude"]);
693
- /**
694
- * Describe one directory tree by content, streaming every file.
695
- *
696
- * The digest covers, for every entry in sorted order: its kind, its tree-relative path, its mode
697
- * under the selected algorithm, and then — for a file, its length and its own sha-256; for a kept
698
- * link, its target; for an excluded entry, the reason and the target. A file's content therefore
699
- * never enters the tree hash directly, which is what removes any in-memory size ceiling: the tree
700
- * hash consumes 32 bytes per file however large the file is.
701
- *
702
- * A hard-linked regular file is described like any other regular file. Its content is what the
703
- * digest is about, and a package manager that links a store into `node_modules` is ordinary
704
- * content, not a reason to refuse a workspace.
705
- */
706
- async function describeWorkspaceTree(directory, options = {}) {
707
- const algorithm = options.algorithm ?? "tree-v1";
708
- const onEscapingLink = options.onEscapingLink ?? "refuse";
709
- const onMissingEntry = options.onMissingEntry ?? "refuse";
710
- if (!TREE_ALGORITHMS.has(algorithm)) throw new Error(`unsupported workspace tree algorithm: ${algorithm}`);
711
- for (const [name, policy] of [["onEscapingLink", onEscapingLink], ["onMissingEntry", onMissingEntry]]) if (!ENTRY_POLICIES.has(policy)) throw new Error(`unsupported workspace tree ${name} policy: ${policy}`);
712
- const root = resolve(directory);
713
- const rootStats = await lstatIfPresent(root);
714
- if (rootStats === null || !rootStats.isDirectory() || rootStats.isSymbolicLink()) throw new Error(`workspace tree root must be a real directory: ${directory}`);
715
- const physicalRoot = await realpath(root);
716
- const hash = createHash("sha256");
717
- hash.update(`workspace-tree\0${algorithm}\0`);
718
- const counts = {
719
- files: 0,
720
- directories: 0,
721
- symlinks: 0,
722
- bytes: 0
723
- };
724
- const excluded = [];
725
- const exclude = (path, reason, target) => {
726
- const name = treePath(root, path);
727
- excluded.push(Object.freeze(target === void 0 ? {
728
- path: name,
729
- reason
730
- } : {
731
- path: name,
732
- reason,
733
- target
734
- }));
735
- hash.update(`excluded\0${name}\0${reason}\0${target ?? ""}\0`);
736
- };
737
- /** True when the caller asked to continue past a vanished entry, and it was not the root. */
738
- const recordMissing = (path) => {
739
- if (onMissingEntry === "refuse" || path === root) return false;
740
- exclude(path, "entry-disappeared");
741
- return true;
742
- };
743
- const visit = async (path) => {
744
- const info = await lstatIfPresent(path);
745
- if (info === null) {
746
- if (recordMissing(path)) return;
747
- throw new Error(`workspace tree entry disappeared during the walk: ${treePath(root, path)}`);
748
- }
749
- const name = treePath(root, path);
750
- const mode = entryMode(info.mode, algorithm, info.isDirectory(), info.isSymbolicLink());
751
- if (info.isDirectory()) {
752
- let entries;
753
- try {
754
- entries = await readdir(path);
755
- } catch (error) {
756
- if (isMissing(error) && recordMissing(path)) return;
757
- throw error;
758
- }
759
- counts.directories += 1;
760
- hash.update(`directory\0${name}\0${mode}\0`);
761
- for (const entry of entries.sort()) await visit(join(path, entry));
762
- return;
763
- }
764
- if (info.isSymbolicLink()) {
765
- await visitSymbolicLink(path, name, mode);
766
- return;
767
- }
768
- if (!info.isFile()) throw new Error(`workspace tree contains an unsupported entry: ${name}`);
769
- const read = await digestFile(path);
770
- if (read === null) {
771
- if (recordMissing(path)) return;
772
- throw new Error(`workspace tree entry disappeared during the walk: ${name}`);
773
- }
774
- counts.files += 1;
775
- counts.bytes += read.byteLength;
776
- hash.update(`file\0${name}\0${mode}\0${read.byteLength}\0${read.sha256}\0`);
777
- };
778
- const visitSymbolicLink = async (path, name, mode) => {
779
- let target;
780
- try {
781
- target = await readlink(path);
782
- } catch (error) {
783
- if (isMissing(error) && recordMissing(path)) return;
784
- throw error;
785
- }
786
- const refuse = (reason) => {
787
- if (onEscapingLink === "refuse") throw new Error(`workspace tree contains a link that ${reasonText(reason)}: ${name} -> ${target}`);
788
- exclude(path, reason, target);
789
- };
790
- if (isAbsolute(target)) return refuse("absolute-symlink");
791
- if (!isWithin(root, resolve(dirname(path), target))) return refuse("symlink-escapes-tree");
792
- let physicalTarget;
793
- try {
794
- physicalTarget = await realpath(path);
795
- } catch {
796
- return refuse("unresolved-symlink");
797
- }
798
- if (!isWithin(physicalRoot, physicalTarget)) return refuse("symlink-resolves-outside-tree");
799
- counts.symlinks += 1;
800
- hash.update(`symlink\0${name}\0${mode}\0${target}\0`);
801
- };
802
- await visit(root);
803
- return Object.freeze({
804
- algorithm,
805
- digest: `sha256:${hash.digest("hex")}`,
806
- files: counts.files,
807
- directories: counts.directories,
808
- symlinks: counts.symlinks,
809
- bytes: counts.bytes,
810
- excluded: Object.freeze(excluded)
811
- });
812
- }
813
- /**
814
- * Seed a workspace from a directory, one entry at a time, and return the digest of what was
815
- * seeded.
816
- *
817
- * Nothing is packed: `cp` walks and copies file by file, so a multi-gigabyte seed costs one file
818
- * handle rather than one archive in memory. Existing destination entries are never overwritten —
819
- * a seed that could replace a file the workspace already holds would make the resulting tree
820
- * depend on the order two seeds ran in.
821
- *
822
- * Links are copied verbatim, exactly as they were written. Following them would copy bytes from
823
- * outside the seed into the workspace, which is the same rule {@link describeWorkspaceTree}
824
- * applies to the digest.
825
- */
826
- async function seedWorkspaceTree(input) {
827
- const source = resolve(input.source);
828
- const destination = resolve(input.destination);
829
- if (source === destination || isWithin(source, destination)) throw new Error("workspace seed must not contain its destination");
830
- const destinationStats = await lstatIfPresent(destination);
831
- if (destinationStats === null || !destinationStats.isDirectory()) throw new Error(`workspace seed destination must be an existing directory: ${input.destination}`);
832
- const descriptor = await describeWorkspaceTree(source, { ...input.algorithm === void 0 ? {} : { algorithm: input.algorithm } });
833
- for (const name of (await readdir(source)).sort()) {
834
- if (await lstatIfPresent(join(destination, name)) !== null) throw new Error(`workspace seed would overwrite an existing entry: ${name}`);
835
- await cp(join(source, name), join(destination, name), {
836
- recursive: true,
837
- force: false,
838
- errorOnExist: true,
839
- verbatimSymlinks: true
840
- });
841
- }
842
- return descriptor;
843
- }
844
- /** Stream one regular file into its own digest, or `null` when it vanished mid-read. */
845
- async function digestFile(path) {
846
- let descriptor;
847
- try {
848
- descriptor = await open(path, constants.O_RDONLY | (typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0));
849
- } catch (error) {
850
- if (isMissing(error)) return null;
851
- throw error;
852
- }
853
- try {
854
- const hash = createHash("sha256");
855
- const buffer = Buffer.allocUnsafe(1024 * 1024);
856
- let total = 0;
857
- while (true) {
858
- const { bytesRead } = await descriptor.read(buffer, 0, buffer.byteLength, null);
859
- if (bytesRead === 0) break;
860
- total += bytesRead;
861
- hash.update(buffer.subarray(0, bytesRead));
862
- }
863
- return {
864
- sha256: `sha256:${hash.digest("hex")}`,
865
- byteLength: total
866
- };
867
- } finally {
868
- await descriptor.close();
869
- }
870
- }
871
- /** Git records exactly two file modes; a portable tree records the same two, plus 755 for a
872
- * directory and 777 for a link, which is what every filesystem reports for one. */
873
- function entryMode(mode, algorithm, isDirectory, isSymbolicLink) {
874
- const bits = Number(mode);
875
- if (algorithm !== "portable-tree-v1") return String(bits & 511);
876
- if (isDirectory) return "755";
877
- if (isSymbolicLink) return "777";
878
- return (bits & 73) !== 0 ? "755" : "644";
879
- }
880
- function reasonText(reason) {
881
- switch (reason) {
882
- case "absolute-symlink": return "is absolute";
883
- case "symlink-escapes-tree": return "escapes its tree";
884
- case "symlink-resolves-outside-tree": return "resolves outside its tree";
885
- default: return "does not resolve";
886
- }
887
- }
888
- function treePath(root, path) {
889
- return relative(root, path).split(sep).join("/") || ".";
890
- }
891
- function isWithin(root, path) {
892
- return path === root || path.startsWith(`${root}${sep}`);
893
- }
894
- function isMissing(error) {
895
- return error?.code === "ENOENT";
896
- }
897
- async function lstatIfPresent(path) {
898
- try {
899
- return await lstat(path);
900
- } catch (error) {
901
- if (isMissing(error)) return null;
902
- throw error;
903
- }
904
- }
905
- //#endregion
906
- export { AGENT_CANDIDATE_EXECUTION_SUPPORT, CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV, CANDIDATE_KNOWLEDGE_ROOT_ENV, CANDIDATE_TRACE_ENV, CANDIDATE_TRACE_TAGS, FileAgentCandidateExecutionClaimStore, InMemoryAgentCandidateExecutionClaimStore, agentCandidateProfileAsAgentProfile, applyExactAgentProfileDiff, assertCandidateProfileBinding, buildAgentCandidateBundle, candidateExecutionClaim, candidateKnowledgeExecutionPaths, candidateWorkspaceManifest, captureAgentCandidateWorkspace, captureAgentCandidateWorkspaceFiles, captureAgentCandidateWorkspaceToArtifacts, captureAgentCandidateWorkspaceTreeToArtifacts, captureAgentWorkspaceSnapshot, createAgentCandidateWorkspacePort, createProtectedAgentCandidateModelPort, describeWorkspaceTree, disposePreparedAgentCandidateExecution, exactProcessProviderAsCandidateExecutor, executePreparedAgentCandidate, freezeGenericAgentCandidateProfile, materializeAgentCandidateWorkspaceFromArtifacts, materializeAgentWorkspaceSnapshot, omitUndefinedObjectFields, parseExactAgentProfile, parseExactAgentProfileDiff, parseExactCandidateProfile, persistCandidateOutputArtifact, prepareAgentCandidateExecution, recoverExpiredAgentCandidateExecution, runProtectedAgentCandidateModelGrant, scanMaterializedWorkspaceManifest, sealAgentCandidateBundle, seedWorkspaceTree, verifyAgentCandidateBundle, verifyAgentCandidateWorkspaceArtifacts, verifyAgentCandidateWorkspaceTree, verifyMaterializedWorkspace };
521
+ export { FileAgentCandidateExecutionClaimStore, agentCandidateProfileAsAgentProfile, applyExactAgentProfileDiff, assertCandidateProfileBinding, buildAgentCandidateBundle, candidateWorkspaceManifest, captureAgentCandidateWorkspace, captureAgentCandidateWorkspaceFiles, captureAgentCandidateWorkspaceToArtifacts, captureAgentCandidateWorkspaceTreeToArtifacts, captureAgentWorkspaceSnapshot, createAgentCandidateWorkspacePort, createProtectedAgentCandidateModelPort, disposePreparedAgentCandidateExecution, exactProcessProviderAsCandidateExecutor, executePreparedAgentCandidate, freezeGenericAgentCandidateProfile, materializeAgentCandidateWorkspaceFromArtifacts, materializeAgentWorkspaceSnapshot, parseExactAgentProfileDiff, prepareAgentCandidateExecution, runProtectedAgentCandidateModelGrant, sealAgentCandidateBundle, verifyAgentCandidateBundle, verifyAgentCandidateWorkspaceArtifacts, verifyAgentCandidateWorkspaceTree };
907
522
 
908
523
  //# sourceMappingURL=index.js.map