@tangle-network/agent-runtime 0.239.0 → 0.246.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 (78) hide show
  1. package/dist/{activation-CUhkPtm0.js → activation-C6d-NTWk.js} +3 -3
  2. package/dist/{activation-CUhkPtm0.js.map → activation-C6d-NTWk.js.map} +1 -1
  3. package/dist/{activation-CRDZUoUE.d.ts → activation-Df-ae5Uq.d.ts} +115 -5
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/candidate-execution/index.js +7 -7
  7. package/dist/candidate-execution/index.js.map +1 -1
  8. package/dist/{coordination-driver-m-2dzvu6.js → coordination-driver-De8pyM57.js} +25 -12
  9. package/dist/coordination-driver-De8pyM57.js.map +1 -0
  10. package/dist/{delegate-DRQtaWF1.js → delegate-DE6hNhbD.js} +2 -2
  11. package/dist/{delegate-DRQtaWF1.js.map → delegate-DE6hNhbD.js.map} +1 -1
  12. package/dist/{durable-file-D24y9zg7.js → durable-file-DWQA4ooo.js} +2 -2
  13. package/dist/{durable-file-D24y9zg7.js.map → durable-file-DWQA4ooo.js.map} +1 -1
  14. package/dist/durable.d.ts +2 -2
  15. package/dist/durable.js +3 -3
  16. package/dist/{graph-B17RjVhE.js → graph-s57f-VCR.js} +3 -3
  17. package/dist/{graph-B17RjVhE.js.map → graph-s57f-VCR.js.map} +1 -1
  18. package/dist/{improvement-cycle-BP4rDivU.js → improvement-cycle-BE3gIJwL.js} +458 -60
  19. package/dist/improvement-cycle-BE3gIJwL.js.map +1 -0
  20. package/dist/{index-DTGWDyrF.d.ts → index-CAG31NtK.d.ts} +7 -7
  21. package/dist/index.d.ts +11 -8
  22. package/dist/index.js +27 -17
  23. package/dist/index.js.map +1 -1
  24. package/dist/intelligence.d.ts +3 -3
  25. package/dist/intelligence.js +9 -6
  26. package/dist/intelligence.js.map +1 -1
  27. package/dist/kernel.d.ts +3 -3
  28. package/dist/kernel.js +9 -9
  29. package/dist/{loop-runner-bin-BGi5UT85.d.ts → loop-runner-bin-B_oSVrE7.d.ts} +3 -3
  30. package/dist/{loop-runner-bin-mrOuv9SU.js → loop-runner-bin-Bp8Mih20.js} +3 -3
  31. package/dist/{loop-runner-bin-mrOuv9SU.js.map → loop-runner-bin-Bp8Mih20.js.map} +1 -1
  32. package/dist/loop-runner-bin.d.ts +1 -1
  33. package/dist/loop-runner-bin.js +1 -1
  34. package/dist/mcp/bin.js +3 -3
  35. package/dist/mcp/index.d.ts +5 -5
  36. package/dist/mcp/index.js +4 -4
  37. package/dist/{openai-tools-BPPAXxP2.d.ts → openai-tools-B1GMKDjW.d.ts} +2 -2
  38. package/dist/{prepare-Dc30WRB0.js → prepare-CibQrhfi.js} +28 -28
  39. package/dist/prepare-CibQrhfi.js.map +1 -0
  40. package/dist/profiles.d.ts +2 -2
  41. package/dist/{protected-model-port-D5gDcnrH.js → protected-model-port-Dhdi5mDl.js} +3 -3
  42. package/dist/{protected-model-port-D5gDcnrH.js.map → protected-model-port-Dhdi5mDl.js.map} +1 -1
  43. package/dist/{protected-redaction-wGo44k2K.js → protected-redaction-Fn1ETfJ-.js} +6 -6
  44. package/dist/protected-redaction-Fn1ETfJ-.js.map +1 -0
  45. package/dist/{provision-supervisor-CNdrsjvc.js → provision-supervisor-D0X9KUv-.js} +5 -5
  46. package/dist/{provision-supervisor-CNdrsjvc.js.map → provision-supervisor-D0X9KUv-.js.map} +1 -1
  47. package/dist/{run-layout-hZREkcfu.js → run-layout-B8-Gqhpg.js} +2 -2
  48. package/dist/{run-layout-hZREkcfu.js.map → run-layout-B8-Gqhpg.js.map} +1 -1
  49. package/dist/{runtime-BsPY_v8H.js → runtime-CHbVv5UI.js} +16 -13
  50. package/dist/{runtime-BsPY_v8H.js.map → runtime-CHbVv5UI.js.map} +1 -1
  51. package/dist/{server-b8uEBoK0.js → server-DwsC_FyV.js} +3 -3
  52. package/dist/{server-b8uEBoK0.js.map → server-DwsC_FyV.js.map} +1 -1
  53. package/dist/{stream-agent-turn-xgmm-M55.d.ts → stream-agent-turn-DQ-W8mHf.d.ts} +2 -2
  54. package/dist/{structural-rollout-sy2sH_7-.js → structural-rollout-DasmuuUp.js} +2 -2
  55. package/dist/{structural-rollout-sy2sH_7-.js.map → structural-rollout-DasmuuUp.js.map} +1 -1
  56. package/dist/{substrate-B_9stFWH.d.ts → substrate-DJOnuoa_.d.ts} +2 -2
  57. package/dist/{supervise-CBd3FyCS.js → supervise-o6CzD2Rt.js} +142 -35
  58. package/dist/supervise-o6CzD2Rt.js.map +1 -0
  59. package/dist/{supervisor-De0lytFU.js → supervisor-tGq-TPIv.js} +162 -103
  60. package/dist/supervisor-tGq-TPIv.js.map +1 -0
  61. package/dist/testing.d.ts +2 -2
  62. package/dist/testing.js +398 -398
  63. package/dist/{top-app-CMMd8DgR.js → top-app-DL-sjv7K.js} +2 -2
  64. package/dist/{top-app-CMMd8DgR.js.map → top-app-DL-sjv7K.js.map} +1 -1
  65. package/dist/tui/bin.js +1 -1
  66. package/dist/tui/index.d.ts +1 -1
  67. package/dist/tui/index.js +2 -2
  68. package/dist/{types-CE7ES_TD.d.ts → types-BoEzH8V6.d.ts} +18 -2
  69. package/dist/{workspace-archive-CBX0hwL_.js → workspace-archive-DSRT4Tro.js} +8 -8
  70. package/dist/workspace-archive-DSRT4Tro.js.map +1 -0
  71. package/package.json +6 -6
  72. package/dist/coordination-driver-m-2dzvu6.js.map +0 -1
  73. package/dist/improvement-cycle-BP4rDivU.js.map +0 -1
  74. package/dist/prepare-Dc30WRB0.js.map +0 -1
  75. package/dist/protected-redaction-wGo44k2K.js.map +0 -1
  76. package/dist/supervise-CBd3FyCS.js.map +0 -1
  77. package/dist/supervisor-De0lytFU.js.map +0 -1
  78. package/dist/workspace-archive-CBX0hwL_.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fsConstants"],"sources":["../../src/candidate-execution/builder.ts","../../src/candidate-execution/claim-file-store.ts","../../src/candidate-execution/dispose.ts","../../src/candidate-execution/protected-model-grant.ts","../../src/candidate-execution/recover.ts","../../src/candidate-execution/workspace-tree.ts"],"sourcesContent":["import type { CodeSurface } from '@tangle-network/agent-eval/campaign'\nimport { verifyCodeSurface } from '@tangle-network/agent-eval/campaign'\nimport type {\n AgentCandidateCodeDisabled,\n AgentCandidateCodeNoOp,\n AgentCandidateExecution,\n AgentCandidateGitHubRepository,\n AgentCandidateKnowledge,\n AgentCandidateMemoryPolicy,\n AgentCandidateProfile,\n AgentProfile,\n AgentProfileDiff,\n} from '@tangle-network/agent-interface'\nimport { type AgentCandidateBundleInput, sealAgentCandidateBundle } from './bundle'\nimport { embeddedCandidateArtifact } from './digest'\nimport {\n applyExactAgentProfileDiff,\n freezeGenericAgentCandidateProfile,\n parseExactAgentProfile,\n parseExactAgentProfileDiff,\n parseExactCandidateProfile,\n} from './profile'\n\n/** A complete profile that can be frozen without losing behavior. */\nexport type AgentCandidateProfileSource =\n | {\n kind: 'profile'\n profile: AgentProfile\n }\n | {\n kind: 'profile-diffs'\n base: AgentProfile\n /** Applied in order before the resulting profile is frozen into the bundle. */\n diffs: readonly AgentProfileDiff[]\n }\n | {\n kind: 'candidate-profile'\n /** Already converted to the closed, secret-free candidate profile contract. */\n profile: AgentCandidateProfile\n }\n\n/** The only accepted path from an agent-eval code candidate to executable bytes. */\nexport interface AgentCandidateCodeSurfaceSource {\n kind: 'code-surface'\n surface: CodeSurface\n repository: AgentCandidateGitHubRepository\n /** Optional parent directory used to resolve a relative `surface.worktreeRef`. */\n worktreeDir?: string\n}\n\n/** Explicit control/no-op code or one finalized CodeSurface whose bytes must still verify. */\nexport type AgentCandidateCodeSource =\n | AgentCandidateCodeDisabled\n | AgentCandidateCodeNoOp\n | AgentCandidateCodeSurfaceSource\n\n/** Complete measured surfaces and execution policy compiled into one candidate bundle. */\nexport interface BuildAgentCandidateBundleInput {\n profile: AgentCandidateProfileSource\n code: AgentCandidateCodeSource\n execution: AgentCandidateExecution\n knowledge?: AgentCandidateKnowledge\n memory: AgentCandidateMemoryPolicy\n}\n\n/**\n * Compile one measured profile/code candidate into the immutable execution\n * contract. Code bytes are re-read and verified by agent-eval before they are\n * embedded. The returned bundle is schema-validated, canonically digested, and\n * deeply immutable; call `verifyAgentCandidateBundle` at the execution boundary\n * to re-read external memory, repository, and workspace artifacts.\n */\nexport function buildAgentCandidateBundle(\n input: BuildAgentCandidateBundleInput,\n): ReturnType<typeof sealAgentCandidateBundle> {\n const bundle: AgentCandidateBundleInput = {\n kind: 'agent-candidate-bundle',\n digestAlgorithm: 'rfc8785-sha256',\n profile: compileCandidateProfile(input.profile),\n code: compileCandidateCode(input.code),\n execution: input.execution,\n ...(input.knowledge !== undefined ? { knowledge: input.knowledge } : {}),\n memory: input.memory,\n }\n return sealAgentCandidateBundle(bundle)\n}\n\nfunction compileCandidateProfile(source: AgentCandidateProfileSource): AgentCandidateProfile {\n if (source.kind === 'candidate-profile') {\n return parseExactCandidateProfile(source.profile)\n }\n\n if (source.kind === 'profile') {\n return freezeGenericAgentCandidateProfile(source.profile)\n }\n\n if (source.kind !== 'profile-diffs') {\n throw new Error(\n `unsupported candidate profile source: ${String((source as { kind?: unknown }).kind)}`,\n )\n }\n if (source.diffs.length === 0) {\n throw new Error('profile-diffs source requires at least one AgentProfileDiff')\n }\n let profile = parseExactAgentProfile(source.base, 'base profile')\n for (const [index, inputDiff] of source.diffs.entries()) {\n const diff = parseExactAgentProfileDiff(inputDiff, `profile diff ${index}`)\n profile = applyExactAgentProfileDiff(profile, diff, `profile diff ${index}`)\n }\n return freezeGenericAgentCandidateProfile(profile)\n}\n\nfunction compileCandidateCode(source: AgentCandidateCodeSource): AgentCandidateBundleInput['code'] {\n if (source.kind === 'disabled' || source.kind === 'no-op') return source\n if (source.kind !== 'code-surface') {\n throw new Error(\n `unsupported candidate code source: ${String((source as { kind?: unknown }).kind)}`,\n )\n }\n\n const verified = verifyCodeSurface(source.surface, source.worktreeDir)\n const patch = embeddedCandidateArtifact(verified.patchBytes)\n if (\n patch.sha256 !== source.surface.patch.sha256 ||\n patch.byteLength !== source.surface.patch.byteLength\n ) {\n throw new Error('verified CodeSurface patch bytes do not match its content identity')\n }\n return {\n kind: 'git-patch',\n repository: source.repository,\n baseCommit: source.surface.baseCommit,\n baseTree: source.surface.baseTree,\n candidateTree: source.surface.candidateTree,\n patch: { format: 'git-diff-binary', artifact: patch },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { linkSync } from 'node:fs'\nimport { mkdir, open, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Sha256Digest } from '@tangle-network/agent-interface'\n\nimport {\n type AgentCandidateExecutionAttemptRecord,\n type AgentCandidateExecutionAttemptRef,\n type AgentCandidateExecutionClaim,\n type AgentCandidateExecutionClaimResult,\n type AgentCandidateExecutionClaimStore,\n type AgentCandidateExecutionFinishResult,\n type AgentCandidateExecutionLease,\n type AgentCandidateExecutionPhase,\n type AgentCandidateExecutionPhaseResult,\n type AgentCandidateExecutionRecoveryEvidence,\n type AgentCandidateExecutionStageResult,\n type AgentCandidateExecutionTerminalRecord,\n type AgentCandidateExecutionTerminalResult,\n type AgentCandidateRetryRejection,\n candidateClaimFileInternals,\n} from './claim'\nimport {\n assertRecoveryMatchesStaged,\n assertTerminalAllowedInPhase,\n assertTerminalMatchesClaim,\n assertTerminalMatchesStaged,\n recoveredTerminalRecord,\n rejectedFinish,\n rejectedStage,\n requireStagedTerminal,\n sealTerminalDigest,\n terminalRecord,\n} from './claim-terminal'\nimport { canonicalCandidateBytes } from './digest'\n\nconst {\n assertExpiredLease,\n assertLease,\n assertSameSlot,\n assertUnexpiredLease,\n attemptRecord,\n claimSlot,\n leaseDigest,\n newLease,\n readClaim,\n readClaimIfPresent,\n readTerminal,\n readTerminalIfPresent,\n readTransitionIfPresent,\n rejectedExistingClaim,\n rejectedRetry,\n retryRejection,\n sealAttemptRef,\n sealClaim,\n sealLease,\n} = candidateClaimFileInternals\n\nexport interface FileAgentCandidateExecutionClaimStoreOptions {\n /** Evaluator-owned directory shared by every process allowed to execute candidates. */\n directory: string\n /** Testable evaluator clock; defaults to `Date.now`. */\n now?: () => number\n}\n\n/** Cross-process lifecycle implemented as fsynced, create-if-absent records. */\nexport class FileAgentCandidateExecutionClaimStore implements AgentCandidateExecutionClaimStore {\n private readonly directory: string\n private readonly now: () => number\n\n constructor(options: FileAgentCandidateExecutionClaimStoreOptions) {\n if (options.directory.length === 0) {\n throw new Error('candidate execution claim directory must not be empty')\n }\n this.directory = options.directory\n this.now = options.now ?? Date.now\n }\n\n async tryClaim(\n requested: AgentCandidateExecutionClaim,\n ): Promise<AgentCandidateExecutionClaimResult> {\n const claim = sealClaim(requested)\n await mkdir(this.directory, { recursive: true })\n const claimPath = this.claimPath(claim)\n const existing = await readClaimIfPresent(claimPath)\n if (existing) {\n assertSameSlot(existing.claim, claim, claimPath)\n return rejectedExistingClaim(existing.claim, claim)\n }\n assertUnexpiredLease(claim.leaseExpiresAtMs, this.now())\n const retryFailure = await this.retryFailure(claim)\n if (retryFailure) return rejectedRetry(claim, retryFailure)\n\n const lease = newLease(claim)\n const acquired = await writeRecordIfAbsent(this.directory, claimPath, {\n ...claim,\n phase: 'claimed',\n leaseDigest: leaseDigest(lease),\n })\n if (acquired) return Object.freeze({ acquired: true, claim, lease })\n\n const winner = await readClaim(claimPath)\n assertSameSlot(winner.claim, claim, claimPath)\n return rejectedExistingClaim(winner.claim, claim)\n }\n\n async getAttempt(\n requestedAttempt: AgentCandidateExecutionAttemptRef,\n ): Promise<AgentCandidateExecutionAttemptRecord | undefined> {\n return await this.storedAttempt(sealAttemptRef(requestedAttempt))\n }\n\n async markCandidateMayRun(\n requestedLease: AgentCandidateExecutionLease,\n ): Promise<AgentCandidateExecutionPhaseResult> {\n const lease = sealLease(requestedLease)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const state = await this.transitionState(stored.claim)\n if (state.phase === 'candidate-may-run') {\n return Object.freeze({ marked: false, phase: 'candidate-may-run' })\n }\n if (state.staged) {\n throw new Error('candidate execution terminal was staged before candidate-may-run phase')\n }\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const marked = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(stored.claim, 1),\n {\n kind: 'candidate-execution-phase',\n executionId: stored.claim.executionId,\n attempt: stored.claim.attempt,\n executionPlanDigest: stored.claim.executionPlanDigest,\n phase: 'candidate-may-run',\n },\n this.ownerPublication(stored.claim),\n )\n if (marked) return Object.freeze({ marked: true, phase: 'candidate-may-run' })\n const winner = await this.transitionState(stored.claim)\n if (winner.phase === 'candidate-may-run') {\n return Object.freeze({ marked: false, phase: 'candidate-may-run' })\n }\n throw new Error('candidate execution terminal was staged before candidate-may-run phase')\n }\n\n async stageTerminal(\n requestedLease: AgentCandidateExecutionLease,\n result: AgentCandidateExecutionTerminalResult,\n ): Promise<AgentCandidateExecutionStageResult> {\n const lease = sealLease(requestedLease)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const terminal = terminalRecord(stored.claim, result)\n const state = await this.transitionState(stored.claim)\n if (state.staged) return rejectedStage(state.staged, terminal)\n assertTerminalAllowedInPhase(state.phase, terminal)\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const transition = state.phase === 'claimed' ? 1 : 2\n const staged = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(stored.claim, transition),\n {\n kind: 'candidate-execution-pending-terminal',\n terminal,\n },\n this.ownerPublication(stored.claim),\n )\n if (staged) return Object.freeze({ staged: true, terminal })\n const winner = await this.transitionState(stored.claim)\n if (!winner.staged) {\n throw new Error('candidate execution phase transition won while staging terminal')\n }\n return rejectedStage(winner.staged, terminal)\n }\n\n async finish(\n requestedLease: AgentCandidateExecutionLease,\n requestedTerminalDigest: Sha256Digest,\n ): Promise<AgentCandidateExecutionFinishResult> {\n const lease = sealLease(requestedLease)\n const terminalDigest = sealTerminalDigest(requestedTerminalDigest)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const state = await this.transitionState(stored.claim)\n const staged = requireStagedTerminal(state.staged, terminalDigest)\n const terminalPath = this.terminalPath(lease)\n const existing = await readTerminalIfPresent(terminalPath)\n if (existing) {\n assertTerminalMatchesClaim(existing, stored.claim, terminalPath)\n assertTerminalMatchesStaged(existing, staged, terminalPath)\n return rejectedFinish(existing, terminalDigest)\n }\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const finished = await writeRecordIfAbsent(\n this.directory,\n terminalPath,\n {\n terminal: staged,\n },\n this.ownerPublication(stored.claim),\n )\n if (finished) return Object.freeze({ finished: true, terminal: staged })\n const winner = await readTerminal(terminalPath)\n assertSameSlot(winner, lease, terminalPath)\n assertTerminalMatchesClaim(winner, stored.claim, terminalPath)\n assertTerminalMatchesStaged(winner, staged, terminalPath)\n return rejectedFinish(winner, terminalDigest)\n }\n\n async recoverExpired(\n requestedAttempt: AgentCandidateExecutionAttemptRef,\n evidence: AgentCandidateExecutionRecoveryEvidence,\n ): Promise<AgentCandidateExecutionFinishResult> {\n const attempt = sealAttemptRef(requestedAttempt)\n const record = await this.storedAttempt(attempt)\n if (!record) throw new Error('candidate execution recovery does not name an acquired attempt')\n const recovered = recoveredTerminalRecord(record.claim, record.phase, evidence)\n if (record.staged) assertRecoveryMatchesStaged(record.staged, recovered)\n const requestedDigest = record.staged?.terminalDigest ?? recovered.terminalDigest\n if (record.terminal) return rejectedFinish(record.terminal, requestedDigest)\n assertExpiredLease(record.claim.leaseExpiresAtMs, this.now())\n\n let staged = record.staged\n if (!staged) {\n const transition = record.phase === 'claimed' ? 1 : 2\n const didStage = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(record.claim, transition),\n {\n kind: 'candidate-execution-pending-terminal',\n terminal: recovered,\n },\n )\n if (didStage) {\n staged = recovered\n } else {\n const winner = await this.transitionState(record.claim)\n if (!winner.staged) {\n throw new Error(\n 'candidate execution recovery lost terminal staging to a phase transition',\n )\n }\n assertRecoveryMatchesStaged(winner.staged, recovered)\n staged = winner.staged\n }\n }\n\n const terminalPath = this.terminalPath(attempt)\n const didFinish = await writeRecordIfAbsent(this.directory, terminalPath, {\n terminal: staged,\n })\n if (didFinish) return Object.freeze({ finished: true, terminal: staged })\n const winner = await readTerminal(terminalPath)\n assertSameSlot(winner, attempt, terminalPath)\n assertTerminalMatchesClaim(winner, record.claim, terminalPath)\n assertTerminalMatchesStaged(winner, staged, terminalPath)\n return rejectedFinish(winner, staged.terminalDigest)\n }\n\n private async storedAttempt(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ): Promise<AgentCandidateExecutionAttemptRecord | undefined> {\n const claimPath = this.claimPath(claim)\n const stored = await readClaimIfPresent(claimPath)\n if (!stored) return undefined\n assertSameSlot(stored.claim, claim, claimPath)\n const terminalPath = this.terminalPath(claim)\n const terminal = await readTerminalIfPresent(terminalPath)\n // Terminal publication follows its immutable staged outbox, so read that prerequisite later.\n const state = await this.transitionState(stored.claim)\n if (terminal) {\n assertTerminalMatchesClaim(terminal, stored.claim, terminalPath)\n if (!state.staged) {\n throw new Error(\n `candidate execution terminal record at ${terminalPath} has no staged outbox`,\n )\n }\n assertTerminalMatchesStaged(terminal, state.staged, terminalPath)\n }\n return attemptRecord(stored.claim, state.phase, state.staged, terminal)\n }\n\n private async transitionState(claim: AgentCandidateExecutionClaim): Promise<{\n phase: AgentCandidateExecutionPhase\n staged?: AgentCandidateExecutionTerminalRecord\n }> {\n const firstPath = this.transitionPath(claim, 1)\n const first = await readTransitionIfPresent(firstPath, claim)\n if (!first) return { phase: 'claimed' }\n if (first.kind === 'pending') return { phase: 'claimed', staged: first.terminal }\n const secondPath = this.transitionPath(claim, 2)\n const second = await readTransitionIfPresent(secondPath, claim)\n if (!second) return { phase: 'candidate-may-run' }\n if (second.kind !== 'pending') {\n throw new Error(`candidate execution transition at ${secondPath} repeats the phase marker`)\n }\n return { phase: 'candidate-may-run', staged: second.terminal }\n }\n\n private async retryFailure(\n claim: AgentCandidateExecutionClaim,\n ): Promise<AgentCandidateRetryRejection | undefined> {\n if (claim.attempt === 1) return undefined\n return retryRejection(\n claim,\n await this.storedAttempt({\n executionId: claim.executionId,\n attempt: claim.attempt - 1,\n }),\n )\n }\n\n private ownerPublication(claim: AgentCandidateExecutionClaim): {\n authorizePublish: () => true\n } {\n return {\n authorizePublish: () => {\n assertUnexpiredLease(claim.leaseExpiresAtMs, this.now())\n return true\n },\n }\n }\n\n private claimPath(claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>): string {\n return join(this.directory, `${claimSlot(claim)}.claim.json`)\n }\n\n private terminalPath(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ): string {\n return join(this.directory, `${claimSlot(claim)}.terminal.json`)\n }\n\n private transitionPath(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ordinal: 1 | 2,\n ): string {\n return join(this.directory, `${claimSlot(claim)}.transition-${ordinal}.json`)\n }\n}\n\n/**\n * Candidate records keep this async writer because lease authorization must run after the\n * asynchronous temp-file fsync and immediately before synchronous link publication. The\n * supervisor durability helper is synchronous and has no lease hook, so combining them would\n * either move authorization earlier or add an async race to the claim boundary.\n */\nasync function writeRecordIfAbsent(\n directory: string,\n destination: string,\n record: object,\n options: {\n /** Synchronous authorization checked after temp fsync, immediately before atomic publication. */\n authorizePublish?: () => true\n } = {},\n): Promise<boolean> {\n const temporaryPath = join(directory, `.candidate-execution-${process.pid}-${randomUUID()}.tmp`)\n const handle = await open(temporaryPath, 'wx', 0o600)\n try {\n await handle.writeFile(\n Buffer.concat([Buffer.from(canonicalCandidateBytes(record)), Buffer.from('\\n')]),\n )\n await handle.sync()\n } finally {\n await handle.close()\n }\n\n let written = false\n try {\n if (options.authorizePublish && options.authorizePublish() !== true) {\n throw new Error('candidate execution record publication was not authorized')\n }\n // Authorization and the atomic filesystem call are one synchronous critical\n // section so the event loop cannot advance an injected lease clock between them.\n linkSync(temporaryPath, destination)\n written = true\n await syncDirectory(directory)\n } catch (error) {\n if (!isNodeError(error, 'EEXIST')) throw error\n } finally {\n await unlink(temporaryPath).catch((error: unknown) => {\n if (!isNodeError(error, 'ENOENT')) throw error\n })\n }\n return written\n}\n\nasync function syncDirectory(directory: string): Promise<void> {\n const handle = await open(directory, 'r')\n try {\n await handle.sync()\n } finally {\n await handle.close()\n }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n error !== null &&\n typeof error === 'object' &&\n 'code' in error &&\n (error as { code?: unknown }).code === code\n )\n}\n","import { candidateCleanupDeadline, withinCandidateCleanupDeadline } from './cleanup'\nimport { sealAgentCandidateModelSettlement } from './model-settlement'\nimport {\n assertPreparedCandidateIntegrity,\n beginPreparedCandidateDisposal,\n consumePreparedCandidateExecution,\n} from './prepared-state'\nimport type { PreparedAgentCandidateExecution } from './types'\n\nexport interface DisposePreparedAgentCandidateOptions {\n cleanupTimeoutMs?: number\n}\n\n/** Revoke reservations held by a prepared candidate that will not be executed. */\nexport async function disposePreparedAgentCandidateExecution(\n prepared: PreparedAgentCandidateExecution,\n options: DisposePreparedAgentCandidateOptions = {},\n): Promise<{ disposed: true }> {\n const initialState = assertPreparedCandidateIntegrity(prepared)\n const cleanupTimeoutMs = options.cleanupTimeoutMs ?? initialState.cleanupTimeoutMs\n if (cleanupTimeoutMs > initialState.cleanupTimeoutMs) {\n throw new Error('disposal cleanup timeout exceeds the frozen preparation bound')\n }\n const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs)\n const state = beginPreparedCandidateDisposal(prepared)\n const cleanup: Array<Promise<unknown>> = []\n\n if (state.memory.mode === 'isolated') {\n const reservation = state.memoryReservation\n if (!reservation) throw new Error('isolated memory reservation is missing')\n cleanup.push(\n withinCandidateCleanupDeadline(\n async () => {\n const closed = await state.ports.memory.close({\n executionId: state.executionId,\n preparationId: reservation.preparationId,\n accessDigest: reservation.accessDigest,\n effectiveNamespace: reservation.effectiveNamespace,\n reason: 'abandoned',\n })\n if (closed.closed !== true || Object.keys(closed).some((key) => key !== 'closed')) {\n throw new Error('abandoned isolated memory access did not acknowledge closure')\n }\n },\n cleanupDeadlineAtMs,\n 'isolated memory disposal',\n ),\n )\n }\n\n cleanup.push(\n withinCandidateCleanupDeadline(\n async () => {\n const settlement = sealAgentCandidateModelSettlement(\n await state.ports.models.settleGrant({\n executionId: state.executionId,\n preparationId: state.preparationId,\n grantDigest: state.modelReservation.digest,\n resolved: state.resolvedModel,\n reason: 'abandoned',\n }),\n {\n preparationId: state.preparationId,\n grantDigest: state.modelReservation.digest,\n model: state.resolvedModel.model,\n },\n )\n if (settlement.usage.modelCalls !== 0) {\n throw new Error('unexecuted model reservation unexpectedly contains calls')\n }\n },\n cleanupDeadlineAtMs,\n 'model reservation disposal',\n ),\n )\n\n const results = await Promise.allSettled(cleanup)\n const failures = results\n .filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n .map((result) => result.reason)\n if (failures.length > 0) {\n consumePreparedCandidateExecution(prepared, 'disposal-failed')\n throw new AggregateError(failures, 'candidate preparation disposal failed')\n }\n\n consumePreparedCandidateExecution(prepared, 'disposed')\n return Object.freeze({ disposed: true as const })\n}\n","import type { AgentCandidateResolvedModel } from '@tangle-network/agent-interface'\n\nimport type {\n AgentCandidateModelGrantActivateInput,\n AgentCandidateModelGrantReserveInput,\n AgentCandidateModelGrantSettleInput,\n} from './protected-model-port'\nimport type {\n AgentCandidateModelPort,\n AgentCandidateProtectedModelActivation,\n AgentCandidateProtectedModelReservation,\n AgentCandidateProtectedModelSettlement,\n} from './types'\n\n/** Reservation fields supplied by a caller before Runtime resolves the model. */\nexport type AgentCandidateModelGrantRunReservationInput = Omit<\n AgentCandidateModelGrantReserveInput,\n 'resolved'\n>\n\n/** Values available only while one protected model grant is active. */\nexport interface ProtectedAgentCandidateModelGrantContext {\n readonly activation: AgentCandidateProtectedModelActivation\n readonly reservation: AgentCandidateProtectedModelReservation\n readonly resolved: AgentCandidateResolvedModel\n}\n\n/** Inputs for one protected grant scoped to one bounded caller unit. */\nexport interface RunProtectedAgentCandidateModelGrantOptions<TResult> {\n /** Runtime port that validates and settles the evaluator-owned grant. */\n readonly port: AgentCandidateModelPort\n /** Provider-neutral model request resolved before any grant is reserved. */\n readonly resolve: Parameters<AgentCandidateModelPort['resolve']>[0]\n /** One bounded unit's immutable identity, attempt, expiry, and limits. */\n readonly reserve: AgentCandidateModelGrantRunReservationInput\n /** Must be no later than the reservation expiry. */\n readonly deadlineAtMs: AgentCandidateModelGrantActivateInput['deadlineAtMs']\n /** Execute exactly one bounded unit while the activated environment is valid. */\n readonly execute: (context: ProtectedAgentCandidateModelGrantContext) => Promise<TResult>\n}\n\n/** Result and sealed settlement returned after one protected grant closes. */\nexport interface RunProtectedAgentCandidateModelGrantResult<TResult> {\n readonly value: TResult\n readonly resolved: AgentCandidateResolvedModel\n readonly reservation: AgentCandidateProtectedModelReservation\n readonly settlement: AgentCandidateProtectedModelSettlement\n}\n\nconst SETTLEMENT_RETRY_INITIAL_DELAY_MS = 25\nconst SETTLEMENT_RETRY_MAX_DELAY_MS = 1_000\n\n/**\n * Run one bounded unit under a protected model grant.\n *\n * Runtime owns the grant lifecycle; callers own the unit boundary and any\n * durable scheduling or accounting around it. A reserved grant is settled\n * after activation failure or callback failure, and the callback error is\n * preserved when settlement also fails.\n */\nexport async function runProtectedAgentCandidateModelGrant<TResult>(\n options: RunProtectedAgentCandidateModelGrantOptions<TResult>,\n): Promise<RunProtectedAgentCandidateModelGrantResult<TResult>> {\n if (typeof options.execute !== 'function') {\n throw new TypeError('protected model grant execute callback is required')\n }\n\n const resolved = await options.port.resolve(options.resolve)\n const reservation = await options.port.reserveGrant({\n ...options.reserve,\n resolved,\n })\n\n let value!: TResult\n let executionError: unknown\n let executionFailed = false\n let activated = false\n let reason: AgentCandidateModelGrantSettleInput['reason'] = 'preparation-failed'\n\n try {\n const activation = await options.port.activateGrant({\n executionId: options.reserve.executionId,\n preparationId: options.reserve.preparationId,\n grantDigest: reservation.digest,\n resolved,\n deadlineAtMs: options.deadlineAtMs,\n })\n activated = true\n value = await options.execute({ activation, reservation, resolved })\n reason = 'completed'\n } catch (error) {\n executionError = error\n executionFailed = true\n if (activated) reason = 'failed'\n }\n\n let settlement: AgentCandidateProtectedModelSettlement\n try {\n settlement = await settleProtectedModelGrant(options, {\n executionId: options.reserve.executionId,\n preparationId: options.reserve.preparationId,\n grantDigest: reservation.digest,\n resolved,\n reason,\n })\n } catch (settlementError) {\n if (executionFailed) {\n throw new AggregateError(\n [executionError, settlementError],\n 'protected model execution failed and its grant did not settle',\n )\n }\n throw settlementError\n }\n\n if (executionFailed) throw executionError\n return { value, resolved, reservation, settlement }\n}\n\nasync function settleProtectedModelGrant<TResult>(\n options: RunProtectedAgentCandidateModelGrantOptions<TResult>,\n input: AgentCandidateModelGrantSettleInput,\n): Promise<AgentCandidateProtectedModelSettlement> {\n let delayMs = SETTLEMENT_RETRY_INITIAL_DELAY_MS\n for (;;) {\n try {\n return await options.port.settleGrant(input)\n } catch (error) {\n if (!isCandidateGrantDrainingError(error)) throw error\n const remainingMs = options.deadlineAtMs - Date.now()\n if (remainingMs <= 0) throw error\n await waitForSettlementRetry(Math.min(delayMs, remainingMs))\n if (Date.now() >= options.deadlineAtMs) throw error\n delayMs = Math.min(delayMs * 2, SETTLEMENT_RETRY_MAX_DELAY_MS)\n }\n }\n}\n\nfunction waitForSettlementRetry(delayMs: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, delayMs))\n}\n\n/** Only the gateway's explicit draining state is retryable; auth and ledger errors fail closed. */\nfunction isCandidateGrantDrainingError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false\n const candidate = error as { code?: unknown; message?: unknown }\n if (candidate.code === 'candidate_grant_draining') return true\n return (\n typeof candidate.message === 'string' && /\\bcandidate_grant_draining\\b/u.test(candidate.message)\n )\n}\n","import type { TraceStore } from '@tangle-network/agent-eval'\nimport type {\n AgentCandidateExecutionPlanMaterial,\n AgentCandidateMaterializationReceipt,\n} from '@tangle-network/agent-interface'\nimport {\n agentCandidateExecutionPlanMaterialSchema,\n agentCandidateMaterializationReceiptSchema,\n} from '@tangle-network/agent-interface'\n\nimport { readVerifiedArtifact } from './artifacts'\nimport type {\n AgentCandidateExecutionAttemptRef,\n AgentCandidateExecutionClaim,\n AgentCandidateExecutionClaimStore,\n AgentCandidateExecutionFinishResult,\n} from './claim'\nimport {\n candidateCleanupDeadline,\n candidateCleanupTimeout,\n withinCandidateCleanupDeadline,\n} from './cleanup'\nimport { canonicalCandidateBytes } from './digest'\nimport { sealAgentCandidateExecutorStopAcknowledgement } from './executor-capture'\nimport { sealAgentCandidateModelSettlement } from './model-settlement'\nimport { persistCandidateModelSettlementEvidence } from './outcome-evidence'\nimport { persistCandidateOutputArtifact } from './output-artifacts'\nimport { RecoveryAgentCandidateTraceStore } from './protected-trace-store'\nimport type {\n AgentCandidateExecutionPorts,\n AgentCandidateExecutorPort,\n AgentCandidateOutputArtifactPort,\n} from './types'\n\nexport interface RecoverExpiredAgentCandidateOptions {\n attempt: AgentCandidateExecutionAttemptRef\n claimStore: AgentCandidateExecutionClaimStore\n executor: AgentCandidateExecutorPort\n traceStore: TraceStore\n ports: Pick<AgentCandidateExecutionPorts, 'models' | 'memory'>\n outputArtifacts: AgentCandidateOutputArtifactPort\n cleanupTimeoutMs?: number\n /** Evaluator clock; must be the same clock used by the claim store. */\n now?: () => number\n}\n\n/** Close an expired crashed attempt from persisted non-secret handles, then record failure. */\nexport async function recoverExpiredAgentCandidateExecution(\n options: RecoverExpiredAgentCandidateOptions,\n): Promise<AgentCandidateExecutionFinishResult> {\n const record = await options.claimStore.getAttempt(options.attempt)\n if (!record) throw new Error('candidate execution recovery attempt is missing')\n if (record.terminal) {\n return Object.freeze({ finished: false, terminal: record.terminal, exactReplay: true })\n }\n const cleanupTimeoutMs = candidateCleanupTimeout(\n options.cleanupTimeoutMs ?? record.claim.cleanup.cleanupTimeoutMs,\n )\n if (cleanupTimeoutMs > record.claim.cleanup.cleanupTimeoutMs) {\n throw new Error('recovery cleanup timeout exceeds the frozen preparation bound')\n }\n\n const now = options.now ?? Date.now\n if (now() < record.claim.leaseExpiresAtMs) {\n throw new Error('candidate execution lease has not expired')\n }\n\n const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs)\n const recoveryTraceStore = new RecoveryAgentCandidateTraceStore(options.traceStore)\n const preparation = withinCandidateCleanupDeadline(\n () => readRecoveryPreparation(record.claim, options.outputArtifacts),\n cleanupDeadlineAtMs,\n 'expired candidate preparation evidence read',\n )\n const processClosure = withinCandidateCleanupDeadline(\n async (cleanupSignal) => {\n const stopped = await options.executor.stop(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n {\n traceStore: recoveryTraceStore,\n reason: 'failed',\n signal: cleanupSignal,\n deadlineAtMs: cleanupDeadlineAtMs,\n },\n )\n sealAgentCandidateExecutorStopAcknowledgement(stopped)\n if (options.executor.dispose) {\n const disposed = await options.executor.dispose(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n { signal: cleanupSignal },\n )\n if (disposed.disposed !== true || Object.keys(disposed).some((key) => key !== 'disposed')) {\n throw new Error('expired candidate executor did not acknowledge resource disposal')\n }\n }\n return { stopped: true as const }\n },\n cleanupDeadlineAtMs,\n 'expired candidate process termination',\n )\n\n const modelClosure = withinCandidateCleanupDeadline(\n async () =>\n sealAgentCandidateModelSettlement(\n await options.ports.models.settleGrant({\n executionId: record.claim.executionId,\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n resolved: record.claim.cleanup.resolvedModel,\n reason: 'failed',\n }),\n {\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n model: record.claim.cleanup.resolvedModel.model,\n },\n ),\n cleanupDeadlineAtMs,\n 'expired candidate model settlement',\n )\n\n const memoryClosure = record.claim.cleanup.memory\n ? withinCandidateCleanupDeadline(\n async () => {\n const memory = record.claim.cleanup.memory\n if (!memory) throw new Error('expired candidate memory handle is missing')\n const closed = await options.ports.memory.close({\n executionId: record.claim.executionId,\n preparationId: record.claim.cleanup.preparationId,\n accessDigest: memory.accessDigest,\n effectiveNamespace: memory.effectiveNamespace,\n reason: 'failed',\n })\n if (closed.closed !== true || Object.keys(closed).some((key) => key !== 'closed')) {\n throw new Error('expired candidate memory did not acknowledge closure')\n }\n return { closed: true as const }\n },\n cleanupDeadlineAtMs,\n 'expired candidate memory closure',\n )\n : undefined\n\n const closureOutcomes = Promise.allSettled([\n modelClosure,\n memoryClosure ?? Promise.resolve(undefined),\n ] as const)\n const [preparationOutcome, processOutcome] = await Promise.allSettled([\n preparation,\n processClosure,\n ] as const)\n const failures: unknown[] = [preparationOutcome, processOutcome]\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason)\n const [modelOutcome, memoryOutcome] = await closureOutcomes\n for (const outcome of [modelOutcome, memoryOutcome]) {\n if (outcome.status === 'rejected') failures.push(outcome.reason)\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, 'expired candidate cleanup could not be proven')\n }\n\n if (modelOutcome.status !== 'fulfilled') {\n throw new Error('expired candidate model settlement was not recovered')\n }\n const model = modelOutcome.value\n const modelSettlement = await withinCandidateCleanupDeadline(\n () =>\n persistCandidateModelSettlementEvidence(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n resolvedModel: record.claim.cleanup.resolvedModel,\n },\n model,\n options.outputArtifacts,\n ),\n cleanupDeadlineAtMs,\n 'expired candidate model-settlement persistence',\n )\n const failureClass =\n record.phase === 'claimed' && model.usage.modelCalls === 0\n ? 'pre-model-infrastructure'\n : 'unknown'\n const failureEvidence = await withinCandidateCleanupDeadline(\n () =>\n persistCandidateOutputArtifact(options.outputArtifacts, {\n executionId: record.claim.executionId,\n purpose: 'failure-evidence',\n bytes: canonicalCandidateBytes({\n kind: 'agent-candidate-recovery-failure',\n executionId: record.claim.executionId,\n attempt: record.claim.attempt,\n bundleDigest: record.claim.bundleDigest,\n executionPlanDigest: record.claim.executionPlanDigest,\n materializationReceiptDigest:\n record.claim.preparationEvidence.materializationReceipt.sha256,\n failureClass,\n processStopped: true,\n modelSettlementDigest: modelSettlement.digest,\n memoryClosed: record.claim.cleanup.memory !== undefined,\n }),\n }),\n cleanupDeadlineAtMs,\n 'expired candidate failure-evidence persistence',\n )\n const memory = record.claim.cleanup.memory\n return await options.claimStore.recoverExpired(options.attempt, {\n failureClass,\n usage: model.usage,\n modelSettlement: modelSettlement.artifact,\n failureEvidence,\n process: {\n stopped: true,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n model: {\n closed: true,\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n },\n ...(memory\n ? {\n memory: {\n closed: true,\n preparationId: record.claim.cleanup.preparationId,\n accessDigest: memory.accessDigest,\n effectiveNamespace: memory.effectiveNamespace,\n },\n }\n : {}),\n })\n}\n\nasync function readRecoveryPreparation(\n claim: AgentCandidateExecutionClaim,\n artifacts: AgentCandidateOutputArtifactPort,\n): Promise<{\n plan: AgentCandidateExecutionPlanMaterial\n receipt: AgentCandidateMaterializationReceipt\n}> {\n const [planBytes, receiptBytes] = await Promise.all([\n readVerifiedArtifact(claim.preparationEvidence.executionPlan, artifacts),\n readVerifiedArtifact(claim.preparationEvidence.materializationReceipt, artifacts),\n ])\n const plan = agentCandidateExecutionPlanMaterialSchema.parse(\n parseCanonicalBytes(planBytes, 'plan'),\n )\n if (claim.preparationEvidence.executionPlan.sha256 !== claim.executionPlanDigest) {\n throw new Error('recovery execution plan artifact does not match the claimed digest')\n }\n const receiptMaterial = parseCanonicalBytes(receiptBytes, 'materialization receipt')\n const receipt = agentCandidateMaterializationReceiptSchema.parse({\n ...receiptMaterial,\n digest: claim.preparationEvidence.materializationReceipt.sha256,\n })\n if (\n receipt.bundleDigest !== claim.bundleDigest ||\n receipt.executionPlan.digest !== claim.executionPlanDigest ||\n plan.runCell.bundleDigest !== claim.bundleDigest ||\n plan.executionId !== claim.executionId\n ) {\n throw new Error('recovery preparation evidence does not match the durable claim')\n }\n return { plan, receipt }\n}\n\nfunction parseCanonicalBytes(bytes: Uint8Array, label: string): Record<string, unknown> {\n let parsed: unknown\n try {\n parsed = JSON.parse(Buffer.from(bytes).toString('utf8'))\n } catch (error) {\n throw new Error(`candidate recovery ${label} is not JSON`, { cause: error })\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`candidate recovery ${label} must be an object`)\n }\n if (!Buffer.from(canonicalCandidateBytes(parsed)).equals(Buffer.from(bytes))) {\n throw new Error(`candidate recovery ${label} bytes are not canonical`)\n }\n return parsed as Record<string, unknown>\n}\n","/**\n * A content digest over a DIRECTORY TREE, and the per-file seed that fills one.\n *\n * The question this answers is \"is this workspace the same workspace\" — the question every launch\n * and every close of a branchable run has to answer, about a tree that a live process is still\n * writing to. That is a different question from the one\n * {@link scanMaterializedWorkspaceManifest} answers, and the difference decides the policies here:\n *\n * - A candidate manifest describes ONE EXACT regular-file workspace. It refuses a symbolic link\n * outright, because `AgentCandidateWorkspaceManifestMaterial` has no representation for one, and\n * it refuses an entry that disappears, because a signed manifest describes a settled tree.\n * - A tree descriptor describes what a RUN PRODUCED. A python venv writes\n * `bin/python -> /usr/bin/python3` as a matter of course, and a work directory can lose an entry\n * between two directory reads. Refusing on either aborts the close, and a run that never wrote\n * its digest can never be branched from.\n *\n * So the two policies are the caller's, one for links and one for vanishing entries, and both\n * default to `'refuse'` — the strict reading, correct for an INPUT seed, where a link that leaves\n * the tree means the seed describes bytes it does not contain. `'exclude'` is the reading a close\n * needs: the entry is never followed, it is recorded, and the exclusion itself is hashed, so two\n * trees that differ only in an excluded entry cannot share a digest.\n *\n * NOTHING is held in memory. A file reaches the tree digest as its own streamed sha-256 plus its\n * length, so the largest file in the tree does not decide whether the tree can be described:\n * `readFile` refuses anything above 2 GiB with `ERR_FS_FILE_TOO_LARGE`, and a single multi-gigabyte\n * artifact is exactly what a run leaves behind.\n *\n * @module\n * @experimental\n */\n\nimport { createHash } from 'node:crypto'\nimport { constants as fsConstants } from 'node:fs'\nimport { cp, lstat, open, readdir, readlink, realpath } from 'node:fs/promises'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\nimport type { Sha256Digest } from '@tangle-network/agent-interface'\n\n/**\n * `'tree-v1'` records a file's exact permission bits. `'portable-tree-v1'` records the two modes\n * Git stores — `755` when any execute bit is set, `644` otherwise, and `755` for a directory — so a\n * digest survives a checkout whose umask differs. Both stamp the algorithm into the digest, so one\n * tree cannot produce the same digest under both.\n */\nexport type WorkspaceTreeAlgorithm = 'tree-v1' | 'portable-tree-v1'\n\n/** What a walk does with an entry it refuses to describe: fail, or record and continue. */\nexport type WorkspaceTreeEntryPolicy = 'refuse' | 'exclude'\n\n/** Why one entry contributed its name instead of its content. */\nexport type WorkspaceTreeExclusionReason =\n | 'absolute-symlink'\n | 'symlink-escapes-tree'\n | 'symlink-resolves-outside-tree'\n | 'unresolved-symlink'\n | 'entry-disappeared'\n\n/** One entry the walk recorded but did not describe. Reported rather than dropped: a digest that\n * silently omitted an entry would be a different digest with no way to tell why. */\nexport interface WorkspaceTreeExclusion {\n /** Tree-relative path, `/`-separated. */\n readonly path: string\n readonly reason: WorkspaceTreeExclusionReason\n /** The link target exactly as it was written, for a symbolic-link exclusion. */\n readonly target?: string\n}\n\nexport interface WorkspaceTreeDescriptor {\n readonly algorithm: WorkspaceTreeAlgorithm\n readonly digest: Sha256Digest\n readonly files: number\n readonly directories: number\n /** Links kept INSIDE the tree. An excluded link is counted in `excluded`, never here. */\n readonly symlinks: number\n /** Total described regular-file bytes. */\n readonly bytes: number\n readonly excluded: ReadonlyArray<WorkspaceTreeExclusion>\n}\n\nexport interface DescribeWorkspaceTreeOptions {\n /** Default `'tree-v1'`. */\n readonly algorithm?: WorkspaceTreeAlgorithm\n /**\n * A symbolic link that is absolute, leaves the tree lexically, resolves outside it, or does not\n * resolve at all. `'refuse'` (default) is correct for an input seed. `'exclude'` is correct for a\n * close-time walk over a tree a run wrote. The link is NEVER followed in either policy: an\n * escaping link must not contribute bytes from outside the tree to a content address.\n */\n readonly onEscapingLink?: WorkspaceTreeEntryPolicy\n /**\n * An entry that vanished between the directory read that named it and the walk that reached it.\n * `'refuse'` (default) is correct for a settled tree; `'exclude'` is correct for a workspace a\n * live process still writes to.\n */\n readonly onMissingEntry?: WorkspaceTreeEntryPolicy\n}\n\nexport interface SeedWorkspaceTreeInput {\n /** The tree to copy FROM. Described, then copied entry by entry. */\n readonly source: string\n /** The tree to copy INTO. Must exist, and must not lie inside `source`. */\n readonly destination: string\n /** Default `'tree-v1'`; decides only the digest this returns, never the bytes it writes. */\n readonly algorithm?: WorkspaceTreeAlgorithm\n}\n\nconst TREE_ALGORITHMS: ReadonlySet<string> = new Set<WorkspaceTreeAlgorithm>([\n 'tree-v1',\n 'portable-tree-v1',\n])\n\nconst ENTRY_POLICIES: ReadonlySet<string> = new Set<WorkspaceTreeEntryPolicy>(['refuse', 'exclude'])\n\n/**\n * Describe one directory tree by content, streaming every file.\n *\n * The digest covers, for every entry in sorted order: its kind, its tree-relative path, its mode\n * under the selected algorithm, and then — for a file, its length and its own sha-256; for a kept\n * link, its target; for an excluded entry, the reason and the target. A file's content therefore\n * never enters the tree hash directly, which is what removes any in-memory size ceiling: the tree\n * hash consumes 32 bytes per file however large the file is.\n *\n * A hard-linked regular file is described like any other regular file. Its content is what the\n * digest is about, and a package manager that links a store into `node_modules` is ordinary\n * content, not a reason to refuse a workspace.\n */\nexport async function describeWorkspaceTree(\n directory: string,\n options: DescribeWorkspaceTreeOptions = {},\n): Promise<WorkspaceTreeDescriptor> {\n const algorithm = options.algorithm ?? 'tree-v1'\n const onEscapingLink = options.onEscapingLink ?? 'refuse'\n const onMissingEntry = options.onMissingEntry ?? 'refuse'\n if (!TREE_ALGORITHMS.has(algorithm)) {\n throw new Error(`unsupported workspace tree algorithm: ${algorithm}`)\n }\n for (const [name, policy] of [\n ['onEscapingLink', onEscapingLink],\n ['onMissingEntry', onMissingEntry],\n ] as const) {\n if (!ENTRY_POLICIES.has(policy)) {\n throw new Error(`unsupported workspace tree ${name} policy: ${policy}`)\n }\n }\n\n const root = resolve(directory)\n const rootStats = await lstatIfPresent(root)\n if (rootStats === null || !rootStats.isDirectory() || rootStats.isSymbolicLink()) {\n throw new Error(`workspace tree root must be a real directory: ${directory}`)\n }\n // Resolve the root once. Every physical containment test below compares against the RESOLVED\n // root, so a symlinked prefix — which is what macOS hands out for a temp directory — does not\n // make every entry look like it escapes.\n const physicalRoot = await realpath(root)\n\n const hash = createHash('sha256')\n // The algorithm is part of the digest. Without this, a tree whose modes already are 755/644\n // produces one digest under both algorithms, and two different questions share one answer.\n hash.update(`workspace-tree\\0${algorithm}\\0`)\n const counts = { files: 0, directories: 0, symlinks: 0, bytes: 0 }\n const excluded: WorkspaceTreeExclusion[] = []\n\n const exclude = (path: string, reason: WorkspaceTreeExclusionReason, target?: string): void => {\n const name = treePath(root, path)\n excluded.push(\n Object.freeze(target === undefined ? { path: name, reason } : { path: name, reason, target }),\n )\n // The reason is hashed with the entry. Two trees that differ only in WHY an entry was excluded\n // are different trees, and a refusal must not become a way to hide a difference.\n hash.update(`excluded\\0${name}\\0${reason}\\0${target ?? ''}\\0`)\n }\n\n /** True when the caller asked to continue past a vanished entry, and it was not the root. */\n const recordMissing = (path: string): boolean => {\n if (onMissingEntry === 'refuse' || path === root) return false\n exclude(path, 'entry-disappeared')\n return true\n }\n\n const visit = async (path: string): Promise<void> => {\n const info = await lstatIfPresent(path)\n if (info === null) {\n if (recordMissing(path)) return\n throw new Error(`workspace tree entry disappeared during the walk: ${treePath(root, path)}`)\n }\n const name = treePath(root, path)\n const mode = entryMode(info.mode, algorithm, info.isDirectory(), info.isSymbolicLink())\n\n if (info.isDirectory()) {\n let entries: string[]\n try {\n entries = await readdir(path)\n } catch (error) {\n if (isMissing(error) && recordMissing(path)) return\n throw error\n }\n counts.directories += 1\n hash.update(`directory\\0${name}\\0${mode}\\0`)\n for (const entry of entries.sort()) await visit(join(path, entry))\n return\n }\n\n if (info.isSymbolicLink()) {\n await visitSymbolicLink(path, name, mode)\n return\n }\n\n if (!info.isFile()) {\n throw new Error(`workspace tree contains an unsupported entry: ${name}`)\n }\n const read = await digestFile(path)\n if (read === null) {\n if (recordMissing(path)) return\n throw new Error(`workspace tree entry disappeared during the walk: ${name}`)\n }\n counts.files += 1\n counts.bytes += read.byteLength\n hash.update(`file\\0${name}\\0${mode}\\0${read.byteLength}\\0${read.sha256}\\0`)\n }\n\n const visitSymbolicLink = async (path: string, name: string, mode: string): Promise<void> => {\n let target: string\n try {\n target = await readlink(path)\n } catch (error) {\n if (isMissing(error) && recordMissing(path)) return\n throw error\n }\n const refuse = (reason: WorkspaceTreeExclusionReason): void => {\n if (onEscapingLink === 'refuse') {\n throw new Error(\n `workspace tree contains a link that ${reasonText(reason)}: ${name} -> ${target}`,\n )\n }\n exclude(path, reason, target)\n }\n if (isAbsolute(target)) return refuse('absolute-symlink')\n if (!isWithin(root, resolve(dirname(path), target))) return refuse('symlink-escapes-tree')\n let physicalTarget: string\n try {\n physicalTarget = await realpath(path)\n } catch {\n // A dangling link is a fact about the tree, not a reason to make the run unrecoverable.\n return refuse('unresolved-symlink')\n }\n if (!isWithin(physicalRoot, physicalTarget)) return refuse('symlink-resolves-outside-tree')\n counts.symlinks += 1\n hash.update(`symlink\\0${name}\\0${mode}\\0${target}\\0`)\n }\n\n await visit(root)\n return Object.freeze({\n algorithm,\n digest: `sha256:${hash.digest('hex')}` as Sha256Digest,\n files: counts.files,\n directories: counts.directories,\n symlinks: counts.symlinks,\n bytes: counts.bytes,\n excluded: Object.freeze(excluded),\n })\n}\n\n/**\n * Seed a workspace from a directory, one entry at a time, and return the digest of what was\n * seeded.\n *\n * Nothing is packed: `cp` walks and copies file by file, so a multi-gigabyte seed costs one file\n * handle rather than one archive in memory. Existing destination entries are never overwritten —\n * a seed that could replace a file the workspace already holds would make the resulting tree\n * depend on the order two seeds ran in.\n *\n * Links are copied verbatim, exactly as they were written. Following them would copy bytes from\n * outside the seed into the workspace, which is the same rule {@link describeWorkspaceTree}\n * applies to the digest.\n */\nexport async function seedWorkspaceTree(\n input: SeedWorkspaceTreeInput,\n): Promise<WorkspaceTreeDescriptor> {\n const source = resolve(input.source)\n const destination = resolve(input.destination)\n if (source === destination || isWithin(source, destination)) {\n throw new Error('workspace seed must not contain its destination')\n }\n const destinationStats = await lstatIfPresent(destination)\n if (destinationStats === null || !destinationStats.isDirectory()) {\n throw new Error(\n `workspace seed destination must be an existing directory: ${input.destination}`,\n )\n }\n // Described BEFORE anything is copied, so a seed this refuses leaves the destination untouched.\n const descriptor = await describeWorkspaceTree(source, {\n ...(input.algorithm === undefined ? {} : { algorithm: input.algorithm }),\n })\n for (const name of (await readdir(source)).sort()) {\n if ((await lstatIfPresent(join(destination, name))) !== null) {\n throw new Error(`workspace seed would overwrite an existing entry: ${name}`)\n }\n await cp(join(source, name), join(destination, name), {\n recursive: true,\n force: false,\n errorOnExist: true,\n verbatimSymlinks: true,\n })\n }\n return descriptor\n}\n\n/** Stream one regular file into its own digest, or `null` when it vanished mid-read. */\nasync function digestFile(\n path: string,\n): Promise<{ sha256: Sha256Digest; byteLength: number } | null> {\n let descriptor: Awaited<ReturnType<typeof open>>\n try {\n descriptor = await open(\n path,\n fsConstants.O_RDONLY |\n (typeof fsConstants.O_NOFOLLOW === 'number' ? fsConstants.O_NOFOLLOW : 0),\n )\n } catch (error) {\n if (isMissing(error)) return null\n throw error\n }\n try {\n const hash = createHash('sha256')\n const buffer = Buffer.allocUnsafe(1024 * 1024)\n let total = 0\n while (true) {\n const { bytesRead } = await descriptor.read(buffer, 0, buffer.byteLength, null)\n if (bytesRead === 0) break\n total += bytesRead\n hash.update(buffer.subarray(0, bytesRead))\n }\n // The length comes from the READ, never from `lstat`, so a file that grew between the two is\n // described by the bytes that reached the digest rather than refused for ordinary churn.\n return { sha256: `sha256:${hash.digest('hex')}` as Sha256Digest, byteLength: total }\n } finally {\n await descriptor.close()\n }\n}\n\n/** Git records exactly two file modes; a portable tree records the same two, plus 755 for a\n * directory and 777 for a link, which is what every filesystem reports for one. */\nfunction entryMode(\n mode: number | bigint,\n algorithm: WorkspaceTreeAlgorithm,\n isDirectory: boolean,\n isSymbolicLink: boolean,\n): string {\n const bits = Number(mode)\n if (algorithm !== 'portable-tree-v1') return String(bits & 0o777)\n if (isDirectory) return '755'\n if (isSymbolicLink) return '777'\n return (bits & 0o111) !== 0 ? '755' : '644'\n}\n\nfunction reasonText(reason: WorkspaceTreeExclusionReason): string {\n switch (reason) {\n case 'absolute-symlink':\n return 'is absolute'\n case 'symlink-escapes-tree':\n return 'escapes its tree'\n case 'symlink-resolves-outside-tree':\n return 'resolves outside its tree'\n default:\n return 'does not resolve'\n }\n}\n\nfunction treePath(root: string, path: string): string {\n return relative(root, path).split(sep).join('/') || '.'\n}\n\nfunction isWithin(root: string, path: string): boolean {\n return path === root || path.startsWith(`${root}${sep}`)\n}\n\nfunction isMissing(error: unknown): boolean {\n return (error as { code?: unknown } | null)?.code === 'ENOENT'\n}\n\nasync function lstatIfPresent(path: string): Promise<Awaited<ReturnType<typeof lstat>> | null> {\n try {\n return await lstat(path)\n } catch (error) {\n if (isMissing(error)) return null\n throw error\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["canonicalCandidateBytes","canonicalCandidateBytes","fsConstants"],"sources":["../../src/candidate-execution/builder.ts","../../src/candidate-execution/claim-file-store.ts","../../src/candidate-execution/dispose.ts","../../src/candidate-execution/protected-model-grant.ts","../../src/candidate-execution/recover.ts","../../src/candidate-execution/workspace-tree.ts"],"sourcesContent":["import type { CodeSurface } from '@tangle-network/agent-eval/campaign'\nimport { verifyCodeSurface } from '@tangle-network/agent-eval/campaign'\nimport type {\n AgentCandidateCodeDisabled,\n AgentCandidateCodeNoOp,\n AgentCandidateExecution,\n AgentCandidateGitHubRepository,\n AgentCandidateKnowledge,\n AgentCandidateMemoryPolicy,\n AgentCandidateProfile,\n AgentProfile,\n AgentProfileDiff,\n} from '@tangle-network/agent-interface'\nimport { type AgentCandidateBundleInput, sealAgentCandidateBundle } from './bundle'\nimport { embeddedCandidateArtifact } from './digest'\nimport {\n applyExactAgentProfileDiff,\n freezeGenericAgentCandidateProfile,\n parseExactAgentProfile,\n parseExactAgentProfileDiff,\n parseExactCandidateProfile,\n} from './profile'\n\n/** A complete profile that can be frozen without losing behavior. */\nexport type AgentCandidateProfileSource =\n | {\n kind: 'profile'\n profile: AgentProfile\n }\n | {\n kind: 'profile-diffs'\n base: AgentProfile\n /** Applied in order before the resulting profile is frozen into the bundle. */\n diffs: readonly AgentProfileDiff[]\n }\n | {\n kind: 'candidate-profile'\n /** Already converted to the closed, secret-free candidate profile contract. */\n profile: AgentCandidateProfile\n }\n\n/** The only accepted path from an agent-eval code candidate to executable bytes. */\nexport interface AgentCandidateCodeSurfaceSource {\n kind: 'code-surface'\n surface: CodeSurface\n repository: AgentCandidateGitHubRepository\n /** Optional parent directory used to resolve a relative `surface.worktreeRef`. */\n worktreeDir?: string\n}\n\n/** Explicit control/no-op code or one finalized CodeSurface whose bytes must still verify. */\nexport type AgentCandidateCodeSource =\n | AgentCandidateCodeDisabled\n | AgentCandidateCodeNoOp\n | AgentCandidateCodeSurfaceSource\n\n/** Complete measured surfaces and execution policy compiled into one candidate bundle. */\nexport interface BuildAgentCandidateBundleInput {\n profile: AgentCandidateProfileSource\n code: AgentCandidateCodeSource\n execution: AgentCandidateExecution\n knowledge?: AgentCandidateKnowledge\n memory: AgentCandidateMemoryPolicy\n}\n\n/**\n * Compile one measured profile/code candidate into the immutable execution\n * contract. Code bytes are re-read and verified by agent-eval before they are\n * embedded. The returned bundle is schema-validated, canonically digested, and\n * deeply immutable; call `verifyAgentCandidateBundle` at the execution boundary\n * to re-read external memory, repository, and workspace artifacts.\n */\nexport function buildAgentCandidateBundle(\n input: BuildAgentCandidateBundleInput,\n): ReturnType<typeof sealAgentCandidateBundle> {\n const bundle: AgentCandidateBundleInput = {\n kind: 'agent-candidate-bundle',\n digestAlgorithm: 'rfc8785-sha256',\n profile: compileCandidateProfile(input.profile),\n code: compileCandidateCode(input.code),\n execution: input.execution,\n ...(input.knowledge !== undefined ? { knowledge: input.knowledge } : {}),\n memory: input.memory,\n }\n return sealAgentCandidateBundle(bundle)\n}\n\nfunction compileCandidateProfile(source: AgentCandidateProfileSource): AgentCandidateProfile {\n if (source.kind === 'candidate-profile') {\n return parseExactCandidateProfile(source.profile)\n }\n\n if (source.kind === 'profile') {\n return freezeGenericAgentCandidateProfile(source.profile)\n }\n\n if (source.kind !== 'profile-diffs') {\n throw new Error(\n `unsupported candidate profile source: ${String((source as { kind?: unknown }).kind)}`,\n )\n }\n if (source.diffs.length === 0) {\n throw new Error('profile-diffs source requires at least one AgentProfileDiff')\n }\n let profile = parseExactAgentProfile(source.base, 'base profile')\n for (const [index, inputDiff] of source.diffs.entries()) {\n const diff = parseExactAgentProfileDiff(inputDiff, `profile diff ${index}`)\n profile = applyExactAgentProfileDiff(profile, diff, `profile diff ${index}`)\n }\n return freezeGenericAgentCandidateProfile(profile)\n}\n\nfunction compileCandidateCode(source: AgentCandidateCodeSource): AgentCandidateBundleInput['code'] {\n if (source.kind === 'disabled' || source.kind === 'no-op') return source\n if (source.kind !== 'code-surface') {\n throw new Error(\n `unsupported candidate code source: ${String((source as { kind?: unknown }).kind)}`,\n )\n }\n\n const verified = verifyCodeSurface(source.surface, source.worktreeDir)\n const patch = embeddedCandidateArtifact(verified.patchBytes)\n if (\n patch.sha256 !== source.surface.patch.sha256 ||\n patch.byteLength !== source.surface.patch.byteLength\n ) {\n throw new Error('verified CodeSurface patch bytes do not match its content identity')\n }\n return {\n kind: 'git-patch',\n repository: source.repository,\n baseCommit: source.surface.baseCommit,\n baseTree: source.surface.baseTree,\n candidateTree: source.surface.candidateTree,\n patch: { format: 'git-diff-binary', artifact: patch },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { linkSync } from 'node:fs'\nimport { mkdir, open, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Sha256Digest } from '@tangle-network/agent-interface'\n\nimport {\n type AgentCandidateExecutionAttemptRecord,\n type AgentCandidateExecutionAttemptRef,\n type AgentCandidateExecutionClaim,\n type AgentCandidateExecutionClaimResult,\n type AgentCandidateExecutionClaimStore,\n type AgentCandidateExecutionFinishResult,\n type AgentCandidateExecutionLease,\n type AgentCandidateExecutionPhase,\n type AgentCandidateExecutionPhaseResult,\n type AgentCandidateExecutionRecoveryEvidence,\n type AgentCandidateExecutionStageResult,\n type AgentCandidateExecutionTerminalRecord,\n type AgentCandidateExecutionTerminalResult,\n type AgentCandidateRetryRejection,\n candidateClaimFileInternals,\n} from './claim'\nimport {\n assertRecoveryMatchesStaged,\n assertTerminalAllowedInPhase,\n assertTerminalMatchesClaim,\n assertTerminalMatchesStaged,\n recoveredTerminalRecord,\n rejectedFinish,\n rejectedStage,\n requireStagedTerminal,\n sealTerminalDigest,\n terminalRecord,\n} from './claim-terminal'\nimport { canonicalCandidateBytes } from './digest'\n\nconst {\n assertExpiredLease,\n assertLease,\n assertSameSlot,\n assertUnexpiredLease,\n attemptRecord,\n claimSlot,\n leaseDigest,\n newLease,\n readClaim,\n readClaimIfPresent,\n readTerminal,\n readTerminalIfPresent,\n readTransitionIfPresent,\n rejectedExistingClaim,\n rejectedRetry,\n retryRejection,\n sealAttemptRef,\n sealClaim,\n sealLease,\n} = candidateClaimFileInternals\n\nexport interface FileAgentCandidateExecutionClaimStoreOptions {\n /** Evaluator-owned directory shared by every process allowed to execute candidates. */\n directory: string\n /** Testable evaluator clock; defaults to `Date.now`. */\n now?: () => number\n}\n\n/** Cross-process lifecycle implemented as fsynced, create-if-absent records. */\nexport class FileAgentCandidateExecutionClaimStore implements AgentCandidateExecutionClaimStore {\n private readonly directory: string\n private readonly now: () => number\n\n constructor(options: FileAgentCandidateExecutionClaimStoreOptions) {\n if (options.directory.length === 0) {\n throw new Error('candidate execution claim directory must not be empty')\n }\n this.directory = options.directory\n this.now = options.now ?? Date.now\n }\n\n async tryClaim(\n requested: AgentCandidateExecutionClaim,\n ): Promise<AgentCandidateExecutionClaimResult> {\n const claim = sealClaim(requested)\n await mkdir(this.directory, { recursive: true })\n const claimPath = this.claimPath(claim)\n const existing = await readClaimIfPresent(claimPath)\n if (existing) {\n assertSameSlot(existing.claim, claim, claimPath)\n return rejectedExistingClaim(existing.claim, claim)\n }\n assertUnexpiredLease(claim.leaseExpiresAtMs, this.now())\n const retryFailure = await this.retryFailure(claim)\n if (retryFailure) return rejectedRetry(claim, retryFailure)\n\n const lease = newLease(claim)\n const acquired = await writeRecordIfAbsent(this.directory, claimPath, {\n ...claim,\n phase: 'claimed',\n leaseDigest: leaseDigest(lease),\n })\n if (acquired) return Object.freeze({ acquired: true, claim, lease })\n\n const winner = await readClaim(claimPath)\n assertSameSlot(winner.claim, claim, claimPath)\n return rejectedExistingClaim(winner.claim, claim)\n }\n\n async getAttempt(\n requestedAttempt: AgentCandidateExecutionAttemptRef,\n ): Promise<AgentCandidateExecutionAttemptRecord | undefined> {\n return await this.storedAttempt(sealAttemptRef(requestedAttempt))\n }\n\n async markCandidateMayRun(\n requestedLease: AgentCandidateExecutionLease,\n ): Promise<AgentCandidateExecutionPhaseResult> {\n const lease = sealLease(requestedLease)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const state = await this.transitionState(stored.claim)\n if (state.phase === 'candidate-may-run') {\n return Object.freeze({ marked: false, phase: 'candidate-may-run' })\n }\n if (state.staged) {\n throw new Error('candidate execution terminal was staged before candidate-may-run phase')\n }\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const marked = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(stored.claim, 1),\n {\n kind: 'candidate-execution-phase',\n executionId: stored.claim.executionId,\n attempt: stored.claim.attempt,\n executionPlanDigest: stored.claim.executionPlanDigest,\n phase: 'candidate-may-run',\n },\n this.ownerPublication(stored.claim),\n )\n if (marked) return Object.freeze({ marked: true, phase: 'candidate-may-run' })\n const winner = await this.transitionState(stored.claim)\n if (winner.phase === 'candidate-may-run') {\n return Object.freeze({ marked: false, phase: 'candidate-may-run' })\n }\n throw new Error('candidate execution terminal was staged before candidate-may-run phase')\n }\n\n async stageTerminal(\n requestedLease: AgentCandidateExecutionLease,\n result: AgentCandidateExecutionTerminalResult,\n ): Promise<AgentCandidateExecutionStageResult> {\n const lease = sealLease(requestedLease)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const terminal = terminalRecord(stored.claim, result)\n const state = await this.transitionState(stored.claim)\n if (state.staged) return rejectedStage(state.staged, terminal)\n assertTerminalAllowedInPhase(state.phase, terminal)\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const transition = state.phase === 'claimed' ? 1 : 2\n const staged = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(stored.claim, transition),\n {\n kind: 'candidate-execution-pending-terminal',\n terminal,\n },\n this.ownerPublication(stored.claim),\n )\n if (staged) return Object.freeze({ staged: true, terminal })\n const winner = await this.transitionState(stored.claim)\n if (!winner.staged) {\n throw new Error('candidate execution phase transition won while staging terminal')\n }\n return rejectedStage(winner.staged, terminal)\n }\n\n async finish(\n requestedLease: AgentCandidateExecutionLease,\n requestedTerminalDigest: Sha256Digest,\n ): Promise<AgentCandidateExecutionFinishResult> {\n const lease = sealLease(requestedLease)\n const terminalDigest = sealTerminalDigest(requestedTerminalDigest)\n const claimPath = this.claimPath(lease)\n const stored = await readClaim(claimPath)\n assertSameSlot(stored.claim, lease, claimPath)\n assertLease(stored.leaseDigest, stored.claim.leaseExpiresAtMs, lease)\n const state = await this.transitionState(stored.claim)\n const staged = requireStagedTerminal(state.staged, terminalDigest)\n const terminalPath = this.terminalPath(lease)\n const existing = await readTerminalIfPresent(terminalPath)\n if (existing) {\n assertTerminalMatchesClaim(existing, stored.claim, terminalPath)\n assertTerminalMatchesStaged(existing, staged, terminalPath)\n return rejectedFinish(existing, terminalDigest)\n }\n assertUnexpiredLease(stored.claim.leaseExpiresAtMs, this.now())\n const finished = await writeRecordIfAbsent(\n this.directory,\n terminalPath,\n {\n terminal: staged,\n },\n this.ownerPublication(stored.claim),\n )\n if (finished) return Object.freeze({ finished: true, terminal: staged })\n const winner = await readTerminal(terminalPath)\n assertSameSlot(winner, lease, terminalPath)\n assertTerminalMatchesClaim(winner, stored.claim, terminalPath)\n assertTerminalMatchesStaged(winner, staged, terminalPath)\n return rejectedFinish(winner, terminalDigest)\n }\n\n async recoverExpired(\n requestedAttempt: AgentCandidateExecutionAttemptRef,\n evidence: AgentCandidateExecutionRecoveryEvidence,\n ): Promise<AgentCandidateExecutionFinishResult> {\n const attempt = sealAttemptRef(requestedAttempt)\n const record = await this.storedAttempt(attempt)\n if (!record) throw new Error('candidate execution recovery does not name an acquired attempt')\n const recovered = recoveredTerminalRecord(record.claim, record.phase, evidence)\n if (record.staged) assertRecoveryMatchesStaged(record.staged, recovered)\n const requestedDigest = record.staged?.terminalDigest ?? recovered.terminalDigest\n if (record.terminal) return rejectedFinish(record.terminal, requestedDigest)\n assertExpiredLease(record.claim.leaseExpiresAtMs, this.now())\n\n let staged = record.staged\n if (!staged) {\n const transition = record.phase === 'claimed' ? 1 : 2\n const didStage = await writeRecordIfAbsent(\n this.directory,\n this.transitionPath(record.claim, transition),\n {\n kind: 'candidate-execution-pending-terminal',\n terminal: recovered,\n },\n )\n if (didStage) {\n staged = recovered\n } else {\n const winner = await this.transitionState(record.claim)\n if (!winner.staged) {\n throw new Error(\n 'candidate execution recovery lost terminal staging to a phase transition',\n )\n }\n assertRecoveryMatchesStaged(winner.staged, recovered)\n staged = winner.staged\n }\n }\n\n const terminalPath = this.terminalPath(attempt)\n const didFinish = await writeRecordIfAbsent(this.directory, terminalPath, {\n terminal: staged,\n })\n if (didFinish) return Object.freeze({ finished: true, terminal: staged })\n const winner = await readTerminal(terminalPath)\n assertSameSlot(winner, attempt, terminalPath)\n assertTerminalMatchesClaim(winner, record.claim, terminalPath)\n assertTerminalMatchesStaged(winner, staged, terminalPath)\n return rejectedFinish(winner, staged.terminalDigest)\n }\n\n private async storedAttempt(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ): Promise<AgentCandidateExecutionAttemptRecord | undefined> {\n const claimPath = this.claimPath(claim)\n const stored = await readClaimIfPresent(claimPath)\n if (!stored) return undefined\n assertSameSlot(stored.claim, claim, claimPath)\n const terminalPath = this.terminalPath(claim)\n const terminal = await readTerminalIfPresent(terminalPath)\n // Terminal publication follows its immutable staged outbox, so read that prerequisite later.\n const state = await this.transitionState(stored.claim)\n if (terminal) {\n assertTerminalMatchesClaim(terminal, stored.claim, terminalPath)\n if (!state.staged) {\n throw new Error(\n `candidate execution terminal record at ${terminalPath} has no staged outbox`,\n )\n }\n assertTerminalMatchesStaged(terminal, state.staged, terminalPath)\n }\n return attemptRecord(stored.claim, state.phase, state.staged, terminal)\n }\n\n private async transitionState(claim: AgentCandidateExecutionClaim): Promise<{\n phase: AgentCandidateExecutionPhase\n staged?: AgentCandidateExecutionTerminalRecord\n }> {\n const firstPath = this.transitionPath(claim, 1)\n const first = await readTransitionIfPresent(firstPath, claim)\n if (!first) return { phase: 'claimed' }\n if (first.kind === 'pending') return { phase: 'claimed', staged: first.terminal }\n const secondPath = this.transitionPath(claim, 2)\n const second = await readTransitionIfPresent(secondPath, claim)\n if (!second) return { phase: 'candidate-may-run' }\n if (second.kind !== 'pending') {\n throw new Error(`candidate execution transition at ${secondPath} repeats the phase marker`)\n }\n return { phase: 'candidate-may-run', staged: second.terminal }\n }\n\n private async retryFailure(\n claim: AgentCandidateExecutionClaim,\n ): Promise<AgentCandidateRetryRejection | undefined> {\n if (claim.attempt === 1) return undefined\n return retryRejection(\n claim,\n await this.storedAttempt({\n executionId: claim.executionId,\n attempt: claim.attempt - 1,\n }),\n )\n }\n\n private ownerPublication(claim: AgentCandidateExecutionClaim): {\n authorizePublish: () => true\n } {\n return {\n authorizePublish: () => {\n assertUnexpiredLease(claim.leaseExpiresAtMs, this.now())\n return true\n },\n }\n }\n\n private claimPath(claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>): string {\n return join(this.directory, `${claimSlot(claim)}.claim.json`)\n }\n\n private terminalPath(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ): string {\n return join(this.directory, `${claimSlot(claim)}.terminal.json`)\n }\n\n private transitionPath(\n claim: Pick<AgentCandidateExecutionClaim, 'executionId' | 'attempt'>,\n ordinal: 1 | 2,\n ): string {\n return join(this.directory, `${claimSlot(claim)}.transition-${ordinal}.json`)\n }\n}\n\n/**\n * Candidate records keep this async writer because lease authorization must run after the\n * asynchronous temp-file fsync and immediately before synchronous link publication. The\n * supervisor durability helper is synchronous and has no lease hook, so combining them would\n * either move authorization earlier or add an async race to the claim boundary.\n */\nasync function writeRecordIfAbsent(\n directory: string,\n destination: string,\n record: object,\n options: {\n /** Synchronous authorization checked after temp fsync, immediately before atomic publication. */\n authorizePublish?: () => true\n } = {},\n): Promise<boolean> {\n const temporaryPath = join(directory, `.candidate-execution-${process.pid}-${randomUUID()}.tmp`)\n const handle = await open(temporaryPath, 'wx', 0o600)\n try {\n await handle.writeFile(\n Buffer.concat([Buffer.from(canonicalCandidateBytes(record)), Buffer.from('\\n')]),\n )\n await handle.sync()\n } finally {\n await handle.close()\n }\n\n let written = false\n try {\n if (options.authorizePublish && options.authorizePublish() !== true) {\n throw new Error('candidate execution record publication was not authorized')\n }\n // Authorization and the atomic filesystem call are one synchronous critical\n // section so the event loop cannot advance an injected lease clock between them.\n linkSync(temporaryPath, destination)\n written = true\n await syncDirectory(directory)\n } catch (error) {\n if (!isNodeError(error, 'EEXIST')) throw error\n } finally {\n await unlink(temporaryPath).catch((error: unknown) => {\n if (!isNodeError(error, 'ENOENT')) throw error\n })\n }\n return written\n}\n\nasync function syncDirectory(directory: string): Promise<void> {\n const handle = await open(directory, 'r')\n try {\n await handle.sync()\n } finally {\n await handle.close()\n }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n error !== null &&\n typeof error === 'object' &&\n 'code' in error &&\n (error as { code?: unknown }).code === code\n )\n}\n","import { candidateCleanupDeadline, withinCandidateCleanupDeadline } from './cleanup'\nimport { sealAgentCandidateModelSettlement } from './model-settlement'\nimport {\n assertPreparedCandidateIntegrity,\n beginPreparedCandidateDisposal,\n consumePreparedCandidateExecution,\n} from './prepared-state'\nimport type { PreparedAgentCandidateExecution } from './types'\n\nexport interface DisposePreparedAgentCandidateOptions {\n cleanupTimeoutMs?: number\n}\n\n/** Revoke reservations held by a prepared candidate that will not be executed. */\nexport async function disposePreparedAgentCandidateExecution(\n prepared: PreparedAgentCandidateExecution,\n options: DisposePreparedAgentCandidateOptions = {},\n): Promise<{ disposed: true }> {\n const initialState = assertPreparedCandidateIntegrity(prepared)\n const cleanupTimeoutMs = options.cleanupTimeoutMs ?? initialState.cleanupTimeoutMs\n if (cleanupTimeoutMs > initialState.cleanupTimeoutMs) {\n throw new Error('disposal cleanup timeout exceeds the frozen preparation bound')\n }\n const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs)\n const state = beginPreparedCandidateDisposal(prepared)\n const cleanup: Array<Promise<unknown>> = []\n\n if (state.memory.mode === 'isolated') {\n const reservation = state.memoryReservation\n if (!reservation) throw new Error('isolated memory reservation is missing')\n cleanup.push(\n withinCandidateCleanupDeadline(\n async () => {\n const closed = await state.ports.memory.close({\n executionId: state.executionId,\n preparationId: reservation.preparationId,\n accessDigest: reservation.accessDigest,\n effectiveNamespace: reservation.effectiveNamespace,\n reason: 'abandoned',\n })\n if (closed.closed !== true || Object.keys(closed).some((key) => key !== 'closed')) {\n throw new Error('abandoned isolated memory access did not acknowledge closure')\n }\n },\n cleanupDeadlineAtMs,\n 'isolated memory disposal',\n ),\n )\n }\n\n cleanup.push(\n withinCandidateCleanupDeadline(\n async () => {\n const settlement = sealAgentCandidateModelSettlement(\n await state.ports.models.settleGrant({\n executionId: state.executionId,\n preparationId: state.preparationId,\n grantDigest: state.modelReservation.digest,\n resolved: state.resolvedModel,\n reason: 'abandoned',\n }),\n {\n preparationId: state.preparationId,\n grantDigest: state.modelReservation.digest,\n model: state.resolvedModel.model,\n },\n )\n if (settlement.usage.modelCalls !== 0) {\n throw new Error('unexecuted model reservation unexpectedly contains calls')\n }\n },\n cleanupDeadlineAtMs,\n 'model reservation disposal',\n ),\n )\n\n const results = await Promise.allSettled(cleanup)\n const failures = results\n .filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n .map((result) => result.reason)\n if (failures.length > 0) {\n consumePreparedCandidateExecution(prepared, 'disposal-failed')\n throw new AggregateError(failures, 'candidate preparation disposal failed')\n }\n\n consumePreparedCandidateExecution(prepared, 'disposed')\n return Object.freeze({ disposed: true as const })\n}\n","import type { AgentCandidateResolvedModel } from '@tangle-network/agent-interface'\n\nimport type {\n AgentCandidateModelGrantActivateInput,\n AgentCandidateModelGrantReserveInput,\n AgentCandidateModelGrantSettleInput,\n} from './protected-model-port'\nimport type {\n AgentCandidateModelPort,\n AgentCandidateProtectedModelActivation,\n AgentCandidateProtectedModelReservation,\n AgentCandidateProtectedModelSettlement,\n} from './types'\n\n/** Reservation fields supplied by a caller before Runtime resolves the model. */\nexport type AgentCandidateModelGrantRunReservationInput = Omit<\n AgentCandidateModelGrantReserveInput,\n 'resolved'\n>\n\n/** Values available only while one protected model grant is active. */\nexport interface ProtectedAgentCandidateModelGrantContext {\n readonly activation: AgentCandidateProtectedModelActivation\n readonly reservation: AgentCandidateProtectedModelReservation\n readonly resolved: AgentCandidateResolvedModel\n}\n\n/** Inputs for one protected grant scoped to one bounded caller unit. */\nexport interface RunProtectedAgentCandidateModelGrantOptions<TResult> {\n /** Runtime port that validates and settles the evaluator-owned grant. */\n readonly port: AgentCandidateModelPort\n /** Provider-neutral model request resolved before any grant is reserved. */\n readonly resolve: Parameters<AgentCandidateModelPort['resolve']>[0]\n /** One bounded unit's immutable identity, attempt, expiry, and limits. */\n readonly reserve: AgentCandidateModelGrantRunReservationInput\n /** Must be no later than the reservation expiry. */\n readonly deadlineAtMs: AgentCandidateModelGrantActivateInput['deadlineAtMs']\n /** Execute exactly one bounded unit while the activated environment is valid. */\n readonly execute: (context: ProtectedAgentCandidateModelGrantContext) => Promise<TResult>\n}\n\n/** Result and sealed settlement returned after one protected grant closes. */\nexport interface RunProtectedAgentCandidateModelGrantResult<TResult> {\n readonly value: TResult\n readonly resolved: AgentCandidateResolvedModel\n readonly reservation: AgentCandidateProtectedModelReservation\n readonly settlement: AgentCandidateProtectedModelSettlement\n}\n\nconst SETTLEMENT_RETRY_INITIAL_DELAY_MS = 25\nconst SETTLEMENT_RETRY_MAX_DELAY_MS = 1_000\n\n/**\n * Run one bounded unit under a protected model grant.\n *\n * Runtime owns the grant lifecycle; callers own the unit boundary and any\n * durable scheduling or accounting around it. A reserved grant is settled\n * after activation failure or callback failure, and the callback error is\n * preserved when settlement also fails.\n */\nexport async function runProtectedAgentCandidateModelGrant<TResult>(\n options: RunProtectedAgentCandidateModelGrantOptions<TResult>,\n): Promise<RunProtectedAgentCandidateModelGrantResult<TResult>> {\n if (typeof options.execute !== 'function') {\n throw new TypeError('protected model grant execute callback is required')\n }\n\n const resolved = await options.port.resolve(options.resolve)\n const reservation = await options.port.reserveGrant({\n ...options.reserve,\n resolved,\n })\n\n let value!: TResult\n let executionError: unknown\n let executionFailed = false\n let activated = false\n let reason: AgentCandidateModelGrantSettleInput['reason'] = 'preparation-failed'\n\n try {\n const activation = await options.port.activateGrant({\n executionId: options.reserve.executionId,\n preparationId: options.reserve.preparationId,\n grantDigest: reservation.digest,\n resolved,\n deadlineAtMs: options.deadlineAtMs,\n })\n activated = true\n value = await options.execute({ activation, reservation, resolved })\n reason = 'completed'\n } catch (error) {\n executionError = error\n executionFailed = true\n if (activated) reason = 'failed'\n }\n\n let settlement: AgentCandidateProtectedModelSettlement\n try {\n settlement = await settleProtectedModelGrant(options, {\n executionId: options.reserve.executionId,\n preparationId: options.reserve.preparationId,\n grantDigest: reservation.digest,\n resolved,\n reason,\n })\n } catch (settlementError) {\n if (executionFailed) {\n throw new AggregateError(\n [executionError, settlementError],\n 'protected model execution failed and its grant did not settle',\n )\n }\n throw settlementError\n }\n\n if (executionFailed) throw executionError\n return { value, resolved, reservation, settlement }\n}\n\nasync function settleProtectedModelGrant<TResult>(\n options: RunProtectedAgentCandidateModelGrantOptions<TResult>,\n input: AgentCandidateModelGrantSettleInput,\n): Promise<AgentCandidateProtectedModelSettlement> {\n let delayMs = SETTLEMENT_RETRY_INITIAL_DELAY_MS\n for (;;) {\n try {\n return await options.port.settleGrant(input)\n } catch (error) {\n if (!isCandidateGrantDrainingError(error)) throw error\n const remainingMs = options.deadlineAtMs - Date.now()\n if (remainingMs <= 0) throw error\n await waitForSettlementRetry(Math.min(delayMs, remainingMs))\n if (Date.now() >= options.deadlineAtMs) throw error\n delayMs = Math.min(delayMs * 2, SETTLEMENT_RETRY_MAX_DELAY_MS)\n }\n }\n}\n\nfunction waitForSettlementRetry(delayMs: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, delayMs))\n}\n\n/** Only the gateway's explicit draining state is retryable; auth and ledger errors fail closed. */\nfunction isCandidateGrantDrainingError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false\n const candidate = error as { code?: unknown; message?: unknown }\n if (candidate.code === 'candidate_grant_draining') return true\n return (\n typeof candidate.message === 'string' && /\\bcandidate_grant_draining\\b/u.test(candidate.message)\n )\n}\n","import type { TraceStore } from '@tangle-network/agent-eval'\nimport type {\n AgentCandidateExecutionPlanMaterial,\n AgentCandidateMaterializationReceipt,\n} from '@tangle-network/agent-interface'\nimport {\n agentCandidateExecutionPlanMaterialSchema,\n agentCandidateMaterializationReceiptSchema,\n} from '@tangle-network/agent-interface'\n\nimport { readVerifiedArtifact } from './artifacts'\nimport type {\n AgentCandidateExecutionAttemptRef,\n AgentCandidateExecutionClaim,\n AgentCandidateExecutionClaimStore,\n AgentCandidateExecutionFinishResult,\n} from './claim'\nimport {\n candidateCleanupDeadline,\n candidateCleanupTimeout,\n withinCandidateCleanupDeadline,\n} from './cleanup'\nimport { canonicalCandidateBytes } from './digest'\nimport { sealAgentCandidateExecutorStopAcknowledgement } from './executor-capture'\nimport { sealAgentCandidateModelSettlement } from './model-settlement'\nimport { persistCandidateModelSettlementEvidence } from './outcome-evidence'\nimport { persistCandidateOutputArtifact } from './output-artifacts'\nimport { RecoveryAgentCandidateTraceStore } from './protected-trace-store'\nimport type {\n AgentCandidateExecutionPorts,\n AgentCandidateExecutorPort,\n AgentCandidateOutputArtifactPort,\n} from './types'\n\nexport interface RecoverExpiredAgentCandidateOptions {\n attempt: AgentCandidateExecutionAttemptRef\n claimStore: AgentCandidateExecutionClaimStore\n executor: AgentCandidateExecutorPort\n traceStore: TraceStore\n ports: Pick<AgentCandidateExecutionPorts, 'models' | 'memory'>\n outputArtifacts: AgentCandidateOutputArtifactPort\n cleanupTimeoutMs?: number\n /** Evaluator clock; must be the same clock used by the claim store. */\n now?: () => number\n}\n\n/** Close an expired crashed attempt from persisted non-secret handles, then record failure. */\nexport async function recoverExpiredAgentCandidateExecution(\n options: RecoverExpiredAgentCandidateOptions,\n): Promise<AgentCandidateExecutionFinishResult> {\n const record = await options.claimStore.getAttempt(options.attempt)\n if (!record) throw new Error('candidate execution recovery attempt is missing')\n if (record.terminal) {\n return Object.freeze({ finished: false, terminal: record.terminal, exactReplay: true })\n }\n const cleanupTimeoutMs = candidateCleanupTimeout(\n options.cleanupTimeoutMs ?? record.claim.cleanup.cleanupTimeoutMs,\n )\n if (cleanupTimeoutMs > record.claim.cleanup.cleanupTimeoutMs) {\n throw new Error('recovery cleanup timeout exceeds the frozen preparation bound')\n }\n\n const now = options.now ?? Date.now\n if (now() < record.claim.leaseExpiresAtMs) {\n throw new Error('candidate execution lease has not expired')\n }\n\n const cleanupDeadlineAtMs = candidateCleanupDeadline(cleanupTimeoutMs)\n const recoveryTraceStore = new RecoveryAgentCandidateTraceStore(options.traceStore)\n const preparation = withinCandidateCleanupDeadline(\n () => readRecoveryPreparation(record.claim, options.outputArtifacts),\n cleanupDeadlineAtMs,\n 'expired candidate preparation evidence read',\n )\n const processClosure = withinCandidateCleanupDeadline(\n async (cleanupSignal) => {\n const stopped = await options.executor.stop(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n {\n traceStore: recoveryTraceStore,\n reason: 'failed',\n signal: cleanupSignal,\n deadlineAtMs: cleanupDeadlineAtMs,\n },\n )\n sealAgentCandidateExecutorStopAcknowledgement(stopped)\n if (options.executor.dispose) {\n const disposed = await options.executor.dispose(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n { signal: cleanupSignal },\n )\n if (disposed.disposed !== true || Object.keys(disposed).some((key) => key !== 'disposed')) {\n throw new Error('expired candidate executor did not acknowledge resource disposal')\n }\n }\n return { stopped: true as const }\n },\n cleanupDeadlineAtMs,\n 'expired candidate process termination',\n )\n\n const modelClosure = withinCandidateCleanupDeadline(\n async () =>\n sealAgentCandidateModelSettlement(\n await options.ports.models.settleGrant({\n executionId: record.claim.executionId,\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n resolved: record.claim.cleanup.resolvedModel,\n reason: 'failed',\n }),\n {\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n model: record.claim.cleanup.resolvedModel.model,\n },\n ),\n cleanupDeadlineAtMs,\n 'expired candidate model settlement',\n )\n\n const memoryClosure = record.claim.cleanup.memory\n ? withinCandidateCleanupDeadline(\n async () => {\n const memory = record.claim.cleanup.memory\n if (!memory) throw new Error('expired candidate memory handle is missing')\n const closed = await options.ports.memory.close({\n executionId: record.claim.executionId,\n preparationId: record.claim.cleanup.preparationId,\n accessDigest: memory.accessDigest,\n effectiveNamespace: memory.effectiveNamespace,\n reason: 'failed',\n })\n if (closed.closed !== true || Object.keys(closed).some((key) => key !== 'closed')) {\n throw new Error('expired candidate memory did not acknowledge closure')\n }\n return { closed: true as const }\n },\n cleanupDeadlineAtMs,\n 'expired candidate memory closure',\n )\n : undefined\n\n const closureOutcomes = Promise.allSettled([\n modelClosure,\n memoryClosure ?? Promise.resolve(undefined),\n ] as const)\n const [preparationOutcome, processOutcome] = await Promise.allSettled([\n preparation,\n processClosure,\n ] as const)\n const failures: unknown[] = [preparationOutcome, processOutcome]\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason)\n const [modelOutcome, memoryOutcome] = await closureOutcomes\n for (const outcome of [modelOutcome, memoryOutcome]) {\n if (outcome.status === 'rejected') failures.push(outcome.reason)\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, 'expired candidate cleanup could not be proven')\n }\n\n if (modelOutcome.status !== 'fulfilled') {\n throw new Error('expired candidate model settlement was not recovered')\n }\n const model = modelOutcome.value\n const modelSettlement = await withinCandidateCleanupDeadline(\n () =>\n persistCandidateModelSettlementEvidence(\n {\n executionId: record.claim.executionId,\n executionPlanDigest: record.claim.executionPlanDigest,\n resolvedModel: record.claim.cleanup.resolvedModel,\n },\n model,\n options.outputArtifacts,\n ),\n cleanupDeadlineAtMs,\n 'expired candidate model-settlement persistence',\n )\n const failureClass =\n record.phase === 'claimed' && model.usage.modelCalls === 0\n ? 'pre-model-infrastructure'\n : 'unknown'\n const failureEvidence = await withinCandidateCleanupDeadline(\n () =>\n persistCandidateOutputArtifact(options.outputArtifacts, {\n executionId: record.claim.executionId,\n purpose: 'failure-evidence',\n bytes: canonicalCandidateBytes({\n kind: 'agent-candidate-recovery-failure',\n executionId: record.claim.executionId,\n attempt: record.claim.attempt,\n bundleDigest: record.claim.bundleDigest,\n executionPlanDigest: record.claim.executionPlanDigest,\n materializationReceiptDigest:\n record.claim.preparationEvidence.materializationReceipt.sha256,\n failureClass,\n processStopped: true,\n modelSettlementDigest: modelSettlement.digest,\n memoryClosed: record.claim.cleanup.memory !== undefined,\n }),\n }),\n cleanupDeadlineAtMs,\n 'expired candidate failure-evidence persistence',\n )\n const memory = record.claim.cleanup.memory\n return await options.claimStore.recoverExpired(options.attempt, {\n failureClass,\n usage: model.usage,\n modelSettlement: modelSettlement.artifact,\n failureEvidence,\n process: {\n stopped: true,\n executionPlanDigest: record.claim.executionPlanDigest,\n },\n model: {\n closed: true,\n preparationId: record.claim.cleanup.preparationId,\n grantDigest: record.claim.cleanup.modelGrantDigest,\n },\n ...(memory\n ? {\n memory: {\n closed: true,\n preparationId: record.claim.cleanup.preparationId,\n accessDigest: memory.accessDigest,\n effectiveNamespace: memory.effectiveNamespace,\n },\n }\n : {}),\n })\n}\n\nasync function readRecoveryPreparation(\n claim: AgentCandidateExecutionClaim,\n artifacts: AgentCandidateOutputArtifactPort,\n): Promise<{\n plan: AgentCandidateExecutionPlanMaterial\n receipt: AgentCandidateMaterializationReceipt\n}> {\n const [planBytes, receiptBytes] = await Promise.all([\n readVerifiedArtifact(claim.preparationEvidence.executionPlan, artifacts),\n readVerifiedArtifact(claim.preparationEvidence.materializationReceipt, artifacts),\n ])\n const plan = agentCandidateExecutionPlanMaterialSchema.parse(\n parseCanonicalBytes(planBytes, 'plan'),\n )\n if (claim.preparationEvidence.executionPlan.sha256 !== claim.executionPlanDigest) {\n throw new Error('recovery execution plan artifact does not match the claimed digest')\n }\n const receiptMaterial = parseCanonicalBytes(receiptBytes, 'materialization receipt')\n const receipt = agentCandidateMaterializationReceiptSchema.parse({\n ...receiptMaterial,\n digest: claim.preparationEvidence.materializationReceipt.sha256,\n })\n if (\n receipt.bundleDigest !== claim.bundleDigest ||\n receipt.executionPlan.digest !== claim.executionPlanDigest ||\n plan.runCell.bundleDigest !== claim.bundleDigest ||\n plan.executionId !== claim.executionId\n ) {\n throw new Error('recovery preparation evidence does not match the durable claim')\n }\n return { plan, receipt }\n}\n\nfunction parseCanonicalBytes(bytes: Uint8Array, label: string): Record<string, unknown> {\n let parsed: unknown\n try {\n parsed = JSON.parse(Buffer.from(bytes).toString('utf8'))\n } catch (error) {\n throw new Error(`candidate recovery ${label} is not JSON`, { cause: error })\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`candidate recovery ${label} must be an object`)\n }\n if (!Buffer.from(canonicalCandidateBytes(parsed)).equals(Buffer.from(bytes))) {\n throw new Error(`candidate recovery ${label} bytes are not canonical`)\n }\n return parsed as Record<string, unknown>\n}\n","/**\n * A content digest over a DIRECTORY TREE, and the per-file seed that fills one.\n *\n * The question this answers is \"is this workspace the same workspace\" — the question every launch\n * and every close of a branchable run has to answer, about a tree that a live process is still\n * writing to. That is a different question from the one\n * {@link scanMaterializedWorkspaceManifest} answers, and the difference decides the policies here:\n *\n * - A candidate manifest describes ONE EXACT regular-file workspace. It refuses a symbolic link\n * outright, because `AgentCandidateWorkspaceManifestMaterial` has no representation for one, and\n * it refuses an entry that disappears, because a signed manifest describes a settled tree.\n * - A tree descriptor describes what a RUN PRODUCED. A python venv writes\n * `bin/python -> /usr/bin/python3` as a matter of course, and a work directory can lose an entry\n * between two directory reads. Refusing on either aborts the close, and a run that never wrote\n * its digest can never be branched from.\n *\n * So the two policies are the caller's, one for links and one for vanishing entries, and both\n * default to `'refuse'` — the strict reading, correct for an INPUT seed, where a link that leaves\n * the tree means the seed describes bytes it does not contain. `'exclude'` is the reading a close\n * needs: the entry is never followed, it is recorded, and the exclusion itself is hashed, so two\n * trees that differ only in an excluded entry cannot share a digest.\n *\n * NOTHING is held in memory. A file reaches the tree digest as its own streamed sha-256 plus its\n * length, so the largest file in the tree does not decide whether the tree can be described:\n * `readFile` refuses anything above 2 GiB with `ERR_FS_FILE_TOO_LARGE`, and a single multi-gigabyte\n * artifact is exactly what a run leaves behind.\n *\n * @module\n * @experimental\n */\n\nimport { createHash } from 'node:crypto'\nimport { constants as fsConstants } from 'node:fs'\nimport { cp, lstat, open, readdir, readlink, realpath } from 'node:fs/promises'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\nimport type { Sha256Digest } from '@tangle-network/agent-interface'\n\n/**\n * `'tree-v1'` records a file's exact permission bits. `'portable-tree-v1'` records the two modes\n * Git stores — `755` when any execute bit is set, `644` otherwise, and `755` for a directory — so a\n * digest survives a checkout whose umask differs. Both stamp the algorithm into the digest, so one\n * tree cannot produce the same digest under both.\n */\nexport type WorkspaceTreeAlgorithm = 'tree-v1' | 'portable-tree-v1'\n\n/** What a walk does with an entry it refuses to describe: fail, or record and continue. */\nexport type WorkspaceTreeEntryPolicy = 'refuse' | 'exclude'\n\n/** Why one entry contributed its name instead of its content. */\nexport type WorkspaceTreeExclusionReason =\n | 'absolute-symlink'\n | 'symlink-escapes-tree'\n | 'symlink-resolves-outside-tree'\n | 'unresolved-symlink'\n | 'entry-disappeared'\n\n/** One entry the walk recorded but did not describe. Reported rather than dropped: a digest that\n * silently omitted an entry would be a different digest with no way to tell why. */\nexport interface WorkspaceTreeExclusion {\n /** Tree-relative path, `/`-separated. */\n readonly path: string\n readonly reason: WorkspaceTreeExclusionReason\n /** The link target exactly as it was written, for a symbolic-link exclusion. */\n readonly target?: string\n}\n\nexport interface WorkspaceTreeDescriptor {\n readonly algorithm: WorkspaceTreeAlgorithm\n readonly digest: Sha256Digest\n readonly files: number\n readonly directories: number\n /** Links kept INSIDE the tree. An excluded link is counted in `excluded`, never here. */\n readonly symlinks: number\n /** Total described regular-file bytes. */\n readonly bytes: number\n readonly excluded: ReadonlyArray<WorkspaceTreeExclusion>\n}\n\nexport interface DescribeWorkspaceTreeOptions {\n /** Default `'tree-v1'`. */\n readonly algorithm?: WorkspaceTreeAlgorithm\n /**\n * A symbolic link that is absolute, leaves the tree lexically, resolves outside it, or does not\n * resolve at all. `'refuse'` (default) is correct for an input seed. `'exclude'` is correct for a\n * close-time walk over a tree a run wrote. The link is NEVER followed in either policy: an\n * escaping link must not contribute bytes from outside the tree to a content address.\n */\n readonly onEscapingLink?: WorkspaceTreeEntryPolicy\n /**\n * An entry that vanished between the directory read that named it and the walk that reached it.\n * `'refuse'` (default) is correct for a settled tree; `'exclude'` is correct for a workspace a\n * live process still writes to.\n */\n readonly onMissingEntry?: WorkspaceTreeEntryPolicy\n}\n\nexport interface SeedWorkspaceTreeInput {\n /** The tree to copy FROM. Described, then copied entry by entry. */\n readonly source: string\n /** The tree to copy INTO. Must exist, and must not lie inside `source`. */\n readonly destination: string\n /** Default `'tree-v1'`; decides only the digest this returns, never the bytes it writes. */\n readonly algorithm?: WorkspaceTreeAlgorithm\n}\n\nconst TREE_ALGORITHMS: ReadonlySet<string> = new Set<WorkspaceTreeAlgorithm>([\n 'tree-v1',\n 'portable-tree-v1',\n])\n\nconst ENTRY_POLICIES: ReadonlySet<string> = new Set<WorkspaceTreeEntryPolicy>(['refuse', 'exclude'])\n\n/**\n * Describe one directory tree by content, streaming every file.\n *\n * The digest covers, for every entry in sorted order: its kind, its tree-relative path, its mode\n * under the selected algorithm, and then — for a file, its length and its own sha-256; for a kept\n * link, its target; for an excluded entry, the reason and the target. A file's content therefore\n * never enters the tree hash directly, which is what removes any in-memory size ceiling: the tree\n * hash consumes 32 bytes per file however large the file is.\n *\n * A hard-linked regular file is described like any other regular file. Its content is what the\n * digest is about, and a package manager that links a store into `node_modules` is ordinary\n * content, not a reason to refuse a workspace.\n */\nexport async function describeWorkspaceTree(\n directory: string,\n options: DescribeWorkspaceTreeOptions = {},\n): Promise<WorkspaceTreeDescriptor> {\n const algorithm = options.algorithm ?? 'tree-v1'\n const onEscapingLink = options.onEscapingLink ?? 'refuse'\n const onMissingEntry = options.onMissingEntry ?? 'refuse'\n if (!TREE_ALGORITHMS.has(algorithm)) {\n throw new Error(`unsupported workspace tree algorithm: ${algorithm}`)\n }\n for (const [name, policy] of [\n ['onEscapingLink', onEscapingLink],\n ['onMissingEntry', onMissingEntry],\n ] as const) {\n if (!ENTRY_POLICIES.has(policy)) {\n throw new Error(`unsupported workspace tree ${name} policy: ${policy}`)\n }\n }\n\n const root = resolve(directory)\n const rootStats = await lstatIfPresent(root)\n if (rootStats === null || !rootStats.isDirectory() || rootStats.isSymbolicLink()) {\n throw new Error(`workspace tree root must be a real directory: ${directory}`)\n }\n // Resolve the root once. Every physical containment test below compares against the RESOLVED\n // root, so a symlinked prefix — which is what macOS hands out for a temp directory — does not\n // make every entry look like it escapes.\n const physicalRoot = await realpath(root)\n\n const hash = createHash('sha256')\n // The algorithm is part of the digest. Without this, a tree whose modes already are 755/644\n // produces one digest under both algorithms, and two different questions share one answer.\n hash.update(`workspace-tree\\0${algorithm}\\0`)\n const counts = { files: 0, directories: 0, symlinks: 0, bytes: 0 }\n const excluded: WorkspaceTreeExclusion[] = []\n\n const exclude = (path: string, reason: WorkspaceTreeExclusionReason, target?: string): void => {\n const name = treePath(root, path)\n excluded.push(\n Object.freeze(target === undefined ? { path: name, reason } : { path: name, reason, target }),\n )\n // The reason is hashed with the entry. Two trees that differ only in WHY an entry was excluded\n // are different trees, and a refusal must not become a way to hide a difference.\n hash.update(`excluded\\0${name}\\0${reason}\\0${target ?? ''}\\0`)\n }\n\n /** True when the caller asked to continue past a vanished entry, and it was not the root. */\n const recordMissing = (path: string): boolean => {\n if (onMissingEntry === 'refuse' || path === root) return false\n exclude(path, 'entry-disappeared')\n return true\n }\n\n const visit = async (path: string): Promise<void> => {\n const info = await lstatIfPresent(path)\n if (info === null) {\n if (recordMissing(path)) return\n throw new Error(`workspace tree entry disappeared during the walk: ${treePath(root, path)}`)\n }\n const name = treePath(root, path)\n const mode = entryMode(info.mode, algorithm, info.isDirectory(), info.isSymbolicLink())\n\n if (info.isDirectory()) {\n let entries: string[]\n try {\n entries = await readdir(path)\n } catch (error) {\n if (isMissing(error) && recordMissing(path)) return\n throw error\n }\n counts.directories += 1\n hash.update(`directory\\0${name}\\0${mode}\\0`)\n for (const entry of entries.sort()) await visit(join(path, entry))\n return\n }\n\n if (info.isSymbolicLink()) {\n await visitSymbolicLink(path, name, mode)\n return\n }\n\n if (!info.isFile()) {\n throw new Error(`workspace tree contains an unsupported entry: ${name}`)\n }\n const read = await digestFile(path)\n if (read === null) {\n if (recordMissing(path)) return\n throw new Error(`workspace tree entry disappeared during the walk: ${name}`)\n }\n counts.files += 1\n counts.bytes += read.byteLength\n hash.update(`file\\0${name}\\0${mode}\\0${read.byteLength}\\0${read.sha256}\\0`)\n }\n\n const visitSymbolicLink = async (path: string, name: string, mode: string): Promise<void> => {\n let target: string\n try {\n target = await readlink(path)\n } catch (error) {\n if (isMissing(error) && recordMissing(path)) return\n throw error\n }\n const refuse = (reason: WorkspaceTreeExclusionReason): void => {\n if (onEscapingLink === 'refuse') {\n throw new Error(\n `workspace tree contains a link that ${reasonText(reason)}: ${name} -> ${target}`,\n )\n }\n exclude(path, reason, target)\n }\n if (isAbsolute(target)) return refuse('absolute-symlink')\n if (!isWithin(root, resolve(dirname(path), target))) return refuse('symlink-escapes-tree')\n let physicalTarget: string\n try {\n physicalTarget = await realpath(path)\n } catch {\n // A dangling link is a fact about the tree, not a reason to make the run unrecoverable.\n return refuse('unresolved-symlink')\n }\n if (!isWithin(physicalRoot, physicalTarget)) return refuse('symlink-resolves-outside-tree')\n counts.symlinks += 1\n hash.update(`symlink\\0${name}\\0${mode}\\0${target}\\0`)\n }\n\n await visit(root)\n return Object.freeze({\n algorithm,\n digest: `sha256:${hash.digest('hex')}` as Sha256Digest,\n files: counts.files,\n directories: counts.directories,\n symlinks: counts.symlinks,\n bytes: counts.bytes,\n excluded: Object.freeze(excluded),\n })\n}\n\n/**\n * Seed a workspace from a directory, one entry at a time, and return the digest of what was\n * seeded.\n *\n * Nothing is packed: `cp` walks and copies file by file, so a multi-gigabyte seed costs one file\n * handle rather than one archive in memory. Existing destination entries are never overwritten —\n * a seed that could replace a file the workspace already holds would make the resulting tree\n * depend on the order two seeds ran in.\n *\n * Links are copied verbatim, exactly as they were written. Following them would copy bytes from\n * outside the seed into the workspace, which is the same rule {@link describeWorkspaceTree}\n * applies to the digest.\n */\nexport async function seedWorkspaceTree(\n input: SeedWorkspaceTreeInput,\n): Promise<WorkspaceTreeDescriptor> {\n const source = resolve(input.source)\n const destination = resolve(input.destination)\n if (source === destination || isWithin(source, destination)) {\n throw new Error('workspace seed must not contain its destination')\n }\n const destinationStats = await lstatIfPresent(destination)\n if (destinationStats === null || !destinationStats.isDirectory()) {\n throw new Error(\n `workspace seed destination must be an existing directory: ${input.destination}`,\n )\n }\n // Described BEFORE anything is copied, so a seed this refuses leaves the destination untouched.\n const descriptor = await describeWorkspaceTree(source, {\n ...(input.algorithm === undefined ? {} : { algorithm: input.algorithm }),\n })\n for (const name of (await readdir(source)).sort()) {\n if ((await lstatIfPresent(join(destination, name))) !== null) {\n throw new Error(`workspace seed would overwrite an existing entry: ${name}`)\n }\n await cp(join(source, name), join(destination, name), {\n recursive: true,\n force: false,\n errorOnExist: true,\n verbatimSymlinks: true,\n })\n }\n return descriptor\n}\n\n/** Stream one regular file into its own digest, or `null` when it vanished mid-read. */\nasync function digestFile(\n path: string,\n): Promise<{ sha256: Sha256Digest; byteLength: number } | null> {\n let descriptor: Awaited<ReturnType<typeof open>>\n try {\n descriptor = await open(\n path,\n fsConstants.O_RDONLY |\n (typeof fsConstants.O_NOFOLLOW === 'number' ? fsConstants.O_NOFOLLOW : 0),\n )\n } catch (error) {\n if (isMissing(error)) return null\n throw error\n }\n try {\n const hash = createHash('sha256')\n const buffer = Buffer.allocUnsafe(1024 * 1024)\n let total = 0\n while (true) {\n const { bytesRead } = await descriptor.read(buffer, 0, buffer.byteLength, null)\n if (bytesRead === 0) break\n total += bytesRead\n hash.update(buffer.subarray(0, bytesRead))\n }\n // The length comes from the READ, never from `lstat`, so a file that grew between the two is\n // described by the bytes that reached the digest rather than refused for ordinary churn.\n return { sha256: `sha256:${hash.digest('hex')}` as Sha256Digest, byteLength: total }\n } finally {\n await descriptor.close()\n }\n}\n\n/** Git records exactly two file modes; a portable tree records the same two, plus 755 for a\n * directory and 777 for a link, which is what every filesystem reports for one. */\nfunction entryMode(\n mode: number | bigint,\n algorithm: WorkspaceTreeAlgorithm,\n isDirectory: boolean,\n isSymbolicLink: boolean,\n): string {\n const bits = Number(mode)\n if (algorithm !== 'portable-tree-v1') return String(bits & 0o777)\n if (isDirectory) return '755'\n if (isSymbolicLink) return '777'\n return (bits & 0o111) !== 0 ? '755' : '644'\n}\n\nfunction reasonText(reason: WorkspaceTreeExclusionReason): string {\n switch (reason) {\n case 'absolute-symlink':\n return 'is absolute'\n case 'symlink-escapes-tree':\n return 'escapes its tree'\n case 'symlink-resolves-outside-tree':\n return 'resolves outside its tree'\n default:\n return 'does not resolve'\n }\n}\n\nfunction treePath(root: string, path: string): string {\n return relative(root, path).split(sep).join('/') || '.'\n}\n\nfunction isWithin(root: string, path: string): boolean {\n return path === root || path.startsWith(`${root}${sep}`)\n}\n\nfunction isMissing(error: unknown): boolean {\n return (error as { code?: unknown } | null)?.code === 'ENOENT'\n}\n\nasync function lstatIfPresent(path: string): Promise<Awaited<ReturnType<typeof lstat>> | null> {\n try {\n return await lstat(path)\n } catch (error) {\n if (isMissing(error)) return null\n throw error\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { At as workerTraceAnalysisStore, Ii as chargedTokens, Mt as assertValidBudget, Qi as withBudgetResources, Qr as writeAllBytes, Qt as createPeerMailbox, R as scopeRetainedOwnerResourceReader, U as resolveSpawnResourcePaths, Vi as promptCacheTokenClasses, Xi as addResourceSpend, Xr as prepareJsonlAppend, Yn as resolveRedactor, Zr as readCommittedJsonLines, _t as FileResultBlobStore, a as pickBestDelivered, bt as InMemorySpawnJournal, dt as createExecutorRegistry, g as withDriverExecutor, kt as parseWorkerToolTraceArtifact, nn as isLiveNodeStatus, o as runFinalizer, qi as unmeteredSpend, qt as createInbox, r as bestDelivered, rn as isTerminalNodeStatus, rt as freeSlots, s as runTree, si as providerAttemptEvidence, tt as errMessage, vt as FileSpawnJournal, wn as runBrainLoop, x as meterRuntimeOwnedProviderAttempt, yi as detachedFrozen, yt as InMemoryResultBlobStore } from "./supervisor-De0lytFU.js";
1
+ import { $i as withBudgetResources, $r as writeAllBytes, At as workerTraceAnalysisStore, Hi as promptCacheTokenClasses, Ji as unmeteredSpend, Li as chargedTokens, Mt as assertValidBudget, Qr as readCommittedJsonLines, Qt as createPeerMailbox, R as scopeRetainedOwnerResourceReader, U as resolveSpawnResourcePaths, Yn as resolveRedactor, Zi as addResourceSpend, Zr as prepareJsonlAppend, _t as FileResultBlobStore, a as pickBestDelivered, bi as detachedFrozen, bt as InMemorySpawnJournal, ci as providerAttemptEvidence, dt as createExecutorRegistry, g as withDriverExecutor, kt as parseWorkerToolTraceArtifact, nn as isLiveNodeStatus, o as runFinalizer, qt as createInbox, r as bestDelivered, rn as isTerminalNodeStatus, rt as freeSlots, s as runTree, tt as errMessage, vt as FileSpawnJournal, wn as runBrainLoop, x as meterRuntimeOwnedProviderAttempt, yt as InMemoryResultBlobStore } from "./supervisor-tGq-TPIv.js";
2
2
  import { f as RuntimeRunStateError, m as ValidationError } from "./errors-DodWX-cb.js";
3
- import { A as writeWorkerCancellation, M as writeWorkerSteerAcknowledgement, b as workerCancellationsDir, c as readWorkerCancelRequests, d as readWorkerSteerRequests, k as writeRunCancellation, l as readWorkerCancellation, o as readRunCancelRequest, r as claimWorkerSteerDelivery, s as readRunCancellation, u as readWorkerSteerAcknowledgement } from "./run-layout-hZREkcfu.js";
3
+ import { A as writeWorkerCancellation, M as writeWorkerSteerAcknowledgement, b as workerCancellationsDir, c as readWorkerCancelRequests, d as readWorkerSteerRequests, k as writeRunCancellation, l as readWorkerCancellation, o as readRunCancelRequest, r as claimWorkerSteerDelivery, s as readRunCancellation, u as readWorkerSteerAcknowledgement } from "./run-layout-B8-Gqhpg.js";
4
4
  import { agentProfileSchema, canonicalCandidateDigest } from "@tangle-network/agent-interface";
5
5
  import { argHash, errorStreakDetector, observeAll, repeatedActionDetector } from "@tangle-network/agent-eval";
6
6
  import { randomUUID } from "node:crypto";
@@ -654,6 +654,10 @@ function spawnRefusalReason(reason, shortfalls, pinned) {
654
654
  }
655
655
  /** Build the driver's MCP tools over a live scope. */
656
656
  function createCoordinationTools(opts) {
657
+ return createCoordinationToolsForManager(opts);
658
+ }
659
+ /** Internal manager binding; its lifetime fences delivery without cancelling the worker scope. */
660
+ function createCoordinationToolsForManager(opts, lifetime) {
657
661
  const deliverable = opts.deliverable;
658
662
  const priorSubmission = deliverable === void 0 ? void 0 : opts.priorJournal?.find((record) => record.event.type === "submission");
659
663
  let stopped = priorSubmission !== void 0;
@@ -1177,8 +1181,11 @@ function createCoordinationTools(opts) {
1177
1181
  let outcome;
1178
1182
  let error;
1179
1183
  try {
1180
- delivered = opts.scope.send(instruction.toWorker, message);
1181
- outcome = deliveryOutcome(instruction.toWorker, delivered);
1184
+ if (lifetime?.aborted) outcome = "scope-stopped";
1185
+ else {
1186
+ delivered = opts.scope.send(instruction.toWorker, message);
1187
+ outcome = deliveryOutcome(instruction.toWorker, delivered);
1188
+ }
1182
1189
  } catch (cause) {
1183
1190
  outcome = "runtime-error";
1184
1191
  error = cause instanceof Error ? cause.message : String(cause);
@@ -1832,7 +1839,7 @@ function createCoordinationTools(opts) {
1832
1839
  },
1833
1840
  {
1834
1841
  name: "observe_agent",
1835
- description: "Inspect a worker WHILE IT RUNS, not only after it finishes: status, spend so far, and `progress` — how long since it last did anything (`idleMs`), whether that counts as stalled, how many turns it has taken, the last tools/files it touched (`recentActivity`), what its executor CHANGED about the profile you gave it (`derived` — an MCP config it materialized, an extension it had to add), whether a steer can even reach it (`steerable`), and how many steers it has not yet read (`pendingMessages`). Returns the settled output artifact once it exists. Use this BEFORE steer_agent: a steer is only worth sending when the progress says the worker is on the wrong path or has stopped making any.",
1842
+ description: "Inspect a worker WHILE IT RUNS, not only after it finishes: status, spend so far, and `progress` — how long since it last did anything (`idleMs`), whether that counts as stalled, how many turns it has taken, the last tools/files it touched (`recentActivity`), what its executor CHANGED about the profile you gave it (`derived` — an MCP config it materialized, an extension it had to add), whether a steer can even reach it (`steerable`), and how many steers it has not yet read (`pendingMessages`). A worker whose executor has FINISHED but whose settlement you have not yet drained reports `settlementPending` with its terminal kind; its `status` still reads running until await_event delivers it, so call await_event, not observe_agent again. The settled output artifact is returned once drained. Use this BEFORE steer_agent: a steer is only worth sending when the progress says the worker is on the wrong path or has stopped making any.",
1836
1843
  inputSchema: {
1837
1844
  type: "object",
1838
1845
  properties: { workerId: idArg },
@@ -1857,11 +1864,16 @@ function createCoordinationTools(opts) {
1857
1864
  }
1858
1865
  const output = node.outRef ? await opts.blobs.get(node.outRef) : void 0;
1859
1866
  const progress = readProgress(id);
1867
+ const pending = node.settlementPending;
1860
1868
  return {
1861
1869
  ...projectNodeEvidence(node),
1862
1870
  outRef: node.outRef ?? null,
1863
1871
  output: output ?? null,
1864
- progress: progress ?? null
1872
+ progress: progress ?? null,
1873
+ ...pending ? {
1874
+ settlementPending: pending,
1875
+ hint: `this worker has finished (${pending.kind}); its settlement is queued — call await_event to receive it, observing again will not change this`
1876
+ } : {}
1865
1877
  };
1866
1878
  }
1867
1879
  },
@@ -3169,7 +3181,7 @@ function validateDriverPromptCache(promptCache) {
3169
3181
  * lead journal their terminal records there before the lead settles into this scope. */
3170
3182
  const SPAWN_JOURNAL_FILE = "spawn-journal.jsonl";
3171
3183
  /**
3172
- * Apply externally admitted steers once from the owning manager's turn loop.
3184
+ * Apply externally admitted steers once through the owning manager's control path.
3173
3185
  *
3174
3186
  * The `unknown` acknowledgement lands before authorization or delivery. A crash after that write
3175
3187
  * can lose this steer, but a restarted manager never delivers it again. This is the same
@@ -3188,6 +3200,7 @@ function createSteerAcknowledger(deps) {
3188
3200
  });
3189
3201
  return { async pass(phase) {
3190
3202
  for (const request of readWorkerSteerRequests(deps.dir)) {
3203
+ if (phase === "turn" && deps.signal?.aborted) return;
3191
3204
  if (!directChildId(request.worker)) continue;
3192
3205
  if (readWorkerSteerAcknowledgement(deps.dir, request.operationId) !== void 0) continue;
3193
3206
  if (phase === "final") {
@@ -3246,8 +3259,8 @@ function steerAcknowledgementDetail(outcome) {
3246
3259
  }
3247
3260
  /**
3248
3261
  * The worker-cancel ACKNOWLEDGER — the runtime-side half of `run-layout`'s `cancelWorker`
3249
- * contract, run from the coordination driver's turn loop (one cancellation-inbox read per turn,
3250
- * no new process, no poller, no extra lifetime). Every manager with a `controlDir` mounts one;
3262
+ * contract. Router managers check between turns; native managers observe throughout their invocation.
3263
+ * Every manager with a `controlDir` mounts one;
3251
3264
  * OWNERSHIP keeps them from colliding: a request naming a node id is owned by the manager whose
3252
3265
  * own id is that node's parent, and a label/profile-name reference is owned by the `'run'`-scoped
3253
3266
  * (root) manager only — so exactly one acknowledger can ever apply one operation.
@@ -3397,7 +3410,7 @@ function createCancelAcknowledger(deps) {
3397
3410
  if (record !== void 0) tracked.set(request.operationId, record);
3398
3411
  }
3399
3412
  if (record === void 0) {
3400
- apply(request);
3413
+ if (phase === "turn") apply(request);
3401
3414
  continue;
3402
3415
  }
3403
3416
  if (record.effect === "cancel_requested") reconcile(record);
@@ -3861,6 +3874,6 @@ function safeJson(v) {
3861
3874
  }
3862
3875
  }
3863
3876
  //#endregion
3864
- export { normalizeAnalyzeOnSettle as A, ANALYST_DEFINITION_BOUNDS as C, coordinationVerbNames as D, canonicalFindingEvent as E, watchTrace as F, questionEscalationTargets as M, createEventBus as N, createCoordinationTools as O, defaultToolDetectors as P, watchRunCancellation as S, analystToolGroupNames as T, renderAnytimeTable as _, allOf as a, FileCoordinationLog as b, createProgressTracker as c, progressStop as d, sampleFromSettled as f, plateauLength as g, bestSoFar as h, finalizeBestDelivered as i, parseAuthoredAnalystDefinition as j, downMessageRefusalReasons as k, noProgressFor as l, areaUnderCurve as m, createSteerAcknowledger as n, allWorkersStalled as o, anytimeReport as p, driverAgent as r, anyOf as s, createCancelAcknowledger as t, plateau as u, createFileRunContext as v, DEFAULT_AWAIT_EVENT_TIMEOUT_MS as w, applyRunCancellation as x, createInMemoryRunContext as y };
3877
+ export { downMessageRefusalReasons as A, ANALYST_DEFINITION_BOUNDS as C, coordinationVerbNames as D, canonicalFindingEvent as E, defaultToolDetectors as F, watchTrace as I, parseAuthoredAnalystDefinition as M, questionEscalationTargets as N, createCoordinationTools as O, createEventBus as P, watchRunCancellation as S, analystToolGroupNames as T, renderAnytimeTable as _, allOf as a, FileCoordinationLog as b, createProgressTracker as c, progressStop as d, sampleFromSettled as f, plateauLength as g, bestSoFar as h, finalizeBestDelivered as i, normalizeAnalyzeOnSettle as j, createCoordinationToolsForManager as k, noProgressFor as l, areaUnderCurve as m, createSteerAcknowledger as n, allWorkersStalled as o, anytimeReport as p, driverAgent as r, anyOf as s, createCancelAcknowledger as t, plateau as u, createFileRunContext as v, DEFAULT_AWAIT_EVENT_TIMEOUT_MS as w, applyRunCancellation as x, createInMemoryRunContext as y };
3865
3878
 
3866
- //# sourceMappingURL=coordination-driver-m-2dzvu6.js.map
3879
+ //# sourceMappingURL=coordination-driver-De8pyM57.js.map