@sema-agent/core 7.54.1 → 7.55.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 (399) hide show
  1. package/CHANGELOG.md +437 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cc-peer-directory.d.ts +36 -0
  5. package/dist/agents/cc-peer-directory.js +138 -0
  6. package/dist/agents/cc-peer-wire.d.ts +105 -0
  7. package/dist/agents/cc-peer-wire.js +98 -0
  8. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  9. package/dist/agents/cc-uds-peer-channel.js +457 -0
  10. package/dist/agents/cross-session-envelope.d.ts +4 -1
  11. package/dist/agents/cross-session-envelope.js +8 -1
  12. package/dist/agents/cross-session-judge.d.ts +2 -2
  13. package/dist/agents/list-agents-tool.js +2 -1
  14. package/dist/agents/observer.d.ts +4 -5
  15. package/dist/agents/observer.js +2 -1
  16. package/dist/agents/peer-admission.d.ts +6 -0
  17. package/dist/agents/peer-admission.js +4 -1
  18. package/dist/agents/peer-directory.d.ts +43 -9
  19. package/dist/agents/peer-directory.js +66 -23
  20. package/dist/agents/peer-notices.d.ts +1 -1
  21. package/dist/agents/peer-session-drain.d.ts +3 -1
  22. package/dist/agents/peer-session-drain.js +1 -0
  23. package/dist/agents/read-inbox-tool.js +2 -1
  24. package/dist/agents/retain-ledger.d.ts +1 -1
  25. package/dist/agents/roster-store.d.ts +1 -1
  26. package/dist/agents/send-message-tool.d.ts +10 -0
  27. package/dist/agents/send-message-tool.js +34 -5
  28. package/dist/agents/subagent.d.ts +34 -79
  29. package/dist/agents/subagent.js +45 -46
  30. package/dist/agents/tool-filter.d.ts +29 -46
  31. package/dist/agents/tool-filter.js +8 -31
  32. package/dist/agents/verify.d.ts +3 -3
  33. package/dist/brain/anthropic.js +14 -9
  34. package/dist/brain/errors.d.ts +15 -0
  35. package/dist/brain/errors.js +10 -0
  36. package/dist/brain/model-presets.d.ts +4 -4
  37. package/dist/brain/open-responses.js +15 -10
  38. package/dist/brain/openai.js +17 -12
  39. package/dist/brain/provider-dialect.d.ts +39 -3
  40. package/dist/brain/provider-dialect.js +28 -0
  41. package/dist/brain/reasoning.d.ts +1 -1
  42. package/dist/brain/request-params.d.ts +55 -5
  43. package/dist/brain/request-params.js +35 -3
  44. package/dist/brain/retry.d.ts +1 -1
  45. package/dist/brain/route-adjudicator.d.ts +15 -0
  46. package/dist/brain/route-adjudicator.js +15 -0
  47. package/dist/brain/stream-engine.js +6 -5
  48. package/dist/brain/stream-shared.d.ts +1 -1
  49. package/dist/core/advisor-verdict.d.ts +120 -0
  50. package/dist/core/advisor-verdict.js +92 -0
  51. package/dist/core/agent-definition.d.ts +7 -8
  52. package/dist/core/allow-entry.d.ts +49 -23
  53. package/dist/core/allow-entry.js +57 -32
  54. package/dist/core/allow-rule-shadow.d.ts +7 -0
  55. package/dist/core/approval-object.d.ts +2 -1
  56. package/dist/core/approval-object.js +6 -6
  57. package/dist/core/ask-origin.d.ts +63 -11
  58. package/dist/core/ask-origin.js +27 -5
  59. package/dist/core/ask-question.js +10 -4
  60. package/dist/core/auto-compaction.d.ts +11 -8
  61. package/dist/core/auto-compaction.js +4 -2
  62. package/dist/core/auto-mode-arming.d.ts +2 -2
  63. package/dist/core/auto-mode-defaults.d.ts +8 -8
  64. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  65. package/dist/core/auto-mode-prompt.d.ts +1 -1
  66. package/dist/core/auto-mode.d.ts +17 -9
  67. package/dist/core/auto-mode.js +9 -6
  68. package/dist/core/background-agent-store.d.ts +3 -3
  69. package/dist/core/canonical-json.d.ts +1 -1
  70. package/dist/core/canonical-json.js +2 -2
  71. package/dist/core/checkpoint-requirements.d.ts +6 -3
  72. package/dist/core/checkpoint-requirements.js +4 -14
  73. package/dist/core/checkpoint-store.d.ts +80 -51
  74. package/dist/core/checkpoint-store.js +56 -74
  75. package/dist/core/child-clamp-seats.d.ts +6 -0
  76. package/dist/core/child-clamp-seats.js +3 -16
  77. package/dist/core/compliance.d.ts +2 -2
  78. package/dist/core/context-edit.d.ts +6 -7
  79. package/dist/core/cross-boundary-taint.d.ts +9 -3
  80. package/dist/core/cross-boundary-taint.js +5 -3
  81. package/dist/core/decision-receipt.js +2 -2
  82. package/dist/core/effective-path-target.d.ts +1 -1
  83. package/dist/core/engine-notice.d.ts +19 -5
  84. package/dist/core/exec-output-tail.d.ts +1 -1
  85. package/dist/core/file-history-retention.d.ts +1 -1
  86. package/dist/core/file-history-store.d.ts +59 -9
  87. package/dist/core/file-history-store.js +35 -17
  88. package/dist/core/gate-fold.js +3 -2
  89. package/dist/core/gate-lanes.js +12 -8
  90. package/dist/core/gate-outcome.d.ts +17 -4
  91. package/dist/core/gate-outcome.js +30 -0
  92. package/dist/core/governance-codes.d.ts +13 -3
  93. package/dist/core/governance-codes.js +10 -0
  94. package/dist/core/hands-band.d.ts +1 -1
  95. package/dist/core/hooks.d.ts +4 -4
  96. package/dist/core/host-target.d.ts +49 -0
  97. package/dist/core/host-target.js +59 -0
  98. package/dist/core/image-downsample.d.ts +1 -1
  99. package/dist/core/lsp-diagnostics.d.ts +4 -4
  100. package/dist/core/lsp.d.ts +3 -3
  101. package/dist/core/mailbox-store.d.ts +4 -0
  102. package/dist/core/mcp-connection-pool.d.ts +18 -2
  103. package/dist/core/mcp-connection-pool.js +53 -6
  104. package/dist/core/mcp-failure.d.ts +23 -4
  105. package/dist/core/mcp-failure.js +26 -11
  106. package/dist/core/mcp-listing-drift.d.ts +10 -0
  107. package/dist/core/mcp-listing-drift.js +6 -0
  108. package/dist/core/mcp-server-link.d.ts +173 -0
  109. package/dist/core/mcp-server-link.js +127 -0
  110. package/dist/core/mcp-server-spec.d.ts +4 -2
  111. package/dist/core/mcp-session-end.d.ts +26 -0
  112. package/dist/core/mcp-session-end.js +29 -0
  113. package/dist/core/mcp-startup-request.d.ts +17 -0
  114. package/dist/core/mcp-startup-request.js +17 -0
  115. package/dist/core/mcp.d.ts +13 -13
  116. package/dist/core/mcp.js +187 -162
  117. package/dist/core/media-byte-cap.d.ts +1 -1
  118. package/dist/core/memory-engine/engine.d.ts +9 -9
  119. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  120. package/dist/core/memory-engine/tools.js +4 -1
  121. package/dist/core/mode-policy.d.ts +1 -1
  122. package/dist/core/namespaced-rule-name.d.ts +33 -7
  123. package/dist/core/namespaced-rule-name.js +39 -25
  124. package/dist/core/output-style.d.ts +1 -1
  125. package/dist/core/param-rule-reach.d.ts +15 -0
  126. package/dist/core/param-rule-reach.js +30 -0
  127. package/dist/core/parent-spec-seat.d.ts +8 -1
  128. package/dist/core/parent-spec-seat.js +4 -0
  129. package/dist/core/pause-registry.d.ts +16 -5
  130. package/dist/core/pause-registry.js +6 -2
  131. package/dist/core/peer-channel.d.ts +70 -0
  132. package/dist/core/peer-channel.js +1 -0
  133. package/dist/core/permission-rule-consent.d.ts +11 -5
  134. package/dist/core/permission-rule-consent.js +37 -30
  135. package/dist/core/permission-rule-model.d.ts +233 -64
  136. package/dist/core/permission-rule-model.js +384 -85
  137. package/dist/core/permission-rule-provider.d.ts +2 -1
  138. package/dist/core/permission-rule-store.d.ts +20 -25
  139. package/dist/core/permission-rule-store.js +1 -4
  140. package/dist/core/permission-rule-sync.d.ts +11 -2
  141. package/dist/core/permission-rule-sync.js +8 -1
  142. package/dist/core/permission-rules.d.ts +49 -11
  143. package/dist/core/permission-rules.js +123 -89
  144. package/dist/core/persisted-rule-arms.d.ts +4 -2
  145. package/dist/core/present-plan-tool.js +3 -1
  146. package/dist/core/protocol-naming.d.ts +2 -2
  147. package/dist/core/read-only-shell-table.d.ts +1 -1
  148. package/dist/core/read-only-shell.d.ts +1 -1
  149. package/dist/core/roles.d.ts +6 -2
  150. package/dist/core/roles.js +45 -44
  151. package/dist/core/rule-offer-read.d.ts +53 -0
  152. package/dist/core/rule-offer-read.js +146 -0
  153. package/dist/core/rule-owner.d.ts +46 -0
  154. package/dist/core/rule-owner.js +28 -0
  155. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  156. package/dist/core/runner/advisor-instructions.js +61 -0
  157. package/dist/core/runner/advisor-tool.d.ts +33 -0
  158. package/dist/core/runner/advisor-tool.js +112 -0
  159. package/dist/core/runner/announce-once-ledger.d.ts +4 -26
  160. package/dist/core/runner/announce-once-ledger.js +14 -46
  161. package/dist/core/runner/approval-feedback.js +6 -3
  162. package/dist/core/runner/assemble-result.d.ts +1 -1
  163. package/dist/core/runner/caller-roster.d.ts +7 -0
  164. package/dist/core/runner/caller-roster.js +11 -0
  165. package/dist/core/runner/classifier-ladder.d.ts +27 -5
  166. package/dist/core/runner/classifier-ladder.js +12 -11
  167. package/dist/core/runner/compaction-restate.d.ts +10 -6
  168. package/dist/core/runner/compaction-restate.js +9 -3
  169. package/dist/core/runner/contracts.d.ts +13 -9
  170. package/dist/core/runner/conversation-segment.d.ts +28 -0
  171. package/dist/core/runner/conversation-segment.js +42 -0
  172. package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
  173. package/dist/core/runner/cross-boundary-lane.js +26 -15
  174. package/dist/core/runner/decide-continuation.d.ts +7 -4
  175. package/dist/core/runner/decide-continuation.js +2 -2
  176. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  177. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  178. package/dist/core/runner/derived-route-fallback.js +9 -7
  179. package/dist/core/runner/gate-exit.d.ts +6 -0
  180. package/dist/core/runner/gate-exit.js +7 -2
  181. package/dist/core/runner/initial-run-state.js +1 -1
  182. package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
  183. package/dist/core/runner/permission-rule-lanes.js +14 -7
  184. package/dist/core/runner/person-path-rows.js +1 -1
  185. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  186. package/dist/core/runner/prepare-advisor.js +77 -0
  187. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  188. package/dist/core/runner/prepare-config-doors.d.ts +6 -4
  189. package/dist/core/runner/prepare-config-doors.js +18 -12
  190. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  191. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  192. package/dist/core/runner/prepare-file-history.js +39 -39
  193. package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
  194. package/dist/core/runner/prepare-gate-stations.js +2 -7
  195. package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
  196. package/dist/core/runner/prepare-inherited-gate.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.js +7 -7
  198. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  199. package/dist/core/runner/prepare-policy-chain.js +4 -10
  200. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  201. package/dist/core/runner/prepare-project-context.js +6 -3
  202. package/dist/core/runner/prepare-prompt-inputs.js +1 -1
  203. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
  204. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  205. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  206. package/dist/core/runner/prepare-safety-scan.js +8 -6
  207. package/dist/core/runner/prepare-task.js +15 -18
  208. package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
  209. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
  210. package/dist/core/runner/prepare-wiring-manifest.js +2 -2
  211. package/dist/core/runner/resume-policy-outcome.js +1 -1
  212. package/dist/core/runner/retired-runner-deps.js +1 -1
  213. package/dist/core/runner/run-attachment-seats.js +0 -1
  214. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  215. package/dist/core/runner/run-compaction-machinery.js +2 -12
  216. package/dist/core/runner/run-git-lane.d.ts +1 -0
  217. package/dist/core/runner/run-harness-handlers.js +2 -3
  218. package/dist/core/runner/run-leg.js +13 -0
  219. package/dist/core/runner/run-settle-and-teardown.js +1 -1
  220. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  221. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  222. package/dist/core/runner/run-turn-boundary.js +14 -12
  223. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  224. package/dist/core/runner/session-rule-policy.js +13 -28
  225. package/dist/core/runner/side-call-account.d.ts +32 -8
  226. package/dist/core/runner/side-call-account.js +23 -1
  227. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  228. package/dist/core/runner/sub-agent-deny-lists.js +4 -3
  229. package/dist/core/runner/synthetic-tools.d.ts +10 -13
  230. package/dist/core/runner/synthetic-tools.js +4 -2
  231. package/dist/core/runner/tool-disclosure.js +2 -1
  232. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  233. package/dist/core/runner/tool-face-overlay.js +17 -1
  234. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  235. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  236. package/dist/core/runner/turn-attachments.d.ts +60 -67
  237. package/dist/core/runner-deps.d.ts +37 -37
  238. package/dist/core/runtime-caps.d.ts +4 -4
  239. package/dist/core/safety-merge-corpus.js +17 -1
  240. package/dist/core/same-plain-value.d.ts +40 -0
  241. package/dist/core/same-plain-value.js +49 -0
  242. package/dist/core/scheduler.d.ts +1 -1
  243. package/dist/core/sensitive-path-policy.d.ts +1 -1
  244. package/dist/core/sensitive-path-policy.js +1 -1
  245. package/dist/core/session-policy-store.d.ts +77 -22
  246. package/dist/core/session-policy-store.js +56 -14
  247. package/dist/core/session-reconcile.d.ts +2 -2
  248. package/dist/core/session-store.d.ts +80 -30
  249. package/dist/core/session-store.js +118 -76
  250. package/dist/core/session.d.ts +24 -46
  251. package/dist/core/shared-memory/tools.js +3 -1
  252. package/dist/core/shared-memory/types.d.ts +1 -1
  253. package/dist/core/side-query.d.ts +10 -0
  254. package/dist/core/side-query.js +5 -0
  255. package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
  256. package/dist/core/store-contracts/file-history-store-contract.js +43 -3
  257. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  258. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  259. package/dist/core/store-contracts/session-repo-contract.js +125 -0
  260. package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
  261. package/dist/core/store-contracts/session-store-contract.js +215 -41
  262. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  263. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  264. package/dist/core/task-event.d.ts +10 -4
  265. package/dist/core/task-notification.d.ts +3 -3
  266. package/dist/core/task-registry-agent.d.ts +4 -4
  267. package/dist/core/task-registry-shared.d.ts +4 -4
  268. package/dist/core/task-registry-shared.js +1 -0
  269. package/dist/core/task-registry.d.ts +4 -4
  270. package/dist/core/task-registry.js +3 -1
  271. package/dist/core/task-result.d.ts +3 -3
  272. package/dist/core/task-spec.d.ts +52 -52
  273. package/dist/core/task-stream.d.ts +6 -6
  274. package/dist/core/task-tool-shape.d.ts +4 -4
  275. package/dist/core/tighten-task-spec.d.ts +1 -1
  276. package/dist/core/tool-catalog-entries.d.ts +19 -2
  277. package/dist/core/tool-catalog-entries.js +57 -42
  278. package/dist/core/tool-conformance.js +1 -0
  279. package/dist/core/tool-errors.d.ts +2 -2
  280. package/dist/core/tool-face-reader.js +5 -3
  281. package/dist/core/tool-face.d.ts +21 -2
  282. package/dist/core/tool-face.js +1 -1
  283. package/dist/core/tool-model-gate.d.ts +3 -3
  284. package/dist/core/tool-name-aliases.d.ts +29 -8
  285. package/dist/core/tool-name-aliases.js +27 -3
  286. package/dist/core/tool-name-readings.d.ts +5 -8
  287. package/dist/core/tool-name-readings.js +1 -2
  288. package/dist/core/tool-policy.d.ts +24 -5
  289. package/dist/core/tool-policy.js +34 -10
  290. package/dist/core/tool-registry.d.ts +14 -7
  291. package/dist/core/tool-registry.js +17 -7
  292. package/dist/core/tool-result-store.js +2 -1
  293. package/dist/core/tool-roster.d.ts +47 -18
  294. package/dist/core/tool-roster.js +53 -32
  295. package/dist/core/tool-spec-members.js +1 -1
  296. package/dist/core/tool-spec.d.ts +35 -21
  297. package/dist/core/tools.js +3 -2
  298. package/dist/core/trace.d.ts +4 -0
  299. package/dist/core/untrusted-egress.d.ts +1 -1
  300. package/dist/core/untrusted-text.d.ts +1 -1
  301. package/dist/core/warm-resume.d.ts +1 -1
  302. package/dist/core/wiring-manifest.d.ts +49 -0
  303. package/dist/core/wiring-manifest.js +13 -5
  304. package/dist/core/workflow-journal-store.d.ts +62 -0
  305. package/dist/core/workflow-journal-store.js +77 -1
  306. package/dist/core/workflow-run-store.d.ts +6 -0
  307. package/dist/core/workflow-run-store.js +2 -0
  308. package/dist/engine/compaction/compaction.d.ts +9 -9
  309. package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
  310. package/dist/engine/execution-env/node-execution-env.js +43 -22
  311. package/dist/engine/harness/agent-harness.d.ts +14 -8
  312. package/dist/engine/harness/agent-harness.js +33 -26
  313. package/dist/engine/harness/types.d.ts +29 -7
  314. package/dist/engine/harness/types.js +12 -1
  315. package/dist/engine/llm/types.d.ts +9 -9
  316. package/dist/engine/llm/validation.d.ts +4 -1
  317. package/dist/engine/llm/validation.js +13 -1
  318. package/dist/engine/loop/agent-loop.d.ts +1 -1
  319. package/dist/engine/loop/agent-loop.js +10 -8
  320. package/dist/engine/loop/types.d.ts +15 -13
  321. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  322. package/dist/engine/session/memory-repo.d.ts +10 -11
  323. package/dist/engine/session/memory-repo.js +13 -8
  324. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  325. package/dist/engine/session/parent-chain-guard.js +1 -1
  326. package/dist/engine/session/repo-utils.d.ts +31 -3
  327. package/dist/engine/session/repo-utils.js +42 -5
  328. package/dist/index.d.ts +27 -15
  329. package/dist/index.js +21 -11
  330. package/dist/internal/harness-types.d.ts +1 -1
  331. package/dist/internal/harness.d.ts +3 -3
  332. package/dist/internal/harness.js +2 -2
  333. package/dist/internal/llm.d.ts +1 -1
  334. package/dist/internal/llm.js +1 -1
  335. package/dist/orchestration/goal.js +2 -2
  336. package/dist/orchestration/run-workflow-tool.d.ts +2 -2
  337. package/dist/orchestration/run-workflow-tool.js +5 -3
  338. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  339. package/dist/orchestration/workflow-types.d.ts +18 -0
  340. package/dist/orchestration/workflow-types.js +6 -0
  341. package/dist/orchestration/workflow.d.ts +2 -13
  342. package/dist/orchestration/workflow.js +21 -31
  343. package/dist/prompt-assembly/event-registry.js +1 -0
  344. package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
  345. package/dist/prompt-assembly/tool-catalog.js +3 -0
  346. package/dist/prompts/default.d.ts +14 -14
  347. package/dist/scenarios/full-body.d.ts +4 -4
  348. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  349. package/dist/stores/file/adoption/adopt.js +24 -31
  350. package/dist/stores/file/adoption/marker.d.ts +6 -13
  351. package/dist/stores/file/adoption/marker.js +6 -15
  352. package/dist/stores/file/checkpoint-store.d.ts +3 -0
  353. package/dist/stores/file/checkpoint-store.js +9 -3
  354. package/dist/stores/file/file-history-store.d.ts +20 -19
  355. package/dist/stores/file/file-history-store.js +152 -135
  356. package/dist/stores/file/fs-atomic.d.ts +15 -0
  357. package/dist/stores/file/fs-atomic.js +89 -14
  358. package/dist/stores/file/index.d.ts +1 -1
  359. package/dist/stores/file/mailbox-store.d.ts +3 -0
  360. package/dist/stores/file/mailbox-store.js +3 -1
  361. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  362. package/dist/stores/file/permission-rule-adopt.js +15 -16
  363. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  364. package/dist/stores/file/permission-rule-store.js +21 -14
  365. package/dist/stores/file/session-policy-store.d.ts +3 -3
  366. package/dist/stores/file/session-store.d.ts +26 -11
  367. package/dist/stores/file/session-store.js +77 -40
  368. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  369. package/dist/stores/file/workflow-journal-store.js +28 -13
  370. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  371. package/dist/tools/artifact/artifact-tool.js +2 -1
  372. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  373. package/dist/tools/fs/fs-bash.d.ts +2 -2
  374. package/dist/tools/fs/fs-bash.js +3 -1
  375. package/dist/tools/fs/fs-shared.d.ts +8 -8
  376. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  377. package/dist/tools/fs/notebook.d.ts +2 -2
  378. package/dist/tools/fs/read-deny.d.ts +29 -7
  379. package/dist/tools/fs/read-deny.js +63 -22
  380. package/dist/tools/fs/removal-targets.d.ts +1 -1
  381. package/dist/tools/fs/safety.d.ts +9 -9
  382. package/dist/tools/fs/search.d.ts +6 -6
  383. package/dist/tools/fs/shell-read-check.js +6 -1
  384. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  385. package/dist/tools/fs/shell-read-judge.js +5 -2
  386. package/dist/tools/loop-tick.d.ts +2 -2
  387. package/dist/tools/scheduler-tools.js +5 -1
  388. package/dist/tools/task-list.d.ts +7 -7
  389. package/dist/tools/task-list.js +5 -1
  390. package/dist/tools/todo.js +2 -1
  391. package/dist/tools/web.d.ts +1 -1
  392. package/dist/tools/web.js +40 -37
  393. package/dist/tools/worktree.d.ts +3 -3
  394. package/dist/tools/worktree.js +3 -1
  395. package/package.json +1 -1
  396. package/test/export-surface.snapshot.json +5756 -5638
  397. package/wire-changes/core@7.55.0.json +3318 -0
  398. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  399. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -12,14 +12,14 @@ import { GENERAL_PURPOSE_SUBAGENT_TYPE, markerFragment } from "../agents/subagen
