@sema-agent/core 7.55.0 → 7.57.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 (502) hide show
  1. package/CHANGELOG.md +1054 -0
  2. package/LICENSE +1 -1
  3. package/dist/agents/cascade.js +1 -1
  4. package/dist/agents/cc-peer-directory.js +1 -0
  5. package/dist/agents/child-model-seat.d.ts +0 -11
  6. package/dist/agents/child-model-seat.js +0 -3
  7. package/dist/agents/list-agents-tool.d.ts +3 -1
  8. package/dist/agents/list-agents-tool.js +7 -7
  9. package/dist/agents/org-delivery-gate.js +3 -4
  10. package/dist/agents/peer-directory.d.ts +22 -4
  11. package/dist/agents/peer-directory.js +24 -2
  12. package/dist/agents/peer-held-queue.d.ts +69 -49
  13. package/dist/agents/peer-held-queue.js +255 -106
  14. package/dist/agents/peer-session-drain.js +65 -45
  15. package/dist/agents/repair-loop.js +2 -2
  16. package/dist/agents/send-message-tool.js +7 -6
  17. package/dist/agents/subagent.d.ts +6 -4
  18. package/dist/agents/subagent.js +72 -68
  19. package/dist/agents/tool-filter.d.ts +7 -5
  20. package/dist/agents/tool-filter.js +12 -9
  21. package/dist/agents/verify.d.ts +3 -2
  22. package/dist/agents/verify.js +3 -3
  23. package/dist/brain/anthropic.js +45 -80
  24. package/dist/brain/media-degrade.d.ts +18 -7
  25. package/dist/brain/media-degrade.js +13 -2
  26. package/dist/brain/model-capability.d.ts +37 -0
  27. package/dist/brain/model-capability.js +34 -0
  28. package/dist/brain/model-presets.d.ts +2 -8
  29. package/dist/brain/model-presets.js +1 -6
  30. package/dist/brain/open-responses.js +23 -34
  31. package/dist/brain/openai.js +25 -96
  32. package/dist/brain/provider-dialect.d.ts +3 -2
  33. package/dist/brain/provider-dialect.js +2 -2
  34. package/dist/brain/reasoning-request.d.ts +96 -0
  35. package/dist/brain/reasoning-request.js +174 -0
  36. package/dist/brain/reasoning.d.ts +11 -11
  37. package/dist/brain/reasoning.js +4 -3
  38. package/dist/brain/request-params.d.ts +13 -4
  39. package/dist/brain/request-params.js +21 -5
  40. package/dist/brain/status-sink.d.ts +20 -0
  41. package/dist/brain/status-sink.js +7 -0
  42. package/dist/brain/stream-engine.d.ts +9 -0
  43. package/dist/brain/stream-engine.js +24 -10
  44. package/dist/brain/stream-shared.d.ts +5 -4
  45. package/dist/brain/stream-shared.js +4 -4
  46. package/dist/core/a2a.d.ts +2 -1
  47. package/dist/core/a2a.js +19 -13
  48. package/dist/core/agent-definition.d.ts +10 -0
  49. package/dist/core/allow-entry.d.ts +23 -23
  50. package/dist/core/allow-entry.js +42 -46
  51. package/dist/core/allow-rule-shadow.d.ts +3 -3
  52. package/dist/core/approval-object.d.ts +21 -5
  53. package/dist/core/approval-object.js +44 -17
  54. package/dist/core/ask-origin.d.ts +66 -20
  55. package/dist/core/ask-origin.js +63 -23
  56. package/dist/core/ask-question.d.ts +51 -8
  57. package/dist/core/ask-question.js +3 -4
  58. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  59. package/dist/core/ask-unresolvable-notice.js +16 -2
  60. package/dist/core/auto-compaction.d.ts +71 -6
  61. package/dist/core/auto-compaction.js +42 -26
  62. package/dist/core/background-agent-store.d.ts +6 -2
  63. package/dist/core/background-agent-store.js +1 -1
  64. package/dist/core/checkpoint-generation.d.ts +53 -0
  65. package/dist/core/checkpoint-generation.js +35 -0
  66. package/dist/core/checkpoint-queries.d.ts +180 -0
  67. package/dist/core/checkpoint-queries.js +272 -0
  68. package/dist/core/checkpoint-requirements.d.ts +19 -1
  69. package/dist/core/checkpoint-requirements.js +6 -0
  70. package/dist/core/checkpoint-store.d.ts +105 -53
  71. package/dist/core/checkpoint-store.js +43 -20
  72. package/dist/core/cross-boundary-taint.d.ts +6 -5
  73. package/dist/core/cross-boundary-taint.js +5 -5
  74. package/dist/core/decision-receipt.d.ts +37 -3
  75. package/dist/core/decision-receipt.js +17 -17
  76. package/dist/core/delegation-not-started.d.ts +6 -0
  77. package/dist/core/delegation-not-started.js +17 -0
  78. package/dist/core/engine-attestation.d.ts +93 -0
  79. package/dist/core/engine-attestation.js +70 -0
  80. package/dist/core/engine-capabilities.d.ts +4 -1
  81. package/dist/core/engine-capabilities.js +1 -1
  82. package/dist/core/engine-notice.d.ts +32 -12
  83. package/dist/core/engine-notice.js +6 -0
  84. package/dist/core/file-history-store.d.ts +104 -22
  85. package/dist/core/file-history-store.js +37 -19
  86. package/dist/core/gate-fold.d.ts +1 -1
  87. package/dist/core/gate-fold.js +22 -10
  88. package/dist/core/gate-lanes.js +73 -65
  89. package/dist/core/gate-outcome.d.ts +26 -5
  90. package/dist/core/gate-outcome.js +26 -0
  91. package/dist/core/governance-codes.d.ts +5 -1
  92. package/dist/core/governance-codes.js +6 -0
  93. package/dist/core/hooks.d.ts +19 -18
  94. package/dist/core/hooks.js +3 -1
  95. package/dist/core/host-floor.d.ts +128 -0
  96. package/dist/core/host-floor.js +206 -0
  97. package/dist/core/host-target.d.ts +38 -3
  98. package/dist/core/host-target.js +38 -5
  99. package/dist/core/mailbox-store.d.ts +62 -1
  100. package/dist/core/mailbox-store.js +59 -0
  101. package/dist/core/mcp-name-judge.d.ts +46 -0
  102. package/dist/core/mcp-name-judge.js +61 -0
  103. package/dist/core/mcp-probe.d.ts +1 -1
  104. package/dist/core/mcp-probe.js +2 -5
  105. package/dist/core/mcp.d.ts +5 -1
  106. package/dist/core/mcp.js +70 -64
  107. package/dist/core/memory-engine/consolidation-driver.js +4 -3
  108. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  109. package/dist/core/memory-engine/distiller.js +26 -17
  110. package/dist/core/memory-engine/engine.js +4 -4
  111. package/dist/core/memory-engine/layout.d.ts +60 -8
  112. package/dist/core/memory-engine/layout.js +70 -8
  113. package/dist/core/model-seat.d.ts +10 -3
  114. package/dist/core/mods/classic-events.d.ts +67 -0
  115. package/dist/core/mods/classic-events.js +1 -0
  116. package/dist/core/mods/dollar.d.ts +13 -0
  117. package/dist/core/mods/extension-call.d.ts +31 -0
  118. package/dist/core/mods/extension-call.js +43 -0
  119. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  120. package/dist/core/mods/kernel/dispatch.js +140 -69
  121. package/dist/core/mods/kernel/events.d.ts +47 -11
  122. package/dist/core/mods/kernel/events.js +66 -42
  123. package/dist/core/mods/kernel/index.d.ts +4 -4
  124. package/dist/core/mods/kernel/index.js +2 -2
  125. package/dist/core/mods/kernel/receive.d.ts +39 -5
  126. package/dist/core/mods/kernel/receive.js +290 -17
  127. package/dist/core/mods/kernel/registration.d.ts +33 -2
  128. package/dist/core/mods/kernel/registration.js +6 -7
  129. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  130. package/dist/core/mods/kernel/site-rules.js +24 -42
  131. package/dist/core/mods/spec-seats.d.ts +69 -0
  132. package/dist/core/mods/spec-seats.js +114 -0
  133. package/dist/core/mods/stations.d.ts +28 -8
  134. package/dist/core/mods/stations.js +29 -13
  135. package/dist/core/mods/tool-call.d.ts +79 -0
  136. package/dist/core/mods/tool-call.js +152 -0
  137. package/dist/core/namespaced-rule-name.d.ts +32 -38
  138. package/dist/core/namespaced-rule-name.js +29 -36
  139. package/dist/core/parent-spec-seat.d.ts +6 -1
  140. package/dist/core/parent-spec-seat.js +2 -0
  141. package/dist/core/park-selfcheck.js +3 -0
  142. package/dist/core/permission-rule-consent.d.ts +24 -3
  143. package/dist/core/permission-rule-consent.js +136 -41
  144. package/dist/core/permission-rule-model.d.ts +57 -5
  145. package/dist/core/permission-rule-model.js +90 -31
  146. package/dist/core/permission-rule-org.d.ts +6 -2
  147. package/dist/core/permission-rule-org.js +8 -4
  148. package/dist/core/permission-rule-provider.d.ts +5 -2
  149. package/dist/core/permission-rule-provider.js +41 -11
  150. package/dist/core/permission-rule-store.d.ts +3 -2
  151. package/dist/core/permission-rule-store.js +11 -2
  152. package/dist/core/permission-rule-sync.js +3 -2
  153. package/dist/core/permission-rule-syntax.d.ts +5 -4
  154. package/dist/core/permission-rule-syntax.js +2 -2
  155. package/dist/core/permission-rules.d.ts +4 -4
  156. package/dist/core/permission-rules.js +11 -20
  157. package/dist/core/persisted-rule-arms.d.ts +2 -2
  158. package/dist/core/persisted-rule-arms.js +10 -12
  159. package/dist/core/principal-name.d.ts +20 -0
  160. package/dist/core/principal-name.js +22 -0
  161. package/dist/core/prompt-section-seat.js +4 -6
  162. package/dist/core/protocol-http-auth.d.ts +40 -5
  163. package/dist/core/protocol-http-auth.js +168 -4
  164. package/dist/core/protocol-naming.d.ts +20 -0
  165. package/dist/core/protocol-naming.js +20 -3
  166. package/dist/core/read-only-shell.d.ts +20 -5
  167. package/dist/core/read-only-shell.js +29 -14
  168. package/dist/core/remote-env.d.ts +37 -1
  169. package/dist/core/remote-env.js +11 -0
  170. package/dist/core/resume-startup-cause.d.ts +24 -2
  171. package/dist/core/resume-startup-cause.js +20 -1
  172. package/dist/core/retired-keys.d.ts +16 -0
  173. package/dist/core/retired-keys.js +16 -4
  174. package/dist/core/rewrite-rejudge.d.ts +60 -0
  175. package/dist/core/rewrite-rejudge.js +36 -0
  176. package/dist/core/roles.d.ts +28 -1
  177. package/dist/core/roles.js +81 -26
  178. package/dist/core/rule-lane-reads.d.ts +20 -15
  179. package/dist/core/rule-lane-reads.js +45 -17
  180. package/dist/core/rule-owner.d.ts +3 -3
  181. package/dist/core/rule-owner.js +3 -2
  182. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  183. package/dist/core/runner/announce-once-ledger.js +5 -0
  184. package/dist/core/runner/assemble-result.d.ts +1 -0
  185. package/dist/core/runner/assemble-result.js +1 -1
  186. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  187. package/dist/core/runner/caller-roster.d.ts +16 -4
  188. package/dist/core/runner/caller-roster.js +33 -6
  189. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  190. package/dist/core/runner/capability-withheld-seat.js +24 -0
  191. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  192. package/dist/core/runner/classifier-ladder.js +3 -3
  193. package/dist/core/runner/compact-session.d.ts +10 -0
  194. package/dist/core/runner/compact-session.js +202 -0
  195. package/dist/core/runner/compaction-call-options.d.ts +2 -2
  196. package/dist/core/runner/compaction-seams.d.ts +21 -1
  197. package/dist/core/runner/compaction-seams.js +11 -8
  198. package/dist/core/runner/construction-doors.js +3 -0
  199. package/dist/core/runner/contracts.d.ts +50 -40
  200. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  201. package/dist/core/runner/cross-boundary-lane.js +40 -27
  202. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  203. package/dist/core/runner/denial-limit-arms.js +1 -1
  204. package/dist/core/runner/derived-route-fallback.d.ts +13 -0
  205. package/dist/core/runner/derived-route-fallback.js +6 -0
  206. package/dist/core/runner/env-capability-census.d.ts +3 -2
  207. package/dist/core/runner/env-capability-census.js +9 -3
  208. package/dist/core/runner/file-history-request.d.ts +18 -0
  209. package/dist/core/runner/file-history-request.js +21 -13
  210. package/dist/core/runner/file-history-restore.d.ts +45 -0
  211. package/dist/core/runner/file-history-restore.js +46 -0
  212. package/dist/core/runner/gate-exit.d.ts +3 -3
  213. package/dist/core/runner/gate-exit.js +4 -3
  214. package/dist/core/runner/image.d.ts +7 -17
  215. package/dist/core/runner/image.js +9 -60
  216. package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
  217. package/dist/core/runner/permission-rule-lanes.js +39 -17
  218. package/dist/core/runner/person-path-rows.d.ts +12 -9
  219. package/dist/core/runner/person-path-rows.js +18 -7
  220. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
  221. package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
  222. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  223. package/dist/core/runner/prepare-ask-lane.js +5 -2
  224. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  225. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  226. package/dist/core/runner/prepare-config-doors.d.ts +35 -38
  227. package/dist/core/runner/prepare-config-doors.js +46 -28
  228. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  229. package/dist/core/runner/prepare-defer-classify.js +7 -8
  230. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  231. package/dist/core/runner/prepare-file-history.js +7 -39
  232. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  233. package/dist/core/runner/prepare-gate-stations.js +10 -1
  234. package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
  235. package/dist/core/runner/prepare-hands-readface.js +17 -14
  236. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  237. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  238. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  239. package/dist/core/runner/prepare-park-ask.d.ts +2 -0
  240. package/dist/core/runner/prepare-park-ask.js +7 -7
  241. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  242. package/dist/core/runner/prepare-policy-chain.js +67 -76
  243. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  244. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  245. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  246. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  247. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  248. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  249. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  250. package/dist/core/runner/prepare-safety-scan.js +0 -17
  251. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  252. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  253. package/dist/core/runner/prepare-task.d.ts +5 -2
  254. package/dist/core/runner/prepare-task.js +48 -43
  255. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
  256. package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
  257. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  258. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  259. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  260. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  261. package/dist/core/runner/resume-admission.js +1 -1
  262. package/dist/core/runner/resume-apply.js +11 -12
  263. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  264. package/dist/core/runner/resume-claim.d.ts +4 -2
  265. package/dist/core/runner/resume-claim.js +15 -8
  266. package/dist/core/runner/retired-runner-deps.js +1 -0
  267. package/dist/core/runner/rewind-files.d.ts +12 -0
  268. package/dist/core/runner/rewind-files.js +90 -0
  269. package/dist/core/runner/run-attachment-seats.js +2 -1
  270. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  271. package/dist/core/runner/run-brain-sinks.js +4 -2
  272. package/dist/core/runner/run-harness-handlers.js +12 -4
  273. package/dist/core/runner/run-leg.d.ts +1 -1
  274. package/dist/core/runner/run-leg.js +40 -39
  275. package/dist/core/runner/run-notification-lane.d.ts +2 -0
  276. package/dist/core/runner/run-notification-lane.js +2 -2
  277. package/dist/core/runner/run-recovery-lanes.js +3 -4
  278. package/dist/core/runner/run-settle-and-teardown.js +7 -12
  279. package/dist/core/runner/run-terminal-adoption.js +3 -4
  280. package/dist/core/runner/run-turn-boundary.js +4 -15
  281. package/dist/core/runner/runtask.d.ts +10 -0
  282. package/dist/core/runner/runtask.js +35 -42
  283. package/dist/core/runner/send-message-continuation.js +1 -1
  284. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  285. package/dist/core/runner/session-read-file-states.js +28 -0
  286. package/dist/core/runner/session-rule-policy.js +4 -3
  287. package/dist/core/runner/session-verb-doors.d.ts +28 -0
  288. package/dist/core/runner/session-verb-doors.js +48 -0
  289. package/dist/core/runner/session-write-ledger.d.ts +30 -0
  290. package/dist/core/runner/session-write-ledger.js +101 -0
  291. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  292. package/dist/core/runner/shell-env-withheld.js +51 -0
  293. package/dist/core/runner/skills-seat.js +6 -2
  294. package/dist/core/runner/stream-settle-backstop.js +12 -15
  295. package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
  296. package/dist/core/runner/sub-agent-deny-lists.js +25 -17
  297. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  298. package/dist/core/runner/synthetic-tools.js +4 -1
  299. package/dist/core/runner/teardown-bounded.d.ts +1 -0
  300. package/dist/core/runner/teardown-bounded.js +1 -0
  301. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  302. package/dist/core/runner/tool-disclosure.js +1 -3
  303. package/dist/core/runner/tool-end-body.d.ts +1 -1
  304. package/dist/core/runner/tool-end-body.js +10 -9
  305. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  306. package/dist/core/runner/tool-not-executed.js +11 -0
  307. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  308. package/dist/core/runner/tool-occurrence.js +7 -0
  309. package/dist/core/runner/turn-attachments.d.ts +33 -15
  310. package/dist/core/runner/turn-attachments.js +62 -37
  311. package/dist/core/runner-deps.d.ts +7 -7
  312. package/dist/core/safety-axis-vocab.d.ts +6 -4
  313. package/dist/core/safety-axis-vocab.js +6 -5
  314. package/dist/core/safety-merge-corpus.js +11 -3
  315. package/dist/core/secret-env.d.ts +30 -3
  316. package/dist/core/secret-env.js +47 -8
  317. package/dist/core/select-model.js +3 -3
  318. package/dist/core/session-policy-store.d.ts +32 -15
  319. package/dist/core/session-policy-store.js +156 -36
  320. package/dist/core/session-store.d.ts +29 -10
  321. package/dist/core/session-store.js +51 -19
  322. package/dist/core/session.d.ts +82 -16
  323. package/dist/core/session.js +53 -0
  324. package/dist/core/shell-read-silence.d.ts +11 -12
  325. package/dist/core/shell-read-silence.js +9 -5
  326. package/dist/core/shell-run-candidates.js +3 -1
  327. package/dist/core/shell-wrapper-projection.d.ts +1 -1
  328. package/dist/core/shell-wrapper-projection.js +1 -1
  329. package/dist/core/shell-wrapper-table.d.ts +14 -7
  330. package/dist/core/shell-wrapper-table.js +5 -4
  331. package/dist/core/side-query.js +10 -1
  332. package/dist/core/skill-grant.d.ts +7 -2
  333. package/dist/core/skill-grant.js +5 -0
  334. package/dist/core/skills-directory.js +6 -2
  335. package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
  336. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  337. package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
  338. package/dist/core/store-contracts/file-history-store-contract.js +40 -1
  339. package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
  340. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  341. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  342. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  343. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  344. package/dist/core/store-contracts/session-store-contract.js +150 -14
  345. package/dist/core/stub-env.d.ts +2 -0
  346. package/dist/core/stub-env.js +1 -0
  347. package/dist/core/synthetic-read-verdict.js +3 -3
  348. package/dist/core/task-event.d.ts +32 -4
  349. package/dist/core/task-notification.d.ts +16 -12
  350. package/dist/core/task-registry-agent.d.ts +8 -4
  351. package/dist/core/task-registry-agent.js +14 -8
  352. package/dist/core/task-registry-shared.d.ts +35 -6
  353. package/dist/core/task-registry-shared.js +11 -0
  354. package/dist/core/task-registry.d.ts +10 -1
  355. package/dist/core/task-registry.js +12 -2
  356. package/dist/core/task-result.d.ts +18 -0
  357. package/dist/core/task-spec.d.ts +18 -13
  358. package/dist/core/tighten-task-spec.js +2 -1
  359. package/dist/core/tool-catalog-entries.d.ts +23 -0
  360. package/dist/core/tool-catalog-entries.js +14 -2
  361. package/dist/core/tool-check-reading.d.ts +11 -0
  362. package/dist/core/tool-check-reading.js +11 -6
  363. package/dist/core/tool-model-gate.d.ts +2 -2
  364. package/dist/core/tool-name-aliases.d.ts +48 -18
  365. package/dist/core/tool-name-aliases.js +36 -19
  366. package/dist/core/tool-name-readings.d.ts +6 -32
  367. package/dist/core/tool-name-readings.js +2 -9
  368. package/dist/core/tool-policy.d.ts +78 -204
  369. package/dist/core/tool-policy.js +152 -204
  370. package/dist/core/tool-result-store.js +3 -0
  371. package/dist/core/tool-roster.d.ts +14 -19
  372. package/dist/core/tool-roster.js +11 -44
  373. package/dist/core/tool-spec-members.js +7 -2
  374. package/dist/core/tool-spec.d.ts +19 -11
  375. package/dist/core/tools.js +49 -9
  376. package/dist/core/trace.d.ts +6 -3
  377. package/dist/core/trace.js +2 -1
  378. package/dist/core/types.d.ts +1 -1
  379. package/dist/core/untrusted-egress.d.ts +20 -0
  380. package/dist/core/untrusted-egress.js +77 -3
  381. package/dist/core/user-attachment.d.ts +8 -1
  382. package/dist/core/user-attachment.js +64 -4
  383. package/dist/core/wiring-manifest.d.ts +9 -0
  384. package/dist/core/wiring-manifest.js +1 -0
  385. package/dist/core/workflow-journal-store.js +1 -1
  386. package/dist/engine/compaction/compaction.js +3 -2
  387. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  388. package/dist/engine/execution-env/node-execution-env.js +11 -2
  389. package/dist/engine/harness/agent-harness.d.ts +32 -6
  390. package/dist/engine/harness/agent-harness.js +65 -9
  391. package/dist/engine/harness/types.d.ts +29 -2
  392. package/dist/engine/llm/types.d.ts +28 -11
  393. package/dist/engine/loop/agent-loop.d.ts +23 -4
  394. package/dist/engine/loop/agent-loop.js +42 -30
  395. package/dist/engine/loop/types.d.ts +16 -6
  396. package/dist/engine/session/memory-repo.d.ts +9 -2
  397. package/dist/engine/session/memory-repo.js +11 -1
  398. package/dist/engine/session/repo-utils.d.ts +6 -5
  399. package/dist/engine/session/repo-utils.js +14 -6
  400. package/dist/index.d.ts +34 -17
  401. package/dist/index.js +22 -11
  402. package/dist/internal/harness-types.d.ts +1 -1
  403. package/dist/internal/harness.d.ts +2 -1
  404. package/dist/internal/harness.js +1 -0
  405. package/dist/internal/llm.d.ts +1 -1
  406. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  407. package/dist/orchestration/run-workflow-tool.js +5 -3
  408. package/dist/orchestration/workflow.d.ts +3 -0
  409. package/dist/orchestration/workflow.js +36 -18
  410. package/dist/primitives/credential-ref.d.ts +89 -0
  411. package/dist/primitives/credential-ref.js +125 -0
  412. package/dist/primitives/index.d.ts +2 -0
  413. package/dist/primitives/index.js +1 -0
  414. package/dist/prompt-assembly/artifact.d.ts +2 -2
  415. package/dist/prompt-assembly/artifact.js +5 -3
  416. package/dist/prompt-assembly/assemble.d.ts +3 -2
  417. package/dist/prompt-assembly/assemble.js +1 -1
  418. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  419. package/dist/prompt-assembly/catalog/schema.js +34 -2
  420. package/dist/prompt-assembly/catalog/sections.js +0 -1
  421. package/dist/prompt-assembly/composer.d.ts +3 -1
  422. package/dist/prompt-assembly/composer.js +1 -1
  423. package/dist/prompt-assembly/event-registry.js +1 -0
  424. package/dist/prompt-assembly/overlay.js +3 -3
  425. package/dist/prompt-assembly/renderers.d.ts +1 -1
  426. package/dist/prompt-assembly/renderers.js +0 -3
  427. package/dist/prompt-assembly/role-base.d.ts +15 -0
  428. package/dist/prompt-assembly/role-base.js +9 -0
  429. package/dist/prompt-assembly/select.d.ts +39 -14
  430. package/dist/prompt-assembly/select.js +47 -16
  431. package/dist/prompt-assembly/sugar.d.ts +17 -11
  432. package/dist/prompt-assembly/sugar.js +8 -3
  433. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  434. package/dist/prompt-assembly/tool-catalog.js +114 -4
  435. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  436. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  437. package/dist/prompt-assembly/types.d.ts +0 -7
  438. package/dist/scenarios/full-body.d.ts +11 -11
  439. package/dist/scenarios/full-body.js +4 -3
  440. package/dist/shell/lex.js +10 -1
  441. package/dist/stores/file/adoption/adopt.js +4 -3
  442. package/dist/stores/file/adoption/marker.js +3 -2
  443. package/dist/stores/file/checkpoint-store.d.ts +21 -4
  444. package/dist/stores/file/checkpoint-store.js +38 -7
  445. package/dist/stores/file/file-history-store.js +18 -11
  446. package/dist/stores/file/index.js +2 -1
  447. package/dist/stores/file/mailbox-store.d.ts +2 -1
  448. package/dist/stores/file/mailbox-store.js +26 -1
  449. package/dist/stores/file/permission-rule-adopt.js +4 -3
  450. package/dist/stores/file/permission-rule-store.js +11 -5
  451. package/dist/stores/file/session-store.d.ts +29 -6
  452. package/dist/stores/file/session-store.js +42 -50
  453. package/dist/tools/artifact/artifact-tool.js +3 -2
  454. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  455. package/dist/tools/fs/bash-program-position.js +56 -9
  456. package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
  457. package/dist/tools/fs/bash-readonly-classifier.js +5 -10
  458. package/dist/tools/fs/fs-bash.js +15 -8
  459. package/dist/tools/fs/fs-glob.d.ts +86 -0
  460. package/dist/tools/fs/fs-glob.js +226 -0
  461. package/dist/tools/fs/fs-read.js +14 -14
  462. package/dist/tools/fs/fs-search-tools.js +7 -7
  463. package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
  464. package/dist/tools/fs/pattern-kill-guard.js +429 -0
  465. package/dist/tools/fs/pdf.d.ts +9 -6
  466. package/dist/tools/fs/pdf.js +3 -3
  467. package/dist/tools/fs/program-read-model.d.ts +57 -7
  468. package/dist/tools/fs/program-read-model.js +11 -1
  469. package/dist/tools/fs/program-read-model.rows.js +78 -21
  470. package/dist/tools/fs/read-deny-home.js +3 -2
  471. package/dist/tools/fs/removal-targets.d.ts +17 -7
  472. package/dist/tools/fs/removal-targets.js +47 -20
  473. package/dist/tools/fs/search.d.ts +10 -0
  474. package/dist/tools/fs/search.js +20 -26
  475. package/dist/tools/fs/shell-read-argv.js +89 -12
  476. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  477. package/dist/tools/fs/shell-read-bindings.js +41 -0
  478. package/dist/tools/fs/shell-read-check.d.ts +10 -0
  479. package/dist/tools/fs/shell-read-check.js +13 -20
  480. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  481. package/dist/tools/fs/shell-read-environment.js +3 -2
  482. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  483. package/dist/tools/fs/shell-read-establish.js +19 -20
  484. package/dist/tools/fs/shell-read-identity.d.ts +12 -9
  485. package/dist/tools/fs/shell-read-identity.js +9 -4
  486. package/dist/tools/fs/shell-read-plan.js +24 -16
  487. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  488. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  489. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  490. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  491. package/dist/tools/fs/shell-reentry-text.js +40 -2
  492. package/dist/tools/todo.js +63 -63
  493. package/dist/tools/web.d.ts +19 -14
  494. package/dist/tools/web.js +46 -61
  495. package/package.json +1 -1
  496. package/test/export-surface.snapshot.json +221 -7
  497. package/wire-changes/core-stores-sql@7.57.0.json +29 -0
  498. package/wire-changes/core@7.56.0.json +3891 -0
  499. package/wire-changes/core@7.57.0.json +1487 -0
  500. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  501. package/wire-changes/mods-kernel@7.57.0.json +29 -0
  502. package/wire-changes/primitives@7.57.0.json +245 -0
