@sema-agent/core 7.54.1 → 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 (621) hide show
  1. package/CHANGELOG.md +950 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cascade.js +1 -1
  5. package/dist/agents/cc-peer-directory.d.ts +36 -0
  6. package/dist/agents/cc-peer-directory.js +139 -0
  7. package/dist/agents/cc-peer-wire.d.ts +105 -0
  8. package/dist/agents/cc-peer-wire.js +98 -0
  9. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  10. package/dist/agents/cc-uds-peer-channel.js +457 -0
  11. package/dist/agents/child-model-seat.d.ts +0 -11
  12. package/dist/agents/child-model-seat.js +0 -3
  13. package/dist/agents/cross-session-envelope.d.ts +4 -1
  14. package/dist/agents/cross-session-envelope.js +8 -1
  15. package/dist/agents/cross-session-judge.d.ts +2 -2
  16. package/dist/agents/list-agents-tool.d.ts +3 -1
  17. package/dist/agents/list-agents-tool.js +9 -8
  18. package/dist/agents/observer.d.ts +4 -5
  19. package/dist/agents/observer.js +2 -1
  20. package/dist/agents/peer-admission.d.ts +6 -0
  21. package/dist/agents/peer-admission.js +4 -1
  22. package/dist/agents/peer-directory.d.ts +65 -13
  23. package/dist/agents/peer-directory.js +90 -25
  24. package/dist/agents/peer-notices.d.ts +1 -1
  25. package/dist/agents/peer-session-drain.d.ts +3 -1
  26. package/dist/agents/peer-session-drain.js +3 -2
  27. package/dist/agents/read-inbox-tool.js +2 -1
  28. package/dist/agents/repair-loop.js +2 -2
  29. package/dist/agents/retain-ledger.d.ts +1 -1
  30. package/dist/agents/roster-store.d.ts +1 -1
  31. package/dist/agents/send-message-tool.d.ts +10 -0
  32. package/dist/agents/send-message-tool.js +37 -8
  33. package/dist/agents/subagent.d.ts +39 -82
  34. package/dist/agents/subagent.js +109 -106
  35. package/dist/agents/tool-filter.d.ts +31 -46
  36. package/dist/agents/tool-filter.js +13 -33
  37. package/dist/agents/verify.d.ts +6 -5
  38. package/dist/agents/verify.js +3 -3
  39. package/dist/brain/anthropic.js +43 -81
  40. package/dist/brain/errors.d.ts +15 -0
  41. package/dist/brain/errors.js +10 -0
  42. package/dist/brain/media-degrade.d.ts +18 -7
  43. package/dist/brain/media-degrade.js +13 -2
  44. package/dist/brain/model-capability.d.ts +37 -0
  45. package/dist/brain/model-capability.js +34 -0
  46. package/dist/brain/model-presets.d.ts +6 -12
  47. package/dist/brain/model-presets.js +1 -6
  48. package/dist/brain/open-responses.js +27 -35
  49. package/dist/brain/openai.js +30 -98
  50. package/dist/brain/provider-dialect.d.ts +39 -3
  51. package/dist/brain/provider-dialect.js +28 -0
  52. package/dist/brain/reasoning-request.d.ts +96 -0
  53. package/dist/brain/reasoning-request.js +174 -0
  54. package/dist/brain/reasoning.d.ts +12 -12
  55. package/dist/brain/reasoning.js +4 -3
  56. package/dist/brain/request-params.d.ts +62 -9
  57. package/dist/brain/request-params.js +42 -7
  58. package/dist/brain/retry.d.ts +1 -1
  59. package/dist/brain/route-adjudicator.d.ts +15 -0
  60. package/dist/brain/route-adjudicator.js +15 -0
  61. package/dist/brain/status-sink.d.ts +20 -0
  62. package/dist/brain/status-sink.js +7 -0
  63. package/dist/brain/stream-engine.js +6 -5
  64. package/dist/brain/stream-shared.d.ts +1 -1
  65. package/dist/core/a2a.d.ts +2 -1
  66. package/dist/core/a2a.js +19 -13
  67. package/dist/core/advisor-verdict.d.ts +120 -0
  68. package/dist/core/advisor-verdict.js +92 -0
  69. package/dist/core/agent-definition.d.ts +17 -8
  70. package/dist/core/allow-entry.d.ts +69 -36
  71. package/dist/core/allow-entry.js +81 -52
  72. package/dist/core/allow-rule-shadow.d.ts +10 -3
  73. package/dist/core/approval-object.d.ts +2 -1
  74. package/dist/core/approval-object.js +6 -6
  75. package/dist/core/ask-origin.d.ts +127 -29
  76. package/dist/core/ask-origin.js +87 -25
  77. package/dist/core/ask-question.d.ts +51 -8
  78. package/dist/core/ask-question.js +12 -7
  79. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  80. package/dist/core/ask-unresolvable-notice.js +16 -2
  81. package/dist/core/auto-compaction.d.ts +11 -8
  82. package/dist/core/auto-compaction.js +4 -2
  83. package/dist/core/auto-mode-arming.d.ts +2 -2
  84. package/dist/core/auto-mode-defaults.d.ts +8 -8
  85. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  86. package/dist/core/auto-mode-prompt.d.ts +1 -1
  87. package/dist/core/auto-mode.d.ts +17 -9
  88. package/dist/core/auto-mode.js +9 -6
  89. package/dist/core/background-agent-store.d.ts +3 -3
  90. package/dist/core/canonical-json.d.ts +1 -1
  91. package/dist/core/canonical-json.js +2 -2
  92. package/dist/core/checkpoint-generation.d.ts +53 -0
  93. package/dist/core/checkpoint-generation.js +35 -0
  94. package/dist/core/checkpoint-queries.d.ts +180 -0
  95. package/dist/core/checkpoint-queries.js +272 -0
  96. package/dist/core/checkpoint-requirements.d.ts +19 -4
  97. package/dist/core/checkpoint-requirements.js +8 -14
  98. package/dist/core/checkpoint-store.d.ts +165 -72
  99. package/dist/core/checkpoint-store.js +79 -82
  100. package/dist/core/child-clamp-seats.d.ts +6 -0
  101. package/dist/core/child-clamp-seats.js +3 -16
  102. package/dist/core/compliance.d.ts +2 -2
  103. package/dist/core/context-edit.d.ts +6 -7
  104. package/dist/core/cross-boundary-taint.d.ts +11 -4
  105. package/dist/core/cross-boundary-taint.js +3 -3
  106. package/dist/core/decision-receipt.d.ts +37 -3
  107. package/dist/core/decision-receipt.js +19 -19
  108. package/dist/core/delegation-not-started.d.ts +6 -0
  109. package/dist/core/delegation-not-started.js +17 -0
  110. package/dist/core/effective-path-target.d.ts +1 -1
  111. package/dist/core/engine-attestation.d.ts +93 -0
  112. package/dist/core/engine-attestation.js +70 -0
  113. package/dist/core/engine-capabilities.d.ts +4 -1
  114. package/dist/core/engine-capabilities.js +1 -1
  115. package/dist/core/engine-notice.d.ts +45 -12
  116. package/dist/core/exec-output-tail.d.ts +1 -1
  117. package/dist/core/file-history-retention.d.ts +1 -1
  118. package/dist/core/file-history-store.d.ts +147 -21
  119. package/dist/core/file-history-store.js +58 -32
  120. package/dist/core/gate-fold.d.ts +1 -1
  121. package/dist/core/gate-fold.js +24 -11
  122. package/dist/core/gate-lanes.js +81 -68
  123. package/dist/core/gate-outcome.d.ts +40 -6
  124. package/dist/core/gate-outcome.js +56 -0
  125. package/dist/core/governance-codes.d.ts +17 -3
  126. package/dist/core/governance-codes.js +16 -0
  127. package/dist/core/hands-band.d.ts +1 -1
  128. package/dist/core/hooks.d.ts +21 -20
  129. package/dist/core/hooks.js +3 -1
  130. package/dist/core/host-floor.d.ts +128 -0
  131. package/dist/core/host-floor.js +206 -0
  132. package/dist/core/host-target.d.ts +84 -0
  133. package/dist/core/host-target.js +92 -0
  134. package/dist/core/image-downsample.d.ts +1 -1
  135. package/dist/core/lsp-diagnostics.d.ts +4 -4
  136. package/dist/core/lsp.d.ts +3 -3
  137. package/dist/core/mailbox-store.d.ts +4 -0
  138. package/dist/core/mcp-connection-pool.d.ts +18 -2
  139. package/dist/core/mcp-connection-pool.js +53 -6
  140. package/dist/core/mcp-failure.d.ts +23 -4
  141. package/dist/core/mcp-failure.js +26 -11
  142. package/dist/core/mcp-listing-drift.d.ts +10 -0
  143. package/dist/core/mcp-listing-drift.js +6 -0
  144. package/dist/core/mcp-server-link.d.ts +173 -0
  145. package/dist/core/mcp-server-link.js +127 -0
  146. package/dist/core/mcp-server-spec.d.ts +4 -2
  147. package/dist/core/mcp-session-end.d.ts +26 -0
  148. package/dist/core/mcp-session-end.js +29 -0
  149. package/dist/core/mcp-startup-request.d.ts +17 -0
  150. package/dist/core/mcp-startup-request.js +17 -0
  151. package/dist/core/mcp.d.ts +17 -13
  152. package/dist/core/mcp.js +240 -189
  153. package/dist/core/media-byte-cap.d.ts +1 -1
  154. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  155. package/dist/core/memory-engine/engine.d.ts +9 -9
  156. package/dist/core/memory-engine/engine.js +4 -4
  157. package/dist/core/memory-engine/layout.d.ts +60 -8
  158. package/dist/core/memory-engine/layout.js +65 -6
  159. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  160. package/dist/core/memory-engine/tools.js +4 -1
  161. package/dist/core/mode-policy.d.ts +1 -1
  162. package/dist/core/model-seat.d.ts +10 -3
  163. package/dist/core/mods/classic-events.d.ts +67 -0
  164. package/dist/core/mods/classic-events.js +1 -0
  165. package/dist/core/mods/dollar.d.ts +13 -0
  166. package/dist/core/mods/extension-call.d.ts +31 -0
  167. package/dist/core/mods/extension-call.js +43 -0
  168. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  169. package/dist/core/mods/kernel/dispatch.js +140 -69
  170. package/dist/core/mods/kernel/events.d.ts +47 -11
  171. package/dist/core/mods/kernel/events.js +66 -42
  172. package/dist/core/mods/kernel/index.d.ts +4 -4
  173. package/dist/core/mods/kernel/index.js +2 -2
  174. package/dist/core/mods/kernel/receive.d.ts +39 -5
  175. package/dist/core/mods/kernel/receive.js +290 -17
  176. package/dist/core/mods/kernel/registration.d.ts +33 -2
  177. package/dist/core/mods/kernel/registration.js +6 -7
  178. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  179. package/dist/core/mods/kernel/site-rules.js +24 -42
  180. package/dist/core/mods/spec-seats.d.ts +69 -0
  181. package/dist/core/mods/spec-seats.js +114 -0
  182. package/dist/core/mods/stations.d.ts +28 -8
  183. package/dist/core/mods/stations.js +29 -13
  184. package/dist/core/mods/tool-call.d.ts +79 -0
  185. package/dist/core/mods/tool-call.js +152 -0
  186. package/dist/core/namespaced-rule-name.d.ts +44 -24
  187. package/dist/core/namespaced-rule-name.js +50 -43
  188. package/dist/core/output-style.d.ts +1 -1
  189. package/dist/core/param-rule-reach.d.ts +15 -0
  190. package/dist/core/param-rule-reach.js +30 -0
  191. package/dist/core/parent-spec-seat.d.ts +13 -1
  192. package/dist/core/parent-spec-seat.js +6 -0
  193. package/dist/core/park-selfcheck.js +1 -0
  194. package/dist/core/pause-registry.d.ts +16 -5
  195. package/dist/core/pause-registry.js +6 -2
  196. package/dist/core/peer-channel.d.ts +70 -0
  197. package/dist/core/peer-channel.js +1 -0
  198. package/dist/core/permission-rule-consent.d.ts +30 -5
  199. package/dist/core/permission-rule-consent.js +147 -50
  200. package/dist/core/permission-rule-model.d.ts +245 -65
  201. package/dist/core/permission-rule-model.js +421 -107
  202. package/dist/core/permission-rule-org.d.ts +6 -2
  203. package/dist/core/permission-rule-org.js +7 -3
  204. package/dist/core/permission-rule-provider.d.ts +6 -2
  205. package/dist/core/permission-rule-provider.js +41 -11
  206. package/dist/core/permission-rule-store.d.ts +22 -26
  207. package/dist/core/permission-rule-store.js +12 -6
  208. package/dist/core/permission-rule-sync.d.ts +11 -2
  209. package/dist/core/permission-rule-sync.js +11 -3
  210. package/dist/core/permission-rule-syntax.d.ts +5 -4
  211. package/dist/core/permission-rule-syntax.js +2 -2
  212. package/dist/core/permission-rules.d.ts +53 -15
  213. package/dist/core/permission-rules.js +125 -100
  214. package/dist/core/persisted-rule-arms.d.ts +6 -4
  215. package/dist/core/persisted-rule-arms.js +10 -12
  216. package/dist/core/present-plan-tool.js +3 -1
  217. package/dist/core/principal-name.d.ts +20 -0
  218. package/dist/core/principal-name.js +22 -0
  219. package/dist/core/prompt-section-seat.js +4 -6
  220. package/dist/core/protocol-http-auth.d.ts +26 -5
  221. package/dist/core/protocol-http-auth.js +137 -4
  222. package/dist/core/protocol-naming.d.ts +2 -2
  223. package/dist/core/read-only-shell-table.d.ts +1 -1
  224. package/dist/core/read-only-shell.d.ts +1 -1
  225. package/dist/core/retired-keys.d.ts +16 -0
  226. package/dist/core/retired-keys.js +16 -4
  227. package/dist/core/rewrite-rejudge.d.ts +60 -0
  228. package/dist/core/rewrite-rejudge.js +36 -0
  229. package/dist/core/roles.d.ts +34 -3
  230. package/dist/core/roles.js +66 -53
  231. package/dist/core/rule-lane-reads.d.ts +20 -15
  232. package/dist/core/rule-lane-reads.js +45 -17
  233. package/dist/core/rule-offer-read.d.ts +53 -0
  234. package/dist/core/rule-offer-read.js +146 -0
  235. package/dist/core/rule-owner.d.ts +46 -0
  236. package/dist/core/rule-owner.js +29 -0
  237. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  238. package/dist/core/runner/advisor-instructions.js +61 -0
  239. package/dist/core/runner/advisor-tool.d.ts +33 -0
  240. package/dist/core/runner/advisor-tool.js +112 -0
  241. package/dist/core/runner/announce-once-ledger.d.ts +18 -26
  242. package/dist/core/runner/announce-once-ledger.js +19 -46
  243. package/dist/core/runner/approval-feedback.js +6 -3
  244. package/dist/core/runner/assemble-result.d.ts +2 -1
  245. package/dist/core/runner/assemble-result.js +1 -1
  246. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  247. package/dist/core/runner/caller-roster.d.ts +21 -2
  248. package/dist/core/runner/caller-roster.js +38 -0
  249. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  250. package/dist/core/runner/capability-withheld-seat.js +24 -0
  251. package/dist/core/runner/classifier-ladder.d.ts +33 -13
  252. package/dist/core/runner/classifier-ladder.js +15 -14
  253. package/dist/core/runner/compaction-restate.d.ts +10 -6
  254. package/dist/core/runner/compaction-restate.js +9 -3
  255. package/dist/core/runner/construction-doors.js +3 -0
  256. package/dist/core/runner/contracts.d.ts +40 -33
  257. package/dist/core/runner/conversation-segment.d.ts +28 -0
  258. package/dist/core/runner/conversation-segment.js +42 -0
  259. package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
  260. package/dist/core/runner/cross-boundary-lane.js +58 -34
  261. package/dist/core/runner/decide-continuation.d.ts +7 -4
  262. package/dist/core/runner/decide-continuation.js +2 -2
  263. package/dist/core/runner/denial-limit-arms.d.ts +4 -4
  264. package/dist/core/runner/denial-limit-arms.js +1 -1
  265. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  266. package/dist/core/runner/derived-route-fallback.js +9 -7
  267. package/dist/core/runner/file-history-request.d.ts +18 -0
  268. package/dist/core/runner/file-history-request.js +21 -13
  269. package/dist/core/runner/file-history-restore.d.ts +45 -0
  270. package/dist/core/runner/file-history-restore.js +46 -0
  271. package/dist/core/runner/gate-exit.d.ts +9 -3
  272. package/dist/core/runner/gate-exit.js +11 -5
  273. package/dist/core/runner/image.d.ts +7 -17
  274. package/dist/core/runner/image.js +9 -60
  275. package/dist/core/runner/initial-run-state.js +1 -1
  276. package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
  277. package/dist/core/runner/permission-rule-lanes.js +38 -15
  278. package/dist/core/runner/person-path-rows.d.ts +12 -9
  279. package/dist/core/runner/person-path-rows.js +19 -8
  280. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  281. package/dist/core/runner/prepare-advisor.js +77 -0
  282. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  283. package/dist/core/runner/prepare-ask-lane.js +5 -2
  284. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  285. package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
  286. package/dist/core/runner/prepare-config-doors.d.ts +31 -38
  287. package/dist/core/runner/prepare-config-doors.js +57 -34
  288. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  289. package/dist/core/runner/prepare-defer-classify.js +7 -8
  290. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  291. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  292. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  293. package/dist/core/runner/prepare-file-history.js +41 -73
  294. package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
  295. package/dist/core/runner/prepare-gate-stations.js +12 -8
  296. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  297. package/dist/core/runner/prepare-hands-readface.js +15 -14
  298. package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
  299. package/dist/core/runner/prepare-inherited-gate.js +8 -6
  300. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  301. package/dist/core/runner/prepare-park-ask.js +12 -12
  302. package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
  303. package/dist/core/runner/prepare-policy-chain.js +68 -81
  304. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  305. package/dist/core/runner/prepare-project-context.js +6 -3
  306. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  307. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  308. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  309. package/dist/core/runner/prepare-prompt-inputs.js +4 -6
  310. package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
  311. package/dist/core/runner/prepare-protocol-tools.js +5 -4
  312. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  313. package/dist/core/runner/prepare-safety-scan.js +8 -23
  314. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  315. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  316. package/dist/core/runner/prepare-task.d.ts +1 -1
  317. package/dist/core/runner/prepare-task.js +41 -35
  318. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  319. package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
  320. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  321. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  322. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
  323. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  324. package/dist/core/runner/resume-admission.js +1 -1
  325. package/dist/core/runner/resume-apply.js +11 -12
  326. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  327. package/dist/core/runner/resume-claim.d.ts +4 -2
  328. package/dist/core/runner/resume-claim.js +15 -8
  329. package/dist/core/runner/resume-policy-outcome.js +1 -1
  330. package/dist/core/runner/retired-runner-deps.js +2 -1
  331. package/dist/core/runner/rewind-files.d.ts +15 -0
  332. package/dist/core/runner/rewind-files.js +132 -0
  333. package/dist/core/runner/run-attachment-seats.js +2 -2
  334. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  335. package/dist/core/runner/run-brain-sinks.js +4 -2
  336. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  337. package/dist/core/runner/run-compaction-machinery.js +2 -12
  338. package/dist/core/runner/run-git-lane.d.ts +1 -0
  339. package/dist/core/runner/run-harness-handlers.js +14 -7
  340. package/dist/core/runner/run-leg.d.ts +1 -1
  341. package/dist/core/runner/run-leg.js +43 -18
  342. package/dist/core/runner/run-settle-and-teardown.js +3 -2
  343. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  344. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  345. package/dist/core/runner/run-turn-boundary.js +15 -22
  346. package/dist/core/runner/runtask.d.ts +3 -0
  347. package/dist/core/runner/runtask.js +8 -9
  348. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  349. package/dist/core/runner/session-read-file-states.js +28 -0
  350. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  351. package/dist/core/runner/session-rule-policy.js +17 -31
  352. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  353. package/dist/core/runner/shell-env-withheld.js +51 -0
  354. package/dist/core/runner/side-call-account.d.ts +32 -8
  355. package/dist/core/runner/side-call-account.js +23 -1
  356. package/dist/core/runner/skills-seat.js +6 -2
  357. package/dist/core/runner/stream-settle-backstop.js +1 -1
  358. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  359. package/dist/core/runner/sub-agent-deny-lists.js +4 -6
  360. package/dist/core/runner/synthetic-tools.d.ts +16 -13
  361. package/dist/core/runner/synthetic-tools.js +8 -3
  362. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  363. package/dist/core/runner/tool-disclosure.js +3 -4
  364. package/dist/core/runner/tool-end-body.d.ts +1 -1
  365. package/dist/core/runner/tool-end-body.js +10 -9
  366. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  367. package/dist/core/runner/tool-face-overlay.js +17 -1
  368. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  369. package/dist/core/runner/tool-not-executed.js +11 -0
  370. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  371. package/dist/core/runner/tool-occurrence.js +7 -0
  372. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  373. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  374. package/dist/core/runner/turn-attachments.d.ts +91 -80
  375. package/dist/core/runner/turn-attachments.js +62 -37
  376. package/dist/core/runner-deps.d.ts +42 -42
  377. package/dist/core/runtime-caps.d.ts +4 -4
  378. package/dist/core/safety-axis-vocab.d.ts +6 -4
  379. package/dist/core/safety-axis-vocab.js +6 -5
  380. package/dist/core/safety-merge-corpus.js +26 -2
  381. package/dist/core/same-plain-value.d.ts +40 -0
  382. package/dist/core/same-plain-value.js +49 -0
  383. package/dist/core/scheduler.d.ts +1 -1
  384. package/dist/core/secret-env.d.ts +26 -3
  385. package/dist/core/secret-env.js +44 -8
  386. package/dist/core/select-model.js +3 -3
  387. package/dist/core/sensitive-path-policy.d.ts +1 -1
  388. package/dist/core/sensitive-path-policy.js +1 -1
  389. package/dist/core/session-policy-store.d.ts +102 -35
  390. package/dist/core/session-policy-store.js +210 -48
  391. package/dist/core/session-reconcile.d.ts +2 -2
  392. package/dist/core/session-store.d.ts +106 -37
  393. package/dist/core/session-store.js +165 -91
  394. package/dist/core/session.d.ts +101 -57
  395. package/dist/core/session.js +53 -0
  396. package/dist/core/shared-memory/tools.js +3 -1
  397. package/dist/core/shared-memory/types.d.ts +1 -1
  398. package/dist/core/shell-read-silence.d.ts +11 -12
  399. package/dist/core/shell-read-silence.js +9 -5
  400. package/dist/core/shell-run-candidates.js +3 -1
  401. package/dist/core/shell-wrapper-projection.js +1 -1
  402. package/dist/core/shell-wrapper-table.d.ts +14 -7
  403. package/dist/core/shell-wrapper-table.js +5 -4
  404. package/dist/core/side-query.d.ts +10 -0
  405. package/dist/core/side-query.js +15 -1
  406. package/dist/core/skill-grant.d.ts +7 -2
  407. package/dist/core/skill-grant.js +5 -0
  408. package/dist/core/skills-directory.js +6 -2
  409. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  410. package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
  411. package/dist/core/store-contracts/file-history-store-contract.js +74 -4
  412. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  413. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  414. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  415. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  416. package/dist/core/store-contracts/session-repo-contract.js +176 -0
  417. package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
  418. package/dist/core/store-contracts/session-store-contract.js +361 -51
  419. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  420. package/dist/core/stub-env.d.ts +2 -0
  421. package/dist/core/stub-env.js +1 -0
  422. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  423. package/dist/core/synthetic-read-verdict.js +3 -3
  424. package/dist/core/task-event.d.ts +42 -8
  425. package/dist/core/task-notification.d.ts +19 -15
  426. package/dist/core/task-registry-agent.d.ts +4 -4
  427. package/dist/core/task-registry-shared.d.ts +4 -4
  428. package/dist/core/task-registry-shared.js +1 -0
  429. package/dist/core/task-registry.d.ts +13 -4
  430. package/dist/core/task-registry.js +14 -2
  431. package/dist/core/task-result.d.ts +21 -3
  432. package/dist/core/task-spec.d.ts +69 -64
  433. package/dist/core/task-stream.d.ts +6 -6
  434. package/dist/core/task-tool-shape.d.ts +4 -4
  435. package/dist/core/tighten-task-spec.d.ts +1 -1
  436. package/dist/core/tighten-task-spec.js +2 -1
  437. package/dist/core/tool-catalog-entries.d.ts +36 -2
  438. package/dist/core/tool-catalog-entries.js +69 -43
  439. package/dist/core/tool-check-reading.d.ts +11 -0
  440. package/dist/core/tool-check-reading.js +11 -6
  441. package/dist/core/tool-conformance.js +1 -0
  442. package/dist/core/tool-errors.d.ts +2 -2
  443. package/dist/core/tool-face-reader.js +5 -3
  444. package/dist/core/tool-face.d.ts +21 -2
  445. package/dist/core/tool-face.js +1 -1
  446. package/dist/core/tool-model-gate.d.ts +5 -5
  447. package/dist/core/tool-name-aliases.d.ts +29 -8
  448. package/dist/core/tool-name-aliases.js +22 -4
  449. package/dist/core/tool-name-readings.d.ts +10 -43
  450. package/dist/core/tool-name-readings.js +2 -11
  451. package/dist/core/tool-policy.d.ts +85 -196
  452. package/dist/core/tool-policy.js +150 -175
  453. package/dist/core/tool-registry.d.ts +14 -7
  454. package/dist/core/tool-registry.js +17 -7
  455. package/dist/core/tool-result-store.js +5 -1
  456. package/dist/core/tool-roster.d.ts +57 -33
  457. package/dist/core/tool-roster.js +56 -68
  458. package/dist/core/tool-spec-members.js +8 -3
  459. package/dist/core/tool-spec.d.ts +53 -31
  460. package/dist/core/tools.js +51 -10
  461. package/dist/core/trace.d.ts +6 -2
  462. package/dist/core/types.d.ts +1 -1
  463. package/dist/core/untrusted-egress.d.ts +1 -1
  464. package/dist/core/untrusted-text.d.ts +1 -1
  465. package/dist/core/user-attachment.d.ts +8 -1
  466. package/dist/core/user-attachment.js +64 -4
  467. package/dist/core/warm-resume.d.ts +1 -1
  468. package/dist/core/wiring-manifest.d.ts +58 -0
  469. package/dist/core/wiring-manifest.js +14 -5
  470. package/dist/core/workflow-journal-store.d.ts +62 -0
  471. package/dist/core/workflow-journal-store.js +78 -2
  472. package/dist/core/workflow-run-store.d.ts +6 -0
  473. package/dist/core/workflow-run-store.js +2 -0
  474. package/dist/engine/compaction/compaction.d.ts +9 -9
  475. package/dist/engine/compaction/compaction.js +3 -2
  476. package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
  477. package/dist/engine/execution-env/node-execution-env.js +54 -24
  478. package/dist/engine/harness/agent-harness.d.ts +39 -9
  479. package/dist/engine/harness/agent-harness.js +87 -33
  480. package/dist/engine/harness/types.d.ts +58 -9
  481. package/dist/engine/harness/types.js +12 -1
  482. package/dist/engine/llm/types.d.ts +36 -19
  483. package/dist/engine/llm/validation.d.ts +4 -1
  484. package/dist/engine/llm/validation.js +13 -1
  485. package/dist/engine/loop/agent-loop.d.ts +23 -1
  486. package/dist/engine/loop/agent-loop.js +26 -34
  487. package/dist/engine/loop/types.d.ts +31 -19
  488. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  489. package/dist/engine/session/memory-repo.d.ts +18 -12
  490. package/dist/engine/session/memory-repo.js +24 -9
  491. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  492. package/dist/engine/session/parent-chain-guard.js +1 -1
  493. package/dist/engine/session/repo-utils.d.ts +32 -3
  494. package/dist/engine/session/repo-utils.js +50 -5
  495. package/dist/index.d.ts +47 -23
  496. package/dist/index.js +35 -17
  497. package/dist/internal/harness-types.d.ts +1 -1
  498. package/dist/internal/harness.d.ts +3 -3
  499. package/dist/internal/harness.js +2 -2
  500. package/dist/internal/llm.d.ts +2 -2
  501. package/dist/internal/llm.js +1 -1
  502. package/dist/orchestration/goal.js +2 -2
  503. package/dist/orchestration/run-workflow-tool.d.ts +8 -6
  504. package/dist/orchestration/run-workflow-tool.js +10 -6
  505. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  506. package/dist/orchestration/workflow-types.d.ts +18 -0
  507. package/dist/orchestration/workflow-types.js +6 -0
  508. package/dist/orchestration/workflow.d.ts +5 -13
  509. package/dist/orchestration/workflow.js +57 -49
  510. package/dist/prompt-assembly/artifact.d.ts +2 -2
  511. package/dist/prompt-assembly/artifact.js +5 -3
  512. package/dist/prompt-assembly/assemble.d.ts +3 -2
  513. package/dist/prompt-assembly/assemble.js +1 -1
  514. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  515. package/dist/prompt-assembly/catalog/schema.js +34 -2
  516. package/dist/prompt-assembly/catalog/sections.js +0 -1
  517. package/dist/prompt-assembly/composer.d.ts +3 -1
  518. package/dist/prompt-assembly/composer.js +1 -1
  519. package/dist/prompt-assembly/event-registry.js +2 -0
  520. package/dist/prompt-assembly/overlay.js +3 -3
  521. package/dist/prompt-assembly/renderers.d.ts +1 -1
  522. package/dist/prompt-assembly/renderers.js +0 -3
  523. package/dist/prompt-assembly/role-base.d.ts +15 -0
  524. package/dist/prompt-assembly/role-base.js +9 -0
  525. package/dist/prompt-assembly/select.d.ts +39 -14
  526. package/dist/prompt-assembly/select.js +47 -16
  527. package/dist/prompt-assembly/sugar.d.ts +17 -11
  528. package/dist/prompt-assembly/sugar.js +8 -3
  529. package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
  530. package/dist/prompt-assembly/tool-catalog.js +117 -4
  531. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  532. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  533. package/dist/prompt-assembly/types.d.ts +0 -7
  534. package/dist/prompts/default.d.ts +14 -14
  535. package/dist/scenarios/full-body.d.ts +15 -15
  536. package/dist/scenarios/full-body.js +4 -3
  537. package/dist/shell/lex.js +10 -1
  538. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  539. package/dist/stores/file/adoption/adopt.js +27 -33
  540. package/dist/stores/file/adoption/marker.d.ts +6 -13
  541. package/dist/stores/file/adoption/marker.js +9 -17
  542. package/dist/stores/file/checkpoint-store.d.ts +24 -0
  543. package/dist/stores/file/checkpoint-store.js +45 -7
  544. package/dist/stores/file/file-history-store.d.ts +20 -19
  545. package/dist/stores/file/file-history-store.js +157 -141
  546. package/dist/stores/file/fs-atomic.d.ts +15 -0
  547. package/dist/stores/file/fs-atomic.js +89 -14
  548. package/dist/stores/file/index.d.ts +1 -1
  549. package/dist/stores/file/index.js +2 -1
  550. package/dist/stores/file/mailbox-store.d.ts +3 -0
  551. package/dist/stores/file/mailbox-store.js +3 -1
  552. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  553. package/dist/stores/file/permission-rule-adopt.js +18 -18
  554. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  555. package/dist/stores/file/permission-rule-store.js +31 -18
  556. package/dist/stores/file/session-policy-store.d.ts +3 -3
  557. package/dist/stores/file/session-store.d.ts +54 -16
  558. package/dist/stores/file/session-store.js +114 -85
  559. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  560. package/dist/stores/file/workflow-journal-store.js +28 -13
  561. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  562. package/dist/tools/artifact/artifact-tool.js +5 -3
  563. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  564. package/dist/tools/fs/bash-program-position.js +56 -9
  565. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  566. package/dist/tools/fs/fs-bash.d.ts +2 -2
  567. package/dist/tools/fs/fs-bash.js +8 -6
  568. package/dist/tools/fs/fs-glob.d.ts +86 -0
  569. package/dist/tools/fs/fs-glob.js +226 -0
  570. package/dist/tools/fs/fs-read.js +14 -14
  571. package/dist/tools/fs/fs-search-tools.js +7 -7
  572. package/dist/tools/fs/fs-shared.d.ts +8 -8
  573. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  574. package/dist/tools/fs/notebook.d.ts +2 -2
  575. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  576. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  577. package/dist/tools/fs/pdf.d.ts +9 -6
  578. package/dist/tools/fs/pdf.js +3 -3
  579. package/dist/tools/fs/program-read-model.d.ts +57 -7
  580. package/dist/tools/fs/program-read-model.js +11 -1
  581. package/dist/tools/fs/program-read-model.rows.js +78 -21
  582. package/dist/tools/fs/read-deny-home.js +3 -2
  583. package/dist/tools/fs/read-deny.d.ts +29 -7
  584. package/dist/tools/fs/read-deny.js +63 -22
  585. package/dist/tools/fs/removal-targets.d.ts +18 -8
  586. package/dist/tools/fs/removal-targets.js +47 -20
  587. package/dist/tools/fs/safety.d.ts +9 -9
  588. package/dist/tools/fs/search.d.ts +16 -6
  589. package/dist/tools/fs/search.js +20 -26
  590. package/dist/tools/fs/shell-read-argv.js +89 -12
  591. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  592. package/dist/tools/fs/shell-read-bindings.js +41 -0
  593. package/dist/tools/fs/shell-read-check.js +12 -20
  594. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  595. package/dist/tools/fs/shell-read-environment.js +3 -2
  596. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  597. package/dist/tools/fs/shell-read-establish.js +19 -20
  598. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  599. package/dist/tools/fs/shell-read-judge.js +5 -2
  600. package/dist/tools/fs/shell-read-plan.js +24 -16
  601. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  602. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  603. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  604. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  605. package/dist/tools/fs/shell-reentry-text.js +40 -2
  606. package/dist/tools/loop-tick.d.ts +2 -2
  607. package/dist/tools/scheduler-tools.js +5 -1
  608. package/dist/tools/task-list.d.ts +7 -7
  609. package/dist/tools/task-list.js +5 -1
  610. package/dist/tools/todo.js +65 -64
  611. package/dist/tools/web.d.ts +20 -15
  612. package/dist/tools/web.js +55 -69
  613. package/dist/tools/worktree.d.ts +3 -3
  614. package/dist/tools/worktree.js +3 -1
  615. package/package.json +1 -1
  616. package/test/export-surface.snapshot.json +5894 -5638
  617. package/wire-changes/core@7.55.0.json +3318 -0
  618. package/wire-changes/core@7.56.0.json +3891 -0
  619. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  620. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  621. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -1,21 +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";