12
12
  import { deploymentSubagentSystemPrompt, runnerRoleMap } from "../agents/child-model-seat.js";
13
13
  import { combinePolicies, createAllowDenyPolicy } from "../core/tool-policy.js";
14
14
  import { createSafeNotifier } from "../core/safe-notify.js";
15
- import { callKeyOrdinal, oversizeJournalResult, journalOversizeTombstone, JOURNAL_OVERSIZE_ERROR_CODE, MAX_JOURNAL_RESULT_BYTES } from "../core/workflow-journal-store.js";
15
+ import { callKeyOrdinal, clampRunIdText, oversizeJournalResult, journalOversizeTombstone, readWorkflowJournalEntry, JOURNAL_OVERSIZE_ERROR_CODE, MAX_JOURNAL_RESULT_BYTES, WorkflowJournalIncompatibleError, } from "../core/workflow-journal-store.js";
16
16
  import { isWorkflowRunActive, closeWorkflowChannel, markWorkflowActive, publishWorkflowEvent } from "./workflow-observe.js";
17
17
  import { isDurablePause } from "../agents/suspend-guard.js";
18
18
  import { RUNNING_AGENT_OBSERVE_EVERY_BEATS } from "../config/defaults.js";
19
19
  import { boundInputHashOf } from "../core/canonical-json.js";
