@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,6 +1,6 @@
1
- import { withArgsReading } from "./effective-path-target.js";
2
- import { attest, attestationOf, decisionText, foldHookAsk, ownArgs, refusalOf, refuseOutOfContractDecision } from "./tool-policy.js";
3
- import { arbitrateByMode, classifyAsk, decisionAskClassesOf, fileCommandOptionsSentence, persistedRuleMandateOf, ruleClearanceOf, safetyAxisOf, stampAskOrigin } from "./ask-origin.js";
1
+ import { argsAsTheToolReads, withArgsReading } from "./effective-path-target.js";
2
+ import { attest, attestationOf, bindableArgsOf, decisionText, foldHookAsk, mergeAttestation, refusalOf, refuseOutOfContractDecision, withAttestation } from "./tool-policy.js";
3
+ import { arbitrateByMode, classifyAsk, decisionAskClassesOf, fileCommandOptionsSentence, persistedRuleMandateOf, safetyAxisOf, stampAskOrigin } from "./ask-origin.js";
4
4
  import { classifierParseFailureDenyMessage, denialLimitFallbackMessage, rungDidNotRule, unarmedWindow } from "./auto-mode.js";
5
5
  import { classifierNoRulingArm, settleNoRulingAsk } from "./classifier-unavailable-arm.js";
6
6
  import { SETTLEMENT_NOBODY_JUDGED } from "./gate-outcome.js";
@@ -10,14 +10,14 @@ import { applyPersistedTightening, disclosedRuleSet } from "./persisted-rule-arm
10
10
  import { skillAllowDecision, skillRowRefusal } from "./skill-grant.js";
11
11
  import { allowRuleShadowOf } from "./allow-entry.js";
12
12
  import { CD_GIT_COMPOUND_SENTENCE, changesDirectoryBeforeGit, readOnlyShellVerdict } from "./read-only-shell.js";
13
- import { readShellCommand } from "./shell-lexer.js";
13
+ import { readShellCommand } from "./shell-run-candidates.js";
14
14
  import { COMMAND_RULE_TOOL } from "./permission-rule-model.js";
15
15
  import { catalogRuleFaceOf } from "./tool-registry.js";
16
16
  import { callFaceSeat } from "./tool-roster.js";
17
17
  import { heldBy, wireOf } from "./tool-name-readings.js";
18
18
  import { asksUnstated, modeAcceptsFileCommand, permissionSeatAt, unstatedAskMessage } from "./mode-policy.js";
19
- import { ORG_RULE_DECISION_REASON, ORG_UNAVAILABLE_DECISION_REASON } from "./permission-rule-org.js";
20
- import { exitGate, passAskFace, unownedArgsMessage } from "./runner/gate-exit.js";
19
+ import { ORG_RULE_DECISION_REASON, ORG_UNAVAILABLE_DECISION_REASON, orgUnreadableClause } from "./permission-rule-org.js";
20
+ import { exitGate, passAskFace, untakenValueExit } from "./runner/gate-exit.js";
21
21
  import { readOrgRuleLane, readPersistedRuleLane } from "./rule-lane-reads.js";
22
22
  import { traceHookCrash } from "./gate-crash-trace.js";
23
23
  import { createGateDeadline, awaitWriteProtectionJudgment, withGateTimeout } from "./gate-bounded-await.js";