3
- import { arbitrateByMode, classifyAsk, decisionAskClassesOf, fileCommandOptionsSentence, persistedRuleMandateOf, safetyAxisOf, stampAskOrigin } from "./ask-origin.js";
2
+ import { attest, attestationOf, bindableArgsOf, decisionText, foldHookAsk, refusalOf, refuseOutOfContractDecision } from "./tool-policy.js";
3
+ import { outletAsk, readRejudge, rewriteChasedSentence, screenRewrite } from "./rewrite-rejudge.js";
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 { ASK_USER_QUESTION_TOOL_NAME, isEngineQuestionFace } from "./ask-question.js";
10
+ import { engineMountedAs } from "./tool-catalog-entries.js";
9
11
  import { applyPersistedTightening, disclosedRuleSet } from "./persisted-rule-arms.js";
10
12
  import { skillAllowDecision, skillRowRefusal } from "./skill-grant.js";
11
- import { allowRuleShadowOf } from "./allow-entry.js";
13
+ import { allowRuleShadowOf, withAllowRuleShadow } from "./allow-entry.js";
12
14
  import { CD_GIT_COMPOUND_SENTENCE, changesDirectoryBeforeGit, readOnlyShellVerdict } from "./read-only-shell.js";
13
15
  import { readShellCommand } from "./shell-run-candidates.js";