20
20
  import { boundedRedactedSummary, egressThrownText } from "../core/untrusted-egress.js";
21
21
  import { delimitUntrusted } from "../core/untrusted-text.js";
22
- import { OUTPUT_TOOL_NAME } from "../core/runner/synthetic-tools.js";
22
+ import { OUTPUT_TOOL_NAME } from "../core/tool-catalog-entries.js";
23
23
  import { deniedToolNamesOf, judgeHostToolCeiling } from "../core/runner/sub-agent-deny-lists.js";
24
24
  import { compileOutputSchema } from "../core/runner/strict-output-schema.js";
25
25
  import { WorkflowBudgetExceededError, WorkflowNestingError, WorkflowAgentBlockedError, WorkflowAgentParkedError, WorkflowAgentSchemaError, WorkflowAgentStalledError, WorkflowMaxAgentsError, WORKFLOW_SPAWN_BLOCKED_ERROR_CODE } from "./workflow-types.js";
@@ -142,7 +142,7 @@ function withWorkflowChildSeats(typed, inheritedModelSnap, inheritedThinkingSnap
142
142
  const statedPersona = deploymentSubagentSystemPrompt(roles);
143
143
  return {
144
144
  ...typed,
145
- modelRole: typed.modelRole ?? "subagent",
145
+ modelRole: typed.modelRole === undefined ? "subagent" : typed.modelRole,
146
146
  ...(typed.model === undefined && inheritedModelSnap !== undefined ? { model: inheritedModelSnap } : {}),
147
147
  ...(typed.thinking === undefined && inheritedThinkingSnap !== undefined ? { thinking: inheritedThinkingSnap } : {}),
148
148
  ...(typed.systemPrompt === undefined && statedPersona !== undefined ? { systemPrompt: statedPersona } : {}),
@@ -229,17 +229,14 @@ export class WorkflowResultTooLargeError extends Error {
229
229
  this.name = "WorkflowResultTooLargeError";
230
230
  }
231
231
  }
232
- export class WorkflowJournalIncompatibleError extends Error {
233
- fromRunId;
234
- ordinal;
235
- code = "workflow.journal_incompatible";
236
- constructor(fromRunId, ordinal) {
237
- super(`startWorkflow: resume from "${fromRunId}" was REFUSED — journal entry #${ordinal} carries no terminal cause (a journal written before TaskResult.terminal, or a malformed entry). ` +
238
- "Completed work must not run again; start a fresh run instead of resuming this journal.");
239
- this.fromRunId = fromRunId;
240
- this.ordinal = ordinal;
241
- this.name = "WorkflowJournalIncompatibleError";
242
- }
232
+ function judgedJournal(runId, rows) {
233
+ return rows.map((raw) => {
234
+ const read = readWorkflowJournalEntry(raw);
235
+ if (!("corrupt" in read))
236
+ return read.entry;
237
+ const callKey = raw?.callKey;
238
+ throw new WorkflowJournalIncompatibleError(runId, typeof callKey === "string" ? callKeyOrdinal(callKey) : -1, raw);
239
+ });
243
240
  }
244
241
  export class WorkflowJournalAppendTimeoutError extends Error {
245
242
  runId;
@@ -475,9 +472,6 @@ function createSemaphore(max) {
475
472
  }),
476
473
  };
477
474
  }
