@sema-agent/core 7.55.0 → 7.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/dist/agents/cascade.js +1 -1
  3. package/dist/agents/cc-peer-directory.js +1 -0
  4. package/dist/agents/child-model-seat.d.ts +0 -11
  5. package/dist/agents/child-model-seat.js +0 -3
  6. package/dist/agents/list-agents-tool.d.ts +3 -1
  7. package/dist/agents/list-agents-tool.js +7 -7
  8. package/dist/agents/peer-directory.d.ts +22 -4
  9. package/dist/agents/peer-directory.js +24 -2
  10. package/dist/agents/peer-session-drain.js +2 -2
  11. package/dist/agents/repair-loop.js +2 -2
  12. package/dist/agents/send-message-tool.js +4 -4
  13. package/dist/agents/subagent.d.ts +6 -4
  14. package/dist/agents/subagent.js +64 -60
  15. package/dist/agents/tool-filter.d.ts +7 -5
  16. package/dist/agents/tool-filter.js +12 -9
  17. package/dist/agents/verify.d.ts +3 -2
  18. package/dist/agents/verify.js +3 -3
  19. package/dist/brain/anthropic.js +30 -73
  20. package/dist/brain/media-degrade.d.ts +18 -7
  21. package/dist/brain/media-degrade.js +13 -2
  22. package/dist/brain/model-capability.d.ts +37 -0
  23. package/dist/brain/model-capability.js +34 -0
  24. package/dist/brain/model-presets.d.ts +2 -8
  25. package/dist/brain/model-presets.js +1 -6
  26. package/dist/brain/open-responses.js +13 -26
  27. package/dist/brain/openai.js +14 -87
  28. package/dist/brain/reasoning-request.d.ts +96 -0
  29. package/dist/brain/reasoning-request.js +174 -0
  30. package/dist/brain/reasoning.d.ts +11 -11
  31. package/dist/brain/reasoning.js +4 -3
  32. package/dist/brain/request-params.d.ts +7 -4
  33. package/dist/brain/request-params.js +7 -4
  34. package/dist/brain/status-sink.d.ts +20 -0
  35. package/dist/brain/status-sink.js +7 -0
  36. package/dist/core/a2a.d.ts +2 -1
  37. package/dist/core/a2a.js +19 -13
  38. package/dist/core/agent-definition.d.ts +10 -0
  39. package/dist/core/allow-entry.d.ts +20 -13
  40. package/dist/core/allow-entry.js +26 -22
  41. package/dist/core/allow-rule-shadow.d.ts +3 -3
  42. package/dist/core/ask-origin.d.ts +64 -18
  43. package/dist/core/ask-origin.js +63 -23
  44. package/dist/core/ask-question.d.ts +51 -8
  45. package/dist/core/ask-question.js +3 -4
  46. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  47. package/dist/core/ask-unresolvable-notice.js +16 -2
  48. package/dist/core/checkpoint-generation.d.ts +53 -0
  49. package/dist/core/checkpoint-generation.js +35 -0
  50. package/dist/core/checkpoint-queries.d.ts +180 -0
  51. package/dist/core/checkpoint-queries.js +272 -0
  52. package/dist/core/checkpoint-requirements.d.ts +13 -1
  53. package/dist/core/checkpoint-requirements.js +4 -0
  54. package/dist/core/checkpoint-store.d.ts +88 -24
  55. package/dist/core/checkpoint-store.js +24 -9
  56. package/dist/core/cross-boundary-taint.d.ts +6 -5
  57. package/dist/core/cross-boundary-taint.js +1 -3
  58. package/dist/core/decision-receipt.d.ts +37 -3
  59. package/dist/core/decision-receipt.js +17 -17
  60. package/dist/core/delegation-not-started.d.ts +6 -0
  61. package/dist/core/delegation-not-started.js +17 -0
  62. package/dist/core/engine-attestation.d.ts +93 -0
  63. package/dist/core/engine-attestation.js +70 -0
  64. package/dist/core/engine-capabilities.d.ts +4 -1
  65. package/dist/core/engine-capabilities.js +1 -1
  66. package/dist/core/engine-notice.d.ts +30 -11
  67. package/dist/core/file-history-store.d.ts +90 -14
  68. package/dist/core/file-history-store.js +23 -15
  69. package/dist/core/gate-fold.d.ts +1 -1
  70. package/dist/core/gate-fold.js +22 -10
  71. package/dist/core/gate-lanes.js +73 -64
  72. package/dist/core/gate-outcome.d.ts +26 -5
  73. package/dist/core/gate-outcome.js +26 -0
  74. package/dist/core/governance-codes.d.ts +5 -1
  75. package/dist/core/governance-codes.js +6 -0
  76. package/dist/core/hooks.d.ts +17 -16
  77. package/dist/core/hooks.js +3 -1
  78. package/dist/core/host-floor.d.ts +128 -0
  79. package/dist/core/host-floor.js +206 -0
  80. package/dist/core/host-target.d.ts +38 -3
  81. package/dist/core/host-target.js +38 -5
  82. package/dist/core/mcp.d.ts +5 -1
  83. package/dist/core/mcp.js +67 -41
  84. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  85. package/dist/core/memory-engine/engine.js +4 -4
  86. package/dist/core/memory-engine/layout.d.ts +60 -8
  87. package/dist/core/memory-engine/layout.js +65 -6
  88. package/dist/core/model-seat.d.ts +10 -3
  89. package/dist/core/mods/classic-events.d.ts +67 -0
  90. package/dist/core/mods/classic-events.js +1 -0
  91. package/dist/core/mods/dollar.d.ts +13 -0
  92. package/dist/core/mods/extension-call.d.ts +31 -0
  93. package/dist/core/mods/extension-call.js +43 -0
  94. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  95. package/dist/core/mods/kernel/dispatch.js +140 -69
  96. package/dist/core/mods/kernel/events.d.ts +47 -11
  97. package/dist/core/mods/kernel/events.js +66 -42
  98. package/dist/core/mods/kernel/index.d.ts +4 -4
  99. package/dist/core/mods/kernel/index.js +2 -2
  100. package/dist/core/mods/kernel/receive.d.ts +39 -5
  101. package/dist/core/mods/kernel/receive.js +290 -17
  102. package/dist/core/mods/kernel/registration.d.ts +33 -2
  103. package/dist/core/mods/kernel/registration.js +6 -7
  104. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  105. package/dist/core/mods/kernel/site-rules.js +24 -42
  106. package/dist/core/mods/spec-seats.d.ts +69 -0
  107. package/dist/core/mods/spec-seats.js +114 -0
  108. package/dist/core/mods/stations.d.ts +28 -8
  109. package/dist/core/mods/stations.js +29 -13
  110. package/dist/core/mods/tool-call.d.ts +79 -0
  111. package/dist/core/mods/tool-call.js +152 -0
  112. package/dist/core/namespaced-rule-name.d.ts +32 -38
  113. package/dist/core/namespaced-rule-name.js +29 -36
  114. package/dist/core/parent-spec-seat.d.ts +6 -1
  115. package/dist/core/parent-spec-seat.js +2 -0
  116. package/dist/core/park-selfcheck.js +1 -0
  117. package/dist/core/permission-rule-consent.d.ts +19 -0
  118. package/dist/core/permission-rule-consent.js +116 -26
  119. package/dist/core/permission-rule-model.d.ts +14 -3
  120. package/dist/core/permission-rule-model.js +39 -24
  121. package/dist/core/permission-rule-org.d.ts +6 -2
  122. package/dist/core/permission-rule-org.js +7 -3
  123. package/dist/core/permission-rule-provider.d.ts +5 -2
  124. package/dist/core/permission-rule-provider.js +41 -11
  125. package/dist/core/permission-rule-store.d.ts +3 -2
  126. package/dist/core/permission-rule-store.js +11 -2
  127. package/dist/core/permission-rule-sync.js +3 -2
  128. package/dist/core/permission-rule-syntax.d.ts +5 -4
  129. package/dist/core/permission-rule-syntax.js +2 -2
  130. package/dist/core/permission-rules.d.ts +4 -4
  131. package/dist/core/permission-rules.js +11 -20
  132. package/dist/core/persisted-rule-arms.d.ts +2 -2
  133. package/dist/core/persisted-rule-arms.js +10 -12
  134. package/dist/core/principal-name.d.ts +20 -0
  135. package/dist/core/principal-name.js +22 -0
  136. package/dist/core/prompt-section-seat.js +4 -6
  137. package/dist/core/protocol-http-auth.d.ts +26 -5
  138. package/dist/core/protocol-http-auth.js +137 -4
  139. package/dist/core/retired-keys.d.ts +16 -0
  140. package/dist/core/retired-keys.js +16 -4
  141. package/dist/core/rewrite-rejudge.d.ts +60 -0
  142. package/dist/core/rewrite-rejudge.js +36 -0
  143. package/dist/core/roles.d.ts +28 -1
  144. package/dist/core/roles.js +31 -19
  145. package/dist/core/rule-lane-reads.d.ts +20 -15
  146. package/dist/core/rule-lane-reads.js +45 -17
  147. package/dist/core/rule-owner.d.ts +3 -3
  148. package/dist/core/rule-owner.js +3 -2
  149. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  150. package/dist/core/runner/announce-once-ledger.js +5 -0
  151. package/dist/core/runner/assemble-result.d.ts +1 -0
  152. package/dist/core/runner/assemble-result.js +1 -1
  153. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  154. package/dist/core/runner/caller-roster.d.ts +16 -4
  155. package/dist/core/runner/caller-roster.js +33 -6
  156. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  157. package/dist/core/runner/capability-withheld-seat.js +24 -0
  158. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  159. package/dist/core/runner/classifier-ladder.js +3 -3
  160. package/dist/core/runner/construction-doors.js +3 -0
  161. package/dist/core/runner/contracts.d.ts +28 -25
  162. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  163. package/dist/core/runner/cross-boundary-lane.js +40 -27
  164. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  165. package/dist/core/runner/denial-limit-arms.js +1 -1
  166. package/dist/core/runner/file-history-request.d.ts +18 -0
  167. package/dist/core/runner/file-history-request.js +21 -13
  168. package/dist/core/runner/file-history-restore.d.ts +45 -0
  169. package/dist/core/runner/file-history-restore.js +46 -0
  170. package/dist/core/runner/gate-exit.d.ts +3 -3
  171. package/dist/core/runner/gate-exit.js +4 -3
  172. package/dist/core/runner/image.d.ts +7 -17
  173. package/dist/core/runner/image.js +9 -60
  174. package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
  175. package/dist/core/runner/permission-rule-lanes.js +26 -10
  176. package/dist/core/runner/person-path-rows.d.ts +12 -9
  177. package/dist/core/runner/person-path-rows.js +18 -7
  178. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  179. package/dist/core/runner/prepare-ask-lane.js +5 -2
  180. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  181. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  182. package/dist/core/runner/prepare-config-doors.d.ts +29 -38
  183. package/dist/core/runner/prepare-config-doors.js +42 -25
  184. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  185. package/dist/core/runner/prepare-defer-classify.js +7 -8
  186. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  187. package/dist/core/runner/prepare-file-history.js +7 -39
  188. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  189. package/dist/core/runner/prepare-gate-stations.js +10 -1
  190. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  191. package/dist/core/runner/prepare-hands-readface.js +15 -14
  192. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  193. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  194. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  195. package/dist/core/runner/prepare-park-ask.js +5 -5
  196. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  197. package/dist/core/runner/prepare-policy-chain.js +65 -72
  198. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  199. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  200. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  201. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  204. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  205. package/dist/core/runner/prepare-safety-scan.js +0 -17
  206. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  207. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  208. package/dist/core/runner/prepare-task.d.ts +1 -1
  209. package/dist/core/runner/prepare-task.js +29 -20
  210. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  211. package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
  212. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  213. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  215. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  216. package/dist/core/runner/resume-admission.js +1 -1
  217. package/dist/core/runner/resume-apply.js +11 -12
  218. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  219. package/dist/core/runner/resume-claim.d.ts +4 -2
  220. package/dist/core/runner/resume-claim.js +15 -8
  221. package/dist/core/runner/retired-runner-deps.js +1 -0
  222. package/dist/core/runner/rewind-files.d.ts +15 -0
  223. package/dist/core/runner/rewind-files.js +132 -0
  224. package/dist/core/runner/run-attachment-seats.js +2 -1
  225. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  226. package/dist/core/runner/run-brain-sinks.js +4 -2
  227. package/dist/core/runner/run-harness-handlers.js +12 -4
  228. package/dist/core/runner/run-leg.d.ts +1 -1
  229. package/dist/core/runner/run-leg.js +30 -18
  230. package/dist/core/runner/run-settle-and-teardown.js +2 -1
  231. package/dist/core/runner/run-turn-boundary.js +1 -10
  232. package/dist/core/runner/runtask.d.ts +3 -0
  233. package/dist/core/runner/runtask.js +8 -9
  234. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  235. package/dist/core/runner/session-read-file-states.js +28 -0
  236. package/dist/core/runner/session-rule-policy.js +4 -3
  237. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  238. package/dist/core/runner/shell-env-withheld.js +51 -0
  239. package/dist/core/runner/skills-seat.js +6 -2
  240. package/dist/core/runner/stream-settle-backstop.js +1 -1
  241. package/dist/core/runner/sub-agent-deny-lists.js +4 -7
  242. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  243. package/dist/core/runner/synthetic-tools.js +4 -1
  244. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  245. package/dist/core/runner/tool-disclosure.js +1 -3
  246. package/dist/core/runner/tool-end-body.d.ts +1 -1
  247. package/dist/core/runner/tool-end-body.js +10 -9
  248. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  249. package/dist/core/runner/tool-not-executed.js +11 -0
  250. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  251. package/dist/core/runner/tool-occurrence.js +7 -0
  252. package/dist/core/runner/turn-attachments.d.ts +33 -15
  253. package/dist/core/runner/turn-attachments.js +62 -37
  254. package/dist/core/runner-deps.d.ts +5 -5
  255. package/dist/core/safety-axis-vocab.d.ts +6 -4
  256. package/dist/core/safety-axis-vocab.js +6 -5
  257. package/dist/core/safety-merge-corpus.js +11 -3
  258. package/dist/core/secret-env.d.ts +26 -3
  259. package/dist/core/secret-env.js +44 -8
  260. package/dist/core/select-model.js +3 -3
  261. package/dist/core/session-policy-store.d.ts +27 -15
  262. package/dist/core/session-policy-store.js +156 -36
  263. package/dist/core/session-store.d.ts +29 -10
  264. package/dist/core/session-store.js +51 -19
  265. package/dist/core/session.d.ts +82 -16
  266. package/dist/core/session.js +53 -0
  267. package/dist/core/shell-read-silence.d.ts +11 -12
  268. package/dist/core/shell-read-silence.js +9 -5
  269. package/dist/core/shell-run-candidates.js +3 -1
  270. package/dist/core/shell-wrapper-projection.js +1 -1
  271. package/dist/core/shell-wrapper-table.d.ts +14 -7
  272. package/dist/core/shell-wrapper-table.js +5 -4
  273. package/dist/core/side-query.js +10 -1
  274. package/dist/core/skill-grant.d.ts +7 -2
  275. package/dist/core/skill-grant.js +5 -0
  276. package/dist/core/skills-directory.js +6 -2
  277. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  278. package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
  279. package/dist/core/store-contracts/file-history-store-contract.js +31 -1
  280. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  281. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  282. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  283. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  284. package/dist/core/store-contracts/session-store-contract.js +150 -14
  285. package/dist/core/stub-env.d.ts +2 -0
  286. package/dist/core/stub-env.js +1 -0
  287. package/dist/core/synthetic-read-verdict.js +3 -3
  288. package/dist/core/task-event.d.ts +32 -4
  289. package/dist/core/task-notification.d.ts +16 -12
  290. package/dist/core/task-registry.d.ts +9 -0
  291. package/dist/core/task-registry.js +11 -1
  292. package/dist/core/task-result.d.ts +18 -0
  293. package/dist/core/task-spec.d.ts +18 -13
  294. package/dist/core/tighten-task-spec.js +2 -1
  295. package/dist/core/tool-catalog-entries.d.ts +17 -0
  296. package/dist/core/tool-catalog-entries.js +13 -2
  297. package/dist/core/tool-check-reading.d.ts +11 -0
  298. package/dist/core/tool-check-reading.js +11 -6
  299. package/dist/core/tool-model-gate.d.ts +2 -2
  300. package/dist/core/tool-name-aliases.d.ts +16 -16
  301. package/dist/core/tool-name-aliases.js +13 -19
  302. package/dist/core/tool-name-readings.d.ts +5 -35
  303. package/dist/core/tool-name-readings.js +1 -9
  304. package/dist/core/tool-policy.d.ts +68 -198
  305. package/dist/core/tool-policy.js +149 -198
  306. package/dist/core/tool-result-store.js +3 -0
  307. package/dist/core/tool-roster.d.ts +14 -19
  308. package/dist/core/tool-roster.js +11 -44
  309. package/dist/core/tool-spec-members.js +7 -2
  310. package/dist/core/tool-spec.d.ts +19 -11
  311. package/dist/core/tools.js +49 -9
  312. package/dist/core/trace.d.ts +2 -2
  313. package/dist/core/types.d.ts +1 -1
  314. package/dist/core/user-attachment.d.ts +8 -1
  315. package/dist/core/user-attachment.js +64 -4
  316. package/dist/core/wiring-manifest.d.ts +9 -0
  317. package/dist/core/wiring-manifest.js +1 -0
  318. package/dist/core/workflow-journal-store.js +1 -1
  319. package/dist/engine/compaction/compaction.js +3 -2
  320. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  321. package/dist/engine/execution-env/node-execution-env.js +11 -2
  322. package/dist/engine/harness/agent-harness.d.ts +25 -1
  323. package/dist/engine/harness/agent-harness.js +54 -7
  324. package/dist/engine/harness/types.d.ts +29 -2
  325. package/dist/engine/llm/types.d.ts +28 -11
  326. package/dist/engine/loop/agent-loop.d.ts +22 -0
  327. package/dist/engine/loop/agent-loop.js +16 -26
  328. package/dist/engine/loop/types.d.ts +16 -6
  329. package/dist/engine/session/memory-repo.d.ts +9 -2
  330. package/dist/engine/session/memory-repo.js +11 -1
  331. package/dist/engine/session/repo-utils.d.ts +6 -5
  332. package/dist/engine/session/repo-utils.js +14 -6
  333. package/dist/index.d.ts +22 -10
  334. package/dist/index.js +15 -7
  335. package/dist/internal/harness-types.d.ts +1 -1
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  338. package/dist/orchestration/run-workflow-tool.js +5 -3
  339. package/dist/orchestration/workflow.d.ts +3 -0
  340. package/dist/orchestration/workflow.js +36 -18
  341. package/dist/prompt-assembly/artifact.d.ts +2 -2
  342. package/dist/prompt-assembly/artifact.js +5 -3
  343. package/dist/prompt-assembly/assemble.d.ts +3 -2
  344. package/dist/prompt-assembly/assemble.js +1 -1
  345. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  346. package/dist/prompt-assembly/catalog/schema.js +34 -2
  347. package/dist/prompt-assembly/catalog/sections.js +0 -1
  348. package/dist/prompt-assembly/composer.d.ts +3 -1
  349. package/dist/prompt-assembly/composer.js +1 -1
  350. package/dist/prompt-assembly/event-registry.js +1 -0
  351. package/dist/prompt-assembly/overlay.js +3 -3
  352. package/dist/prompt-assembly/renderers.d.ts +1 -1
  353. package/dist/prompt-assembly/renderers.js +0 -3
  354. package/dist/prompt-assembly/role-base.d.ts +15 -0
  355. package/dist/prompt-assembly/role-base.js +9 -0
  356. package/dist/prompt-assembly/select.d.ts +39 -14
  357. package/dist/prompt-assembly/select.js +47 -16
  358. package/dist/prompt-assembly/sugar.d.ts +17 -11
  359. package/dist/prompt-assembly/sugar.js +8 -3
  360. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  361. package/dist/prompt-assembly/tool-catalog.js +114 -4
  362. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  363. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  364. package/dist/prompt-assembly/types.d.ts +0 -7
  365. package/dist/scenarios/full-body.d.ts +11 -11
  366. package/dist/scenarios/full-body.js +4 -3
  367. package/dist/shell/lex.js +10 -1
  368. package/dist/stores/file/adoption/adopt.js +4 -3
  369. package/dist/stores/file/adoption/marker.js +3 -2
  370. package/dist/stores/file/checkpoint-store.d.ts +21 -0
  371. package/dist/stores/file/checkpoint-store.js +38 -6
  372. package/dist/stores/file/file-history-store.js +6 -7
  373. package/dist/stores/file/index.js +2 -1
  374. package/dist/stores/file/permission-rule-adopt.js +4 -3
  375. package/dist/stores/file/permission-rule-store.js +11 -5
  376. package/dist/stores/file/session-store.d.ts +29 -6
  377. package/dist/stores/file/session-store.js +42 -50
  378. package/dist/tools/artifact/artifact-tool.js +3 -2
  379. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  380. package/dist/tools/fs/bash-program-position.js +56 -9
  381. package/dist/tools/fs/fs-bash.js +5 -5
  382. package/dist/tools/fs/fs-glob.d.ts +86 -0
  383. package/dist/tools/fs/fs-glob.js +226 -0
  384. package/dist/tools/fs/fs-read.js +14 -14
  385. package/dist/tools/fs/fs-search-tools.js +7 -7
  386. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  387. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  388. package/dist/tools/fs/pdf.d.ts +9 -6
  389. package/dist/tools/fs/pdf.js +3 -3
  390. package/dist/tools/fs/program-read-model.d.ts +57 -7
  391. package/dist/tools/fs/program-read-model.js +11 -1
  392. package/dist/tools/fs/program-read-model.rows.js +78 -21
  393. package/dist/tools/fs/read-deny-home.js +3 -2
  394. package/dist/tools/fs/removal-targets.d.ts +17 -7
  395. package/dist/tools/fs/removal-targets.js +47 -20
  396. package/dist/tools/fs/search.d.ts +10 -0
  397. package/dist/tools/fs/search.js +20 -26
  398. package/dist/tools/fs/shell-read-argv.js +89 -12
  399. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  400. package/dist/tools/fs/shell-read-bindings.js +41 -0
  401. package/dist/tools/fs/shell-read-check.js +6 -19
  402. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  403. package/dist/tools/fs/shell-read-environment.js +3 -2
  404. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  405. package/dist/tools/fs/shell-read-establish.js +19 -20
  406. package/dist/tools/fs/shell-read-plan.js +24 -16
  407. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  408. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  409. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  410. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  411. package/dist/tools/fs/shell-reentry-text.js +40 -2
  412. package/dist/tools/todo.js +63 -63
  413. package/dist/tools/web.d.ts +19 -14
  414. package/dist/tools/web.js +38 -55
  415. package/package.json +1 -1
  416. package/test/export-surface.snapshot.json +143 -5
  417. package/wire-changes/core@7.56.0.json +3891 -0
  418. package/wire-changes/mods-kernel@7.56.0.json +303 -0
