@sema-agent/core 7.52.0 → 7.54.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 (357) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/LICENSE +3 -1
  3. package/README.md +3 -1
  4. package/dist/agents/cross-session-envelope.d.ts +8 -0
  5. package/dist/agents/cross-session-envelope.js +6 -0
  6. package/dist/agents/cross-session-judge.d.ts +21 -1
  7. package/dist/agents/cross-session-judge.js +8 -0
  8. package/dist/agents/cross-session-ref.d.ts +5 -0
  9. package/dist/agents/cross-session-ref.js +1 -0
  10. package/dist/agents/org-delivery-gate.d.ts +122 -0
  11. package/dist/agents/org-delivery-gate.js +69 -0
  12. package/dist/agents/peer-held-queue.d.ts +9 -4
  13. package/dist/agents/peer-held-queue.js +6 -5
  14. package/dist/agents/peer-session-drain.d.ts +35 -6
  15. package/dist/agents/peer-session-drain.js +271 -182
  16. package/dist/agents/read-inbox-tool.d.ts +7 -0
  17. package/dist/agents/read-inbox-tool.js +5 -1
  18. package/dist/agents/send-message-tool.js +3 -4
  19. package/dist/agents/subagent.d.ts +6 -5
  20. package/dist/agents/subagent.js +117 -83
  21. package/dist/agents/tool-filter.d.ts +25 -4
  22. package/dist/agents/tool-filter.js +13 -3
  23. package/dist/brain/anthropic.d.ts +6 -1
  24. package/dist/brain/anthropic.js +4 -4
  25. package/dist/brain/model-presets.js +2 -1
  26. package/dist/brain/route-adjudicator.d.ts +6 -0
  27. package/dist/brain/routing.d.ts +24 -1
  28. package/dist/brain/routing.js +54 -19
  29. package/dist/brain/timeout.js +5 -4
  30. package/dist/core/a2a.d.ts +5 -2
  31. package/dist/core/a2a.js +33 -14
  32. package/dist/core/allow-entry.d.ts +3 -1
  33. package/dist/core/allow-entry.js +3 -2
  34. package/dist/core/approval-object.d.ts +87 -0
  35. package/dist/core/approval-object.js +85 -0
  36. package/dist/core/arg-summary.d.ts +3 -2
  37. package/dist/core/arg-summary.js +17 -11
  38. package/dist/core/ask-origin.d.ts +43 -27
  39. package/dist/core/ask-origin.js +20 -11
  40. package/dist/core/ask-question.d.ts +0 -1
  41. package/dist/core/ask-question.js +4 -67
  42. package/dist/core/ask-unresolvable-notice.d.ts +3 -2
  43. package/dist/core/auto-compaction.d.ts +106 -50
  44. package/dist/core/auto-compaction.js +69 -53
  45. package/dist/core/auto-mode-prompt.d.ts +4 -2
  46. package/dist/core/auto-mode-prompt.js +4 -3
  47. package/dist/core/canonical-json.d.ts +69 -0
  48. package/dist/core/canonical-json.js +130 -8
  49. package/dist/core/checkpoint-requirements.d.ts +13 -7
  50. package/dist/core/checkpoint-requirements.js +4 -1
  51. package/dist/core/checkpoint-store.d.ts +60 -36
  52. package/dist/core/checkpoint-store.js +7 -6
  53. package/dist/core/child-clamp-seats.d.ts +45 -6
  54. package/dist/core/child-clamp-seats.js +56 -4
  55. package/dist/core/compliance.js +3 -1
  56. package/dist/core/consolidate-scope.d.ts +1 -1
  57. package/dist/core/cross-boundary-taint.d.ts +213 -0
  58. package/dist/core/cross-boundary-taint.js +196 -0
  59. package/dist/core/decision-receipt.d.ts +44 -1
  60. package/dist/core/decision-receipt.js +16 -0
  61. package/dist/core/effective-path-target.d.ts +28 -6
  62. package/dist/core/effective-path-target.js +28 -2
  63. package/dist/core/engine-notice.d.ts +47 -4
  64. package/dist/core/engine-notice.js +17 -1
  65. package/dist/core/engine-storage-backend.d.ts +73 -0
  66. package/dist/core/engine-storage-backend.js +1 -0
  67. package/dist/core/file-history-store.d.ts +6 -2
  68. package/dist/core/file-history-store.js +1 -0
  69. package/dist/core/gate-fold.js +13 -4
  70. package/dist/core/gate-lanes.js +41 -34
  71. package/dist/core/gate-outcome.d.ts +18 -9
  72. package/dist/core/governance-codes.d.ts +9 -2
  73. package/dist/core/governance-codes.js +9 -0
  74. package/dist/core/hands-band-screen.d.ts +7 -0
  75. package/dist/core/hands-band-screen.js +32 -0
  76. package/dist/core/hooks.d.ts +21 -19
  77. package/dist/core/hooks.js +6 -5
  78. package/dist/core/locked-config.d.ts +110 -31
  79. package/dist/core/locked-config.js +155 -42
  80. package/dist/core/lsp.d.ts +1 -1
  81. package/dist/core/mcp-probe.js +1 -1
  82. package/dist/core/mcp-server-spec.d.ts +152 -17
  83. package/dist/core/mcp-server-spec.js +223 -40
  84. package/dist/core/mcp.d.ts +21 -14
  85. package/dist/core/mcp.js +59 -54
  86. package/dist/core/memory-engine/engine.d.ts +14 -19
  87. package/dist/core/memory-engine/engine.js +9 -6
  88. package/dist/core/memory-engine/export-bundle.d.ts +1 -1
  89. package/dist/core/memory-engine/export-bundle.js +1 -1
  90. package/dist/core/memory-engine/file-backend.d.ts +2 -6
  91. package/dist/core/memory-engine/file-backend.js +1 -12
  92. package/dist/core/memory.d.ts +3 -3
  93. package/dist/core/mode-policy.d.ts +16 -26
  94. package/dist/core/mode-policy.js +5 -18
  95. package/dist/core/mods/kernel/dispatch.js +13 -15
  96. package/dist/core/mods/kernel/events.d.ts +9 -6
  97. package/dist/core/mods/kernel/events.js +2 -2
  98. package/dist/core/mods/kernel/receive.d.ts +41 -11
  99. package/dist/core/mods/kernel/receive.js +124 -54
  100. package/dist/core/mods/kernel/site-rules.d.ts +80 -15
  101. package/dist/core/mods/kernel/site-rules.js +232 -40
  102. package/dist/core/mods/stations.d.ts +0 -6
  103. package/dist/core/mods/stations.js +0 -7
  104. package/dist/core/mounted-mcp.d.ts +57 -0
  105. package/dist/core/mounted-mcp.js +71 -2
  106. package/dist/core/own-property-receipt.d.ts +13 -0
  107. package/dist/core/own-property-receipt.js +3 -1
  108. package/dist/core/parent-spec-seat.d.ts +12 -15
  109. package/dist/core/parent-spec-seat.js +14 -6
  110. package/dist/core/pause-registry.d.ts +35 -1
  111. package/dist/core/pause-registry.js +10 -0
  112. package/dist/core/permission-rule-consent.d.ts +18 -5
  113. package/dist/core/permission-rule-consent.js +13 -8
  114. package/dist/core/permission-rule-model.d.ts +87 -15
  115. package/dist/core/permission-rule-model.js +87 -8
  116. package/dist/core/permission-rule-org.d.ts +200 -33
  117. package/dist/core/permission-rule-org.js +217 -91
  118. package/dist/core/permission-rule-session.js +2 -2
  119. package/dist/core/permission-rule-store.d.ts +8 -0
  120. package/dist/core/permission-rule-store.js +1 -0
  121. package/dist/core/permission-rule-sync.js +3 -2
  122. package/dist/core/permission-rules.d.ts +7 -1
  123. package/dist/core/permission-rules.js +37 -8
  124. package/dist/core/read-only-shell.d.ts +1 -1
  125. package/dist/core/read-only-shell.js +30 -9
  126. package/dist/core/remote-env.d.ts +41 -1
  127. package/dist/core/remote-env.js +18 -0
  128. package/dist/core/resume-startup-cause.d.ts +18 -0
  129. package/dist/core/resume-startup-cause.js +12 -0
  130. package/dist/core/retention.js +7 -2
  131. package/dist/core/retired-keys.d.ts +8 -2
  132. package/dist/core/retired-keys.js +12 -1
  133. package/dist/core/roles.js +60 -10
  134. package/dist/core/rule-lane-reads.js +1 -1
  135. package/dist/core/runner/approval-feedback.d.ts +46 -0
  136. package/dist/core/runner/approval-feedback.js +41 -0
  137. package/dist/core/runner/compaction-call-options.d.ts +3 -3
  138. package/dist/core/runner/compaction-call-options.js +2 -2
  139. package/dist/core/runner/contracts.d.ts +34 -41
  140. package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
  141. package/dist/core/runner/cross-boundary-lane.js +190 -0
  142. package/dist/core/runner/decide-continuation.d.ts +4 -4
  143. package/dist/core/runner/decide-continuation.js +3 -1
  144. package/dist/core/runner/gate-exit.d.ts +32 -12
  145. package/dist/core/runner/gate-exit.js +77 -34
  146. package/dist/core/runner/inherited-ask-grants.js +2 -2
  147. package/dist/core/runner/mcp-redial.d.ts +52 -10
  148. package/dist/core/runner/mcp-redial.js +38 -9
  149. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  150. package/dist/core/runner/permission-rule-lanes.js +22 -10
  151. package/dist/core/runner/person-path-rows.d.ts +5 -3
  152. package/dist/core/runner/person-path-rows.js +2 -2
  153. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
  154. package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
  155. package/dist/core/runner/prepare-ask-lane.js +3 -3
  156. package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
  157. package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
  158. package/dist/core/runner/prepare-config-doors.d.ts +58 -15
  159. package/dist/core/runner/prepare-config-doors.js +167 -146
  160. package/dist/core/runner/prepare-context-lane.js +6 -3
  161. package/dist/core/runner/prepare-defer-classify.js +4 -7
  162. package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
  163. package/dist/core/runner/prepare-delegation-surface.js +8 -7
  164. package/dist/core/runner/prepare-execution-env.d.ts +1 -2
  165. package/dist/core/runner/prepare-execution-env.js +2 -1
  166. package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
  167. package/dist/core/runner/prepare-gate-stations.js +4 -3
  168. package/dist/core/runner/prepare-hands-readface.d.ts +3 -3
  169. package/dist/core/runner/prepare-hands-readface.js +3 -2
  170. package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
  171. package/dist/core/runner/prepare-inherited-gate.js +3 -2
  172. package/dist/core/runner/prepare-listings.d.ts +1 -1
  173. package/dist/core/runner/prepare-listings.js +4 -2
  174. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  175. package/dist/core/runner/prepare-memory-engine-session.js +19 -6
  176. package/dist/core/runner/prepare-memory.d.ts +3 -2
  177. package/dist/core/runner/prepare-memory.js +6 -2
  178. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  179. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  180. package/dist/core/runner/prepare-park-ask.d.ts +1 -1
  181. package/dist/core/runner/prepare-park-ask.js +9 -3
  182. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  183. package/dist/core/runner/prepare-policy-chain.js +14 -19
  184. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  185. package/dist/core/runner/prepare-project-context.js +6 -4
  186. package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
  187. package/dist/core/runner/prepare-prompt-assembly.js +20 -16
  188. package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
  189. package/dist/core/runner/prepare-prompt-inputs.js +6 -3
  190. package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
  191. package/dist/core/runner/prepare-protocol-tools.js +19 -12
  192. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  193. package/dist/core/runner/prepare-question-face.js +4 -3
  194. package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
  195. package/dist/core/runner/prepare-safety-scan.js +34 -27
  196. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
  197. package/dist/core/runner/prepare-suspend-saga.js +6 -2
  198. package/dist/core/runner/prepare-task.js +22 -19
  199. package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
  200. package/dist/core/runner/prepare-turn-wiring.js +14 -49
  201. package/dist/core/runner/prepare-wiring-manifest.d.ts +10 -5
  202. package/dist/core/runner/prepare-wiring-manifest.js +9 -6
  203. package/dist/core/runner/prepare-workspace-restore.js +2 -2
  204. package/dist/core/runner/resume-admission.d.ts +4 -1
  205. package/dist/core/runner/resume-admission.js +16 -14
  206. package/dist/core/runner/resume-apply.js +4 -4
  207. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  208. package/dist/core/runner/resume-internals-and-config.js +3 -8
  209. package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
  210. package/dist/core/runner/resume-policy-outcome.js +18 -15
  211. package/dist/core/runner/resume-preflight.js +2 -2
  212. package/dist/core/runner/resume-review-outcome.js +3 -3
  213. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  214. package/dist/core/runner/retired-runner-deps.js +1 -4
  215. package/dist/core/runner/run-leg.js +97 -43
  216. package/dist/core/runner/run-recovery-lanes.js +5 -3
  217. package/dist/core/runner/run-settle-and-teardown.js +2 -0
  218. package/dist/core/runner/run-terminal-adoption.js +21 -9
  219. package/dist/core/runner/run-turn-boundary.js +9 -3
  220. package/dist/core/runner/runtask.js +1 -1
  221. package/dist/core/runner/session-file-state-replay.d.ts +5 -2
  222. package/dist/core/runner/session-file-state-replay.js +3 -2
  223. package/dist/core/runner/skills-seat.d.ts +15 -0
  224. package/dist/core/runner/skills-seat.js +57 -0
  225. package/dist/core/runner/stream-steer-verb.js +2 -2
  226. package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
  227. package/dist/core/runner/sub-agent-deny-lists.js +7 -5
  228. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  229. package/dist/core/runner/synthetic-tools.js +2 -12
  230. package/dist/core/runner/tool-face-overlay.d.ts +24 -6
  231. package/dist/core/runner/tool-face-overlay.js +24 -15
  232. package/dist/core/runner-deps.d.ts +37 -22
  233. package/dist/core/session-policy-store.d.ts +19 -0
  234. package/dist/core/session-policy-store.js +22 -2
  235. package/dist/core/session-store.d.ts +35 -16
  236. package/dist/core/session-store.js +20 -12
  237. package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
  238. package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
  239. package/dist/core/shell-wrapper-table.d.ts +5 -3
  240. package/dist/core/shell-wrapper-table.js +1 -1
  241. package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
  242. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  243. package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
  244. package/dist/core/store-contracts/session-store-contract.js +639 -0
  245. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
  246. package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
  247. package/dist/core/task-event.d.ts +44 -6
  248. package/dist/core/task-notification.js +2 -2
  249. package/dist/core/task-registry-agent.js +1 -0
  250. package/dist/core/task-registry-shared.d.ts +5 -0
  251. package/dist/core/task-registry.d.ts +7 -0
  252. package/dist/core/task-registry.js +17 -0
  253. package/dist/core/task-result.d.ts +1 -1
  254. package/dist/core/task-spec.d.ts +7 -7
  255. package/dist/core/tighten-task-spec.d.ts +6 -4
  256. package/dist/core/tighten-task-spec.js +2 -2
  257. package/dist/core/tool-catalog-entries.d.ts +1 -1
  258. package/dist/core/tool-catalog-entries.js +52 -52
  259. package/dist/core/tool-face-reader.d.ts +49 -0
  260. package/dist/core/tool-face-reader.js +94 -0
  261. package/dist/core/tool-face.d.ts +17 -8
  262. package/dist/core/tool-face.js +1 -0
  263. package/dist/core/tool-policy.d.ts +67 -23
  264. package/dist/core/tool-policy.js +72 -60
  265. package/dist/core/tool-roster.d.ts +46 -28
  266. package/dist/core/tool-roster.js +91 -14
  267. package/dist/core/tool-spec-members.js +2 -2
  268. package/dist/core/tool-spec.d.ts +20 -4
  269. package/dist/core/tools.js +2 -0
  270. package/dist/core/trace.d.ts +24 -2
  271. package/dist/core/types.d.ts +3 -3
  272. package/dist/core/types.js +1 -1
  273. package/dist/core/untrusted-text.d.ts +23 -0
  274. package/dist/core/untrusted-text.js +10 -10
  275. package/dist/core/user-attachment.d.ts +56 -2
  276. package/dist/core/user-attachment.js +139 -56
  277. package/dist/core/wiring-manifest.d.ts +4 -2
  278. package/dist/engine/compaction/compaction.d.ts +2 -2
  279. package/dist/engine/compaction/utils.d.ts +2 -2
  280. package/dist/engine/harness/agent-harness.js +2 -1
  281. package/dist/engine/harness/types.d.ts +10 -4
  282. package/dist/engine/llm/types.d.ts +7 -2
  283. package/dist/engine/llm/types.js +2 -1
  284. package/dist/engine/loop/agent-loop.d.ts +12 -1
  285. package/dist/engine/loop/agent-loop.js +17 -5
  286. package/dist/engine/loop/types.d.ts +7 -1
  287. package/dist/engine/session/repo-utils.d.ts +5 -0
  288. package/dist/engine/session/repo-utils.js +9 -0
  289. package/dist/engine/session/storage-base.js +2 -2
  290. package/dist/index.d.ts +37 -17
  291. package/dist/index.js +31 -14
  292. package/dist/internal/harness.d.ts +1 -0
  293. package/dist/internal/harness.js +1 -0
  294. package/dist/internal/llm.d.ts +1 -1
  295. package/dist/internal/llm.js +1 -1
  296. package/dist/orchestration/goal.d.ts +24 -1
  297. package/dist/orchestration/goal.js +3 -2
  298. package/dist/orchestration/run-workflow-tool.d.ts +3 -0
  299. package/dist/orchestration/run-workflow-tool.js +1 -0
  300. package/dist/orchestration/workflow-governance.d.ts +1 -1
  301. package/dist/orchestration/workflow.d.ts +3 -0
  302. package/dist/orchestration/workflow.js +2 -1
  303. package/dist/prompt-assembly/artifact-store.d.ts +44 -9
  304. package/dist/prompt-assembly/artifact-store.js +38 -12
  305. package/dist/prompt-assembly/artifact.d.ts +12 -11
  306. package/dist/prompt-assembly/artifact.js +52 -21
  307. package/dist/prompt-assembly/assemble.d.ts +2 -0
  308. package/dist/prompt-assembly/assemble.js +2 -1
  309. package/dist/prompt-assembly/catalog/index.js +2 -1
  310. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  311. package/dist/prompt-assembly/catalog/memory.js +6 -0
  312. package/dist/prompt-assembly/catalog/schema.d.ts +19 -2
  313. package/dist/prompt-assembly/catalog/schema.js +3 -0
  314. package/dist/prompt-assembly/composer.d.ts +2 -0
  315. package/dist/prompt-assembly/composer.js +1 -1
  316. package/dist/prompt-assembly/overlay.d.ts +21 -11
  317. package/dist/prompt-assembly/overlay.js +57 -19
  318. package/dist/prompt-assembly/select.d.ts +21 -6
  319. package/dist/prompt-assembly/select.js +41 -4
  320. package/dist/prompts/default.d.ts +1 -12
  321. package/dist/prompts/default.js +0 -3
  322. package/dist/shell/lex.d.ts +87 -8
  323. package/dist/shell/lex.js +283 -49
  324. package/dist/stores/file/index.d.ts +8 -6
  325. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  326. package/dist/stores/file/permission-rule-store.js +2 -1
  327. package/dist/tools/artifact/artifact-tool.js +14 -3
  328. package/dist/tools/fs/bash-program-position.d.ts +3 -15
  329. package/dist/tools/fs/bash-program-position.js +3 -10
  330. package/dist/tools/fs/bash-readonly-classifier.js +2 -0
  331. package/dist/tools/fs/fs-bash.d.ts +3 -3
  332. package/dist/tools/fs/fs-bash.js +72 -101
  333. package/dist/tools/fs/fs-read.d.ts +12 -0
  334. package/dist/tools/fs/fs-read.js +10 -9
  335. package/dist/tools/fs/fs-shared.d.ts +27 -31
  336. package/dist/tools/fs/fs-shared.js +12 -15
  337. package/dist/tools/fs/fs-write.js +1 -1
  338. package/dist/tools/fs/index.js +2 -2
  339. package/dist/tools/fs/read-deny-home.d.ts +1 -1
  340. package/dist/tools/fs/read-deny-home.js +5 -4
  341. package/dist/tools/fs/read-deny.d.ts +16 -3
  342. package/dist/tools/fs/read-deny.js +12 -9
  343. package/dist/tools/fs/safety.d.ts +7 -6
  344. package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
  345. package/dist/tools/fs/shell-read-bindings.js +15 -16
  346. package/dist/tools/fs/shell-read-device.js +1 -1
  347. package/dist/tools/fs/shell-read-plan.js +36 -47
  348. package/dist/tools/fs/shell-read-word.d.ts +1 -6
  349. package/dist/tools/fs/shell-read-word.js +2 -20
  350. package/dist/tools/fs/shell-reentry-text.js +1 -1
  351. package/dist/tools/web.d.ts +2 -2
  352. package/package.json +4 -1
  353. package/test/export-surface.snapshot.json +5651 -5457
  354. package/wire-changes/core@7.53.0.json +1968 -0
  355. package/wire-changes/core@7.54.0.json +2870 -0
  356. package/dist/core/shell-scan.d.ts +0 -60
  357. package/dist/core/shell-scan.js +0 -183
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_CHARS_PER_TOKEN, estimateContextTokens } from "../../internal/harness.js";
2
2
  import { TOOL_TURN_REPAIR_DROPS } from "../../internal/llm.js";