478
- function clampRunIdText(raw) {
479
- return raw.replace(/[^A-Za-z0-9_.:-]/g, "").slice(0, 64);
480
- }
481
475
  const fallbackResumeClaimTables = new WeakMap();
482
476
  function fallbackResumeClaimKey(scope, sourceRunId) {
483
477
  return JSON.stringify([scope, sourceRunId]);
@@ -933,7 +927,9 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
933
927
  if (key.originRunId === opts.resumeFromRunId)
934
928
  entry = replayByOrdinal[ordinal];
935
929
  else if (journalStore) {
936
- const loaded = await finalizeWithin(timers, new Promise((resolve) => resolve(journalStore.load(key.originRunId, scope))).then((entries) => ({ entries }), (err) => ({ err })), "timeout");
930
+ const loaded = await finalizeWithin(timers, new Promise((resolve) => resolve(journalStore.load(key.originRunId, scope)))
931
+ .then((rows) => ({ entries: judgedJournal(key.originRunId, rows) }))
932
+ .catch((err) => ({ err })), "timeout");
937
933
  if (loaded === "timeout" || "err" in loaded) {
938
934
  emitRunLog(`resume: the journal of run "${clampRunIdText(key.originRunId)}" (the origin of the park at ordinal ${ordinal}) could not be read (${loaded === "timeout" ? `the load did not settle within ${WORKFLOW_RESUME_CLAIM_FINALIZE_TIMEOUT_MS}ms` : withoutToken(errText(loaded.err), key.token)}).`);
939
935
  }
@@ -2299,22 +2295,16 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
2299
2295
  "re-run the whole suffix live, duplicating every side effect. Wait for the holder to reach a terminal " +
2300
2296
  "state (or stop it) and resume again.");
2301
2297
  }
