@sema-agent/core 7.55.0 → 7.56.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 (418) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/dist/agents/cascade.js +1 -1
  3. package/dist/agents/cc-peer-directory.js +1 -0
  4. package/dist/agents/child-model-seat.d.ts +0 -11
  5. package/dist/agents/child-model-seat.js +0 -3
  6. package/dist/agents/list-agents-tool.d.ts +3 -1
  7. package/dist/agents/list-agents-tool.js +7 -7
  8. package/dist/agents/peer-directory.d.ts +22 -4
  9. package/dist/agents/peer-directory.js +24 -2
  10. package/dist/agents/peer-session-drain.js +2 -2
  11. package/dist/agents/repair-loop.js +2 -2
  12. package/dist/agents/send-message-tool.js +4 -4
  13. package/dist/agents/subagent.d.ts +6 -4
  14. package/dist/agents/subagent.js +64 -60
  15. package/dist/agents/tool-filter.d.ts +7 -5
  16. package/dist/agents/tool-filter.js +12 -9
  17. package/dist/agents/verify.d.ts +3 -2
  18. package/dist/agents/verify.js +3 -3
  19. package/dist/brain/anthropic.js +30 -73
  20. package/dist/brain/media-degrade.d.ts +18 -7
  21. package/dist/brain/media-degrade.js +13 -2
  22. package/dist/brain/model-capability.d.ts +37 -0
  23. package/dist/brain/model-capability.js +34 -0
  24. package/dist/brain/model-presets.d.ts +2 -8
  25. package/dist/brain/model-presets.js +1 -6
  26. package/dist/brain/open-responses.js +13 -26
  27. package/dist/brain/openai.js +14 -87
  28. package/dist/brain/reasoning-request.d.ts +96 -0
  29. package/dist/brain/reasoning-request.js +174 -0
  30. package/dist/brain/reasoning.d.ts +11 -11
  31. package/dist/brain/reasoning.js +4 -3
  32. package/dist/brain/request-params.d.ts +7 -4
  33. package/dist/brain/request-params.js +7 -4
  34. package/dist/brain/status-sink.d.ts +20 -0
  35. package/dist/brain/status-sink.js +7 -0
  36. package/dist/core/a2a.d.ts +2 -1
  37. package/dist/core/a2a.js +19 -13
  38. package/dist/core/agent-definition.d.ts +10 -0
  39. package/dist/core/allow-entry.d.ts +20 -13
  40. package/dist/core/allow-entry.js +26 -22
  41. package/dist/core/allow-rule-shadow.d.ts +3 -3
  42. package/dist/core/ask-origin.d.ts +64 -18
  43. package/dist/core/ask-origin.js +63 -23
  44. package/dist/core/ask-question.d.ts +51 -8
  45. package/dist/core/ask-question.js +3 -4
  46. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  47. package/dist/core/ask-unresolvable-notice.js +16 -2
  48. package/dist/core/checkpoint-generation.d.ts +53 -0
  49. package/dist/core/checkpoint-generation.js +35 -0
  50. package/dist/core/checkpoint-queries.d.ts +180 -0
  51. package/dist/core/checkpoint-queries.js +272 -0
  52. package/dist/core/checkpoint-requirements.d.ts +13 -1
  53. package/dist/core/checkpoint-requirements.js +4 -0
  54. package/dist/core/checkpoint-store.d.ts +88 -24
  55. package/dist/core/checkpoint-store.js +24 -9
  56. package/dist/core/cross-boundary-taint.d.ts +6 -5
  57. package/dist/core/cross-boundary-taint.js +1 -3
  58. package/dist/core/decision-receipt.d.ts +37 -3
  59. package/dist/core/decision-receipt.js +17 -17
  60. package/dist/core/delegation-not-started.d.ts +6 -0
  61. package/dist/core/delegation-not-started.js +17 -0
  62. package/dist/core/engine-attestation.d.ts +93 -0
  63. package/dist/core/engine-attestation.js +70 -0
  64. package/dist/core/engine-capabilities.d.ts +4 -1
  65. package/dist/core/engine-capabilities.js +1 -1
  66. package/dist/core/engine-notice.d.ts +30 -11
  67. package/dist/core/file-history-store.d.ts +90 -14
  68. package/dist/core/file-history-store.js +23 -15
  69. package/dist/core/gate-fold.d.ts +1 -1
  70. package/dist/core/gate-fold.js +22 -10
  71. package/dist/core/gate-lanes.js +73 -64
  72. package/dist/core/gate-outcome.d.ts +26 -5
  73. package/dist/core/gate-outcome.js +26 -0
  74. package/dist/core/governance-codes.d.ts +5 -1
  75. package/dist/core/governance-codes.js +6 -0
  76. package/dist/core/hooks.d.ts +17 -16
  77. package/dist/core/hooks.js +3 -1
  78. package/dist/core/host-floor.d.ts +128 -0
  79. package/dist/core/host-floor.js +206 -0
  80. package/dist/core/host-target.d.ts +38 -3
  81. package/dist/core/host-target.js +38 -5
  82. package/dist/core/mcp.d.ts +5 -1
  83. package/dist/core/mcp.js +67 -41
  84. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  85. package/dist/core/memory-engine/engine.js +4 -4
  86. package/dist/core/memory-engine/layout.d.ts +60 -8
  87. package/dist/core/memory-engine/layout.js +65 -6
  88. package/dist/core/model-seat.d.ts +10 -3
  89. package/dist/core/mods/classic-events.d.ts +67 -0
  90. package/dist/core/mods/classic-events.js +1 -0
  91. package/dist/core/mods/dollar.d.ts +13 -0
  92. package/dist/core/mods/extension-call.d.ts +31 -0
  93. package/dist/core/mods/extension-call.js +43 -0
  94. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  95. package/dist/core/mods/kernel/dispatch.js +140 -69
  96. package/dist/core/mods/kernel/events.d.ts +47 -11
  97. package/dist/core/mods/kernel/events.js +66 -42
  98. package/dist/core/mods/kernel/index.d.ts +4 -4
  99. package/dist/core/mods/kernel/index.js +2 -2
  100. package/dist/core/mods/kernel/receive.d.ts +39 -5
  101. package/dist/core/mods/kernel/receive.js +290 -17
  102. package/dist/core/mods/kernel/registration.d.ts +33 -2
  103. package/dist/core/mods/kernel/registration.js +6 -7
  104. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  105. package/dist/core/mods/kernel/site-rules.js +24 -42
  106. package/dist/core/mods/spec-seats.d.ts +69 -0
  107. package/dist/core/mods/spec-seats.js +114 -0
  108. package/dist/core/mods/stations.d.ts +28 -8
  109. package/dist/core/mods/stations.js +29 -13
  110. package/dist/core/mods/tool-call.d.ts +79 -0
  111. package/dist/core/mods/tool-call.js +152 -0
  112. package/dist/core/namespaced-rule-name.d.ts +32 -38
  113. package/dist/core/namespaced-rule-name.js +29 -36
  114. package/dist/core/parent-spec-seat.d.ts +6 -1
  115. package/dist/core/parent-spec-seat.js +2 -0
  116. package/dist/core/park-selfcheck.js +1 -0
  117. package/dist/core/permission-rule-consent.d.ts +19 -0
  118. package/dist/core/permission-rule-consent.js +116 -26
  119. package/dist/core/permission-rule-model.d.ts +14 -3
  120. package/dist/core/permission-rule-model.js +39 -24
  121. package/dist/core/permission-rule-org.d.ts +6 -2
  122. package/dist/core/permission-rule-org.js +7 -3
  123. package/dist/core/permission-rule-provider.d.ts +5 -2
  124. package/dist/core/permission-rule-provider.js +41 -11
  125. package/dist/core/permission-rule-store.d.ts +3 -2
  126. package/dist/core/permission-rule-store.js +11 -2
  127. package/dist/core/permission-rule-sync.js +3 -2
  128. package/dist/core/permission-rule-syntax.d.ts +5 -4
  129. package/dist/core/permission-rule-syntax.js +2 -2
  130. package/dist/core/permission-rules.d.ts +4 -4
  131. package/dist/core/permission-rules.js +11 -20
  132. package/dist/core/persisted-rule-arms.d.ts +2 -2
  133. package/dist/core/persisted-rule-arms.js +10 -12
  134. package/dist/core/principal-name.d.ts +20 -0
  135. package/dist/core/principal-name.js +22 -0
  136. package/dist/core/prompt-section-seat.js +4 -6
  137. package/dist/core/protocol-http-auth.d.ts +26 -5
  138. package/dist/core/protocol-http-auth.js +137 -4
  139. package/dist/core/retired-keys.d.ts +16 -0
  140. package/dist/core/retired-keys.js +16 -4
  141. package/dist/core/rewrite-rejudge.d.ts +60 -0
  142. package/dist/core/rewrite-rejudge.js +36 -0
  143. package/dist/core/roles.d.ts +28 -1
  144. package/dist/core/roles.js +31 -19
  145. package/dist/core/rule-lane-reads.d.ts +20 -15
  146. package/dist/core/rule-lane-reads.js +45 -17
  147. package/dist/core/rule-owner.d.ts +3 -3
  148. package/dist/core/rule-owner.js +3 -2
  149. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  150. package/dist/core/runner/announce-once-ledger.js +5 -0
  151. package/dist/core/runner/assemble-result.d.ts +1 -0
  152. package/dist/core/runner/assemble-result.js +1 -1
  153. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  154. package/dist/core/runner/caller-roster.d.ts +16 -4
  155. package/dist/core/runner/caller-roster.js +33 -6
  156. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  157. package/dist/core/runner/capability-withheld-seat.js +24 -0
  158. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  159. package/dist/core/runner/classifier-ladder.js +3 -3
  160. package/dist/core/runner/construction-doors.js +3 -0
  161. package/dist/core/runner/contracts.d.ts +28 -25
  162. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  163. package/dist/core/runner/cross-boundary-lane.js +40 -27
  164. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  165. package/dist/core/runner/denial-limit-arms.js +1 -1
  166. package/dist/core/runner/file-history-request.d.ts +18 -0
  167. package/dist/core/runner/file-history-request.js +21 -13
  168. package/dist/core/runner/file-history-restore.d.ts +45 -0
  169. package/dist/core/runner/file-history-restore.js +46 -0
  170. package/dist/core/runner/gate-exit.d.ts +3 -3
  171. package/dist/core/runner/gate-exit.js +4 -3
  172. package/dist/core/runner/image.d.ts +7 -17
  173. package/dist/core/runner/image.js +9 -60
  174. package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
  175. package/dist/core/runner/permission-rule-lanes.js +26 -10
  176. package/dist/core/runner/person-path-rows.d.ts +12 -9
  177. package/dist/core/runner/person-path-rows.js +18 -7
  178. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  179. package/dist/core/runner/prepare-ask-lane.js +5 -2
  180. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  181. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  182. package/dist/core/runner/prepare-config-doors.d.ts +29 -38
  183. package/dist/core/runner/prepare-config-doors.js +42 -25
  184. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  185. package/dist/core/runner/prepare-defer-classify.js +7 -8
  186. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  187. package/dist/core/runner/prepare-file-history.js +7 -39
  188. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  189. package/dist/core/runner/prepare-gate-stations.js +10 -1
  190. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  191. package/dist/core/runner/prepare-hands-readface.js +15 -14
  192. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  193. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  194. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  195. package/dist/core/runner/prepare-park-ask.js +5 -5
  196. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  197. package/dist/core/runner/prepare-policy-chain.js +65 -72
  198. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  199. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  200. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  201. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  204. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  205. package/dist/core/runner/prepare-safety-scan.js +0 -17
  206. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  207. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  208. package/dist/core/runner/prepare-task.d.ts +1 -1
  209. package/dist/core/runner/prepare-task.js +29 -20
  210. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  211. package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
  212. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  213. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  215. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  216. package/dist/core/runner/resume-admission.js +1 -1
  217. package/dist/core/runner/resume-apply.js +11 -12
  218. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  219. package/dist/core/runner/resume-claim.d.ts +4 -2
  220. package/dist/core/runner/resume-claim.js +15 -8
  221. package/dist/core/runner/retired-runner-deps.js +1 -0
  222. package/dist/core/runner/rewind-files.d.ts +15 -0
  223. package/dist/core/runner/rewind-files.js +132 -0
  224. package/dist/core/runner/run-attachment-seats.js +2 -1
  225. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  226. package/dist/core/runner/run-brain-sinks.js +4 -2
  227. package/dist/core/runner/run-harness-handlers.js +12 -4
  228. package/dist/core/runner/run-leg.d.ts +1 -1
  229. package/dist/core/runner/run-leg.js +30 -18
  230. package/dist/core/runner/run-settle-and-teardown.js +2 -1
  231. package/dist/core/runner/run-turn-boundary.js +1 -10
  232. package/dist/core/runner/runtask.d.ts +3 -0
  233. package/dist/core/runner/runtask.js +8 -9
  234. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  235. package/dist/core/runner/session-read-file-states.js +28 -0
  236. package/dist/core/runner/session-rule-policy.js +4 -3
  237. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  238. package/dist/core/runner/shell-env-withheld.js +51 -0
  239. package/dist/core/runner/skills-seat.js +6 -2
  240. package/dist/core/runner/stream-settle-backstop.js +1 -1
  241. package/dist/core/runner/sub-agent-deny-lists.js +4 -7
  242. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  243. package/dist/core/runner/synthetic-tools.js +4 -1
  244. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  245. package/dist/core/runner/tool-disclosure.js +1 -3
  246. package/dist/core/runner/tool-end-body.d.ts +1 -1
  247. package/dist/core/runner/tool-end-body.js +10 -9
  248. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  249. package/dist/core/runner/tool-not-executed.js +11 -0
  250. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  251. package/dist/core/runner/tool-occurrence.js +7 -0
  252. package/dist/core/runner/turn-attachments.d.ts +33 -15
  253. package/dist/core/runner/turn-attachments.js +62 -37
  254. package/dist/core/runner-deps.d.ts +5 -5
  255. package/dist/core/safety-axis-vocab.d.ts +6 -4
  256. package/dist/core/safety-axis-vocab.js +6 -5
  257. package/dist/core/safety-merge-corpus.js +11 -3
  258. package/dist/core/secret-env.d.ts +26 -3
  259. package/dist/core/secret-env.js +44 -8
  260. package/dist/core/select-model.js +3 -3
  261. package/dist/core/session-policy-store.d.ts +27 -15
  262. package/dist/core/session-policy-store.js +156 -36
  263. package/dist/core/session-store.d.ts +29 -10
  264. package/dist/core/session-store.js +51 -19
  265. package/dist/core/session.d.ts +82 -16
  266. package/dist/core/session.js +53 -0
  267. package/dist/core/shell-read-silence.d.ts +11 -12
  268. package/dist/core/shell-read-silence.js +9 -5
  269. package/dist/core/shell-run-candidates.js +3 -1
  270. package/dist/core/shell-wrapper-projection.js +1 -1
  271. package/dist/core/shell-wrapper-table.d.ts +14 -7
  272. package/dist/core/shell-wrapper-table.js +5 -4
  273. package/dist/core/side-query.js +10 -1
  274. package/dist/core/skill-grant.d.ts +7 -2
  275. package/dist/core/skill-grant.js +5 -0
  276. package/dist/core/skills-directory.js +6 -2
  277. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  278. package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
  279. package/dist/core/store-contracts/file-history-store-contract.js +31 -1
  280. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  281. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  282. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  283. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  284. package/dist/core/store-contracts/session-store-contract.js +150 -14
  285. package/dist/core/stub-env.d.ts +2 -0
  286. package/dist/core/stub-env.js +1 -0
  287. package/dist/core/synthetic-read-verdict.js +3 -3
  288. package/dist/core/task-event.d.ts +32 -4
  289. package/dist/core/task-notification.d.ts +16 -12
  290. package/dist/core/task-registry.d.ts +9 -0
  291. package/dist/core/task-registry.js +11 -1
  292. package/dist/core/task-result.d.ts +18 -0
  293. package/dist/core/task-spec.d.ts +18 -13
  294. package/dist/core/tighten-task-spec.js +2 -1
  295. package/dist/core/tool-catalog-entries.d.ts +17 -0
  296. package/dist/core/tool-catalog-entries.js +13 -2
  297. package/dist/core/tool-check-reading.d.ts +11 -0
  298. package/dist/core/tool-check-reading.js +11 -6
  299. package/dist/core/tool-model-gate.d.ts +2 -2
  300. package/dist/core/tool-name-aliases.d.ts +16 -16
  301. package/dist/core/tool-name-aliases.js +13 -19
  302. package/dist/core/tool-name-readings.d.ts +5 -35
  303. package/dist/core/tool-name-readings.js +1 -9
  304. package/dist/core/tool-policy.d.ts +68 -198
  305. package/dist/core/tool-policy.js +149 -198
  306. package/dist/core/tool-result-store.js +3 -0
  307. package/dist/core/tool-roster.d.ts +14 -19
  308. package/dist/core/tool-roster.js +11 -44
  309. package/dist/core/tool-spec-members.js +7 -2
  310. package/dist/core/tool-spec.d.ts +19 -11
  311. package/dist/core/tools.js +49 -9
  312. package/dist/core/trace.d.ts +2 -2
  313. package/dist/core/types.d.ts +1 -1
  314. package/dist/core/user-attachment.d.ts +8 -1
  315. package/dist/core/user-attachment.js +64 -4
  316. package/dist/core/wiring-manifest.d.ts +9 -0
  317. package/dist/core/wiring-manifest.js +1 -0
  318. package/dist/core/workflow-journal-store.js +1 -1
  319. package/dist/engine/compaction/compaction.js +3 -2
  320. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  321. package/dist/engine/execution-env/node-execution-env.js +11 -2
  322. package/dist/engine/harness/agent-harness.d.ts +25 -1
  323. package/dist/engine/harness/agent-harness.js +54 -7
  324. package/dist/engine/harness/types.d.ts +29 -2
  325. package/dist/engine/llm/types.d.ts +28 -11
  326. package/dist/engine/loop/agent-loop.d.ts +22 -0
  327. package/dist/engine/loop/agent-loop.js +16 -26
  328. package/dist/engine/loop/types.d.ts +16 -6
  329. package/dist/engine/session/memory-repo.d.ts +9 -2
  330. package/dist/engine/session/memory-repo.js +11 -1
  331. package/dist/engine/session/repo-utils.d.ts +6 -5
  332. package/dist/engine/session/repo-utils.js +14 -6
  333. package/dist/index.d.ts +22 -10
  334. package/dist/index.js +15 -7
  335. package/dist/internal/harness-types.d.ts +1 -1
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  338. package/dist/orchestration/run-workflow-tool.js +5 -3
  339. package/dist/orchestration/workflow.d.ts +3 -0
  340. package/dist/orchestration/workflow.js +36 -18
  341. package/dist/prompt-assembly/artifact.d.ts +2 -2
  342. package/dist/prompt-assembly/artifact.js +5 -3
  343. package/dist/prompt-assembly/assemble.d.ts +3 -2
  344. package/dist/prompt-assembly/assemble.js +1 -1
  345. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  346. package/dist/prompt-assembly/catalog/schema.js +34 -2
  347. package/dist/prompt-assembly/catalog/sections.js +0 -1
  348. package/dist/prompt-assembly/composer.d.ts +3 -1
  349. package/dist/prompt-assembly/composer.js +1 -1
  350. package/dist/prompt-assembly/event-registry.js +1 -0
  351. package/dist/prompt-assembly/overlay.js +3 -3
  352. package/dist/prompt-assembly/renderers.d.ts +1 -1
  353. package/dist/prompt-assembly/renderers.js +0 -3
  354. package/dist/prompt-assembly/role-base.d.ts +15 -0
  355. package/dist/prompt-assembly/role-base.js +9 -0
  356. package/dist/prompt-assembly/select.d.ts +39 -14
  357. package/dist/prompt-assembly/select.js +47 -16
  358. package/dist/prompt-assembly/sugar.d.ts +17 -11
  359. package/dist/prompt-assembly/sugar.js +8 -3
  360. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  361. package/dist/prompt-assembly/tool-catalog.js +114 -4
  362. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  363. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  364. package/dist/prompt-assembly/types.d.ts +0 -7
  365. package/dist/scenarios/full-body.d.ts +11 -11
  366. package/dist/scenarios/full-body.js +4 -3
  367. package/dist/shell/lex.js +10 -1
  368. package/dist/stores/file/adoption/adopt.js +4 -3
  369. package/dist/stores/file/adoption/marker.js +3 -2
  370. package/dist/stores/file/checkpoint-store.d.ts +21 -0
  371. package/dist/stores/file/checkpoint-store.js +38 -6
  372. package/dist/stores/file/file-history-store.js +6 -7
  373. package/dist/stores/file/index.js +2 -1
  374. package/dist/stores/file/permission-rule-adopt.js +4 -3
  375. package/dist/stores/file/permission-rule-store.js +11 -5
  376. package/dist/stores/file/session-store.d.ts +29 -6
  377. package/dist/stores/file/session-store.js +42 -50
  378. package/dist/tools/artifact/artifact-tool.js +3 -2
  379. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  380. package/dist/tools/fs/bash-program-position.js +56 -9
  381. package/dist/tools/fs/fs-bash.js +5 -5
  382. package/dist/tools/fs/fs-glob.d.ts +86 -0
  383. package/dist/tools/fs/fs-glob.js +226 -0
  384. package/dist/tools/fs/fs-read.js +14 -14
  385. package/dist/tools/fs/fs-search-tools.js +7 -7
  386. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  387. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  388. package/dist/tools/fs/pdf.d.ts +9 -6
  389. package/dist/tools/fs/pdf.js +3 -3
  390. package/dist/tools/fs/program-read-model.d.ts +57 -7
  391. package/dist/tools/fs/program-read-model.js +11 -1
  392. package/dist/tools/fs/program-read-model.rows.js +78 -21
  393. package/dist/tools/fs/read-deny-home.js +3 -2
  394. package/dist/tools/fs/removal-targets.d.ts +17 -7
  395. package/dist/tools/fs/removal-targets.js +47 -20
  396. package/dist/tools/fs/search.d.ts +10 -0
  397. package/dist/tools/fs/search.js +20 -26
  398. package/dist/tools/fs/shell-read-argv.js +89 -12
  399. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  400. package/dist/tools/fs/shell-read-bindings.js +41 -0
  401. package/dist/tools/fs/shell-read-check.js +6 -19
  402. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  403. package/dist/tools/fs/shell-read-environment.js +3 -2
  404. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  405. package/dist/tools/fs/shell-read-establish.js +19 -20
  406. package/dist/tools/fs/shell-read-plan.js +24 -16
  407. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  408. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  409. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  410. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  411. package/dist/tools/fs/shell-reentry-text.js +40 -2
  412. package/dist/tools/todo.js +63 -63
  413. package/dist/tools/web.d.ts +19 -14
  414. package/dist/tools/web.js +38 -55
  415. package/package.json +1 -1
  416. package/test/export-surface.snapshot.json +143 -5
  417. package/wire-changes/core@7.56.0.json +3891 -0
  418. package/wire-changes/mods-kernel@7.56.0.json +303 -0