3
+ import { droppedTransmissions } from "../user-attachment.js";
3
4
  import { clearStaleToolResults, createClearedProjectionLedger, dropEmptyFailureAssistants, editBudget, replayClearedProjection, resolveTriggerWindow } from "../context-edit.js";
4
5
  import { guardBudget, insertTrimNotice, protectGitFrame, trimToBudget } from "../context-guard.js";
5
6
  import { capAggregateMediaBytes, mediaBudgetBytes } from "../media-byte-cap.js";
@@ -155,14 +156,14 @@ function buildMicroCompactState(deps, model, sessionId, runId, offloadStore, kno
155
156
  };
156
157
  }
157
158
  export function landStaleResultClears(args) {
158
- const clearedToolCallIds = [];
159
+ const transmissions = [];
159
160
  for (const c of args.cleared) {
160
161
  args.ledger.entries.set(c.key, { marker: c.marker, groupCount: c.groupCount, fp: c.fp });
161
162
  if (c.toolCallId !== undefined)
162
- clearedToolCallIds.push(c.toolCallId);
163
+ transmissions.push(c.toolCallId);
163
164
  }
164
165
  if (args.readFileState !== undefined) {
165
- applyContextShrinkToReadFileState(args.readFileState, { kind: "tool-results-cleared", clearedToolCallIds });
166
+ applyContextShrinkToReadFileState(args.readFileState, { kind: "transmissions-gone", transmissions });
166
167
  }
167
168
  }