@@ -11,14 +11,31 @@ declare function joinUnder(root: string, rel: string): string;
11
11
  declare function parentDirOf(absPath: string): string | undefined;
12
12
  /** The re-join verdict of {@link resolveTrackKey}: an absolute path to operate on, or a NAMED
13
13
  * refusal (the fail-closed arm — a recorded key that would escape `root` is never coerced into
14
- * something writable). A-082 idx5: named so the fence can be part of the public surface. */
14
+ * something writable) carrying the restore ledger's class for it. A-082 idx5: named so the fence can be part of the public surface. */
15
15
  export type FileHistoryTrackKeyResolution = {
16
16
  ok: true;
17
17
  abs: string;
18
18
  } | {
19
19
  ok: false;
20
20
  reason: string;
21
+ class: "key_unresolvable";
21
22
  };
23
+ /**
24
+ * Why a restore declined a file it could reach — the `class` of every {@link FileHistoryRestoreResult.refused}
25
+ * row, named by the arm that decided the refusal (the shared env half and key resolver below, or a backend's
26
+ * own base-unavailable arm) and copied by the backend, never re-derived from the reason text:
27
+ * · `link_safety` — the object at the path is not the regular file the record describes (a symlink, a
28
+ * directory or other kind), its parent chain no longer resolves to the recorded identity, or a guarded
29
+ * write found the path changed under it;
30
+ * · `base_unavailable` — the first touch recorded that the path's pre-edit bytes could not be read (DV-14),
31
+ * so there is no pristine version to write;
32
+ * · `key_unresolvable` — the recorded key cannot be re-joined against this root (it would escape it, or it
33
+ * came from another path family and is absolute or ambiguous here).
34
+ * Damage to the store's own records (a missing version record, a missing or corrupt blob) is not a refusal
35
+ * in any backend: it is a `failed` row.
36
+ */
37
+ export declare const FILE_HISTORY_REFUSAL_CLASSES: readonly ["link_safety", "base_unavailable", "key_unresolvable"];
38
+ export type FileHistoryRefusalClass = (typeof FILE_HISTORY_REFUSAL_CLASSES)[number];
22
39
  /** The path family a track key was MINTED under — the half a bare key string cannot carry. */
