@caupulican/pi-adaptative 0.86.2 → 0.86.5

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 (226) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/core/agent-paths.d.ts +13 -0
  3. package/dist/core/agent-paths.d.ts.map +1 -1
  4. package/dist/core/agent-paths.js +23 -0
  5. package/dist/core/agent-paths.js.map +1 -1
  6. package/dist/core/autonomy/bounded-completion.d.ts +7 -0
  7. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  8. package/dist/core/autonomy/bounded-completion.js +12 -4
  9. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  10. package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
  11. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  12. package/dist/core/autonomy/lane-tool-surface.js +6 -3
  13. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  14. package/dist/core/autonomy/subagent-prompt.js +1 -1
  15. package/dist/core/autonomy/subagent-prompt.js.map +1 -1
  16. package/dist/core/background-lane-controller.d.ts +25 -2
  17. package/dist/core/background-lane-controller.d.ts.map +1 -1
  18. package/dist/core/background-lane-controller.js +67 -0
  19. package/dist/core/background-lane-controller.js.map +1 -1
  20. package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts +4 -0
  21. package/dist/core/delegation/replay-safe-mailbox-bounds.d.ts.map +1 -0
  22. package/dist/core/delegation/replay-safe-mailbox-bounds.js +20 -0
  23. package/dist/core/delegation/replay-safe-mailbox-bounds.js.map +1 -0
  24. package/dist/core/delegation/sanitized-context-fork.d.ts +25 -0
  25. package/dist/core/delegation/sanitized-context-fork.d.ts.map +1 -0
  26. package/dist/core/delegation/sanitized-context-fork.js +299 -0
  27. package/dist/core/delegation/sanitized-context-fork.js.map +1 -0
  28. package/dist/core/delegation/session-root-mailbox.d.ts +75 -0
  29. package/dist/core/delegation/session-root-mailbox.d.ts.map +1 -0
  30. package/dist/core/delegation/session-root-mailbox.js +627 -0
  31. package/dist/core/delegation/session-root-mailbox.js.map +1 -0
  32. package/dist/core/delegation/worker-agent-control-coordinator.d.ts +102 -9
  33. package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
  34. package/dist/core/delegation/worker-agent-control-coordinator.js +1307 -125
  35. package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
  36. package/dist/core/delegation/worker-agent-control.d.ts +183 -8
  37. package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
  38. package/dist/core/delegation/worker-agent-control.js +778 -48
  39. package/dist/core/delegation/worker-agent-control.js.map +1 -1
  40. package/dist/core/delegation/worker-attempt-executor.d.ts +9 -0
  41. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  42. package/dist/core/delegation/worker-attempt-executor.js +479 -214
  43. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  44. package/dist/core/delegation/worker-authority-resolver.d.ts +9 -0
  45. package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
  46. package/dist/core/delegation/worker-authority-resolver.js +22 -14
  47. package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
  48. package/dist/core/delegation/worker-context-fork-store.d.ts +71 -0
  49. package/dist/core/delegation/worker-context-fork-store.d.ts.map +1 -0
  50. package/dist/core/delegation/worker-context-fork-store.js +437 -0
  51. package/dist/core/delegation/worker-context-fork-store.js.map +1 -0
  52. package/dist/core/delegation/worker-context-inheritance-policy.d.ts +18 -0
  53. package/dist/core/delegation/worker-context-inheritance-policy.d.ts.map +1 -0
  54. package/dist/core/delegation/worker-context-inheritance-policy.js +28 -0
  55. package/dist/core/delegation/worker-context-inheritance-policy.js.map +1 -0
  56. package/dist/core/delegation/worker-conversation-revision.d.ts +31 -0
  57. package/dist/core/delegation/worker-conversation-revision.d.ts.map +1 -0
  58. package/dist/core/delegation/worker-conversation-revision.js +203 -0
  59. package/dist/core/delegation/worker-conversation-revision.js.map +1 -0
  60. package/dist/core/delegation/worker-conversation-store.d.ts +130 -18
  61. package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
  62. package/dist/core/delegation/worker-conversation-store.js +1263 -79
  63. package/dist/core/delegation/worker-conversation-store.js.map +1 -1
  64. package/dist/core/delegation/worker-delegation-controller.d.ts +29 -2
  65. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  66. package/dist/core/delegation/worker-delegation-controller.js +625 -111
  67. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  68. package/dist/core/delegation/worker-delegation-request.d.ts +2 -0
  69. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
  70. package/dist/core/delegation/worker-delegation-request.js.map +1 -1
  71. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +20 -1
  72. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
  73. package/dist/core/delegation/worker-dispatch-scheduler.js +210 -37
  74. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
  75. package/dist/core/delegation/worker-fleet-limits.d.ts +38 -0
  76. package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -0
  77. package/dist/core/delegation/worker-fleet-limits.js +113 -0
  78. package/dist/core/delegation/worker-fleet-limits.js.map +1 -0
  79. package/dist/core/delegation/worker-lane-projection.d.ts +1 -0
  80. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
  81. package/dist/core/delegation/worker-lane-projection.js +6 -2
  82. package/dist/core/delegation/worker-lane-projection.js.map +1 -1
  83. package/dist/core/delegation/worker-lifecycle.d.ts +20 -3
  84. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
  85. package/dist/core/delegation/worker-lifecycle.js +42 -18
  86. package/dist/core/delegation/worker-lifecycle.js.map +1 -1
  87. package/dist/core/delegation/worker-notification-coordinator.d.ts +4 -0
  88. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
  89. package/dist/core/delegation/worker-notification-coordinator.js +45 -4
  90. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
  91. package/dist/core/delegation/worker-provider-turn-protocol.d.ts +50 -0
  92. package/dist/core/delegation/worker-provider-turn-protocol.d.ts.map +1 -0
  93. package/dist/core/delegation/worker-provider-turn-protocol.js +185 -0
  94. package/dist/core/delegation/worker-provider-turn-protocol.js.map +1 -0
  95. package/dist/core/delegation/worker-recovery-coordinator.d.ts +45 -4
  96. package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
  97. package/dist/core/delegation/worker-recovery-coordinator.js +223 -17
  98. package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
  99. package/dist/core/delegation/worker-retry-policy.d.ts +36 -0
  100. package/dist/core/delegation/worker-retry-policy.d.ts.map +1 -0
  101. package/dist/core/delegation/worker-retry-policy.js +41 -0
  102. package/dist/core/delegation/worker-retry-policy.js.map +1 -0
  103. package/dist/core/delegation/worker-runner.d.ts +3 -1
  104. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  105. package/dist/core/delegation/worker-runner.js +4 -2
  106. package/dist/core/delegation/worker-runner.js.map +1 -1
  107. package/dist/core/delegation/worker-task-view.d.ts +43 -0
  108. package/dist/core/delegation/worker-task-view.d.ts.map +1 -0
  109. package/dist/core/delegation/worker-task-view.js +194 -0
  110. package/dist/core/delegation/worker-task-view.js.map +1 -0
  111. package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts +55 -0
  112. package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts.map +1 -0
  113. package/dist/core/delegation/worker-terminal-handoff-coordinator.js +179 -0
  114. package/dist/core/delegation/worker-terminal-handoff-coordinator.js.map +1 -0
  115. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +2 -2
  116. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
  117. package/dist/core/delegation/worker-tree-budget-coordinator.js +12 -46
  118. package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
  119. package/dist/core/keybindings.d.ts +10 -0
  120. package/dist/core/keybindings.d.ts.map +1 -1
  121. package/dist/core/keybindings.js +2 -0
  122. package/dist/core/keybindings.js.map +1 -1
  123. package/dist/core/orchestration/attempt-ordering.d.ts +9 -0
  124. package/dist/core/orchestration/attempt-ordering.d.ts.map +1 -0
  125. package/dist/core/orchestration/attempt-ordering.js +29 -0
  126. package/dist/core/orchestration/attempt-ordering.js.map +1 -0
  127. package/dist/core/orchestration/capability-gateway.d.ts +19 -0
  128. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
  129. package/dist/core/orchestration/capability-gateway.js +19 -2
  130. package/dist/core/orchestration/capability-gateway.js.map +1 -1
  131. package/dist/core/orchestration/contracts.d.ts +43 -3
  132. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  133. package/dist/core/orchestration/contracts.js +24 -0
  134. package/dist/core/orchestration/contracts.js.map +1 -1
  135. package/dist/core/orchestration/delegation-ledger.d.ts +8 -3
  136. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
  137. package/dist/core/orchestration/delegation-ledger.js +148 -55
  138. package/dist/core/orchestration/delegation-ledger.js.map +1 -1
  139. package/dist/core/orchestration/event-store.d.ts +6 -3
  140. package/dist/core/orchestration/event-store.d.ts.map +1 -1
  141. package/dist/core/orchestration/event-store.js +228 -30
  142. package/dist/core/orchestration/event-store.js.map +1 -1
  143. package/dist/core/orchestration/task-runtime-codecs.d.ts +31 -0
  144. package/dist/core/orchestration/task-runtime-codecs.d.ts.map +1 -0
  145. package/dist/core/orchestration/task-runtime-codecs.js +1471 -0
  146. package/dist/core/orchestration/task-runtime-codecs.js.map +1 -0
  147. package/dist/core/orchestration/task-runtime-projection.d.ts +30 -0
  148. package/dist/core/orchestration/task-runtime-projection.d.ts.map +1 -0
  149. package/dist/core/orchestration/task-runtime-projection.js +340 -0
  150. package/dist/core/orchestration/task-runtime-projection.js.map +1 -0
  151. package/dist/core/orchestration/task-runtime-reducer.d.ts +38 -0
  152. package/dist/core/orchestration/task-runtime-reducer.d.ts.map +1 -0
  153. package/dist/core/orchestration/task-runtime-reducer.js +1270 -0
  154. package/dist/core/orchestration/task-runtime-reducer.js.map +1 -0
  155. package/dist/core/orchestration/task-runtime-state.d.ts +142 -0
  156. package/dist/core/orchestration/task-runtime-state.d.ts.map +1 -0
  157. package/dist/core/orchestration/task-runtime-state.js +14 -0
  158. package/dist/core/orchestration/task-runtime-state.js.map +1 -0
  159. package/dist/core/orchestration/task-runtime.d.ts +44 -98
  160. package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
  161. package/dist/core/orchestration/task-runtime.js +357 -1113
  162. package/dist/core/orchestration/task-runtime.js.map +1 -1
  163. package/dist/core/orchestration/worker-context-fork-reference.d.ts +20 -0
  164. package/dist/core/orchestration/worker-context-fork-reference.d.ts.map +1 -0
  165. package/dist/core/orchestration/worker-context-fork-reference.js +53 -0
  166. package/dist/core/orchestration/worker-context-fork-reference.js.map +1 -0
  167. package/dist/core/research/research-runner.d.ts +2 -0
  168. package/dist/core/research/research-runner.d.ts.map +1 -1
  169. package/dist/core/research/research-runner.js +1 -0
  170. package/dist/core/research/research-runner.js.map +1 -1
  171. package/dist/core/runtime-builder.d.ts.map +1 -1
  172. package/dist/core/runtime-builder.js +8 -0
  173. package/dist/core/runtime-builder.js.map +1 -1
  174. package/dist/core/secrets/credential-project.d.ts.map +1 -1
  175. package/dist/core/secrets/credential-project.js +24 -2
  176. package/dist/core/secrets/credential-project.js.map +1 -1
  177. package/dist/core/security/secret-text.d.ts +3 -0
  178. package/dist/core/security/secret-text.d.ts.map +1 -1
  179. package/dist/core/security/secret-text.js +15 -0
  180. package/dist/core/security/secret-text.js.map +1 -1
  181. package/dist/core/settings-manager.d.ts +3 -0
  182. package/dist/core/settings-manager.d.ts.map +1 -1
  183. package/dist/core/settings-manager.js +160 -8
  184. package/dist/core/settings-manager.js.map +1 -1
  185. package/dist/core/tools/delegate.d.ts +31 -4
  186. package/dist/core/tools/delegate.d.ts.map +1 -1
  187. package/dist/core/tools/delegate.js +751 -98
  188. package/dist/core/tools/delegate.js.map +1 -1
  189. package/dist/main.d.ts.map +1 -1
  190. package/dist/main.js +1 -0
  191. package/dist/main.js.map +1 -1
  192. package/dist/modes/interactive/components/activity-lane.d.ts +5 -0
  193. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/activity-lane.js +133 -49
  195. package/dist/modes/interactive/components/activity-lane.js.map +1 -1
  196. package/dist/modes/interactive/components/agents-overlay.d.ts +40 -0
  197. package/dist/modes/interactive/components/agents-overlay.d.ts.map +1 -0
  198. package/dist/modes/interactive/components/agents-overlay.js +153 -0
  199. package/dist/modes/interactive/components/agents-overlay.js.map +1 -0
  200. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  201. package/dist/modes/interactive/components/settings-selector.js +18 -13
  202. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  203. package/dist/modes/interactive/interactive-event-controller.d.ts +1 -1
  204. package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
  205. package/dist/modes/interactive/interactive-event-controller.js +6 -3
  206. package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
  207. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  208. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  209. package/dist/modes/interactive/interactive-mode.js +51 -0
  210. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  211. package/dist/modes/interactive/key-handlers.d.ts +1 -0
  212. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  213. package/dist/modes/interactive/key-handlers.js +1 -0
  214. package/dist/modes/interactive/key-handlers.js.map +1 -1
  215. package/docs/harness-architecture.md +61 -17
  216. package/docs/settings.md +17 -9
  217. package/docs/worker-profiles.md +6 -2
  218. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  219. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  220. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  221. package/examples/extensions/sandbox/package-lock.json +2 -2
  222. package/examples/extensions/sandbox/package.json +1 -1
  223. package/examples/extensions/with-deps/package-lock.json +2 -2
  224. package/examples/extensions/with-deps/package.json +1 -1
  225. package/npm-shrinkwrap.json +12 -12
  226. package/package.json +4 -4