2302
- const entries = await journalStore.load(opts.resumeFromRunId, scope);
2298
+ const entries = judgedJournal(opts.resumeFromRunId, await journalStore.load(opts.resumeFromRunId, scope));
2303
2299
  for (const e of entries) {
2304
- const parked = e.parked;
2305
- if (parked !== undefined) {
2306
- const pt = parked?.terminal;
2307
- if (pt === null || typeof pt !== "object" || pt.kind !== "paused" || typeof pt.token !== "string" || pt.token.length === 0) {
2308
- throw new WorkflowJournalIncompatibleError(clampRunIdText(opts.resumeFromRunId), callKeyOrdinal(e.callKey));
2300
+ const ordinal = callKeyOrdinal(e.callKey);
2301
+ if (e.parked === undefined) {
2302
+ const t = e.result.terminal;
2303
+ if (t === null || typeof t !== "object" || !isTerminalCauseKind(t.kind)) {
2304
+ throw new WorkflowJournalIncompatibleError(opts.resumeFromRunId, ordinal);
2309
2305
  }
2310
- replayByOrdinal[callKeyOrdinal(e.callKey)] = e;
2311
- continue;
2312
- }
2313
- const t = e.result?.terminal;
2314
- if (t === null || typeof t !== "object" || !isTerminalCauseKind(t.kind)) {
2315
- throw new WorkflowJournalIncompatibleError(clampRunIdText(opts.resumeFromRunId), callKeyOrdinal(e.callKey));
2316
2306
  }
2317
- replayByOrdinal[callKeyOrdinal(e.callKey)] = e;
2307
+ replayByOrdinal[ordinal] = e;
2318
2308
  }
2319
2309
  const fromRunId = clampRunIdText(opts.resumeFromRunId);
2320
2310
  let prior = null;
@@ -20,6 +20,7 @@ export const EVENT_PROMPT_REGISTRY = new Map([
20
20
  { kind: "limit_approach_converge", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "run-turn-boundary.ts#limitApproachFrames" },
21
21
  { kind: "limit_approach_deliver", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "run-turn-boundary.ts#limitApproachFrames" },
22
22
  { kind: "final_verification", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "runtask.ts#final-verification" },
23
+ { kind: "advisor_tool", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "always", rendererRef: "advisor-instructions.ts#advisorInstructionFrame" },
23
24
  ].map((e) => [e.kind, e]));
24
25
  export function eventDefaultOn(kind) {
25
26
  return EVENT_PROMPT_REGISTRY.get(kind)?.defaultPolicy === "on";
@@ -4,6 +4,9 @@ import type { ProtocolId } from "../core/protocol-table.js";
4
4
  /** The protocol slice comes from the protocol table — adding a protocol extends ProtocolId and this
5
5
  * union follows automatically (the origin projection is table-driven, prepare-task). */
6
6
  export type ToolOrigin = "core" | "caller" | "synthetic" | ProtocolId;
7
+ /** The origin a declared contract id names: a `core.` id is one of the engine's own contracts, any other id a caller's. The one
8
+ * reading of the prefix — the definition factory attaches by it, and the caller-tool door refuses a caller spec that declares one. */
9
+ export declare function contractOriginOf(contractId: string): "core" | "caller";
7
10
  export interface ToolContractDescriptor {
8
11
  /** Stable contract identity, e.g. `core.read@2`. Versioned independently of the wire name. */
9
12
  contractId: string;
@@ -1,4 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
+ export function contractOriginOf(contractId) {
3
+ return contractId.startsWith("core.") ? "core" : "caller";
4
+ }
2
5
  const PRESENTATION_KEYWORDS = new Set(["description", "title", "examples", "$id"]);
3
6
  const SCHEMA_NAME_MAPS = new Set([
4
7
  "properties",
@@ -17,7 +17,7 @@ export declare const SUBAGENT_DELIVERY_NOTES: string;
17
17
  /**
18
18
  * Memory **safety** rules — a STANDALONE prompt asset, NOT injected by core. The flag-driven injection
19
19
  * (`memoryEnabled`/`consolidationEnabled` → a `memory.safety` constitution block) was retired in
20
- * RB-482 #16 along with both flags; the engine now injects the CC-verbatim `# Memory` instruction via
20
+ * RB-482 #16 along with both flags; the engine now injects the `# Memory` instruction via
21
21
  * the memory engine's `injection.block` instead. A deployment composing its own prompt is responsible
22
22
  * for including this block, and should treat it as non-suppressible: it carries the load-bearing
23
23
  * constraints (declarative-fact-not-command + the no-secrets rule + the
@@ -71,8 +71,8 @@ export declare const EXECUTION_ENVIRONMENT_OPEN_READS: string;
71
71
  /** The isolated-worktree notice, composed only when the task really runs in an isolated git worktree. */
72
72
  export declare const WORKTREE_NOTICE: string;
73
73
  /**
74
- * RB-314 — CC 2.1.220 `atp` (@597127 (cli250.js:44534)) VERBATIM. Rides the variable `# Environment` tail (see
75
- * {@link buildEnvironmentContext}), which is exactly where 220 emits it: both env-block assemblers
74
+ * RB-314 — Rides the variable `# Environment` tail (see
75
+ * {@link buildEnvironmentContext}), which is exactly where the reference emits it: both env-block assemblers
76
76
  * (@596927 `IMy`, @596976 `OMy`) push `worktree ? atp : null` directly after the isolated-copy
77
77
  * directive. Deliberately NOT folded into {@link WORKTREE_NOTICE}: that block is composed only for
78
78
  * `isolation: "worktree"` spawns, while the hazard belongs to ANY run whose cwd is a linked worktree
@@ -120,7 +120,7 @@ export interface EnvironmentFacts {
120
120
  /** design/99 §E14 — the working tree's toplevel (`git rev-parse --show-toplevel`). Lets the agent/shell know
121
121
  * it may be in a linked worktree rather than the main checkout. */
122
122
  gitWorktreeRoot?: string;
123
- /** design/119 (CC 198): cwd is a LINKED git worktree (git-dir ≠ git-common-dir) — an isolated copy. */
123
+ /** design/119: cwd is a LINKED git worktree (git-dir ≠ git-common-dir) — an isolated copy. */
124
124
  isLinkedWorktree?: boolean;
125
125
  /** design/119 (CC --add-dir parity): extra directories the file tools may access (canonical). */
126
126
  additionalDirectories?: readonly string[];
@@ -164,7 +164,7 @@ export interface EnvironmentFacts {
164
164
  /** A1 — outbound-network posture; `none` renders an explicit downloads-will-fail caveat (TB
165
165
  * autopsy 2026-07-05: agents burned budget retrying downloads in a no-egress sandbox). */
166
166
  sandboxEgress?: "none" | "allowlist" | "full";
167
- /** H4 (CC 2.1.198 git snapshot) — the pre-rendered {@link buildGitSnapshot} block. env-tail
167
+ /** H4 — the pre-rendered {@link buildGitSnapshot} block. env-tail
168
168
  * migration (#254 shape): NO LONGER RENDERED by {@link buildEnvironmentContext} — the snapshot is
169
169
  * the turn-dynamic git view and rides the `git_status` frame (re-sent only when the rendered view
170
170
  * changes); the field remains as a structured data carrier for callers that assembled it. */
@@ -185,17 +185,17 @@ export interface EnvironmentFacts {
185
185
  * it twice could drift). Renders ONE neutral declarative line; absent ⇒ nothing renders.
186
186
  */
187
187
  externalContentTarget?: boolean;
188
- /** CC 2.1.198 `MZn` Scratchpad port (system-prompt diff 档 2026-07-08 §13, 活体逐字双证) — the
188
+ /** Scratchpad port — the
189
189
  * session-scoped temp directory the agent should use instead of `/tmp` (parallel tasks/multi-tenant
190
190
  * deployments clobber each other's `/tmp`; project checkouts collect stray temp files without it).
191
191
  * DEPLOYMENT-supplied, and only injected when set — the deployment MUST have created (or be about to
192
- * create) the directory; core renders the CC-verbatim section with this path interpolated (§6.3:
192
+ * create) the directory; core renders the section with this path interpolated (§6.3:
193
193
  * never advertise a directory the task doesn't have). */
194
194
  scratchpadDir?: string;
195
195
  }
196
196
  /**
197
- * CC 2.1.198 `# Scratchpad Directory` section (bundle `MZn`, L590674; 活体 2026-07-08 byte-match) with the
198
- * path parameterized for the deployment. Wording is verbatim CC — including the closing permission-prompts
197
+ * The `# Scratchpad Directory` section with the
198
+ * path parameterized for the deployment. Wording as in the reference — including the closing permission-prompts
199
199
  * sentence, which holds for sema too (an approval-gated deployment normally allowlists its own scratchpad) —
200
200
  * PLUS one sema-added ephemerality sentence (ruled 2026-08-05): sema deployments run under durable suspend /
201
201
  * multi-replica serving where the scratchpad is a local-disk copy that does NOT survive a cross-replica
@@ -204,22 +204,22 @@ export interface EnvironmentFacts {
204
204
  * in a directory that can vanish mid-task. Volatility magnitude only — no serving-layer mechanism names.
205
205
  */
206
206
  export declare function buildScratchpadSection(scratchpadDir: string): string;
207
- /** CC 2.1.198 `Juo` — the git status truncation bound (chars) for {@link buildGitSnapshot}. */
207
+ /** The git status truncation bound (chars) for {@link buildGitSnapshot}. */
208
208
  export declare const GIT_STATUS_MAX_CHARS = 2000;
209
- /** The CC-verbatim first paragraph of the git snapshot (CC 2.1.198 `Quo` head sentence). Kept as a
209
+ /** The first paragraph of the git snapshot. Kept as a
210
210
  * named constant so the git-status FRAME renderer (the snapshot's carrier since the env-tail
211
211
  * migration) can swap exactly this paragraph for its own update-semantics preamble — under the
212
212
  * frame protocol the snapshot IS re-sent when the visible view changes, so the "will not update"
213
213
  * claim would be false there. {@link buildGitSnapshot} itself still renders it byte-exact. */
214
214
  export declare const GIT_SNAPSHOT_CC_PREAMBLE = "This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.";
215
215
  /**
216
- * H4 — the CC 2.1.198 ENV git snapshot block (B1/B2; template + truncation copy verified against
217
- * observed Claude Code v2.1.198 behavior). Pure renderer — the Runner gathers the raw values through the
216
+ * H4 — the ENV git snapshot block (B1/B2).
217
+ * Pure renderer — the Runner gathers the raw values through the
218
218
  * ExecutionEnv seam (remote = the container's repo) and calls this once per prepareTask (a durable
219
219
  * resume re-prepares → re-snapshots, CC new-session 同型). env-tail migration (#254 shape): the
220
220
  * rendered block now feeds the `git_status` TURN FRAME (src/core/runner/git-status-frame.ts, which
221
221
  * swaps the {@link GIT_SNAPSHOT_CC_PREAMBLE} for an update-semantics preamble) instead of the
222
- * `# Environment` system-prompt section — the template body itself stays CC-verbatim.
222
+ * `# Environment` system-prompt section — the template body itself is unchanged.
223
223
  *
224
224
  * Sanitization (deliberate CC deviation — CC injects raw): status/log/branch/user are REPO-controlled
225
225
  * text (filenames, commit subjects, an untrusted clone's config) landing in the TRUSTED prompt region →
@@ -27,7 +27,7 @@ export interface CodeToolsConfig {
27
27
  * general-purpose delegation). Pass an explicit `systemPrompt` here to override. */
28
28
  subagent?: SubagentToolOptions;
29
29
  /**
30
- * TodoWrite (CONTEXT leg). Default true, BUT mutually exclusive with the task-list family (CC 209
30
+ * TodoWrite (CONTEXT leg). Default true, BUT mutually exclusive with the task-list family (
31
31
  * parity: TodoWrite is enabled only when the task list is off). With `taskList` on (the default),
32
32
  * TodoWrite is NOT mounted even when `todoWrite: true` is set explicitly — the exclusion gate wins;
33
33
  * pass `taskList: false` to get TodoWrite back. `todoWrite: false` always drops it.
@@ -36,8 +36,8 @@ export interface CodeToolsConfig {
36
36
  */
37
37
  todoWrite?: boolean;
38
38
  /**
39
- * design/119 → CC209 对齐批B B3: the structured task-list family (TaskCreate/TaskGet/TaskUpdate/
40
- * TaskList — stable ids, status transitions, dependencies). Default TRUE (CC 209 alignment: the task
39
+ * design/119 → B3: the structured task-list family (TaskCreate/TaskGet/TaskUpdate/
40
+ * TaskList — stable ids, status transitions, dependencies). Default TRUE (the task
41
41
  * list is on unless explicitly disabled, and TodoWrite is its off-state fallback — the two families
42
42
  * are mutually exclusive, never co-mounted). Only an explicit `taskList: false` reverts to the
43
43
  * TodoWrite shape.
@@ -47,7 +47,7 @@ export interface CodeToolsConfig {
47
47
  */
48
48
  taskList?: boolean;
49
49
  /**
50
- * design/147 §6 D2 (CC 2.1.216 shared team task list): a shared {@link TaskListStore} for the
50
+ * design/147 §6 D2 (shared team task list): a shared {@link TaskListStore} for the
51
51
  * task-list family. Mount the SAME instance into each teammate's bundle to share one team task
52
52
  * list (the `owner` claim semantics come alive); absent ⇒ the private per-run list (unchanged
53
53
  * default). Ignored when `taskList: false`. This bundle's own Agent children share it by inheritance.
@@ -56,7 +56,8 @@
56
56
  * file half ships the freeze face, the acceptance face and the rebind legs.
57
57
  */
58
58
  import type { PermissionRuleSyncTransport } from "../../../core/permission-rule-sync.js";
59
- import { type AdoptionReceipt, type AdoptionSource, type AffectedDeploymentConfig } from "./marker.js";
59
+ import { type AdoptionReceipt, type AffectedDeploymentConfig } from "./marker.js";
60
+ import { type RuleOwner } from "../../../core/rule-owner.js";
60
61
  /** The per-leg context handed to a carriage leg: rows the far side REFUSES go here — preserved and
61
62
  * disclosed, never deleted (design/183 §7.2). Quarantining never fails the leg. */
62
63
  export interface AdoptionCarriageLegContext {
@@ -79,7 +80,7 @@ export interface AdoptionCarriageLeg {
79
80
  export interface AdoptLocalDataRootOptions {
80
81
  /** The data root (the directory `FileStorageBackend` and the independent file stores build over). */
81
82
  root: string;
82
- from: AdoptionSource;
83
+ from: RuleOwner;
83
84
  toPrincipal: string;
84
85
  /** The claim REFERENCE for the new identity's credentials (minted by the server; design/183 §4.3).
85
86
  * A reference, never the credential bytes — the marker file is a plain-text sidecar. */
@@ -141,7 +142,7 @@ export type AdoptionStatus = {
141
142
  state: "none";
142
143
  } | {
143
144
  state: "in-flight";
144
- from: AdoptionSource;
145
+ from: RuleOwner;
145
146
  toPrincipal: string;
146
147
  phase: 2 | 3 | 4 | 5;
147
148
  } | {
@@ -7,6 +7,7 @@ import { SESSION_POLICY_MARK_SUFFIX, attributeSessionPolicyRow, judgeSessionPoli
7
7
  import { SessionPolicyError } from "../../../core/session-policy-store.js";
8
8
  import { thrownText } from "../../../core/thrown-value.js";
9
9
  import { AdoptionError, NOT_MIGRATED_BY_DESIGN, readRootAdoptionFile, writeRootAdoptionFile, } from "./marker.js";
10
+ import { readRuleOwner, ruleOwnerText, sameRuleOwner } from "../../../core/rule-owner.js";
10
11
  const CONFIG_ACCOUNT_FILE = "adoption-configs.json";
11
12
  function baselineConfigs(toPrincipal) {
12
13
  return [
@@ -282,12 +283,6 @@ const ZERO_ACTION_STORES = [
282
283
  ];
283
284
  const SESSION_POLICY_LEG = "session-policy";
284
285
  const CARRIAGE_BIT_PREFIX = "carriage:";
285
- function sameSource(a, b) {
286
- return a.kind === "principal" ? b.kind === "principal" && a.principal === b.principal : b.kind === "local-owner";
287
- }
288
- function sourceText(o) {
289
- return o.kind === "principal" ? `principal "${o.principal}"` : "the local owner";
290
- }
291
286
  function receiptFromTerminal(root, adopted) {
292
287
  const account = readConfigAccountEvidence(root);
293
288
  const accountBinds = account !== undefined && account.adoptionId === adopted.immutableReport.adoptionId;
@@ -325,13 +320,13 @@ function answerFromExisting(root, existing, from, toPrincipal) {
325
320
  if (existing === undefined)
326
321
  return undefined;
327
322
  if ("adopted" in existing) {
328
- if (existing.adopted.toPrincipal === toPrincipal && sameSource(existing.adopted.from, from)) {
323
+ if (existing.adopted.toPrincipal === toPrincipal && sameRuleOwner(existing.adopted.from, from)) {
329
324
  return receiptFromTerminal(root, existing.adopted);
330
325
  }
331
- throw new AdoptionError("adoption_retarget", `this data root already carries a completed adoption (${sourceText(existing.adopted.from)} → "${existing.adopted.toPrincipal}") — ` +
326
+ throw new AdoptionError("adoption_retarget", `this data root already carries a completed adoption (${ruleOwnerText(existing.adopted.from)} → "${existing.adopted.toPrincipal}") — ` +
332
327
  `a second adoption of the same root is a multi-tenant transfer, not a shape this protocol supports`);
333
328
  }
334
- if (existing.marker.toPrincipal !== toPrincipal || !sameSource(existing.marker.from, from)) {
329
+ if (existing.marker.toPrincipal !== toPrincipal || !sameRuleOwner(existing.marker.from, from)) {
335
330
  throw new AdoptionError("adoption_in_flight_mismatch", `an adoption toward "${existing.marker.toPrincipal}" is already in flight in this data root (phase ${existing.marker.phase}) — ` +
336
331
  `refusing to start a different one (resume the original, or repair the marker by hand)`);
337
332
  }
@@ -341,17 +336,18 @@ export async function adoptLocalDataRoot(opts) {
341
336
  if (typeof opts.toPrincipal !== "string" || opts.toPrincipal === "") {
342
337
  throw new AdoptionError("adoption_bad_request", "adoptLocalDataRoot requires the adopting principal — adoption is the act of giving this data root an identity");
343
338
  }
344
- if (opts.from.kind === "principal" && (typeof opts.from.principal !== "string" || opts.from.principal === "")) {
345
- throw new AdoptionError("adoption_bad_request", "a principal-form source requires a non-empty principal — local-single-user identity is the local-owner kind, never an empty string");
339
+ const from = readRuleOwner(opts.from);
340
+ if (from === undefined) {
341
+ throw new AdoptionError("adoption_bad_request", "the adoption source must be the local-owner kind or a principal with a non-blank name — local-single-user identity is the local-owner kind, never a blank string");
346
342
  }
347
- if (opts.from.kind === "principal" && opts.from.principal === opts.toPrincipal) {
343
+ if (from.kind === "principal" && from.principal === opts.toPrincipal) {
348
344
  throw new AdoptionError("adoption_bad_request", `the data root already belongs to "${opts.toPrincipal}" — there is nothing to adopt`);
349
345
  }
350
346
  if (typeof opts.credentials.ref !== "string" || opts.credentials.ref === "") {
351
347
  throw new AdoptionError("adoption_bad_request", "the credentials claim ref must be a non-empty reference (the claim is what makes the new identity redeemable)");
352
348
  }
353
- if (opts.from === null || typeof opts.from !== "object" || opts.credentials === null || typeof opts.credentials !== "object") {
354
- throw new AdoptionError("adoption_bad_request", "adoptLocalDataRoot requires `from` and `credentials` objects");
349
+ if (opts.credentials === null || typeof opts.credentials !== "object") {
350
+ throw new AdoptionError("adoption_bad_request", "adoptLocalDataRoot requires a `credentials` object");
355
351
  }
356
352
  if (opts.additionalConfigs !== undefined && !Array.isArray(opts.additionalConfigs)) {
357
353
  throw new AdoptionError("adoption_bad_request", "additionalConfigs must be an array when supplied");
@@ -368,9 +364,6 @@ export async function adoptLocalDataRoot(opts) {
368
364
  if (opts.onError !== undefined && typeof opts.onError !== "function") {
369
365
  throw new AdoptionError("adoption_bad_request", "`onError` must be callable when supplied");
370
366
  }
371
- if (opts.from.kind !== "local-owner" && opts.from.kind !== "principal") {
372
- throw new AdoptionError("adoption_bad_request", "the adoption source must be the local-owner kind or a named principal");
373
- }
374
367
  if (opts.credentials.issuedBy !== "server") {
375
368
  throw new AdoptionError("adoption_bad_request", `the credentials claim must be server-issued (got issuedBy: ${JSON.stringify(opts.credentials.issuedBy)}) — the server mints the new identity`);
376
369
  }
@@ -402,7 +395,7 @@ export async function adoptLocalDataRoot(opts) {
402
395
  }
403
396
  }
404
397
  ensureDir(opts.root);
405
- const pre = answerFromExisting(opts.root, readRootAdoptionFile(opts.root), opts.from, opts.toPrincipal);
398
+ const pre = answerFromExisting(opts.root, readRootAdoptionFile(opts.root), from, opts.toPrincipal);
406
399
  if (pre !== undefined) {
407
400
  const account = readConfigAccountEvidence(opts.root);
408
401
  if (account !== undefined && account.adoptionId === pre.immutableReport.adoptionId)
@@ -425,7 +418,7 @@ export async function adoptLocalDataRoot(opts) {
425
418
  }
426
419
  try {
427
420
  const existing = readRootAdoptionFile(opts.root);
428
- const answered = answerFromExisting(opts.root, existing, opts.from, opts.toPrincipal);
421
+ const answered = answerFromExisting(opts.root, existing, from, opts.toPrincipal);
429
422
  if (answered !== undefined) {
430
423
  rebuildConfigAccountIfUnbound(opts.root, answered.immutableReport);
431
424
  return receiptFromTerminal(opts.root, {
@@ -481,7 +474,7 @@ export async function adoptLocalDataRoot(opts) {
481
474
  `They would never run, and reporting them as done would be a lie; post-adoption carriage rides each store's normal channel.`);
482
475
  }
483
476
  if (plan !== existing.marker.plan) {
484
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, phase, plan, legBits);
477
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, phase, plan, legBits);
485
478
  }
486
479
  const accountInFlight = readConfigAccount(opts.root);
487
480
  if (accountInFlight === undefined || accountInFlight.adoptionId !== adoptionId) {
@@ -496,7 +489,7 @@ export async function adoptLocalDataRoot(opts) {
496
489
  legBits = {};
497
490
  plan = { ...(offeredRulesDir !== undefined ? { rulesDir: offeredRulesDir } : {}), carriage: offeredCarriage, credentialsRef: opts.credentials.ref };
498
491
  upsertConfigAccount(opts.root, adoptionId, opts.toPrincipal, opts.additionalConfigs ?? []);
499
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 2, plan, legBits);
492
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 2, plan, legBits);
500
493
  }
501
494
  const legs = [];
502
495
  if (phase < 3) {
@@ -505,7 +498,7 @@ export async function adoptLocalDataRoot(opts) {
505
498
  try {
506
499
  nested = await adoptFilePermissionRuleStore({
507
500
  dir: opts.rules.dir,
508
- from: opts.from,
501
+ from,
509
502
  toPrincipal: opts.toPrincipal,
510
503
  transport: opts.rules.transport,
511
504
  ...(opts.now !== undefined ? { now: opts.now } : {}),
@@ -526,15 +519,15 @@ export async function adoptLocalDataRoot(opts) {
526
519
  }
527
520
  }
528
521
  if (legBits[SESSION_POLICY_LEG]?.done !== true) {
529
- const rows = rewriteSessionPolicyRows(opts.root, opts.from.kind === "principal" ? opts.from.principal : null, opts.toPrincipal);
522
+ const rows = rewriteSessionPolicyRows(opts.root, from.kind === "principal" ? from.principal : null, opts.toPrincipal);
530
523
  legBits = { ...legBits, [SESSION_POLICY_LEG]: { done: true, rows } };
531
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 2, plan, legBits);
524
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 2, plan, legBits);
532
525
  }
533
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 3, plan, legBits);
526
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 3, plan, legBits);
534
527
  phase = 3;
535
528
  }
536
529
  if (phase < 4) {
537
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 4, plan, legBits);
530
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 4, plan, legBits);
538
531
  phase = 4;
539
532
  }
540
533
  if (phase < 5) {
@@ -575,9 +568,9 @@ export async function adoptLocalDataRoot(opts) {
575
568
  ...(quarantined > 0 ? { quarantined } : {}),
576
569
  },
577
570
  };
578
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 4, plan, legBits);
571
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 4, plan, legBits);
579
572
  }
580
- publishMarker(opts.root, adoptionId, opts.from, opts.toPrincipal, 5, plan, legBits);
573
+ publishMarker(opts.root, adoptionId, from, opts.toPrincipal, 5, plan, legBits);
581
574
  phase = 5;
582
575
  }
583
576
  if (plan.rulesDir !== undefined)
@@ -609,7 +602,7 @@ export async function adoptLocalDataRoot(opts) {
609
602
  }
610
603
  const immutableReport = {
611
604
  adoptionId,
612
- from: opts.from,
605
+ from,
613
606
  toPrincipal: opts.toPrincipal,
614
607
  atMs,
615
608
  credentials: opts.credentials,
@@ -619,9 +612,9 @@ export async function adoptLocalDataRoot(opts) {
619
612
  };
620
613
  writeRootAdoptionFile(opts.root, {
621
614
  schemaVersion: 1,
622
- adopted: { from: opts.from, toPrincipal: opts.toPrincipal, atMs: immutableReport.atMs, immutableReport },
615
+ adopted: { from, toPrincipal: opts.toPrincipal, atMs: immutableReport.atMs, immutableReport },
623
616
  });
624
- return receiptFromTerminal(opts.root, { from: opts.from, toPrincipal: opts.toPrincipal, atMs: immutableReport.atMs, immutableReport });
617
+ return receiptFromTerminal(opts.root, { from, toPrincipal: opts.toPrincipal, atMs: immutableReport.atMs, immutableReport });
625
618
  }
626
619
  finally {
627
620
  adoptionLock.release();
@@ -14,17 +14,10 @@
14
14
  * with the same (from → toPrincipal) short-circuits to the recorded receipt) and it carries the
15
15
  * IMMUTABLE report — the byte-stable half of every receipt.
16
16
  *
17
- * This module is deliberately tiny and dependency-light (node:fs + the atomic-write primitive): every
18
- * file store imports the gate from here, so it must never grow an import back into a store.
17
+ * This module is deliberately tiny and dependency-light (node:fs, the atomic-write primitive, the import-free owner
18
+ * reading): every file store imports the gate from here, so it must never grow an import back into a store.
19
19
  */
20
- /** Who the data root belonged to before adoption. Shape-identical to the rule domain's `RuleOwner`
21
- * (design/182): local-single-user identity is a STRUCTURAL ABSENCE, never a sentinel string. */
22
- export type AdoptionSource = {
23
- kind: "local-owner";
24
- } | {
25
- kind: "principal";
26
- principal: string;
27
- };
20
+ import { type RuleOwner } from "../../../core/rule-owner.js";
28
21
  /** Typed refusal codes (design/183 §7.3): every adoption refusal is discriminable — from `not_found`,
29
22
  * from a broken deployment, and from each other. */
30
23
  export type AdoptionErrorCode =
@@ -81,7 +74,7 @@ export interface AdoptionLegReport {
81
74
  export interface AdoptionReport {
82
75
  /** Minted at phase ② — the binding anchor config-witness receipts must carry. */
83
76
  adoptionId: string;
84
- from: AdoptionSource;
77
+ from: RuleOwner;
85
78
  toPrincipal: string;
86
79
  atMs: number;
87
80
  /** The claim REFERENCE for the new identity's credentials — never the credentials themselves (the
@@ -120,7 +113,7 @@ export type RootAdoptionFile = {
120
113
  schemaVersion: 1;
121
114
  marker: {
122
115
  adoptionId: string;
123
- from: AdoptionSource;
116
+ from: RuleOwner;
124
117
  toPrincipal: string;
125
118
  phase: 2 | 3 | 4 | 5;
126
119
  /** The migration plan recorded at phase ② and grown MONOTONICALLY across resumes — what a
@@ -147,7 +140,7 @@ export type RootAdoptionFile = {
147
140
  } | {
148
141
  schemaVersion: 1;
149
142
  adopted: {
150
- from: AdoptionSource;
143
+ from: RuleOwner;
151
144
  toPrincipal: string;
152
145
  atMs: number;
153
146
  immutableReport: AdoptionReport;
@@ -1,5 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { readRuleOwner, sameRuleOwner } from "../../../core/rule-owner.js";
3
4
  import { atomicWriteFile, ensureDir } from "../fs-atomic.js";
4
5
  export class AdoptionError extends Error {
5
6
  code;
@@ -26,14 +27,6 @@ export const BASELINE_CONFIG_IDENTITIES = [
26
27
  { deployment: "env", key: "REQUIRE_PRINCIPAL" },
27
28
  { deployment: "core-decl", key: "localOwnerRules" },
28
29
  ];
29
- function isSource(v) {
30
- if (v === null || typeof v !== "object")
31
- return false;
32
- const s = v;
33
- if (s.kind === "local-owner")
34
- return true;
35
- return s.kind === "principal" && typeof s.principal === "string" && s.principal !== "";
36
- }
37
30
  function isRootAdoptionFileShape(v) {
38
31
  if (v === null || typeof v !== "object")
39
32
  return false;
@@ -45,7 +38,7 @@ function isRootAdoptionFileShape(v) {
45
38
  if (m === null ||
46
39
  typeof m !== "object" ||
47
40
  typeof m.adoptionId !== "string" ||
48
- !isSource(m.from) ||
41
+ readRuleOwner(m.from) === undefined ||
49
42
  typeof m.toPrincipal !== "string" ||
50
43
  typeof m.phase !== "number" ||
51
44
  ![2, 3, 4, 5].includes(m.phase)) {
@@ -91,9 +84,10 @@ function isRootAdoptionFileShape(v) {
91
84
  }
92
85
  if ("adopted" in f && !("marker" in f)) {
93
86
  const a = f.adopted;
87
+ const from = readRuleOwner(a?.from);
94
88
  if (a === null ||
95
89
  typeof a !== "object" ||
96
- !isSource(a.from) ||
90
+ from === undefined ||
97
91
  typeof a.toPrincipal !== "string" ||
98
92
  typeof a.atMs !== "number" ||
99
93
  a.immutableReport === null ||
@@ -101,11 +95,8 @@ function isRootAdoptionFileShape(v) {
101
95
  return false;
102
96
  }
103
97
  const r = a.immutableReport;
104
- const sameFrom = isSource(r.from) &&
105
- (r.from.kind === "local-owner"
106
- ? a.from.kind === "local-owner"
107
- : a.from.kind === "principal" &&
108
- r.from.principal === a.from.principal);
98
+ const reportFrom = readRuleOwner(r.from);
99
+ const sameFrom = reportFrom !== undefined && sameRuleOwner(reportFrom, from);
109
100
  const okCount = (n) => n === undefined || (typeof n === "number" && Number.isSafeInteger(n) && n >= 0);
110
101
  const configIds = new Set();
111
102
  const configsOk = Array.isArray(r.affectedDeploymentConfigs) &&
@@ -42,6 +42,9 @@ export declare class FileCheckpointStore implements CheckpointStore {
42
42
  private get cps();
43
43
  /** One-shot crash fault (mirrors `InMemoryCheckpointStore.testInjectFault`). */
44
44
  private fault;
45
+ /** The guarded {@link FileCheckpointStoreOptions.onCorruptRead} seat (the ledger's replay and this store's projection share it). */
46
+ private readonly discloseCorrupt;
47
+ private readonly ledgerPath;
45
48
  constructor(root: string, opts?: FileCheckpointStoreOptions);
46
49
  /** Serialize an op behind any in-flight op on the same token (the in-process per-token async mutex). */
47
50
  private withLock;
@@ -92,16 +92,20 @@ export class FileCheckpointStore {
92
92
  return this.ledger.rows;
93
93
  }
94
94
  fault = null;
95
+ discloseCorrupt;
96
+ ledgerPath;
95
97
  constructor(root, opts = {}) {
96
98
  assertAdoptionBootGate(root, "FileCheckpointStore");
97
99
  this.fsyncEnabled = opts.fsync !== false;
98
100
  this.compactEvery = opts.compactEvery ?? 1000;
101
+ this.discloseCorrupt = guardCorruptSink(opts.onCorruptRead);
99
102
  const dir = join(root, "checkpoints");
103
+ this.ledgerPath = join(dir, "checkpoints.jsonl");
100
104
  this.ledger = checkpointLedgers.acquire({
101
105
  dir,
102
106
  tmpDir: join(root, "tmp"),
103
- ...(opts.onCorruptRead !== undefined ? { onCorruptRead: guardCorruptSink(opts.onCorruptRead) } : {}),
104
- ledgerPath: join(dir, "checkpoints.jsonl"),
107
+ ...(this.discloseCorrupt !== undefined ? { onCorruptRead: this.discloseCorrupt } : {}),
108
+ ledgerPath: this.ledgerPath,
105
109
  snapshotPath: join(dir, "checkpoints.snapshot.jsonl"),
106
110
  });
107
111
  }
@@ -218,10 +222,12 @@ export class FileCheckpointStore {
218
222
  return n;
219
223
  }
220
224
  async listByScope(scope) {
225
+ const sink = this.discloseCorrupt;
226
+ const disclose = sink === undefined ? undefined : (sentence) => sink({ kind: "file", path: this.ledgerPath, reason: sentence });
221
227
  const out = [];
222
228
  for (const cp of this.cps.values()) {
223
229
  if (cp.scope === scope && cp.status === "pending")
224
- out.push(summarizeCheckpoint(cp));
230
+ out.push(summarizeCheckpoint(cp, disclose));
225
231
  }
226
232
  return out;
227
233
  }