168
169
  function recordFrontierClears(args) {
@@ -209,6 +210,8 @@ export async function runGuardChain(args) {
209
210
  if (dropped) {
210
211
  args.trimPressureRef.droppedMessages = true;
211
212
  const droppedCount = view.length - trimmed.length;
213
+ if (args.readFileState !== undefined)
214
+ applyContextShrinkToReadFileState(args.readFileState, { kind: "transmissions-gone", transmissions: droppedTransmissions(view, trimmed) });
212
215
  trimmed = insertTrimNotice(trimmed);
213
216
  emitTrace(deps.tracer, () => ({
214
217
  kind: "context.trim",
@@ -9,6 +9,7 @@ import { classifyDeferredWithGate } from "./tool-defer-gate.js";
9
9
  import { TOOL_SEARCH_NAME } from "./tool-disclosure.js";
10
10
  import { resolveToolSearch, toolSearchSettingOf } from "../tool-search-setting.js";
11
11
  import { RosterBuilder } from "../tool-roster.js";
12
+ import { valveLeaves } from "../../agents/tool-filter.js";
12
13
  function explicitlyDeferredMemoryTrio(mounted, roster, callerDeferNames) {
13
14
  return mounted ? MEMORY_ENGINE_TOOL_NAMES.filter((n) => roster.some((t) => t.name === n) && (callerDeferNames ?? []).includes(n)) : [];
14
15
  }
@@ -19,12 +20,8 @@ export function prepareDeferClassify(input) {
19
20
  const { spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryRecallSegment, onceLedger, sessionId } = input;
20
21
  const tools = roster.tools;
21
22
  let memoryBlock = input.memoryBlock;
22
- if (spec.excludeAllTools === true) {
23
- roster.unmountWhere(() => true);
24
- }
25
- else {
26
- roster.unmountWhere((t) => !toolFaceSnapshot.selector.admits(t));
27
- }
23
+ const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
24
+ roster.unmountWhere((t) => !leaves(t));
28
25
  if (handsEnabled) {
29
26
  const fullShellOnRoster = tools.some((t) => t.name === "Bash" && getToolContract(t, "core").contractId === FULL_SHELL_CONTRACT_ID);
30
27
  if (fullShellOnRoster !== fullShellReachable) {
@@ -48,7 +45,7 @@ export function prepareDeferClassify(input) {
48
45
  .map((t) => t.name);
49
46
  const resolvedToolSearch = resolveToolSearch(deps.toolSearch);
50
47
  const toolSearchSeat = toolSearchSettingOf(resolvedToolSearch);
51
- const toolSearchAdmitted = toolFaceSnapshot.selector.admits({ name: TOOL_SEARCH_NAME });
48
+ const toolSearchAdmitted = leaves({ name: TOOL_SEARCH_NAME });
52
49
  const classifyDeferredOverFace = (face, builtinDeferNames) => {
53
50
  const mounted = new Set(face.map((t) => t.name));
54
51
  const classified = classifyDeferredWithGate({
@@ -30,11 +30,11 @@ export interface PrepareDelegationSurfaceInput {
30
30
  /** borrowed-readonly — the REBOUND spec. Read: `tools` (the shadow checks and the revival spawner's delegation-tool
31
31
  * lookup), `oneShot` (the read/kill faces' completion promises), `retainBackgroundProcesses` (the Monitor receipt),
32
32
  * `handsReadOnly` is NOT read here (the hands mount decided the surface). Never mutated. */
33
- spec: Pick<TaskSpec, "tools" | "oneShot" | "retainBackgroundProcesses">;
33
+ spec: Pick<TaskSpec, "tools" | "oneShot" | "retainBackgroundProcesses" | "excludeAllTools">;
34
34
  /** borrowed-readonly — the deployment seats the mounts read: `workflowRunStore` / `backgroundAgentStore` / `mailboxStore` (the
35
35
  * read/kill faces and the tier-3 revival seams), `rosterStore`, `peerLane`, `peerDirectory`, `onNotice`,
36
36
  * `onBackgroundChildEvent`, `tracer`. */
37
- deps: Pick<RunnerDeps, "workflowRunStore" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "peerLane" | "peerDirectory" | "onNotice" | "onBackgroundChildEvent" | "tracer">;
37
+ deps: Pick<RunnerDeps, "workflowRunStore" | "backgroundAgentStore" | "mailboxStore" | "rosterStore" | "peerLane" | "peerDirectory" | "principalInboxConsumer" | "onNotice" | "onBackgroundChildEvent" | "tracer">;
38
38
  /** borrowed-readonly — the trusted spawn-side channel: `parentNotify` (the delegated-child door), the uplink / sibling /
39
39
  * identity seats the SendMessage mount forwards, `onTaskNotification`, `onSubagentSpawn`. Never mutated. */
40
40
  internals: Pick<RunInternals, "parentNotify" | "parentPeerRef" | "uplinkSessionId" | "parentRetainLedger" | "explicitAgentName" | "parentTaskId" | "parentSessionId" | "peerSelfRef" | "peerInboundChainRef" | "onTaskNotification" | "onSubagentSpawn"> | undefined;
@@ -75,8 +75,9 @@ export interface PrepareDelegationSurfaceInput {
75
75
  * Writers here: the eight mounts (TaskOutput, TaskStop, SendMessage, AgentTranscript, ListAgents, Monitor, the worktree
76
76
  * pair, the offload reader), every one a `mount`. */
77
77
  roster: RosterBuilder;
78
- /** borrowed-mutable — the effect collection (`Prepared.toolEffects`). Writers here: TaskOutput → read, TaskStop / SendMessage
79
- * (built-in mount only) / Monitor / EnterWorktree / ExitWorktree → write. */
78
+ /** borrowed-readonly — not read by this phase: the effect collection (`Prepared.toolEffects`), the same map `roster` writes at each mount
79
+ * (TaskOutput → read, TaskStop / SendMessage / Monitor / EnterWorktree / ExitWorktree → write, ReadInbox / ListAgents and its
80
+ * alias → read), each from the mounted tool's own declaration; this phase writes nothing into it by name. */
80
81
  toolEffects: Map<string, ToolEffect>;
81
82
  /** borrowed-mutable — the explicit-negative axis declarations. Writer here: the built-in SendMessage mount's `egress: false`
82
83
  * (report-face only). */
@@ -1,8 +1,9 @@
1
1
  import { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME } from "../../agents/agent-transcript-tool.js";
2
2
  import { createSendMessageTool, SEND_MESSAGE_TOOL_NAME } from "../../agents/send-message-tool.js";
3
- import { listAgentsMountable, mountListAgents, peerLaneSendMessageSeats } from "../../agents/peer-session-drain.js";
3
+ import { listAgentsMountable, mountListAgents, peerLaneSendMessageSeats, terminalsDrainPrincipalInbox } from "../../agents/peer-session-drain.js";
4
4
  import { resolvePeerLaneConfig } from "../../agents/peer-admission.js";
5
5
  import { createReadInboxTool, READ_INBOX_TOOL_NAME } from "../../agents/read-inbox-tool.js";
6
+ import { valveLeaves } from "../../agents/tool-filter.js";
6
7
  import { createMonitorTool } from "../../tools/monitor.js";
7
8
  import { createWorktreeTools } from "../../tools/worktree.js";
8
9
  import { createTaskOutputTool, createTaskStopTool, defaultTaskRegistry } from "../task-registry.js";
@@ -12,9 +13,10 @@ import { deliverEngineNotice } from "../types.js";
12
13
  import { RosterBuilder } from "../tool-roster.js";
13
14
  import { sendMessageContinuationSeats } from "./send-message-continuation.js";
14
15
  export function prepareDelegationSurface(input) {
15
- const { spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, taskRootCanonical, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, sessionBox, roster, toolEffects, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, checkpointSeat, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle } = input;
16
+ const { spec, deps, internals, resume, sessionId, hostTaskId, taskScope, taskRootFinal, taskRootCanonical, executionEnv, runnerSelf, backgroundTaskToolsActive, workflowToolsActive, peerLaneActive, peerSendMessageBuiltIn, peerLaneRefs, sessionBox, roster, axisExplicitNegatives, envHandToolNames, toolFaceSnapshot, firstPartyOffload, offloadStore, subagentRetain, enrichSpecToolCtx, checkpointSeat, handsCwdRef, wsSnapshot, rebaseWsPath, rebaseRestoredPath, workspaceStateSettle } = input;
16
17
  let worktreeSessionRef;
17
18
  const delegationSurfaceActive = backgroundTaskToolsActive || workflowToolsActive;
19
+ const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
18
20
  let sendMessageTier;
19
21
  if (delegationSurfaceActive || internals?.parentNotify !== undefined || peerLaneActive) {
20
22
  if (delegationSurfaceActive) {
@@ -54,7 +56,7 @@ export function prepareDelegationSurface(input) {
54
56
  ...(deps.backgroundAgentStore !== undefined ? { agentStore: deps.backgroundAgentStore } : {}),
55
57
  ...(deps.mailboxStore !== undefined ? { mailbox: deps.mailboxStore } : {}),
56
58
  ...(reviveSpawn !== undefined ? { reviveSpawn } : {}),
57
- ...(peerLaneActive ? peerLaneSendMessageSeats({ peerDirectory: deps.peerDirectory, sessionId, scope: taskScope, ...(internals?.explicitAgentName !== undefined ? { name: internals.explicitAgentName } : {}), refs: peerLaneRefs, listingMounted: listAgentsMountable({ selector: toolFaceSnapshot.selector, specTools: spec.tools ?? [] }) }) : {}),
59
+ ...(peerLaneActive ? peerLaneSendMessageSeats({ peerDirectory: deps.peerDirectory, sessionId, scope: taskScope, ...(internals?.explicitAgentName !== undefined ? { name: internals.explicitAgentName } : {}), refs: peerLaneRefs, listingMounted: listAgentsMountable({ leaves, specTools: spec.tools ?? [] }) }) : {}),
58
60
  onNotifyError: (f) => emitTrace(deps.tracer, () => ({ kind: "observer.notify_failed", version: 1, taskId: hostTaskId, site: f.site, message: f.error.message, ts: Date.now() })),
59
61
  onTranscriptIntegrityGap: (handle, scope) => deliverEngineNotice(deps.onNotice, {
60
62
  code: "delegation.transcript_integrity",
@@ -80,11 +82,10 @@ export function prepareDelegationSurface(input) {
80
82
  }
81
83
  }
82
84
  }
83
- if (sessionBox !== undefined && internals?.onTaskNotification !== undefined && toolFaceSnapshot.selector.admits({ name: READ_INBOX_TOOL_NAME }) && !(spec.tools ?? []).some((t) => t.name === READ_INBOX_TOOL_NAME)) {
84
- toolEffects.set(READ_INBOX_TOOL_NAME, "read");
85
- roster.mount(firstPartyOffload(createReadInboxTool({ pull: () => peerLaneRefs.pull })), { source: "builtin", mountedBy: "peerLane" });
85
+ if (sessionBox !== undefined && internals?.onTaskNotification !== undefined && leaves({ name: READ_INBOX_TOOL_NAME }) && !(spec.tools ?? []).some((t) => t.name === READ_INBOX_TOOL_NAME)) {
86
+ roster.mount(firstPartyOffload(createReadInboxTool({ pull: () => peerLaneRefs.pull, ...(terminalsDrainPrincipalInbox(deps) ? { coversPrincipalInbox: true } : {}) })), { source: "builtin", mountedBy: "peerLane" });
86
87
  }
87
- const listAgents = (peerLaneActive || delegationSurfaceActive) && peerSendMessageBuiltIn && listAgentsMountable({ selector: toolFaceSnapshot.selector, specTools: spec.tools ?? [] }) ? mountListAgents({ ...(peerLaneActive ? { peerDirectory: deps.peerDirectory } : {}), freshWindowMs: resolvePeerLaneConfig(deps.peerLane, deps.onNotice).listingFreshWindowMs, sessionId, scope: taskScope, hostTaskId, ...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}), ...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}), registry: defaultTaskRegistry, ...(deps.rosterStore !== undefined ? { roster: deps.rosterStore } : {}), ...(sendMessageTier !== undefined ? { continuationTier: sendMessageTier } : {}), ...(checkpointSeat !== undefined ? { readSeats: { checkpointSeat } } : {}), specTools: spec.tools ?? [], toolEffects }) : undefined;
88
+ const listAgents = (peerLaneActive || delegationSurfaceActive) && peerSendMessageBuiltIn && listAgentsMountable({ leaves, specTools: spec.tools ?? [] }) ? mountListAgents({ ...(peerLaneActive ? { peerDirectory: deps.peerDirectory } : {}), freshWindowMs: resolvePeerLaneConfig(deps.peerLane, deps.onNotice).listingFreshWindowMs, sessionId, scope: taskScope, hostTaskId, ...(internals?.parentTaskId !== undefined ? { parentTaskId: internals.parentTaskId } : {}), ...(internals?.parentSessionId !== undefined ? { parentSessionId: internals.parentSessionId } : {}), registry: defaultTaskRegistry, ...(deps.rosterStore !== undefined ? { roster: deps.rosterStore } : {}), ...(sendMessageTier !== undefined ? { continuationTier: sendMessageTier } : {}), ...(checkpointSeat !== undefined ? { readSeats: { checkpointSeat } } : {}), specTools: spec.tools ?? [] }) : undefined;
88
89
  if (listAgents !== undefined)
89
90
  roster.mount(firstPartyOffload(listAgents), { source: "builtin", mountedBy: "peerLane" });
90
91
  if (backgroundTaskToolsActive) {
@@ -20,8 +20,7 @@ export interface PrepareExecutionEnvInput {
20
20
  /** borrowed-readonly — the trusted spawn-side requests: the explicit cwd (a contract), the isolation
21
21
  * request and the parent's cwd (both threaded to the factory ctx). */
22
22
  internals: Pick<RunInternals, "requestedCwd" | "isolation" | "parentCwd" | "callerRoot" | "worktreeOffered"> | undefined;
23
- /** borrowed-readonly — the resume leg, read only to refuse an explicit cwd that a checkpoint workspace
24
- * restore would overrule. */
23
+ /** borrowed-readonly — the resume leg: read to refuse an explicit cwd a checkpoint restore would overrule, and to tell the factory which workspace it rebuilds. */
25
24
  resume: Pick<PrepareResume, "workspaceHandle"> | undefined;
26
25
  /** borrowed-readonly — the run tree's placement fixed point, resolved ONCE by the driver; the factory
27
26
  * door refuses an empty value loudly before the factory is asked. */
@@ -1,5 +1,5 @@
1
1
  import { StubExecutionEnv } from "../stub-env.js";
2
- import { hasDestroy } from "../remote-env.js";
2
+ import { frozenHandleCopy, hasDestroy } from "../remote-env.js";
3
3
  import { announceMalformedCapabilities } from "./env-capability-census.js";
4
4
  import { childPlacementOnLeg, deploymentCanRerootChild, worktreeNotHonored } from "./child-tree.js";
5
5
  import { settleTeardownLeg } from "./teardown-bounded.js";
@@ -24,6 +24,7 @@ export async function prepareExecutionEnv(input) {
24
24
  taskId: spec.taskId,
25
25
  ...(internals?.isolation ? { isolation: internals.isolation } : {}),
26
26
  ...(internals?.parentCwd ? { parentCwd: internals.parentCwd } : {}),
27
+ ...(resume?.workspaceHandle !== undefined ? { resumeWorkspace: frozenHandleCopy(resume.workspaceHandle) } : {}),
27
28
  })
28
29
  : undefined;
29
30
  if (ownedEnv !== undefined)
@@ -170,6 +170,8 @@ export interface PrepareGateStationsInput {
170
170
  /** borrowed-readonly — the leg's shell READ STATION (`ToolGateInput.shellReadCheck`), mounted by the hands phase, or
171
171
  * undefined with no real shell: no station, nothing judged. */
172
172
  shellReadCheck: ShellReadCheck | undefined;
173
+ /** borrowed-readonly — the leg's cross-boundary seat (`ToolGateInput.crossBoundaryCheck`), or undefined on a leg whose station is not engaged. */
174
+ crossBoundaryCheck: import("../cross-boundary-taint.js").CrossBoundaryCheck | undefined;
173
175
  /** borrowed-readonly — the leg's resolved read face (`undefined` with no hands), read per call into the class derivation. */
174
176
  readFace: () => ContainmentFace | undefined;
175
177
  /** borrowed-readonly — the per-tool irreversibility tier handed to the gate per call. */
@@ -46,7 +46,7 @@ export function maybeHumanRejectionHalt(input) {
46
46
  };
47
47
  }
48
48
  export function prepareGateStations(input) {
49
- const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, handsCwdRef, stampCallTarget, hookEnvFace, writeProtectionCheck, shellReadCheck, readFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, askRoute, permissionMode, toolMarkSources, a2aIsolatePeers, ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, frameSettlement, seatInputsFor, modBus, inheritedToolChecks } = input;
49
+ const { askLane, parkAsk, tools, toolRosterDeltas, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, toolOccurrences, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, handsCwdRef, stampCallTarget, hookEnvFace, writeProtectionCheck, shellReadCheck, crossBoundaryCheck, readFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider, autoModeDenialTracking, askRoute, permissionMode, toolMarkSources, a2aIsolatePeers, ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, frameSettlement, seatInputsFor, modBus, inheritedToolChecks } = input;
50
50
  const releasesAnnounced = new Map();
51
51
  const onModeReleased = (info) => {
52
52
  const table = info.readUnestablished === true ? input.readDenyInForce(info.toolCallId) : undefined;
@@ -86,7 +86,8 @@ export function prepareGateStations(input) {
86
86
  spec.enablePlanMode === true ||
87
87
  complianceDenies.has("web_fetch") ||
88
88
  writeProtectionArmed ||
89
- shellReadCheck !== undefined;
89
+ shellReadCheck !== undefined ||
90
+ crossBoundaryCheck !== undefined;
90
91
  if (toolCallGateArmedRef.armed) {
91
92
  harness.on("tool_call", async (called) => {
92
93
  const e = { ...called, toolName: rosterToolName(toolRosterDeltas.current, called.toolName) };
@@ -132,7 +133,7 @@ export function prepareGateStations(input) {
132
133
  egress: heldBy("gate.egress", egressTools, call),
133
134
  peerMessage: heldBy("gate.peerMessage", PEER_MESSAGE_NAMES, call),
134
135
  ...(writeProtectionCheck !== undefined ? { writeProtectionCheck } : {}),
135
- ...(shellReadCheck !== undefined ? { shellReadCheck } : {}),
136
+ ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(crossBoundaryCheck !== undefined ? { crossBoundaryCheck } : {}),
136
137
  readFace,
137
138
  irreversibility: tierSeat?.value,
138
139
  reversibilityProbe: tierSeat?.read(reversibilityProbes),
@@ -88,7 +88,7 @@ export interface PrepareHandsReadFaceInput {
88
88
  /** borrowed-readonly — the task-spec seats this phase reads, as a Pick over the SAME spec object
89
89
  * (R-4). `tools` feeds only the band shadow check; `envFacts` only the advertised scratchpad;
90
90
  * `retainBackgroundProcesses` only the band's retain lane (Bash's lifetime sentence + row stamp). */
91
- spec: Pick<TaskSpec, "additionalDirectories" | "additionalReadDirectories" | "envFacts" | "handsReadOnly" | "readDenyPatterns" | "readFace" | "writeFace" | "oneShot" | "resumeAt" | "retainBackgroundProcesses" | "sessionId" | "tools">;
91
+ spec: Pick<TaskSpec, "additionalDirectories" | "additionalReadDirectories" | "envFacts" | "handsReadOnly" | "readDenyPatterns" | "readFace" | "writeFace" | "oneShot" | "resumeAt" | "retainBackgroundProcesses" | "sessionId" | "tools" | "excludeAllTools">;
92
92
  /** borrowed-readonly — the deployment seats this phase reads, as a Pick over the SAME deps
93
93
  * object (R-4: `deps.onError?.()` keeps its receiver; a new deps read must widen this Pick).
94
94
  * `readDenyBuiltinTiers`/`readDenyBuiltinExclude` are SNAPSHOTTED before the first await that
@@ -260,8 +260,8 @@ export interface PrepareHandsReadFaceResult {
260
260
  grantReadRoot: GrantReadRoot | undefined;
261
261
  /** owned — the store cell {@link grantReadRoot} judges against; the driver threads it to its one writer, the Artifact phase. */
262
262
  artifactStoreRef: ArtifactStoreRef | undefined;
263
- /** owned — the canonical containment root, published so the working-file ATTACHMENT
264
- * reader applies the same containment the hands tools do. Undefined ⇔ hands-less. */
263
+ /** owned — the canonical containment root, published so the compaction's kept-tail path
264
+ * normalizer resolves the way the hands tools do. Undefined ⇔ hands-less. */
265
265
  attachmentRootCanonical: string | undefined;
266
266
  /** owned — the run's read deny table ({@link pathTables}' facade: the run's latest, `forCall` a call's own). Undefined ⇔
267
267
  * hands-less (its consumers only exist with hands). */
@@ -21,6 +21,7 @@ import { RosterBuilder } from "../tool-roster.js";
21
21
  import { unionAddOnly } from "../child-clamp-seats.js";
22
22
  import { assertStringArraySeat } from "../read-face-seats.js";
23
23
  import { modePolicyOf } from "../mode-policy.js";
24
+ import { valveLeaves } from "../../agents/tool-filter.js";
24
25
  const faceClampAnnouncedSinks = { read: new WeakSet(), write: new WeakSet() };
25
26
  const faceClampConsoleAnnounced = { read: false, write: false };
26
27
  function announceDeploymentFaceClamp(kind, sink) {
@@ -253,7 +254,7 @@ export async function prepareHandsMount(input) {
253
254
  if (rk === undefined)
254
255
  continue;
255
256
  if ("content" in rec)
256
- seedReadFileStateFromTranscript(readFileState, rk, rec.content, rec.at);
257
+ seedReadFileStateFromTranscript(readFileState, rk, rec.content, rec.at, rec.transmittedByToolCallId);
257
258
  else
258
259
  readFileState.set(rk, { ...rec.observation, lastReadAt: rec.at });
259
260
  }
@@ -370,7 +371,7 @@ export async function prepareHandsMount(input) {
370
371
  return memoryWriteGate?.(w);
371
372
  },
372
373
  mountBackgroundTaskTools: false,
373
- monitorToolActive: backgroundTaskToolsActive && toolFaceSnapshot.selector.admits({ name: "Monitor" }),
374
+ monitorToolActive: backgroundTaskToolsActive && valveLeaves(spec, toolFaceSnapshot.selector)({ name: "Monitor" }),
374
375
  });
375
376
  {
376
377
  const bandNames = new Set(band.flatMap((t) => [t.name, ...(t.aliases ?? [])]));
@@ -70,6 +70,8 @@ export interface PrepareInheritedGateInput {
70
70
  deps: Pick<RunnerDeps, "autoMode" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "compliancePostureResolver" | "onError" | "onNotice" | "executionEnv" | "delegationEntryCaps" | "rosterStore" | "onBackgroundChildEvent" | "onQuestion">;
71
71
  /** borrowed-readonly — the run's approval seat as the config doors froze it: the frozen approver, and this leg's chain view. */
72
72
  askSeat: import("../wiring-manifest.js").AskSeat;
73
+ /** borrowed-readonly — the tree's cross-boundary token (the leg's lane: inherited, or minted by a root leg), handed to children. */
74
+ crossBoundaryTree: import("../cross-boundary-taint.js").CrossBoundaryTreeToken;
73
75
  /** borrowed-readonly — the trusted spawn-side channel: `inheritedGate` (the LIVE half of the chain fold), `ownOrgAdmissionRef`
74
76
  * (the same-session continuation's freeze), `delegationProvenance` (the F-012 stamp), and the identity / peer / notification
75
77
  * seats the ctx enrichment forwards. Never mutated. */
@@ -14,6 +14,7 @@ import { SessionModeSeats } from "./session-mode-seats.js";
14
14
  import { recordedModeSeed } from "../checkpoint-store.js";
15
15
  import { frozenSkillGrants } from "../skill-grant.js";
16
16
  import { attachRebuiltDenialTrackers, createDenialLimitStop } from "./denial-limit-arms.js";
17
+ import { valveLeaves } from "../../agents/tool-filter.js";
17
18
  export function prepareInheritedGate(input) {
18
19
  const { spec, deps, askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, pathRuleAnchors, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
19
20
  const liveInheritedGate = internals?.inheritedGate;
@@ -192,8 +193,7 @@ export function prepareInheritedGate(input) {
192
193
  const fullShellReachable = handsEnabled &&
193
194
  !(executionEnv instanceof StubExecutionEnv) &&
194
195
  spec.handsReadOnly !== true &&
195
- spec.excludeAllTools !== true &&
196
- toolFaceSnapshot.selector.admits({ name: "Bash" });
196
+ valveLeaves(spec, toolFaceSnapshot.selector)({ name: "Bash" });
197
197
  const { gateStopRef, stopForDenialLimit } = createDenialLimitStop({ sessionId, runId, onNotice: deps.onNotice, abort: abortRun });
198
198
  const delegationEntryCapsResolved = resolveDelegationEntryCaps(deps.delegationEntryCaps);
199
199
  const enrichSpecToolCtx = (ctx) => {
@@ -246,6 +246,7 @@ export function prepareInheritedGate(input) {
246
246
  activeSkillGrants: () => skillGrants.records(),
247
247
  activeRequestAllowedTools: () => input.requestAllowedTools.entries(),
248
248
  inheritedGateForChildren,
249
+ crossBoundaryTreeForChildren: input.crossBoundaryTree,
249
250
  delegationProvenanceForChildren,
250
251
  delegationSettlement: delegationSettlementForChildren,
251
252
  ...(autoModeDecider ? { autoModeReview: { decider: autoModeDecider } } : {}),
@@ -5,7 +5,7 @@ import type { ResolvedSkillListingBudget } from "../skill-listing-budget.js";
5
5
  export interface PrepareListingsInput {
6
6
  /** borrowed-readonly — the REBOUND spec (`spec′`). Read: `tools` (the roster-bearing delegation tool, by its `agentListing`
7
7
  * marker), `sessionId` (continuation ⇒ seeded/removal projections), `attachments` (the two opt-outs). Never mutated. */
8
- spec: Pick<TaskSpec, "agents" | "tools" | "sessionId" | "attachments">;
8
+ spec: Pick<TaskSpec, "agents" | "tools" | "sessionId" | "attachments" | "excludeAllTools">;
9
9
  /** borrowed-readonly — the once-per-session ledger: its deduplicated operator sink (`onError`) and
10
10
  * the whole announced snapshot (`arms()`) the mirror is seeded from. */
11
11
  onceLedger: AnnounceOnceSink & {
@@ -1,17 +1,19 @@
1
1
  import { formatLocalDate } from "../../prompts/default.js";
2
+ import { valveLeaves } from "../../agents/tool-filter.js";
2
3
  import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
3
4
  import { renderAgentListingDelta } from "./turn-attachments.js";
4
5
  export function prepareListings(input) {
5
6
  const { spec, onceLedger, sessionId, toolFaceSnapshot, activeTools, deferred, resume, skillsListing, listingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz, dateAnchor } = input;
6
7
  const rosterBearingSpec = (spec.tools ?? []).find((t) => t.agentListing !== undefined && t.agentListing.length > 0);
8
+ const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
7
9
  const rosterFaceDeferred = rosterBearingSpec !== undefined &&
8
- toolFaceSnapshot.selector.admits(rosterBearingSpec) &&
10
+ leaves(rosterBearingSpec) &&
9
11
  (toolFaceSnapshot.defer?.includes(rosterBearingSpec.name) ?? false) &&
10
12
  deferred.has(rosterBearingSpec.name) &&
11
13
  !activeTools.has(rosterBearingSpec.name);
12
14
  const agentListingSpec = rosterBearingSpec !== undefined &&
13
15
  !rosterFaceDeferred &&
14
- toolFaceSnapshot.selector.admits(rosterBearingSpec)
16
+ leaves(rosterBearingSpec)
15
17
  ? rosterBearingSpec
16
18
  : undefined;
17
19
  const agentListing = agentListingSpec
@@ -12,12 +12,8 @@
12
12
  * installs, which run at tool-call time), so the phase adds no yield between the deferred classification before it
13
13
  * and the prompt assembly after it (a stretch with no await is extracted as a sync function).
14
14
  * Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
15
- *
16
- * One read changed spelling and nothing else: the declared-class announcement read `mcp?.statuses` while `mcp` had
17
- * long been the protocol-tools phase's non-null handle; the optional chain was dead and is now the plain member read.
18
15
  */
19
16
  import type { LockedPreflight } from "../locked-config.js";
20
- import type { MaterializedMcp } from "../mcp.js";
21
17
  import { type DelegationContentSafety } from "../memory-engine/delegation-provenance.js";
22
18
  import type { RunnerDeps, TaskSpec } from "../types.js";
23
19
  import type { Prepared, RunInternals } from "./contracts.js";
@@ -40,8 +36,6 @@ export interface PrepareMemoryEngineSessionInput {
40
36
  lockedPreflight: Pick<LockedPreflight, "mcp">;
41
37
  /** borrowed-readonly — the run's MCP mount, read at call time (present iff the run declared a server): the children a delegation tool spawns inherit it, so its tools are rows of their pool. */
42
38
  mountedMcp?: () => import("../mounted-mcp.js").MountedMcp;
43
- /** borrowed-readonly — the materialized MCP handle; only `statuses` (the announcement's mounted-tool count). */
44
- mcp: Pick<MaterializedMcp, "statuses">;
45
39
  /** borrowed-readonly — the acquired session id (notice detail). */
46
40
  sessionId: string;
47
41
  /** borrowed-readonly — the run's invocation id (notice detail; the once-per-leg claims are per-RUN claims). */
@@ -1,5 +1,5 @@
1
1
  import { classifyToolContentOrigin, contentOriginPollutes, delegationCallIsExternal } from "../memory-engine/content-origin.js";
2
- import { mountedMcpPoolRows } from "../mounted-mcp.js";
2
+ import { mountedMcpPoolRows, toolNamesOfServer } from "../mounted-mcp.js";
3
3
  import { narrowContentSafety, readCardAttestation } from "../memory-engine/delegation-provenance.js";
4
4
  import { recordSyncUnattestable, sessionSettlements } from "../memory-engine/delegation-settlement.js";
5
5
  import { protocolOf } from "../protocol-table.js";
@@ -7,9 +7,10 @@ import { deliverEngineNotice } from "../types.js";
7
7
  import { inlineUntrusted } from "../untrusted-text.js";
8
8
  import { fileArgPath } from "../tool-registry.js";
9
9
  import { RosterBuilder } from "../tool-roster.js";
10
+ import { isNotStartedDelegationResult } from "../../agents/subagent.js";
10
11
  import { thrownText } from "../thrown-value.js";
11
12
  export function prepareMemoryEngineSession(input) {
12
- const { memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mcp, mountedMcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef } = input;
13
+ const { memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mountedMcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef } = input;
13
14
  const tools = roster.tools;
14
15
  const delegationProvenanceChannel = internals?.delegationProvenance;
15
16
  if (memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined) {
@@ -22,7 +23,7 @@ export function prepareMemoryEngineSession(input) {
22
23
  provenanceForChildrenRef.current = { trustedTools: [...trustedTools], execIsExternalContent };
23
24
  announceDeclaredMcpContentClasses({
24
25
  entries: lockedPreflight.mcp,
25
- statuses: mcp.statuses,
26
+ mountedNames: roster.tools.map((t) => t.name),
26
27
  execIsExternalContent,
27
28
  sessionId,
28
29
  runId,
@@ -133,6 +134,9 @@ export function prepareMemoryEngineSession(input) {
133
134
  isPolluting: poolToolPollutes,
134
135
  });
135
136
  const result = await inner(toolCallId, params, signal, onUpdate);
137
+ const delivery = delegationDeliveryOf(result);
138
+ if (delivery === "none")
139
+ return result;
136
140
  const att = readCardAttestation(result?.details);
137
141
  if (att === "external") {
138
142
  mark(`tool "${t.name}" returned the output of a delegated agent that invoked an external-content-class tool at runtime` +
@@ -141,8 +145,11 @@ export function prepareMemoryEngineSession(input) {
141
145
  }
142
146
  else if (att !== "clean") {
143
147
  if (external) {
144
- const staticFaceReason = `tool "${t.name}" returned the output of a delegated agent whose tool face can reach external content` +
145
- (typeof requested === "string" ? ` (subagent_type "${requested}")` : " (no subagent_type named — classified fail-closed)");
148
+ const staticFaceReason = (delivery === "launched"
149
+ ? `tool "${t.name}" launched a background delegated agent whose tool face can reach external content`
150
+ : `tool "${t.name}" returned the output of a delegated agent whose tool face can reach external content`) +
151
+ (typeof requested === "string" ? ` (subagent_type "${requested}")` : " (no subagent_type named — classified fail-closed)") +
152
+ (delivery === "launched" ? " — its output enters this session when it finishes" : "");
146
153
  if (!delegationEvidenceAttestedOnly) {
147
154
  mark(staticFaceReason, "static");
148
155
  }
@@ -207,13 +214,19 @@ export function prepareMemoryEngineSession(input) {
207
214
  }
208
215
  return { armed: memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined };
209
216
  }
217
+ function delegationDeliveryOf(result) {
218
+ if (isNotStartedDelegationResult(result))
219
+ return "none";
220
+ const details = typeof result === "object" && result !== null ? result.details : undefined;
221
+ return typeof details === "object" && details !== null && details.status === "async_launched" ? "launched" : "report";
222
+ }
210
223
  function announceDeclaredMcpContentClasses(args) {
211
224
  for (const entry of args.entries ?? []) {
212
225
  const declaredClass = entry.contentOrigin;
213
226
  if (declaredClass === undefined)
214
227
  continue;
215
228
  const server = inlineUntrusted(String(entry.name), 160);
216
- const toolCount = args.statuses?.find((s) => s.name === entry.name)?.toolNames?.length ?? 0;
229
+ const toolCount = toolNamesOfServer(args.mountedNames, entry.name).length;
217
230
  const resourceFaceCaveat = " (Not covered: the cross-server resource faces — ListMcpResourcesTool/ReadMcpResourceTool/ReadMcpResourceDirTool — stay externally classified and still mark.)";
218
231
  const posture = declaredClass === "local"
219
232
  ? `this server's mounted tools' invocations will not mark this session's memory as externally exposed.${resourceFaceCaveat}`
@@ -208,11 +208,12 @@ export interface PrepareMemoryResult {
208
208
  * BEFORE it). It performs the one destructive read this phase has — `inject()` drains the announcement queue —
209
209
  * so a hands-phase refusal cannot consume announcements a later prepare should deliver, and it takes the
210
210
  * roster-wide persistence verdict the driver can only read off the MOUNTED roster (`rosterCanPersist`: the
211
- * `TaskSpec.memoryPersistenceCapable` declaration when set, else the known-store-path inference over the
212
- * assembled tools). Call exactly once per prepare.
211
+ * `memoryPersistenceCapable` declaration when set, else the store-path inference over the assembled tools) and
212
+ * `isSubagent` (a non-fork delegated child — no user conversation, no not-mounted notice). Call once per prepare.
213
213
  */
214
214
  composeInjection: (facts: {
215
215
  rosterCanPersist: boolean;
216
+ isSubagent: boolean;
216
217
  }) => MemoryInjectionComposition;
217
218
  /**
218
219
  * The FROZEN org-admission verdict of this prepare: every org scope the task actually mounts
@@ -6,7 +6,7 @@ import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir,
6
6
  import { memoryProjectScopeAbsentNotice, normalizeMemorySpec } from "../memory.js";
7
7
  import { deriveSupersededSet } from "../memory-engine/consolidation.js";
8
8
  import { shadowNamesOf } from "../memory-engine/shadowing.js";
9
- import { MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA, MEMORY_ANNOUNCEMENT_READONLY_CODA, MEMORY_CAPTURE_INDETERMINATE_NOTICE, MEMORY_CAPTURE_OPTOUT_NOTICE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, MemoryEngine, entryFileHeadCarriesOrigin, memoryCaptureOptedOutNotice, memoryCaptureOptOutUnpersistedNotice, memoryConsolidationRecommendedNotice, memoryHarvestQuarantinedNotice, memoryHoldNotices, memoryRecallDisciplineSegment, memoryRestoreWithheldNotice, memorySessionPollutedNotice, pollutionContainmentCounts, } from "../memory-engine/engine.js";
9
+ import { MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA, MEMORY_ANNOUNCEMENT_READONLY_CODA, MEMORY_CAPTURE_OPTOUT_NOTICE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, MemoryEngine, entryFileHeadCarriesOrigin, memoryCaptureOptedOutNotice, memoryCaptureOptOutUnpersistedNotice, memoryConsolidationRecommendedNotice, memoryHarvestQuarantinedNotice, memoryHoldNotices, memoryRecallDisciplineSegment, memoryRestoreWithheldNotice, memorySessionPollutedNotice, memoryUnavailableNotice, pollutionContainmentCounts, } from "../memory-engine/engine.js";
10
10
  import { adjudicateCaptureOptOut, captureOptOutDeniedError, captureOptOutUnpersistedError } from "./memory-capture-optout.js";
11
11
  import { readSessionCaptureOptOut } from "../memory-engine/layout.js";
12
12
  import { sessionIncarnationResolver } from "../memory-engine/session-incarnation.js";
@@ -14,6 +14,7 @@ import { createMemoryEngineTools } from "../memory-engine/tools.js";
14
14
  import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
15
15
  import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
16
16
  import { writableRootOf } from "../memory-engine/types.js";
17
+ import { catalogText } from "../../prompt-assembly/catalog/index.js";
17
18
  import { asThrownError, thrownText } from "../thrown-value.js";
18
19
  let undeclaredCapturePostureAnnounced = false;
19
20
  export async function prepareMemory(input) {
@@ -781,7 +782,7 @@ export async function prepareMemory(input) {
781
782
  blockBody = [MEMORY_CAPTURE_OPTOUT_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
782
783
  }
783
784
  else if (captureIndeterminate && facts.rosterCanPersist) {
784
- blockBody = [MEMORY_CAPTURE_INDETERMINATE_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
785
+ blockBody = [memoryUnavailableNotice({ what: "capture-record-unreadable", notesReadable: true }), injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
785
786
  }
786
787
  else if (!facts.rosterCanPersist && injection.instruction === "" && injection.readOnlyNotice === undefined) {
787
788
  blockBody = blockBody.trim() ? `${MEMORY_READONLY_NOTICE}\n\n${blockBody}` : MEMORY_READONLY_NOTICE;
@@ -817,6 +818,9 @@ export async function prepareMemory(input) {
817
818
  if (memoryBlock !== undefined && injection.indexSeed !== undefined && facts.rosterCanPersist && !captureOptedOut && !captureIndeterminate)
818
819
  seedFiles = [injection.indexSeed];
819
820
  }
821
+ else if (!facts.rosterCanPersist && !facts.isSubagent) {
822
+ memoryBlock = effectiveMemoryScopes?.reason === "mount-failed" ? memoryUnavailableNotice({ what: "mount-failed", notesReadable: false }) : catalogText("core/memory.no-persistent-store");
823
+ }
820
824
  return {
821
825
  memoryBlock,
822
826
  ...(recallDisciplineSegment !== undefined ? { recallDisciplineSegment } : {}),
@@ -20,10 +20,10 @@ import type { ToolSelector } from "../tool-face.js";
20
20
  export interface PrepareOffloadWrappersInput {
21
21
  /** borrowed-readonly — the REBOUND spec (the config-doors result); read for the per-task coarse
22
22
  * offload knob only. */
23
- spec: Pick<TaskSpec, "toolResultThresholdChars">;
24
- /** borrowed-readonly — the leg's compiled selector: an offloaded result is read back through the reader tool, so a leg whose selector
25
- * does not admit the reader (a sub-agent whose lists leave it out, a deployment that excludes it) offloads nothing — a preview that
26
- * sends the model to a tool it does not have is a dead end. */
23
+ spec: Pick<TaskSpec, "toolResultThresholdChars" | "excludeAllTools">;
24
+ /** borrowed-readonly — the leg's compiled selector, read through the valve (`valveLeaves`): an offloaded result is read back through the
25
+ * reader tool, so a leg whose valve does not leave the reader (a sub-agent whose lists leave it out, a deployment that excludes it, a
26
+ * run whose whole face is switched off) offloads nothing — a preview that sends the model to a tool it does not have is a dead end. */
27
27
  selector: Pick<ToolSelector, "admits">;
28
28
  /** borrowed-readonly — the deployment's coarse offload knob and its injected store (used AS-IS when
29
29
  * present; a Runner-shared instance is viewed per task, see the body). */
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, InMemoryToolResultStore, OFFLOAD_TOOL_NAME, RunnerSharedToolResultStore, ScopedToolResultStore, withToolResultOffload, } from "../tool-result-store.js";
2
2
  import { faceOf } from "../tool-roster.js";
3
+ import { valveLeaves } from "../../agents/tool-filter.js";
3
4
  const FIRST_PARTY_OFFLOAD_THRESHOLD_CHARS = 50_000;
4
5
  export function prepareOffloadWrappers(input) {
5
6
  const { spec, deps, resume, offloadScope, sessionId, selector } = input;
@@ -21,7 +22,7 @@ export function prepareOffloadWrappers(input) {
21
22
  };
22
23
  const explicitGlobalThreshold = spec.toolResultThresholdChars ?? deps.toolResultThresholdChars;
23
24
  const offloadThreshold = explicitGlobalThreshold ?? DEFAULT_TOOL_RESULT_THRESHOLD_CHARS;
24
- const offloadEnabled = Number.isFinite(offloadThreshold) && offloadThreshold > 0 && selector.admits({ name: OFFLOAD_TOOL_NAME });
25
+ const offloadEnabled = Number.isFinite(offloadThreshold) && offloadThreshold > 0 && valveLeaves(spec, selector)({ name: OFFLOAD_TOOL_NAME });
25
26
  const rawOffloadStore = offloadEnabled ? (deps.toolResultStore ?? new InMemoryToolResultStore()) : undefined;
26
27
  const offloadStore = rawOffloadStore instanceof RunnerSharedToolResultStore
27
28
  ? new ScopedToolResultStore(rawOffloadStore, offloadScope)
@@ -20,7 +20,7 @@
20
20
  * closures, so the orchestrator grows no branch.
21
21
  */
22
22
  import type { AgentHarness, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
23
- import type { CallTargetStamp } from "../effective-path-target.js";
23
+ import { type CallTargetStamp } from "../effective-path-target.js";
24
24
  import { type OnQuestion } from "../ask-question.js";
25
25
  import { type CheckpointStore } from "../checkpoint-store.js";
26
26
  import type { GrantBindingOf } from "../skill-grant-binding.js";
@@ -1,15 +1,17 @@
1
+ import { callTargetReadingOf } from "../effective-path-target.js";
2
+ import { approvalTargetsOf } from "../approval-object.js";
1
3
  import { uuidv7 } from "../../engine/session/uuid.js";
2
4
  import { Value } from "typebox/value";
3
5
  import { classifyQuestionOutcome, validateAskQuestions } from "../ask-question.js";
4
6
  import { hasBackgroundShell, sweepBackgroundShells, sweepRunBoundaryBackgroundShells } from "../background-shell.js";
5
- import { boundInputHashOf } from "../canonical-json.js";
7
+ import { boundInputHashOf, exactBoundInputHashOf } from "../canonical-json.js";
6
8
  import { unencodableIn } from "../checkpoint-requirements.js";
7
9
  import { buildRiskDescriptor, debitLedger, encodeAtFidelity, mintCheckpointId, mintCheckpointToken, resolveDeclaredFidelity, samePlainValue, } from "../checkpoint-store.js";
8
10
  import { pauseOf } from "../pause-registry.js";
9
11
  import { askCarryRowMembers } from "../hooks.js";
10
12
  import { askMandateMember, ownedClearanceFacts } from "../ask-origin.js";
11
13
  import { defaultTaskRegistry } from "../task-registry.js";
12
- import { advertisedWritableRootsSeat, exemptRootsSeat, isLiveApproverSeat, carriesBidiControls, describeThrown, ownArgs, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
14
+ import { advertisedWritableRootsSeat, exemptRootsSeat, isLiveApproverSeat, licenseCovers, carriesBidiControls, describeThrown, ownArgs, refuseOutOfContractDecision, tryCloneArgs } from "../tool-policy.js";
13
15
  import { InMemoryToolResultStore, ScopedToolResultStore, isVolatileOffloadStore } from "../tool-result-store.js";
14
16
  import { raceAbort, raceSettlementAgainstSignal } from "./abort-race.js";
15
17
  import { CONTENT_ASK_BINDING_CAP } from "./content-ask-bindings.js";
@@ -147,6 +149,9 @@ export function prepareParkAsk(input) {
147
149
  const unencodable = unencodableIn(parkedArgs, "pendingAction.args");
148
150
  if (unencodable !== undefined)
149
151
  throw new ParkRefusal(`the arguments of "${req.toolName}" cannot be bound into the approval row's digest (${unencodable.kind} at ${unencodable.path}) — a durable approval row must hold an inert snapshot of exactly what a human approves and a resume executes`);
152
+ const parkedHash = exactBoundInputHashOf(parkedArgs);
153
+ if (parkedHash === undefined)
154
+ throw new ParkRefusal(`the arguments of "${req.toolName}" hold a value no exact digest binds — no approval row can be bound to them`);
150
155
  const projectionMovedArgs = backendFidelity !== "structured-clone" && !samePlainValue(parked.value, parkedArgs);
151
156
  if (projectionMovedArgs && basePolicyForResumeEdit === undefined) {
152
157
  throw new ParkRefusal(`the arguments of "${req.toolName}" change shape when stored by this checkpoint backend, and no policy is wired to re-adjudicate the stored shape ` +
@@ -306,6 +311,7 @@ export function prepareParkAsk(input) {
306
311
  toolCallId: req.toolCallId,
307
312
  toolName: req.toolName,
308
313
  ...parkedToolIdentity(toolRosterDeltas.current, req.toolName), ...parkedToolFace(toolRosterDeltas.current, req),
314
+ ...approvalTargetsOf(licenseCovers(parkedHash, req.args) ? callTargetReadingOf(req) : undefined),
309
315
  args: parkedArgs,
310
316
  ...(() => {
311
317
  const p = approvalPreviewOf(req.toolName, parkedArgs);
@@ -320,7 +326,7 @@ export function prepareParkAsk(input) {
320
326
  ...askMandateMember(clearanceFacts),
321
327
  ...askCarryRowMembers(carry),
322
328
  ...ruleOffersOf(req, parkedArgs, clearanceFacts),
323
- boundInputHash: boundInputHashOf(parkedArgs),
329
+ boundInputHash: parkedHash,
324
330
  ...grantBindingOf(req, parkedArgs),
325
331
  batchToolCallIds,
326
332
  completedCallIds,
@@ -46,7 +46,7 @@ export interface PreparePolicyChainInput {
46
46
  /** borrowed-readonly — the REBOUND spec. Read: `sessionId` / `principal` (the session-rule read and the lanes' identity),
47
47
  * `durableApproval` / `checkpointStore` (the mandate-park facility test and the sandbox arming's park prerequisites), `taskId` (the late-ask observer's detail),
48
48
  * `tools` (the names the caller mounted, for the name audit). Never mutated. */
49
- spec: Pick<TaskSpec, "sessionId" | "principal" | "durableApproval" | "taskId" | "checkpointStore" | "tools">;
49
+ spec: Pick<TaskSpec, "sessionId" | "principal" | "durableApproval" | "taskId" | "checkpointStore" | "tools" | "excludeAllTools">;
50
50
  /** borrowed-readonly — the deployment seats: `sessionPolicyStore` (the rule reads),
51
51
  * `permissionRuleStore` / `localOwnerRules` (the lanes and the offer factory), `onError` / `onNotice` (the advisories,
52
52
  * the refusal disclosures, the late-ask observer), `tracer` (the admission and rule-store frames), `checkpointStore` (the park facility). Receiver preserved;