@@ -0,0 +1,437 @@
1
+ import { createHash } from "node:crypto";
2
+ import { unlinkSync } from "node:fs";
3
+ import { basename, join } from "node:path";
4
+ import { workerContextForkFile, workerContextForksDir } from "../agent-paths.js";
5
+ import { MAX_ORCHESTRATION_IDENTIFIER_LENGTH, MAX_ORCHESTRATION_MODEL_ID_LENGTH, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, } from "../orchestration/contracts.js";
6
+ import { MAX_WORKER_CONTEXT_FORK_API_LENGTH, MAX_WORKER_CONTEXT_FORK_BYTES, MAX_WORKER_CONTEXT_FORK_MESSAGES, MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS, normalizeWorkerContextForkReference, WORKER_CONTEXT_FORK_REFERENCE_SCHEMA_VERSION as SCHEMA_VERSION, } from "../orchestration/worker-context-fork-reference.js";
7
+ import { withFileLockSync, writeFileAtomicSync } from "../util/atomic-file.js";
8
+ import { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from "../util/bounded-file.js";
9
+ import { requireBoundedTrimmedText } from "../util/bounded-value.js";
10
+ import { DEFAULT_WORKER_FLEET_LIMITS } from "./worker-fleet-limits.js";
11
+ const MAX_PATH_CHARS = 4096;
12
+ const MAX_FILE_BYTES = MAX_WORKER_CONTEXT_FORK_BYTES + 16 * 1024;
13
+ const MAX_DIRECTORY_ENTRIES = DEFAULT_WORKER_FLEET_LIMITS.maxAgentsPerSession + 32;
14
+ const SNAPSHOT_FILE_PATTERN = /^([a-f0-9]{64})-([a-f0-9]{64})\.json$/;
15
+ export const MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS = DEFAULT_WORKER_FLEET_LIMITS.maxAgentsPerSession;
16
+ /** Stable failure classification for controller admission and recovery wiring. */
17
+ export class WorkerContextForkStoreError extends Error {
18
+ constructor(code, message, cause) {
19
+ super(message, cause === undefined ? undefined : { cause });
20
+ this.name = "WorkerContextForkStoreError";
21
+ this.code = code;
22
+ }
23
+ }
24
+ class DurableWorkerContextForkReferenceIndex {
25
+ constructor(value) {
26
+ this.keysByIdentity = new Map();
27
+ if (!Array.isArray(value))
28
+ throw new TypeError("Durable worker context fork references must be an array.");
29
+ for (const candidate of value) {
30
+ const reference = normalizeWorkerContextForkReference(candidate);
31
+ const keys = this.keysByIdentity.get(reference.identityDigest) ?? new Set();
32
+ keys.add(referenceKey(reference));
33
+ this.keysByIdentity.set(reference.identityDigest, keys);
34
+ }
35
+ }
36
+ hasIdentity(identityDigest) {
37
+ return this.keysByIdentity.has(identityDigest);
38
+ }
39
+ hasConflictingIdentity(reference) {
40
+ const keys = this.keysByIdentity.get(reference.identityDigest);
41
+ return keys !== undefined && (keys.size !== 1 || !keys.has(referenceKey(reference)));
42
+ }
43
+ }
44
+ function exactObject(value, keys, label) {
45
+ if (!value || typeof value !== "object" || Array.isArray(value))
46
+ throw new TypeError(`${label} must be an object.`);
47
+ const record = value;
48
+ const actualKeys = Object.keys(record);
49
+ if (actualKeys.length !== keys.length || keys.some((key) => !Object.hasOwn(record, key))) {
50
+ throw new TypeError(`${label} has an unsupported shape.`);
51
+ }
52
+ return record;
53
+ }
54
+ function boundedString(value, maximum, label) {
55
+ if (typeof value !== "string" || !value.trim() || value.length > maximum) {
56
+ throw new TypeError(`${label} must be non-empty and no longer than ${maximum} characters.`);
57
+ }
58
+ return value;
59
+ }
60
+ function safeTimestamp(value, label) {
61
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
62
+ throw new TypeError(`${label} must be a non-negative safe integer.`);
63
+ }
64
+ return value;
65
+ }
66
+ function nonNegativeFinite(value, label) {
67
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
68
+ throw new TypeError(`${label} must be a non-negative finite number.`);
69
+ }
70
+ return value;
71
+ }
72
+ function nonNegativeTokenCount(value, label) {
73
+ const normalized = nonNegativeFinite(value, label);
74
+ if (!Number.isSafeInteger(normalized))
75
+ throw new TypeError(`${label} must be a safe integer.`);
76
+ return normalized;
77
+ }
78
+ function normalizeUsage(value) {
79
+ const usage = exactObject(value, ["input", "output", "cacheRead", "cacheWrite", "totalTokens", "cost"], "Usage");
80
+ const cost = exactObject(usage.cost, ["input", "output", "cacheRead", "cacheWrite", "total"], "Usage cost");
81
+ return {
82
+ input: nonNegativeTokenCount(usage.input, "Usage input"),
83
+ output: nonNegativeTokenCount(usage.output, "Usage output"),
84
+ cacheRead: nonNegativeTokenCount(usage.cacheRead, "Usage cache read"),
85
+ cacheWrite: nonNegativeTokenCount(usage.cacheWrite, "Usage cache write"),
86
+ totalTokens: nonNegativeTokenCount(usage.totalTokens, "Usage total tokens"),
87
+ cost: {
88
+ input: nonNegativeFinite(cost.input, "Usage input cost"),
89
+ output: nonNegativeFinite(cost.output, "Usage output cost"),
90
+ cacheRead: nonNegativeFinite(cost.cacheRead, "Usage cache-read cost"),
91
+ cacheWrite: nonNegativeFinite(cost.cacheWrite, "Usage cache-write cost"),
92
+ total: nonNegativeFinite(cost.total, "Usage total cost"),
93
+ },
94
+ };
95
+ }
96
+ function normalizeTextBlock(value, counter) {
97
+ if (counter.count >= MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS) {
98
+ throw new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS} text blocks.`);
99
+ }
100
+ const block = exactObject(value, ["type", "text"], "Worker context fork text block");
101
+ if (block.type !== "text")
102
+ throw new TypeError("Worker context forks may contain text blocks only.");
103
+ const text = boundedString(block.text, MAX_WORKER_CONTEXT_FORK_BYTES, "Worker context fork text");
104
+ counter.count += 1;
105
+ return { type: "text", text };
106
+ }
107
+ function normalizeUserMessage(value, counter) {
108
+ const message = exactObject(value, ["role", "content", "timestamp"], "Worker context fork user message");
109
+ if (message.role !== "user")
110
+ throw new TypeError("Worker context fork user role is invalid.");
111
+ let content;
112
+ if (typeof message.content === "string") {
113
+ content = boundedString(message.content, MAX_WORKER_CONTEXT_FORK_BYTES, "Worker context fork user content");
114
+ counter.count += 1;
115
+ if (counter.count > MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS) {
116
+ throw new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS} text blocks.`);
117
+ }
118
+ }
119
+ else {
120
+ if (!Array.isArray(message.content) || message.content.length === 0) {
121
+ throw new TypeError("Worker context fork user content must contain text.");
122
+ }
123
+ content = message.content.map((block) => normalizeTextBlock(block, counter));
124
+ }
125
+ return { role: "user", content, timestamp: safeTimestamp(message.timestamp, "User timestamp") };
126
+ }
127
+ function normalizeAssistantMessage(value, counter) {
128
+ const message = exactObject(value, ["role", "content", "api", "provider", "model", "usage", "stopReason", "timestamp"], "Worker context fork assistant message");
129
+ if (message.role !== "assistant")
130
+ throw new TypeError("Worker context fork assistant role is invalid.");
131
+ if (!Array.isArray(message.content) || message.content.length === 0) {
132
+ throw new TypeError("Worker context fork assistant content must contain text.");
133
+ }
134
+ if (message.stopReason !== "stop") {
135
+ throw new TypeError("Worker context forks may contain complete assistant messages only.");
136
+ }
137
+ return {
138
+ role: "assistant",
139
+ content: message.content.map((block) => normalizeTextBlock(block, counter)),
140
+ api: boundedString(message.api, MAX_WORKER_CONTEXT_FORK_API_LENGTH, "Assistant API"),
141
+ provider: boundedString(message.provider, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, "Assistant provider"),
142
+ model: boundedString(message.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, "Assistant model"),
143
+ usage: normalizeUsage(message.usage),
144
+ stopReason: "stop",
145
+ timestamp: safeTimestamp(message.timestamp, "Assistant timestamp"),
146
+ };
147
+ }
148
+ function normalizeMessages(value) {
149
+ if (!Array.isArray(value) || value.length > MAX_WORKER_CONTEXT_FORK_MESSAGES) {
150
+ throw new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_MESSAGES} messages.`);
151
+ }
152
+ const messages = [];
153
+ const counter = { count: 0 };
154
+ let hasUser = false;
155
+ for (const candidate of value) {
156
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
157
+ throw new TypeError("Worker context fork message must be an object.");
158
+ }
159
+ const role = Object.getOwnPropertyDescriptor(candidate, "role");
160
+ const roleValue = role && "value" in role ? role.value : undefined;
161
+ if (roleValue === "user") {
162
+ messages.push(normalizeUserMessage(candidate, counter));
163
+ hasUser = true;
164
+ continue;
165
+ }
166
+ if (roleValue === "assistant") {
167
+ if (!hasUser)
168
+ throw new TypeError("A worker context fork cannot begin with an assistant message.");
169
+ messages.push(normalizeAssistantMessage(candidate, counter));
170
+ continue;
171
+ }
172
+ throw new TypeError("Worker context forks may contain user and assistant messages only.");
173
+ }
174
+ const serialized = JSON.stringify(messages);
175
+ const byteLength = Buffer.byteLength(serialized, "utf-8");
176
+ if (byteLength > MAX_WORKER_CONTEXT_FORK_BYTES) {
177
+ throw new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_BYTES} bytes.`);
178
+ }
179
+ return { messages, serialized, byteLength };
180
+ }
181
+ function sha256(domain, value) {
182
+ return createHash("sha256").update(domain).update("\0").update(value).digest("hex");
183
+ }
184
+ function identityDigest(parentSessionId, logicalAgentId) {
185
+ return sha256("pi-worker-context-fork-identity-v1", `${parentSessionId}\0${logicalAgentId}`);
186
+ }
187
+ function contentDigest(serializedMessages) {
188
+ return sha256("pi-worker-context-fork-content-v1", serializedMessages);
189
+ }
190
+ function referenceKey(reference) {
191
+ return JSON.stringify([
192
+ reference.schemaVersion,
193
+ reference.identityDigest,
194
+ reference.contentDigest,
195
+ reference.messageCount,
196
+ reference.messageBytes,
197
+ ]);
198
+ }
199
+ function canonicalEnvelope(parentSessionId, logicalAgentId, reference, messages) {
200
+ return {
201
+ schemaVersion: SCHEMA_VERSION,
202
+ parentSessionId,
203
+ logicalAgentId,
204
+ identityDigest: reference.identityDigest,
205
+ contentDigest: reference.contentDigest,
206
+ messageCount: reference.messageCount,
207
+ messageBytes: reference.messageBytes,
208
+ messages,
209
+ };
210
+ }
211
+ function serializeEnvelope(envelope) {
212
+ const serialized = `${JSON.stringify(envelope)}\n`;
213
+ if (Buffer.byteLength(serialized, "utf-8") > MAX_FILE_BYTES) {
214
+ throw new TypeError("Worker context fork snapshot exceeds its durable byte limit.");
215
+ }
216
+ return serialized;
217
+ }
218
+ function persistedIdentity(value, label) {
219
+ if (typeof value !== "string")
220
+ throw new TypeError(`${label} is invalid.`);
221
+ const normalized = requireBoundedTrimmedText(value, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, label);
222
+ if (normalized !== value)
223
+ throw new TypeError(`${label} is not canonical.`);
224
+ return normalized;
225
+ }
226
+ function parseEnvelope(raw, expectedParentSessionId, expectedLogicalAgentId, expectedReference) {
227
+ let parsed;
228
+ try {
229
+ parsed = JSON.parse(raw);
230
+ }
231
+ catch (error) {
232
+ throw new WorkerContextForkStoreError("snapshot_corrupt", "Worker context fork snapshot is not valid JSON.", error);
233
+ }
234
+ try {
235
+ const envelope = exactObject(parsed, [
236
+ "schemaVersion",
237
+ "parentSessionId",
238
+ "logicalAgentId",
239
+ "identityDigest",
240
+ "contentDigest",
241
+ "messageCount",
242
+ "messageBytes",
243
+ "messages",
244
+ ], "Worker context fork snapshot");
245
+ if (envelope.schemaVersion !== SCHEMA_VERSION) {
246
+ throw new TypeError("Worker context fork snapshot schema is unsupported.");
247
+ }
248
+ const parentSessionId = persistedIdentity(envelope.parentSessionId, "Snapshot parent session id");
249
+ const logicalAgentId = persistedIdentity(envelope.logicalAgentId, "Snapshot logical agent id");
250
+ if (parentSessionId !== expectedParentSessionId || logicalAgentId !== expectedLogicalAgentId) {
251
+ throw new WorkerContextForkStoreError("identity_conflict", "Worker context fork snapshot identity conflicts with the requested logical agent.");
252
+ }
253
+ const messages = normalizeMessages(envelope.messages);
254
+ const actualReference = {
255
+ schemaVersion: SCHEMA_VERSION,
256
+ identityDigest: identityDigest(parentSessionId, logicalAgentId),
257
+ contentDigest: contentDigest(messages.serialized),
258
+ messageCount: messages.messages.length,
259
+ messageBytes: messages.byteLength,
260
+ };
261
+ if (envelope.identityDigest !== actualReference.identityDigest ||
262
+ envelope.contentDigest !== actualReference.contentDigest ||
263
+ envelope.messageCount !== actualReference.messageCount ||
264
+ envelope.messageBytes !== actualReference.messageBytes ||
265
+ (expectedReference !== undefined &&
266
+ (expectedReference.identityDigest !== actualReference.identityDigest ||
267
+ expectedReference.contentDigest !== actualReference.contentDigest ||
268
+ expectedReference.messageCount !== actualReference.messageCount ||
269
+ expectedReference.messageBytes !== actualReference.messageBytes))) {
270
+ throw new TypeError("Worker context fork snapshot digest or bounds metadata is invalid.");
271
+ }
272
+ const canonical = canonicalEnvelope(parentSessionId, logicalAgentId, actualReference, messages.messages);
273
+ if (raw !== serializeEnvelope(canonical)) {
274
+ throw new TypeError("Worker context fork snapshot is not in canonical form.");
275
+ }
276
+ return { ...actualReference, parentSessionId, logicalAgentId, messages: messages.messages };
277
+ }
278
+ catch (error) {
279
+ if (error instanceof WorkerContextForkStoreError)
280
+ throw error;
281
+ throw new WorkerContextForkStoreError("snapshot_corrupt", "Worker context fork snapshot failed schema, digest, or bounds validation.", error);
282
+ }
283
+ }
284
+ function errorCode(error) {
285
+ if (!error || typeof error !== "object")
286
+ return undefined;
287
+ const descriptor = Object.getOwnPropertyDescriptor(error, "code");
288
+ return descriptor && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : undefined;
289
+ }
290
+ /**
291
+ * Immutable, per-session store for the exact sanitized message snapshot inherited by a new logical
292
+ * worker. Capture is synchronous so the caller can commit the snapshot before admitting dispatch.
293
+ * Identity is deliberately `(parentSessionId, logicalAgentId)`: persistent-agent follow-up tasks
294
+ * continue the existing transcript and cannot install a second birth context.
295
+ */
296
+ export class WorkerContextForkStore {
297
+ constructor(options) {
298
+ this.agentDir = requireBoundedTrimmedText(options.agentDir, MAX_PATH_CHARS, "Agent directory");
299
+ this.parentSessionId = requireBoundedTrimmedText(options.parentSessionId, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, "Parent session id");
300
+ this.directory = workerContextForksDir(this.agentDir, this.parentSessionId);
301
+ this.lockFile = join(this.directory, "capture-index");
302
+ }
303
+ capture(request) {
304
+ const prepared = this.prepareCapture(request);
305
+ return withFileLockSync(this.lockFile, () => this.captureLocked(prepared).reference);
306
+ }
307
+ /**
308
+ * Hold the capture lock across orphan classification, capture, and synchronous durable prepare.
309
+ * A callback failure removes only a file created by this invocation, and only after a refreshed
310
+ * lifecycle reference read still proves the logical identity unbound. A process crash can leave
311
+ * an orphan, which the next transaction may reclaim under the same proof and lock.
312
+ */
313
+ captureAndPrepare(request) {
314
+ const prepared = this.prepareCapture(request);
315
+ return withFileLockSync(this.lockFile, () => {
316
+ if (request.isLogicalIdentityClaimed?.()) {
317
+ throw new WorkerContextForkStoreError("identity_claimed", "Logical worker context identity already owns a durable attempt.");
318
+ }
319
+ const referenced = new DurableWorkerContextForkReferenceIndex(request.readDurableReferences());
320
+ const captured = this.captureLocked(prepared, referenced);
321
+ try {
322
+ const value = request.prepare(structuredClone(captured.reference));
323
+ return { reference: structuredClone(captured.reference), value };
324
+ }
325
+ catch (error) {
326
+ if (captured.created)
327
+ this.rollbackCreatedSnapshot(prepared, request.readDurableReferences);
328
+ throw error;
329
+ }
330
+ });
331
+ }
332
+ open(request) {
333
+ const logicalAgentId = requireBoundedTrimmedText(request.logicalAgentId, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, "Logical agent id");
334
+ let reference;
335
+ try {
336
+ reference = normalizeWorkerContextForkReference(request.reference);
337
+ }
338
+ catch (error) {
339
+ throw new WorkerContextForkStoreError("snapshot_corrupt", "Worker context fork reference failed schema or bounds validation.", error);
340
+ }
341
+ if (reference.identityDigest !== identityDigest(this.parentSessionId, logicalAgentId)) {
342
+ throw new WorkerContextForkStoreError("identity_conflict", "Worker context fork reference conflicts with the requested logical agent.");
343
+ }
344
+ const filePath = workerContextForkFile(this.agentDir, this.parentSessionId, reference.identityDigest, reference.contentDigest);
345
+ return this.readSnapshot(filePath, logicalAgentId, reference);
346
+ }
347
+ prepareCapture(request) {
348
+ const logicalAgentId = requireBoundedTrimmedText(request.logicalAgentId, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, "Logical agent id");
349
+ const normalized = normalizeMessages(request.messages);
350
+ const reference = {
351
+ schemaVersion: SCHEMA_VERSION,
352
+ identityDigest: identityDigest(this.parentSessionId, logicalAgentId),
353
+ contentDigest: contentDigest(normalized.serialized),
354
+ messageCount: normalized.messages.length,
355
+ messageBytes: normalized.byteLength,
356
+ };
357
+ const targetFile = workerContextForkFile(this.agentDir, this.parentSessionId, reference.identityDigest, reference.contentDigest);
358
+ const targetName = basename(targetFile);
359
+ const serialized = serializeEnvelope(canonicalEnvelope(this.parentSessionId, logicalAgentId, reference, normalized.messages));
360
+ return { logicalAgentId, normalized, reference, targetFile, targetName, serialized };
361
+ }
362
+ captureLocked(prepared, referenced) {
363
+ let names;
364
+ try {
365
+ names = readBoundedDirectoryNamesSync(this.directory, MAX_DIRECTORY_ENTRIES, "Worker context fork snapshot directory");
366
+ }
367
+ catch (error) {
368
+ throw new WorkerContextForkStoreError("capacity_reached", "Worker context fork snapshot directory exceeds its bounded retention capacity.", error);
369
+ }
370
+ const snapshotNames = names.filter((name) => SNAPSHOT_FILE_PATTERN.test(name));
371
+ const identityPrefix = `${prepared.reference.identityDigest}-`;
372
+ const identityMatches = snapshotNames.filter((name) => name.startsWith(identityPrefix));
373
+ if (identityMatches.length > 1) {
374
+ throw new WorkerContextForkStoreError("identity_conflict", "Logical worker context identity has multiple durable snapshots.");
375
+ }
376
+ const existingName = identityMatches[0];
377
+ if (existingName === prepared.targetName) {
378
+ if (referenced?.hasConflictingIdentity(prepared.reference)) {
379
+ throw new WorkerContextForkStoreError("identity_conflict", "Logical worker context identity conflicts with its durable lifecycle reference.");
380
+ }
381
+ const existing = this.readSnapshot(prepared.targetFile, prepared.logicalAgentId, prepared.reference);
382
+ if (JSON.stringify(existing.messages) !== prepared.normalized.serialized) {
383
+ throw new WorkerContextForkStoreError("identity_conflict", "Logical worker context identity is bound to different snapshot content.");
384
+ }
385
+ return { reference: prepared.reference, created: false };
386
+ }
387
+ let retainedSnapshotCount = snapshotNames.length;
388
+ if (existingName !== undefined) {
389
+ if (!referenced || referenced.hasIdentity(prepared.reference.identityDigest)) {
390
+ throw new WorkerContextForkStoreError("identity_conflict", "Logical worker context identity is already bound to a different snapshot.");
391
+ }
392
+ const existingFile = join(this.directory, existingName);
393
+ const existing = this.readSnapshot(existingFile, prepared.logicalAgentId);
394
+ const canonicalExistingName = `${existing.identityDigest}-${existing.contentDigest}.json`;
395
+ if (existingName !== canonicalExistingName) {
396
+ throw new WorkerContextForkStoreError("snapshot_corrupt", "Worker context fork snapshot filename conflicts with its canonical content.");
397
+ }
398
+ unlinkSync(existingFile);
399
+ retainedSnapshotCount -= 1;
400
+ }
401
+ else if (referenced?.hasIdentity(prepared.reference.identityDigest)) {
402
+ throw new WorkerContextForkStoreError("identity_conflict", "Logical worker context identity has a durable reference but no exact snapshot replay.");
403
+ }
404
+ if (retainedSnapshotCount >= MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS) {
405
+ throw new WorkerContextForkStoreError("capacity_reached", `Worker context fork retention is capped at ${MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS} snapshots.`);
406
+ }
407
+ writeFileAtomicSync(prepared.targetFile, prepared.serialized, { mode: 0o600 });
408
+ this.readSnapshot(prepared.targetFile, prepared.logicalAgentId, prepared.reference);
409
+ return { reference: prepared.reference, created: true };
410
+ }
411
+ rollbackCreatedSnapshot(prepared, readDurableReferences) {
412
+ try {
413
+ const refreshed = new DurableWorkerContextForkReferenceIndex(readDurableReferences());
414
+ if (refreshed.hasIdentity(prepared.reference.identityDigest))
415
+ return;
416
+ unlinkSync(prepared.targetFile);
417
+ }
418
+ catch {
419
+ // Preserve the snapshot on an ambiguous refresh or cleanup failure. The next locked
420
+ // transaction can reclassify it from a fresh durable lifecycle projection.
421
+ }
422
+ }
423
+ readSnapshot(filePath, logicalAgentId, reference) {
424
+ let raw;
425
+ try {
426
+ raw = readBoundedTextFileSync(filePath, MAX_FILE_BYTES, "Worker context fork snapshot");
427
+ }
428
+ catch (error) {
429
+ if (errorCode(error) === "ENOENT") {
430
+ throw new WorkerContextForkStoreError("snapshot_missing", "Worker context fork snapshot is missing.", error);
431
+ }
432
+ throw new WorkerContextForkStoreError("snapshot_corrupt", "Worker context fork snapshot cannot be read within its durable bounds.", error);
433
+ }
434
+ return parseEnvelope(raw, this.parentSessionId, logicalAgentId, reference);
435
+ }
436
+ }
437
+ //# sourceMappingURL=worker-context-fork-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-context-fork-store.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-context-fork-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { unlinkSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport type { AssistantMessage, TextContent, Usage, UserMessage } from \"@caupulican/pi-ai\";\nimport { workerContextForkFile, workerContextForksDir } from \"../agent-paths.ts\";\nimport {\n\tMAX_ORCHESTRATION_IDENTIFIER_LENGTH,\n\tMAX_ORCHESTRATION_MODEL_ID_LENGTH,\n\tMAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH,\n} from \"../orchestration/contracts.ts\";\nimport {\n\tMAX_WORKER_CONTEXT_FORK_API_LENGTH,\n\tMAX_WORKER_CONTEXT_FORK_BYTES,\n\tMAX_WORKER_CONTEXT_FORK_MESSAGES,\n\tMAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS,\n\tnormalizeWorkerContextForkReference,\n\tWORKER_CONTEXT_FORK_REFERENCE_SCHEMA_VERSION as SCHEMA_VERSION,\n\ttype WorkerContextForkReference,\n} from \"../orchestration/worker-context-fork-reference.ts\";\nimport { withFileLockSync, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { readBoundedDirectoryNamesSync, readBoundedTextFileSync } from \"../util/bounded-file.ts\";\nimport { requireBoundedTrimmedText } from \"../util/bounded-value.ts\";\nimport type { SanitizedContextForkMessage } from \"./sanitized-context-fork.ts\";\nimport { DEFAULT_WORKER_FLEET_LIMITS } from \"./worker-fleet-limits.ts\";\n\nconst MAX_PATH_CHARS = 4096;\nconst MAX_FILE_BYTES = MAX_WORKER_CONTEXT_FORK_BYTES + 16 * 1024;\nconst MAX_DIRECTORY_ENTRIES = DEFAULT_WORKER_FLEET_LIMITS.maxAgentsPerSession + 32;\nconst SNAPSHOT_FILE_PATTERN = /^([a-f0-9]{64})-([a-f0-9]{64})\\.json$/;\n\nexport const MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS = DEFAULT_WORKER_FLEET_LIMITS.maxAgentsPerSession;\n\nexport type WorkerContextForkStoreErrorCode =\n\t| \"capacity_reached\"\n\t| \"identity_conflict\"\n\t| \"identity_claimed\"\n\t| \"snapshot_corrupt\"\n\t| \"snapshot_missing\";\n\n/** Stable failure classification for controller admission and recovery wiring. */\nexport class WorkerContextForkStoreError extends Error {\n\treadonly code: WorkerContextForkStoreErrorCode;\n\n\tconstructor(code: WorkerContextForkStoreErrorCode, message: string, cause?: unknown) {\n\t\tsuper(message, cause === undefined ? undefined : { cause });\n\t\tthis.name = \"WorkerContextForkStoreError\";\n\t\tthis.code = code;\n\t}\n}\n\nexport interface WorkerContextForkSnapshot extends WorkerContextForkReference {\n\tparentSessionId: string;\n\tlogicalAgentId: string;\n\tmessages: SanitizedContextForkMessage[];\n}\n\nexport interface CaptureWorkerContextForkRequest {\n\t/**\n\t * Newly admitted persistent specialist. Follow-up tasks reuse its durable conversation and must\n\t * reopen, never replace, this one birth snapshot.\n\t */\n\tlogicalAgentId: string;\n\tmessages: readonly SanitizedContextForkMessage[];\n}\n\nexport interface OpenWorkerContextForkRequest {\n\tlogicalAgentId: string;\n\treference: WorkerContextForkReference;\n}\n\n/**\n * Cross-process transaction input for the capture-before-dispatch boundary. The durable-reference\n * reader is invoked while the capture lock is held, so reclamation never relies on a stale snapshot\n * gathered before lock acquisition. `prepare` must synchronously persist or adopt the dispatch.\n */\nexport interface CaptureAndPrepareWorkerContextForkRequest<T> extends CaptureWorkerContextForkRequest {\n\treadDurableReferences: () => readonly WorkerContextForkReference[];\n\t/** Rechecked under the capture lock so a fresh start never adopts another caller's dispatch. */\n\tisLogicalIdentityClaimed?: () => boolean;\n\tprepare: (reference: WorkerContextForkReference) => T;\n}\n\nexport interface CaptureAndPrepareWorkerContextForkResult<T> {\n\treference: WorkerContextForkReference;\n\tvalue: T;\n}\n\ninterface NormalizedMessages {\n\tmessages: SanitizedContextForkMessage[];\n\tserialized: string;\n\tbyteLength: number;\n}\n\ninterface PreparedWorkerContextForkCapture {\n\tlogicalAgentId: string;\n\tnormalized: NormalizedMessages;\n\treference: WorkerContextForkReference;\n\ttargetFile: string;\n\ttargetName: string;\n\tserialized: string;\n}\n\ninterface LockedCaptureResult {\n\treference: WorkerContextForkReference;\n\tcreated: boolean;\n}\n\nclass DurableWorkerContextForkReferenceIndex {\n\tprivate readonly keysByIdentity = new Map<string, Set<string>>();\n\n\tconstructor(value: unknown) {\n\t\tif (!Array.isArray(value)) throw new TypeError(\"Durable worker context fork references must be an array.\");\n\t\tfor (const candidate of value as readonly unknown[]) {\n\t\t\tconst reference = normalizeWorkerContextForkReference(candidate);\n\t\t\tconst keys = this.keysByIdentity.get(reference.identityDigest) ?? new Set<string>();\n\t\t\tkeys.add(referenceKey(reference));\n\t\t\tthis.keysByIdentity.set(reference.identityDigest, keys);\n\t\t}\n\t}\n\n\thasIdentity(identityDigest: string): boolean {\n\t\treturn this.keysByIdentity.has(identityDigest);\n\t}\n\n\thasConflictingIdentity(reference: WorkerContextForkReference): boolean {\n\t\tconst keys = this.keysByIdentity.get(reference.identityDigest);\n\t\treturn keys !== undefined && (keys.size !== 1 || !keys.has(referenceKey(reference)));\n\t}\n}\n\ninterface PersistedWorkerContextFork {\n\tschemaVersion: 1;\n\tparentSessionId: string;\n\tlogicalAgentId: string;\n\tidentityDigest: string;\n\tcontentDigest: string;\n\tmessageCount: number;\n\tmessageBytes: number;\n\tmessages: SanitizedContextForkMessage[];\n}\n\ninterface TextBlockCounter {\n\tcount: number;\n}\n\nfunction exactObject(value: unknown, keys: readonly string[], label: string): Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw new TypeError(`${label} must be an object.`);\n\tconst record = value as Record<string, unknown>;\n\tconst actualKeys = Object.keys(record);\n\tif (actualKeys.length !== keys.length || keys.some((key) => !Object.hasOwn(record, key))) {\n\t\tthrow new TypeError(`${label} has an unsupported shape.`);\n\t}\n\treturn record;\n}\n\nfunction boundedString(value: unknown, maximum: number, label: string): string {\n\tif (typeof value !== \"string\" || !value.trim() || value.length > maximum) {\n\t\tthrow new TypeError(`${label} must be non-empty and no longer than ${maximum} characters.`);\n\t}\n\treturn value;\n}\n\nfunction safeTimestamp(value: unknown, label: string): number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new TypeError(`${label} must be a non-negative safe integer.`);\n\t}\n\treturn value;\n}\n\nfunction nonNegativeFinite(value: unknown, label: string): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\tthrow new TypeError(`${label} must be a non-negative finite number.`);\n\t}\n\treturn value;\n}\n\nfunction nonNegativeTokenCount(value: unknown, label: string): number {\n\tconst normalized = nonNegativeFinite(value, label);\n\tif (!Number.isSafeInteger(normalized)) throw new TypeError(`${label} must be a safe integer.`);\n\treturn normalized;\n}\n\nfunction normalizeUsage(value: unknown): Usage {\n\tconst usage = exactObject(value, [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"totalTokens\", \"cost\"], \"Usage\");\n\tconst cost = exactObject(usage.cost, [\"input\", \"output\", \"cacheRead\", \"cacheWrite\", \"total\"], \"Usage cost\");\n\treturn {\n\t\tinput: nonNegativeTokenCount(usage.input, \"Usage input\"),\n\t\toutput: nonNegativeTokenCount(usage.output, \"Usage output\"),\n\t\tcacheRead: nonNegativeTokenCount(usage.cacheRead, \"Usage cache read\"),\n\t\tcacheWrite: nonNegativeTokenCount(usage.cacheWrite, \"Usage cache write\"),\n\t\ttotalTokens: nonNegativeTokenCount(usage.totalTokens, \"Usage total tokens\"),\n\t\tcost: {\n\t\t\tinput: nonNegativeFinite(cost.input, \"Usage input cost\"),\n\t\t\toutput: nonNegativeFinite(cost.output, \"Usage output cost\"),\n\t\t\tcacheRead: nonNegativeFinite(cost.cacheRead, \"Usage cache-read cost\"),\n\t\t\tcacheWrite: nonNegativeFinite(cost.cacheWrite, \"Usage cache-write cost\"),\n\t\t\ttotal: nonNegativeFinite(cost.total, \"Usage total cost\"),\n\t\t},\n\t};\n}\n\nfunction normalizeTextBlock(value: unknown, counter: TextBlockCounter): TextContent {\n\tif (counter.count >= MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS) {\n\t\tthrow new TypeError(\n\t\t\t`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS} text blocks.`,\n\t\t);\n\t}\n\tconst block = exactObject(value, [\"type\", \"text\"], \"Worker context fork text block\");\n\tif (block.type !== \"text\") throw new TypeError(\"Worker context forks may contain text blocks only.\");\n\tconst text = boundedString(block.text, MAX_WORKER_CONTEXT_FORK_BYTES, \"Worker context fork text\");\n\tcounter.count += 1;\n\treturn { type: \"text\", text };\n}\n\nfunction normalizeUserMessage(value: unknown, counter: TextBlockCounter): UserMessage {\n\tconst message = exactObject(value, [\"role\", \"content\", \"timestamp\"], \"Worker context fork user message\");\n\tif (message.role !== \"user\") throw new TypeError(\"Worker context fork user role is invalid.\");\n\tlet content: UserMessage[\"content\"];\n\tif (typeof message.content === \"string\") {\n\t\tcontent = boundedString(message.content, MAX_WORKER_CONTEXT_FORK_BYTES, \"Worker context fork user content\");\n\t\tcounter.count += 1;\n\t\tif (counter.count > MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_TEXT_BLOCKS} text blocks.`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (!Array.isArray(message.content) || message.content.length === 0) {\n\t\t\tthrow new TypeError(\"Worker context fork user content must contain text.\");\n\t\t}\n\t\tcontent = message.content.map((block) => normalizeTextBlock(block, counter));\n\t}\n\treturn { role: \"user\", content, timestamp: safeTimestamp(message.timestamp, \"User timestamp\") };\n}\n\nfunction normalizeAssistantMessage(value: unknown, counter: TextBlockCounter): AssistantMessage {\n\tconst message = exactObject(\n\t\tvalue,\n\t\t[\"role\", \"content\", \"api\", \"provider\", \"model\", \"usage\", \"stopReason\", \"timestamp\"],\n\t\t\"Worker context fork assistant message\",\n\t);\n\tif (message.role !== \"assistant\") throw new TypeError(\"Worker context fork assistant role is invalid.\");\n\tif (!Array.isArray(message.content) || message.content.length === 0) {\n\t\tthrow new TypeError(\"Worker context fork assistant content must contain text.\");\n\t}\n\tif (message.stopReason !== \"stop\") {\n\t\tthrow new TypeError(\"Worker context forks may contain complete assistant messages only.\");\n\t}\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: message.content.map((block) => normalizeTextBlock(block, counter)),\n\t\tapi: boundedString(message.api, MAX_WORKER_CONTEXT_FORK_API_LENGTH, \"Assistant API\"),\n\t\tprovider: boundedString(message.provider, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, \"Assistant provider\"),\n\t\tmodel: boundedString(message.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, \"Assistant model\"),\n\t\tusage: normalizeUsage(message.usage),\n\t\tstopReason: \"stop\",\n\t\ttimestamp: safeTimestamp(message.timestamp, \"Assistant timestamp\"),\n\t};\n}\n\nfunction normalizeMessages(value: unknown): NormalizedMessages {\n\tif (!Array.isArray(value) || value.length > MAX_WORKER_CONTEXT_FORK_MESSAGES) {\n\t\tthrow new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_MESSAGES} messages.`);\n\t}\n\tconst messages: SanitizedContextForkMessage[] = [];\n\tconst counter: TextBlockCounter = { count: 0 };\n\tlet hasUser = false;\n\tfor (const candidate of value as readonly unknown[]) {\n\t\tif (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) {\n\t\t\tthrow new TypeError(\"Worker context fork message must be an object.\");\n\t\t}\n\t\tconst role = Object.getOwnPropertyDescriptor(candidate, \"role\");\n\t\tconst roleValue = role && \"value\" in role ? role.value : undefined;\n\t\tif (roleValue === \"user\") {\n\t\t\tmessages.push(normalizeUserMessage(candidate, counter));\n\t\t\thasUser = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (roleValue === \"assistant\") {\n\t\t\tif (!hasUser) throw new TypeError(\"A worker context fork cannot begin with an assistant message.\");\n\t\t\tmessages.push(normalizeAssistantMessage(candidate, counter));\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new TypeError(\"Worker context forks may contain user and assistant messages only.\");\n\t}\n\tconst serialized = JSON.stringify(messages);\n\tconst byteLength = Buffer.byteLength(serialized, \"utf-8\");\n\tif (byteLength > MAX_WORKER_CONTEXT_FORK_BYTES) {\n\t\tthrow new TypeError(`A worker context fork may contain at most ${MAX_WORKER_CONTEXT_FORK_BYTES} bytes.`);\n\t}\n\treturn { messages, serialized, byteLength };\n}\n\nfunction sha256(domain: string, value: string): string {\n\treturn createHash(\"sha256\").update(domain).update(\"\\0\").update(value).digest(\"hex\");\n}\n\nfunction identityDigest(parentSessionId: string, logicalAgentId: string): string {\n\treturn sha256(\"pi-worker-context-fork-identity-v1\", `${parentSessionId}\\0${logicalAgentId}`);\n}\n\nfunction contentDigest(serializedMessages: string): string {\n\treturn sha256(\"pi-worker-context-fork-content-v1\", serializedMessages);\n}\n\nfunction referenceKey(reference: WorkerContextForkReference): string {\n\treturn JSON.stringify([\n\t\treference.schemaVersion,\n\t\treference.identityDigest,\n\t\treference.contentDigest,\n\t\treference.messageCount,\n\t\treference.messageBytes,\n\t]);\n}\n\nfunction canonicalEnvelope(\n\tparentSessionId: string,\n\tlogicalAgentId: string,\n\treference: WorkerContextForkReference,\n\tmessages: SanitizedContextForkMessage[],\n): PersistedWorkerContextFork {\n\treturn {\n\t\tschemaVersion: SCHEMA_VERSION,\n\t\tparentSessionId,\n\t\tlogicalAgentId,\n\t\tidentityDigest: reference.identityDigest,\n\t\tcontentDigest: reference.contentDigest,\n\t\tmessageCount: reference.messageCount,\n\t\tmessageBytes: reference.messageBytes,\n\t\tmessages,\n\t};\n}\n\nfunction serializeEnvelope(envelope: PersistedWorkerContextFork): string {\n\tconst serialized = `${JSON.stringify(envelope)}\\n`;\n\tif (Buffer.byteLength(serialized, \"utf-8\") > MAX_FILE_BYTES) {\n\t\tthrow new TypeError(\"Worker context fork snapshot exceeds its durable byte limit.\");\n\t}\n\treturn serialized;\n}\n\nfunction persistedIdentity(value: unknown, label: string): string {\n\tif (typeof value !== \"string\") throw new TypeError(`${label} is invalid.`);\n\tconst normalized = requireBoundedTrimmedText(value, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, label);\n\tif (normalized !== value) throw new TypeError(`${label} is not canonical.`);\n\treturn normalized;\n}\n\nfunction parseEnvelope(\n\traw: string,\n\texpectedParentSessionId: string,\n\texpectedLogicalAgentId: string,\n\texpectedReference?: WorkerContextForkReference,\n): WorkerContextForkSnapshot {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (error) {\n\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\"snapshot_corrupt\",\n\t\t\t\"Worker context fork snapshot is not valid JSON.\",\n\t\t\terror,\n\t\t);\n\t}\n\ttry {\n\t\tconst envelope = exactObject(\n\t\t\tparsed,\n\t\t\t[\n\t\t\t\t\"schemaVersion\",\n\t\t\t\t\"parentSessionId\",\n\t\t\t\t\"logicalAgentId\",\n\t\t\t\t\"identityDigest\",\n\t\t\t\t\"contentDigest\",\n\t\t\t\t\"messageCount\",\n\t\t\t\t\"messageBytes\",\n\t\t\t\t\"messages\",\n\t\t\t],\n\t\t\t\"Worker context fork snapshot\",\n\t\t);\n\t\tif (envelope.schemaVersion !== SCHEMA_VERSION) {\n\t\t\tthrow new TypeError(\"Worker context fork snapshot schema is unsupported.\");\n\t\t}\n\t\tconst parentSessionId = persistedIdentity(envelope.parentSessionId, \"Snapshot parent session id\");\n\t\tconst logicalAgentId = persistedIdentity(envelope.logicalAgentId, \"Snapshot logical agent id\");\n\t\tif (parentSessionId !== expectedParentSessionId || logicalAgentId !== expectedLogicalAgentId) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"identity_conflict\",\n\t\t\t\t\"Worker context fork snapshot identity conflicts with the requested logical agent.\",\n\t\t\t);\n\t\t}\n\t\tconst messages = normalizeMessages(envelope.messages);\n\t\tconst actualReference: WorkerContextForkReference = {\n\t\t\tschemaVersion: SCHEMA_VERSION,\n\t\t\tidentityDigest: identityDigest(parentSessionId, logicalAgentId),\n\t\t\tcontentDigest: contentDigest(messages.serialized),\n\t\t\tmessageCount: messages.messages.length,\n\t\t\tmessageBytes: messages.byteLength,\n\t\t};\n\t\tif (\n\t\t\tenvelope.identityDigest !== actualReference.identityDigest ||\n\t\t\tenvelope.contentDigest !== actualReference.contentDigest ||\n\t\t\tenvelope.messageCount !== actualReference.messageCount ||\n\t\t\tenvelope.messageBytes !== actualReference.messageBytes ||\n\t\t\t(expectedReference !== undefined &&\n\t\t\t\t(expectedReference.identityDigest !== actualReference.identityDigest ||\n\t\t\t\t\texpectedReference.contentDigest !== actualReference.contentDigest ||\n\t\t\t\t\texpectedReference.messageCount !== actualReference.messageCount ||\n\t\t\t\t\texpectedReference.messageBytes !== actualReference.messageBytes))\n\t\t) {\n\t\t\tthrow new TypeError(\"Worker context fork snapshot digest or bounds metadata is invalid.\");\n\t\t}\n\t\tconst canonical = canonicalEnvelope(parentSessionId, logicalAgentId, actualReference, messages.messages);\n\t\tif (raw !== serializeEnvelope(canonical)) {\n\t\t\tthrow new TypeError(\"Worker context fork snapshot is not in canonical form.\");\n\t\t}\n\t\treturn { ...actualReference, parentSessionId, logicalAgentId, messages: messages.messages };\n\t} catch (error) {\n\t\tif (error instanceof WorkerContextForkStoreError) throw error;\n\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\"snapshot_corrupt\",\n\t\t\t\"Worker context fork snapshot failed schema, digest, or bounds validation.\",\n\t\t\terror,\n\t\t);\n\t}\n}\n\nfunction errorCode(error: unknown): string | undefined {\n\tif (!error || typeof error !== \"object\") return undefined;\n\tconst descriptor = Object.getOwnPropertyDescriptor(error, \"code\");\n\treturn descriptor && \"value\" in descriptor && typeof descriptor.value === \"string\" ? descriptor.value : undefined;\n}\n\n/**\n * Immutable, per-session store for the exact sanitized message snapshot inherited by a new logical\n * worker. Capture is synchronous so the caller can commit the snapshot before admitting dispatch.\n * Identity is deliberately `(parentSessionId, logicalAgentId)`: persistent-agent follow-up tasks\n * continue the existing transcript and cannot install a second birth context.\n */\nexport class WorkerContextForkStore {\n\tprivate readonly agentDir: string;\n\tprivate readonly parentSessionId: string;\n\tprivate readonly directory: string;\n\tprivate readonly lockFile: string;\n\n\tconstructor(options: { agentDir: string; parentSessionId: string }) {\n\t\tthis.agentDir = requireBoundedTrimmedText(options.agentDir, MAX_PATH_CHARS, \"Agent directory\");\n\t\tthis.parentSessionId = requireBoundedTrimmedText(\n\t\t\toptions.parentSessionId,\n\t\t\tMAX_ORCHESTRATION_IDENTIFIER_LENGTH,\n\t\t\t\"Parent session id\",\n\t\t);\n\t\tthis.directory = workerContextForksDir(this.agentDir, this.parentSessionId);\n\t\tthis.lockFile = join(this.directory, \"capture-index\");\n\t}\n\n\tcapture(request: CaptureWorkerContextForkRequest): WorkerContextForkReference {\n\t\tconst prepared = this.prepareCapture(request);\n\t\treturn withFileLockSync(this.lockFile, () => this.captureLocked(prepared).reference);\n\t}\n\n\t/**\n\t * Hold the capture lock across orphan classification, capture, and synchronous durable prepare.\n\t * A callback failure removes only a file created by this invocation, and only after a refreshed\n\t * lifecycle reference read still proves the logical identity unbound. A process crash can leave\n\t * an orphan, which the next transaction may reclaim under the same proof and lock.\n\t */\n\tcaptureAndPrepare<T>(\n\t\trequest: CaptureAndPrepareWorkerContextForkRequest<T>,\n\t): CaptureAndPrepareWorkerContextForkResult<T> {\n\t\tconst prepared = this.prepareCapture(request);\n\t\treturn withFileLockSync(this.lockFile, () => {\n\t\t\tif (request.isLogicalIdentityClaimed?.()) {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"identity_claimed\",\n\t\t\t\t\t\"Logical worker context identity already owns a durable attempt.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst referenced = new DurableWorkerContextForkReferenceIndex(request.readDurableReferences());\n\t\t\tconst captured = this.captureLocked(prepared, referenced);\n\t\t\ttry {\n\t\t\t\tconst value = request.prepare(structuredClone(captured.reference));\n\t\t\t\treturn { reference: structuredClone(captured.reference), value };\n\t\t\t} catch (error) {\n\t\t\t\tif (captured.created) this.rollbackCreatedSnapshot(prepared, request.readDurableReferences);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t}\n\n\topen(request: OpenWorkerContextForkRequest): WorkerContextForkSnapshot {\n\t\tconst logicalAgentId = requireBoundedTrimmedText(\n\t\t\trequest.logicalAgentId,\n\t\t\tMAX_ORCHESTRATION_IDENTIFIER_LENGTH,\n\t\t\t\"Logical agent id\",\n\t\t);\n\t\tlet reference: WorkerContextForkReference;\n\t\ttry {\n\t\t\treference = normalizeWorkerContextForkReference(request.reference);\n\t\t} catch (error) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"snapshot_corrupt\",\n\t\t\t\t\"Worker context fork reference failed schema or bounds validation.\",\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t\tif (reference.identityDigest !== identityDigest(this.parentSessionId, logicalAgentId)) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"identity_conflict\",\n\t\t\t\t\"Worker context fork reference conflicts with the requested logical agent.\",\n\t\t\t);\n\t\t}\n\t\tconst filePath = workerContextForkFile(\n\t\t\tthis.agentDir,\n\t\t\tthis.parentSessionId,\n\t\t\treference.identityDigest,\n\t\t\treference.contentDigest,\n\t\t);\n\t\treturn this.readSnapshot(filePath, logicalAgentId, reference);\n\t}\n\n\tprivate prepareCapture(request: CaptureWorkerContextForkRequest): PreparedWorkerContextForkCapture {\n\t\tconst logicalAgentId = requireBoundedTrimmedText(\n\t\t\trequest.logicalAgentId,\n\t\t\tMAX_ORCHESTRATION_IDENTIFIER_LENGTH,\n\t\t\t\"Logical agent id\",\n\t\t);\n\t\tconst normalized = normalizeMessages(request.messages);\n\t\tconst reference: WorkerContextForkReference = {\n\t\t\tschemaVersion: SCHEMA_VERSION,\n\t\t\tidentityDigest: identityDigest(this.parentSessionId, logicalAgentId),\n\t\t\tcontentDigest: contentDigest(normalized.serialized),\n\t\t\tmessageCount: normalized.messages.length,\n\t\t\tmessageBytes: normalized.byteLength,\n\t\t};\n\t\tconst targetFile = workerContextForkFile(\n\t\t\tthis.agentDir,\n\t\t\tthis.parentSessionId,\n\t\t\treference.identityDigest,\n\t\t\treference.contentDigest,\n\t\t);\n\t\tconst targetName = basename(targetFile);\n\t\tconst serialized = serializeEnvelope(\n\t\t\tcanonicalEnvelope(this.parentSessionId, logicalAgentId, reference, normalized.messages),\n\t\t);\n\t\treturn { logicalAgentId, normalized, reference, targetFile, targetName, serialized };\n\t}\n\n\tprivate captureLocked(\n\t\tprepared: PreparedWorkerContextForkCapture,\n\t\treferenced?: DurableWorkerContextForkReferenceIndex,\n\t): LockedCaptureResult {\n\t\tlet names: string[];\n\t\ttry {\n\t\t\tnames = readBoundedDirectoryNamesSync(\n\t\t\t\tthis.directory,\n\t\t\t\tMAX_DIRECTORY_ENTRIES,\n\t\t\t\t\"Worker context fork snapshot directory\",\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"capacity_reached\",\n\t\t\t\t\"Worker context fork snapshot directory exceeds its bounded retention capacity.\",\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t\tconst snapshotNames = names.filter((name) => SNAPSHOT_FILE_PATTERN.test(name));\n\t\tconst identityPrefix = `${prepared.reference.identityDigest}-`;\n\t\tconst identityMatches = snapshotNames.filter((name) => name.startsWith(identityPrefix));\n\t\tif (identityMatches.length > 1) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"identity_conflict\",\n\t\t\t\t\"Logical worker context identity has multiple durable snapshots.\",\n\t\t\t);\n\t\t}\n\n\t\tconst existingName = identityMatches[0];\n\t\tif (existingName === prepared.targetName) {\n\t\t\tif (referenced?.hasConflictingIdentity(prepared.reference)) {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"identity_conflict\",\n\t\t\t\t\t\"Logical worker context identity conflicts with its durable lifecycle reference.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst existing = this.readSnapshot(prepared.targetFile, prepared.logicalAgentId, prepared.reference);\n\t\t\tif (JSON.stringify(existing.messages) !== prepared.normalized.serialized) {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"identity_conflict\",\n\t\t\t\t\t\"Logical worker context identity is bound to different snapshot content.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { reference: prepared.reference, created: false };\n\t\t}\n\n\t\tlet retainedSnapshotCount = snapshotNames.length;\n\t\tif (existingName !== undefined) {\n\t\t\tif (!referenced || referenced.hasIdentity(prepared.reference.identityDigest)) {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"identity_conflict\",\n\t\t\t\t\t\"Logical worker context identity is already bound to a different snapshot.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst existingFile = join(this.directory, existingName);\n\t\t\tconst existing = this.readSnapshot(existingFile, prepared.logicalAgentId);\n\t\t\tconst canonicalExistingName = `${existing.identityDigest}-${existing.contentDigest}.json`;\n\t\t\tif (existingName !== canonicalExistingName) {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"snapshot_corrupt\",\n\t\t\t\t\t\"Worker context fork snapshot filename conflicts with its canonical content.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tunlinkSync(existingFile);\n\t\t\tretainedSnapshotCount -= 1;\n\t\t} else if (referenced?.hasIdentity(prepared.reference.identityDigest)) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"identity_conflict\",\n\t\t\t\t\"Logical worker context identity has a durable reference but no exact snapshot replay.\",\n\t\t\t);\n\t\t}\n\n\t\tif (retainedSnapshotCount >= MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS) {\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"capacity_reached\",\n\t\t\t\t`Worker context fork retention is capped at ${MAX_RETAINED_WORKER_CONTEXT_FORK_SNAPSHOTS} snapshots.`,\n\t\t\t);\n\t\t}\n\t\twriteFileAtomicSync(prepared.targetFile, prepared.serialized, { mode: 0o600 });\n\t\tthis.readSnapshot(prepared.targetFile, prepared.logicalAgentId, prepared.reference);\n\t\treturn { reference: prepared.reference, created: true };\n\t}\n\n\tprivate rollbackCreatedSnapshot(\n\t\tprepared: PreparedWorkerContextForkCapture,\n\t\treadDurableReferences: () => readonly WorkerContextForkReference[],\n\t): void {\n\t\ttry {\n\t\t\tconst refreshed = new DurableWorkerContextForkReferenceIndex(readDurableReferences());\n\t\t\tif (refreshed.hasIdentity(prepared.reference.identityDigest)) return;\n\t\t\tunlinkSync(prepared.targetFile);\n\t\t} catch {\n\t\t\t// Preserve the snapshot on an ambiguous refresh or cleanup failure. The next locked\n\t\t\t// transaction can reclassify it from a fresh durable lifecycle projection.\n\t\t}\n\t}\n\n\tprivate readSnapshot(\n\t\tfilePath: string,\n\t\tlogicalAgentId: string,\n\t\treference?: WorkerContextForkReference,\n\t): WorkerContextForkSnapshot {\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = readBoundedTextFileSync(filePath, MAX_FILE_BYTES, \"Worker context fork snapshot\");\n\t\t} catch (error) {\n\t\t\tif (errorCode(error) === \"ENOENT\") {\n\t\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\t\"snapshot_missing\",\n\t\t\t\t\t\"Worker context fork snapshot is missing.\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new WorkerContextForkStoreError(\n\t\t\t\t\"snapshot_corrupt\",\n\t\t\t\t\"Worker context fork snapshot cannot be read within its durable bounds.\",\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t\treturn parseEnvelope(raw, this.parentSessionId, logicalAgentId, reference);\n\t}\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type SanitizedContextForkMode } from "./sanitized-context-fork.ts";
2
+ export interface WorkerContextModelIdentity {
3
+ provider: string;
4
+ model: string;
5
+ }
6
+ export interface ResolveWorkerContextInheritanceModeInput {
7
+ parent: WorkerContextModelIdentity;
8
+ worker: WorkerContextModelIdentity;
9
+ /** Eventual `fork_turns` wire value. Omission is policy-significant. */
10
+ mode?: string;
11
+ }
12
+ /**
13
+ * Pure provider/model egress policy for sanitized birth context. Implicit inheritance is allowed
14
+ * only when both identities match exactly; crossing either boundary defaults to none and requires
15
+ * an explicit none if a mode was supplied.
16
+ */
17
+ export declare function resolveWorkerContextInheritanceMode(input: ResolveWorkerContextInheritanceModeInput): SanitizedContextForkMode;
18
+ //# sourceMappingURL=worker-context-inheritance-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-context-inheritance-policy.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-context-inheritance-policy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE3G,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wCAAwC;IACxD,MAAM,EAAE,0BAA0B,CAAC;IACnC,MAAM,EAAE,0BAA0B,CAAC;IACnC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AASD;;;;GAIG;AACH,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,wCAAwC,GAC7C,wBAAwB,CAqB1B"}
@@ -0,0 +1,28 @@
1
+ import { MAX_ORCHESTRATION_MODEL_ID_LENGTH, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, } from "../orchestration/contracts.js";
2
+ import { parseSanitizedContextForkMode } from "./sanitized-context-fork.js";
3
+ function canonicalIdentity(value, maximum, label) {
4
+ if (!value || value.trim() !== value || value.length > maximum) {
5
+ throw new TypeError(`${label} must be a bounded non-empty canonical string.`);
6
+ }
7
+ return value;
8
+ }
9
+ /**
10
+ * Pure provider/model egress policy for sanitized birth context. Implicit inheritance is allowed
11
+ * only when both identities match exactly; crossing either boundary defaults to none and requires
12
+ * an explicit none if a mode was supplied.
13
+ */
14
+ export function resolveWorkerContextInheritanceMode(input) {
15
+ const parentProvider = canonicalIdentity(input.parent.provider, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, "Parent provider");
16
+ const parentModel = canonicalIdentity(input.parent.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, "Parent model");
17
+ const workerProvider = canonicalIdentity(input.worker.provider, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, "Worker provider");
18
+ const workerModel = canonicalIdentity(input.worker.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, "Worker model");
19
+ const sameBoundary = parentProvider === workerProvider && parentModel === workerModel;
20
+ if (input.mode === undefined)
21
+ return sameBoundary ? { kind: "all" } : { kind: "none" };
22
+ const mode = parseSanitizedContextForkMode(input.mode);
23
+ if (!sameBoundary && mode.kind !== "none") {
24
+ throw new TypeError("Worker context inheritance cannot cross a provider/model boundary.");
25
+ }
26
+ return mode;
27
+ }
28
+ //# sourceMappingURL=worker-context-inheritance-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-context-inheritance-policy.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-context-inheritance-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iCAAiC,EACjC,uCAAuC,GACvC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,6BAA6B,EAAiC,MAAM,6BAA6B,CAAC;AAc3G,SAAS,iBAAiB,CAAC,KAAa,EAAE,OAAe,EAAE,KAAa;IACvE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;QAChE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,gDAAgD,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mCAAmC,CAClD,KAA+C;IAE/C,MAAM,cAAc,GAAG,iBAAiB,CACvC,KAAK,CAAC,MAAM,CAAC,QAAQ,EACrB,uCAAuC,EACvC,iBAAiB,CACjB,CAAC;IACF,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,iCAAiC,EAAE,cAAc,CAAC,CAAC;IAC7G,MAAM,cAAc,GAAG,iBAAiB,CACvC,KAAK,CAAC,MAAM,CAAC,QAAQ,EACrB,uCAAuC,EACvC,iBAAiB,CACjB,CAAC;IACF,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,iCAAiC,EAAE,cAAc,CAAC,CAAC;IAC7G,MAAM,YAAY,GAAG,cAAc,KAAK,cAAc,IAAI,WAAW,KAAK,WAAW,CAAC;IAEtF,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACvF,MAAM,IAAI,GAAG,6BAA6B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,SAAS,CAAC,oEAAoE,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["import {\n\tMAX_ORCHESTRATION_MODEL_ID_LENGTH,\n\tMAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH,\n} from \"../orchestration/contracts.ts\";\nimport { parseSanitizedContextForkMode, type SanitizedContextForkMode } from \"./sanitized-context-fork.ts\";\n\nexport interface WorkerContextModelIdentity {\n\tprovider: string;\n\tmodel: string;\n}\n\nexport interface ResolveWorkerContextInheritanceModeInput {\n\tparent: WorkerContextModelIdentity;\n\tworker: WorkerContextModelIdentity;\n\t/** Eventual `fork_turns` wire value. Omission is policy-significant. */\n\tmode?: string;\n}\n\nfunction canonicalIdentity(value: string, maximum: number, label: string): string {\n\tif (!value || value.trim() !== value || value.length > maximum) {\n\t\tthrow new TypeError(`${label} must be a bounded non-empty canonical string.`);\n\t}\n\treturn value;\n}\n\n/**\n * Pure provider/model egress policy for sanitized birth context. Implicit inheritance is allowed\n * only when both identities match exactly; crossing either boundary defaults to none and requires\n * an explicit none if a mode was supplied.\n */\nexport function resolveWorkerContextInheritanceMode(\n\tinput: ResolveWorkerContextInheritanceModeInput,\n): SanitizedContextForkMode {\n\tconst parentProvider = canonicalIdentity(\n\t\tinput.parent.provider,\n\t\tMAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH,\n\t\t\"Parent provider\",\n\t);\n\tconst parentModel = canonicalIdentity(input.parent.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, \"Parent model\");\n\tconst workerProvider = canonicalIdentity(\n\t\tinput.worker.provider,\n\t\tMAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH,\n\t\t\"Worker provider\",\n\t);\n\tconst workerModel = canonicalIdentity(input.worker.model, MAX_ORCHESTRATION_MODEL_ID_LENGTH, \"Worker model\");\n\tconst sameBoundary = parentProvider === workerProvider && parentModel === workerModel;\n\n\tif (input.mode === undefined) return sameBoundary ? { kind: \"all\" } : { kind: \"none\" };\n\tconst mode = parseSanitizedContextForkMode(input.mode);\n\tif (!sameBoundary && mode.kind !== \"none\") {\n\t\tthrow new TypeError(\"Worker context inheritance cannot cross a provider/model boundary.\");\n\t}\n\treturn mode;\n}\n"]}
@@ -0,0 +1,31 @@
1
+ export interface WorkerConversationFileRevision {
2
+ readonly dev: bigint;
3
+ readonly ino: bigint;
4
+ readonly size: bigint;
5
+ readonly mtimeNs: bigint;
6
+ readonly ctimeNs: bigint;
7
+ }
8
+ export interface WorkerSessionFileHead {
9
+ readonly revision: WorkerConversationFileRevision;
10
+ readonly headerDigest: string;
11
+ readonly entryDigest: string;
12
+ readonly entryCount: number;
13
+ readonly prefixDigest?: string;
14
+ }
15
+ export declare class WorkerConversationOwnershipError extends Error {
16
+ constructor(message: string);
17
+ }
18
+ export declare function readWorkerConversationFileRevision(file: string): WorkerConversationFileRevision;
19
+ export declare function sameWorkerConversationFileRevision(left: WorkerConversationFileRevision, right: WorkerConversationFileRevision): boolean;
20
+ /**
21
+ * Verify the exact bytes appended by SessionManager and advance the trusted raw-file head once.
22
+ *
23
+ * The caller must hold the canonical conversation lock. That advisory lock excludes every
24
+ * supported writer, while revision/digest scans detect changes made between owned critical
25
+ * sections and during cold opens. This bounded append check intentionally reads only the new
26
+ * suffix: it cannot detect a noncooperating process rewriting an equal-length prefix inside the
27
+ * locked append window without reintroducing an O(n) prefix scan or a second durable authority.
28
+ */
29
+ export declare function advanceWorkerSessionHeadAfterOwnedAppend(sessionFile: string, previousHead: WorkerSessionFileHead, serializedEntry: string): WorkerSessionFileHead;
30
+ export declare function scanWorkerSessionFile(sessionFile: string, expectedSessionId: string, expectedCwd: string, prefixEntryCount?: number): WorkerSessionFileHead;
31
+ //# sourceMappingURL=worker-conversation-revision.d.ts.map