@sema-agent/core 7.55.0 → 7.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/dist/agents/cascade.js +1 -1
  3. package/dist/agents/cc-peer-directory.js +1 -0
  4. package/dist/agents/child-model-seat.d.ts +0 -11
  5. package/dist/agents/child-model-seat.js +0 -3
  6. package/dist/agents/list-agents-tool.d.ts +3 -1
  7. package/dist/agents/list-agents-tool.js +7 -7
  8. package/dist/agents/peer-directory.d.ts +22 -4
  9. package/dist/agents/peer-directory.js +24 -2
  10. package/dist/agents/peer-session-drain.js +2 -2
  11. package/dist/agents/repair-loop.js +2 -2
  12. package/dist/agents/send-message-tool.js +4 -4
  13. package/dist/agents/subagent.d.ts +6 -4
  14. package/dist/agents/subagent.js +64 -60
  15. package/dist/agents/tool-filter.d.ts +7 -5
  16. package/dist/agents/tool-filter.js +12 -9
  17. package/dist/agents/verify.d.ts +3 -2
  18. package/dist/agents/verify.js +3 -3
  19. package/dist/brain/anthropic.js +30 -73
  20. package/dist/brain/media-degrade.d.ts +18 -7
  21. package/dist/brain/media-degrade.js +13 -2
  22. package/dist/brain/model-capability.d.ts +37 -0
  23. package/dist/brain/model-capability.js +34 -0
  24. package/dist/brain/model-presets.d.ts +2 -8
  25. package/dist/brain/model-presets.js +1 -6
  26. package/dist/brain/open-responses.js +13 -26
  27. package/dist/brain/openai.js +14 -87
  28. package/dist/brain/reasoning-request.d.ts +96 -0
  29. package/dist/brain/reasoning-request.js +174 -0
  30. package/dist/brain/reasoning.d.ts +11 -11
  31. package/dist/brain/reasoning.js +4 -3
  32. package/dist/brain/request-params.d.ts +7 -4
  33. package/dist/brain/request-params.js +7 -4
  34. package/dist/brain/status-sink.d.ts +20 -0
  35. package/dist/brain/status-sink.js +7 -0
  36. package/dist/core/a2a.d.ts +2 -1
  37. package/dist/core/a2a.js +19 -13
  38. package/dist/core/agent-definition.d.ts +10 -0
  39. package/dist/core/allow-entry.d.ts +20 -13
  40. package/dist/core/allow-entry.js +26 -22
  41. package/dist/core/allow-rule-shadow.d.ts +3 -3
  42. package/dist/core/ask-origin.d.ts +64 -18
  43. package/dist/core/ask-origin.js +63 -23
  44. package/dist/core/ask-question.d.ts +51 -8
  45. package/dist/core/ask-question.js +3 -4
  46. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  47. package/dist/core/ask-unresolvable-notice.js +16 -2
  48. package/dist/core/checkpoint-generation.d.ts +53 -0
  49. package/dist/core/checkpoint-generation.js +35 -0
  50. package/dist/core/checkpoint-queries.d.ts +180 -0
  51. package/dist/core/checkpoint-queries.js +272 -0
  52. package/dist/core/checkpoint-requirements.d.ts +13 -1
  53. package/dist/core/checkpoint-requirements.js +4 -0
  54. package/dist/core/checkpoint-store.d.ts +88 -24
  55. package/dist/core/checkpoint-store.js +24 -9
  56. package/dist/core/cross-boundary-taint.d.ts +6 -5
  57. package/dist/core/cross-boundary-taint.js +1 -3
  58. package/dist/core/decision-receipt.d.ts +37 -3
  59. package/dist/core/decision-receipt.js +17 -17
  60. package/dist/core/delegation-not-started.d.ts +6 -0
  61. package/dist/core/delegation-not-started.js +17 -0
  62. package/dist/core/engine-attestation.d.ts +93 -0
  63. package/dist/core/engine-attestation.js +70 -0
  64. package/dist/core/engine-capabilities.d.ts +4 -1
  65. package/dist/core/engine-capabilities.js +1 -1
  66. package/dist/core/engine-notice.d.ts +30 -11
  67. package/dist/core/file-history-store.d.ts +90 -14
  68. package/dist/core/file-history-store.js +23 -15
  69. package/dist/core/gate-fold.d.ts +1 -1
  70. package/dist/core/gate-fold.js +22 -10
  71. package/dist/core/gate-lanes.js +73 -64
  72. package/dist/core/gate-outcome.d.ts +26 -5
  73. package/dist/core/gate-outcome.js +26 -0
  74. package/dist/core/governance-codes.d.ts +5 -1
  75. package/dist/core/governance-codes.js +6 -0
  76. package/dist/core/hooks.d.ts +17 -16
  77. package/dist/core/hooks.js +3 -1
  78. package/dist/core/host-floor.d.ts +128 -0
  79. package/dist/core/host-floor.js +206 -0
  80. package/dist/core/host-target.d.ts +38 -3
  81. package/dist/core/host-target.js +38 -5
  82. package/dist/core/mcp.d.ts +5 -1
  83. package/dist/core/mcp.js +67 -41
  84. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  85. package/dist/core/memory-engine/engine.js +4 -4
  86. package/dist/core/memory-engine/layout.d.ts +60 -8
  87. package/dist/core/memory-engine/layout.js +65 -6
  88. package/dist/core/model-seat.d.ts +10 -3
  89. package/dist/core/mods/classic-events.d.ts +67 -0
  90. package/dist/core/mods/classic-events.js +1 -0
  91. package/dist/core/mods/dollar.d.ts +13 -0
  92. package/dist/core/mods/extension-call.d.ts +31 -0
  93. package/dist/core/mods/extension-call.js +43 -0
  94. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  95. package/dist/core/mods/kernel/dispatch.js +140 -69
  96. package/dist/core/mods/kernel/events.d.ts +47 -11
  97. package/dist/core/mods/kernel/events.js +66 -42
  98. package/dist/core/mods/kernel/index.d.ts +4 -4
  99. package/dist/core/mods/kernel/index.js +2 -2
  100. package/dist/core/mods/kernel/receive.d.ts +39 -5
  101. package/dist/core/mods/kernel/receive.js +290 -17
  102. package/dist/core/mods/kernel/registration.d.ts +33 -2
  103. package/dist/core/mods/kernel/registration.js +6 -7
  104. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  105. package/dist/core/mods/kernel/site-rules.js +24 -42
  106. package/dist/core/mods/spec-seats.d.ts +69 -0
  107. package/dist/core/mods/spec-seats.js +114 -0
  108. package/dist/core/mods/stations.d.ts +28 -8
  109. package/dist/core/mods/stations.js +29 -13
  110. package/dist/core/mods/tool-call.d.ts +79 -0
  111. package/dist/core/mods/tool-call.js +152 -0
  112. package/dist/core/namespaced-rule-name.d.ts +32 -38
  113. package/dist/core/namespaced-rule-name.js +29 -36
  114. package/dist/core/parent-spec-seat.d.ts +6 -1
  115. package/dist/core/parent-spec-seat.js +2 -0
  116. package/dist/core/park-selfcheck.js +1 -0
  117. package/dist/core/permission-rule-consent.d.ts +19 -0
  118. package/dist/core/permission-rule-consent.js +116 -26
  119. package/dist/core/permission-rule-model.d.ts +14 -3
  120. package/dist/core/permission-rule-model.js +39 -24
  121. package/dist/core/permission-rule-org.d.ts +6 -2
  122. package/dist/core/permission-rule-org.js +7 -3
  123. package/dist/core/permission-rule-provider.d.ts +5 -2
  124. package/dist/core/permission-rule-provider.js +41 -11
  125. package/dist/core/permission-rule-store.d.ts +3 -2
  126. package/dist/core/permission-rule-store.js +11 -2
  127. package/dist/core/permission-rule-sync.js +3 -2
  128. package/dist/core/permission-rule-syntax.d.ts +5 -4
  129. package/dist/core/permission-rule-syntax.js +2 -2
  130. package/dist/core/permission-rules.d.ts +4 -4
  131. package/dist/core/permission-rules.js +11 -20
  132. package/dist/core/persisted-rule-arms.d.ts +2 -2
  133. package/dist/core/persisted-rule-arms.js +10 -12
  134. package/dist/core/principal-name.d.ts +20 -0
  135. package/dist/core/principal-name.js +22 -0
  136. package/dist/core/prompt-section-seat.js +4 -6
  137. package/dist/core/protocol-http-auth.d.ts +26 -5
  138. package/dist/core/protocol-http-auth.js +137 -4
  139. package/dist/core/retired-keys.d.ts +16 -0
  140. package/dist/core/retired-keys.js +16 -4
  141. package/dist/core/rewrite-rejudge.d.ts +60 -0
  142. package/dist/core/rewrite-rejudge.js +36 -0
  143. package/dist/core/roles.d.ts +28 -1
  144. package/dist/core/roles.js +31 -19
  145. package/dist/core/rule-lane-reads.d.ts +20 -15
  146. package/dist/core/rule-lane-reads.js +45 -17
  147. package/dist/core/rule-owner.d.ts +3 -3
  148. package/dist/core/rule-owner.js +3 -2
  149. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  150. package/dist/core/runner/announce-once-ledger.js +5 -0
  151. package/dist/core/runner/assemble-result.d.ts +1 -0
  152. package/dist/core/runner/assemble-result.js +1 -1
  153. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  154. package/dist/core/runner/caller-roster.d.ts +16 -4
  155. package/dist/core/runner/caller-roster.js +33 -6
  156. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  157. package/dist/core/runner/capability-withheld-seat.js +24 -0
  158. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  159. package/dist/core/runner/classifier-ladder.js +3 -3
  160. package/dist/core/runner/construction-doors.js +3 -0
  161. package/dist/core/runner/contracts.d.ts +28 -25
  162. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  163. package/dist/core/runner/cross-boundary-lane.js +40 -27
  164. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  165. package/dist/core/runner/denial-limit-arms.js +1 -1
  166. package/dist/core/runner/file-history-request.d.ts +18 -0
  167. package/dist/core/runner/file-history-request.js +21 -13
  168. package/dist/core/runner/file-history-restore.d.ts +45 -0
  169. package/dist/core/runner/file-history-restore.js +46 -0
  170. package/dist/core/runner/gate-exit.d.ts +3 -3
  171. package/dist/core/runner/gate-exit.js +4 -3
  172. package/dist/core/runner/image.d.ts +7 -17
  173. package/dist/core/runner/image.js +9 -60
  174. package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
  175. package/dist/core/runner/permission-rule-lanes.js +26 -10
  176. package/dist/core/runner/person-path-rows.d.ts +12 -9
  177. package/dist/core/runner/person-path-rows.js +18 -7
  178. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  179. package/dist/core/runner/prepare-ask-lane.js +5 -2
  180. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  181. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  182. package/dist/core/runner/prepare-config-doors.d.ts +29 -38
  183. package/dist/core/runner/prepare-config-doors.js +42 -25
  184. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  185. package/dist/core/runner/prepare-defer-classify.js +7 -8
  186. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  187. package/dist/core/runner/prepare-file-history.js +7 -39
  188. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  189. package/dist/core/runner/prepare-gate-stations.js +10 -1
  190. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  191. package/dist/core/runner/prepare-hands-readface.js +15 -14
  192. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  193. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  194. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  195. package/dist/core/runner/prepare-park-ask.js +5 -5
  196. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  197. package/dist/core/runner/prepare-policy-chain.js +65 -72
  198. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  199. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  200. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  201. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  204. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  205. package/dist/core/runner/prepare-safety-scan.js +0 -17
  206. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  207. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  208. package/dist/core/runner/prepare-task.d.ts +1 -1
  209. package/dist/core/runner/prepare-task.js +29 -20
  210. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  211. package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
  212. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  213. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  215. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  216. package/dist/core/runner/resume-admission.js +1 -1
  217. package/dist/core/runner/resume-apply.js +11 -12
  218. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  219. package/dist/core/runner/resume-claim.d.ts +4 -2
  220. package/dist/core/runner/resume-claim.js +15 -8
  221. package/dist/core/runner/retired-runner-deps.js +1 -0
  222. package/dist/core/runner/rewind-files.d.ts +15 -0
  223. package/dist/core/runner/rewind-files.js +132 -0
  224. package/dist/core/runner/run-attachment-seats.js +2 -1
  225. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  226. package/dist/core/runner/run-brain-sinks.js +4 -2
  227. package/dist/core/runner/run-harness-handlers.js +12 -4
  228. package/dist/core/runner/run-leg.d.ts +1 -1
  229. package/dist/core/runner/run-leg.js +30 -18
  230. package/dist/core/runner/run-settle-and-teardown.js +2 -1
  231. package/dist/core/runner/run-turn-boundary.js +1 -10
  232. package/dist/core/runner/runtask.d.ts +3 -0
  233. package/dist/core/runner/runtask.js +8 -9
  234. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  235. package/dist/core/runner/session-read-file-states.js +28 -0
  236. package/dist/core/runner/session-rule-policy.js +4 -3
  237. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  238. package/dist/core/runner/shell-env-withheld.js +51 -0
  239. package/dist/core/runner/skills-seat.js +6 -2
  240. package/dist/core/runner/stream-settle-backstop.js +1 -1
  241. package/dist/core/runner/sub-agent-deny-lists.js +4 -7
  242. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  243. package/dist/core/runner/synthetic-tools.js +4 -1
  244. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  245. package/dist/core/runner/tool-disclosure.js +1 -3
  246. package/dist/core/runner/tool-end-body.d.ts +1 -1
  247. package/dist/core/runner/tool-end-body.js +10 -9
  248. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  249. package/dist/core/runner/tool-not-executed.js +11 -0
  250. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  251. package/dist/core/runner/tool-occurrence.js +7 -0
  252. package/dist/core/runner/turn-attachments.d.ts +33 -15
  253. package/dist/core/runner/turn-attachments.js +62 -37
  254. package/dist/core/runner-deps.d.ts +5 -5
  255. package/dist/core/safety-axis-vocab.d.ts +6 -4
  256. package/dist/core/safety-axis-vocab.js +6 -5
  257. package/dist/core/safety-merge-corpus.js +11 -3
  258. package/dist/core/secret-env.d.ts +26 -3
  259. package/dist/core/secret-env.js +44 -8
  260. package/dist/core/select-model.js +3 -3
  261. package/dist/core/session-policy-store.d.ts +27 -15
  262. package/dist/core/session-policy-store.js +156 -36
  263. package/dist/core/session-store.d.ts +29 -10
  264. package/dist/core/session-store.js +51 -19
  265. package/dist/core/session.d.ts +82 -16
  266. package/dist/core/session.js +53 -0
  267. package/dist/core/shell-read-silence.d.ts +11 -12
  268. package/dist/core/shell-read-silence.js +9 -5
  269. package/dist/core/shell-run-candidates.js +3 -1
  270. package/dist/core/shell-wrapper-projection.js +1 -1
  271. package/dist/core/shell-wrapper-table.d.ts +14 -7
  272. package/dist/core/shell-wrapper-table.js +5 -4
  273. package/dist/core/side-query.js +10 -1
  274. package/dist/core/skill-grant.d.ts +7 -2
  275. package/dist/core/skill-grant.js +5 -0
  276. package/dist/core/skills-directory.js +6 -2
  277. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  278. package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
  279. package/dist/core/store-contracts/file-history-store-contract.js +31 -1
  280. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  281. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  282. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  283. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  284. package/dist/core/store-contracts/session-store-contract.js +150 -14
  285. package/dist/core/stub-env.d.ts +2 -0
  286. package/dist/core/stub-env.js +1 -0
  287. package/dist/core/synthetic-read-verdict.js +3 -3
  288. package/dist/core/task-event.d.ts +32 -4
  289. package/dist/core/task-notification.d.ts +16 -12
  290. package/dist/core/task-registry.d.ts +9 -0
  291. package/dist/core/task-registry.js +11 -1
  292. package/dist/core/task-result.d.ts +18 -0
  293. package/dist/core/task-spec.d.ts +18 -13
  294. package/dist/core/tighten-task-spec.js +2 -1
  295. package/dist/core/tool-catalog-entries.d.ts +17 -0
  296. package/dist/core/tool-catalog-entries.js +13 -2
  297. package/dist/core/tool-check-reading.d.ts +11 -0
  298. package/dist/core/tool-check-reading.js +11 -6
  299. package/dist/core/tool-model-gate.d.ts +2 -2
  300. package/dist/core/tool-name-aliases.d.ts +16 -16
  301. package/dist/core/tool-name-aliases.js +13 -19
  302. package/dist/core/tool-name-readings.d.ts +5 -35
  303. package/dist/core/tool-name-readings.js +1 -9
  304. package/dist/core/tool-policy.d.ts +68 -198
  305. package/dist/core/tool-policy.js +149 -198
  306. package/dist/core/tool-result-store.js +3 -0
  307. package/dist/core/tool-roster.d.ts +14 -19
  308. package/dist/core/tool-roster.js +11 -44
  309. package/dist/core/tool-spec-members.js +7 -2
  310. package/dist/core/tool-spec.d.ts +19 -11
  311. package/dist/core/tools.js +49 -9
  312. package/dist/core/trace.d.ts +2 -2
  313. package/dist/core/types.d.ts +1 -1
  314. package/dist/core/user-attachment.d.ts +8 -1
  315. package/dist/core/user-attachment.js +64 -4
  316. package/dist/core/wiring-manifest.d.ts +9 -0
  317. package/dist/core/wiring-manifest.js +1 -0
  318. package/dist/core/workflow-journal-store.js +1 -1
  319. package/dist/engine/compaction/compaction.js +3 -2
  320. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  321. package/dist/engine/execution-env/node-execution-env.js +11 -2
  322. package/dist/engine/harness/agent-harness.d.ts +25 -1
  323. package/dist/engine/harness/agent-harness.js +54 -7
  324. package/dist/engine/harness/types.d.ts +29 -2
  325. package/dist/engine/llm/types.d.ts +28 -11
  326. package/dist/engine/loop/agent-loop.d.ts +22 -0
  327. package/dist/engine/loop/agent-loop.js +16 -26
  328. package/dist/engine/loop/types.d.ts +16 -6
  329. package/dist/engine/session/memory-repo.d.ts +9 -2
  330. package/dist/engine/session/memory-repo.js +11 -1
  331. package/dist/engine/session/repo-utils.d.ts +6 -5
  332. package/dist/engine/session/repo-utils.js +14 -6
  333. package/dist/index.d.ts +22 -10
  334. package/dist/index.js +15 -7
  335. package/dist/internal/harness-types.d.ts +1 -1
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  338. package/dist/orchestration/run-workflow-tool.js +5 -3
  339. package/dist/orchestration/workflow.d.ts +3 -0
  340. package/dist/orchestration/workflow.js +36 -18
  341. package/dist/prompt-assembly/artifact.d.ts +2 -2
  342. package/dist/prompt-assembly/artifact.js +5 -3
  343. package/dist/prompt-assembly/assemble.d.ts +3 -2
  344. package/dist/prompt-assembly/assemble.js +1 -1
  345. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  346. package/dist/prompt-assembly/catalog/schema.js +34 -2
  347. package/dist/prompt-assembly/catalog/sections.js +0 -1
  348. package/dist/prompt-assembly/composer.d.ts +3 -1
  349. package/dist/prompt-assembly/composer.js +1 -1
  350. package/dist/prompt-assembly/event-registry.js +1 -0
  351. package/dist/prompt-assembly/overlay.js +3 -3
  352. package/dist/prompt-assembly/renderers.d.ts +1 -1
  353. package/dist/prompt-assembly/renderers.js +0 -3
  354. package/dist/prompt-assembly/role-base.d.ts +15 -0
  355. package/dist/prompt-assembly/role-base.js +9 -0
  356. package/dist/prompt-assembly/select.d.ts +39 -14
  357. package/dist/prompt-assembly/select.js +47 -16
  358. package/dist/prompt-assembly/sugar.d.ts +17 -11
  359. package/dist/prompt-assembly/sugar.js +8 -3
  360. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  361. package/dist/prompt-assembly/tool-catalog.js +114 -4
  362. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  363. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  364. package/dist/prompt-assembly/types.d.ts +0 -7
  365. package/dist/scenarios/full-body.d.ts +11 -11
  366. package/dist/scenarios/full-body.js +4 -3
  367. package/dist/shell/lex.js +10 -1
  368. package/dist/stores/file/adoption/adopt.js +4 -3
  369. package/dist/stores/file/adoption/marker.js +3 -2
  370. package/dist/stores/file/checkpoint-store.d.ts +21 -0
  371. package/dist/stores/file/checkpoint-store.js +38 -6
  372. package/dist/stores/file/file-history-store.js +6 -7
  373. package/dist/stores/file/index.js +2 -1
  374. package/dist/stores/file/permission-rule-adopt.js +4 -3
  375. package/dist/stores/file/permission-rule-store.js +11 -5
  376. package/dist/stores/file/session-store.d.ts +29 -6
  377. package/dist/stores/file/session-store.js +42 -50
  378. package/dist/tools/artifact/artifact-tool.js +3 -2
  379. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  380. package/dist/tools/fs/bash-program-position.js +56 -9
  381. package/dist/tools/fs/fs-bash.js +5 -5
  382. package/dist/tools/fs/fs-glob.d.ts +86 -0
  383. package/dist/tools/fs/fs-glob.js +226 -0
  384. package/dist/tools/fs/fs-read.js +14 -14
  385. package/dist/tools/fs/fs-search-tools.js +7 -7
  386. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  387. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  388. package/dist/tools/fs/pdf.d.ts +9 -6
  389. package/dist/tools/fs/pdf.js +3 -3
  390. package/dist/tools/fs/program-read-model.d.ts +57 -7
  391. package/dist/tools/fs/program-read-model.js +11 -1
  392. package/dist/tools/fs/program-read-model.rows.js +78 -21
  393. package/dist/tools/fs/read-deny-home.js +3 -2
  394. package/dist/tools/fs/removal-targets.d.ts +17 -7
  395. package/dist/tools/fs/removal-targets.js +47 -20
  396. package/dist/tools/fs/search.d.ts +10 -0
  397. package/dist/tools/fs/search.js +20 -26
  398. package/dist/tools/fs/shell-read-argv.js +89 -12
  399. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  400. package/dist/tools/fs/shell-read-bindings.js +41 -0
  401. package/dist/tools/fs/shell-read-check.js +6 -19
  402. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  403. package/dist/tools/fs/shell-read-environment.js +3 -2
  404. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  405. package/dist/tools/fs/shell-read-establish.js +19 -20
  406. package/dist/tools/fs/shell-read-plan.js +24 -16
  407. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  408. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  409. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  410. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  411. package/dist/tools/fs/shell-reentry-text.js +40 -2
  412. package/dist/tools/todo.js +63 -63
  413. package/dist/tools/web.d.ts +19 -14
  414. package/dist/tools/web.js +38 -55
  415. package/package.json +1 -1
  416. package/test/export-surface.snapshot.json +143 -5
  417. package/wire-changes/core@7.56.0.json +3891 -0
  418. package/wire-changes/mods-kernel@7.56.0.json +303 -0