14
- import { COMMAND_RULE_TOOL } from "./permission-rule-model.js";
15
- import { catalogRuleFaceOf } from "./tool-registry.js";
16
+ import { COMMAND_RULE_TOOL, ruleShapeOf } from "./permission-rule-model.js";
17
+ import { catalogRuleFaceOf, isProtectedWrite } from "./tool-registry.js";
16
18
  import { callFaceSeat } from "./tool-roster.js";
17
- import { heldBy, wireOf } from "./tool-name-readings.js";
18
- import { asksUnstated, modeAcceptsFileCommand, permissionSeatAt, unstatedAskMessage } from "./mode-policy.js";
19
+ import { wireOf } from "./tool-name-readings.js";
20
+ import { modeAcceptsFileCommand } from "./mode-policy.js";
19
21
  import { ORG_RULE_DECISION_REASON, ORG_UNAVAILABLE_DECISION_REASON, orgUnreadableClause } from "./permission-rule-org.js";
20
22
  import { exitGate, passAskFace, untakenValueExit } from "./runner/gate-exit.js";
21
23
  import { readOrgRuleLane, readPersistedRuleLane } from "./rule-lane-reads.js";
@@ -23,9 +25,9 @@ import { traceHookCrash } from "./gate-crash-trace.js";
23
25
  import { createGateDeadline, awaitWriteProtectionJudgment, withGateTimeout } from "./gate-bounded-await.js";