@@ -2,6 +2,8 @@ import { inlineUntrusted } from "./untrusted-text.js";
2
2
  import { markTightenMessage } from "./safety-axis-vocab.js";
3
3
  import { PROBE_REASON_MAX, normalizeProbeCause } from "./checkpoint-store.js";
4
4
  import { normalizeReadRootCandidate } from "./read-root-candidate.js";
5
+ import { engineFailClosedExit, hookDenyExit } from "./runner/gate-exit.js";
6
+ import { readRejudge, screenRewrite } from "./rewrite-rejudge.js";
5
7
  import { traceHookCrash } from "./gate-crash-trace.js";
6
8
  import { writeProtectionMandated, writeProtectionTightenDecision } from "./write-protect.js";
7
9
  import { createGateDeadline, awaitWriteProtectionJudgment, gateWaitFailureOf, withGateTimeout } from "./gate-bounded-await.js";
@@ -26,7 +28,7 @@ export async function runGateFold(pass) {
26
28
  catch (error) {
27
29
  unread = { error };
28
30
  }
29
- pass.decision = unread !== undefined ? failedJudgmentDeny(unread.error, callSignal ?? input.abortSignal, (e) => traceHookCrash(input, e, notifier), "the call's target reading", { toolName, toolCallId }) : adjudicate ? refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(pass.req, callSignal) : adjudicate(pass.req))) : { action: "allow" };
31
+ pass.decision = unread !== undefined ? failedJudgmentDeny(unread.error, callSignal ?? input.abortSignal, (e) => traceHookCrash(input, e, notifier), "the call's target reading", { toolName, toolCallId }) : adjudicate ? refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(pass.req, callSignal) : adjudicate(pass.req)), { call: pass.req }) : { action: "allow" };
30
32
  {
31
33
  const read = ledger.fromDecision(pass.decision);
32
34
  pass.decision = read.decision;
@@ -38,6 +40,18 @@ export async function runGateFold(pass) {
38
40
  if (attributed !== undefined)
39
41
  pass.classifierRound = attributed;
40
42
  }
43
+ const rewritten = pass.screening !== undefined && pass.decision.action !== "deny" ? readRejudge(pass.req, pass.currentInput, pass.decision) : undefined;
44
+ if (pass.screening !== undefined && rewritten?.kind === "rewritten") {
45
+ const second = await screenRewrite(pass.screening, pass.req, rewritten.form, `the rewritten call to "${toolName}"`);
46
+ if (second.kind === "refused") {
47
+ pass.currentInput = rewritten.form;
48
+ return second.by === "hook" ? hookDenyExit(pass, second.reason) : await engineFailClosedExit(pass, second.reason);
49
+ }
50
+ if (second.answer?.additionalContext)
51
+ pass.preToolContext.push(second.answer.additionalContext);
52
+ pass.hookAsk = second.answer?.action === "ask" ? second.answer : undefined;
53
+ pass.hookAllowedBy = second.answer?.action === "allow" ? (second.answeredBy !== undefined ? [second.answeredBy] : []) : undefined;
54
+ }
41
55
  if ((pass.decision.action === "allow" || pass.decision.action === "ask") && pass.decision.updatedInput !== undefined) {
42
56
  pass.policyRewrite = argsAsTheToolReads(pass.req, pass.decision.updatedInput);
43
57
  }
@@ -124,7 +138,7 @@ export async function runGateFold(pass) {
124
138
  if (tighten) {
125
139
  pass.decision = {
126
140
  action: "ask",
127
- message: markTightenMessage(toolName, "irreversible"),
141
+ message: markTightenMessage(toolName, input.irreversibility === "always" ? "irreversible" : "unproven"),
128
142
  decisionReason: "safety",
129
143
  ...(probeReason !== undefined ? { probeReason } : {}),
130
144
  ...(probeCause !== undefined ? { probeCause } : {}),
@@ -219,19 +233,18 @@ function applyShellReadVerdict(pass, answer, toolName, shellGated) {
219
233
  pass.shellReadDetails = verdict.details;
220
234
  if (pass.decision.action !== "allow") {
221
235
  if (pass.decision.action === "ask")
222
- pass.decision = { ...withProbeMandate(pass.decision, account), ...silencedBy(verdict, pass.decision) };
236
+ pass.decision = silencedBy(withProbeMandate(pass.decision, account), verdict, pass.req);
223
237
  return;
224
238
  }
225
239
  const candidate = normalizeReadRootCandidate(verdict.readRootCandidate);
226
- pass.decision = {
240
+ pass.decision = silencedBy({
227
241
  action: "ask",
228
242
  message: shellReadAskMessage(toolName, verdict),
229
243
  decisionReason: "safety",
230
244
  probeMandated: true,
231
- ...silencedBy(verdict, {}),
232
245
  ...(account !== undefined ? { probeReason: account } : {}),
233
246
  ...(candidate !== undefined ? { probeReadRootCandidate: candidate } : {}),
234
- };
247
+ }, verdict, pass.req);
235
248
  if (candidate !== undefined)
236
249
  pass.shellReadOffer = true;
237
250
  pass.tightenedBy = shellGated ? "shell_gate" : "safety";
@@ -242,17 +255,16 @@ function applyShellReadVerdict(pass, answer, toolName, shellGated) {
242
255
  if (verdict.details !== undefined)
243
256
  pass.shellReadDetails = verdict.details;
244
257
  if (pass.decision.action === "ask")
245
- pass.decision = { ...pass.decision, ...silencedBy(verdict, pass.decision) };
258
+ pass.decision = silencedBy(pass.decision, verdict, pass.req);
246
259
  if (pass.decision.action === "allow") {
247
260
  const candidate = normalizeReadRootCandidate(verdict.readRootCandidate);
248
- pass.decision = {
261
+ pass.decision = silencedBy({
249
262
  action: "ask",
250
263
  message: shellReadAskMessage(toolName, verdict),
251
264
  decisionReason: "safety",
252
- ...silencedBy(verdict, {}),
253
265
  ...(account !== undefined ? { probeReason: account } : {}),
254
266
  ...(candidate !== undefined ? { probeReadRootCandidate: candidate } : {}),
255
- };
267
+ }, verdict, pass.req);
256
268
  if (candidate !== undefined)
257
269
  pass.shellReadOffer = true;
258
270
  pass.tightenedBy = shellGated ? "shell_gate" : "safety";
@@ -1,22 +1,23 @@
1
1
  import { argsAsTheToolReads, withArgsReading } from "./effective-path-target.js";
2
- import { attest, attestationOf, bindableArgsOf, decisionText, foldHookAsk, mergeAttestation, refusalOf, refuseOutOfContractDecision, withAttestation } from "./tool-policy.js";
2
+ import { attest, attestationOf, bindableArgsOf, decisionText, foldHookAsk, refusalOf, refuseOutOfContractDecision } from "./tool-policy.js";
3
+ import { outletAsk, readRejudge, rewriteChasedSentence, screenRewrite } from "./rewrite-rejudge.js";
3
4
  import { arbitrateByMode, classifyAsk, decisionAskClassesOf, dontAskRefusalMessage, fileCommandOptionsSentence, persistedRuleMandateOf, safetyAxisOf, stampAskOrigin } from "./ask-origin.js";
4
5
  import { classifierParseFailureDenyMessage, denialLimitFallbackMessage, rungDidNotRule, unarmedWindow } from "./auto-mode.js";
5
6
  import { classifierNoRulingArm, settleNoRulingAsk } from "./classifier-unavailable-arm.js";
6
7
  import { SETTLEMENT_NOBODY_JUDGED } from "./gate-outcome.js";
7
8
  import { inlineUntrusted } from "./untrusted-text.js";
8
- import { ASK_USER_QUESTION_TOOL_NAME } from "./ask-question.js";
9
- import { toolFace } from "./tool-catalog-entries.js";
9
+ import { ASK_USER_QUESTION_TOOL_NAME, isEngineQuestionFace } from "./ask-question.js";
10
+ import { engineMountedAs } from "./tool-catalog-entries.js";
10
11
  import { applyPersistedTightening, disclosedRuleSet } from "./persisted-rule-arms.js";
11
12
  import { skillAllowDecision, skillRowRefusal } from "./skill-grant.js";
12
- import { allowRuleShadowOf } from "./allow-entry.js";
13
+ import { allowRuleShadowOf, withAllowRuleShadow } from "./allow-entry.js";
13
14
  import { CD_GIT_COMPOUND_SENTENCE, changesDirectoryBeforeGit, readOnlyShellVerdict } from "./read-only-shell.js";
14
15
  import { readShellCommand } from "./shell-run-candidates.js";
15
16
  import { COMMAND_RULE_TOOL, ruleShapeOf } from "./permission-rule-model.js";
16
17
  import { catalogRuleFaceOf, isProtectedWrite } from "./tool-registry.js";
17
18
  import { callFaceSeat } from "./tool-roster.js";
18
- import { heldBy, wireOf } from "./tool-name-readings.js";
19
- import { asksUnstated, modeAcceptsFileCommand, permissionSeatAt, unstatedAskMessage } from "./mode-policy.js";
19
+ import { wireOf } from "./tool-name-readings.js";
20
+ import { modeAcceptsFileCommand } from "./mode-policy.js";
20
21
  import { ORG_RULE_DECISION_REASON, ORG_UNAVAILABLE_DECISION_REASON, orgUnreadableClause } from "./permission-rule-org.js";
21
22
  import { exitGate, passAskFace, untakenValueExit } from "./runner/gate-exit.js";
22
23
  import { readOrgRuleLane, readPersistedRuleLane } from "./rule-lane-reads.js";
@@ -24,11 +25,9 @@ import { traceHookCrash } from "./gate-crash-trace.js";
24
25
  import { createGateDeadline, awaitWriteProtectionJudgment, withGateTimeout } from "./gate-bounded-await.js";
25
26
  import { readStationAnswer } from "./shell-read-silence.js";
26
27
  import { agentIdOf, judgedInputOf, raiseToolCheck } from "./mods/stations.js";
27
- import { readToolChecks } from "./tool-check-reading.js";
28
+ import { extensionAllowOf, readToolChecks } from "./tool-check-reading.js";
28
29
  import { policyThrowLine, reportPolicyThrow } from "./runner/policy-throw.js";
29
- const QUESTION_TOOL_NAMES = new Set([ASK_USER_QUESTION_TOOL_NAME]);
30
- const CONTENT_ROUTING_CONTRACTS = new Set(["ask-user-question", "structured-output", "report-blocked"].map((id) => toolFace(id).contract.contractId));
31
- const routesContent = (f) => f?.engineMounted === true && CONTENT_ROUTING_CONTRACTS.has(f.contractId);
30
+ const routesContent = engineMountedAs(["ask-user-question", "structured-output", "report-blocked"]);
32
31
  function parkWith(suspendAsk, parkArgs, carry) {
33
32
  return suspendAsk(...parkArgs, carry);
34
33
  }
@@ -83,7 +82,8 @@ export async function runGateLanes(pass) {
83
82
  });
84
83
  const readFaceNow = input.readFace?.();
85
84
  const askOriginFacts = (org, lane) => ({
86
- contentQuestion: heldBy("lanes.contentQuestionClass", QUESTION_TOOL_NAMES, pass.req),
85
+ call: { toolCallId: pass.req.toolCallId, toolName: pass.req.toolName },
86
+ contentQuestion: isEngineQuestionFace(pass.req.face),
87
87
  markedUnresolvable: markedUnresolvable(),
88
88
  org,
89
89
  ...(ruleCallUnreadableOf(lane) ? { ruleCallUnreadable: true } : {}),
@@ -232,7 +232,7 @@ export async function runGateLanes(pass) {
232
232
  if (laneAnswer?.unreadable === true)
233
233
  personalEvidence = { dotsAbsent: "unavailable" };
234
234
  let laneCoverage;
235
- const questionTool = wireOf("lanes.allowLayerQuestionSkip", pass.req) === ASK_USER_QUESTION_TOOL_NAME;
235
+ const questionTool = originFacts.contentQuestion;
236
236
  const laneIsProvenance = orgAnswer.org === undefined &&
237
237
  pass.decision.action === "ask" &&
238
238
  pass.decision.requiresRealApproval !== true &&
@@ -272,7 +272,7 @@ export async function runGateLanes(pass) {
272
272
  });
273
273
  const storedAllows = laneAnswer?.hit?.behavior === "allow" ? laneAnswer.hit.rules : undefined;
274
274
  const members = [
275
- ["hook", () => (pass.hookAllowedBy !== undefined && pass.policyRewrite === undefined ? { entries: pass.hookAllowedBy, clear: () => ({ action: "allow", message: "a PreToolUse hook allowed this call", decisionReason: "hook" }), afterClear: async () => undefined } : undefined)],
275
+ ["hook", () => (pass.hookAllowedBy !== undefined ? { entries: pass.hookAllowedBy, clear: () => extensionAllowOf(pass.hookAllowedBy ?? [], pass.policyRewrite), afterClear: async () => undefined } : undefined)],
276
276
  ["deployment", () => {
277
277
  const hit = input.deploymentAllows?.allowing(pass.req, mode);
278
278
  return hit && { entries: hit.entries, ...(hit.positions !== undefined ? { positions: hit.positions } : {}), clear: () => listAllow("deployment_rule", "the deployment's", hit.entries), afterClear: () => notifier.notifyAsync(() => input.deploymentAllows?.onAllowed?.({ toolName: pass.req.toolName, toolCallId, entries: hit.entries }), "toolGate.allowedToolsResolved") };
@@ -292,7 +292,15 @@ export async function runGateLanes(pass) {
292
292
  return hit && { entries: hit.entries, ...(hit.positions !== undefined ? { positions: hit.positions } : {}), clear: () => listAllow("request_rule", "this run's", hit.entries), afterClear: () => notifier.notifyAsync(() => input.requestAllows?.onAllowed?.({ toolName: pass.req.toolName, toolCallId, entries: hit.entries }), "toolGate.allowedToolsResolved") };
293
293
  }],
294
294
  ];
295
- const shadows = [];
295
+ const clearAs = async (member, hit) => {
296
+ const cleared = hit.clear();
297
+ pass.clearedBy = { ...allowRuleShadowOf(member, hit.entries), ...(hit.positions !== undefined ? { positions: hit.positions } : {}) };
298
+ await hit.afterClear();
299
+ if (member !== "hook")
300
+ afterRuleClear();
301
+ return cleared;
302
+ };
303
+ let shadows = [];
296
304
  if (!questionTool) {
297
305
  for (const [member, match] of members) {
298
306
  if (pass.decision.action !== "ask")
@@ -301,14 +309,10 @@ export async function runGateLanes(pass) {
301
309
  if (hit === undefined)
302
310
  continue;
303
311
  if (allowMayClear()) {
304
- pass.decision = hit.clear();
305
- pass.clearedBy = { ...allowRuleShadowOf(member, hit.entries), ...(hit.positions !== undefined ? { positions: hit.positions } : {}) };
306
- await hit.afterClear();
307
- if (member !== "hook")
308
- afterRuleClear();
312
+ pass.decision = await clearAs(member, hit);
309
313
  break;
310
314
  }
311
- shadows.push(allowRuleShadowOf(member, hit.entries));
315
+ shadows = withAllowRuleShadow(shadows, allowRuleShadowOf(member, hit.entries));
312
316
  hit.shadowed?.();
313
317
  }
314
318
  }
@@ -351,7 +355,7 @@ export async function runGateLanes(pass) {
351
355
  if (read?.kind === "denied")
352
356
  refuseByExtension(read.deny);
353
357
  else if (read?.kind === "cleared")
354
- pass.decision = read.allow;
358
+ pass.decision = await clearAs("hook", { entries: read.entries, clear: () => read.allow, afterClear: async () => undefined });
355
359
  else if (read?.kind === "asked") {
356
360
  const asked = read.minted ? { ...read.ask, ruleEvidence: mintRuleEvidence(personalEvidence) } : read.ask;
357
361
  if (read.marked === true)
@@ -360,7 +364,7 @@ export async function runGateLanes(pass) {
360
364
  pass.decision = stampAskOrigin(asked, facts, classifyStanding(asked, facts));
361
365
  }
362
366
  else if (read?.kind === "shadowed" && pass.decision.action === "ask")
363
- pass.decision = { ...pass.decision, allowRuleShadowed: [...(pass.decision.allowRuleShadowed ?? []), ...read.shadows] };
367
+ pass.decision = { ...pass.decision, allowRuleShadowed: read.shadows.reduce(withAllowRuleShadow, [...(pass.decision.allowRuleShadowed ?? [])]) };
364
368
  else if (read?.kind === "approved")
365
369
  takeApprovedEdit(read);
366
370
  }
@@ -417,7 +421,6 @@ export async function runGateLanes(pass) {
417
421
  }
418
422
  if (input.sandboxAdmission !== undefined &&
419
423
  pass.decision.action === "ask" &&
420
- wireOf("lanes.sandboxQuestionSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME &&
421
424
  input.isMarkedUnresolvable?.(input.event.toolCallId) !== true &&
422
425
  pass.decision.requiresRealApproval !== true &&
423
426
  pass.decision.decisionReason !== "hook" &&
@@ -484,7 +487,7 @@ export async function runGateLanes(pass) {
484
487
  if (parked)
485
488
  return parked;
486
489
  }
487
- if (pass.decision.action === "ask" && wireOf("lanes.contentAskRoute", pass.req) === ASK_USER_QUESTION_TOOL_NAME) {
490
+ if (pass.decision.action === "ask" && originFacts.contentQuestion) {
488
491
  const outcome = input.resolveContentAsk !== undefined ? await (callSignal !== undefined ? input.resolveContentAsk(pass.req, callSignal) : input.resolveContentAsk(pass.req)) : { kind: "unavailable", parkDeclined: false };
489
492
  if (outcome.kind === "answered") {
490
493
  pass.decision = { action: "allow" };
@@ -552,7 +555,6 @@ export async function runGateLanes(pass) {
552
555
  if (approvedWithArgs && pass.decision.action === "allow" && pass.decision.updatedInput !== undefined) {
553
556
  let editArgs = pass.decision.updatedInput;
554
557
  let editDenied;
555
- let editRewrittenSinceHuman = false;
556
558
  let editAnswer = pass.decision;
557
559
  let unanswered;
558
560
  const refusedAtResolution = (d) => { editDenied = d; pass.deniedBy = "ask_resolution"; };
@@ -575,6 +577,7 @@ export async function runGateLanes(pass) {
575
577
  break;
576
578
  }
577
579
  let editHookAsk;
580
+ let rewrittenEdit = false;
578
581
  if (screening !== undefined) {
579
582
  const screened = await screening.screen(editArgs, `the approved edit for "${toolName}"`);
580
583
  if (screened.kind === "refused") {
@@ -595,9 +598,10 @@ export async function runGateLanes(pass) {
595
598
  const { updatedInput: _adopted, ...ask } = hr;
596
599
  editHookAsk = ask;
597
600
  }
598
- if (hr.updatedInput !== undefined) {
599
- editArgs = argsAsTheToolReads(pass.req, hr.updatedInput);
600
- editRewrittenSinceHuman = true;
601
+ const hookRead = readRejudge(pass.req, editArgs, hr);
602
+ if (hookRead.kind === "rewritten") {
603
+ editArgs = hookRead.form;
604
+ rewrittenEdit = true;
601
605
  }
602
606
  }
603
607
  }
@@ -605,7 +609,7 @@ export async function runGateLanes(pass) {
605
609
  if (adjudicate) {
606
610
  try {
607
611
  const editReq = Object.freeze({ toolName, args: editArgs, toolCallId, ...(pass.req.face !== undefined ? { face: pass.req.face } : {}) });
608
- recheck = refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(editReq, callSignal) : adjudicate(editReq)));
612
+ recheck = refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(editReq, callSignal) : adjudicate(editReq)), { call: editReq });
609
613
  }
610
614
  catch (err) {
611
615
  reportPolicyThrow((e) => traceHookCrash(input, e, notifier), "the tool policy's re-check of the approved edit", { toolName, toolCallId }, err, callSignal ?? input.abortSignal);
@@ -628,9 +632,30 @@ export async function runGateLanes(pass) {
628
632
  break;
629
633
  }
630
634
  }
631
- if (recheck.updatedInput !== undefined) {
632
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
633
- editRewrittenSinceHuman = true;
635
+ const policyRead = recheck.action !== "deny" ? readRejudge(pass.req, editArgs, recheck) : undefined;
636
+ if (recheck.action !== "deny" && recheck.updatedInput !== undefined) {
637
+ const { updatedInput: _form, ...verdict } = recheck;
638
+ recheck = verdict;
639
+ }
640
+ if (policyRead?.kind === "rewritten") {
641
+ if (rewrittenEdit) {
642
+ editDenied = { action: "deny", message: rewriteChasedSentence(toolName) };
643
+ pass.deniedBy = "policy";
644
+ break;
645
+ }
646
+ editArgs = policyRead.form;
647
+ rewrittenEdit = true;
648
+ const second = screening !== undefined ? await screenRewrite(screening, pass.req, editArgs, `the rewritten edit for "${toolName}"`) : undefined;
649
+ if (second?.kind === "refused") {
650
+ editDenied = { action: "deny", message: second.reason };
651
+ pass.deniedBy = "hook";
652
+ break;
653
+ }
654
+ if (second?.kind === "stands") {
655
+ if (second.answer?.additionalContext)
656
+ pass.preToolContext.push(second.answer.additionalContext);
657
+ editHookAsk = second.answer?.action === "ask" ? second.answer : undefined;
658
+ }
634
659
  }
635
660
  const editOrg = await applyOrgLayer(recheck, editArgs);
636
661
  recheck = editOrg.decision;
@@ -657,21 +682,17 @@ export async function runGateLanes(pass) {
657
682
  pass.deniedBy = "policy";
658
683
  break;
659
684
  }
660
- if (recheck.action === "allow") {
661
- if (recheck.updatedInput !== undefined) {
662
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
663
- editRewrittenSinceHuman = true;
664
- }
665
- const answeredRecheck = withAttestation(recheck, mergeAttestation(pass.req, attestationOf(editAnswer, pass.req), attestationOf(recheck, pass.req), "answer"));
666
- if (asksUnstated(answeredRecheck, pass.req, editArgs, permissionSeatAt(input, editArgs)?.seat, input.permissionMode?.())) {
667
- recheck = { action: "ask", message: permissionSeatAt(input, editArgs)?.question ?? unstatedAskMessage(toolName) };
668
- pass.tightenedBy = "unstated";
685
+ if (rewrittenEdit && input.writeProtectionCheck !== undefined) {
686
+ const check = input.writeProtectionCheck;
687
+ const verdict = await awaitWriteProtectionJudgment((deadline) => check(toolName, editArgs, pass.req.face, input.trackedCwd?.(), deadline), boundedAwaitDeadlineMs, callSignal ?? input.abortSignal);
688
+ if (verdict !== undefined && verdict.kind !== "clear") {
689
+ editDenied = { action: "deny", message: verdict.kind === "hit" ? `the approved edit for "${toolName}" was rewritten by the restriction chain onto a write-protected path (table entry "${verdict.hit.name}") that no approval covers — denied fail-closed; re-submit the edited action directly` : `the approved edit for "${toolName}" was rewritten by the restriction chain onto a target whose destination could not be determined (target_unresolved: ${verdict.cause}) — denied fail-closed; re-submit the edited action directly` };
690
+ pass.deniedBy = "write_protection";
691
+ break;
669
692
  }
670
693
  }
671
- if (recheck.updatedInput !== undefined) {
672
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
673
- editRewrittenSinceHuman = true;
674
- }
694
+ if (rewrittenEdit)
695
+ recheck = outletAsk(recheck, toolName, editArgs);
675
696
  let editFacts;
676
697
  const stampEditAsk = (ask) => {
677
698
  const editAskSnapshot = { ...ask, ruleEvidence: mintRuleEvidence({ dotsAbsent: "not_adjudicated" }) };
@@ -687,7 +708,9 @@ export async function runGateLanes(pass) {
687
708
  if (carriedOwnAsk !== undefined) {
688
709
  const { updatedInput: _theOriginalBytes, ...carried } = carriedOwnAsk;
689
710
  const rra = carried.requiresRealApproval === true ? { requiresRealApproval: true } : {};
690
- editDecision = stampEditAsk(editDecision.action === "ask" ? { ...editDecision, foldedAskClasses: [...(editDecision.foldedAskClasses ?? []), ...decisionAskClassesOf(carried), ...(carried.classes ?? [])], ...rra } : carried);
711
+ const call = { toolCallId, toolName };
712
+ const folded = new Set([...(editDecision.action === "ask" ? (attestationOf(editDecision, call)?.foldedClasses ?? []) : []), ...decisionAskClassesOf(carried, call), ...(carried.classes ?? [])]);
713
+ editDecision = stampEditAsk(editDecision.action === "ask" ? attest({ ...editDecision, ...rra }, call, { foldedClasses: [...folded] }) : carried);
691
714
  carriedOwnAsk = undefined;
692
715
  }
693
716
  const editRead = await checkTool(editDecision, editArgs, editOrg.org, undefined);
@@ -700,7 +723,6 @@ export async function runGateLanes(pass) {
700
723
  carriedOwnAsk = editRead.outstanding ?? (editDecision.action === "ask" ? editDecision : undefined);
701
724
  editArgs = editRead.allow.updatedInput;
702
725
  editAnswer = editRead.allow;
703
- editRewrittenSinceHuman = false;
704
726
  continue;
705
727
  }
706
728
  if (editRead?.kind === "asked" && editRead.marked === true)
@@ -708,13 +730,13 @@ export async function runGateLanes(pass) {
708
730
  if (editRead?.kind === "asked")
709
731
  editDecision = stampEditAsk(editRead.ask);
710
732
  else if (editRead?.kind === "shadowed" && editDecision.action === "ask")
711
- editDecision = { ...editDecision, allowRuleShadowed: [...(editDecision.allowRuleShadowed ?? []), ...editRead.shadows] };
733
+ editDecision = { ...editDecision, allowRuleShadowed: editRead.shadows.reduce(withAllowRuleShadow, [...(editDecision.allowRuleShadowed ?? [])]) };
712
734
  if (editDecision.action !== "ask")
713
735
  break;
714
736
  const editAskDecision = editDecision;
715
737
  if (input.permissionMode !== undefined && pass.askClassification !== undefined) {
716
738
  const editVerdict = arbitrateByMode(input.permissionMode(), pass.askClassification, { ...(editAskDecision.origin !== undefined ? { origin: editAskDecision.origin } : {}), ...(editAskDecision.mandate !== undefined ? { mandate: editAskDecision.mandate } : {}) });
717
- if (editVerdict.kind === "released") {
739
+ if (editVerdict.kind === "released" && !rewrittenEdit) {
718
740
  ledger.supersede();
719
741
  pass.arbitration = editVerdict;
720
742
  await notifier.notifyAsync(() => input.onModeReleased?.({ toolName, toolCallId, release: { mode: editVerdict.mode, askClass: editVerdict.askClass, classes: editVerdict.classes, ...(editVerdict.origin !== undefined ? { origin: editVerdict.origin } : {}), ...(editVerdict.mandate !== undefined ? { mandate: editVerdict.mandate } : {}), ...(editVerdict.reason !== undefined ? { reason: editVerdict.reason } : {}) }, ...(pass.shellReadUnestablished === true ? { readUnestablished: true } : {}) }), "toolGate.onModeReleased");
@@ -736,34 +758,21 @@ export async function runGateLanes(pass) {
736
758
  const rr = ledger.fromResolved(await (callSignal !== undefined ? resolveAsk(editAskDecision, editAskReq, callSignal) : resolveAsk(editAskDecision, editAskReq)), editAskDecision, editAskReq);
737
759
  if (rr.action !== "allow") {
738
760
  refusedAtResolution(rr);
761
+ if (rewrittenEdit)
762
+ pass.denyDetails = { editRewritten: { acceptableForm: editArgs } };
739
763
  if (rr.approverUnavailable === true)
740
764
  unanswered = { ask: editAskDecision, req: editAskReq, org: editOrg.org, deny: rr };
741
765
  break;
742
766
  }
743
767
  if (rr.updatedInput === undefined) {
744
- editRewrittenSinceHuman = false;
745
768
  break;
746
769
  }
747
770
  editArgs = rr.updatedInput;
748
771
  editAnswer = rr;
749
772
  if (editAskDecision.action === "ask")
750
773
  editAskedOrigin = editAskDecision.origin;
751
- editRewrittenSinceHuman = false;
752
774
  }
753
775
  const rejudged = () => editDenied === undefined || editDenied === unanswered?.deny;
754
- if (rejudged() && editRewrittenSinceHuman && input.writeProtectionCheck !== undefined) {
755
- const check = input.writeProtectionCheck;
756
- const verdict = await awaitWriteProtectionJudgment((deadline) => check(toolName, editArgs, pass.req.face, input.trackedCwd?.(), deadline), boundedAwaitDeadlineMs, callSignal ?? input.abortSignal);
757
- if (verdict !== undefined && verdict.kind !== "clear") {
758
- editDenied = {
759
- action: "deny",
760
- message: verdict.kind === "hit"
761
- ? `the approved edit for "${toolName}" was rewritten by the restriction chain onto a write-protected path (table entry "${verdict.hit.name}") that no approval covers — denied fail-closed; re-submit the edited action directly`
762
- : `the approved edit for "${toolName}" was rewritten by the restriction chain onto a target whose destination could not be determined (target_unresolved: ${verdict.cause}) — denied fail-closed; re-submit the edited action directly`,
763
- };
764
- pass.deniedBy = "write_protection";
765
- }
766
- }
767
776
  if (rejudged() && input.shellReadCheck !== undefined) {
768
777
  const station = input.shellReadCheck;
769
778
  const judged = station.judge(pass.req, editArgs, input.trackedCwd?.(), callSignal ?? input.abortSignal, { seat: "rejudge", toolCallId });
@@ -10,6 +10,7 @@
10
10
  import { type AskClass, type AskOrigin, type AssertAllKeysHandled, type ModeReleaseReason, type PermissionMode, type PersistedRuleMandate } from "./ask-origin.js";
11
11
  import { type AutoModeClassifierRound, type AutoModeFallbackCause } from "./auto-mode.js";
12
12
  import { type AllowRuleClearance } from "./allow-rule-shadow.js";
13
+ import type { ResolvedOutcome } from "./checkpoint-store.js";
13
14
  /**
14
15
  * How the wait an ask was in ENDED — the closed set. One word per way a wait can end; the `who` on the
15
16
  * record says which party ended it and is fixed BY the word (see {@link Settlement}).
@@ -244,6 +245,18 @@ export declare const SETTLEMENT_NOBODY_JUDGED: {
244
245
  };
245
246
  /** Compile-time fence: `never` while every settlement kind has a nobody-judged row. */
246
247
  export type NobodyJudgedTableCoversEveryKind = AssertAllKeysHandled<Exclude<SettlementKind, keyof typeof SETTLEMENT_NOBODY_JUDGED>>;
248
+ /** Which words of a durable row's winner ({@link ResolvedOutcome.decision}) are the ALLOW direction: a tool approval's `allow`, a plan
249
+ * pause's `approve` / `edit`; the others refuse. Total over the winner's words — the fence below refuses a word without a row — so
250
+ * invariant I11 compares directions by table lookup. */
251
+ declare const WINNER_DECISION_ALLOWS: {
252
+ readonly allow: true;
253
+ readonly approve: true;
254
+ readonly edit: true;
255
+ readonly deny: false;
256
+ readonly reject: false;
257
+ };
258
+ /** Compile-time fence: `never` while every word a winner can hold has a direction row. */
259
+ export type WinnerDecisionTableCoversEveryDecision = AssertAllKeysHandled<Exclude<ResolvedOutcome["decision"], keyof typeof WINNER_DECISION_ALLOWS>>;
247
260
  /**
248
261
  * WHO REFUSED a call — the layer whose verdict is the deny. The other question a deny raises, "who ASKED",
249
262
  * is answered by {@link GateOutcome.origin} (an {@link import("./ask-origin.js").AskOrigin}); the two used
@@ -353,8 +366,8 @@ export type CauseTableCoversEveryDeniedBy = AssertAllKeysHandled<Exclude<DeniedB
353
366
  * handed the question to the approval seat, whose settlement then names the resolution that ask reached.
354
367
  * Additive. Invariant I6 ({@link screenGateOutcome}) screens its shape.
355
368
  *
356
- * `clearedBy` — the allow layer's account of a call it let run without asking: which member's allow rule cleared the ask
357
- * (`hook` / `deployment` / `persisted` / `skill` / `request`) and the entries it stood on, sanitized and capped as a shadow
369
+ * `clearedBy` — the allow layer's account of a call it let run without asking: which member cleared the ask (`hook`, an
370
+ * extension's `classic.PreToolUse` or `tool.check` allow, / `deployment` / `persisted` / `skill` / `request`) and the entries it stood on, sanitized and capped as a shadow
358
371
  * record is, with `positions` for a list member (the indices of those entries in the list the run received — a host maps them
359
372
  * onto the declaration it sent for this run). Present exactly when an allow member cleared a standing ask and nobody answered
360
373
  * it: absent on a call nothing asked about, a mode's release or acceptance, the read-only arm's, the classifier's or the
@@ -404,7 +417,7 @@ export interface ModeRefusal {
404
417
  * payload, the call's `tool_end` frame, and the durable row's resolved outcome. The three faces are the
405
418
  * same object graph, so they cannot tell different stories.
406
419
  *
407
- * The three members are orthogonal but bound by four invariants ({@link screenGateOutcome}):
420
+ * The three members are orthogonal but bound by the invariants ({@link screenGateOutcome}):
408
421
  * I1 `settlement` present ⇔ `origin` present (they describe the same ask);
409
422
  * I2 `disposition.deniedBy === "ask_resolution"` ⇒ `settlement` present and a refusal kind;
410
423
  * I3 `settlement` an approval (a kind {@link SETTLEMENT_IS_REFUSAL} says is not a refusal) ∧
@@ -428,7 +441,11 @@ export interface ModeRefusal {
428
441
  * I9 `disposition.clearedBy` present ⇒ `kind === "allowed"`, no settlement and no release (an allow member cleared the ask
429
442
  * before anyone answered it), `member` one of the allow layer's members, `entries` a list of strings, `omitted` a positive
430
443
  * whole number when present, and `positions` — only on a list member (`request`, `deployment`) — a list of non-negative
431
- * whole numbers.
444
+ * whole numbers;
445
+ * I10 `settlement.when` present ⇒ a finite number (epoch ms — the moment the wait ended is a value a reader can order);
446
+ * I11 a winner's `decision` stated beside the record (the caller reads a durable row: `winnerDecision`) ⇒ a word a winner holds,
447
+ * and its direction (allow: `allow` / `approve` / `edit`; refusal: `deny` / `reject`) is the direction of the record's
448
+ * settlement ({@link SETTLEMENT_IS_REFUSAL}) and of its disposition (`allowed` / `denied`) — one decision, one direction.
432
449
  * Nothing here is read out of an ABSENCE: an ordinary allow with no ask is `{ disposition: { kind: "allowed" } }`,
433
450
  * a direct policy deny is `{ disposition: { kind: "denied", deniedBy: "policy" } }`, and neither carries a
434
451
  * settlement because neither settled one.
@@ -506,7 +523,7 @@ type DenyOnlyMember = Exclude<keyof Extract<GateDisposition, {
506
523
  /** Compile-time fence: `never` while the list is exactly the denied arm's own members. */
507
524
  export type DenyOnlyMembersAreListed = AssertAllKeysHandled<Exclude<DenyOnlyMember, (typeof DENY_ONLY_MEMBERS)[number]> | Exclude<(typeof DENY_ONLY_MEMBERS)[number], DenyOnlyMember>>;
508
525
  /**
509
- * The one invariant screen for a {@link GateOutcome} (I1–I8 above, plus the closed-set word each member carries). Two readings:
526
+ * The one invariant screen for a {@link GateOutcome} (I1–I11 above, plus the closed-set word each member carries). Two readings:
510
527
  * - `"archive"` (the default) — a record read back from where it was kept (a replay, a ledger, a durable row): its shape, with
511
528
  * every closed set read as its live members plus {@link RETIRED_MEMBERS}. A record lawful when minted is not a defect later.
512
529
  * - `"producer"` — a record THIS engine is composing or publishing now: the live sets alone, and the engine's release law
@@ -514,10 +531,14 @@ export type DenyOnlyMembersAreListed = AssertAllKeysHandled<Exclude<DenyOnlyMemb
514
531
  * The record is read as whatever it holds (`unknown`): a member that is not the shape the type names — `null`, an array, a
515
532
  * primitive where a record belongs, an object where a word belongs — is a defect naming its position, never an exception, and
516
533
  * every class, reason, origin and mandate word is read wherever the record carries it.
534
+ * A caller reading a durable row's winner ({@link ResolvedOutcome}) states the winner's `decision` beside the record it carries
535
+ * (`winnerDecision`, the key present whatever it holds, read as `reading` is read): invariant I11 then reads that word, so the decision and the record it filed
536
+ * cannot be read as two directions. Without the key there is no winner beside the record and I11 reads nothing.
517
537
  * Returns the defects as sentences (an empty list is a clean record); the caller decides the fail-loud form (report + withhold,
518
538
  * or refuse), never silently repairs the record. An options value that is not an object, or a reading outside the two, throws.
519
539
  */
520
540
  export declare function screenGateOutcome(g: unknown, opts?: {
521
541
  readonly reading?: "archive" | "producer";
542
+ readonly winnerDecision?: unknown;
522
543
  }): string[];
523
544
  export {};
@@ -75,6 +75,16 @@ export const SETTLEMENT_NOBODY_JUDGED = {
75
75
  policy_refused: true,
76
76
  task_aborted: false,
77
77
  };
78
+ const WINNER_DECISION_ALLOWS = {
79
+ allow: true,
80
+ approve: true,
81
+ edit: true,
82
+ deny: false,
83
+ reject: false,
84
+ };
85
+ function isWinnerDecision(v) {
86
+ return typeof v === "string" && Object.hasOwn(WINNER_DECISION_ALLOWS, v);
87
+ }
78
88
  export const DENIED_BY_VALUES = Object.freeze(["policy", "hook", "org", "persisted_rule", "classifier", "compliance", "write_protection", "ask_resolution", "read_boundary", "mode"]);
79
89
  const DENIED_BY_SET = new Set(DENIED_BY_VALUES);
80
90
  export function isDeniedBy(v) {
@@ -231,6 +241,8 @@ export function screenGateOutcome(g, opts) {
231
241
  const party = objectOf(s?.who)?.party;
232
242
  if (s !== undefined && !member("settlementParty", party))
233
243
  defects.push(outside("settlement.who.party", "settlementParty", party));
244
+ if (s !== undefined && !(typeof s.when === "number" && Number.isFinite(s.when)))
245
+ defects.push(`I10: settlement.when ${spelled(s.when)} is not a finite number (epoch ms)`);
234
246
  if (record.origin !== undefined && !member("askOrigin", record.origin))
235
247
  defects.push(outside("origin", "askOrigin", record.origin));
236
248
  if (settled !== (record.origin !== undefined))
@@ -317,6 +329,20 @@ export function screenGateOutcome(g, opts) {
317
329
  }
318
330
  }
319
331
  }
332
+ if (opts !== undefined && "winnerDecision" in opts) {
333
+ const decision = opts.winnerDecision;
334
+ if (!isWinnerDecision(decision))
335
+ defects.push(`I11: winnerDecision ${spelled(decision)} is none of the words a winner holds (${Object.keys(WINNER_DECISION_ALLOWS).join(", ")})`);
336
+ else {
337
+ const allows = WINNER_DECISION_ALLOWS[decision];
338
+ const says = allows ? "allow" : "refusal";
339
+ if (kind !== undefined && SETTLEMENT_IS_REFUSAL[kind] === allows)
340
+ defects.push(`I11: the winner's decision "${decision}" is the ${says} direction but the settlement kind ${kind} ended the wait as ${allows ? "a refusal" : "an approval"}`);
341
+ const recordAllows = allowed !== undefined ? true : denied !== undefined ? false : undefined;
342
+ if (recordAllows !== undefined && recordAllows !== allows)
343
+ defects.push(`I11: the winner's decision "${decision}" is the ${says} direction but the disposition reads ${recordAllows ? "allowed" : "denied"}`);
344
+ }
345
+ }
320
346
  if (producer)
321
347
  defects.push(...releasePolicyDefects(g));
322
348
  return defects;
@@ -145,7 +145,7 @@ export type NoticeAudience = "user" | "operator";
145
145
  * the union's catalog ({@link EngineNotice.code}). The groups below say only which family a row joins,
146
146
  * so the catalog is not written a second time here and the two cannot drift.
147
147
  */
148
- 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.seat_detached", "advisor.not_attached", "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"];
148
+ 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", "inherit_env.names_withheld", "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.seat_detached", "advisor.not_attached", "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", "model.capability_downgraded", "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"];
149
149
  /** A catalogued code (see {@link ENGINE_NOTICE_CODES}); {@link NOTICE_MINTER} says who mints it. NOT the type of
150
150
  * `EngineNotice.code`, which stays `string` — a host forwarding its own notices through the same
151
151
  * sink is a supported shape, and narrowing that field would break it. */
@@ -201,6 +201,7 @@ declare const NOTICE_AUDIENCE_TABLE: {
201
201
  readonly "memory.capture_optout_unpersisted": "user";
202
202
  readonly "memory.consolidation_withheld": "operator";
203
203
  readonly "delegation.ask_unresolvable": "user";
204
+ readonly "inherit_env.names_withheld": "user";
204
205
  readonly "config.autocompact_window_clamped": "operator";
205
206
  readonly "config.env_timeout_discarded": "operator";
206
207
  readonly "config.materialize_env_discarded": "operator";
@@ -253,6 +254,7 @@ declare const NOTICE_AUDIENCE_TABLE: {
253
254
  readonly "route.response_model_mismatch": "operator";
254
255
  readonly "route.tool_call_id_folded": "operator";
255
256
  readonly "route.extra_body_reserved_dropped": "operator";
257
+ readonly "model.capability_downgraded": "user";
256
258
  readonly "context.tool_turn_repaired": "operator";
257
259
  readonly "skills.listing_truncated": "operator";
258
260
  readonly "agents.listing_truncated": "operator";
@@ -315,6 +317,7 @@ declare const NOTICE_MINTER_TABLE: {
315
317
  readonly "config.peer_admission_out_of_range": "engine";
316
318
  readonly "config.peer_lane_unmounted": "engine";
317
319
  readonly "config.secret_env_scrubbed": "engine";
320
+ readonly "inherit_env.names_withheld": "engine";
318
321
  readonly "config.credential_not_withheld": "engine";
319
322
  readonly "config.cross_boundary_posture_undeclared": "engine";
320
323
  readonly "config.cross_boundary_record_unwritten": "engine";
@@ -367,6 +370,7 @@ declare const NOTICE_MINTER_TABLE: {
367
370
  readonly "route.finish_reason_unknown": "engine";
368
371
  readonly "route.stream_end_ignored": "engine";
369
372
  readonly "route.extra_body_reserved_dropped": "engine";
373
+ readonly "model.capability_downgraded": "engine";
370
374
  readonly "context.tool_turn_repaired": "engine";
371
375
  readonly "task.user_steer_undrained": "engine";
372
376
  readonly "task.user_followup_undrained": "engine";