@sema-agent/core 7.51.1 → 7.52.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 (372) hide show
  1. package/CHANGELOG.md +550 -2
  2. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  3. package/dist/agents/cascade.js +4 -0
  4. package/dist/agents/cumulative-stats.d.ts +3 -0
  5. package/dist/agents/cumulative-stats.js +3 -0
  6. package/dist/agents/list-agents-tool.d.ts +1 -1
  7. package/dist/agents/read-inbox-tool.d.ts +1 -1
  8. package/dist/agents/repair-loop.js +4 -0
  9. package/dist/agents/send-message-tool.d.ts +11 -16
  10. package/dist/agents/send-message-tool.js +11 -13
  11. package/dist/agents/subagent.d.ts +5 -0
  12. package/dist/agents/subagent.js +7 -4
  13. package/dist/agents/tool-filter.d.ts +40 -13
  14. package/dist/agents/tool-filter.js +28 -14
  15. package/dist/bench/metrics.d.ts +1 -0
  16. package/dist/brain/anthropic.js +16 -12
  17. package/dist/brain/model-presets.d.ts +4 -5
  18. package/dist/brain/model-presets.js +4 -4
  19. package/dist/brain/open-responses.js +16 -12
  20. package/dist/brain/openai.js +16 -12
  21. package/dist/brain/request-params.d.ts +12 -33
  22. package/dist/brain/request-params.js +5 -2
  23. package/dist/brain/request-route.d.ts +9 -8
  24. package/dist/brain/request-route.js +1 -0
  25. package/dist/brain/route-adjudicator.d.ts +117 -47
  26. package/dist/brain/route-adjudicator.js +171 -42
  27. package/dist/brain/route-conformance.js +2 -2
  28. package/dist/brain/status-sink.d.ts +18 -0
  29. package/dist/brain/status-sink.js +7 -0
  30. package/dist/core/allow-entry.d.ts +42 -8
  31. package/dist/core/allow-entry.js +24 -17
  32. package/dist/core/auto-compaction.d.ts +23 -20
  33. package/dist/core/auto-compaction.js +37 -16
  34. package/dist/core/auto-promote.d.ts +2 -1
  35. package/dist/core/auto-promote.js +2 -2
  36. package/dist/core/caller-tool-name.d.ts +9 -0
  37. package/dist/core/caller-tool-name.js +13 -0
  38. package/dist/core/checkpoint-requirements.d.ts +7 -1
  39. package/dist/core/checkpoint-requirements.js +2 -0
  40. package/dist/core/checkpoint-store.d.ts +36 -12
  41. package/dist/core/checkpoint-store.js +1 -1
  42. package/dist/core/child-clamp-seats.d.ts +6 -0
  43. package/dist/core/child-clamp-seats.js +2 -1
  44. package/dist/core/credential-vocabulary.d.ts +33 -8
  45. package/dist/core/credential-vocabulary.js +32 -7
  46. package/dist/core/decision-receipt.d.ts +2 -2
  47. package/dist/core/delegation-frames.d.ts +9 -2
  48. package/dist/core/delegation-name.d.ts +18 -0
  49. package/dist/core/delegation-name.js +47 -0
  50. package/dist/core/engine-capabilities.d.ts +8 -1
  51. package/dist/core/engine-capabilities.js +1 -1
  52. package/dist/core/engine-notice.d.ts +36 -19
  53. package/dist/core/frontmatter-fence.d.ts +10 -0
  54. package/dist/core/frontmatter-fence.js +6 -0
  55. package/dist/core/gate-fold.js +5 -23
  56. package/dist/core/gate-lanes.js +356 -270
  57. package/dist/core/governance-codes.d.ts +9 -4
  58. package/dist/core/governance-codes.js +9 -3
  59. package/dist/core/hooks.d.ts +276 -734
  60. package/dist/core/hooks.js +97 -192
  61. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  62. package/dist/{tools/fs → core}/image-admission.js +24 -6
  63. package/dist/core/locked-config.d.ts +26 -5
  64. package/dist/core/locked-config.js +31 -6
  65. package/dist/core/mcp-connection-pool.d.ts +4 -1
  66. package/dist/core/mcp-connection-pool.js +7 -2
  67. package/dist/core/mcp-probe.d.ts +12 -9
  68. package/dist/core/mcp-probe.js +2 -2
  69. package/dist/core/mcp-server-spec.d.ts +53 -7
  70. package/dist/core/mcp-server-spec.js +84 -1
  71. package/dist/core/mcp.d.ts +11 -7
  72. package/dist/core/mcp.js +27 -9
  73. package/dist/core/memory-engine/data-plane.js +5 -1
  74. package/dist/core/memory-engine/distiller.js +16 -2
  75. package/dist/core/memory-engine/engine.d.ts +8 -11
  76. package/dist/core/memory-engine/engine.js +9 -5
  77. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  78. package/dist/core/memory-engine/frontmatter.js +19 -16
  79. package/dist/core/memory.d.ts +2 -2
  80. package/dist/core/mode-policy.d.ts +4 -0
  81. package/dist/core/mode-policy.js +7 -5
  82. package/dist/core/model-seat.d.ts +4 -1
  83. package/dist/core/mods/dollar.d.ts +109 -0
  84. package/dist/core/mods/dollar.js +154 -0
  85. package/dist/core/mods/host.d.ts +23 -0
  86. package/dist/core/mods/host.js +21 -0
  87. package/dist/core/mods/kernel/budget.d.ts +43 -0
  88. package/dist/core/mods/kernel/budget.js +83 -0
  89. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  90. package/dist/core/mods/kernel/dispatch.js +701 -0
  91. package/dist/core/mods/kernel/events.d.ts +242 -0
  92. package/dist/core/mods/kernel/events.js +210 -0
  93. package/dist/core/mods/kernel/index.d.ts +6 -0
  94. package/dist/core/mods/kernel/index.js +5 -0
  95. package/dist/core/mods/kernel/receive.d.ts +65 -0
  96. package/dist/core/mods/kernel/receive.js +123 -0
  97. package/dist/core/mods/kernel/registration.d.ts +131 -0
  98. package/dist/core/mods/kernel/registration.js +102 -0
  99. package/dist/core/mods/kernel/site-rules.d.ts +84 -0
  100. package/dist/core/mods/kernel/site-rules.js +104 -0
  101. package/dist/core/mods/stations.d.ts +350 -0
  102. package/dist/core/mods/stations.js +444 -0
  103. package/dist/core/own-property-receipt.js +11 -23
  104. package/dist/core/parent-spec-seat.d.ts +18 -7
  105. package/dist/core/parent-spec-seat.js +6 -2
  106. package/dist/core/path-identity.js +2 -1
  107. package/dist/core/permission-rule-syntax.d.ts +15 -0
  108. package/dist/core/permission-rule-syntax.js +24 -16
  109. package/dist/core/permission-rules.d.ts +7 -1
  110. package/dist/core/permission-rules.js +26 -15
  111. package/dist/core/prompt-section-seat.d.ts +15 -27
  112. package/dist/core/prompt-section-seat.js +73 -40
  113. package/dist/core/protocol-http-auth.d.ts +3 -1
  114. package/dist/core/protocol-http-auth.js +2 -0
  115. package/dist/core/reminder-mint.d.ts +2 -2
  116. package/dist/core/remote-env.d.ts +24 -12
  117. package/dist/core/remote-env.js +1 -0
  118. package/dist/core/resume-startup-cause.d.ts +16 -1
  119. package/dist/core/resume-startup-cause.js +4 -1
  120. package/dist/core/retired-keys.d.ts +4 -0
  121. package/dist/core/retired-keys.js +3 -0
  122. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  123. package/dist/core/runner/announce-once-ledger.js +22 -0
  124. package/dist/core/runner/assemble-result.d.ts +9 -0
  125. package/dist/core/runner/assemble-result.js +3 -1
  126. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  127. package/dist/core/runner/call-hook-stations.js +58 -42
  128. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  129. package/dist/core/runner/caller-stop-gate.js +7 -0
  130. package/dist/core/runner/compaction-seams.d.ts +8 -22
  131. package/dist/core/runner/compaction-seams.js +28 -53
  132. package/dist/core/runner/construction-doors.js +11 -1
  133. package/dist/core/runner/contracts.d.ts +85 -83
  134. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  135. package/dist/core/runner/credential-origin-seat.js +19 -0
  136. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  137. package/dist/core/runner/gate-exit.d.ts +47 -36
  138. package/dist/core/runner/gate-exit.js +8 -2
  139. package/dist/core/runner/image.js +1 -2
  140. package/dist/core/runner/inline-image.js +1 -1
  141. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  142. package/dist/core/runner/notice-seat-input.js +1 -0
  143. package/dist/core/runner/person-path-rows.js +1 -0
  144. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  145. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  146. package/dist/core/runner/prepare-ask-lane.js +6 -15
  147. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  148. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  149. package/dist/core/runner/prepare-config-doors.d.ts +5 -0
  150. package/dist/core/runner/prepare-config-doors.js +9 -0
  151. package/dist/core/runner/prepare-defer-classify.js +3 -4
  152. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  153. package/dist/core/runner/prepare-gate-stations.js +11 -10
  154. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  155. package/dist/core/runner/prepare-inherited-gate.js +8 -21
  156. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  157. package/dist/core/runner/prepare-park-ask.js +10 -14
  158. package/dist/core/runner/prepare-policy-chain.d.ts +18 -16
  159. package/dist/core/runner/prepare-policy-chain.js +98 -101
  160. package/dist/core/runner/prepare-project-context.js +7 -10
  161. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  162. package/dist/core/runner/prepare-prompt-assembly.js +134 -101
  163. package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
  164. package/dist/core/runner/prepare-prompt-inputs.js +5 -7
  165. package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
  166. package/dist/core/runner/prepare-protocol-tools.js +2 -2
  167. package/dist/core/runner/prepare-safety-scan.js +6 -10
  168. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  169. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  170. package/dist/core/runner/prepare-task.js +33 -15
  171. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  172. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  173. package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
  174. package/dist/core/runner/prepare-wiring-manifest.js +7 -7
  175. package/dist/core/runner/resume-apply.d.ts +5 -2
  176. package/dist/core/runner/resume-apply.js +24 -42
  177. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  178. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  179. package/dist/core/runner/resume-preflight.js +38 -16
  180. package/dist/core/runner/retired-runner-deps.js +3 -1
  181. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  182. package/dist/core/runner/run-brain-sinks.js +5 -1
  183. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  184. package/dist/core/runner/run-compaction-machinery.js +7 -33
  185. package/dist/core/runner/run-harness-handlers.js +4 -2
  186. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  187. package/dist/core/runner/run-identity-wiring.js +3 -2
  188. package/dist/core/runner/run-leg.js +62 -84
  189. package/dist/core/runner/run-notification-lane.js +1 -0
  190. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  191. package/dist/core/runner/run-recovery-lanes.js +11 -10
  192. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  193. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  194. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  195. package/dist/core/runner/run-terminal-adoption.js +33 -22
  196. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  197. package/dist/core/runner/run-turn-boundary.js +23 -34
  198. package/dist/core/runner/runtask.d.ts +6 -7
  199. package/dist/core/runner/runtask.js +14 -72
  200. package/dist/core/runner/session-rule-policy.d.ts +6 -4
  201. package/dist/core/runner/session-rule-policy.js +17 -10
  202. package/dist/core/runner/side-call-account.d.ts +68 -0
  203. package/dist/core/runner/side-call-account.js +61 -0
  204. package/dist/core/runner/stream-halt-verbs.js +12 -17
  205. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  206. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  207. package/dist/core/runner/stream-steer-verb.js +20 -38
  208. package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
  209. package/dist/core/runner/sub-agent-deny-lists.js +228 -71
  210. package/dist/core/runner/tool-end-body.d.ts +5 -6
  211. package/dist/core/runner/tool-end-body.js +6 -4
  212. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  213. package/dist/core/runner/tool-not-executed.js +30 -0
  214. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  215. package/dist/core/runner/tool-occurrence.js +5 -5
  216. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  217. package/dist/core/runner-deps.d.ts +20 -28
  218. package/dist/core/safety-merge-corpus.js +18 -2
  219. package/dist/core/secret-env.d.ts +93 -20
  220. package/dist/core/secret-env.js +192 -38
  221. package/dist/core/session-policy-store.d.ts +93 -17
  222. package/dist/core/session-policy-store.js +178 -25
  223. package/dist/core/session-reconcile.d.ts +4 -0
  224. package/dist/core/session-reconcile.js +2 -1
  225. package/dist/core/shell-read-silence.js +3 -32
  226. package/dist/core/side-query.d.ts +5 -3
  227. package/dist/core/skill-grant.d.ts +3 -2
  228. package/dist/core/skill-grant.js +17 -9
  229. package/dist/core/skills-directory.d.ts +31 -11
  230. package/dist/core/skills-directory.js +655 -104
  231. package/dist/core/task-event.d.ts +13 -3
  232. package/dist/core/task-result.d.ts +8 -0
  233. package/dist/core/task-spec.d.ts +20 -19
  234. package/dist/core/task-stream.d.ts +14 -4
  235. package/dist/core/tighten-task-spec.d.ts +4 -3
  236. package/dist/core/tighten-task-spec.js +2 -4
  237. package/dist/core/tool-check-reading.d.ts +74 -0
  238. package/dist/core/tool-check-reading.js +80 -0
  239. package/dist/core/tool-policy.d.ts +59 -18
  240. package/dist/core/tool-policy.js +77 -12
  241. package/dist/core/tool-registry.d.ts +20 -0
  242. package/dist/core/tool-registry.js +4 -0
  243. package/dist/core/tool-spec.d.ts +10 -6
  244. package/dist/core/tools.js +2 -0
  245. package/dist/core/trace.d.ts +51 -32
  246. package/dist/core/types.d.ts +2 -1
  247. package/dist/core/types.js +1 -0
  248. package/dist/core/unc-spelling.d.ts +10 -0
  249. package/dist/core/unc-spelling.js +3 -0
  250. package/dist/core/untrusted-egress.d.ts +8 -0
  251. package/dist/core/untrusted-egress.js +4 -1
  252. package/dist/core/user-attachment.d.ts +12 -2
  253. package/dist/core/user-attachment.js +17 -2
  254. package/dist/core/wiring-manifest.d.ts +14 -13
  255. package/dist/core/wiring-manifest.js +2 -2
  256. package/dist/engine/compaction/utils.js +1 -2
  257. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  258. package/dist/engine/execution-env/symlink-chain.js +1 -1
  259. package/dist/engine/harness/agent-harness.d.ts +1 -1
  260. package/dist/engine/harness/agent-harness.js +3 -3
  261. package/dist/engine/harness/types.d.ts +17 -16
  262. package/dist/engine/harness/types.js +7 -1
  263. package/dist/engine/llm/types.d.ts +12 -7
  264. package/dist/engine/loop/agent-loop.js +1 -1
  265. package/dist/engine/loop/types.d.ts +1 -1
  266. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  267. package/dist/engine/session/import-validate.js +3 -10
  268. package/dist/engine/session/session.d.ts +4 -4
  269. package/dist/engine/session/session.js +4 -4
  270. package/dist/index.d.ts +24 -17
  271. package/dist/index.js +15 -12
  272. package/dist/internal/harness.d.ts +1 -1
  273. package/dist/internal/harness.js +1 -1
  274. package/dist/orchestration/run-spec.d.ts +4 -6
  275. package/dist/orchestration/run-spec.js +39 -63
  276. package/dist/orchestration/run-workflow-tool.js +1 -2
  277. package/dist/orchestration/workflow.d.ts +11 -3
  278. package/dist/orchestration/workflow.js +11 -2
  279. package/dist/prompt-assembly/artifact-store.d.ts +37 -56
  280. package/dist/prompt-assembly/artifact-store.js +31 -49
  281. package/dist/prompt-assembly/artifact.d.ts +89 -76
  282. package/dist/prompt-assembly/artifact.js +167 -146
  283. package/dist/prompt-assembly/assemble.d.ts +34 -29
  284. package/dist/prompt-assembly/assemble.js +33 -220
  285. package/dist/prompt-assembly/bands.d.ts +20 -0
  286. package/dist/prompt-assembly/bands.js +18 -0
  287. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  288. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  289. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  290. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  291. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  292. package/dist/prompt-assembly/catalog/index.js +59 -0
  293. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  294. package/dist/prompt-assembly/catalog/modes.js +137 -0
  295. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  296. package/dist/prompt-assembly/catalog/role.js +157 -0
  297. package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
  298. package/dist/prompt-assembly/catalog/schema.js +25 -0
  299. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  300. package/dist/prompt-assembly/catalog/sections.js +98 -0
  301. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  302. package/dist/prompt-assembly/catalog/team.js +258 -0
  303. package/dist/prompt-assembly/composer.d.ts +24 -28
  304. package/dist/prompt-assembly/composer.js +124 -46
  305. package/dist/prompt-assembly/epoch.d.ts +89 -79
  306. package/dist/prompt-assembly/epoch.js +115 -142
  307. package/dist/prompt-assembly/explain.d.ts +58 -34
  308. package/dist/prompt-assembly/explain.js +21 -24
  309. package/dist/prompt-assembly/overlay.d.ts +127 -0
  310. package/dist/prompt-assembly/overlay.js +301 -0
  311. package/dist/prompt-assembly/renderers.d.ts +21 -0
  312. package/dist/prompt-assembly/renderers.js +39 -0
  313. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  314. package/dist/prompt-assembly/section-usage.js +1 -1
  315. package/dist/prompt-assembly/select.d.ts +56 -0
  316. package/dist/prompt-assembly/select.js +69 -0
  317. package/dist/prompt-assembly/sugar.d.ts +31 -0
  318. package/dist/prompt-assembly/sugar.js +20 -0
  319. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  320. package/dist/prompt-assembly/types.d.ts +45 -148
  321. package/dist/prompts/coordinator.d.ts +2 -21
  322. package/dist/prompts/coordinator.js +3 -255
  323. package/dist/prompts/cowork.d.ts +27 -16
  324. package/dist/prompts/cowork.js +2 -23
  325. package/dist/prompts/default.d.ts +38 -500
  326. package/dist/prompts/default.js +20 -285
  327. package/dist/prompts/supervisor.d.ts +6 -71
  328. package/dist/prompts/supervisor.js +6 -117
  329. package/dist/stores/file/session-policy-store.d.ts +3 -3
  330. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  331. package/dist/tools/fs/dir-entries.d.ts +4 -2
  332. package/dist/tools/fs/dir-entries.js +16 -4
  333. package/dist/tools/fs/fs-bash.d.ts +1 -1
  334. package/dist/tools/fs/fs-bash.js +22 -11
  335. package/dist/tools/fs/fs-pdf.js +17 -13
  336. package/dist/tools/fs/fs-read.js +4 -3
  337. package/dist/tools/fs/fs-shared.d.ts +1 -10
  338. package/dist/tools/fs/fs-shared.js +3 -4
  339. package/dist/tools/fs/fs-write.js +2 -1
  340. package/dist/tools/fs/notebook.js +1 -1
  341. package/dist/tools/fs/pdf.d.ts +20 -10
  342. package/dist/tools/fs/pdf.js +19 -10
  343. package/dist/tools/fs/program-read-model.d.ts +68 -8
  344. package/dist/tools/fs/program-read-model.js +112 -33
  345. package/dist/tools/fs/program-read-model.rows.js +30 -10
  346. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  347. package/dist/tools/fs/read-deny-home.js +28 -27
  348. package/dist/tools/fs/read-deny.d.ts +41 -11
  349. package/dist/tools/fs/read-deny.js +51 -5
  350. package/dist/tools/fs/safety.d.ts +4 -26
  351. package/dist/tools/fs/safety.js +10 -32
  352. package/dist/tools/fs/search.js +15 -10
  353. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  354. package/dist/tools/fs/shell-read-argv.js +118 -38
  355. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  356. package/dist/tools/fs/shell-read-establish.js +11 -61
  357. package/dist/tools/fs/shell-read-identity.js +6 -3
  358. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  359. package/dist/tools/fs/shell-read-judge.js +18 -4
  360. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  361. package/dist/tools/web.js +1 -1
  362. package/package.json +13 -1
  363. package/test/export-surface.snapshot.json +256 -99
  364. package/wire-changes/core@7.51.1.json +5 -5
  365. package/wire-changes/core@7.51.2.json +293 -0
  366. package/wire-changes/core@7.52.0.json +5859 -0
  367. package/dist/core/hook-seats.d.ts +0 -66
  368. package/dist/core/hook-seats.js +0 -37
  369. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  370. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  371. package/dist/prompts/simple-sections.d.ts +0 -58
  372. package/dist/prompts/simple-sections.js +0 -43