@@ -32,6 +32,7 @@ const TASK_PREFIX = {
32
32
  background_agent: "a",
33
33
  monitor: "m",
34
34
  };
35
+ const A_LATER_LEG = Object.freeze({});
35
36
  function noTask(taskId, runningAgents) {
36
37
  return {
37
38
  content: `No task found with ID: ${taskId}${runningAgents ? notFoundRunningAgentsTail(runningAgents) : ""}`,
@@ -871,6 +872,9 @@ export class TaskRegistry {
871
872
  return { legs: [] };
872
873
  return { legs: verb === "output" ? ["outside_read"] : [] };
873
874
  }
875
+ owedDeliveries(access) {
876
+ return this.liveTasks(access).map((t) => this.boundaryLegsOf(t.task_id, access, "output", A_LATER_LEG));
877
+ }
874
878
  async pollTask(id, access, opts = {}) {
875
879
  const taskId = id.trim();
876
880
  const deadline = opts.block ? blockDeadline(opts.timeoutMs, Date.now()) : undefined;
@@ -1017,6 +1021,12 @@ The durable record is still marked running (last update ${new Date(row.updatedAt
1017
1021
  lastGcAt = 0;
1018
1022
  list(access, opts = {}) {
1019
1023
  const limit = Math.min(500, Math.max(1, Math.floor(opts.limit ?? 50)));
1024
+ return this.rowsUnder(access).slice(0, limit);
1025
+ }
1026
+ liveTasks(access) {
1027
+ return this.rowsUnder(access).filter((t) => t.status === "pending" || t.status === "running" || t.status === "parked");
1028
+ }
1029
+ rowsUnder(access) {
1020
1030
  const out = [];
1021
1031
  for (const h of this.handles.values()) {
1022
1032
  if (!canAccess(h, access))
@@ -1034,7 +1044,7 @@ The durable record is still marked running (last update ${new Date(row.updatedAt
1034
1044
  });
1035
1045
  }
1036
1046
  out.sort((a, b) => b.createdAt - a.createdAt);
1037
- return out.slice(0, limit);
1047
+ return out;
1038
1048
  }
1039
1049
  maybeGc(now = Date.now()) {
1040
1050
  if (now - this.lastGcAt < 60_000)
@@ -247,6 +247,24 @@ export interface TaskResult {
247
247
  effectiveReasoning?: import("../brain/reasoning.js").ResolvedReasoning;
248
248
  /** Final assistant text. */
249
249
  result: string;
250
+ /**
251
+ * Where {@link result} was read from: the session-tree entry ids of the committed assistant messages the engine selected
252
+ * as the answer's source, in conversation order — the ids `message_committed.entryId` carries on the stream. One id for
253
+ * an ordinary answer; every member of the continuation chain when a cut answer was continued (`result` is their texts,
254
+ * joined). `result` is the answer's one authority: a committed message can differ from what streamed (engine notes
255
+ * placed at finalize, a degenerate cut trimmed), so a consumer that rendered the stream replaces the named messages'
256
+ * text rows with `result` instead of comparing; one that cannot bind an id (it lost that `message_committed`) reads the
257
+ * named entries from the session rather than guessing which rows they were.
258
+ *
259
+ * EMPTY when `result` was read from no committed message (the run produced no assistant message, or only one that was
260
+ * never appended — an empty failure). A named message may contribute no text (a tool-calling message a park or a stop
261
+ * ended on; a thinking-only head of a continuation chain), so `result` may be empty beside a non-empty list. ABSENT when
262
+ * the provenance is unknown: a record an older engine wrote, a result rebuilt from a checkpoint row alone, or an answer
263
+ * a leg read from a message committed before it began (whose append that leg never saw).
264
+ *
265
+ * Not yet byte-equal: `result` alone drops inline `<think>…</think>` blocks and is trimmed; the named messages keep both.
266
+ */
267
+ resultEntryIds?: readonly string[];
250
268
  /**
251
269
  * Best-effort salvaged assistant text from a terminal FAILURE. Consumption recipe: on a non-`completed`
252
270
  * status read `result` FIRST — most failure terminals (max-turns, budget, tool errors, …) still carry
@@ -296,12 +296,12 @@ export interface TaskSpec {
296
296
  advisorModel?: ModelRef;
297
297
  /** Thinking level. If omitted, a default from the resolved role's `RoleSpec.thinking` applies. */
298
298
  thinking?: ThinkingLevel;
299
- /** This task's role text: it replaces the selected role base (`promptRole`). Text carrying a locked section verbatim
300
- * (an already-assembled prompt) is refused by name (`prompt.assembled_role_refused`). */
299
+ /** This task's role text: it replaces the role base `promptRole` selects; the task names its role base first, above its role's preset (`RoleSpec`).
300
+ * Text carrying a locked section verbatim (an already-assembled prompt) is refused by name (`prompt.assembled_role_refused`). */
301
301
  systemPrompt?: string;
302
- /** The role base `core/role.base` selects: `"general"` (absent), `"code"`, `"coordinator"`, `"cowork"` (rendered from the
303
- * mounted tools and the working directory); `systemPrompt` replaces whichever is selected. Not inherited (a child gets
304
- * the sub-agent persona). A value outside the closed set (`HOST_ROLES`, tested by `isHostRole`) is refused at prepare. */
302
+ /** The role base `core/role.base` selects — `"general"`, `"code"`, `"coordinator"`, `"cowork"` (rendered from the mounted tools and the
303
+ * working directory) — and the run's host role; `systemPrompt` replaces it. A task naming neither takes its role's preset (`RoleSpec.promptRole` /
304
+ * `systemPrompt`) whole; an explicit `"general"` names the general base and ends that chain, absent does not. Not inherited (a child gets the sub-agent persona). Outside the closed set (`HOST_ROLES`, `isHostRole`) ⇒ refused at prepare. */
305
305
  promptRole?: import("../prompt-assembly/catalog/schema.js").HostRole;
306
306
  /** `"minimal"` leaves the core-behavior band out; the locked sections (mode sections in play among them) and
307
307
  * `appendSystemPrompt` stay. Absent ⇒ standard. Rides the parent spec seat to every engine-built child (a clamp-table
@@ -600,14 +600,14 @@ export interface TaskSpec {
600
600
  */
601
601
  deferSelfResolve?: boolean;
602
602
  /**
603
- * R2 双形轴(2026-07-18 裁): which prompt-profile face this task speaks — "simple" (default;
604
- * the short-form tool descriptions + lean system sections, what CC serves every non-claude
605
- * model id) or "classic" (the long-form face, ≈ CC 4.x-era wording — switchable per task/model,
606
- * e.g. serving classic to a model that scores better on it; center distribution rides this field).
607
- * Affects PRESENTATION only (descriptions/section wording), never tool behavior or policy.
608
- * Inherited by delegated children unless their spec overrides.
603
+ * The task's one switch on the prompt's shape: `true` adds the `lean_prompt` trait to the model's declared traits
604
+ * (`Model.promptTraits`), `false` removes it (the long, classic shape of the system sections and tool descriptions),
605
+ * absent leaves the model's answer. It moves no other trait — a model-family trait stays the model's. PRESENTATION
606
+ * only (section wording, tool descriptions), never tool behavior or policy. Inherited by delegated children (and
607
+ * workflow agents) unless their spec writes it; a value that is not a boolean refuses the task
608
+ * (`config.prompt_selector_invalid`).
609
609
  */
610
- promptProfile?: "simple" | "classic";
610
+ promptLean?: boolean;
611
611
  /**
612
612
  * core half — PER-TASK custom sub-agents. Same shape as the boot injection point
613
613
  * ({@link RunnerDeps.agents} / `SubagentToolOptions.agents`): full {@link AgentDefinition} objects
@@ -665,7 +665,7 @@ export interface TaskSpec {
665
665
  * registrations hang handlers on the `classic.*` events the engine's stations raise (tool pre/post/failure/batch,
666
666
  * prompt submit, stop, compaction, permission denied). A delegated child dispatches its parent's task seat as its own
667
667
  * (the parent spec seat fills an unset one). */
668
- mods?: readonly import("./mods/kernel/index.js").ModRegistration<import("./mods/dollar.js").EngineDollar>[];
668
+ mods?: readonly import("./mods/classic-events.js").EngineModRegistration[];
669
669
  /**
670
670
  * The session's SELF-REPORTED presence for the peer directory (`agent` = what it is, `intent` = what
671
671
  * it is doing; each ≤ 120 chars). The engine never writes a directory row: the same object goes out
@@ -1538,6 +1538,11 @@ export interface TaskSpec {
1538
1538
  * the default was off — a probe pinning "no background_tasks frame without opt-in" reds. */
1539
1539
  backgroundTasks?: boolean;
1540
1540
  toolsDelta?: true;
1541
+ /** The notice that a declared MCP server did not connect for this message: its tools are unavailable for now, and it is
1542
+ * tried again when the next message arrives. Rides the leg's first request (a fresh leg's first user message, a resumed leg's continuation),
1543
+ * once per session per server and error. DEFAULT ON — boolean: `false` is the opt-out, a non-boolean is refused at the
1544
+ * task's door (`config.invalid_argument`). BREAKING: the notice used to ride {@link toolsDelta}, and only a turn boundary. */
1545
+ mcpUnavailable?: boolean;
1541
1546
  /** [c209-C] listing family — DEFAULT ON (boolean, not `true`: explicit `false` is the opt-out;
1542
1547
  * see the family carve-out note above). BREAKING (B-3): pre-[c209-C] the default was off. */
1543
1548
  agentListing?: boolean;
@@ -1,4 +1,5 @@
1
1
  import { combinePolicies } from "./tool-policy.js";
2
+ import { namesEveryTool } from "../agents/tool-filter.js";
2
3
  import { clampPermissionMode } from "./ask-origin.js";
3
4
  import { CLAMP_SEATS, clampCellOf, clampCellPath, composeClampSeat, loosensClampSeat } from "./child-clamp-seats.js";
4
5
  export class TaskSpecTightenError extends Error {
@@ -25,7 +26,7 @@ export function tightenTaskSpec(base, overrides) {
25
26
  {
26
27
  const b = base.allowTools;
27
28
  const o = overrides.allowTools;
28
- if (b !== undefined && o !== undefined && !b.includes("*")) {
29
+ if (b !== undefined && o !== undefined && !b.some(namesEveryTool)) {
29
30
  const wider = o.filter((entry) => !b.includes(entry));
30
31
  if (wider.length > 0)
31
32
  throw new TaskSpecTightenError(`tightenTaskSpec: cannot widen allowTools beyond the base list (override names ${JSON.stringify(wider)}; the override may only narrow)`);
@@ -54,6 +54,23 @@ export declare function toolFace(id: string): ToolFaceDeclaration;
54
54
  /** Is `contract` a contract object the catalog minted for an engine definition ({@link toolFace}) — the one record of "the engine
55
55
  * declared this", which a value written by hand (the same id spelled out) is not. */
56
56
  export declare function isCatalogContract(contract: unknown): boolean;
57
+ /**
58
+ * "Does this call dispatch to the ENGINE's own instance of one of these definitions?" — the one judge, read off the call's face:
59
+ * one of the engine's own mount sites mounted the tool (`engineMounted`, the one identity a caller cannot wear), and the
60
+ * contract it carries is the one the catalog gives one of `ids`. Never the name or the contract alone: a caller's tool can take
61
+ * an engine name, and a contract id can be written by hand. False for every other call — a caller's or a protocol peer's tool,
62
+ * a face rebuilt from a park row minted before the row recorded its mount site, a bare request (no face). A row minted since
63
+ * carries the mount site its roster entry had at the park, so the pre-claim recheck of its edit reads this judge's answer at park time.
64
+ */
65
+ export declare function engineMountedAs(ids: readonly string[]): (face: {
66
+ readonly engineMounted?: true;
67
+ readonly contractId: string;
68
+ } | undefined) => boolean;
69
+ /** Is this call's face the engine's own shell tool (either of its two mounts)? */
70
+ export declare const isEngineShellFace: (face: {
71
+ readonly engineMounted?: true;
72
+ readonly contractId: string;
73
+ } | undefined) => boolean;
57
74
  /**
58
75
  * The rule face a definition whose schema is BUILT PER MOUNT puts on its instance: its row's primaries only (none ⇒ no rule
59
76
  * face). The row's `params` is the static view's vocabulary, the fullest mount's; a mount's own is read off the schema it
@@ -58,7 +58,7 @@ export const TOOL_CATALOG_ENTRIES = [
58
58
  },
59
59
  {
60
60
  id: "bash", name: "Bash", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"],
61
- cards: ["bash", "readonly_out_of_root", "read_unestablished", "bash_invalid_timeout"],
61
+ cards: ["bash", "readonly_out_of_root", "read_unestablished", "bash_invalid_timeout", "bash_self_kill_refused"],
62
62
  face: {
63
63
  family: "shell", boundaryLegs: ["env"], effect: "write", contentOrigin: "execution", contract: c(FULL_SHELL_CONTRACT_ID),
64
64
  ruleFace: SHELL_RULE_FACE,
@@ -174,6 +174,7 @@ export const ENGINE_CARDS = Object.freeze({
174
174
  read_path_denied: "src/tools/fs/safety.ts",
175
175
  readonly_out_of_root: "src/tools/fs/shell-read-check.ts",
176
176
  read_unestablished: "src/tools/fs/shell-read-check.ts",
177
+ bash_self_kill_refused: "src/tools/fs/pattern-kill-guard.ts",
177
178
  });
178
179
  const byId = new Map();
179
180
  for (const e of TOOL_CATALOG_ENTRIES) {
@@ -190,12 +191,22 @@ export function toolFace(id) {
190
191
  throw new Error(`tool catalog: no definition ${JSON.stringify(id)}`);
191
192
  const face = { contentOrigin: "local", ...structuredClone(e.face) };
192
193
  if (face.contract !== undefined)
193
- CATALOG_CONTRACTS.add(face.contract);
194
+ CATALOG_CONTRACTS.add(Object.freeze(face.contract));
194
195
  return face;
195
196
  }
196
197
  export function isCatalogContract(contract) {
197
198
  return typeof contract === "object" && contract !== null && CATALOG_CONTRACTS.has(contract);
198
199
  }
200
+ export function engineMountedAs(ids) {
201
+ const contracts = new Set(ids.map((id) => {
202
+ const contractId = byId.get(id)?.face.contract?.contractId;
203
+ if (contractId === undefined)
204
+ throw new Error(`tool catalog: ${JSON.stringify(id)} declares no contract — an engine mount is judged by its definition's contract`);
205
+ return contractId;
206
+ }));
207
+ return (face) => face?.engineMounted === true && contracts.has(face.contractId);
208
+ }
209
+ export const isEngineShellFace = engineMountedAs(["bash", "bash-readonly"]);
199
210
  export function mountRuleFace(id) {
200
211
  const primaryParams = toolFace(id).ruleFace?.primaryParams;
201
212
  return primaryParams === undefined ? undefined : { primaryParams: [...primaryParams] };
@@ -11,6 +11,8 @@ export type ToolCheckStanding = Exclude<PermissionResult, {
11
11
  action: "deny";
12
12
  }>;
13
13
  /** What a reading came to. `minted` on an ask: the reading minted it over an allow (the ask carries no stamp of the round yet).
14
+ * `cleared`: the allow layer's `hook` member cleared the ask, `entries` naming the registrations that spoke (the allow layer
15
+ * records the clearance as it records the member's clear on a `classic.PreToolUse` allow).
14
16
  * `approved`: a person an inherited installation's question went to approved an edit of the call — the gate's approved-edit
15
17
  * pass takes it, as it takes an edit approved at this leg's own question. */
16
18
  export type ToolCheckReading = {
@@ -30,6 +32,7 @@ export type ToolCheckReading = {
30
32
  readonly allow: Extract<PermissionResult, {
31
33
  action: "allow";
32
34
  }>;
35
+ readonly entries: readonly string[];
33
36
  } | {
34
37
  readonly kind: "shadowed";
35
38
  readonly shadows: readonly AllowRuleShadow[];
@@ -53,6 +56,14 @@ export interface ToolCheckCall {
53
56
  readonly request: ToolCallRequest;
54
57
  readonly signal: AbortSignal | undefined;
55
58
  }
59
+ /**
60
+ * The allow layer's `hook` member clearing an ask — an extension's word that the call needs no asking, whichever event spoke
61
+ * it (a `classic.PreToolUse` allow at the head of the layer, a `tool.check` allow behind the read-only arm): the allow over
62
+ * the args the gate judged (the policy's rewrite riding), named by the registrations that spoke.
63
+ */
64
+ export declare function extensionAllowOf(speakers: readonly string[], rewrite: unknown): Extract<PermissionResult, {
65
+ action: "allow";
66
+ }>;
56
67
  /** One chain a gate raises `tool.check` on: its raise over a projection; for the leg's own bus only, the allow layer's
57
68
  * predicate under which its `allow` may clear an ask; for an inherited installation only, the settlement its question takes. */
58
69
  export interface ToolCheckChain {
@@ -1,5 +1,5 @@
1
1
  import { refusalOf } from "./tool-policy.js";
2
- import { allowRuleShadowOf } from "./allow-entry.js";
2
+ import { allowRuleShadowOf, withAllowRuleShadow } from "./allow-entry.js";
3
3
  import { inlineUntrusted } from "./untrusted-text.js";
4
4
  import { failedHandlerClause } from "./mods/stations.js";
5
5
  const STANDS = Object.freeze({ kind: "stands" });
@@ -23,9 +23,14 @@ function readToolCheck(heard, standing, call, mayClear) {
23
23
  }
24
24
  if (standing.action === "allow")
25
25
  return STANDS;
26
+ const entries = heard.by !== undefined ? [heard.by] : [];
26
27
  if (mayClear?.() === true)
27
- return { kind: "cleared", allow: { action: "allow", message: `${who} allowed this call`, decisionReason: "hook", ...rewritten } };
28
- return { kind: "shadowed", shadows: [allowRuleShadowOf("hook", heard.by !== undefined ? [heard.by] : [])] };
28
+ return { kind: "cleared", allow: extensionAllowOf(entries, call.rewrite), entries };
29
+ return { kind: "shadowed", shadows: [allowRuleShadowOf("hook", entries)] };
30
+ }
31
+ export function extensionAllowOf(speakers, rewrite) {
32
+ const who = speakers.length > 0 ? speakers.map((s) => `extension "${inlineUntrusted(s, 80)}"`).join(", ") : "an extension";
33
+ return { action: "allow", message: `${who} allowed this call`, decisionReason: "hook", ...(rewrite !== undefined ? { updatedInput: rewrite } : {}) };
29
34
  }
30
35
  function speakerOf(heard) {
31
36
  return { who: heard.by !== undefined ? `extension "${inlineUntrusted(heard.by, 80)}"` : "an extension", why: heard.reason !== undefined ? `: ${inlineUntrusted(heard.reason, 500)}` : "" };
@@ -38,7 +43,7 @@ export async function readToolChecks(chains, standing, call, project) {
38
43
  let raised = false;
39
44
  let current = standing;
40
45
  let moved;
41
- const shadows = [];
46
+ let shadows = [];
42
47
  for (const chain of chains) {
43
48
  const heard = await chain.raise(project(current, chain.mayClear));
44
49
  if (heard === undefined)
@@ -62,7 +67,7 @@ export async function readToolChecks(chains, standing, call, project) {
62
67
  continue;
63
68
  }
64
69
  if (reading.kind === "shadowed")
65
- shadows.push(...reading.shadows);
70
+ shadows = reading.shadows.reduce(withAllowRuleShadow, shadows);
66
71
  if (reading.kind === "asked") {
67
72
  moved = { ...reading, minted: reading.minted || (moved?.kind === "asked" && moved.minted), ...(moved?.kind === "asked" && moved.marked === true ? { marked: true } : {}) };
68
73
  current = reading.ask;
@@ -75,6 +80,6 @@ export async function readToolChecks(chains, standing, call, project) {
75
80
  if (!raised)
76
81
  return undefined;
77
82
  if (moved?.kind === "asked" && shadows.length > 0)
78
- return { ...moved, ask: { ...moved.ask, allowRuleShadowed: [...(moved.ask.allowRuleShadowed ?? []), ...shadows] } };
83
+ return { ...moved, ask: { ...moved.ask, allowRuleShadowed: shadows.reduce(withAllowRuleShadow, [...(moved.ask.allowRuleShadowed ?? [])]) } };
79
84
  return moved ?? (shadows.length > 0 ? { kind: "shadowed", shadows } : STANDS);
80
85
  }
@@ -34,8 +34,8 @@
34
34
  import type { ToolSpec } from "./types.js";
35
35
  /** The shared tail extractor (BYOM ids may carry provider prefixes — "openrouter/anthropic/claude-fable-5"):
36
36
  * boundary-aware LAST path segment, case-folded. Single source for every model-family/model-id
37
- * comparison site (`isFableFamilyModelId` consumes it too — the prompt-shape axis, semantically
38
- * independent but sharing the one tail-extraction posture). */
37
+ * comparison site (the tool-registration gate's; prompt text never reads a model id — it selects on the model's
38
+ * declared traits). */
39
39
  export declare function modelIdTail(id: string): string;
40
40
  /** One gate class's matching rule (both axes optional; a rule with BOTH axes empty gates nothing —
41
41
  * the per-class OFF shape a deployment reaches by explicitly clearing the axes). */
@@ -44,8 +44,8 @@ export declare const RULE_TOOL_NAME_VERDICTS: readonly ["current", "retired", "u
44
44
  * (the server / remote agent) is empty or not a spelling the mint produces for any peer (the name is read as written —
45
45
  * peers compare exactly — and every mounted tool carries the minted spelling, so the name reaches none of them), or the
46
46
  * tool segment is EMPTY (a trailing separator, `mcp__srv__`: no tool is minted under an empty segment), or the peer segment
47
- * carries a wildcard the list's behavior does not read (`mcp__git*`, `mcp__*__get_*`; and `mcp__*` / `mcp__*__*` in an
48
- * allow list — a deny or ask list reads those two as every tool of the protocol, see {@link wholeProtocolOf}). `guidance`
47
+ * carries a wildcard the list's behavior does not read (`mcp__git*`, `mcp__*`, `mcp__*__get_*` in an allow list — a deny or
48
+ * ask list reads every `*` as part of a glob over the whole name, see {@link readsNameGlob}). `guidance`
49
49
  * says so in one line; `currentName` is the whole name rewritten with the spelling the mint produces (`mcp__github.com__*` →
50
50
  * `mcp__github_com__*`), absent when a segment is empty or wild and there is nothing to rewrite. A tool segment that is not
51
51
  * empty is never judged: it is a literal tool name or a glob over one, and an unmatched one is the audit's advisory.
@@ -81,24 +81,24 @@ export declare function splitNamespacedName(name: string): {
81
81
  readonly tool?: string;
82
82
  } | undefined;
83
83
  /**
84
- * The protocol a name spells as a WHOLE — `mcp__*` and `mcp__*__*`, the two spellings that name every tool of every peer of one
85
- * namespace — or `undefined` for any other name. THE one reading of that spelling: the name judgment, the covering matcher, the
86
- * entry reader and the tool-name lists all ask it, so none keeps a second list of the spellings.
84
+ * Does a list of this behavior read a `*` in a tool name as a glob over the WHOLE name — anywhere in it, the lone `*` (every tool)
85
+ * included? A list that RESTRICTS (`deny`, `ask`) does: it reaches every tool any of whose names the glob matches (the reference's
86
+ * deny and ask lookups match a rule's tool name with `globMatching` on, and its settings validator says "deny and ask rules accept
87
+ * wildcards anywhere"). A list that GRANTS (`allow`) does not — an allow names the scope it widens, so it reads a `*` only in the
88
+ * tool segment after a literal `<ns>__<peer>__` ({@link grantWildcardRefusalOf}) — and neither does a caller that states no behavior.
87
89
  */
88
- export declare function wholeProtocolOf(name: string): ProtocolNamespace | undefined;
90
+ export declare function readsNameGlob(behavior: RuleBehavior | undefined): boolean;
89
91
  /**
90
- * Does a list of this behavior read a whole-protocol spelling ({@link wholeProtocolOf})? A list that RESTRICTS (`deny`, `ask`) does:
91
- * the spelling reaches every tool of the protocol. A list that GRANTS (`allow`) does not — an allow names the scope it widens,
92
- * and the reference's allow settings refuse a wildcard in the server position — and neither does a caller that states no
93
- * behavior: the spelling then names no tool, the reading every list had before it was one.
92
+ * The sentence for a `*` in a tool name that a GRANTING list does not read — anywhere but the tool segment after a literal, non-empty
93
+ * `<ns>__<peer>__` — or `undefined` (no `*`, or one in that segment). The one test every allow-side reader asks (a policy's allowlist
94
+ * constructor, an entry list, a run's allowed list, the name judgment's allow arm), so a spelling an allow cannot read is refused
95
+ * or read as nothing in one sentence wherever it is written.
94
96
  */
95
- export declare function readsWholeProtocol(behavior: RuleBehavior | undefined): boolean;
96
- /** The judgment's sentence for a namespaced name whose peer segment carries a wildcard the list's `behavior` does not read, else `undefined`
97
- * — only that arm of the judgment, for the stations that ask it with no roster (a rule policy's compile, an allowlist constructor). */
98
- export declare function wildcardPeerRefusalOf(name: string, behavior: RuleBehavior | undefined): string | undefined;
97
+ export declare function grantWildcardRefusalOf(name: string): string | undefined;
99
98
  /** See {@link RuleToolNameVerdict}. Pure; the one answer to "is this rule's tool name a name that reaches no tool".
100
- * `behavior` = the behavior of the list the name is written in: a restricting one (`deny`, `ask`) reads the whole-protocol
101
- * spelling ({@link wholeProtocolOf}) as `current`; with `allow` or none the spelling names no peer and is `unmintable_segment`. */
99
+ * `behavior` = the behavior of the list the name is written in: a restricting one (`deny`, `ask`) reads a `*` anywhere in the name
100
+ * as a glob ({@link readsNameGlob}) — such a name outside every namespace, or with a glob in its peer segment, is a pattern and
101
+ * `current`; with `allow` or none a wildcard peer names no peer and is `unmintable_segment`. */
102
102
  export declare function judgeRuleToolName(name: string, roster: ReadonlySet<string>, behavior?: RuleBehavior): RuleToolNameVerdict;
103
103
  /** The two kinds of tool-name miss — a closed set. `unknown`: the name is none the engine ever mounted (a typo, a
104
104
  * guess). `expected-absent`: the name is one the engine RETIRED ({@link RETIRED_TOOL_NAMES}), so its absence is no
@@ -53,19 +53,20 @@ export function splitNamespacedName(name) {
53
53
  const [peer = "", ...rest] = name.slice(ns.prefix.length).split(NAMESPACE_SEPARATOR);
54
54
  return rest.length > 0 ? { ns, peer, tool: rest.join(NAMESPACE_SEPARATOR) } : { ns, peer };
55
55
  }
56
- const WHOLE_PROTOCOL_PEER = "*";
57
- export function wholeProtocolOf(name) {
58
- const split = splitNamespacedName(name);
59
- return split !== undefined && spellsWholeProtocol(split) ? split.ns : undefined;
60
- }
61
- function spellsWholeProtocol(split) {
62
- return split.peer === WHOLE_PROTOCOL_PEER && (split.tool === undefined || split.tool === "*");
63
- }
64
- export function readsWholeProtocol(behavior) {
56
+ export function readsNameGlob(behavior) {
65
57
  return behavior === "deny" || behavior === "ask";
66
58
  }
67
59
  function peerWildcardGuidance(ns) {
68
- return `a ${ns.id} entry takes no wildcard in its peer segment — write ${ns.prefix}<peer> (every tool of one peer) or ${ns.prefix}<peer>${NAMESPACE_SEPARATOR}<tool> (one tool); a deny or ask entry may also write ${ns.prefix}* or ${ns.prefix}*${NAMESPACE_SEPARATOR}* for every ${ns.id} tool`;
60
+ return `an allow entry takes no wildcard in a ${ns.id} name's peer segment — write ${ns.prefix}<peer> (every tool of one peer), ${ns.prefix}<peer>${NAMESPACE_SEPARATOR}<tool> (one tool) or ${ns.prefix}<peer>${NAMESPACE_SEPARATOR}<glob> (the tools of one peer the glob matches); a deny or ask entry may put a \`*\` anywhere in a name`;
61
+ }
62
+ const GRANT_WILDCARD_GUIDANCE = "an allow entry names the tools it grants — a `*` in a tool name is read on an allow list only in the tool segment after a literal <ns>__<peer>__ (mcp__<server>__*), so this entry grants nothing; name the tools, or put the wildcard on a deny or ask entry, which reads a `*` anywhere in a name";
63
+ export function grantWildcardRefusalOf(name) {
64
+ if (!name.includes("*"))
65
+ return undefined;
66
+ const split = splitNamespacedName(name);
67
+ if (split === undefined)
68
+ return GRANT_WILDCARD_GUIDANCE;
69
+ return split.peer !== "" && !split.peer.includes("*") && split.tool !== undefined ? undefined : peerWildcardGuidance(split.ns);
69
70
  }
70
71
  function unmintableSegmentOf(split, behavior) {
71
72
  const { ns, peer, tool } = split;
@@ -74,7 +75,7 @@ function unmintableSegmentOf(split, behavior) {
74
75
  if (tool === "")
75
76
  return { kind: "unmintable_segment", guidance: `the ${ns.id} name has an empty tool segment — no tool is minted under it; write ${ns.prefix}<peer> to cover every tool of a peer, or ${ns.prefix}<peer>${NAMESPACE_SEPARATOR}<tool> for one tool` };
76
77
  if (peer.includes("*"))
77
- return spellsWholeProtocol(split) && readsWholeProtocol(behavior) ? undefined : { kind: "unmintable_segment", guidance: peerWildcardGuidance(ns) };
78
+ return readsNameGlob(behavior) ? undefined : { kind: "unmintable_segment", guidance: peerWildcardGuidance(ns) };
78
79
  const minted = mintNamespacePrefix(ns, peer).slice(ns.prefix.length, -NAMESPACE_SEPARATOR.length);
79
80
  if (minted === peer)
80
81
  return undefined;
@@ -84,13 +85,6 @@ function unmintableSegmentOf(split, behavior) {
84
85
  currentName: `${ns.prefix}${minted}${tool !== undefined ? `${NAMESPACE_SEPARATOR}${tool}` : ""}`,
85
86
  };
86
87
  }
87
- export function wildcardPeerRefusalOf(name, behavior) {
88
- const split = splitNamespacedName(name);
89
- if (split === undefined || !split.peer.includes("*"))
90
- return undefined;
91
- const verdict = unmintableSegmentOf(split, behavior);
92
- return verdict?.kind === "unmintable_segment" ? verdict.guidance : undefined;
93
- }
94
88
  export function judgeRuleToolName(name, roster, behavior) {
95
89
  if (roster.has(name))
96
90
  return CURRENT;
@@ -101,7 +95,7 @@ export function judgeRuleToolName(name, roster, behavior) {
101
95
  }
102
96
  const split = splitNamespacedName(name);
103
97
  if (split === undefined)
104
- return carriesNamespaceSeparator(name) ? UNPREFIXED : CURRENT;
98
+ return carriesNamespaceSeparator(name) && !(readsNameGlob(behavior) && name.includes("*")) ? UNPREFIXED : CURRENT;
105
99
  return unmintableSegmentOf(split, behavior) ?? CURRENT;
106
100
  }
107
101
  export const TOOL_MISS_KINDS = Object.freeze(["unknown", "expected-absent"]);
@@ -8,7 +8,8 @@
8
8
  * answers to ({@link heldBy}); a set-valued table is read as the union of its entries ({@link heldValues}).
9
9
  * · `seat` — a multi-key seat keyed on engine names: ONE name is chosen ({@link seatOf}) and every key of the seat is
10
10
  * read under it. `tier` = the name whose irreversibility tier is strictest (`never < maybe < always`, an
11
- * absent tier lowest, ties to the earlier name of the call); `member` = the first name the table holds.
11
+ * absent tier lowest; a tie goes to the call's wire name — the tool that runs judges its own call with its
12
+ * own probe — then to the earlier name of the call); `member` = the first name the table holds.
12
13
  * · `wire` — a GRANT or a ROUTING keyed on an engine name: the call's wire name only ({@link wireOf}).
13
14
  * · `spelling` — a record of what the model said (stream frames, transcripts, counters): the harness event's own name;
14
15
  * no port — listed so the table is complete.
@@ -78,10 +79,6 @@ export declare const NAME_READINGS: {
78
79
  readonly rank: "member";
79
80
  readonly file: string;
80
81
  };
81
- readonly "lanes.contentQuestionClass": {
82
- readonly kind: "any";
83
- readonly file: string;
84
- };
85
82
  readonly "lanes.readOnlyShellAllow": {
86
83
  readonly kind: "wire";
87
84
  readonly file: string;
@@ -90,22 +87,10 @@ export declare const NAME_READINGS: {
90
87
  readonly kind: "wire";
91
88
  readonly file: string;
92
89
  };
93
- readonly "lanes.contentAskRoute": {
94
- readonly kind: "wire";
95
- readonly file: string;
96
- };
97
90
  readonly "lanes.orgContentAskExemption": {
98
91
  readonly kind: "wire";
99
92
  readonly file: string;
100
93
  };
101
- readonly "lanes.allowLayerQuestionSkip": {
102
- readonly kind: "wire";
103
- readonly file: string;
104
- };
105
- readonly "lanes.sandboxQuestionSkip": {
106
- readonly kind: "wire";
107
- readonly file: string;
108
- };
109
94
  readonly "policy.nameLists": {
110
95
  readonly kind: "any";
111
96
  readonly file: string;
@@ -142,10 +127,6 @@ export declare const NAME_READINGS: {
142
127
  readonly kind: "any";
143
128
  readonly file: string;
144
129
  };
145
- readonly "policy.durableQuestion": {
146
- readonly kind: "any";
147
- readonly file: string;
148
- };
149
130
  readonly "policy.sensitivePathGuardedByName": {
150
131
  readonly kind: "any";
151
132
  readonly file: string;
@@ -240,10 +221,6 @@ export declare const NAME_READINGS: {
240
221
  readonly kind: "spelling";
241
222
  readonly file: string;
242
223
  };
243
- readonly "inherited.questionFloat": {
244
- readonly kind: "wire";
245
- readonly file: string;
246
- };
247
224
  readonly "inherited.askFace": {
248
225
  readonly kind: "wire";
249
226
  readonly file: string;
@@ -252,14 +229,6 @@ export declare const NAME_READINGS: {
252
229
  readonly kind: "wire";
253
230
  readonly file: string;
254
231
  };
255
- readonly "resume.editRecheckQuestionSkip": {
256
- readonly kind: "wire";
257
- readonly file: string;
258
- };
259
- readonly "resume.questionArgsShown": {
260
- readonly kind: "wire";
261
- readonly file: string;
262
- };
263
232
  readonly "budget.exemptResult": {
264
233
  readonly kind: "wire";
265
234
  readonly file: string;
@@ -347,8 +316,9 @@ export interface TierSeat extends Seat<IrreversibilityTierWord> {
347
316
  }): boolean;
348
317
  }
349
318
  /**
350
- * A `seat` site's read. A `tier` seat takes the irreversibility tier table and picks the name whose tier is strictest;
351
- * a `member` seat takes a table (a map, or a set whose value reads `true`) and picks the first name it holds.
319
+ * A `seat` site's read. A `tier` seat takes the irreversibility tier table and picks the name whose tier is strictest, a tie
320
+ * going to the call's wire name, then to its earlier name; a `member` seat takes a table (a map, or a set whose value reads
321
+ * `true`) and picks the first name it holds.
352
322
  */
353
323
  export declare function seatOf(site: TierSeatSite, tiers: {
354
324
  get(name: string): IrreversibilityTierWord | undefined;
@@ -21,13 +21,9 @@ export const NAME_READINGS = {
21
21
  "gate.preToolUse": wire("src/core/hooks.ts"),
22
22
  "gate.askFace": wire("src/core/runner/gate-exit.ts"),
23
23
  "fold.readStation": seat("member", "src/tools/fs/shell-read-check.ts"),
24
- "lanes.contentQuestionClass": any(LANES),
25
24
  "lanes.readOnlyShellAllow": wire(LANES),
26
25
  "lanes.modeFileCommand": wire(LANES),
27
- "lanes.contentAskRoute": wire(LANES),
28
26
  "lanes.orgContentAskExemption": wire(LANES),
29
- "lanes.allowLayerQuestionSkip": wire(LANES),
30
- "lanes.sandboxQuestionSkip": wire(LANES),
31
27
  "policy.nameLists": any(POLICY),
32
28
  "policy.shellToolsList": any(POLICY),
33
29
  "policy.projectionReplay": any(POLICY),
@@ -37,7 +33,6 @@ export const NAME_READINGS = {
37
33
  "gate.skillActivationSeat": wire(GATE),
38
34
  "policy.permissionRules": any("src/core/permission-rules.ts"),
39
35
  "policy.persistedGrammar": any("src/core/permission-rule-model.ts"),
40
- "policy.durableQuestion": any("src/core/ask-question.ts"),
41
36
  "policy.sensitivePathGuardedByName": any("src/core/sensitive-path-policy.ts"),
42
37
  "floor.protectivePathTarget": seat("member", "src/core/tool-registry.ts"),
43
38
  "floor.protectiveHostTarget": seat("member", "src/core/host-target.ts"),
@@ -60,11 +55,8 @@ export const NAME_READINGS = {
60
55
  "stats.subagentToolCounter": spelling("src/agents/subagent.ts"),
61
56
  "activity.sink": spelling(HANDLERS),
62
57
  "reconcile.orphanEffect": spelling("src/core/session-reconcile.ts"),
63
- "inherited.questionFloat": wire(CHAIN),
64
58
  "inherited.askFace": wire(CHAIN),
65
59
  "card.reserved": wire("src/core/tool-roster.ts"),
66
- "resume.editRecheckQuestionSkip": wire("src/core/runner/resume-apply.ts"),
67
- "resume.questionArgsShown": wire("src/core/runner/run-leg.ts"),
68
60
  "budget.exemptResult": wire("src/core/tool-result-budget.ts"),
69
61
  "compaction.compactableResult": wire("src/core/context-edit.ts"),
70
62
  };
@@ -112,7 +104,7 @@ export function seatOf(site, table, call) {
112
104
  const valueAt = (n) => (typeof table.get === "function" ? table.get(n) : table.has(n) ? true : undefined);
113
105
  if (r.kind === "seat" && r.rank === "tier") {
114
106
  let best;
115
- for (const n of names) {
107
+ for (const n of [call.toolName, ...names.filter((name) => name !== call.toolName)]) {
116
108
  const v = valueAt(n);
117
109
  if (v === undefined)
118
110
  continue;