@@ -34,9 +34,9 @@ const ruleStoreUnreadableOf = (lane) => lane?.unreadable === true && lane.reason
34
34
  export async function runGateLanes(pass) {
35
35
  const { input, toolName, toolCallId, callSignal, ledger, notifier, screening, adjudicate, resolveAsk, suspendAsk } = pass;
36
36
  const boundedAwaitDeadlineMs = createGateDeadline(input, notifier);
37
- let orgRealApprovalRequired = false;
38
37
  let markedThisRound;
39
38
  let approvedWithArgs = false;
39
+ let editAskedOrigin;
40
40
  let carriedOwnAsk;
41
41
  const takeApprovedEdit = (read) => {
42
42
  carriedOwnAsk = read.outstanding ?? (pass.decision.action === "ask" ? pass.decision : undefined);
@@ -112,7 +112,6 @@ export async function runGateLanes(pass) {
112
112
  const answer = await readOrgRuleLane(input.orgRules, Object.freeze({ toolName, args, toolCallId, ...callFaceSeat(pass.req.face) }), input.abortSignal);
113
113
  if (answer.status === "unavailable") {
114
114
  orgEvidence = { revisionAbsent: "unavailable", ruleAbsent: "unavailable" };
115
- orgRealApprovalRequired = true;
116
115
  await notifier.notifyAsync(() => input.orgRules?.onUnavailable?.({ toolName, toolCallId, message: answer.disclosures.join("; ") }), "toolGate.orgSnapshotUnavailable");
117
116
  const orgUnavailableMessage = `tool "${toolName}" needs approval: this deployment is org-governed and cannot currently adjudicate ` +
118
117
  `against an organization policy snapshot — every allow tightens to a real approval until it can`;
@@ -137,14 +136,13 @@ export async function runGateLanes(pass) {
137
136
  orgTightenCount += 1;
138
137
  pass.deniedBy = "org";
139
138
  pass.denyCause = undefined;
140
- return { decision: refusalOf({ action: "deny", message: `an organization policy rule (${rule}) denies this call`, decisionReason: ORG_RULE_DECISION_REASON }, args), org: undefined };
139
+ return { decision: refusalOf({ action: "deny", message: `an organization policy rule (${rule}) denies this call${unreadable !== undefined ? `, ${orgUnreadableClause(unreadable)}` : ""}`, decisionReason: ORG_RULE_DECISION_REASON }, args), org: undefined };
141
140
  }
142
141
  if (decided.action === "deny")
143
142
  return { decision: decided, org: undefined };
144
143
  orgTightenCount += 1;
145
- orgRealApprovalRequired = true;
146
144
  const orgRuleMessage = unreadable !== undefined
147
- ? `an organization policy rule (${rule}) may reach this call, which could not be read against it (${unreadable}) — a person must decide`
145
+ ? `an organization policy rule (${rule}) may reach this call, ${orgUnreadableClause(unreadable)} — a person must decide`
148
146
  : `an organization policy rule (${rule}) requires approval for this call`;
149
147
  return {
150
148
  decision: decided.action === "ask"
@@ -160,8 +158,7 @@ export async function runGateLanes(pass) {
160
158
  const orgAnswer = await applyOrgLayer(pass.decision, finalArgs);
161
159
  pass.decision = orgAnswer.decision;
162
160
  const readPersistedRules = (req) => readPersistedRuleLane(input.persistedRules, req, input.abortSignal);
163
- const reread = pass.policyRewrite !== undefined ? withArgsReading(pass.req, pass.policyRewrite, pass.callSignal ?? input.abortSignal) : undefined;
164
- const laneReq = Object.freeze(reread !== undefined ? await reread : { ...pass.req, ...(pass.policyRewrite !== undefined ? { args: pass.policyRewrite } : {}) });
161
+ const laneReq = Object.freeze(pass.policyRewrite !== undefined ? await withArgsReading(pass.req, pass.policyRewrite, pass.callSignal ?? input.abortSignal) : { ...pass.req });
165
162
  const laneAnswer = input.persistedRules !== undefined && wireOf("lanes.persistedLaneSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME ? await readPersistedRules(laneReq) : undefined;
166
163
  {
167
164
  const tightened = applyPersistedTightening(pass.decision, laneAnswer, laneReq);
@@ -224,19 +221,21 @@ export async function runGateLanes(pass) {
224
221
  pass.currentInput = pass.policyRewrite;
225
222
  pass.req = Object.freeze({ ...pass.req, args: pass.policyRewrite, ...(laneReq.targetReading !== undefined ? { targetReading: laneReq.targetReading } : {}) });
226
223
  }
227
- const ruleMayClear = () => ruleClearanceOf(pass.decision.action === "ask" ? pass.decision : undefined, mandateMarksNow()).ruleMayClear;
228
- const classMayClear = () => pass.decision.action === "ask" && classifyAsk(pass.decision, askOriginFacts(orgAnswer.org, laneAnswer)).row.ruleMayClear;
224
+ const originFacts = askOriginFacts(orgAnswer.org, laneAnswer);
225
+ if (pass.decision.action === "ask")
226
+ classifyStanding(pass.decision, originFacts);
227
+ const allowMayClear = () => pass.decision.action === "ask" && pass.askClassification?.row.ruleMayClear === true;
229
228
  let personalEvidence = { dotsAbsent: input.persistedRules === undefined ? "not_wired" : "not_adjudicated" };
230
229
  if (laneAnswer?.unreadable === true)
231
230
  personalEvidence = { dotsAbsent: "unavailable" };
232
231
  let laneCoverage;
233
232
  const questionTool = wireOf("lanes.allowLayerQuestionSkip", pass.req) === ASK_USER_QUESTION_TOOL_NAME;
234
- const allowLayerMayClear = () => !orgRealApprovalRequired &&
233
+ const laneIsProvenance = orgAnswer.org === undefined &&
235
234
  pass.decision.action === "ask" &&
236
235
  pass.decision.requiresRealApproval !== true &&
237
236
  pass.decision.decisionReason !== "hook" &&
238
237
  !questionTool &&
239
- !markedUnresolvable();
238
+ !originFacts.markedUnresolvable;
240
239
  const unionDotsOf = (rules) => {
241
240
  const seen = new Set();
242
241
  const union = [];
@@ -251,7 +250,7 @@ export async function runGateLanes(pass) {
251
250
  }
252
251
  return { dots: union };
253
252
  };
254
- if (input.persistedRules && allowLayerMayClear()) {
253
+ if (input.persistedRules && laneIsProvenance) {
255
254
  const answer = laneAnswer ?? {};
256
255
  laneCoverage = answer.coverage;
257
256
  personalEvidence = answer.hit?.behavior === "ask" ? unionDotsOf(answer.hit.rules) : { dotsAbsent: answer.unreadable === true ? "unavailable" : "no_match" };
@@ -298,7 +297,7 @@ export async function runGateLanes(pass) {
298
297
  const hit = match();
299
298
  if (hit === undefined)
300
299
  continue;
301
- if (allowLayerMayClear() && ruleMayClear() && classMayClear()) {
300
+ if (allowMayClear()) {
302
301
  pass.decision = hit.clear();
303
302
  await hit.afterClear();
304
303
  if (member !== "hook")
@@ -313,7 +312,6 @@ export async function runGateLanes(pass) {
313
312
  const { allowRuleShadowed: _claimed, ...standing } = pass.decision;
314
313
  pass.decision = shadows.length > 0 ? { ...standing, allowRuleShadowed: shadows } : standing;
315
314
  }
316
- const originFacts = askOriginFacts(orgAnswer.org, laneAnswer);
317
315
  let noRulingMinted = false;
318
316
  const fallbackAskOf = (standingAsk, fallback, latestBlockedAction) => {
319
317
  const { classifierNoRuling: _why, ...standing } = standingAsk;
@@ -324,7 +322,7 @@ export async function runGateLanes(pass) {
324
322
  const stamped = { ...pass.decision, ruleEvidence: mintRuleEvidence(personalEvidence), ...(laneCoverage !== undefined ? { segmentCoverage: laneCoverage } : {}) };
325
323
  pass.decision = stampAskOrigin(stamped, originFacts, classifyStanding(stamped, originFacts));
326
324
  }
327
- if (allowLayerMayClear() && pass.decision.action === "ask" && ruleMayClear() && classMayClear() && pass.probeBoundaryDeclined !== true && wireOf("lanes.readOnlyShellAllow", pass.req) === COMMAND_RULE_TOOL) {
325
+ if (allowMayClear() && pass.probeBoundaryDeclined !== true && wireOf("lanes.readOnlyShellAllow", pass.req) === COMMAND_RULE_TOOL) {
328
326
  const commandParam = catalogRuleFaceOf(COMMAND_RULE_TOOL)?.primaryParams[0] ?? "command";
329
327
  const args = pass.req.args;
330
328
  const command = typeof args === "object" && args !== null && !Array.isArray(args) ? args[commandParam] : undefined;
@@ -345,7 +343,7 @@ export async function runGateLanes(pass) {
345
343
  }
346
344
  }
347
345
  if (pass.toolCheckRaised !== true && pass.decision.action !== "deny") {
348
- const read = await checkTool(pass.decision, pass.currentInput, orgAnswer.org, pass.policyRewrite, () => allowLayerMayClear() && ruleMayClear() && classMayClear());
346
+ const read = await checkTool(pass.decision, pass.currentInput, orgAnswer.org, pass.policyRewrite, allowMayClear);
349
347
  if (read?.kind === "denied")
350
348
  refuseByExtension(read.deny);
351
349
  else if (read?.kind === "cleared")
@@ -543,22 +541,27 @@ export async function runGateLanes(pass) {
543
541
  }
544
542
  }
545
543
  approvedWithArgs = pass.decision.action === "allow" && pass.decision.updatedInput !== undefined;
544
+ if (approvedWithArgs && askBeforeResolve.action === "ask")
545
+ editAskedOrigin = askBeforeResolve.origin;
546
546
  }
547
547
  }
548
548
  if (approvedWithArgs && pass.decision.action === "allow" && pass.decision.updatedInput !== undefined) {
549
549
  let editArgs = pass.decision.updatedInput;
550
550
  let editDenied;
551
551
  let editRewrittenSinceHuman = false;
552
+ let editAnswer = pass.decision;
552
553
  let unanswered;
553
554
  const refusedAtResolution = (d) => { editDenied = d; pass.deniedBy = "ask_resolution"; };
554
555
  for (let round = 0;; round++) {
555
- const taken = ownArgs(editArgs);
556
+ const taken = bindableArgsOf(toolName, editArgs);
556
557
  if (!taken.ok) {
557
- editDenied = { action: "deny", message: unownedArgsMessage(`the approved edit for "${toolName}"`, taken.reason) };
558
- pass.deniedBy = "policy";
559
- break;
558
+ const origin = attestationOf(editAnswer, { toolCallId, toolName })?.origin ?? editAskedOrigin;
559
+ if (origin === undefined)
560
+ throw new Error(`the approved edit for "${toolName}" reached its refusal without an origin word — the origin stamp precedes every resolution`);
561
+ ledger.set({ settlement: { kind: "presentation_failed", who: { party: "none" }, when: Date.now() }, origin });
562
+ return await untakenValueExit(pass, { value: editArgs, message: taken.refusal, deniedBy: "ask_resolution" });
560
563
  }
561
- editArgs = taken.value;
564
+ editArgs = argsAsTheToolReads(pass.req, taken.value);
562
565
  if (round >= 3) {
563
566
  editDenied = {
564
567
  action: "deny",
@@ -589,7 +592,7 @@ export async function runGateLanes(pass) {
589
592
  editHookAsk = ask;
590
593
  }
591
594
  if (hr.updatedInput !== undefined) {
592
- editArgs = hr.updatedInput;
595
+ editArgs = argsAsTheToolReads(pass.req, hr.updatedInput);
593
596
  editRewrittenSinceHuman = true;
594
597
  }
595
598
  }
@@ -622,7 +625,7 @@ export async function runGateLanes(pass) {
622
625
  }
623
626
  }
624
627
  if (recheck.updatedInput !== undefined) {
625
- editArgs = recheck.updatedInput;
628
+ editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
626
629
  editRewrittenSinceHuman = true;
627
630
  }
628
631
  const editOrg = await applyOrgLayer(recheck, editArgs);
@@ -632,8 +635,7 @@ export async function runGateLanes(pass) {
632
635
  break;
633
636
  }
634
637
  let editLane;
635
- const editReread = withArgsReading(pass.req, editArgs, callSignal ?? input.abortSignal);
636
- const editLaneReq = Object.freeze(editReread !== undefined ? await editReread : { toolName, args: editArgs, toolCallId, ...(pass.req.face !== undefined ? { face: pass.req.face } : {}) });
638
+ const editLaneReq = Object.freeze(await withArgsReading(pass.req, editArgs, callSignal ?? input.abortSignal));
637
639
  if (input.persistedRules !== undefined && wireOf("lanes.persistedEditSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME) {
638
640
  editLane = await readPersistedRules(editLaneReq);
639
641
  const editTightened = applyPersistedTightening(recheck, editLane, editLaneReq);
@@ -653,16 +655,17 @@ export async function runGateLanes(pass) {
653
655
  }
654
656
  if (recheck.action === "allow") {
655
657
  if (recheck.updatedInput !== undefined) {
656
- editArgs = recheck.updatedInput;
658
+ editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
657
659
  editRewrittenSinceHuman = true;
658
660
  }
659
- if (editRewrittenSinceHuman && asksUnstated(recheck, permissionSeatAt(input, editArgs)?.seat, input.permissionMode?.())) {
661
+ const answeredRecheck = withAttestation(recheck, mergeAttestation(pass.req, attestationOf(editAnswer, pass.req), attestationOf(recheck, pass.req), "answer"));
662
+ if (asksUnstated(answeredRecheck, pass.req, editArgs, permissionSeatAt(input, editArgs)?.seat, input.permissionMode?.())) {
660
663
  recheck = { action: "ask", message: permissionSeatAt(input, editArgs)?.question ?? unstatedAskMessage(toolName) };
661
664
  pass.tightenedBy = "unstated";
662
665
  }
663
666
  }
664
667
  if (recheck.updatedInput !== undefined) {
665
- editArgs = recheck.updatedInput;
668
+ editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
666
669
  editRewrittenSinceHuman = true;
667
670
  }
668
671
  let editFacts;
@@ -692,6 +695,7 @@ export async function runGateLanes(pass) {
692
695
  if (editRead?.kind === "approved") {
693
696
  carriedOwnAsk = editRead.outstanding ?? (editDecision.action === "ask" ? editDecision : undefined);
694
697
  editArgs = editRead.allow.updatedInput;
698
+ editAnswer = editRead.allow;
695
699
  editRewrittenSinceHuman = false;
696
700
  continue;
697
701
  }
@@ -737,6 +741,9 @@ export async function runGateLanes(pass) {
737
741
  break;
738
742
  }
739
743
  editArgs = rr.updatedInput;
744
+ editAnswer = rr;
745
+ if (editAskDecision.action === "ask")
746
+ editAskedOrigin = editAskDecision.origin;
740
747
  editRewrittenSinceHuman = false;
741
748
  }
742
749
  const rejudged = () => editDenied === undefined || editDenied === unanswered?.deny;
@@ -31,13 +31,16 @@ import { type AutoModeClassifierRound, type AutoModeFallbackCause } from "./auto
31
31
  * timer over the synchronous leg) elapsed with no answer.
32
32
  * - `park_sla_expired` — a DURABLE park's SLA deadline passed and the host's sweep resolved it as a deny
33
33
  * (FACET A). A store `expire`/`reap` produces no `tool_end` and therefore no settlement.
34
- * - `no_approver` — headless: no approver (or no question face) is wired, or the deny posture string.
34
+ * - `no_approver` — headless: no approver (or no question face) is wired, or the deny posture string (arguments no approval
35
+ * can be bound to are refused there in the binding's own sentence, under this word).
35
36
  * - `approver_unavailable` — the approver (or an ancestor's frozen approver) answered the ROUTING question
36
37
  * "nobody reachable", and no park took the ask.
37
38
  * - `approver_error` — the approver threw.
38
39
  * - `approver_contract` — the approver answered outside its contract (a non-boolean verdict, an
39
40
  * unreadable member, a timeout-settled allow, a refused attribution…).
40
- * - `presentation_failed` — the args or the edit could not be safely presented/adopted (unclonable).
41
+ * - `presentation_failed` — at a seat with an approver, the arguments could not be bound (`bindableArgsOf`: not a record of plain
42
+ * JSON data nested at most 256 levels deep): the asked ones — nobody was asked — or a resolution's edit (the engine's resolver's
43
+ * or, recorded by the gate, a host resolver's) — its yes is not used.
41
44
  * - `blanket_allow_refused` — an allow NO PERSON JUDGED met a `requiresRealApproval` ask: a blanket
42
45
  * `onAsk:"allow"`, or an approver's allow it reported as the deployment's policy (`settledBy: "policy"`).
43
46
  * - `task_aborted` — the wait's abort signal ended it (the run's own end, or a turn-level interrupt).
@@ -218,7 +221,8 @@ export type SettlementRefusalTableCoversEveryKind = AssertAllKeysHandled<Exclude
218
221
  * the ask on a durable queue instead), and the two sites that treat it as headless anyway say so at
219
222
  * their own call, because they are the ones with no park route left.
220
223
  * - `approver_error` / `approver_contract` / `presentation_failed` — the approver was there and the
221
- * engine could not use it. A defect to report, not a deployment with nobody home.
224
+ * engine could not use its answer, or could not put these arguments before it (or adopt its edit). Not a
225
+ * deployment with nobody home: with no approver, such arguments are refused under `no_approver`.
222
226
  * - `task_aborted` — the run ended; nothing is escalating anywhere.
223
227
  */
224
228
  export declare const SETTLEMENT_NOBODY_JUDGED: {
@@ -336,12 +340,17 @@ export type CauseTableCoversEveryDeniedBy = AssertAllKeysHandled<Exclude<DeniedB
336
340
  * allow or deny) and from BOTH stations (this gate's own classifier step, and an ANCESTOR's frozen
337
341
  * classifier reached through the inherited policy chain, whose allow and deny carry it out on the same seat
338
342
  * that carries the FORM): which model it was for, which one answered, and — only when the ladder moved —
339
- * the rung it left and why. ABSENT reads UNKNOWN, never "the seat answered" (that is `fallback` absent WITH
340
- * the member present), and a consumer cannot tell its two causes apart from the record alone: no
341
- * classification happened, or one ran on a decider given no candidate ladder and can name no model (a
342
- * hand-built decider; a parked ancestor's cross-process rebuild, whose single fresh leg has none). A block
343
- * at the DENIAL-LIMIT bound reaches no attribution seat: it becomes an ask, and the disposition names that
344
- * resolution. Additive. Invariant I6 ({@link screenGateOutcome}) screens its shape. */
343
+ * the rung it left and why. It is the classification's account, not the settlement's: a classification that
344
+ * RULED keeps it whoever then decided the call — a call whose question a person then answered (an ask a
345
+ * station after the classifier raised, or a block at the DENIAL-LIMIT bound, which becomes an ask) carries
346
+ * it beside that person's settlement on {@link GateOutcome}; who decided is read from the settlement
347
+ * (`human_allowed`, `policy_allowed`, …), never from this member's presence. ABSENT reads UNKNOWN, never
348
+ * "the seat answered" (that is `fallback` absent WITH the member present), and a consumer cannot tell its
349
+ * three causes apart from the record alone: no classification happened; one ran on a decider given no
350
+ * candidate ladder and can name no model (a hand-built decider; a parked ancestor's cross-process rebuild,
351
+ * whose single fresh leg has none); or one did not rule (it could not run, or replied with no verdict) and
352
+ * handed the question to the approval seat, whose settlement then names the resolution that ask reached.
353
+ * Additive. Invariant I6 ({@link screenGateOutcome}) screens its shape. */
345
354
  export type GateDisposition = {
346
355
  kind: "allowed";
347
356
  classifier?: AutoModeClassifierRound;
@@ -48,7 +48,8 @@ export declare function governanceRetryClass(code: string): GovernanceRetryClass
48
48
  * fixed the roster (`config.tool_mount_denied`), a
49
49
  * member over a roster row's wire bound (`config.tool_roster_bound` / `config.tool_name_too_long` /
50
50
  * `config.tool_contract_too_long`), a schema over the row's key bounds (`config.tool_schema_bound`), a
51
- * declared face or result card the schema / namespace cannot carry (`config.tool_face_invalid`), a name or
51
+ * declared face or result card the schema / namespace cannot carry (`config.tool_face_invalid` — also the code an MCP server entry's
52
+ * unreadable `toolFaces` is refused with at the task preparation door and at `materializeMcpTools`), a name or
52
53
  * alias outside the caller tool name contract — one no rule can name, or one carrying the protocol namespace separator
53
54
  * (`config.tool_name_invalid`), an egress tool declared other than
54
55
  * `write` (`config.egress_requires_write_effect` — also minted, same meaning, for a protocol tool's resolved
@@ -138,7 +139,7 @@ export type NoticeAudience = "user" | "operator";
138
139
  * the union's catalog ({@link EngineNotice.code}). The groups below say only which family a row joins,
139
140
  * so the catalog is not written a second time here and the two cannot drift.
140
141
  */
141
- export declare const ENGINE_NOTICE_CODES: readonly ["config.autocompact_window_clamped", "config.env_timeout_discarded", "config.materialize_env_discarded", "config.models_swapped", "config.context_settings_swapped", "config.read_face_swapped", "config.read_face_deployment_clamped", "config.write_face_swapped", "config.write_face_deployment_clamped", "config.read_deny_swapped", "config.tool_model_gate_removed", "config.tool_model_gate_unknown_class", "config.tool_model_gate_env_invalid", "config.artifact_host_invalid", "config.task_root_not_canonical", "config.write_protection_target_view_absent", "config.path_view_unresolved", "config.execution_env_capability_invalid", "config.tool_card_undeclared", "config.tool_face_undeclared", "config.tool_face_invalid", "config.forward_sink_failed", "config.durable_gate_unavailable", "config.peer_admission_out_of_range", "config.peer_lane_unmounted", "config.secret_env_scrubbed", "config.credential_not_withheld", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "mods.registration_refused", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "classifier.fallback", "classifier.role_defaulted", "classifier.contract_broken", "classifier.unavailable", "checkpoint.execution_outcome_unrecorded", "delegation.transcript_integrity", "delegation.ask_unresolvable", "mcp.injection_dropped", "mcp.revocation_probe_failed", "mcp.server_redialed", "workflow.governance_key_stripped", "workflow.agent_option_ignored", "memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.content_class_declared", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "memory.consolidation_recommended", "memory.consolidation_committed", "memory.consolidation_conflict", "memory.consolidation_incomplete", "memory.consolidation_refused", "memory.consolidation_withheld", "memory.restore_withheld", "memory.project_scope_absent", "route.fallback_to_primary", "route.classifier_unroutable", "route.credential_origin_mismatch", "route.response_model_mismatch", "route.tool_call_id_folded", "route.finish_reason_unknown", "route.stream_end_ignored", "route.extra_body_reserved_dropped", "context.tool_turn_repaired", "task.user_steer_undrained", "task.user_followup_undrained", "steering.parked_input_blocked", "task.turn_interrupted", "task.halt_unconsumed", "task.late_approval", "task.interrupt_unconsumed", "task.tool_turn_incomplete", "approval.read_root_granted", "approval.read_root_grant_rejected", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "skills.listing_truncated", "agents.listing_truncated", "tool_result.offload_put_failed", "tool_result.media_refused", "instructions.source_changed", "session.records_skipped", "memory.layer_locked_legacy", "server.model_unreachable", "permission.entry_mode_clamped"];
142
+ export declare const ENGINE_NOTICE_CODES: readonly ["config.autocompact_window_clamped", "config.env_timeout_discarded", "config.materialize_env_discarded", "config.models_swapped", "config.context_settings_swapped", "config.read_face_swapped", "config.read_face_deployment_clamped", "config.write_face_swapped", "config.write_face_deployment_clamped", "config.read_deny_swapped", "config.tool_model_gate_removed", "config.tool_model_gate_unknown_class", "config.tool_model_gate_env_invalid", "config.artifact_host_invalid", "config.task_root_not_canonical", "config.write_protection_target_view_absent", "config.path_view_unresolved", "config.execution_env_capability_invalid", "config.tool_card_undeclared", "config.tool_face_undeclared", "config.tool_face_invalid", "config.forward_sink_failed", "config.durable_gate_unavailable", "config.peer_admission_out_of_range", "config.peer_lane_unmounted", "config.secret_env_scrubbed", "config.credential_not_withheld", "config.cross_boundary_posture_undeclared", "config.cross_boundary_record_unwritten", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "config.session_rules_earlier_grammar", "permission.allowed_tool_not_granted", "mods.registration_refused", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "classifier.fallback", "classifier.role_defaulted", "classifier.contract_broken", "classifier.unavailable", "checkpoint.execution_outcome_unrecorded", "delegation.transcript_integrity", "delegation.ask_unresolvable", "mcp.injection_dropped", "mcp.revocation_probe_failed", "mcp.server_redialed", "workflow.governance_key_stripped", "workflow.agent_option_ignored", "memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.content_class_declared", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "memory.consolidation_recommended", "memory.consolidation_committed", "memory.consolidation_conflict", "memory.consolidation_incomplete", "memory.consolidation_refused", "memory.consolidation_withheld", "memory.restore_withheld", "memory.project_scope_absent", "route.fallback_to_primary", "route.classifier_unroutable", "route.credential_origin_mismatch", "route.response_model_mismatch", "route.tool_call_id_folded", "route.finish_reason_unknown", "route.stream_end_ignored", "route.extra_body_reserved_dropped", "context.tool_turn_repaired", "task.user_steer_undrained", "task.user_followup_undrained", "steering.parked_input_blocked", "task.turn_interrupted", "task.halt_unconsumed", "task.late_approval", "task.interrupt_unconsumed", "task.tool_turn_incomplete", "approval.read_root_granted", "approval.read_root_grant_rejected", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "skills.listing_truncated", "agents.listing_truncated", "tool_result.offload_put_failed", "tool_result.media_refused", "instructions.source_changed", "session.records_skipped", "memory.layer_locked_legacy", "server.model_unreachable", "permission.entry_mode_clamped"];
142
143
  /** A catalogued code (see {@link ENGINE_NOTICE_CODES}); {@link NOTICE_MINTER} says who mints it. NOT the type of
143
144
  * `EngineNotice.code`, which stays `string` — a host forwarding its own notices through the same
144
145
  * sink is a supported shape, and narrowing that field would break it. */
@@ -187,6 +188,7 @@ declare const NOTICE_AUDIENCE_TABLE: {
187
188
  readonly "permission.read_deny_unapplied": "user";
188
189
  readonly "permission.rule_store_unavailable": "user";
189
190
  readonly "permission.rule_row_dropped": "user";
191
+ readonly "config.session_rules_earlier_grammar": "user";
190
192
  readonly "permission.allowed_tool_not_granted": "user";
191
193
  readonly "mods.registration_refused": "user";
192
194
  readonly "memory.capture_opted_out": "user";
@@ -218,6 +220,8 @@ declare const NOTICE_AUDIENCE_TABLE: {
218
220
  readonly "config.peer_admission_out_of_range": "operator";
219
221
  readonly "config.secret_env_scrubbed": "operator";
220
222
  readonly "config.credential_not_withheld": "operator";
223
+ readonly "config.cross_boundary_posture_undeclared": "operator";
224
+ readonly "config.cross_boundary_record_unwritten": "operator";
221
225
  readonly "peer.inbound_disposition": "user";
222
226
  readonly "peer.held_settled": "user";
223
227
  readonly "peer.idle_subscription": "user";
@@ -304,11 +308,14 @@ declare const NOTICE_MINTER_TABLE: {
304
308
  readonly "config.peer_lane_unmounted": "engine";
305
309
  readonly "config.secret_env_scrubbed": "engine";
306
310
  readonly "config.credential_not_withheld": "engine";
311
+ readonly "config.cross_boundary_posture_undeclared": "engine";
312
+ readonly "config.cross_boundary_record_unwritten": "engine";
307
313
  readonly "config.permission_mode_unavailable": "engine";
308
314
  readonly "permission.ask_released_by_mode": "engine";
309
315
  readonly "permission.read_deny_unapplied": "engine";
310
316
  readonly "permission.rule_store_unavailable": "engine";
311
317
  readonly "permission.rule_row_dropped": "engine";
318
+ readonly "config.session_rules_earlier_grammar": "engine";
312
319
  readonly "permission.allowed_tool_not_granted": "engine";
313
320
  readonly "mods.registration_refused": "engine";
314
321
  readonly "peer.inbound_disposition": "engine";
@@ -146,11 +146,14 @@ export const ENGINE_NOTICE_CODES = Object.freeze([
146
146
  "config.peer_lane_unmounted",
147
147
  "config.secret_env_scrubbed",
148
148
  "config.credential_not_withheld",
149
+ "config.cross_boundary_posture_undeclared",
150
+ "config.cross_boundary_record_unwritten",
149
151
  "config.permission_mode_unavailable",
150
152
  "permission.ask_released_by_mode",
151
153
  "permission.read_deny_unapplied",
152
154
  "permission.rule_store_unavailable",
153
155
  "permission.rule_row_dropped",
156
+ "config.session_rules_earlier_grammar",
154
157
  "permission.allowed_tool_not_granted",
155
158
  "mods.registration_refused",
156
159
  "peer.inbound_disposition",
@@ -246,6 +249,7 @@ const NOTICE_AUDIENCE_TABLE = {
246
249
  "permission.read_deny_unapplied": "user",
247
250
  "permission.rule_store_unavailable": "user",
248
251
  "permission.rule_row_dropped": "user",
252
+ "config.session_rules_earlier_grammar": "user",
249
253
  "permission.allowed_tool_not_granted": "user",
250
254
  "mods.registration_refused": "user",
251
255
  "memory.capture_opted_out": "user",
@@ -277,6 +281,8 @@ const NOTICE_AUDIENCE_TABLE = {
277
281
  "config.peer_admission_out_of_range": "operator",
278
282
  "config.secret_env_scrubbed": "operator",
279
283
  "config.credential_not_withheld": "operator",
284
+ "config.cross_boundary_posture_undeclared": "operator",
285
+ "config.cross_boundary_record_unwritten": "operator",
280
286
  "peer.inbound_disposition": "user",
281
287
  "peer.held_settled": "user",
282
288
  "peer.idle_subscription": "user",
@@ -344,11 +350,14 @@ const NOTICE_MINTER_TABLE = {
344
350
  "config.peer_lane_unmounted": "engine",
345
351
  "config.secret_env_scrubbed": "engine",
346
352
  "config.credential_not_withheld": "engine",
353
+ "config.cross_boundary_posture_undeclared": "engine",
354
+ "config.cross_boundary_record_unwritten": "engine",
347
355
  "config.permission_mode_unavailable": "engine",
348
356
  "permission.ask_released_by_mode": "engine",
349
357
  "permission.read_deny_unapplied": "engine",
350
358
  "permission.rule_store_unavailable": "engine",
351
359
  "permission.rule_row_dropped": "engine",
360
+ "config.session_rules_earlier_grammar": "engine",
352
361
  "permission.allowed_tool_not_granted": "engine",
353
362
  "mods.registration_refused": "engine",
354
363
  "peer.inbound_disposition": "engine",
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Total over what a deployment can hand the seat: absent passes; a value that is not a plain record, a member the record does not
3
+ * have, or a member holding a value it does not take refuses by name (`config.invalid_argument`, `detail.field` = `RunnerDeps.hands`
4
+ * or `RunnerDeps.hands.<member>`) — a band setting the engine cannot read is never run as if it were absent. A member holding
5
+ * `undefined` is absence, as on every optional seat.
6
+ */
7
+ export declare function screenHandsBandOptions(value: unknown): void;
@@ -0,0 +1,32 @@
1
+ const HANDS_BAND_MEMBERS = {
2
+ bashReadonlyAllow: { takes: "a list of command-name strings", ok: (v) => Array.isArray(v) && v.every((c) => typeof c === "string") },
3
+ commitCoAuthor: { takes: "a string or false", ok: (v) => typeof v === "string" || v === false },
4
+ readImageDownsampler: { takes: "a function or false", ok: (v) => typeof v === "function" || v === false },
5
+ beforeWrite: { takes: "a function", ok: (v) => typeof v === "function" },
6
+ autoBackgroundOnTimeout: { takes: "a boolean", ok: (v) => typeof v === "boolean" },
7
+ };
8
+ const kindOf = (v) => (v === null ? "null" : Array.isArray(v) ? "an array" : typeof v);
9
+ export function screenHandsBandOptions(value) {
10
+ if (value === undefined)
11
+ return;
12
+ const refuse = (field, problem) => {
13
+ const e = new Error(`${field} ${problem} — a hands band setting the engine cannot read is refused rather than ignored.`);
14
+ e.code = "config.invalid_argument";
15
+ e.detail = { field };
16
+ throw e;
17
+ };
18
+ const proto = typeof value === "object" && value !== null ? Object.getPrototypeOf(value) : undefined;
19
+ if (typeof value !== "object" || value === null || Array.isArray(value) || (proto !== Object.prototype && proto !== null)) {
20
+ refuse("RunnerDeps.hands", `must be a plain record of hands band settings (got ${kindOf(value)})`);
21
+ }
22
+ for (const key of Object.keys(value)) {
23
+ const v = value[key];
24
+ if (v === undefined)
25
+ continue;
26
+ if (!Object.hasOwn(HANDS_BAND_MEMBERS, key))
27
+ refuse(`RunnerDeps.hands.${key}`, `is not a hands band setting (the settings: ${Object.keys(HANDS_BAND_MEMBERS).join(", ")})`);
28
+ const member = HANDS_BAND_MEMBERS[key];
29
+ if (!member.ok(v))
30
+ refuse(`RunnerDeps.hands.${key}`, `must be ${member.takes} (got ${kindOf(v)})`);
31
+ }
32
+ }
@@ -1,7 +1,7 @@
1
1
  import type { ActorAssertion, DocumentContent, ImageContent, TextContent } from "../internal/llm.js";
2
2
  import type { ExecutionEnv, FileError, Result, SessionTreeEntry } from "../internal/harness-types.js";
3
3
  import type { DecisionReason, PermissionResult, ResolvedAsk, ToolCallFace, ToolCallRequest, ToolPolicy } from "./tool-policy.js";
4
- import type { CallTargetStamp } from "./effective-path-target.js";
4
+ import { type CallTargetStamp } from "./effective-path-target.js";
5
5
  import type { GateOutcome } from "./gate-outcome.js";
6
6
  import { type PreToolUseScreening } from "./runner/gate-exit.js";
7
7
  export { normalizeOrgGateVerdict, normalizePersistedRuleHit } from "./rule-lane-reads.js";
@@ -13,6 +13,7 @@ import type { WiringLegKind } from "./wiring-manifest.js";
13
13
  import type { PermissionSeatInputs } from "./mode-policy.js";
14
14
  import type { SkillGateSeats } from "./skill-grant.js";
15
15
  import type { AllowEntryGateSeats } from "./allow-entry.js";
16
+ import type { CrossBoundaryGateSeat } from "./cross-boundary-taint.js";
16
17
  /**
17
18
  * The classic stations' faces and the two-phase tool gate. A deployment extends the engine through the mods bus
18
19
  * (`RunnerDeps.mods` / `TaskSpec.mods`, `src/core/mods/`): each sema station raises one `classic.*` event, and the
@@ -554,9 +555,10 @@ export interface ToolGateResult {
554
555
  * as taken at the gate's entry, or what a hook, a policy or a person rewrote them to); re-validated by the loop. Present
555
556
  * on every allow exit, whether or not anything rewrote (compare values to tell); absent on a block and a suspend. */
556
557
  updatedInput?: unknown;
557
- /** The input this pass decided on (what a refusal refused, what an allowed call runs with) as a deep, FROZEN copy taken
558
- * at the exit — never the live args. Beside {@link gate} on both terminal exits; absent on the suspend exit. The deny
559
- * observer gets a detached, writable copy of it. */
558
+ /** The input this pass decided on (what a refusal refused, what an allowed call runs with) as a deep, FROZEN plain-data projection
559
+ * taken at the exit — never the live args: on a refusal every member that is not data (a bigint, a Map, a Date, a class instance, a
560
+ * function, an accessor, a symbol-keyed member) is a `[not recorded: …]` marker; an allow exit meets only the gate's own copy, so there
561
+ * just a bigint, a cycle's closing member and containers past 256 levels are. Beside {@link gate} on both terminal exits; absent on the suspend exit. */
560
562
  finalInput?: unknown;
561
563
  /** A blocking refusal's structured details, when the refusing station minted any (the shell read station's
562
564
  * `read_path_denied` / `readonly_out_of_root` cards): the loop attaches them to the error result it mints
@@ -611,9 +613,8 @@ export type ContentAskOutcome = {
611
613
  * happened" (no facility armed, or the closure took its sync-first decline) — that case hides nothing,
612
614
  * while this one does: the gate falls back to the synchronous approver chain either way (the
613
615
  * compensation contract — an uncommitted checkpoint is a safe fallback — is unchanged), but on a
614
- * headless deployment that fallback is the auto-deny whose text is "no approver is wired". True as far
615
- * as it goes, and the whole reason the call did not park lives somewhere else entirely (the host's
616
- * `onError` face). So the reason travels with the fall-through and the deny quotes it.
616
+ * headless deployment that fallback is the auto-deny whose text is "no approver is wired". True as far as it goes, and the whole
617
+ * reason the call did not park lives somewhere else entirely (the host's `onError` face). So the reason travels with the fall-through and the deny quotes it.
617
618
  */
618
619
  export interface ParkAttemptFailed {
619
620
  /** Why the park could not be minted — a sentence, already worded for a reader. */
@@ -629,9 +630,9 @@ export interface ParkAttemptFailed {
629
630
  */
630
631
  export type OrgGateVerdict = {
631
632
  status: "available";
632
- /** The org rule that speaks for this call, if any. Deny outranks ask; there is no allow bucket. An
633
- * `unreadable` member (the lexer's reason) says the call could not be READ against `rule` — an
634
- * org rule that may reach it — so `behavior` is `ask` and the message names the reason. */
633
+ /** The org rule that speaks for this call, if any. Deny outranks ask; there is no allow bucket. An `unreadable` member says why
634
+ * `rule` could not be judged against the call (the message names it): the call could not be READ against it (the lexer's reason;
635
+ * `behavior` is `ask`), or the row is one the org layer does not read, standing at its strictest reading (`deny`, or `ask`). */
635
636
  verdict?: {
636
637
  behavior: "deny" | "ask";
637
638
  rule: string;
@@ -720,18 +721,20 @@ export type PersistedRuleAnswer = PersistedRuleHit | PersistedRuleCoverage | Per
720
721
  * signal; when the caller also supplies {@link ToolGateInput.callSignal}, the Runner's closures
721
722
  * additionally bind their waits to that per-call signal (`AbortSignal.any` of the two), so a turn
722
723
  * interrupt releases a pending ask instead of leaving it hanging on the run's lifetime alone. */
723
- export interface ToolGateInput extends PermissionSeatInputs, SkillGateSeats, AllowEntryGateSeats {
724
+ export interface ToolGateInput extends PermissionSeatInputs, SkillGateSeats, AllowEntryGateSeats, CrossBoundaryGateSeat {
724
725
  /** RB-473 batch 2b — bounded disclosure for a HOST callback that throws inside this gate call's
725
726
  * isolation scope (onHookError itself, the deny observer, the durable-park observer). The runner
726
727
  * wires this to an `observer.notify_failed` trace event; absent = counted only (unchanged). */
727
728
  onNotifyError?: (failure: import("./safe-notify.js").SafeNotifyFailure) => void;
728
729
  /** The call. `toolName` is the name every policy, hook and name-keyed table of this gate reads — the wire name of the
729
730
  * tool the call dispatches to: the Runner's station resolves a call made under an alias through the roster
730
- * (`rosterToolName`) before this gate runs; a host driving the gate resolves it the same way. */
731
+ * (`rosterToolName`) before this gate runs; a host driving the gate resolves it the same way. `readArguments` = the loop's
732
+ * reading of the call's args: stamped on the call's face, every rewrite this gate adopts is read through it (`argsAsTheToolReads`). */
731
733
  event: {
732
734
  toolCallId: string;
733
735
  toolName: string;
734
736
  input: Record<string, unknown>;
737
+ readArguments?: (args: unknown) => unknown;
735
738
  };
736
739
  /** The run/leg identity envelope, put verbatim on every {@link PreToolUseEvent} this
737
740
  * gate call builds and on every {@link PermissionDeniedPayload} it emits. The Runner supplies its
@@ -1092,12 +1095,11 @@ export interface ToolGateInput extends PermissionSeatInputs, SkillGateSeats, All
1092
1095
  * The deny exit nobody judged: the call's approval could not be RESOLVED (`cause` — the approver
1093
1096
  * answered `unavailable`, no approver is wired, or an inherited durable mandate has no park facility on
1094
1097
  * this leg) and no durable park took the call, so the fail-closed deny STANDS. Fired once per such call
1095
- * from the gate's single deny exit, after every park re-route has had its attempt, with the facts the
1096
- * `delegation.ask_unresolvable` notice is composed from (`ask-unresolvable-notice.ts`);
1097
- * `parkLaneExisted` = a park lane was armed for this run; `remedy` = the caller-side change that would have let the
1098
- * call run, present for the causes that say nobody could be asked (`approver_unavailable`, `no_approver_wired`).
1099
- * Observe-only: a throwing seat never alters the deny. Absent ⇒ the deny stands silently (a host driving the gate
1100
- * directly, no notice sink).
1098
+ * from the gate's single deny exit, after every park re-route has had its attempt, with the facts the `delegation.ask_unresolvable`
1099
+ * notice is composed from (`ask-unresolvable-notice.ts`); `parkLaneExisted` = a park lane was armed for this run; `remedy` = the
1100
+ * caller-side change that would have let the call run, present for the causes that say nobody could be asked (`approver_unavailable`,
1101
+ * `no_approver_wired`) — for arguments no approval can be bound to, the binding's own sentence (the remedy's approver half would not
1102
+ * let them run). Observe-only: a throwing seat never alters the deny. Absent ⇒ the deny stands silently (no notice sink).
1101
1103
  */
1102
1104
  onAskUnresolvable?: (info: {
1103
1105
  toolName: string;
@@ -1309,7 +1311,7 @@ export declare function createPreToolUseScreening(input: Pick<ToolGateInput, "ev
1309
1311
  * structural rather than restated.
1310
1312
  *
1311
1313
  * The mapping mirrors the gate's own phase 1 decision for decision:
1312
- * - no opinion → `allow`, contributing nothing;
1314
+ * - no opinion, and an `allow` → `allow`, contributing nothing (a constraint only tightens: it clears no question);
1313
1315
  * - `deny` → `deny` in the fold's own words;
1314
1316
  * - `ask` → `ask`, stamped `decisionReason:"hook"` (and the mandate, when the answer set it) so every consumer that
1315
1317
  * distinguishes a screening ask from a policy ask reads the same fact one level down;
@@ -1,4 +1,5 @@
1
- import { abortedSeatDeny, decisionText, describeThrown, isEngineRefusal, ownArgs, refuseOutOfContractDecision, unaskedSeatAnswer } from "./tool-policy.js";
1
+ import { argsAsTheToolReads, stampArgsReading } from "./effective-path-target.js";
2
+ import { abortedSeatDeny, decisionText, describeThrown, isEngineRefusal, ownArgs, ownedReading, refuseOutOfContractDecision, unaskedSeatAnswer } from "./tool-policy.js";
2
3
  import { createSettlementLedger, engineFailClosedExit, hookDenyExit, unownedArgsExit } from "./runner/gate-exit.js";
3
4
  import { classicEventBase, dispatchClassic, ENGINE_CORE_ANSWER, engineCore, failedHandlerClause, judgedInputOf, observePermissionDenied, recordScreeningChain } from "./mods/stations.js";
4
5
  import { runGateFold } from "./gate-fold.js";
@@ -185,8 +186,7 @@ export function createPreToolUseConstraintPolicy(chain, env) {
185
186
  ...(r.updatedInput !== undefined ? { updatedInput: r.updatedInput } : {}),
186
187
  };
187
188
  }
188
- const stated = r.action === "allow" ? { decisionReason: "hook" } : {};
189
- return r.updatedInput !== undefined ? { action: "allow", updatedInput: r.updatedInput, ...stated } : { action: "allow", ...stated };
189
+ return r.updatedInput !== undefined ? { action: "allow", updatedInput: r.updatedInput } : { action: "allow" };
190
190
  },
191
191
  }, "hook");
192
192
  recordScreeningChain(minted, chain);
@@ -235,7 +235,8 @@ export async function runToolGate(input) {
235
235
  screening,
236
236
  afterFold: runGateLanes,
237
237
  currentInput: args,
238
- req: Object.freeze({ toolName, args, toolCallId, ...(() => { const f = input.toolFaceOf?.(toolName); return f !== undefined ? { face: f } : {}; })() }),
238
+ req: Object.freeze({ toolName, args, toolCallId, ...(() => { const f = input.toolFaceOf?.(toolName); const read = event.readArguments; if (f !== undefined && read !== undefined)
239
+ stampArgsReading(f, ownedReading(read)); return f !== undefined ? { face: f } : {}; })() }),
239
240
  preToolContext: [],
240
241
  hookAsk: undefined,
241
242
  parkFailed: undefined,
@@ -261,7 +262,7 @@ export async function runToolGate(input) {
261
262
  return hookDenyExit(pass, screening.deniedReason(r));
262
263
  }
263
264
  if (r.updatedInput !== undefined) {
264
- pass.currentInput = r.updatedInput;
265
+ pass.currentInput = argsAsTheToolReads(pass.req, r.updatedInput);
265
266
  }
266
267
  if (r.action === "ask") {
267
268
  pass.hookAsk = r;