@@ -1,4 +1,4 @@
1
- import { DEFAULT_COMPACTION_INSTRUCTIONS, maybeCompact } from "../auto-compaction.js";
1
+ import { DEFAULT_COMPACTION_INSTRUCTIONS, isCompactionManualCancel, maybeCompact } from "../auto-compaction.js";
2
2
  import { eventDefaultOn } from "../../prompt-assembly/event-registry.js";
3
3
  import { appendInterruptionMarker, reconcileInterruptedSession } from "../session-reconcile.js";
4
4
  import { emitTrace } from "../trace.js";
@@ -12,7 +12,7 @@ import { MAX_CONSECUTIVE_COMPACTION_FAILURES } from "./compaction-knobs.js";
12
12
  import { emitSettled, reconciledEnd } from "./tool-end-body.js";
13
13
  import { asThrownError, thrownText } from "../thrown-value.js";
14
14
  export async function runTerminalAdoption(input) {
15
- const { spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions, undrainedUserAtEnd, userInputLostAtEnd, final, abortedLive, userInterruptedLive, runner, sessions, next } = input;
15
+ const { spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions, undrainedUserAtEnd, userInputLostAtEnd, final, abortedLive, userInterruptedLive, callerStop, runner, sessions, next } = input;
16
16
  let { threw } = input;
17
17
  const settled = answerSettled(final, userInputLostAtEnd.current || prepared.undeliveredContinuationRef.current.parkedSteers.length > 0 || prepared.workCutRef.continuation || prepared.workCutRef.abortedBeforeTurnEnd);
18
18
  if (threw === undefined && prepared.brainCallGuardrailRef.timedOut !== undefined) {
@@ -115,12 +115,12 @@ export async function runTerminalAdoption(input) {
115
115
  }
116
116
  const comp = await finish(spec, prepared, {
117
117
  telemetry: { tracer: rs.telemetry.tracer, taskId: rs.telemetry.taskId },
118
- skipCompaction: durablyPaused || (abortedLive && settled) || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
118
+ skipCompaction: durablyPaused || (abortedLive && settled) || callerStop.signal.aborted || compactionBreaker.failures >= MAX_CONSECUTIVE_COMPACTION_FAILURES,
119
+ callerStop,
119
120
  minTokens: rs.counters.compactionFloor,
120
121
  brain: compactionBrain,
121
122
  windowSafety: windowSafetyOptions(prepared.harness.getModel()),
122
- onCompactionFailed: (reason) => queue.push({ type: "compaction_outcome", outcome: "failed", trigger: "auto", reason, ...ident() }),
123
- cancelled: abortedLive,
123
+ onCompactionOutcome: (outcome, reason) => queue.push({ type: "compaction_outcome", outcome, trigger: "auto", reason, ...ident() }),
124
124
  }, runner, sessions);
125
125
  return await next({ threw, comp, answerSettled: settled, owedUserInput });
126
126
  }
@@ -130,7 +130,7 @@ async function finish(spec, prepared, opts, runner, sessions) {
130
130
  try {
131
131
  const finishComp = await maybeCompact({
132
132
  session: prepared.session,
133
- epochDeclaredSections: prepared.epochDeclaredSections,
133
+ promptIdentity: prepared.promptIdentity,
134
134
  ...centerAdoptionOption(prepared),
135
135
  model: prepared.harness.getModel(),
136
136
  ...legContextOverlayOption(prepared, runner),
@@ -141,6 +141,8 @@ async function finish(spec, prepared, opts, runner, sessions) {
141
141
  thinking: prepared.thinking,
142
142
  settings: legCompactionSettings(spec, legContextOverlayOption(prepared, runner).contextOverlay),
143
143
  customInstructions: spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
144
+ signal: opts.callerStop.signal,
145
+ manualCancelSignal: opts.callerStop.signal,
144
146
  minTokens: opts?.minTokens,
145
147
  overheadTokens: prepared.promptOverheadTokens,
146
148
  ...(prepared.activeTools.size > 0 ? { activeTools: [...prepared.activeTools] } : {}),
@@ -151,10 +153,7 @@ async function finish(spec, prepared, opts, runner, sessions) {
151
153
  ...(prepared.onCompactionApplied ? { onApplied: prepared.onCompactionApplied } : {}),
152
154
  ...seamCCompactionOptions(runner, prepared),
153
155
  ...compactionRestateOptions(prepared),
154
- ...compactionHookOptions(runner, spec, prepared.sessionId, "auto", prepared.hookIdentity, {
155
- timeoutMs: prepared.hookTimeoutMs,
156
- ...(opts?.cancelled === true ? { signal: prepared.abortController.signal } : {}),
157
- }),
156
+ ...compactionHookOptions(runner, prepared, "auto", opts.callerStop.signal),
158
157
  });
159
158
  recordCompactionReuse(runner, prepared, finishComp);
160
159
  if (finishComp.unevaluableWindow) {
@@ -163,18 +162,30 @@ async function finish(spec, prepared, opts, runner, sessions) {
163
162
  comp = finishComp;
164
163
  }
165
164
  catch (err) {
166
- const failMsg = thrownText(err);
167
- const failReason = failMsg.length > 512 ? `${failMsg.slice(0, 512)}…` : failMsg;
168
- emitTrace(opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, () => ({
169
- kind: "compaction.failed",
170
- version: 1,
171
- taskId: opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId,
172
- trigger: "auto",
173
- reason: failReason,
174
- ts: Date.now(),
175
- }));
176
- opts?.onCompactionFailed?.(failReason);
177
- runner.deps.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
165
+ if (isCompactionManualCancel(err)) {
166
+ emitTrace(opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, () => ({
167
+ kind: "compaction.mooted",
168
+ version: 1,
169
+ taskId: opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId,
170
+ reason: "cancelled",
171
+ ts: Date.now(),
172
+ }));
173
+ opts?.onCompactionOutcome?.("mooted", "cancelled");
174
+ }
175
+ else {
176
+ const failMsg = thrownText(err);
177
+ const failReason = failMsg.length > 512 ? `${failMsg.slice(0, 512)}…` : failMsg;
178
+ emitTrace(opts?.telemetry?.tracer ?? spec.tracer ?? runner.deps.tracer, () => ({
179
+ kind: "compaction.failed",
180
+ version: 1,
181
+ taskId: opts?.telemetry?.taskId ?? spec.taskId ?? prepared.sessionId,
182
+ trigger: "auto",
183
+ reason: failReason,
184
+ ts: Date.now(),
185
+ }));
186
+ opts?.onCompactionOutcome?.("failed", failReason);
187
+ runner.deps.onError?.(err, { phase: "compaction", sessionId: prepared.sessionId });
188
+ }
178
189
  }
179
190
  }
180
191
  try {
@@ -21,11 +21,13 @@ export function runToolMountFacts(input) {
21
21
  emitTrace(rs.telemetry.tracer, () => ({ kind: "task.start", version: 1, taskId: rs.telemetry.taskId, runId: rs.telemetry.runId, model: prepared.model.id, engineVersion: engineVersion(), ts: rs.telemetry.taskStart }));
22
22
  emitTrace(rs.telemetry.tracer, () => ({
23
23
  kind: "prompt.assembled",
24
- version: 1,
24
+ version: 3,
25
25
  taskId: rs.telemetry.taskId,
26
- constitution: prepared.promptManifest.constitution,
26
+ identity: prepared.promptManifest.identity,
27
+ selectors: prepared.promptManifest.selectors,
27
28
  blocks: prepared.promptManifest.blocks,
28
- ...(prepared.promptManifest.sections ? { sections: prepared.promptManifest.sections } : {}),
29
+ sections: prepared.promptManifest.sections,
30
+ ...(prepared.promptManifest.superseded ? { superseded: prepared.promptManifest.superseded } : {}),
29
31
  ...(prepared.promptManifest.tools ? { tools: prepared.promptManifest.tools } : {}),
30
32
  ...(prepared.promptManifest.snapshot ? { snapshot: prepared.promptManifest.snapshot } : {}),
31
33
  ...(prepared.promptManifest.lowering ? { lowering: prepared.promptManifest.lowering } : {}),
@@ -7,7 +7,7 @@ import { redactThenCut } from "../../agents/subagent-steps.js";
7
7
  import { ATTACHMENT_BYTE_CAP, CHANGED_FILES_MAX, TOTAL_TOKENS_REMINDER_DEFAULT_MODE, attachmentEnvelopeTags, clipToBytes, collectDateChange, collectDueAttachments, collectInstructionsChange, commitAgentListing, commitInstructionsChange, commitSkillsListing, isIntactSource, rebaseCadenceWindows, renderAgentListingFrame, renderMcpDroppedTools, renderMcpInstructionsDelta, selectMcpDroppedBatch, renderSkillsListingFrame, renderToolsDelta } from "./turn-attachments.js";
8
8
  import { announceListingTruncation } from "../skill-listing-budget.js";
9
9
  import { buildWorkingFileAttachments, centerAdoptionOption, contextInstructionFilesOption, emitInputTruncated, forkContextOption, legCompactionSettings, legContextOverlayOption } from "./compaction-call-options.js";
10
- import { hookSeatExpiredError, runHookSeat } from "../hooks.js";
10
+ import { classicEventBase, dispatchClassic, stringMembersAnswer, stringMembersOf } from "../mods/stations.js";
11
11
  import { sanitizeUntrustedText, SHELLED_BODY_ENVELOPE_TAGS } from "../untrusted-text.js";
12
12
  import { droppedToolDigest, withAnnounceDigests } from "./announce-once-ledger.js";
13
13
  import { formatDiagnosticsBlock, withholdListedDiagnostics } from "../lsp-diagnostics.js";
@@ -23,7 +23,7 @@ const BATCH_CONTEXT_MIN_KEEP_BYTES = 160;
23
23
  const BATCH_TRUNCATION_MARKER = "\n…[truncated]";
24
24
  export function createTurnBoundary(input) {
25
25
  const { prepared, stats, rs, deps } = input;
26
- const { spec, queue, manualCompactRef, todoToolMounted, taskToolsMounted, walltimeMonotonicDeadline, timeout, ident, postToolBatchHook, batchArgs, compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact, runnerHooks, runner } = deps;
26
+ const { spec, queue, loopLatch: { callerStop }, manualCompactRef, todoToolMounted, taskToolsMounted, walltimeMonotonicDeadline, timeout, ident, postToolBatchArmed, batchArgs, compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact, runnerHooks, runner } = deps;
27
27
  let finalVerifySeenAtLastBoundary = 0;
28
28
  let legContinues = true;
29
29
  const boundaryPass = async (event) => {
@@ -464,35 +464,30 @@ export function createTurnBoundary(input) {
464
464
  let batchContextBlock;
465
465
  const finalVerifyInjectedThisTurn = rs.counters.finalVerifyInjections !== finalVerifySeenAtLastBoundary;
466
466
  finalVerifySeenAtLastBoundary = rs.counters.finalVerifyInjections;
467
- if (postToolBatchHook !== undefined && rs.turn.toolBatch.length > 0) {
467
+ if (postToolBatchArmed && rs.turn.toolBatch.length > 0) {
468
468
  const batch = rs.turn.toolBatch;
469
469
  rs.turn.toolBatch = [];
470
470
  batchArgs?.clear();
471
471
  const injectedThisTurn = finalVerifyInjectedThisTurn ? "final_verification" : undefined;
472
472
  if (!boundarySteered && !prepared.abortController.signal.aborted) {
473
- try {
474
- const batchSeat = await runHookSeat("postToolBatch", { timeoutMs: prepared.hookTimeoutMs, signal: prepared.abortController.signal }, (sig) => postToolBatchHook(batch, injectedThisTurn !== undefined ? { injectedThisTurn } : undefined, { identity: prepared.hookIdentity, permissionMode: prepared.permissionMode.observed, signal: sig }));
475
- if (batchSeat.expired) {
476
- runnerHooks.onError?.(hookSeatExpiredError("postToolBatch", prepared.hookTimeoutMs, batchSeat.cause, "the boundary observation was abandoned and its additionalContext dropped; the turn boundary itself is unchanged"), { phase: "hook", sessionId: prepared.sessionId });
477
- }
478
- const r = batchSeat.expired ? undefined : batchSeat.value;
479
- if (r?.additionalContext && injectedThisTurn === undefined) {
480
- const body = sanitizeUntrustedText(r.additionalContext, SHELLED_BODY_ENVELOPE_TAGS);
481
- const budget = ATTACHMENT_BYTE_CAP - boundaryAttachmentBytes;
482
- if (budget >= BATCH_CONTEXT_MIN_KEEP_BYTES) {
483
- const clipped = clipToBytes(body, budget) === body
484
- ? body
485
- : `${clipToBytes(body, budget - Buffer.byteLength(BATCH_TRUNCATION_MARKER, "utf8"))}${BATCH_TRUNCATION_MARKER}`;
486
- batchContextBlock = mintSystemReminder(clipped, prepared.reminderMark);
487
- }
488
- }
489
- }
490
- catch (err) {
473
+ const outcome = await dispatchClassic(prepared.modBus, "classic.PostToolBatch", { ...classicEventBase(prepared.hookIdentity, prepared.permissionMode.observed), batch, ...(injectedThisTurn !== undefined ? { injectedThisTurn } : {}) }, { signal: prepared.abortController.signal, checkAnswer: stringMembersAnswer("classic.PostToolBatch", ["additionalContext"]) }).catch((err) => {
491
474
  try {
492
475
  runnerHooks.onError?.(asThrownError(err), { phase: "hook", sessionId: prepared.sessionId });
493
476
  }
494
477
  catch {
495
478
  }
479
+ return undefined;
480
+ });
481
+ const r = outcome?.kind === "answered" ? stringMembersOf(outcome.answer, ["additionalContext"]) : undefined;
482
+ if (r?.additionalContext && injectedThisTurn === undefined) {
483
+ const body = sanitizeUntrustedText(r.additionalContext, SHELLED_BODY_ENVELOPE_TAGS);
484
+ const budget = ATTACHMENT_BYTE_CAP - boundaryAttachmentBytes;
485
+ if (budget >= BATCH_CONTEXT_MIN_KEEP_BYTES) {
486
+ const clipped = clipToBytes(body, budget) === body
487
+ ? body
488
+ : `${clipToBytes(body, budget - Buffer.byteLength(BATCH_TRUNCATION_MARKER, "utf8"))}${BATCH_TRUNCATION_MARKER}`;
489
+ batchContextBlock = mintSystemReminder(clipped, prepared.reminderMark);
490
+ }
496
491
  }
497
492
  }
498
493
  }
@@ -507,6 +502,7 @@ export function createTurnBoundary(input) {
507
502
  const forceManual = manualCompactRef.requested;
508
503
  if ((!withinTaskCompaction() && !forceManual) ||
509
504
  prepared.abortController.signal.aborted ||
505
+ callerStop.signal.aborted ||
510
506
  prepared.pausedRef.current !== undefined) {
511
507
  if (forceManual) {
512
508
  emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "task_ending", ts: Date.now() }));
@@ -553,14 +549,8 @@ export function createTurnBoundary(input) {
553
549
  w.resolve(outcome);
554
550
  };
555
551
  const claimedCancelSignals = claimedManual?.waiters.flatMap((w) => (w.signal !== undefined ? [w.signal] : [])) ?? [];
556
- const manualCancelSignal = claimedCancelSignals.length === 0
557
- ? undefined
558
- : claimedCancelSignals.length === 1
559
- ? claimedCancelSignals[0]
560
- : AbortSignal.any(claimedCancelSignals);
561
- const compactionPassSignal = claimedCancelSignals.length > 0
562
- ? AbortSignal.any([prepared.abortController.signal, ...claimedCancelSignals])
563
- : prepared.abortController.signal;
552
+ const manualCancelSignal = claimedCancelSignals.length === 0 ? callerStop.signal : AbortSignal.any([callerStop.signal, ...claimedCancelSignals]);
553
+ const compactionPassSignal = AbortSignal.any([prepared.abortController.signal, manualCancelSignal]);
564
554
  const trimPressureArmed = prepared.trimPressureRef.droppedMessages;
565
555
  if (trimPressureArmed)
566
556
  prepared.trimPressureRef.droppedMessages = false;
@@ -571,7 +561,7 @@ export function createTurnBoundary(input) {
571
561
  try {
572
562
  const comp = await maybeCompact({
573
563
  session: prepared.session,
574
- epochDeclaredSections: prepared.epochDeclaredSections,
564
+ promptIdentity: prepared.promptIdentity,
575
565
  ...centerAdoptionOption(prepared),
576
566
  model: event.model,
577
567
  ...legContextOverlayOption(prepared, runner),
@@ -583,7 +573,7 @@ export function createTurnBoundary(input) {
583
573
  settings: legCompactionSettings(spec, legContextOverlayOption(prepared, runner).contextOverlay),
584
574
  customInstructions: manualInstructions ?? spec.compaction?.instructions ?? DEFAULT_COMPACTION_INSTRUCTIONS,
585
575
  signal: compactionPassSignal,
586
- ...(manualCancelSignal !== undefined ? { manualCancelSignal } : {}),
576
+ manualCancelSignal,
587
577
  minTokens: forceManual ? 0 : rs.counters.compactionFloor,
588
578
  force: forceManual,
589
579
  onInputTruncated: emitInputTruncated(rs.telemetry.tracer, rs.telemetry.taskId),
@@ -596,7 +586,7 @@ export function createTurnBoundary(input) {
596
586
  ...seamCCompactionOptions(runner, prepared),
597
587
  ...compactionRestateOptions(prepared),
598
588
  ...windowSafetyOptions(event.model),
599
- ...compactionHookOptions(runner, spec, prepared.sessionId, passTrigger, prepared.hookIdentity, { timeoutMs: prepared.hookTimeoutMs, signal: prepared.abortController.signal }),
589
+ ...compactionHookOptions(runner, prepared, passTrigger, compactionPassSignal),
600
590
  });
601
591
  if (comp.blocked) {
602
592
  emitTrace(rs.telemetry.tracer, () => ({
@@ -678,8 +668,7 @@ export function createTurnBoundary(input) {
678
668
  }
679
669
  }
680
670
  catch (err) {
681
- const manualCancelAbort = !prepared.abortController.signal.aborted && isCompactionManualCancel(err);
682
- if (manualCancelAbort) {
671
+ if (isCompactionManualCancel(err)) {
683
672
  emitTrace(rs.telemetry.tracer, () => ({ kind: "compaction.mooted", version: 1, taskId: rs.telemetry.taskId, reason: "cancelled", ts: Date.now() }));
684
673
  queue.push({ type: "compaction_outcome", outcome: "mooted", trigger: passTrigger, reason: "cancelled", ...ident() });
685
674
  manualOutcome = "mooted";
@@ -88,13 +88,13 @@ export declare class Runner implements RunnerSelfSeat {
88
88
  * followed) against the seat and catalog in force, so a `swapDeps` reaches legs already running. */
89
89
  contextOverlayOf(ref: ModelRef | undefined): ContextWindowOverlay | undefined;
90
90
  /** The deployment-level gating baseline, exposed READ-ONLY so thin
91
- * assemblers over the Runner (`runSpec`) can COMPOSE with it. The task-level engine semantic is a
92
- * WHOLE-SLOT override (`spec.toolPolicy ?? deps.toolPolicy`, same for hooks — prepare-task), so any
93
- * assembler that sets `spec.toolPolicy`/`spec.hooks` without folding these in silently shadows the
94
- * deployment baseline. Getter only — nothing here is writable from outside. */
91
+ * assemblers over the Runner (`runSpec`) can COMPOSE with it. The task-level engine semantic for the policy is a
92
+ * WHOLE-SLOT override (`spec.toolPolicy ?? deps.toolPolicy` — prepare-task), so any assembler that sets
93
+ * `spec.toolPolicy` without folding this in silently shadows the deployment baseline. (The mods bus needs no
94
+ * baseline: its two seats run side by side, so an assembler's task registrations never shadow `deps.mods`.)
95
+ * Getter only — nothing here is writable from outside. */
95
96
  get gateBaseline(): {
96
97
  toolPolicy?: RunnerDeps["toolPolicy"];
97
- hooks?: RunnerDeps["hooks"];
98
98
  };
99
99
  /** Acquire the lock for a sessionId; returns a release fn. The one lock every leg holds on its session, from the moment it
100
100
  * knows the id to the leg's end (through `holdSessionLock` in `runTaskStream`, one per leg). */
@@ -122,8 +122,7 @@ export declare class Runner implements RunnerSelfSeat {
122
122
  * engine default); a key absent is kept. `tiers` omitted beside `models` ⇒ the current bindings are
123
123
  * re-applied over the new catalog.
124
124
  * - **Announced per seat.** `config.models_swapped` (models/tiers counts — key material only, never the
125
- * catalog itself; plus the advisory `route.base_url_changed_key_unchanged` for same-name entries
126
- * whose URL moved while the Model-visible credential fingerprint did not) and
125
+ * catalog itself) and
127
126
  * `config.read_face_swapped` / `config.write_face_swapped` (`{ from, to, occurrenceId }`, the seat's
128
127
  * previous and new value, `null` = no declaration) — the table {@link SWAP_SEAT_NOTICE} binds every
129
128
  * seat to its line.
@@ -7,7 +7,6 @@ import { createRapidRefillState } from "../auto-compaction.js";
7
7
  import { boundInputHashOf } from "../canonical-json.js";
8
8
  import { emitTrace } from "../trace.js";
9
9
  import { emitTaskOutcome } from "../task-outcome.js";
10
- import { authCarrierFingerprint, displayUrlOf, routeKeyOf } from "../../brain/route-adjudicator.js";
11
10
  import { runWithReasoningWireFacts } from "../../brain/status-sink.js";
12
11
  import { expandTiers } from "../roles.js";
13
12
  import { announceReadDenySwap, screenSwappableDeps } from "../swappable-deps.js";
@@ -142,48 +141,12 @@ export class Runner {
142
141
  }
143
142
  get gateBaseline() {
144
143
  const deps = this.deps;
145
- const h = deps.hooks;
146
- const hooks = h
147
- ? {
148
- ...(typeof h.preToolUse === "function" ? { preToolUse: (t, i, c) => h.preToolUse(t, i, c) } : {}),
149
- ...(typeof h.preToolUse === "function" && h.preToolUseObservational === true ? { preToolUseObservational: true } : {}),
150
- ...(typeof h.postToolUse === "function" ? { postToolUse: (t, i, o, c) => h.postToolUse(t, i, o, c) } : {}),
151
- ...(typeof h.userPromptSubmit === "function" ? { userPromptSubmit: (p, c) => h.userPromptSubmit(p, c) } : {}),
152
- ...(typeof h.stop === "function" ? { stop: (c) => h.stop(c) } : {}),
153
- ...(typeof h.postToolUseFailure === "function"
154
- ? { postToolUseFailure: (t, i, f, c) => h.postToolUseFailure(t, i, f, c) }
155
- : {}),
156
- ...(typeof h.postToolBatch === "function" ? { postToolBatch: (b, m, c) => h.postToolBatch(b, m, c) } : {}),
157
- ...(typeof h.preCompact === "function" ? { preCompact: (c) => h.preCompact(c) } : {}),
158
- ...(typeof h.postCompact === "function" ? { postCompact: (c) => h.postCompact(c) } : {}),
159
- ...(typeof h.stopFailure === "function" ? { stopFailure: (c) => h.stopFailure(c) } : {}),
160
- ...(typeof h.permissionDenied === "function" ? { permissionDenied: (p) => h.permissionDenied(p) } : {}),
161
- ...(h.timeoutMs !== undefined ? { timeoutMs: h.timeoutMs } : {}),
162
- }
163
- : undefined;
164
- const MIRRORED_HOOK_KEYS = [
165
- "preToolUse",
166
- "preToolUseObservational",
167
- "postToolUse",
168
- "userPromptSubmit",
169
- "stop",
170
- "postToolUseFailure",
171
- "postToolBatch",
172
- "preCompact",
173
- "postCompact",
174
- "stopFailure",
175
- "permissionDenied",
176
- "timeoutMs",
177
- ];
178
- const _mirrorIsComplete = true;
179
- void _mirrorIsComplete;
180
144
  return {
181
145
  ...(deps.toolPolicy !== undefined
182
146
  ? {
183
147
  toolPolicy: wrapToolPolicy(deps.toolPolicy, (req, signal) => deps.toolPolicy.check(req, signal)),
184
148
  }
185
149
  : {}),
186
- ...(hooks !== undefined ? { hooks } : {}),
187
150
  };
188
151
  }
189
152
  async acquireSessionLock(sessionId) {
@@ -210,19 +173,10 @@ export class Runner {
210
173
  const catalogSwap = seats.includes("models");
211
174
  let expanded;
212
175
  let tiers;
213
- const movedEntries = [];
214
176
  if (catalogSwap) {
215
177
  const models = candidate.models;
216
178
  tiers = Object.hasOwn(candidate, "tiers") ? candidate.tiers : this.deps.tiers;
217
179
  expanded = tiers && Object.keys(tiers).length > 0 ? expandTiers({ ...models }, tiers) : { ...models };
218
- for (const [name, nextModel] of Object.entries(expanded ?? {})) {
219
- const prior = this.deps.models?.[name];
220
- if (!prior)
221
- continue;
222
- if (routeKeyOf(prior.baseUrl) !== routeKeyOf(nextModel.baseUrl) && authCarrierFingerprint(prior.headers) === authCarrierFingerprint(nextModel.headers)) {
223
- movedEntries.push({ modelId: name, from: displayUrlOf(prior.baseUrl), to: displayUrlOf(nextModel.baseUrl) });
224
- }
225
- }
226
180
  }
227
181
  const faceSeats = ["readFace", "writeFace"].filter((seat) => seats.includes(seat));
228
182
  const priorFaces = {
@@ -254,18 +208,6 @@ export class Runner {
254
208
  message: `model catalog swapped: ${modelCount} model(s), ${tiers ? Object.keys(tiers).length : 0} tier binding(s); in-flight tasks finish on their resolved models, new tasks resolve against the new catalog`,
255
209
  detail: { models: modelCount, tiers: tiers ? Object.keys(tiers).length : 0, occurrenceId: uuidv7() },
256
210
  });
257
- if (movedEntries.length > 0) {
258
- const RENDER_CAP = 8;
259
- const rendered = movedEntries.slice(0, RENDER_CAP);
260
- deliverEngineNotice(this.deps.onNotice, {
261
- code: "route.base_url_changed_key_unchanged",
262
- message: `model catalog swap moved ${movedEntries.length} entry/entries to a new baseUrl while the Model-visible credential half stayed unchanged: ` +
263
- rendered.map((e) => `"${e.modelId}" ${e.from || "(config root)"} → ${e.to || "(config root)"}`).join("; ") +
264
- (movedEntries.length > rendered.length ? `; +${movedEntries.length - rendered.length} more` : "") +
265
- " — if the provider changed (not just its domain), update the credential reference in the same step",
266
- detail: { entries: rendered, total: movedEntries.length, occurrenceId: uuidv7() },
267
- });
268
- }
269
211
  }
270
212
  if (seats.includes("contextSettings")) {
271
213
  const to = candidate.contextSettings;
@@ -461,27 +403,27 @@ export class Runner {
461
403
  const { effectiveTimeoutMs, walltimeMonotonicDeadline, timeout, pushContent, ownCommittedTailRef, emitCommitted } = runClockAndContent({ spec, prepared, queue, internals, rs, ident, parentToolCallId, startedToolCallIds });
462
404
  const toolProgress = createToolProgressLane(pushContent, ident, prepared.toolOccurrences);
463
405
  prepared.toolProgressRef.current = toolProgress;
464
- const { withBrainSinks, withExtraBodyDroppedSink } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId } });
406
+ const { withBrainSinks, withLegRequestSinks } = runBrainSinks({ queue, internals, rs, ident, observeReasoningWireFacts, notice: { onNotice: this.deps.onNotice, sessionId: prepared.sessionId, runId: prepared.runId } });
465
407
  const toolLabels = new Map(prepared.tools.flatMap((t) => (t.label !== undefined && t.label !== t.name ? [[t.name, t.label]] : [])));
466
408
  for (const orphan of prepared.wakeRecovered) {
467
409
  emitSettled(prepared.toolOccurrences, { toolCallId: orphan.toolCallId, spelledName: orphan.toolName, ...(toolLabels.has(orphan.toolName) ? { label: toolLabels.get(orphan.toolName) } : {}), args: orphan.args }, reconciledEnd(orphan), { push: (f) => queue.push({ ...f, ...ident() }), structured: prepared.structuredProjector, mediaByteCapBytes: this.deps.mediaByteCapBytes });
468
410
  emitCommitted(orphan.entryId, "toolResult", orphan.toolCallId);
469
411
  }
470
- const postToolBatchHook = (spec.hooks ?? this.deps.hooks)?.postToolBatch;
471
- const batchArgs = postToolBatchHook ? new Map() : undefined;
412
+ const postToolBatchArmed = prepared.modBus.hasHandlers("classic.PostToolBatch");
413
+ const batchArgs = postToolBatchArmed ? new Map() : undefined;
472
414
  rs.turn.toolBatch = [];
473
415
  const { onMessageUpdate, onMessageEnd, onToolStart, onToolEnd, onTurnEnd, announceWorkspaceMove } = createHarnessHandlers({
474
416
  prepared, stats, rs,
475
417
  deps: {
476
418
  spec, queue, internals, ident, mediaByteCapBytes: this.deps.mediaByteCapBytes,
477
419
  pushContent, emitCommitted, startedToolCallIds, toolStartAt, toolProgress, writeFamilyOf,
478
- toolLabels, postToolBatchHook, batchArgs, internalsNotifier,
420
+ toolLabels, postToolBatchArmed, batchArgs, internalsNotifier,
479
421
  runnerHooks: { onError: (e, info) => this.deps.onError?.(e, info), onNotice: this.deps.onNotice },
480
422
  },
481
423
  });
482
- const { compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions } = runCompactionMachinery({ spec, prepared, rs, stats, noteUnevaluablePriceTable, runner: this.depsSeat });
424
+ const { compactionBrain, withinTaskCompaction, compactionBreaker, windowSafetyOptions } = runCompactionMachinery({ spec, prepared, rs, stats, noteUnevaluablePriceTable, modelCatalog, runner: this.depsSeat });
483
425
  runStopAndFinalVerify({ spec, prepared, queue, rs, stats, ident, walltimeMonotonicDeadline, runner: this.depsSeat });
484
- runRecoveryLanes({ spec, prepared, queue, rs, ident, compactionBrain, compactionBreaker, windowSafetyOptions, runner: this.depsSeat });
426
+ runRecoveryLanes({ spec, prepared, queue, rs, ident, compactionBrain, compactionBreaker, windowSafetyOptions, callerStop: loopLatch.callerStop, runner: this.depsSeat });
485
427
  const rapidRefill = createRapidRefillState();
486
428
  const drainManualCompact = (outcome) => {
487
429
  manualCompactRef.requested = false;
@@ -493,20 +435,20 @@ export class Runner {
493
435
  deps: {
494
436
  spec, queue, loopLatch, manualCompactRef, todoToolMounted, taskToolsMounted,
495
437
  walltimeMonotonicDeadline,
496
- timeout, ident, postToolBatchHook, batchArgs, compactionBrain, withinTaskCompaction,
438
+ timeout, ident, postToolBatchArmed, batchArgs, compactionBrain, withinTaskCompaction,
497
439
  compactionBreaker, windowSafetyOptions, rapidRefill, drainManualCompact,
498
440
  runnerHooks: { onError: this.deps.onError },
499
441
  runner: this.depsSeat,
500
442
  },
501
443
  });
502
444
  const { flushGitMirror, unsubGitRetry, unsubBoundary, unsub } = runGitLane({ prepared, queue, rs, ident, onMessageUpdate, onMessageEnd, onToolStart, onToolEnd, onTurnEnd, onTurnBoundary, runner: this.depsSeat });
503
- return withExtraBodyDroppedSink(() => runLeg({
445
+ return withLegRequestSinks(() => runLeg({
504
446
  spec, queue, prepared, resume, rs, entryActor, effectiveTimeoutMs, timeout, pushContent, ident, emitCommitted, writeFamilyOf, startedToolCallIds,
505
447
  announceWorkspaceMove, withBrainSinks, flushGitMirror, loopLatch, notificationLane, unsubscribeTaskNotifications, unsubGitRetry, unsubBoundary, unsub,
506
448
  runner: this.depsSeat,
507
449
  next: ({ final, threw, abortedLive, userInterruptedLive, strandedHumanAnswers }) => runTerminalAdoption({
508
450
  spec, queue, prepared, rs, stats, ident, emitCommitted, startedToolCallIds, toolLabels, timeout, compactionBrain, compactionBreaker, windowSafetyOptions,
509
- undrainedUserAtEnd, userInputLostAtEnd, final, threw, abortedLive, userInterruptedLive, runner: this.depsSeat, sessions: this.sessions,
451
+ undrainedUserAtEnd, userInputLostAtEnd, final, threw, abortedLive, userInterruptedLive, callerStop: loopLatch.callerStop, runner: this.depsSeat, sessions: this.sessions,
510
452
  next: ({ threw, comp, answerSettled, owedUserInput }) => runSettleAndTeardown({
511
453
  spec, queue, prepared, resume, internals, rs, stats, ident, loopLatch, timeout, ownCommittedTailRef,
512
454
  emitDelegationLifecycle, taskIdRef, manualCompactRef, drainManualCompact, final, threw, abortedLive, userInterruptedLive, answerSettled, strandedHumanAnswers, reasoningResolution, comp, compactionBreaker, owedUserInput,
@@ -548,7 +490,7 @@ export class Runner {
548
490
  const { config, internals, store, cp, outcomeGate, resumeSignal, wakeMessage } = admitted;
549
491
  const { plainReviewOutcome, plainParkOutcome } = resumeReviewOutcome({ cp, outcome, outcomeGate, wakeMessage });
550
492
  const { plainPolicyOutcome: capturedPolicyOutcome, redeemedAnswer } = resumePolicyOutcome({ cp, outcome, config, runner: this.depsSeat });
551
- const { resumeInternals } = resumeCheckpointScreen({ cp, resumeSignal, internals, runner: this.depsSeat });
493
+ const { resumeInternals } = resumeCheckpointScreen({ cp, resumeSignal, internals, tools: config.tools, runner: this.depsSeat });
552
494
  const { recheckGovernanceWindow, windowEntrance } = resumeInternalsAndConfig({ cp, config, internals, outcomeGate, runner: this.depsSeat });
553
495
  if (windowEntrance !== undefined)
554
496
  await windowEntrance;
@@ -556,19 +498,19 @@ export class Runner {
556
498
  cp, config, internals, outcomeGate, wakeMessage, resumeSignal, recheckGovernanceWindow,
557
499
  plainPolicyOutcome: capturedPolicyOutcome, plainReviewOutcome, plainParkOutcome,
558
500
  runner: this.depsSeat, effectiveDelegationFacts,
559
- next: ({ wakeHookContext, plainPolicyOutcome, outcomeForStore }) => resumePreflight({
501
+ next: ({ wakeHookContext, legMods, plainPolicyOutcome, outcomeForStore }) => resumePreflight({
560
502
  token, cp, resumeSignal, recheckGovernanceWindow, store, runner: this.depsSeat,
561
503
  locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry, suspendedEnvReaps: this.suspendedEnvReaps,
562
504
  next: () => resumeClaim({
563
505
  token, cp, store, outcomeForStore,
564
506
  locallyClaimedTokens: this.locallyClaimedTokens, parentConstraintRegistry: this.parentConstraintRegistry,
565
- next: () => this.resumeHandoff({ token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, resumeSignal }),
507
+ next: () => this.resumeHandoff({ token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, legMods, resumeSignal }),
566
508
  }),
567
509
  }),
568
510
  });
569
511
  }
570
512
  async resumeHandoff(claimed) {
571
- const { token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, resumeSignal } = claimed;
513
+ const { token, cp, store, config, internals, resumeInternals, plainPolicyOutcome, redeemedAnswer, outcomeForStore, wakeMessage, wakeHookContext, legMods, resumeSignal } = claimed;
572
514
  let consumeFlipDone = false;
573
515
  if (internals?.afterCheckpointResolve !== undefined) {
574
516
  await internals.afterCheckpointResolve();
@@ -616,7 +558,7 @@ export class Runner {
616
558
  ? new CheckpointError("checkpoint.reopen_failed", "the resume was aborted before the approved action could run AND the store refused to reopen the checkpoint — the approval is terminally consumed and the suspended work was not executed; a retry needs a fresh approval")
617
559
  : new CheckpointError("checkpoint.reopen_failed", "the resume was aborted before the approved action could run and the reopen attempt FAILED IN FLIGHT — the checkpoint's state is unprovable from here: it may already be pending again. Re-read it before deciding; do NOT issue a fresh approval on the assumption the old one is dead (the approved action did NOT run either way)");
618
560
  }
619
- return this.runTaskStream(spec, { cp, outcome: outcomeForStore, onEnvRestoreFailed, recordExecutionOutcome, ...(wakeMessage !== undefined ? { wakeMessage } : {}), ...(wakeHookContext !== undefined ? { wakeMessageHookContext: wakeHookContext } : {}) }, resumeInternals);
561
+ return this.runTaskStream(spec, { cp, outcome: outcomeForStore, onEnvRestoreFailed, recordExecutionOutcome, ...(wakeMessage !== undefined ? { wakeMessage } : {}), ...(wakeHookContext !== undefined ? { wakeMessageHookContext: wakeHookContext } : {}), ...(legMods !== undefined ? { legMods } : {}) }, resumeInternals);
620
562
  }
621
563
  }
622
564
  export function runTask(spec, deps) {
@@ -1,7 +1,7 @@
1
1
  import type { ExecutionEnv } from "../../internal/harness-types.js";
2
2
  import type { ToolEffect } from "../types.js";
3
3
  import type { NamedToolPolicy } from "../tool-policy.js";
4
- import { type SessionPermissionRules, type SessionPolicyStore, type StoredSessionRules } from "../session-policy-store.js";
4
+ import { type SessionPermissionRules, type SessionPolicyStore, type SessionRuleEntryField, type StoredSessionRules } from "../session-policy-store.js";
5
5
  import type { PathRuleBases } from "../permission-rule-model.js";
6
6
  /** The FULL path-confinable write-tool set: every catalog tool declaring a write path target — `Write` / `Edit`
7
7
  * (target `file_path`) and `NotebookEdit`, whose write target is `notebook_path` and is extracted by the shared
@@ -91,7 +91,7 @@ export interface SessionRuleSource {
91
91
  * the turn-boundary read-visibility query reuses one synthetic id for every path it screens and for every
92
92
  * turn of the run. The entry is taken ONCE, and a claimed snapshot is served only while its `rev` still
93
93
  * stands at the enforced floor; a claim from a later adjudication, whose floor has moved on, falls through
94
- * to a fresh read. A real tool call's id is minted per call and never repeats.
94
+ * to a fresh read. A real call's id is the provider's: unique within one assistant response only (`brain/tool-call-id.ts`).
95
95
  */
96
96
  export declare function createLiveSessionRules(store: SessionPolicyStore, floor: {
97
97
  sessionId: string;
@@ -111,8 +111,9 @@ export declare function createLiveSessionRules(store: SessionPolicyStore, floor:
111
111
  * (a line it cannot read against the rule is refused too), a path rule over every view of the call's target.
112
112
  * - `toolAllow` (if set) → deny any call no entry admits (the matcher's allow reading in the `narrowing` posture: every
113
113
  * segment of a command line named by an entry; never the allow layer's auto-mode strip), naming the uncovered segment.
114
- * - an entry that reads as nothing → in no row (it guards and grants nothing; the prepare-time audit names it).
115
- * - a snapshot the shape reading refuses → deny every call, saying what it holds (never its text).
114
+ * - an entry that reads as nothing → in no row (it guards and grants nothing; the prepare-time audit names it, or
115
+ * `onEarlierGrammar(entries, bucket, grammar)`, once per distinct set, when its snapshot's own earlier grammar reads it so).
116
+ * - a snapshot that cannot be read (its shape; a `toolDeny` entry no grammar reads) → deny every call, never quoting it.
116
117
  * - `allowDirs` (if set) → a WRITE tool must land inside one of the dirs (resolved via `canonicalizeTarget`,
117
118
  * so a symlink can't carry across a write out); a write-capable tool that cannot be path-confined (e.g. `bash`)
118
119
  * is DENIED while `allowDirs` is set (fail-closed).
@@ -131,4 +132,5 @@ export declare function createSessionRulePolicy(rules: SessionPermissionRules |
131
132
  rootPath?: string;
132
133
  toolEffects?: ReadonlyMap<string, ToolEffect>;
133
134
  anchors?: PathRuleBases;
135
+ onEarlierGrammar?: (entries: readonly string[], field: SessionRuleEntryField, grammar: number) => void;
134
136
  }): NamedToolPolicy;
@@ -1,6 +1,6 @@
1
1
  import { canonicalizeTarget, isWinFormPath, pathFamilyOf, writeTargetPath } from "../../tools/fs/safety.js";
2
- import { continuesLineage, readSessionRulesShape } from "../session-policy-store.js";
3
- import { compileAllowList, compiledEntryName, judgeAllowEntries, uncoveredCommandSegment } from "../allow-entry.js";
2
+ import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, continuesLineage, earlierGrammarAnnouncer, earlierGrammarRefusalClause, readSessionRulesShape, unreadableDenyEntries } from "../session-policy-store.js";
3
+ import { compiledEntryName, judgeAllowEntries, uncoveredCommandSegment } from "../allow-entry.js";
4
4
  import { inlineUntrusted } from "../untrusted-text.js";
5
5
  import { callTargetReadingOf, pathTargetBaseOf, readCallTarget } from "../effective-path-target.js";
6
6
  import { egressThrownText } from "../untrusted-egress.js";
@@ -106,24 +106,28 @@ export function createLiveSessionRules(store, floor, hooks) {
106
106
  }
107
107
  function compileSessionRules(rules) {
108
108
  const shaped = readSessionRulesShape(rules);
109
+ const refuseEvery = (what) => `the session rules cannot be read as rules (they hold ${what}) — every call is refused until they are rewritten`;
109
110
  if ("fault" in shaped) {
110
111
  const { field, got } = shaped.fault;
111
112
  const what = got === "not a rule bucket" ? "a key that is no rule bucket" : field === "" ? `a value that is ${got}, not an object of rule buckets` : `${field} holding ${got}`;
112
- return { deny: [], allow: undefined, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: `the session rules cannot be read as rules (they hold ${what}) — every call is refused until they are rewritten` };
113
+ return { deny: [], allow: undefined, earlier: { grammar: SESSION_RULES_GRAMMAR, toolAllow: [], toolDeny: [] }, allowDirs: undefined, pathRows: false, names: { deny: [], allow: [] }, unreadable: refuseEvery(what) };
113
114
  }
114
- const { toolDeny, toolAllow, allowDirs } = shaped.rules;
115
- const denyList = compileAllowList(toolDeny ?? [], "deny");
116
- const allowList = toolAllow === undefined ? undefined : compileAllowList(toolAllow, "allow");
115
+ const { toolAllow, allowDirs, grammar } = shaped.rules;
116
+ const unreadDeny = unreadableDenyEntries(shaped.rules).length;
117
+ const denyList = compileSessionRuleBucket(shaped.rules, "toolDeny");
118
+ const allowList = toolAllow === undefined ? undefined : compileSessionRuleBucket(shaped.rules, "toolAllow");
117
119
  const rowsOf = (behavior, list) => list.rows.map((r) => ({ behavior, entry: r.entry, compiled: r.compiled }));
118
120
  const deny = rowsOf("deny", denyList);
119
121
  const allow = allowList === undefined ? undefined : rowsOf("allow", allowList);
120
- const namesOf = (rows, list) => [...rows.map((r) => compiledEntryName(r.compiled)), ...(list?.inert ?? []).map((i) => i.entry)];
122
+ const named = (list, earlier) => (list?.inert ?? []).filter((i) => (i.reason === "earlier_grammar") === earlier).map((i) => i.entry);
121
123
  return {
122
124
  deny,
123
125
  allow,
126
+ earlier: { grammar, toolAllow: named(allowList, true), toolDeny: named(denyList, true) },
124
127
  allowDirs: allowDirs !== undefined && allowDirs.length > 0 ? allowDirs : undefined,
125
128
  pathRows: [...deny, ...(allow ?? [])].some((r) => r.compiled.kind === "path"),
126
- names: { deny: namesOf(deny, denyList), allow: namesOf(allow ?? [], allowList) },
129
+ names: { deny: [...deny.map((r) => compiledEntryName(r.compiled)), ...named(denyList, false)], allow: [...(allow ?? []).map((r) => compiledEntryName(r.compiled)), ...named(allowList, false)] },
130
+ ...(unreadDeny > 0 ? { unreadable: refuseEvery(`${unreadDeny === 1 ? "a toolDeny entry" : `${unreadDeny} toolDeny entries`} that rule grammar ${SESSION_RULES_GRAMMAR} reads as no rule`) } : {}),
127
131
  };
128
132
  }
129
133
  export function createSessionRulePolicy(rules, opts) {
@@ -132,11 +136,14 @@ export function createSessionRulePolicy(rules, opts) {
132
136
  const source = "seed" in rules ? rules : { seed: rules };
133
137
  const seed = source.seed;
134
138
  const readRules = source.read ?? (() => Promise.resolve(seed));
139
+ const announceEarlier = earlierGrammarAnnouncer(opts.onEarlierGrammar);
135
140
  let compiledFor;
136
141
  let compiled;
137
142
  const compile = (r) => {
138
143
  if (compiled === undefined || compiledFor !== r) {
139
144
  compiled = compileSessionRules(r);
145
+ for (const field of ["toolAllow", "toolDeny"])
146
+ announceEarlier(compiled.earlier[field], field, compiled.earlier.grammar);
140
147
  compiledFor = r;
141
148
  }
142
149
  return compiled;
@@ -145,7 +152,7 @@ export function createSessionRulePolicy(rules, opts) {
145
152
  return {
146
153
  nameSets: [{ ...(seedNames.deny.length > 0 ? { deny: seedNames.deny } : {}), ...(seedNames.allow.length > 0 ? { allow: seedNames.allow } : {}) }],
147
154
  async check(req, signal) {
148
- const { deny: denyRows, allow: allowRows, allowDirs, unreadable, pathRows } = compile(await readRules(req.toolCallId, signal));
155
+ const { deny: denyRows, allow: allowRows, earlier, allowDirs, unreadable, pathRows } = compile(await readRules(req.toolCallId, signal));
149
156
  if (unreadable !== undefined)
150
157
  return deny(req.toolName, unreadable);
151
158
  if (denyRows.length > 0 || allowRows !== undefined) {
@@ -157,7 +164,7 @@ export function createSessionRulePolicy(rules, opts) {
157
164
  return deny(req.toolName);
158
165
  if (allowRows !== undefined && judgeAllowEntries(allowRows, call, "allow", judged, "narrowing") === undefined) {
159
166
  const segment = uncoveredCommandSegment(allowRows, call, judged, "narrowing");
160
- return deny(req.toolName, segment === undefined ? "it is not in the session-rule allowlist" : `it is not in the session-rule allowlist (no entry covers ${JSON.stringify(inlineUntrusted(segment, 200))})`);
167
+ return deny(req.toolName, `it is not in the session-rule allowlist${segment === undefined ? "" : ` (no entry covers ${JSON.stringify(inlineUntrusted(segment, 200))})`}${earlierGrammarRefusalClause(earlier.toolAllow, earlier.grammar)}`);
161
168
  }
162
169
  }
163
170
  if (allowDirs) {