23
40
  export type FileHistoryKeyFamily = "posix" | "win";
24
41
  /**
@@ -83,19 +100,27 @@ export declare const FILE_HISTORY_ERROR_CODES: readonly ["track_failed", "snapsh
83
100
  export interface FileHistoryError {
84
101
  /** `not_found` = no boundary for that (scope, entryId) — an absence, never a fault (a boundary that is there
85
102
  * but cannot be read is the verb's `*_failed` with the fault); `aborted` = the signal fired (or the
86
- * fencing discarded a timed-out attempt); `conflict` = a non-destructive-target law refused
87
- * (adopt/import onto a scope with its own history) — and ONLY that, because a caller decides
88
- * whether to stay quiet on it: the engine's fork-carry seat treats `conflict` as "already carried,
89
- * or grown its own" and says nothing, so an adoption that failed for any OTHER reason (a corrupt
90
- * source graph, a blob it cannot reach, a consumed-id ledger it cannot carry, a target whose
91
- * history cannot be judged) must NOT wear this
103
+ * fencing discarded a timed-out attempt); `conflict` = a HISTORY-PRESERVATION law refused the call:
104
+ * doing it would discard or overwrite history that is not the caller's — `adoptScope` / `importHistory`
105
+ * onto a target that holds history of its own (the non-destructive-target law), or `annulTrack` of a
106
+ * record that is no longer just the caller's own mint (a boundary froze it, it grew past its first
107
+ * version, another edit was served it, or the proof read found the file moved or the base-unavailable
108
+ * marker standing). It is never a fault, and it is never "could not judge": a verb that cannot JUDGE its
109
+ * law (an unreadable graph, a listing that fails, a proof read that cannot re-read the path) answers its
110
+ * own `*_failed` (or `aborted`) with the fault. A caller reads `conflict` as "the law answered; the history
111
+ * stands" — the engine's fork-carry seat says nothing on it because the only verb that seat calls is
112
+ * `adoptScope`, whose `conflict` is the target law alone, so an adoption that failed for any OTHER
113
+ * reason (a corrupt source graph, a blob it cannot reach, a consumed-id ledger it cannot carry, a target
114
+ * whose history cannot be judged) must NOT wear this
92
115
  * code or the failure disappears into that silence — those are `adopt_failed`, which the
93
116
  * ADOPTION FAMILY shares: `importHistory` publishes under the same target law and answers the
94
- * same code for the same non-conflict failures, and `exportHistory` answers it for a history it cannot
95
- * read whole (its `unsupported_format` names a bad ENVELOPE or
96
- * work its shape drove; a fault in the PUBLISH step itself — the disk refusing a good graph —
97
- * answers `adopt_failed`); `unsupported_format`
98
- * = a foreign-epoch or wrong-version envelope; the rest name the verb that failed. */
117
+ * same code for the same non-conflict failures — a source that cannot supply a referenced blob (it is
118
+ * absent, its read throws, or its bytes do not hash to their address), a target whose history cannot
119
+ * be judged, a fault in staging or publishing a good graph (the disk refusing it) — and `exportHistory`
120
+ * answers it for a history it cannot read whole. `unsupported_format` is the import DOOR's refusal and
121
+ * nothing else: a foreign-epoch or wrong-version envelope, or an envelope whose content the closed sets
122
+ * (or the backend's own record-naming rules) cannot hold, refused before any blob is fetched; the rest
123
+ * name the verb that failed. */
99
124
  code: (typeof FILE_HISTORY_ERROR_CODES)[number];
100
125
  message: string;
101
126
  /** The backend's judgment of a FAULT — it could not do what it was asked — as a {@link GovernanceRetryClass}
@@ -172,10 +197,12 @@ export type FileHistoryRestoreResult = {
172
197
  filesChanged: string[];
173
198
  /** Track keys already equal to the target (untouched — content-hash proven, never mtime). */
174
199
  identicalSkipped: string[];
175
- /** Per-file security/consistency refusals (skipped, counted, never failing the whole restore). */
200
+ /** Per-file security/consistency refusals (skipped, counted, never failing the whole restore); `class` is
201
+ * the closed reading of why ({@link FileHistoryRefusalClass}), `reason` the sentence for a person. */
176
202
  refused: Array<{
177
203
  path: string;
178
204
  reason: string;
205
+ class: FileHistoryRefusalClass;
179
206
  }>;
180
207
  /** Per-file operational failures (env write/remove errors, aborts after k writes). */
181
208
  failed: Array<{
@@ -192,6 +219,34 @@ export interface FileHistoryDiffStats {
192
219
  insertions: number;
193
220
  deletions: number;
194
221
  }
222
+ /** `Runner.rewindFiles`' request — the out-of-run code-only rewind (the reference's `rewind_files` control request). */
223
+ export interface RewindFilesRequest {
224
+ /** The session whose history is converged. It must exist. */
225
+ sessionId: string;
226
+ /** The boundary key: the entry id of a turn's FIRST user entry — the id space `TaskSpec.rewindFilesTo`
227
+ * addresses ("the files as they were when that turn began"). An entry with no boundary of its own refuses. */
228
+ to: string;
229
+ /** Preview only: the working tree is not written (a fork whose history was never carried may have its carry
230
+ * completed — the same carry the session's next run performs). */
231
+ dryRun?: boolean;
232
+ /** Caller cancel for the restore. */
233
+ signal?: AbortSignal;
234
+ }
235
+ /** `Runner.rewindFiles`' answer. A refusal is a thrown `Error` carrying a `code`. */
236
+ export type RewindFilesResult =
237
+ /** `preview: null` = no preview for this request (the backend implements no `diffStats`, or answered none);
238
+ * an empty `filesChanged` with zero counts = a real "nothing would change". */
239
+ {
240
+ dryRun: true;
241
+ preview: FileHistoryDiffStats | null;
242
+ }
243
+ /** The store's ledger as it answered: `complete`, or `partial` with every refused / failed file on it. */
244
+ | {
245
+ dryRun: false;
246
+ restore: FileHistoryRestoreResult & {
247
+ outcome: "complete" | "partial";
248
+ };
249
+ };
195
250
  /** The line-diff bound (see {@link countRestoreLineDiff}): a pair whose edit distance exceeds this
196
251
  * is counted as a whole-file replacement. Public so a preview UI can state what it is showing. */
197
252
  export declare const FILE_HISTORY_DIFF_LINE_BUDGET = 2000;
@@ -277,8 +332,9 @@ export declare function fileHistoryExportDigest(data: FileHistoryExport): string
277
332
  * The import DOOR's structural judgment, shared by every backend (a second implementation is a second
278
333
  * opinion about what is safe to accept): the envelope must carry THIS format version and every row
279
334
  * must be shaped and self-described from the closed sets — `unsupported_format` otherwise, never a
280
- * coercion. Backends call this BEFORE fetching a single blob, so a foreign-epoch payload costs
281
- * nothing and changes nothing.
335
+ * coercion and never a throw (a payload that cannot be read is refused in the same word). Backends call
336
+ * this BEFORE fetching a single blob, so a foreign-epoch payload costs nothing and changes nothing, and
337
+ * `unsupported_format` is a word only this door (and a backend's own record-naming rule) says.
282
338
  */
283
339
  export declare function validateFileHistoryExport(data: FileHistoryExport): FileHistoryResult;
284
340
  /**
@@ -345,7 +401,9 @@ export interface FileHistoryStore {
345
401
  * still matches what the mint recorded (bytes still absent for an existed-not mint, still the same
346
402
  * hash for a captured one). A file that changed keeps its record, because the alternative is
347
403
  * deleting the only baseline of a file the agent really did modify — damage rewind could no longer
348
- * reach, which is strictly worse than a stale record.
404
+ * reach, which is strictly worse than a stale record. Every refusal above is the history-preservation
405
+ * law (`conflict`, see {@link FileHistoryError.code}); a proof read that cannot re-read the path at all
406
+ * judged nothing, and keeps the record with `track_failed` (`aborted` when the signal fired) instead.
349
407
  */
350
408
  annulTrack(scope: string, absPath: string, root: string, verify?: {
351
409
  env: ExecutionEnv;
@@ -513,7 +571,10 @@ export interface FileHistoryStore {
513
571
  * re-publish). A non-empty target with any other content ⇒ typed `conflict` refusal — atomic
514
572
  * visibility prevents half-graphs, this law prevents publishing the WRONG complete graph over
515
573
  * locally-grown history. A target whose history cannot be judged ⇒ `adopt_failed`, before any blob is
516
- * fetched; a source that cannot supply a referenced blob ⇒ `adopt_failed`. `exportHistory` answers a
574
+ * fetched; a source that cannot supply a referenced blob — absent, its read throws, or bytes that fail
575
+ * their content address — ⇒ `adopt_failed`, and so is a fault in staging or publishing the graph.
576
+ * `unsupported_format` is the door's refusal alone ({@link validateFileHistoryExport}, before any blob
577
+ * is fetched). `exportHistory` answers a
517
578
  * {@link FileHistoryExportResult}: the whole graph, `null` for nothing to export, or `adopt_failed` with the
518
579
  * fault for a history it cannot read whole (an unreadable tracked set, boundaries that cannot be judged) —
519
580
  * never a partial graph, and never a `null` that hides a fault.
@@ -600,13 +661,30 @@ export declare function captureFileBackupViaEnv(env: ExecutionEnv, absPath: stri
600
661
  * refusal state that stops a later touch from minting already-modified bytes as pristine — erasing
601
662
  * it on an ambiguous failure re-opens exactly the DV-14 hole it exists to close. It stays
602
663
  * retractable through the `"proven"` path, which needs no evidence read at all.
664
+ *
665
+ * THREE verdicts, because a backend answers them three ways: `unchanged` retracts; `kept` is the
666
+ * history-preservation law keeping the record (`conflict`); `unjudged` is a read that never happened —
667
+ * the path could not be re-read, or the signal fired — so nothing was judged and the record stays with
668
+ * the verb's own failure (`track_failed`, or `aborted` when `aborted` is true), never with the law's word.
603
669
  */
604
- export declare function worldStillMatchesMint(env: ExecutionEnv, absPath: string, root: string, baseAvailable: boolean, mintedBlobHash: string | null, signal?: AbortSignal): Promise<{
605
- unchanged: true;
670
+ export type FileHistoryMintProof = {
671
+ verdict: "unchanged";
606
672
  } | {
607
- unchanged: false;
673
+ verdict: "kept";
608
674
  reason: string;
609
- }>;
675
+ } | {
676
+ verdict: "unjudged";
677
+ reason: string;
678
+ aborted: boolean;
679
+ };
680
+ export declare function worldStillMatchesMint(env: ExecutionEnv, absPath: string, root: string, baseAvailable: boolean, mintedBlobHash: string | null, signal?: AbortSignal): Promise<FileHistoryMintProof>;
681
+ /** A backend's ONE mapping of a proof that did not say `unchanged` onto the annul verb's failure — the two
682
+ * bundled backends call it, and an out-of-tree backend reuses it with the proof read itself. */
683
+ export declare function annulProofFailure(proof: Exclude<FileHistoryMintProof, {
684
+ verdict: "unchanged";
685
+ }>, absPath: string): FileHistoryResult & {
686
+ ok: false;
687
+ };
610
688
  /**
611
689
  * DV-13's metadata rule applied to the MODE axis (design/381 slice 3), and it is a rule about
612
690
  * EVIDENCE rather than about equality: metadata may prove two states DIFFERENT, never the same. Two
@@ -649,9 +727,13 @@ export type FileRestoreApplyOutcome =
649
727
  } | {
650
728
  outcome: "identical";
651
729
  modeNotPreserved?: true;
652
- } | {
730
+ }
731
+ /** Every refusal this half decides is about the object at the path (its kind, its parent chain, a guarded
732
+ * write's precondition), so its class is `link_safety`; a backend copies it into the ledger row. */
733
+ | {
653
734
  outcome: "refused";
654
735
  reason: string;
736
+ class: "link_safety";
655
737
  } | {
656
738
  outcome: "failed";
657
739
  reason: string;
@@ -32,6 +32,7 @@ function parentDirOf(absPath) {
32
32
  const parent = cut.slice(0, i);
33
33
  return win ? parent.replace(/\//g, "\\") : parent;
34
34
  }
35
+ export const FILE_HISTORY_REFUSAL_CLASSES = Object.freeze(["link_safety", "base_unavailable", "key_unresolvable"]);
35
36
  export function trackKeyFamilyOf(root) {
36
37
  return isWinFormPath(root) ? "win" : "posix";
37
38
  }
@@ -53,17 +54,17 @@ export function resolveTrackKey(root, key, minted) {
53
54
  const win = isWinFormPath(root);
54
55
  if (minted !== undefined && minted.family !== trackKeyFamilyOf(root)) {
55
56
  if (minted.kind === "absolute") {
56
- return { ok: false, reason: `foreign-family absolute key cannot be restored here (recorded under a ${minted.family} root, this root is ${trackKeyFamilyOf(root)}): ${key}` };
57
+ return { ok: false, reason: `foreign-family absolute key cannot be restored here (recorded under a ${minted.family} root, this root is ${trackKeyFamilyOf(root)}): ${key}`, class: "key_unresolvable" };
57
58
  }
58
59
  if (isUnsafeRelPathLike(normSlash(key)) || key.includes("\\")) {
59
- return { ok: false, reason: `foreign-family key is ambiguous across path families (recorded under a ${minted.family} root, this root is ${trackKeyFamilyOf(root)}): ${key}` };
60
+ return { ok: false, reason: `foreign-family key is ambiguous across path families (recorded under a ${minted.family} root, this root is ${trackKeyFamilyOf(root)}): ${key}`, class: "key_unresolvable" };
60
61
  }
61
62
  }
62
63
  const keyN = win ? normSlash(key) : key;
63
64
  if (isAbsoluteForFamily(pathFamilyOf({ root }), keyN) || (win && /^[A-Za-z]:/.test(keyN)))
64
65
  return { ok: true, abs: key };
65
66
  if (win ? isUnsafeRelPathLike(keyN) : keyN.split("/").includes(".."))
66
- return { ok: false, reason: `unsafe recorded key escapes root: ${key}` };
67
+ return { ok: false, reason: `unsafe recorded key escapes root: ${key}`, class: "key_unresolvable" };
67
68
  return { ok: true, abs: joinUnder(root, keyN) };
68
69
  }
69
70
  export const FILE_HISTORY_ERROR_CODES = Object.freeze(["track_failed", "snapshot_failed", "restore_failed", "adopt_failed", "not_found", "aborted", "unsupported_format", "conflict"]);
@@ -157,6 +158,14 @@ export function fileHistoryExportDigest(data) {
157
158
  return createHash("sha256").update(JSON.stringify(canonical)).digest("hex");
158
159
  }
159
160
  export function validateFileHistoryExport(data) {
161
+ try {
162
+ return judgeFileHistoryEnvelope(data);
163
+ }
164
+ catch (err) {
165
+ return { ok: false, error: { code: "unsupported_format", message: `file-history import payload cannot be read: ${thrownText(err)}` } };
166
+ }
167
+ }
168
+ function judgeFileHistoryEnvelope(data) {
160
169
  const bad = (message) => ({ ok: false, error: { code: "unsupported_format", message } });
161
170
  if (data === null || typeof data !== "object")
162
171
  return bad("file-history import payload is not an envelope");
@@ -181,6 +190,8 @@ export function validateFileHistoryExport(data) {
181
190
  if (typeof t.baseAvailable !== "boolean" || !Array.isArray(t.versions))
182
191
  return bad(`tracked row ${t.relOrAbsPath} is missing its base-availability state or version chain`);
183
192
  for (const v of t.versions) {
193
+ void v?.backupTime;
194
+ void v?.parentIdent;
184
195
  if (typeof v?.version !== "number" || !Number.isInteger(v.version) || v.version < 1)
185
196
  return bad(`tracked row ${t.relOrAbsPath} carries a non-integer version number`);
186
197
  if (v.blobHash !== null && (typeof v.blobHash !== "string" || !/^[0-9a-f]{64}$/.test(v.blobHash)))
@@ -272,18 +283,24 @@ export async function captureFileBackupViaEnv(env, absPath, root, signal) {
272
283
  }
273
284
  export async function worldStillMatchesMint(env, absPath, root, baseAvailable, mintedBlobHash, signal) {
274
285
  if (!baseAvailable) {
275
- return { unchanged: false, reason: "the first touch recorded a base-UNAVAILABLE marker, whose whole purpose is to refuse a fake pristine later — an ambiguous failure may not erase it" };
286
+ return { verdict: "kept", reason: "the first touch recorded a base-UNAVAILABLE marker, whose whole purpose is to refuse a fake pristine later — an ambiguous failure may not erase it" };
276
287
  }
277
288
  const cap = await captureFileBackupViaEnv(env, absPath, root, signal);
278
289
  if (cap.state === "absent") {
279
- return mintedBlobHash === null ? { unchanged: true } : { unchanged: false, reason: "the file recorded at the first touch is gone now" };
290
+ return mintedBlobHash === null ? { verdict: "unchanged" } : { verdict: "kept", reason: "the file recorded at the first touch is gone now" };
280
291
  }
281
292
  if (cap.state === "file") {
282
293
  if (mintedBlobHash === null)
283
- return { unchanged: false, reason: "the path was recorded as NOT EXISTING at the first touch but holds bytes now" };
284
- return cap.hash === mintedBlobHash ? { unchanged: true } : { unchanged: false, reason: "the file's bytes differ from the ones recorded at the first touch" };
294
+ return { verdict: "kept", reason: "the path was recorded as NOT EXISTING at the first touch but holds bytes now" };
295
+ return cap.hash === mintedBlobHash ? { verdict: "unchanged" } : { verdict: "kept", reason: "the file's bytes differ from the ones recorded at the first touch" };
285
296
  }
286
- return { unchanged: false, reason: `the path could not be re-read to prove it is unchanged (${cap.state === "aborted" ? "aborted" : cap.cause})` };
297
+ return { verdict: "unjudged", reason: `the path could not be re-read to prove it is unchanged (${cap.state === "aborted" ? "aborted" : cap.cause})`, aborted: cap.state === "aborted" };
298
+ }
299
+ export function annulProofFailure(proof, absPath) {
300
+ if (proof.verdict === "kept") {
301
+ return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} is NOT retractable: ${proof.reason} — the write this retraction compensates for may have changed the file, and deleting the only baseline of a modified file is worse than keeping a stale record` } };
302
+ }
303
+ return { ok: false, error: { code: proof.aborted ? "aborted" : "track_failed", message: `first-touch record for ${absPath} was left in place: ${proof.reason}, so whether the write this retraction compensates for changed the file was not judged` } };
287
304
  }
288
305
  export function modeProvenDifferent(recorded, current) {
289
306
  return recorded !== undefined && current !== undefined && recorded !== current;
@@ -317,7 +334,7 @@ export async function applyFileRestoreViaEnv(env, absPath, target, opts) {
317
334
  }
318
335
  const w = await writeRestoredBytes(env, absPath, target.bytes, signal);
319
336
  if (!w.ok)
320
- return { outcome: w.refused ? "refused" : "failed", reason: `write: ${w.code}` };
337
+ return w.refused ? { outcome: "refused", reason: `write: ${w.code}`, class: "link_safety" } : { outcome: "failed", reason: `write: ${w.code}` };
321
338
  const modeAfter = await applyRecordedMode(env, absPath, opts, undefined);
322
339
  return { outcome: "applied", ...(modeAfter === "unpreserved" || modeAfter === "applied_unpreserved" ? { modeNotPreserved: true } : {}) };
323
340
  }
@@ -330,6 +347,7 @@ async function restorePreflight(env, absPath, opts) {
330
347
  reason: info.value.kind === "symlink"
331
348
  ? "restore target is a SYMLINK — the recorded bytes belong to the file that was edited, not to whatever the link now points at"
332
349
  : `restore target is a ${info.value.kind}, not a regular file — the recorded bytes are not this object's`,
350
+ class: "link_safety",
333
351
  },
334
352
  };
335
353
  }
@@ -345,6 +363,7 @@ async function restorePreflight(env, absPath, opts) {
345
363
  refused: {
346
364
  outcome: "refused",
347
365
  reason: `restore target's parent chain changed identity since it was recorded (recorded ${JSON.stringify(opts.parentIdent)}, now ${JSON.stringify(now)}) — writing here could land outside the task root`,
366
+ class: "link_safety",
348
367
  },
349
368
  };
350
369
  }
@@ -542,9 +561,8 @@ export class InMemoryFileHistoryStore {
542
561
  if (before !== undefined)
543
562
  return { ok: false, error: { code: "conflict", message: before } };
544
563
  const proof = verify === undefined ? undefined : await worldStillMatchesMint(verify.env, absPath, root, t.baseAvailable, t.versions[0]?.blobHash ?? null, verify.signal);
545
- if (proof !== undefined && !proof.unchanged) {
546
- return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} is NOT retractable: ${proof.reason} — the write this retraction compensates for may have changed the file, and deleting the only baseline of a modified file is worse than keeping a stale record` } };
547
- }
564
+ if (proof !== undefined && proof.verdict !== "unchanged")
565
+ return annulProofFailure(proof, absPath);
548
566
  const after = ineligible();
549
567
  if (after !== undefined)
550
568
  return { ok: false, error: { code: "conflict", message: after } };
@@ -655,7 +673,7 @@ export class InMemoryFileHistoryStore {
655
673
  let targetVersion = boundary.get(key);
656
674
  if (targetVersion === undefined) {
657
675
  if (!t.baseAvailable) {
658
- ledger.refused.push({ path: key, reason: "base_unavailable" });
676
+ ledger.refused.push({ path: key, reason: "base_unavailable", class: "base_unavailable" });
659
677
  continue;
660
678
  }
661
679
  targetVersion = 1;
@@ -667,7 +685,7 @@ export class InMemoryFileHistoryStore {
667
685
  }
668
686
  const resolved = resolveTrackKey(root, key, t.keyDesc);
669
687
  if (!resolved.ok) {
670
- ledger.refused.push({ path: key, reason: resolved.reason });
688
+ ledger.refused.push({ path: key, reason: resolved.reason, class: resolved.class });
671
689
  continue;
672
690
  }
673
691
  let target;
@@ -698,7 +716,7 @@ export class InMemoryFileHistoryStore {
698
716
  else if (applied.outcome === "identical")
699
717
  ledger.identicalSkipped.push(key);
700
718
  else if (applied.outcome === "refused")
701
- ledger.refused.push({ path: key, reason: applied.reason });
719
+ ledger.refused.push({ path: key, reason: applied.reason, class: applied.class });
702
720
  else
703
721
  ledger.failed.push({ path: key, reason: applied.reason });
704
722
  if ((applied.outcome === "applied" || applied.outcome === "identical") && applied.modeNotPreserved === true)
@@ -866,7 +884,7 @@ export class InMemoryFileHistoryStore {
866
884
  }
867
885
  }
868
886
  catch (err) {
869
- return { ok: false, error: { code: "unsupported_format", message: `importHistory failed: ${thrownText(err)}`, ...caughtFault(err) } };
887
+ return { ok: false, error: { code: "adopt_failed", message: `importHistory failed: ${thrownText(err)}`, ...caughtFault(err) } };
870
888
  }
871
889
  }
872
890
  async importStaged(scope, data, srcGetBlob, needed) {
@@ -880,12 +898,12 @@ export class InMemoryFileHistoryStore {
880
898
  bytes = await srcGetBlob(hash);
881
899
  }
882
900
  catch (err) {
883
- return { ok: false, error: { code: "unsupported_format", message: `source blob ${hash} fetch failed: ${thrownText(err)}`, ...caughtFault(err) } };
901
+ return { ok: false, error: { code: "adopt_failed", message: `source blob ${hash} fetch failed: ${thrownText(err)}`, ...caughtFault(err) } };
884
902
  }
885
903
  if (bytes === undefined)
886
904
  return { ok: false, error: { code: "adopt_failed", message: `source blob ${hash} is missing — the envelope's graph cannot be completed, so nothing is published` } };
887
905
  if (createHash("sha256").update(bytes).digest("hex") !== hash) {
888
- return { ok: false, error: { code: "unsupported_format", message: `source blob ${hash} fails content-address integrity — refused, nothing published` } };
906
+ return { ok: false, error: { code: "adopt_failed", message: `source blob ${hash} fails content-address integrity — refused, nothing published` } };
889
907
  }
890
908
  staged.set(hash, bytes);
891
909
  }
@@ -912,7 +930,7 @@ export class InMemoryFileHistoryStore {
912
930
  return { ok: true };
913
931
  }
914
932
  catch (err) {
915
- return { ok: false, error: { code: "unsupported_format", message: `importHistory failed: ${thrownText(err)}`, ...caughtFault(err) } };
933
+ return { ok: false, error: { code: "adopt_failed", message: `importHistory failed: ${thrownText(err)}`, ...caughtFault(err) } };
916
934
  }
917
935
  }
918
936
  }
@@ -1,4 +1,4 @@
1
- import type { GatePass } from "./runner/gate-exit.js";
1
+ import { type GatePass } from "./runner/gate-exit.js";
2
2
  import type { ToolGateResult } from "./hooks.js";
3
3
  /**
4
4
  * Run the fold over the pass: adjudicate, fold the hook-ask, tighten. Writes `req` (re-minted over the FINAL
@@ -2,6 +2,8 @@ import { inlineUntrusted } from "./untrusted-text.js";
2
2
  import { markTightenMessage } from "./safety-axis-vocab.js";
3
3
  import { PROBE_REASON_MAX, normalizeProbeCause } from "./checkpoint-store.js";
4
4
  import { normalizeReadRootCandidate } from "./read-root-candidate.js";
5
+ import { engineFailClosedExit, hookDenyExit } from "./runner/gate-exit.js";
6
+ import { readRejudge, screenRewrite } from "./rewrite-rejudge.js";
5
7
  import { traceHookCrash } from "./gate-crash-trace.js";
6
8
  import { writeProtectionMandated, writeProtectionTightenDecision } from "./write-protect.js";
7
9
  import { createGateDeadline, awaitWriteProtectionJudgment, gateWaitFailureOf, withGateTimeout } from "./gate-bounded-await.js";
@@ -26,7 +28,7 @@ export async function runGateFold(pass) {
26
28
  catch (error) {
27
29
  unread = { error };
28
30
  }
29
- pass.decision = unread !== undefined ? failedJudgmentDeny(unread.error, callSignal ?? input.abortSignal, (e) => traceHookCrash(input, e, notifier), "the call's target reading", { toolName, toolCallId }) : adjudicate ? refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(pass.req, callSignal) : adjudicate(pass.req))) : { action: "allow" };
31
+ pass.decision = unread !== undefined ? failedJudgmentDeny(unread.error, callSignal ?? input.abortSignal, (e) => traceHookCrash(input, e, notifier), "the call's target reading", { toolName, toolCallId }) : adjudicate ? refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(pass.req, callSignal) : adjudicate(pass.req)), { call: pass.req }) : { action: "allow" };
30
32
  {
31
33
  const read = ledger.fromDecision(pass.decision);
32
34
  pass.decision = read.decision;
@@ -38,6 +40,18 @@ export async function runGateFold(pass) {
38
40
  if (attributed !== undefined)
39
41
  pass.classifierRound = attributed;
40
42
  }
43
+ const rewritten = pass.screening !== undefined && pass.decision.action !== "deny" ? readRejudge(pass.req, pass.currentInput, pass.decision) : undefined;
44
+ if (pass.screening !== undefined && rewritten?.kind === "rewritten") {
45
+ const second = await screenRewrite(pass.screening, pass.req, rewritten.form, `the rewritten call to "${toolName}"`);
46
+ if (second.kind === "refused") {
47
+ pass.currentInput = rewritten.form;
48
+ return second.by === "hook" ? hookDenyExit(pass, second.reason) : await engineFailClosedExit(pass, second.reason);
49
+ }
50
+ if (second.answer?.additionalContext)
51
+ pass.preToolContext.push(second.answer.additionalContext);
52
+ pass.hookAsk = second.answer?.action === "ask" ? second.answer : undefined;
53
+ pass.hookAllowedBy = second.answer?.action === "allow" ? (second.answeredBy !== undefined ? [second.answeredBy] : []) : undefined;
54
+ }
41
55
  if ((pass.decision.action === "allow" || pass.decision.action === "ask") && pass.decision.updatedInput !== undefined) {
42
56
  pass.policyRewrite = argsAsTheToolReads(pass.req, pass.decision.updatedInput);
43
57
  }
@@ -124,7 +138,7 @@ export async function runGateFold(pass) {
124
138
  if (tighten) {
125
139
  pass.decision = {
126
140
  action: "ask",
127
- message: markTightenMessage(toolName, "irreversible"),
141
+ message: markTightenMessage(toolName, input.irreversibility === "always" ? "irreversible" : "unproven"),
128
142
  decisionReason: "safety",
129
143
  ...(probeReason !== undefined ? { probeReason } : {}),
130
144
  ...(probeCause !== undefined ? { probeCause } : {}),
@@ -219,19 +233,18 @@ function applyShellReadVerdict(pass, answer, toolName, shellGated) {
219
233
  pass.shellReadDetails = verdict.details;
220
234
  if (pass.decision.action !== "allow") {
221
235
  if (pass.decision.action === "ask")
222
- pass.decision = { ...withProbeMandate(pass.decision, account), ...silencedBy(verdict, pass.decision) };
236
+ pass.decision = silencedBy(withProbeMandate(pass.decision, account), verdict, pass.req);
223
237
  return;
224
238
  }
225
239
  const candidate = normalizeReadRootCandidate(verdict.readRootCandidate);
226
- pass.decision = {
240
+ pass.decision = silencedBy({
227
241
  action: "ask",
228
242
  message: shellReadAskMessage(toolName, verdict),
229
243
  decisionReason: "safety",
230
244
  probeMandated: true,
231
- ...silencedBy(verdict, {}),
232
245
  ...(account !== undefined ? { probeReason: account } : {}),
233
246
  ...(candidate !== undefined ? { probeReadRootCandidate: candidate } : {}),
234
- };
247
+ }, verdict, pass.req);
235
248
  if (candidate !== undefined)
236
249
  pass.shellReadOffer = true;
237
250
  pass.tightenedBy = shellGated ? "shell_gate" : "safety";
@@ -242,17 +255,16 @@ function applyShellReadVerdict(pass, answer, toolName, shellGated) {
242
255
  if (verdict.details !== undefined)
243
256
  pass.shellReadDetails = verdict.details;
244
257
  if (pass.decision.action === "ask")
245
- pass.decision = { ...pass.decision, ...silencedBy(verdict, pass.decision) };
258
+ pass.decision = silencedBy(pass.decision, verdict, pass.req);
246
259
  if (pass.decision.action === "allow") {
247
260
  const candidate = normalizeReadRootCandidate(verdict.readRootCandidate);
248
- pass.decision = {
261
+ pass.decision = silencedBy({
249
262
  action: "ask",
250
263
  message: shellReadAskMessage(toolName, verdict),
251
264
  decisionReason: "safety",
252
- ...silencedBy(verdict, {}),
253
265
  ...(account !== undefined ? { probeReason: account } : {}),
254
266
  ...(candidate !== undefined ? { probeReadRootCandidate: candidate } : {}),
255
- };
267
+ }, verdict, pass.req);
256
268
  if (candidate !== undefined)
257
269
  pass.shellReadOffer = true;
258
270
  pass.tightenedBy = shellGated ? "shell_gate" : "safety";