24
26
  import { readStationAnswer } from "./shell-read-silence.js";
25
27
  import { agentIdOf, judgedInputOf, raiseToolCheck } from "./mods/stations.js";
26
- import { readToolChecks } from "./tool-check-reading.js";
28
+ import { extensionAllowOf, readToolChecks } from "./tool-check-reading.js";
27
29
  import { policyThrowLine, reportPolicyThrow } from "./runner/policy-throw.js";
28
- const QUESTION_TOOL_NAMES = new Set([ASK_USER_QUESTION_TOOL_NAME]);
30
+ const routesContent = engineMountedAs(["ask-user-question", "structured-output", "report-blocked"]);
29
31
  function parkWith(suspendAsk, parkArgs, carry) {
30
32
  return suspendAsk(...parkArgs, carry);
31
33
  }
@@ -80,7 +82,8 @@ export async function runGateLanes(pass) {
80
82
  });
81
83
  const readFaceNow = input.readFace?.();
82
84
  const askOriginFacts = (org, lane) => ({
83
- 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),
84
87
  markedUnresolvable: markedUnresolvable(),
85
88
  org,
86
89
  ...(ruleCallUnreadableOf(lane) ? { ruleCallUnreadable: true } : {}),
@@ -159,7 +162,7 @@ export async function runGateLanes(pass) {
159
162
  pass.decision = orgAnswer.decision;
160
163
  const readPersistedRules = (req) => readPersistedRuleLane(input.persistedRules, req, input.abortSignal);
161
164
  const laneReq = Object.freeze(pass.policyRewrite !== undefined ? await withArgsReading(pass.req, pass.policyRewrite, pass.callSignal ?? input.abortSignal) : { ...pass.req });
162
- const laneAnswer = input.persistedRules !== undefined && wireOf("lanes.persistedLaneSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME ? await readPersistedRules(laneReq) : undefined;
165
+ const laneAnswer = input.persistedRules !== undefined && !routesContent(pass.req.face) ? await readPersistedRules(laneReq) : undefined;
163
166
  {
164
167
  const tightened = applyPersistedTightening(pass.decision, laneAnswer, laneReq);
165
168
  pass.decision = tightened.tightened === "deny" ? refusalOf(tightened.decision, laneReq.args) : tightened.decision;
@@ -229,7 +232,7 @@ export async function runGateLanes(pass) {
229
232
  if (laneAnswer?.unreadable === true)
230
233
  personalEvidence = { dotsAbsent: "unavailable" };
231
234
  let laneCoverage;
232
- const questionTool = wireOf("lanes.allowLayerQuestionSkip", pass.req) === ASK_USER_QUESTION_TOOL_NAME;
235
+ const questionTool = originFacts.contentQuestion;
233
236
  const laneIsProvenance = orgAnswer.org === undefined &&
234
237
  pass.decision.action === "ask" &&
235
238
  pass.decision.requiresRealApproval !== true &&
@@ -269,10 +272,10 @@ export async function runGateLanes(pass) {
269
272
  });
270
273
  const storedAllows = laneAnswer?.hit?.behavior === "allow" ? laneAnswer.hit.rules : undefined;
271
274
  const members = [
272
- ["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)],
273
276
  ["deployment", () => {
274
277
  const hit = input.deploymentAllows?.allowing(pass.req, mode);
275
- return hit && { entries: hit.entries, 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") };
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") };
276
279
  }],
277
280
  ["persisted", () => storedAllows && {
278
281
  entries: storedAllows.map((r) => r.rule),
@@ -286,10 +289,18 @@ export async function runGateLanes(pass) {
286
289
  }],
287
290
  ["request", () => {
288
291
  const hit = input.requestAllows?.allowing(pass.req, mode);
289
- return hit && { entries: hit.entries, 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") };
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") };
290
293
  }],
291
294
  ];
292
- 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 = [];
293
304
  if (!questionTool) {
294
305
  for (const [member, match] of members) {
295
306
  if (pass.decision.action !== "ask")
@@ -298,13 +309,10 @@ export async function runGateLanes(pass) {
298
309
  if (hit === undefined)
299
310
  continue;
300
311
  if (allowMayClear()) {
301
- pass.decision = hit.clear();
302
- await hit.afterClear();
303
- if (member !== "hook")
304
- afterRuleClear();
312
+ pass.decision = await clearAs(member, hit);
305
313
  break;
306
314
  }
307
- shadows.push(allowRuleShadowOf(member, hit.entries));
315
+ shadows = withAllowRuleShadow(shadows, allowRuleShadowOf(member, hit.entries));
308
316
  hit.shadowed?.();
309
317
  }
310
318
  }
@@ -347,7 +355,7 @@ export async function runGateLanes(pass) {
347
355
  if (read?.kind === "denied")
348
356
  refuseByExtension(read.deny);
349
357
  else if (read?.kind === "cleared")
350
- pass.decision = read.allow;
358
+ pass.decision = await clearAs("hook", { entries: read.entries, clear: () => read.allow, afterClear: async () => undefined });
351
359
  else if (read?.kind === "asked") {
352
360
  const asked = read.minted ? { ...read.ask, ruleEvidence: mintRuleEvidence(personalEvidence) } : read.ask;
353
361
  if (read.marked === true)
@@ -356,7 +364,7 @@ export async function runGateLanes(pass) {
356
364
  pass.decision = stampAskOrigin(asked, facts, classifyStanding(asked, facts));
357
365
  }
358
366
  else if (read?.kind === "shadowed" && pass.decision.action === "ask")
359
- pass.decision = { ...pass.decision, allowRuleShadowed: [...(pass.decision.allowRuleShadowed ?? []), ...read.shadows] };
367
+ pass.decision = { ...pass.decision, allowRuleShadowed: read.shadows.reduce(withAllowRuleShadow, [...(pass.decision.allowRuleShadowed ?? [])]) };
360
368
  else if (read?.kind === "approved")
361
369
  takeApprovedEdit(read);
362
370
  }
@@ -413,7 +421,6 @@ export async function runGateLanes(pass) {
413
421
  }
414
422
  if (input.sandboxAdmission !== undefined &&
415
423
  pass.decision.action === "ask" &&
416
- wireOf("lanes.sandboxQuestionSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME &&
417
424
  input.isMarkedUnresolvable?.(input.event.toolCallId) !== true &&
418
425
  pass.decision.requiresRealApproval !== true &&
419
426
  pass.decision.decisionReason !== "hook" &&
@@ -468,7 +475,7 @@ export async function runGateLanes(pass) {
468
475
  pass.decision = refusalOf({
469
476
  action: "deny",
470
477
  message: verdict.mode === "dontAsk"
471
- ? `refused by the dontAsk permission mode: this call needed approval (${verdict.askClass}) and the mode answers no ask; run under a mode with an approver, or change the call`
478
+ ? dontAskRefusalMessage({ toolName, classification: pass.askClassification, coveredWrite: isProtectedWrite(pass.req), ruleShape: ruleShapeOf(pass.req, "allow") ?? toolName })
472
479
  : `refused by the bypassPermissions permission mode: the write-protection judge could not resolve this write's target, and with nobody to ask the mode refuses rather than releases it`,
473
480
  decisionReason: "mode",
474
481
  }, finalArgs);
@@ -480,7 +487,7 @@ export async function runGateLanes(pass) {
480
487
  if (parked)
481
488
  return parked;
482
489
  }
483
- if (pass.decision.action === "ask" && wireOf("lanes.contentAskRoute", pass.req) === ASK_USER_QUESTION_TOOL_NAME) {
490
+ if (pass.decision.action === "ask" && originFacts.contentQuestion) {
484
491
  const outcome = input.resolveContentAsk !== undefined ? await (callSignal !== undefined ? input.resolveContentAsk(pass.req, callSignal) : input.resolveContentAsk(pass.req)) : { kind: "unavailable", parkDeclined: false };
485
492
  if (outcome.kind === "answered") {
486
493
  pass.decision = { action: "allow" };
@@ -548,7 +555,6 @@ export async function runGateLanes(pass) {
548
555
  if (approvedWithArgs && pass.decision.action === "allow" && pass.decision.updatedInput !== undefined) {
549
556
  let editArgs = pass.decision.updatedInput;
550
557
  let editDenied;
551
- let editRewrittenSinceHuman = false;
552
558
  let editAnswer = pass.decision;
553
559
  let unanswered;
554
560
  const refusedAtResolution = (d) => { editDenied = d; pass.deniedBy = "ask_resolution"; };
@@ -571,6 +577,7 @@ export async function runGateLanes(pass) {
571
577
  break;
572
578
  }
573
579
  let editHookAsk;
580
+ let rewrittenEdit = false;
574
581
  if (screening !== undefined) {
575
582
  const screened = await screening.screen(editArgs, `the approved edit for "${toolName}"`);
576
583
  if (screened.kind === "refused") {
@@ -591,9 +598,10 @@ export async function runGateLanes(pass) {
591
598
  const { updatedInput: _adopted, ...ask } = hr;
592
599
  editHookAsk = ask;
593
600
  }
594
- if (hr.updatedInput !== undefined) {
595
- editArgs = argsAsTheToolReads(pass.req, hr.updatedInput);
596
- editRewrittenSinceHuman = true;
601
+ const hookRead = readRejudge(pass.req, editArgs, hr);
602
+ if (hookRead.kind === "rewritten") {
603
+ editArgs = hookRead.form;
604
+ rewrittenEdit = true;
597
605
  }
598
606
  }
599
607
  }
@@ -601,7 +609,7 @@ export async function runGateLanes(pass) {
601
609
  if (adjudicate) {
602
610
  try {
603
611
  const editReq = Object.freeze({ toolName, args: editArgs, toolCallId, ...(pass.req.face !== undefined ? { face: pass.req.face } : {}) });
604
- recheck = refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(editReq, callSignal) : adjudicate(editReq)));
612
+ recheck = refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(editReq, callSignal) : adjudicate(editReq)), { call: editReq });
605
613
  }
606
614
  catch (err) {
607
615
  reportPolicyThrow((e) => traceHookCrash(input, e, notifier), "the tool policy's re-check of the approved edit", { toolName, toolCallId }, err, callSignal ?? input.abortSignal);
@@ -624,9 +632,30 @@ export async function runGateLanes(pass) {
624
632
  break;
625
633
  }
626
634
  }
627
- if (recheck.updatedInput !== undefined) {
628
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
629
- 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
+ }
630
659
  }
631
660
  const editOrg = await applyOrgLayer(recheck, editArgs);
632
661
  recheck = editOrg.decision;
@@ -636,7 +665,7 @@ export async function runGateLanes(pass) {
636
665
  }
637
666
  let editLane;
638
667
  const editLaneReq = Object.freeze(await withArgsReading(pass.req, editArgs, callSignal ?? input.abortSignal));
639
- if (input.persistedRules !== undefined && wireOf("lanes.persistedEditSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME) {
668
+ if (input.persistedRules !== undefined && !routesContent(pass.req.face)) {
640
669
  editLane = await readPersistedRules(editLaneReq);
641
670
  const editTightened = applyPersistedTightening(recheck, editLane, editLaneReq);
642
671
  recheck = editTightened.decision;
@@ -653,21 +682,17 @@ export async function runGateLanes(pass) {
653
682
  pass.deniedBy = "policy";
654
683
  break;
655
684
  }
656
- if (recheck.action === "allow") {
657
- if (recheck.updatedInput !== undefined) {
658
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
659
- editRewrittenSinceHuman = true;
660
- }
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?.())) {
663
- recheck = { action: "ask", message: permissionSeatAt(input, editArgs)?.question ?? unstatedAskMessage(toolName) };
664
- 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;
665
692
  }
666
693
  }
667
- if (recheck.updatedInput !== undefined) {
668
- editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
669
- editRewrittenSinceHuman = true;
670
- }
694
+ if (rewrittenEdit)
695
+ recheck = outletAsk(recheck, toolName, editArgs);
671
696
  let editFacts;
672
697
  const stampEditAsk = (ask) => {
673
698
  const editAskSnapshot = { ...ask, ruleEvidence: mintRuleEvidence({ dotsAbsent: "not_adjudicated" }) };
@@ -683,7 +708,9 @@ export async function runGateLanes(pass) {
683
708
  if (carriedOwnAsk !== undefined) {
684
709
  const { updatedInput: _theOriginalBytes, ...carried } = carriedOwnAsk;
685
710
  const rra = carried.requiresRealApproval === true ? { requiresRealApproval: true } : {};
686
- 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);
687
714
  carriedOwnAsk = undefined;
688
715
  }
689
716
  const editRead = await checkTool(editDecision, editArgs, editOrg.org, undefined);
@@ -696,7 +723,6 @@ export async function runGateLanes(pass) {
696
723
  carriedOwnAsk = editRead.outstanding ?? (editDecision.action === "ask" ? editDecision : undefined);
697
724
  editArgs = editRead.allow.updatedInput;
698
725
  editAnswer = editRead.allow;
699
- editRewrittenSinceHuman = false;
700
726
  continue;
701
727
  }
702
728
  if (editRead?.kind === "asked" && editRead.marked === true)
@@ -704,13 +730,13 @@ export async function runGateLanes(pass) {
704
730
  if (editRead?.kind === "asked")
705
731
  editDecision = stampEditAsk(editRead.ask);
706
732
  else if (editRead?.kind === "shadowed" && editDecision.action === "ask")
707
- editDecision = { ...editDecision, allowRuleShadowed: [...(editDecision.allowRuleShadowed ?? []), ...editRead.shadows] };
733
+ editDecision = { ...editDecision, allowRuleShadowed: editRead.shadows.reduce(withAllowRuleShadow, [...(editDecision.allowRuleShadowed ?? [])]) };
708
734
  if (editDecision.action !== "ask")
709
735
  break;
710
736
  const editAskDecision = editDecision;
711
737
  if (input.permissionMode !== undefined && pass.askClassification !== undefined) {
712
738
  const editVerdict = arbitrateByMode(input.permissionMode(), pass.askClassification, { ...(editAskDecision.origin !== undefined ? { origin: editAskDecision.origin } : {}), ...(editAskDecision.mandate !== undefined ? { mandate: editAskDecision.mandate } : {}) });
713
- if (editVerdict.kind === "released") {
739
+ if (editVerdict.kind === "released" && !rewrittenEdit) {
714
740
  ledger.supersede();
715
741
  pass.arbitration = editVerdict;
716
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");
@@ -732,34 +758,21 @@ export async function runGateLanes(pass) {
732
758
  const rr = ledger.fromResolved(await (callSignal !== undefined ? resolveAsk(editAskDecision, editAskReq, callSignal) : resolveAsk(editAskDecision, editAskReq)), editAskDecision, editAskReq);
733
759
  if (rr.action !== "allow") {
734
760
  refusedAtResolution(rr);
761
+ if (rewrittenEdit)
762
+ pass.denyDetails = { editRewritten: { acceptableForm: editArgs } };
735
763
  if (rr.approverUnavailable === true)
736
764
  unanswered = { ask: editAskDecision, req: editAskReq, org: editOrg.org, deny: rr };
737
765
  break;
738
766
  }
739
767
  if (rr.updatedInput === undefined) {
740
- editRewrittenSinceHuman = false;
741
768
  break;
742
769
  }
743
770
  editArgs = rr.updatedInput;
744
771
  editAnswer = rr;
745
772
  if (editAskDecision.action === "ask")
746
773
  editAskedOrigin = editAskDecision.origin;
747
- editRewrittenSinceHuman = false;
748
774
  }
749
775
  const rejudged = () => editDenied === undefined || editDenied === unanswered?.deny;
750
- if (rejudged() && editRewrittenSinceHuman && input.writeProtectionCheck !== undefined) {
751
- const check = input.writeProtectionCheck;
752
- const verdict = await awaitWriteProtectionJudgment((deadline) => check(toolName, editArgs, pass.req.face, input.trackedCwd?.(), deadline), boundedAwaitDeadlineMs, callSignal ?? input.abortSignal);
753
- if (verdict !== undefined && verdict.kind !== "clear") {
754
- editDenied = {
755
- action: "deny",
756
- message: verdict.kind === "hit"
757
- ? `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`
758
- : `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`,
759
- };
760
- pass.deniedBy = "write_protection";
761
- }
762
- }
763
776
  if (rejudged() && input.shellReadCheck !== undefined) {
764
777
  const station = input.shellReadCheck;
765
778
  const judged = station.judge(pass.req, editArgs, input.trackedCwd?.(), callSignal ?? input.abortSignal, { seat: "rejudge", toolCallId });
@@ -9,6 +9,8 @@
9
9
  */
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
+ import { type AllowRuleClearance } from "./allow-rule-shadow.js";
13
+ import type { ResolvedOutcome } from "./checkpoint-store.js";
12
14
  /**
13
15
  * How the wait an ask was in ENDED — the closed set. One word per way a wait can end; the `who` on the
14
16
  * record says which party ended it and is fixed BY the word (see {@link Settlement}).
@@ -243,6 +245,18 @@ export declare const SETTLEMENT_NOBODY_JUDGED: {
243
245
  };
244
246
  /** Compile-time fence: `never` while every settlement kind has a nobody-judged row. */
245
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>>;
246
260
  /**
247
261
  * WHO REFUSED a call — the layer whose verdict is the deny. The other question a deny raises, "who ASKED",
248
262
  * is answered by {@link GateOutcome.origin} (an {@link import("./ask-origin.js").AskOrigin}); the two used
@@ -302,9 +316,9 @@ export type VetoTableCoversEveryDeniedBy = AssertAllKeysHandled<Exclude<DeniedBy
302
316
  * deny came through the classifier station. The classifier ends a round three ways, and until this
303
317
  * member the wire carried the three as one layer word plus prose:
304
318
  * - `unavailable` — the classifier could not run (the model leg threw / rejected / ran past the cap):
305
- * a fail-closed refusal that SAYS SO — the call may simply be retried later (CC 2.1.250 `x1t`);
319
+ * a fail-closed refusal that SAYS SO — the call may simply be retried later;
306
320
  * - `parse_error` — the classifier answered outside its verdict contract: blocked for safety, counted by
307
- * the denial limit like a ruling (CC 2.1.250 `Ure`);
321
+ * the denial limit like a ruling;
308
322
  * - ABSENT beside `deniedBy: "classifier"` — the classifier's own RULING (a `<block>yes` verdict).
309
323
  * The WHY behind an `unavailable` (error vs timeout) is not a branching fact: the deny sentence spells it
310
324
  * and the `auto_mode.classified` trace frame carries it (`cause: "error" | "timeout"`).
@@ -350,11 +364,19 @@ export type CauseTableCoversEveryDeniedBy = AssertAllKeysHandled<Exclude<DeniedB
350
364
  * candidate ladder and can name no model (a hand-built decider; a parked ancestor's cross-process rebuild,
351
365
  * whose single fresh leg has none); or one did not rule (it could not run, or replied with no verdict) and
352
366
  * 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. */
367
+ * Additive. Invariant I6 ({@link screenGateOutcome}) screens its shape.
368
+ *
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
371
+ * record is, with `positions` for a list member (the indices of those entries in the list the run received — a host maps them
372
+ * onto the declaration it sent for this run). Present exactly when an allow member cleared a standing ask and nobody answered
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
374
+ * sandbox's allow, and a person's yes. Additive. Invariant I9 ({@link screenGateOutcome}) screens its shape. */
354
375
  export type GateDisposition = {
355
376
  kind: "allowed";
356
377
  classifier?: AutoModeClassifierRound;
357
378
  released?: ModeRelease;
379
+ clearedBy?: AllowRuleClearance;
358
380
  } | {
359
381
  kind: "denied";
360
382
  deniedBy: DeniedBy;
@@ -395,7 +417,7 @@ export interface ModeRefusal {
395
417
  * payload, the call's `tool_end` frame, and the durable row's resolved outcome. The three faces are the
396
418
  * same object graph, so they cannot tell different stories.
397
419
  *
398
- * 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}):
399
421
  * I1 `settlement` present ⇔ `origin` present (they describe the same ask);
400
422
  * I2 `disposition.deniedBy === "ask_resolution"` ⇒ `settlement` present and a refusal kind;
401
423
  * I3 `settlement` an approval (a kind {@link SETTLEMENT_IS_REFUSAL} says is not a refusal) ∧
@@ -415,7 +437,15 @@ export interface ModeRefusal {
415
437
  * record outlives the policy of its day), every member of `classes` is an ask class, `origin` / `mandate` / `reason`,
416
438
  * when present, are members of their closed sets, and `reason` names a member of `classes` (the mint takes it from
417
439
  * that set) — a mode releases nothing a person answered;
418
- * I8 `deniedBy === "mode"` ⇔ `mode` present (`bypassPermissions` | `dontAsk`) with `askClass` and `classes`.
440
+ * I8 `deniedBy === "mode"` ⇔ `mode` present (`bypassPermissions` | `dontAsk`) with `askClass` and `classes`;
441
+ * I9 `disposition.clearedBy` present ⇒ `kind === "allowed"`, no settlement and no release (an allow member cleared the ask
442
+ * before anyone answered it), `member` one of the allow layer's members, `entries` a list of strings, `omitted` a positive
443
+ * whole number when present, and `positions` — only on a list member (`request`, `deployment`) — a list of non-negative
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.
419
449
  * Nothing here is read out of an ABSENCE: an ordinary allow with no ask is `{ disposition: { kind: "allowed" } }`,
420
450
  * a direct policy deny is `{ disposition: { kind: "denied", deniedBy: "policy" } }`, and neither carries a
421
451
  * settlement because neither settled one.
@@ -493,7 +523,7 @@ type DenyOnlyMember = Exclude<keyof Extract<GateDisposition, {
493
523
  /** Compile-time fence: `never` while the list is exactly the denied arm's own members. */
494
524
  export type DenyOnlyMembersAreListed = AssertAllKeysHandled<Exclude<DenyOnlyMember, (typeof DENY_ONLY_MEMBERS)[number]> | Exclude<(typeof DENY_ONLY_MEMBERS)[number], DenyOnlyMember>>;
495
525
  /**
496
- * 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:
497
527
  * - `"archive"` (the default) — a record read back from where it was kept (a replay, a ledger, a durable row): its shape, with
498
528
  * every closed set read as its live members plus {@link RETIRED_MEMBERS}. A record lawful when minted is not a defect later.
499
529
  * - `"producer"` — a record THIS engine is composing or publishing now: the live sets alone, and the engine's release law
@@ -501,10 +531,14 @@ export type DenyOnlyMembersAreListed = AssertAllKeysHandled<Exclude<DenyOnlyMemb
501
531
  * The record is read as whatever it holds (`unknown`): a member that is not the shape the type names — `null`, an array, a
502
532
  * primitive where a record belongs, an object where a word belongs — is a defect naming its position, never an exception, and
503
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.
504
537
  * Returns the defects as sentences (an empty list is a clean record); the caller decides the fail-loud form (report + withhold,
505
538
  * or refuse), never silently repairs the record. An options value that is not an object, or a reading outside the two, throws.
506
539
  */
507
540
  export declare function screenGateOutcome(g: unknown, opts?: {
508
541
  readonly reading?: "archive" | "producer";
542
+ readonly winnerDecision?: unknown;
509
543
  }): string[];
510
544
  export {};
@@ -1,5 +1,6 @@
1
1
  import { isAskClass, isAskOrigin, isModeReleaseReason, isPermissionMode, isPersistedRuleMandate, ASK_FACES, releasableAskClassesFor } from "./ask-origin.js";
2
2
  import { isAutoModeFallbackCause } from "./auto-mode.js";
3
+ import { ALLOW_RULE_MEMBERS } from "./allow-rule-shadow.js";
3
4
  export const SETTLEMENT_KINDS = Object.freeze([
4
5
  "human_allowed",
5
6
  "human_refused",
@@ -74,6 +75,16 @@ export const SETTLEMENT_NOBODY_JUDGED = {
74
75
  policy_refused: true,
75
76
  task_aborted: false,
76
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
+ }
77
88
  export const DENIED_BY_VALUES = Object.freeze(["policy", "hook", "org", "persisted_rule", "classifier", "compliance", "write_protection", "ask_resolution", "read_boundary", "mode"]);
78
89
  const DENIED_BY_SET = new Set(DENIED_BY_VALUES);
79
90
  export function isDeniedBy(v) {
@@ -153,6 +164,31 @@ export function releasePolicyDefects(g) {
153
164
  const held = [askClass, ...classes];
154
165
  return ASK_FACES.some((face) => held.every((c) => releasableAskClassesFor(face).includes(c))) ? [] : [`I7: released.classes ${JSON.stringify(classes)} is not a set one face of this engine's table releases`];
155
166
  }
167
+ const LIST_MEMBERS = new Set(["request", "deployment"]);
168
+ const ALLOW_MEMBER_SET = new Set(ALLOW_RULE_MEMBERS);
169
+ function clearanceDefects(v, settled, released) {
170
+ const c = objectOf(v);
171
+ if (c === undefined)
172
+ return [`I9: disposition.clearedBy is not an object (${shapeOf(v)})`];
173
+ const out = [];
174
+ if (settled)
175
+ out.push("I9: a clearance carries no settlement — an allow rule cleared the ask before anyone answered it");
176
+ if (released)
177
+ out.push("I9: a clearance stands beside no mode release — the ask it cleared never reached the mode");
178
+ if (!ALLOW_MEMBER_SET.has(c.member))
179
+ out.push(`I9: clearedBy.member ${spelled(c.member)} is not one of the allow layer's members (${ALLOW_RULE_MEMBERS.join(", ")})`);
180
+ if (!Array.isArray(c.entries) || !c.entries.every((e) => typeof e === "string"))
181
+ out.push("I9: clearedBy.entries must be a list of strings");
182
+ if (c.omitted !== undefined && !(typeof c.omitted === "number" && Number.isInteger(c.omitted) && c.omitted > 0))
183
+ out.push(`I9: clearedBy.omitted ${spelled(c.omitted)} is not a positive whole number`);
184
+ if (c.positions !== undefined) {
185
+ if (!LIST_MEMBERS.has(c.member))
186
+ out.push(`I9: clearedBy.positions stands only on a list member (request, deployment), not ${spelled(c.member)}`);
187
+ if (!Array.isArray(c.positions) || !c.positions.every((p) => typeof p === "number" && Number.isInteger(p) && p >= 0))
188
+ out.push("I9: clearedBy.positions must be a list of non-negative whole numbers");
189
+ }
190
+ return out;
191
+ }
156
192
  const DENY_ONLY_MEMBERS = Object.freeze(["deniedBy", "cause", "mode", "askClass", "classes"]);
157
193
  function objectOf(v) {
158
194
  return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
@@ -205,6 +241,8 @@ export function screenGateOutcome(g, opts) {
205
241
  const party = objectOf(s?.who)?.party;
206
242
  if (s !== undefined && !member("settlementParty", party))
207
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)`);
208
246
  if (record.origin !== undefined && !member("askOrigin", record.origin))
209
247
  defects.push(outside("origin", "askOrigin", record.origin));
210
248
  if (settled !== (record.origin !== undefined))
@@ -252,6 +290,10 @@ export function screenGateOutcome(g, opts) {
252
290
  defects.push(`I7: released.reason "${String(r.reason)}" is not a member of released.classes`);
253
291
  }
254
292
  }
293
+ if (denied !== undefined && denied.clearedBy !== undefined)
294
+ defects.push("I9: disposition.clearedBy stands only on an allowed disposition");
295
+ if (d !== undefined && d.clearedBy !== undefined)
296
+ defects.push(...clearanceDefects(d.clearedBy, settled, d.released !== undefined));
255
297
  if (denied !== undefined) {
256
298
  const modeRefusal = denied.deniedBy === "mode";
257
299
  if (modeRefusal !== (denied.mode !== undefined))
@@ -287,6 +329,20 @@ export function screenGateOutcome(g, opts) {
287
329
  }
288
330
  }
289
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
+ }
290
346
  if (producer)
291
347
  defects.push(...releasePolicyDefects(g));
292
348
  return defects;