@@ -17,7 +17,7 @@ import type { HumanReviewGateRow } from "../task-result.js";
17
17
  import type { RepairBundle } from "../../agents/repair-loop.js";
18
18
  import type { SubagentRetainLedger } from "../../agents/retain-ledger.js";
19
19
  import type { BrainCallGuardrailRef } from "../../brain/timeout.js";
20
- import type { ActiveWorktreeSession, AgentHarness, AgentMessage, AgentTool, AnnouncedListingSnapshotInput, ExecutionEnv, ThinkingLevel } from "../../internal/harness.js";
20
+ import type { ActiveWorktreeSession, AgentHarness, AgentMessage, AgentTool, AnnouncedListingSnapshotInput, AnnouncedMcpFailure, ExecutionEnv, ThinkingLevel } from "../../internal/harness.js";
21
21
  import type { Model } from "../../internal/llm.js";
22
22
  import type { WorkflowSizeGuideline } from "../../orchestration/workflow-size-guideline.js";
23
23
  import type { ToolManifestRow } from "../../prompt-assembly/tool-catalog.js";
@@ -234,7 +234,7 @@ export interface FrameReceipt {
234
234
  text: string;
235
235
  /** Which frame this receipt settles. No collector renders a frame whose receipt is still pending (the frame is on
236
236
  * its way, not yet in the transcript) — the one reading is `frameCarried` (compaction-restate.ts). */
237
- source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "posture" | "approval_feedback" | "advisor_tool";
237
+ source: "git_status" | "agent_listing" | "skills_listing" | "date_change" | "output_style" | "mcp_unavailable" | "posture" | "approval_feedback" | "advisor_tool";
238
238
  /** Runs inside the `message_end` walk (synchronous, never awaited): advances the run-local record
239
239
  * and parks any session write for the next serialization point. */
240
240
  commit: (entryId: string) => void;
@@ -291,6 +291,8 @@ export interface Prepared {
291
291
  * prepare emits run-scoped disclosures of its own and each must have a terminal that names it.
292
292
  */
293
293
  runId: string;
294
+ /** The deployment's host floor as the config doors compiled it (absent ⇒ none declared) — the task images' guard reads it. */
295
+ hostFloor?: import("../host-floor.js").HostFloor;
294
296
  /** The (owner, scope) key this run's registry-facing tools register rows under — (host task id, mount domain), minted once at prepare; the teardown sweeps read it and never re-derive it. */
295
297
  registryAccess: {
296
298
  readonly owner: string;
@@ -472,13 +474,15 @@ export interface Prepared {
472
474
  readonly args: unknown;
473
475
  readonly admit: () => void;
474
476
  }>;
477
+ /** The leg's `tool.call` station (`mods/tool-call.ts`) — every execution of a call passes it; absent when no handler hangs on the event. */
478
+ toolCallStation?: import("../mods/tool-call.js").ToolCallStation;
475
479
  /** The leg's shell READ STATION, re-run on a durable RESUME before an approved shell call executes: the parked leg's
476
480
  * admission died with that leg, so the resumed bytes are judged (and admitted for their pre-spawn re-establishment)
477
481
  * on THIS leg — a deny row found now vetoes, an operator's edit is judged on the `rejudge` seat. */
478
482
  shellReadCheck?: import("../../tools/fs/shell-read-check.js").ShellReadCheck;
479
483
  crossBoundary?: {
480
484
  readonly check: import("../cross-boundary-taint.js").CrossBoundaryCheck | undefined;
481
- settle(): Promise<void>;
485
+ settle(owed: import("../cross-boundary-taint.js").OwedDeliveries): Promise<void>;
482
486
  storeWaits(): number;
483
487
  };
484
488
  /** The ORG adjudication face, re-resolved on a durable RESUME before an approved
@@ -1140,27 +1144,25 @@ export interface Prepared {
1140
1144
  * turn boundary. Appended by the rematerialize diff (newly-activated names only — the announced set
1141
1145
  * is seeded with prepare-time actives INCLUDING resume-reseeded ones, so a resume never replays);
1142
1146
  * DRAINED by the run loop only when the `tools_delta` attachment actually survived the byte cap.
1143
- * Present when the task has deferred tools at all — OR when a declared MCP server failed
1144
- * to connect, so the failure is announceable even on a task whose every MCP tool went missing with it.
1147
+ * Present when the task has deferred tools at all.
1145
1148
  *
1146
- * The same frame's MCP arms, filled by the SAME rematerialize seam / materialize-time
1147
- * projection and drained by the same intact-survival predicate:
1149
+ * The same frame's MCP arms, filled by the SAME rematerialize seam and drained by the same intact-survival predicate:
1148
1150
  * - `pendingRemoved`: previously-ANNOUNCED tool names that left the live roster (a RefreshMcpTools
1149
1151
  * re-splice whose server withdrew them). CC `removedNames`.
1150
1152
  * - `pendingReadded`: names in `pendingRemoved`'s history that came back on a later refresh. CC
1151
- * `readdedNames`.
1152
- * - `pendingFailed`: declared servers whose connect failed at materialize (`statuses`), name/error
1153
- * neutralized + bounded at intake, MINUS the pairs this session's record already announced (CC
1154
- * `failedMcpServers` compared against the previous attachment — a serving layer runs prepare once
1155
- * per user message, so the per-run set alone re-announced every message). */
1153
+ * `readdedNames`. */
1156
1154
  toolsDeltaRef?: {
1157
1155
  pending: string[];
1158
1156
  pendingRemoved: string[];
1159
1157
  pendingReadded: string[];
1160
- pendingFailed: Array<{
1161
- name: string;
1162
- error?: string;
1163
- }>;
1158
+ };
1159
+ /** The `mcp_unavailable` frame's pending servers: declared servers whose dial failed at materialize (`statuses`), name/error
1160
+ * neutralized + bounded at intake, MINUS the pairs this session's record already announced (a serving layer runs prepare once
1161
+ * per user message, so the per-run set alone would re-announce every message). Present when at least one is pending — a
1162
+ * task whose every MCP tool went missing with its server is exactly the one that must say so. Carried by the leg's first
1163
+ * request (a fresh leg's first message, a resumed leg's continuation) and drained by that message's receipt (`settleMcpUnavailable`). */
1164
+ mcpUnavailable?: {
1165
+ pending: AnnouncedMcpFailure[];
1164
1166
  };
1165
1167
  /** G1 通告层续批 (CC `agent_listing_delta` parity) — the mounted delegation tool's agent-type roster
1166
1168
  * (read off `ToolSpec.agentListing`, filled by createSubagentTool), plus the tool's mounted name for
@@ -1200,7 +1202,7 @@ export interface Prepared {
1200
1202
  * catalog change across a suspend is re-announced as a "Models available…" drift line.
1201
1203
  * `mcpFailed` / `advisories` are the once-per-SESSION arms of the same snapshot (see
1202
1204
  * announce-once-ledger.ts): seeded at prepare from the branch's record, advanced by the run loop
1203
- * on intact delivery of the tools_delta `failedServers` arm / the mcp_dropped_tools frame. */
1205
+ * on delivery of the mcp_unavailable frame / intact delivery of the mcp_dropped_tools frame. */
1204
1206
  announcedListingsRef: AnnouncedListingSnapshotInput;
1205
1207
  /** The frame-receipt ledger — the ONE commit point of every engine frame that rides a user message
1206
1208
  * (the git-status frame, the agent and skills listing frames). Always present; per leg. */
@@ -1213,10 +1215,11 @@ export interface Prepared {
1213
1215
  gitStatusRef: GitStatusLaneRef;
1214
1216
  /** The posture composition's run-local half (the newest carrier's protection slot; the row last composed for). */
1215
1217
  postureFrameRef: import("../auto-mode-directive.js").PostureFrameRef;
1216
- /** G1 通告层 — narrow post-compact getter over the process task registry: THIS run's visible
1217
- * pending/running background tasks (same owner/scope/session identity the TaskOutput/TaskStop tools
1218
- * use), as a bounded display projection (id/description/status — never handles/env/abort). Called by
1219
- * the run loop ONLY when `spec.attachments.backgroundTasks` opted in AND a compaction just landed. */
1218
+ /** G1 通告层 — narrow getter over the process task registry: THIS run's visible live background tasks
1219
+ * (pending / running / parked under the same owner/scope/session identity the TaskOutput/TaskStop tools
1220
+ * use), EVERY one (`TaskRegistry.liveTasks`), as a projection (id/description/status — never
1221
+ * handles/env/abort). Read by the post-compact listing (which caps what it renders), the resume's orphan
1222
+ * diff and the stop hook's `backgroundTasks` view. */
1220
1223
  listBackgroundTasks: () => Array<{
1221
1224
  id: string;
1222
1225
  description?: string;
@@ -1586,8 +1589,6 @@ export interface PromptFeatureFlags {
1586
1589
  writeFaceOpen: boolean;
1587
1590
  orchestrationEnabled: boolean;
1588
1591
  orchestrationDeferred: boolean;
1589
- promptProfile: "simple" | "classic";
1590
- fableMitigations: boolean;
1591
1592
  goalEnabled: boolean;
1592
1593
  awarenessEnabled: boolean;
1593
1594
  worktreeIsolated: boolean;
@@ -1795,6 +1796,10 @@ export interface RunInternals {
1795
1796
  outcome?: ResumeOutcome;
1796
1797
  inheritedGate?: InheritedGate;
1797
1798
  }>;
1799
+ /** The deployment's credential for the claim this run acts under (an opaque grant id; a TRUSTED channel like the decisions above).
1800
+ * A resume handed one carries it into its CAS as `expect.holder` (the store judges it; a superseded grant is
1801
+ * `resume.holder_superseded`, nothing applied), and so does every Workflow drive this run makes. Never inherited by children. */
1802
+ holder?: string;
1798
1803
  /**
1799
1804
  * Set ONLY by the Agent tool's fork route (`Agent(subagent_type:"fork")`, a core caller) on the
1800
1805
  * child it spawns: this run IS a forked child. `prepareTask` threads it to tool ctx as `insideFork` so the
@@ -2049,8 +2054,6 @@ export interface RunInternals {
2049
2054
  parentCenterArtifactDigest?: string;
2050
2055
  /** Publish provenance companion of {@link parentCenterArtifactDigest} (audit only). */
2051
2056
  parentCenterSourceRevision?: string;
2052
- /** R2 双形轴 — parent's resolved prompt profile, inherited unless the child spec overrides. */
2053
- promptProfile?: "simple" | "classic";
2054
2057
  /**
2055
2058
  * An OPT-IN, DISPLAY-ONLY event sink a deployment sets on the TOP run to
2056
2059
  * receive a subagent's live `task_progress` ticks (which otherwise stay in the child's ISOLATED stream). Threaded
@@ -6,12 +6,15 @@
6
6
  * `ToolExecuteContext.crossBoundaryTreeForChildren`) through this module alone; each leg joins into it what it knows at prepare (its
7
7
  * environment's declaration, its session's newest record, its posture) and every bit an exit sets lands there before the call
8
8
  * runs — after the record that carries it, so a call the exit refuses sets nothing. Each leg's session holds a record
9
- * (`CROSS_BOUNDARY_RECORD_TYPE`) of the state its content was produced under — written only for an armed tree: at prepare and at an
9
+ * (`CROSS_BOUNDARY_RECORD_TYPE`) of the state its content is read under — written only for an armed tree: at prepare and at an
10
10
  * exit (before the call runs) when the state grew past what the session already says, and at a leg's end (before a suspend's row is
11
11
  * put, when the leg settles) also when conversation content follows the newest record. A write that fails refuses its call (or its
12
12
  * row) on a governed tree; a prepare's or a settle's, and any write on a tree that is not governed, mints
13
- * `config.cross_boundary_record_unwritten`, once per state. A record covers the content before it: a leg that takes over a session
14
- * whose content no record covers (none on the branch, or after the newest), on an armed tree, reads that content as off-target.
13
+ * `config.cross_boundary_record_unwritten`, once per state. A record says how the content before it is READ: a leg's end record also
14
+ * carries what the session is still owed — each unfinished background task the leg's TaskOutput reaches, judged as the poll the
15
+ * session's next leg (another tree) would make of it, so its delivery is read under the bit it brings. A leg that takes over a
16
+ * session whose content no record covers (none on the branch, or after the newest), on an armed tree, reads that content as
17
+ * off-target.
15
18
  *
16
19
  * THE OBLIGATION of a call is read off three things at the moment it is asked ({@link crossBoundaryObligation}): the legs the
17
20
  * call travels (its roster row's declaration, or what the dispatching code gives per call), whether the environment the `env`
@@ -19,7 +22,7 @@
19
22
  */
20
23
  import type { AgentTool } from "../../internal/harness.js";
21
24
  import type { SessionTreeEntry } from "../../internal/harness-types.js";
22
- import { type CrossBoundaryCheck, type CrossBoundaryPosture, type CrossBoundaryTreeToken } from "../cross-boundary-taint.js";
25
+ import { type CrossBoundaryCheck, type CrossBoundaryPosture, type CrossBoundaryTreeToken, type OwedDeliveries } from "../cross-boundary-taint.js";
23
26
  import { type ToolRoster } from "../tool-roster.js";
24
27
  import type { RunnerDeps } from "../types.js";
25
28
  /** A new tree with no bit set, and the token that names it — the one mint of a token. */
@@ -39,23 +42,24 @@ export interface CrossBoundaryLane {
39
42
  seat(view: CrossBoundaryLegView): CrossBoundaryCheck | undefined;
40
43
  /** The seat minted by {@link seat}, for the resumed call's exit. */
41
44
  readonly check: CrossBoundaryCheck | undefined;
42
- /** Write the record the tree's state owes this leg's session: the new entry's id, or undefined when nothing was owed (or, on a tree
43
- * that is not governed, the write failed and was reported); throws when it cannot be written on a governed tree. With `atLeaf` (a
44
- * suspend: a leg's end), the record also covers the content after the newest one and is written only as the child of that leaf
45
- * (the row then points at it). */
46
- owe(atLeaf?: string): Promise<string | undefined>;
45
+ /** A suspend (a leg's end) writes the record its row's leaf owes: the new entry's id, or undefined when nothing was owed (or, on a
46
+ * tree that is not governed, the write failed and was reported); throws when it cannot be written on a governed tree. The record
47
+ * covers the content after the newest one and what the session is still `owed`, and is written only as the child of `atLeaf` (the
48
+ * row then points at it). */
49
+ owe(atLeaf: string, owed: OwedDeliveries): Promise<string | undefined>;
47
50
  /** The tree is armed, so the session OWES the tree's record and a parked row says a reader must read it — on a tree that is not
48
51
  * governed a failed write leaves the record missing (the notice says so), and the reader then reads the content after the newest
49
52
  * record as off-target. */
50
53
  recorded(): boolean;
51
- /** The leg settles: the record that covers what it added is written, a failure reported loudly (the next leg then reads the
52
- * content after the newest record as off-target). */
53
- settle(): Promise<void>;
54
+ /** The leg settles: the record that covers what it added and what the session is still `owed` is written, a failure reported
55
+ * loudly (the next leg then reads the content after the newest record as off-target). */
56
+ settle(owed: OwedDeliveries): Promise<void>;
54
57
  /** How many times this leg's record writes have waited on the session store — a station that judged before an exit reads again
55
58
  * when the count moved across it (the exit's own form: judged again after a wait). */
56
59
  storeWaits(): number;
57
60
  }
58
- /** What the seat reads per call: the live roster (the legs a row declares) and the mounted instances (a `"per_call"` resolver). */
61
+ /** What the seat reads per call: the live roster (the legs a row declares) and the mounted instances (a `"per_call"` row's resolver,
62
+ * read off the later mount under the row's name — the instance the row was minted from, but in a redial window: KL-2284-c). */
59
63
  export interface CrossBoundaryLegView {
60
64
  readonly tools: readonly AgentTool[];
61
65
  readonly roster: {
@@ -2,7 +2,7 @@ import { BOUNDARY_LEGS, CROSS_BOUNDARY_RECORD_TYPE, CROSS_BOUNDARY_TAINT_BITS, S
2
2
  import { deliverEngineNotice } from "../engine-notice.js";
3
3
  import { policyCannotAnswer } from "../real-approval.js";
4
4
  import { thrownText } from "../thrown-value.js";
5
- import { rosterEntryNamed } from "../tool-roster.js";
5
+ import { rosterEntryNamed, survivorsByName } from "../tool-roster.js";
6
6
  import { emitTrace } from "../trace.js";
7
7
  const TREE_STATE = new WeakMap();
8
8
  export function mintCrossBoundaryTree() {
@@ -21,6 +21,7 @@ export function joinedCrossBoundaryTree(handed, report) {
21
21
  return token;
22
22
  }
23
23
  const EVERY_LEG = Object.freeze([...BOUNDARY_LEGS]);
24
+ const ONE_OUTSIDE_READ = Object.freeze([Object.freeze({ legs: Object.freeze(["outside_read"]) })]);
24
25
  const bitsOf = (t) => CROSS_BOUNDARY_TAINT_BITS.filter((b) => t[b] === true);
25
26
  function legsOfCall(view, legEnv, token, call, report) {
26
27
  const roster = view.roster.current;
@@ -30,7 +31,7 @@ function legsOfCall(view, legEnv, token, call, report) {
30
31
  if (row.boundaryLegs !== "per_call")
31
32
  return { legs: row.boundaryLegs, env: legEnv };
32
33
  const strictest = (why) => (report(`tool "${row.name}" declares its boundary legs per call, and its boundaryLegsFor ${why} — the call reads as every leg, off the target (the strictest reading)`), { legs: EVERY_LEG, env: undefined });
33
- const resolve = view.tools.find((t) => t.name === row.name)?.boundaryLegsFor;
34
+ const resolve = survivorsByName(view.tools).get(row.name)?.boundaryLegsFor;
34
35
  if (typeof resolve !== "function")
35
36
  return strictest("is missing");
36
37
  let given;
@@ -47,7 +48,13 @@ function legsOfCall(view, legEnv, token, call, report) {
47
48
  }
48
49
  export async function prepareCrossBoundaryLane(input) {
49
50
  const { posture, externalContentTargetActive, env, session, resumeLeg, sessionId, runId, hostTaskId, deps } = input;
50
- const report = (message) => deps.onError?.(new Error(message), { phase: "config", sessionId });
51
+ const report = (message) => {
52
+ try {
53
+ deps.onError?.(new Error(message), { phase: "config", sessionId });
54
+ }
55
+ catch {
56
+ }
57
+ };
51
58
  const token = input.token ?? mintCrossBoundaryTree();
52
59
  const ref = TREE_STATE.get(token);
53
60
  if (ref === undefined)
@@ -71,57 +78,53 @@ export async function prepareCrossBoundaryLane(input) {
71
78
  ref.current = tree;
72
79
  const stationEngaged = posture !== undefined || externalContentTargetActive || crossBoundaryTreeGoverned(tree);
73
80
  let reported;
74
- const unwritten = (phase, state, catchUp, err) => {
81
+ const unwritten = (phase, state, err) => {
75
82
  if (reported !== undefined && crossBoundaryTreeCovers(reported, state))
76
83
  return;
77
84
  reported = state;
78
- deliverEngineNotice(deps.onNotice, crossBoundaryRecordUnwrittenNotice({ sessionId, runId, phase, governed: crossBoundaryTreeGoverned(ref.current), catchUp, cause: thrownText(err) }));
85
+ deliverEngineNotice(deps.onNotice, crossBoundaryRecordUnwrittenNotice({ sessionId, runId, phase, governed: crossBoundaryTreeGoverned(ref.current), cause: thrownText(err) }));
79
86
  };
80
87
  let writing = Promise.resolve();
81
88
  let storeWaits = 0;
82
- const write = (phase, atLeaf, adds = {}) => {
89
+ const write = (phase, atLeaf, joins = () => undefined) => {
83
90
  const next = writing.then(async () => {
84
- let leafAt = atLeaf;
85
- let cover = phase === "suspend" || phase === "settle";
91
+ const legEnd = phase === "suspend" || phase === "settle";
86
92
  let written;
87
93
  for (;;) {
88
- const state = joinCrossBoundaryTree(ref.current, adds);
89
- if (state.targetExecutionArmed !== true)
94
+ if (ref.current.targetExecutionArmed !== true)
90
95
  return written;
96
+ const state = joinCrossBoundaryTree(ref.current, joins() ?? {});
91
97
  const grown = !crossBoundaryTreeCovers(recorded, state);
92
- if (!grown && !cover)
98
+ if (!grown && !legEnd)
93
99
  return written;
94
100
  try {
95
101
  if (!grown) {
96
102
  storeWaits++;
97
103
  const now = readCrossBoundaryRecord((await session.getBranch()));
98
- if (now.kind !== "malformed" && !now.uncoveredContent) {
99
- cover = false;
100
- continue;
101
- }
104
+ if (now.kind !== "malformed" && !now.uncoveredContent)
105
+ return written;
102
106
  }
103
- if (leafAt !== undefined) {
107
+ if (atLeaf !== undefined) {
104
108
  storeWaits++;
105
- if ((await session.getLeafId()) !== leafAt)
109
+ if ((await session.getLeafId()) !== atLeaf)
106
110
  throw new Error("the session moved past the row's leaf before its record could be written");
107
111
  }
108
112
  storeWaits++;
109
113
  const entryId = await session.appendCustomEntry(CROSS_BOUNDARY_RECORD_TYPE, crossBoundaryRecordData(state));
110
114
  if (typeof entryId !== "string" || entryId.length === 0)
111
115
  throw new Error(`the session store answered the record's append with no entry id (${typeof entryId})`);
112
- if (leafAt !== undefined && (storeWaits++, await session.getLeafId()) !== entryId)
116
+ if (atLeaf !== undefined && (storeWaits++, await session.getLeafId()) !== entryId)
113
117
  throw new Error("the record the session store appended is not the session's new leaf");
114
118
  recorded = state;
115
119
  written = entryId;
116
- if (leafAt !== undefined)
117
- leafAt = entryId;
118
- cover = false;
120
+ if (legEnd)
121
+ return written;
119
122
  }
120
123
  catch (err) {
121
124
  const governed = crossBoundaryTreeGoverned(ref.current);
122
125
  if (governed && (phase === "exit" || phase === "suspend"))
123
126
  throw err;
124
- unwritten(phase, state, written !== undefined, err);
127
+ unwritten(phase, state, err);
125
128
  if (!governed)
126
129
  recorded = state;
127
130
  return written;
@@ -131,8 +134,18 @@ export async function prepareCrossBoundaryLane(input) {
131
134
  writing = next.catch(() => undefined);
132
135
  return next;
133
136
  };
134
- const owe = (atLeaf) => write(atLeaf !== undefined ? "suspend" : "exit", atLeaf);
135
137
  const OBSERVED = Object.freeze({ offTargetReadObserved: true });
138
+ const addedBy = (record) => (record && ref.current.offTargetReadObserved !== true ? OBSERVED : undefined);
139
+ const owedBit = (owed) => {
140
+ const records = (given) => given.some((d) => crossBoundaryObligation(d.legs, d.env?.externalContentTarget === true, ref.current).record);
141
+ try {
142
+ return addedBy(records(owed()));
143
+ }
144
+ catch (err) {
145
+ report(`the deliveries this leg's session is still owed could not be read (${thrownText(err)}) — read as content from beyond the device`);
146
+ return addedBy(records(ONE_OUTSIDE_READ));
147
+ }
148
+ };
136
149
  const trace = (phase, call) => emitTrace(deps.tracer, () => ({ kind: "permission.cross_boundary_taint", version: 1, taskId: hostTaskId, runId, phase, taint: bitsOf(ref.current), governed: ref.current.governed === true, ...(call !== undefined ? { toolName: call.toolName, ...(call.toolCallId !== undefined ? { toolCallId: call.toolCallId } : {}) } : {}), ts: Date.now() }));
137
150
  if (tree.targetExecutionArmed === true) {
138
151
  trace(resumeLeg ? "resume" : "prepare");
@@ -172,10 +185,10 @@ export async function prepareCrossBoundaryLane(input) {
172
185
  message: `tool "${call.toolName}" needs a person's confirmation: this run executes on a target device${ref.current.offTargetReadObserved === true ? " and has since let content from beyond it in, so a call that reaches beyond the device or back into it" : ", so a call that writes beyond the device"} is put to a person — this call was allowed by a configuration, not a person, and was not executed`,
173
186
  };
174
187
  }
175
- const adds = now.record && ref.current.offTargetReadObserved !== true ? OBSERVED : undefined;
188
+ const adds = addedBy(now.record);
176
189
  const judged = ref.current;
177
190
  try {
178
- await write("exit", undefined, adds);
191
+ await write("exit", undefined, () => adds);
179
192
  }
180
193
  catch (err) {
181
194
  return { kind: "unrecorded", message: `tool "${call.toolName}" was not executed: the session's cross-boundary record could not be written before it ran (${thrownText(err)}) — on a governed tree a call that owes its record does not run without it; refused fail-closed` };
@@ -192,10 +205,10 @@ export async function prepareCrossBoundaryLane(input) {
192
205
  };
193
206
  return check;
194
207
  },
195
- owe,
208
+ owe: (atLeaf, owed) => write("suspend", atLeaf, () => owedBit(owed)),
196
209
  storeWaits: () => storeWaits,
197
210
  recorded: () => ref.current.targetExecutionArmed === true,
198
- settle: () => write("settle").then(() => undefined),
211
+ settle: (owed) => write("settle", undefined, () => owedBit(owed)).then(() => undefined),
199
212
  };
200
213
  return lane;
201
214
  }
@@ -103,9 +103,9 @@ export type InheritedAsk = Extract<PermissionResult, {
103
103
  * {@link judgeInheritedClassifier} and threaded to every reader ({@link inheritedAskCarry}).
104
104
  * The MANDATE marks here are empty (the base names no seat): the policy-chain phase builds each call's facts over this
105
105
  * base with THIS task's tool seat — the seat the request's risk axes are read from — so a marked tool's ask is
106
- * classified by the seat at the station as at the gate. What the ancestor's ask carries on ITSELF still answers.
106
+ * classified by the seat at the station as at the gate. What the ancestor's ask carries on ITSELF still answers. No call either (each station's own).
107
107
  */
108
- export declare const INHERITED_STATION_FACTS: AskOriginFacts;
108
+ export declare const INHERITED_STATION_FACTS: Omit<AskOriginFacts, "call">;
109
109
  /** The members of a surviving ask that ride onto the approval request with a COMPUTED value — what the
110
110
  * four request mint stations (the gate's own and the three inherited-lane ones) spread after the seats
111
111
  * they spell themselves: the ask's origin word, its class (the word and the set, carried together) and its
@@ -86,7 +86,7 @@ export function inheritedAskCarry(judged, liveApprover, tracker) {
86
86
  export const inheritedAskFallbackMessage = (toolName) => `approval required for "${toolName}" (inherited parent policy)`;
87
87
  export async function judgeInheritedClassifier(opts) {
88
88
  const { autoMode, req } = opts;
89
- const facts = opts.facts ?? INHERITED_STATION_FACTS, m = facts.mandateMarks;
89
+ const facts = opts.facts ?? { ...INHERITED_STATION_FACTS, call: req }, m = facts.mandateMarks;
90
90
  const frames = [...(m.egress === true ? [markTightenMessage(req.toolName, "egress")] : []), ...(m.irreversibility === "always" ? [markTightenMessage(req.toolName, "irreversible")] : [])];
91
91
  const ask = (frames.length > 0 ? { ...opts.ask, message: [opts.ask.message ?? inheritedAskFallbackMessage(req.toolName), ...frames].join(" — ") } : opts.ask);
92
92
  const origin = askOriginOf(ask, facts);
@@ -11,6 +11,24 @@ import type { RunnerDeps, TaskSpec } from "../types.js";
11
11
  * exactly as it was. What it resolves rides into the file-history phase (`prepareFileHistory`) unchanged.
12
12
  */
13
13
  export declare function resolveFileHistoryRequest(spec: Pick<TaskSpec, "resumeAt" | "resumeAtMode" | "restoreFiles" | "rewindFilesTo" | "fileHistory">, deps: Pick<RunnerDeps, "onTrackFailure" | "fileHistoryStore" | "fileHistoryCapture">): FileHistoryRequest;
14
+ /**
15
+ * The DEPLOYMENT's file-history door — the three seats a deployment sets once (`RunnerDeps.onTrackFailure`,
16
+ * `RunnerDeps.fileHistoryStore`, `RunnerDeps.fileHistoryCapture`), each refused by name on a bad value. Read by
17
+ * every seat that touches file history: the run's request door above and the out-of-run `Runner.rewindFiles`, so a
18
+ * misconfigured deployment is refused the same way at both. `fileHistoryStore` is the store after the declared
19
+ * `"disabled"` word; `captureStore` additionally drops it when capture is `"off"` (recording stops, restore stays).
20
+ */
21
+ export declare function resolveDeploymentFileHistory(deps: Pick<RunnerDeps, "onTrackFailure" | "fileHistoryStore" | "fileHistoryCapture">): {
22
+ onTrackFailure: "refuse" | "proceed-unprotected";
23
+ wiredSeat: FileHistoryStore | "disabled" | undefined;
24
+ captureOff: boolean;
25
+ fileHistoryStore: FileHistoryStore | undefined;
26
+ captureStore: FileHistoryStore | undefined;
27
+ };
28
+ /** A restore asked of a deployment that holds no history backend (none wired, or declared `"disabled"`). */
29
+ export declare function storeUnconfiguredRefusal(wiredSeat: FileHistoryStore | "disabled" | undefined, target: string): Error & {
30
+ code?: string;
31
+ };
14
32
  /** What {@link resolveFileHistoryRequest} resolved: the validated seats and words, the run's store (after every off
15
33
  * switch) and its capture store, and the restore target (`undefined` = no restore asked). */
16
34
  export interface FileHistoryRequest {
@@ -1,13 +1,6 @@
1
1
  export function resolveFileHistoryRequest(spec, deps) {
2
- const onTrackFailure = deps.onTrackFailure === undefined ? "refuse" : deps.onTrackFailure;
3
- if (onTrackFailure !== "refuse" && onTrackFailure !== "proceed-unprotected") {
4
- const e = new Error(`RunnerDeps.onTrackFailure must be "refuse" or "proceed-unprotected"; got ${JSON.stringify(deps.onTrackFailure)} — refusing prepare rather than silently defaulting a first-touch-failure policy.`);
5
- e.code = "config.invalid_on_track_failure";
6
- throw e;
7
- }
8
- const wiredSeat = resolveWiredFileHistoryStore(deps.fileHistoryStore);
2
+ const { onTrackFailure, wiredSeat, captureOff } = resolveDeploymentFileHistory(deps);
9
3
  const runDeclaredOff = resolveRunFileHistoryWord(spec.fileHistory);
10
- const captureOff = resolveFileHistoryCaptureWord(deps.fileHistoryCapture, wiredSeat);
11
4
  const declaredOff = wiredSeat === "disabled" || runDeclaredOff;
12
5
  const fileHistoryStore = declaredOff ? undefined : wiredSeat;
13
6
  const captureStore = captureOff ? undefined : fileHistoryStore;
@@ -34,14 +27,29 @@ export function resolveFileHistoryRequest(spec, deps) {
34
27
  if (rewindTarget !== undefined && fileHistoryStore === undefined) {
35
28
  if (runDeclaredOff)
36
29
  throw captureDisabledRefusal(rewindTarget);
37
- const e = new Error(wiredSeat === "disabled"
38
- ? `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment declared file history disabled (RunnerDeps.fileHistoryStore: "disabled"), so there is no history to restore — the files were NOT rewound`
39
- : `rewind-files: restoring files to entry "${rewindTarget}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
40
- e.code = "rewind.store_unconfigured";
41
- throw e;
30
+ throw storeUnconfiguredRefusal(wiredSeat, rewindTarget);
42
31
  }
43
32
  return { onTrackFailure, wiredSeat, runDeclaredOff, captureOff, declaredOff, fileHistoryStore, captureStore, rewindTarget, rewindBefore };
44
33
  }
34
+ export function resolveDeploymentFileHistory(deps) {
35
+ const onTrackFailure = deps.onTrackFailure === undefined ? "refuse" : deps.onTrackFailure;
36
+ if (onTrackFailure !== "refuse" && onTrackFailure !== "proceed-unprotected") {
37
+ const e = new Error(`RunnerDeps.onTrackFailure must be "refuse" or "proceed-unprotected"; got ${JSON.stringify(deps.onTrackFailure)} — refusing prepare rather than silently defaulting a first-touch-failure policy.`);
38
+ e.code = "config.invalid_on_track_failure";
39
+ throw e;
40
+ }
41
+ const wiredSeat = resolveWiredFileHistoryStore(deps.fileHistoryStore);
42
+ const captureOff = resolveFileHistoryCaptureWord(deps.fileHistoryCapture, wiredSeat);
43
+ const fileHistoryStore = wiredSeat === "disabled" ? undefined : wiredSeat;
44
+ return { onTrackFailure, wiredSeat, captureOff, fileHistoryStore, captureStore: captureOff ? undefined : fileHistoryStore };
45
+ }
46
+ export function storeUnconfiguredRefusal(wiredSeat, target) {
47
+ const e = new Error(wiredSeat === "disabled"
48
+ ? `rewind-files: restoring files to entry "${target}" requires a history backend, but this deployment declared file history disabled (RunnerDeps.fileHistoryStore: "disabled"), so there is no history to restore — the files were NOT rewound`
49
+ : `rewind-files: restoring files to entry "${target}" requires a history backend, but this deployment wired no RunnerDeps.fileHistoryStore — no file history was ever recorded, so the files were NOT rewound`);
50
+ e.code = "rewind.store_unconfigured";
51
+ return e;
52
+ }
45
53
  function resolveWiredFileHistoryStore(candidate) {
46
54
  if (candidate === undefined || candidate === "disabled")
47
55
  return candidate;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The ONE restore of a session's tracked set and the ONE reading of its answer, reached DOWN for by the two seats that
3
+ * restore: the file-history phase's restore seat (`prepare-file-history.ts`, a `restoreFiles` / `rewindFilesTo` run)
4
+ * and the out-of-run rewind (`rewind-files.ts`, `Runner.rewindFiles`). A rewind outside a run is therefore the same
5
+ * history operation as the one a run performs, refused with the same codes and sentences, and handing the paths it
6
+ * moved to the same read-state channel.
7
+ */
8
+ import type { ExecutionEnv } from "../../internal/harness.js";
9
+ import type { FileHistoryRestoreResult, FileHistoryStore, RewindFilesResult } from "../file-history-store.js";
10
+ import type { SessionReadFileStates } from "./session-read-file-states.js";
11
+ /** A restore outcome a seat may accept: the ledger, with `failed` (the operation could not run) already refused —
12
+ * the out-of-run rewind's answer carries exactly this. */
13
+ export type AcceptedFileHistoryRestore = Extract<RewindFilesResult, {
14
+ dryRun: false;
15
+ }>["restore"];
16
+ /**
17
+ * The ONE restore of a session's tracked set and the ONE reading of its answer — the run's restore seat and the
18
+ * out-of-run `Runner.rewindFiles` both call it, so the two cannot disagree about what a restore means:
19
+ * · every path the attempt may have moved (`filesChanged` ∪ `failed[].path`, whatever the outcome) goes to the
20
+ * session's read-state channel (`noteRestored`), because a read record of the old bytes must stop vouching
21
+ * for them on the session's next leg;
22
+ * · `not_found` is "no boundary for that entry" — `rewind_snapshot.unresolvable` (in a "before" restore, the
23
+ * before-specific sentence);
24
+ * · any other `failed` outcome is `rewind.restore_failed` carrying the ledger and the store's own judgment on
25
+ * the coded `detail` channel (a host reads it, never the prose).
26
+ * A `complete` or `partial` answer is returned for the caller to accept: only a run goes on to work on the tree,
27
+ * so only the run seat has a partial-restore policy.
28
+ */
29
+ export declare function settleFileHistoryRestore(input: {
30
+ store: FileHistoryStore;
31
+ sessionId: string;
32
+ target: string;
33
+ before: boolean;
34
+ env: ExecutionEnv;
35
+ root: string;
36
+ signal: AbortSignal | undefined;
37
+ readStates: Pick<SessionReadFileStates, "noteRestored"> | undefined;
38
+ }): Promise<AcceptedFileHistoryRestore>;
39
+ /** The per-file ledger as one sentence (counts, then each refused / failed path with its reason). */
40
+ export declare function fileHistoryRestoreLedgerLine(r: FileHistoryRestoreResult): string;
41
+ /** A restore whose entry has no boundary on the session; a PREVIEW's form says "usable" — its probe
42
+ * (`canRestore`) cannot tell a boundary never made from one that is there and unreadable, a real restore can. */
43
+ export declare function noBoundaryRefusal(target: string, sessionId: string, preview?: boolean): Error & {
44
+ code?: string;
45
+ };
@@ -0,0 +1,46 @@
1
+ import { resolveTrackKey } from "../file-history-store.js";
2
+ import { isGovernanceRetryClass } from "../governance-codes.js";
3
+ export async function settleFileHistoryRestore(input) {
4
+ const { store, sessionId, target, env, root } = input;
5
+ const restored = await store.restore(sessionId, target, env, root, input.signal);
6
+ input.readStates?.noteRestored(sessionId, restoredAbsPathsOf(restored, root));
7
+ if (restored.outcome !== "failed")
8
+ return restored;
9
+ if (restored.error?.code === "not_found") {
10
+ if (input.before)
11
+ throw beforeWithoutBoundaryRefusal(target, sessionId);
12
+ throw noBoundaryRefusal(target, sessionId);
13
+ }
14
+ const e = new Error(`rewind-files restore failed (${restored.error?.code ?? "restore_failed"}): ${restored.error?.message ?? "unknown"} — ledger: ${fileHistoryRestoreLedgerLine(restored)}`);
15
+ e.code = "rewind.restore_failed";
16
+ if (restored.error !== undefined)
17
+ e.detail = { code: restored.error.code, ...(isGovernanceRetryClass(restored.error.permanence) ? { permanence: restored.error.permanence } : {}) };
18
+ throw e;
19
+ }
20
+ export function fileHistoryRestoreLedgerLine(r) {
21
+ return `applied ${r.filesChanged.length}, identical ${r.identicalSkipped.length}, refused ${r.refused.length}${r.refused.length > 0 ? ` (${r.refused.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}, failed ${r.failed.length}${r.failed.length > 0 ? ` (${r.failed.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}`;
22
+ }
23
+ export function noBoundaryRefusal(target, sessionId, preview = false) {
24
+ const e = new Error(preview
25
+ ? `rewind-files: no usable file-history boundary exists for entry "${target}" on session "${sessionId}" (never made, reaped, or there but unreadable — a real rewind names which), so there is nothing to preview. ${rewindRefusalTail()}`
26
+ : `rewind-files: no file-history boundary exists for entry "${target}" on session "${sessionId}" — the working tree was NOT rewound. ${rewindRefusalTail()}`);
27
+ e.code = "rewind_snapshot.unresolvable";
28
+ return e;
29
+ }
30
+ function restoredAbsPathsOf(restored, root) {
31
+ const out = [];
32
+ for (const key of [...restored.filesChanged, ...restored.failed.map((f) => f.path)]) {
33
+ const abs = resolveTrackKey(root, key);
34
+ if (abs.ok)
35
+ out.push(abs.abs);
36
+ }
37
+ return out;
38
+ }
39
+ function rewindRefusalTail() {
40
+ return `Boundaries are keyed by a turn's INITIAL entry and exist only for turns that recorded history (a RunnerDeps.fileHistoryStore wired, capture on, and the run's file history not disabled); a boundary from the retired whole-tree snapshot era is not restorable by this seat, and reaped boundaries have none.`;
41
+ }
42
+ function beforeWithoutBoundaryRefusal(target, sessionId) {
43
+ const e = new Error(`rewind-files: entry "${target}" has no file-history boundary on session "${sessionId}" — a before-restore needs the target's own boundary and never crosses into an earlier turn, so the working tree was NOT rewound. ${rewindRefusalTail()}`);
44
+ e.code = "rewind_snapshot.unresolvable";
45
+ return e;
46
+ }
@@ -238,9 +238,9 @@ export interface GatePass {
238
238
  hookAsk: Extract<PermissionResult, {
239
239
  action: "ask";
240
240
  }> | undefined;
241
- /** borrowed-mutable — the phase-1 screen answered its own `allow` (the exact word), naming the registration that answered
242
- * it: the allow layer's hook member (its `entries`), which speaks only while no policy rewrote the arguments after the
243
- * screen saw them. Writer: the dispatch (phase 1). Reader: the lanes' allow layer (its one reader). */
241
+ /** borrowed-mutable — the screen answered its own `allow` (the exact word) for the bytes that run, naming the registration
242
+ * that answered it: the allow layer's hook member (its `entries`). Writers: the dispatch (phase 1) and the fold's second
243
+ * look after a policy rewrite (rewrite-rejudge.ts), whose answer replaces the first. Reader: the lanes' allow layer. */
244
244
  hookAllowedBy?: readonly string[];
245
245
  /** borrowed-mutable — `tool.check` was raised in this pass's first adjudication, which raises it once: set by the
246
246
  * raise in front of the ask branch, read by the raise behind the read-only arm (it then raises nothing). Writer and
@@ -244,7 +244,7 @@ export function hookDenyExit(pass, deniedReason) {
244
244
  preToolContext: pass.preToolContext,
245
245
  };
246
246
  }
247
- const ANCESTOR_UNRESOLVED_CLASSIFICATION = classifyAsk({ action: "ask", message: "" }, { contentQuestion: false, markedUnresolvable: true, org: undefined, tightened: undefined, mandateMarks: {} });
247
+ const ancestorUnresolvedClassification = (call) => classifyAsk({ action: "ask", message: "" }, { call, contentQuestion: false, markedUnresolvable: true, org: undefined, tightened: undefined, mandateMarks: {} });
248
248
  function unresolvableCauseOfSettlement(gate) {
249
249
  if (gate.disposition.kind !== "denied" || gate.disposition.deniedBy !== "ask_resolution" || gate.settlement === undefined)
250
250
  return undefined;
@@ -274,12 +274,13 @@ export async function exitGate(pass) {
274
274
  const tableSeat = unresolvable !== undefined ? askUnresolvableRemedySeat(unresolvable) : undefined;
275
275
  const remedySeat = tableSeat === "absent" && input.askSeatForm === "declared_none" && pass.askClassification?.classes.has("content_question") !== true ? "declared_none" : tableSeat;
276
276
  const bindingRefusal = attestationOf(pass.decision, { toolCallId, toolName })?.bindingRefusal;
277
- const remedy = bindingRefusal !== undefined ? undefined : remedySeat !== undefined ? headlessApprovalRemedy({ mode: input.permissionMode?.(), classification: foldCause !== undefined ? ANCESTOR_UNRESOLVED_CLASSIFICATION : pass.askClassification, approverSeat: remedySeat, coveredWrite: isProtectedWrite(pass.req), ...(pass.shellUnplacedOptions !== undefined ? { unplacedOptions: pass.shellUnplacedOptions } : {}) }) : undefined;
277
+ const headless = bindingRefusal !== undefined ? undefined : remedySeat !== undefined ? headlessApprovalRemedy({ mode: input.permissionMode?.(), classification: foldCause !== undefined ? ancestorUnresolvedClassification(pass.req) : pass.askClassification, approverSeat: remedySeat, coveredWrite: isProtectedWrite(pass.req), ...(pass.shellUnplacedOptions !== undefined ? { unplacedOptions: pass.shellUnplacedOptions } : {}) }) : undefined;
278
+ const remedy = headless?.sentence;
278
279
  const denyReason = withParkFailureCause(`${decisionText(pass.decision) ?? `tool "${toolName}" denied by policy`}${remedy !== undefined ? ` — ${remedy}` : ""}`, pass.parkFailed, unresolvable !== undefined);
279
280
  if (unresolvable !== undefined) {
280
281
  const cause = unresolvable;
281
282
  const noticeRemedy = bindingRefusal ?? remedy;
282
- pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}) }), "toolGate.onAskUnresolvable");
283
+ pass.notifier.notify(() => input.onAskUnresolvable?.({ toolName, toolCallId, cause, parkLaneExisted: pass.suspendAsk !== undefined, ...(noticeRemedy !== undefined ? { remedy: noticeRemedy } : {}), ...(headless !== undefined ? { remedies: headless.remedies } : {}) }), "toolGate.onAskUnresolvable");
283
284
  }
284
285
  const finalInput = frozenInputSnapshot(pass.currentInput);
285
286
  await notifyPermissionDenied({