@sema-agent/core 7.54.1 → 7.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (621) hide show
  1. package/CHANGELOG.md +950 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cascade.js +1 -1
  5. package/dist/agents/cc-peer-directory.d.ts +36 -0
  6. package/dist/agents/cc-peer-directory.js +139 -0
  7. package/dist/agents/cc-peer-wire.d.ts +105 -0
  8. package/dist/agents/cc-peer-wire.js +98 -0
  9. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  10. package/dist/agents/cc-uds-peer-channel.js +457 -0
  11. package/dist/agents/child-model-seat.d.ts +0 -11
  12. package/dist/agents/child-model-seat.js +0 -3
  13. package/dist/agents/cross-session-envelope.d.ts +4 -1
  14. package/dist/agents/cross-session-envelope.js +8 -1
  15. package/dist/agents/cross-session-judge.d.ts +2 -2
  16. package/dist/agents/list-agents-tool.d.ts +3 -1
  17. package/dist/agents/list-agents-tool.js +9 -8
  18. package/dist/agents/observer.d.ts +4 -5
  19. package/dist/agents/observer.js +2 -1
  20. package/dist/agents/peer-admission.d.ts +6 -0
  21. package/dist/agents/peer-admission.js +4 -1
  22. package/dist/agents/peer-directory.d.ts +65 -13
  23. package/dist/agents/peer-directory.js +90 -25
  24. package/dist/agents/peer-notices.d.ts +1 -1
  25. package/dist/agents/peer-session-drain.d.ts +3 -1
  26. package/dist/agents/peer-session-drain.js +3 -2
  27. package/dist/agents/read-inbox-tool.js +2 -1
  28. package/dist/agents/repair-loop.js +2 -2
  29. package/dist/agents/retain-ledger.d.ts +1 -1
  30. package/dist/agents/roster-store.d.ts +1 -1
  31. package/dist/agents/send-message-tool.d.ts +10 -0
  32. package/dist/agents/send-message-tool.js +37 -8
  33. package/dist/agents/subagent.d.ts +39 -82
  34. package/dist/agents/subagent.js +109 -106
  35. package/dist/agents/tool-filter.d.ts +31 -46
  36. package/dist/agents/tool-filter.js +13 -33
  37. package/dist/agents/verify.d.ts +6 -5
  38. package/dist/agents/verify.js +3 -3
  39. package/dist/brain/anthropic.js +43 -81
  40. package/dist/brain/errors.d.ts +15 -0
  41. package/dist/brain/errors.js +10 -0
  42. package/dist/brain/media-degrade.d.ts +18 -7
  43. package/dist/brain/media-degrade.js +13 -2
  44. package/dist/brain/model-capability.d.ts +37 -0
  45. package/dist/brain/model-capability.js +34 -0
  46. package/dist/brain/model-presets.d.ts +6 -12
  47. package/dist/brain/model-presets.js +1 -6
  48. package/dist/brain/open-responses.js +27 -35
  49. package/dist/brain/openai.js +30 -98
  50. package/dist/brain/provider-dialect.d.ts +39 -3
  51. package/dist/brain/provider-dialect.js +28 -0
  52. package/dist/brain/reasoning-request.d.ts +96 -0
  53. package/dist/brain/reasoning-request.js +174 -0
  54. package/dist/brain/reasoning.d.ts +12 -12
  55. package/dist/brain/reasoning.js +4 -3
  56. package/dist/brain/request-params.d.ts +62 -9
  57. package/dist/brain/request-params.js +42 -7
  58. package/dist/brain/retry.d.ts +1 -1
  59. package/dist/brain/route-adjudicator.d.ts +15 -0
  60. package/dist/brain/route-adjudicator.js +15 -0
  61. package/dist/brain/status-sink.d.ts +20 -0
  62. package/dist/brain/status-sink.js +7 -0
  63. package/dist/brain/stream-engine.js +6 -5
  64. package/dist/brain/stream-shared.d.ts +1 -1
  65. package/dist/core/a2a.d.ts +2 -1
  66. package/dist/core/a2a.js +19 -13
  67. package/dist/core/advisor-verdict.d.ts +120 -0
  68. package/dist/core/advisor-verdict.js +92 -0
  69. package/dist/core/agent-definition.d.ts +17 -8
  70. package/dist/core/allow-entry.d.ts +69 -36
  71. package/dist/core/allow-entry.js +81 -52
  72. package/dist/core/allow-rule-shadow.d.ts +10 -3
  73. package/dist/core/approval-object.d.ts +2 -1
  74. package/dist/core/approval-object.js +6 -6
  75. package/dist/core/ask-origin.d.ts +127 -29
  76. package/dist/core/ask-origin.js +87 -25
  77. package/dist/core/ask-question.d.ts +51 -8
  78. package/dist/core/ask-question.js +12 -7
  79. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  80. package/dist/core/ask-unresolvable-notice.js +16 -2
  81. package/dist/core/auto-compaction.d.ts +11 -8
  82. package/dist/core/auto-compaction.js +4 -2
  83. package/dist/core/auto-mode-arming.d.ts +2 -2
  84. package/dist/core/auto-mode-defaults.d.ts +8 -8
  85. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  86. package/dist/core/auto-mode-prompt.d.ts +1 -1
  87. package/dist/core/auto-mode.d.ts +17 -9
  88. package/dist/core/auto-mode.js +9 -6
  89. package/dist/core/background-agent-store.d.ts +3 -3
  90. package/dist/core/canonical-json.d.ts +1 -1
  91. package/dist/core/canonical-json.js +2 -2
  92. package/dist/core/checkpoint-generation.d.ts +53 -0
  93. package/dist/core/checkpoint-generation.js +35 -0
  94. package/dist/core/checkpoint-queries.d.ts +180 -0
  95. package/dist/core/checkpoint-queries.js +272 -0
  96. package/dist/core/checkpoint-requirements.d.ts +19 -4
  97. package/dist/core/checkpoint-requirements.js +8 -14
  98. package/dist/core/checkpoint-store.d.ts +165 -72
  99. package/dist/core/checkpoint-store.js +79 -82
  100. package/dist/core/child-clamp-seats.d.ts +6 -0
  101. package/dist/core/child-clamp-seats.js +3 -16
  102. package/dist/core/compliance.d.ts +2 -2
  103. package/dist/core/context-edit.d.ts +6 -7
  104. package/dist/core/cross-boundary-taint.d.ts +11 -4
  105. package/dist/core/cross-boundary-taint.js +3 -3
  106. package/dist/core/decision-receipt.d.ts +37 -3
  107. package/dist/core/decision-receipt.js +19 -19
  108. package/dist/core/delegation-not-started.d.ts +6 -0
  109. package/dist/core/delegation-not-started.js +17 -0
  110. package/dist/core/effective-path-target.d.ts +1 -1
  111. package/dist/core/engine-attestation.d.ts +93 -0
  112. package/dist/core/engine-attestation.js +70 -0
  113. package/dist/core/engine-capabilities.d.ts +4 -1
  114. package/dist/core/engine-capabilities.js +1 -1
  115. package/dist/core/engine-notice.d.ts +45 -12
  116. package/dist/core/exec-output-tail.d.ts +1 -1
  117. package/dist/core/file-history-retention.d.ts +1 -1
  118. package/dist/core/file-history-store.d.ts +147 -21
  119. package/dist/core/file-history-store.js +58 -32
  120. package/dist/core/gate-fold.d.ts +1 -1
  121. package/dist/core/gate-fold.js +24 -11
  122. package/dist/core/gate-lanes.js +81 -68
  123. package/dist/core/gate-outcome.d.ts +40 -6
  124. package/dist/core/gate-outcome.js +56 -0
  125. package/dist/core/governance-codes.d.ts +17 -3
  126. package/dist/core/governance-codes.js +16 -0
  127. package/dist/core/hands-band.d.ts +1 -1
  128. package/dist/core/hooks.d.ts +21 -20
  129. package/dist/core/hooks.js +3 -1
  130. package/dist/core/host-floor.d.ts +128 -0
  131. package/dist/core/host-floor.js +206 -0
  132. package/dist/core/host-target.d.ts +84 -0
  133. package/dist/core/host-target.js +92 -0
  134. package/dist/core/image-downsample.d.ts +1 -1
  135. package/dist/core/lsp-diagnostics.d.ts +4 -4
  136. package/dist/core/lsp.d.ts +3 -3
  137. package/dist/core/mailbox-store.d.ts +4 -0
  138. package/dist/core/mcp-connection-pool.d.ts +18 -2
  139. package/dist/core/mcp-connection-pool.js +53 -6
  140. package/dist/core/mcp-failure.d.ts +23 -4
  141. package/dist/core/mcp-failure.js +26 -11
  142. package/dist/core/mcp-listing-drift.d.ts +10 -0
  143. package/dist/core/mcp-listing-drift.js +6 -0
  144. package/dist/core/mcp-server-link.d.ts +173 -0
  145. package/dist/core/mcp-server-link.js +127 -0
  146. package/dist/core/mcp-server-spec.d.ts +4 -2
  147. package/dist/core/mcp-session-end.d.ts +26 -0
  148. package/dist/core/mcp-session-end.js +29 -0
  149. package/dist/core/mcp-startup-request.d.ts +17 -0
  150. package/dist/core/mcp-startup-request.js +17 -0
  151. package/dist/core/mcp.d.ts +17 -13
  152. package/dist/core/mcp.js +240 -189
  153. package/dist/core/media-byte-cap.d.ts +1 -1
  154. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  155. package/dist/core/memory-engine/engine.d.ts +9 -9
  156. package/dist/core/memory-engine/engine.js +4 -4
  157. package/dist/core/memory-engine/layout.d.ts +60 -8
  158. package/dist/core/memory-engine/layout.js +65 -6
  159. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  160. package/dist/core/memory-engine/tools.js +4 -1
  161. package/dist/core/mode-policy.d.ts +1 -1
  162. package/dist/core/model-seat.d.ts +10 -3
  163. package/dist/core/mods/classic-events.d.ts +67 -0
  164. package/dist/core/mods/classic-events.js +1 -0
  165. package/dist/core/mods/dollar.d.ts +13 -0
  166. package/dist/core/mods/extension-call.d.ts +31 -0
  167. package/dist/core/mods/extension-call.js +43 -0
  168. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  169. package/dist/core/mods/kernel/dispatch.js +140 -69
  170. package/dist/core/mods/kernel/events.d.ts +47 -11
  171. package/dist/core/mods/kernel/events.js +66 -42
  172. package/dist/core/mods/kernel/index.d.ts +4 -4
  173. package/dist/core/mods/kernel/index.js +2 -2
  174. package/dist/core/mods/kernel/receive.d.ts +39 -5
  175. package/dist/core/mods/kernel/receive.js +290 -17
  176. package/dist/core/mods/kernel/registration.d.ts +33 -2
  177. package/dist/core/mods/kernel/registration.js +6 -7
  178. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  179. package/dist/core/mods/kernel/site-rules.js +24 -42
  180. package/dist/core/mods/spec-seats.d.ts +69 -0
  181. package/dist/core/mods/spec-seats.js +114 -0
  182. package/dist/core/mods/stations.d.ts +28 -8
  183. package/dist/core/mods/stations.js +29 -13
  184. package/dist/core/mods/tool-call.d.ts +79 -0
  185. package/dist/core/mods/tool-call.js +152 -0
  186. package/dist/core/namespaced-rule-name.d.ts +44 -24
  187. package/dist/core/namespaced-rule-name.js +50 -43
  188. package/dist/core/output-style.d.ts +1 -1
  189. package/dist/core/param-rule-reach.d.ts +15 -0
  190. package/dist/core/param-rule-reach.js +30 -0
  191. package/dist/core/parent-spec-seat.d.ts +13 -1
  192. package/dist/core/parent-spec-seat.js +6 -0
  193. package/dist/core/park-selfcheck.js +1 -0
  194. package/dist/core/pause-registry.d.ts +16 -5
  195. package/dist/core/pause-registry.js +6 -2
  196. package/dist/core/peer-channel.d.ts +70 -0
  197. package/dist/core/peer-channel.js +1 -0
  198. package/dist/core/permission-rule-consent.d.ts +30 -5
  199. package/dist/core/permission-rule-consent.js +147 -50
  200. package/dist/core/permission-rule-model.d.ts +245 -65
  201. package/dist/core/permission-rule-model.js +421 -107
  202. package/dist/core/permission-rule-org.d.ts +6 -2
  203. package/dist/core/permission-rule-org.js +7 -3
  204. package/dist/core/permission-rule-provider.d.ts +6 -2
  205. package/dist/core/permission-rule-provider.js +41 -11
  206. package/dist/core/permission-rule-store.d.ts +22 -26
  207. package/dist/core/permission-rule-store.js +12 -6
  208. package/dist/core/permission-rule-sync.d.ts +11 -2
  209. package/dist/core/permission-rule-sync.js +11 -3
  210. package/dist/core/permission-rule-syntax.d.ts +5 -4
  211. package/dist/core/permission-rule-syntax.js +2 -2
  212. package/dist/core/permission-rules.d.ts +53 -15
  213. package/dist/core/permission-rules.js +125 -100
  214. package/dist/core/persisted-rule-arms.d.ts +6 -4
  215. package/dist/core/persisted-rule-arms.js +10 -12
  216. package/dist/core/present-plan-tool.js +3 -1
  217. package/dist/core/principal-name.d.ts +20 -0
  218. package/dist/core/principal-name.js +22 -0
  219. package/dist/core/prompt-section-seat.js +4 -6
  220. package/dist/core/protocol-http-auth.d.ts +26 -5
  221. package/dist/core/protocol-http-auth.js +137 -4
  222. package/dist/core/protocol-naming.d.ts +2 -2
  223. package/dist/core/read-only-shell-table.d.ts +1 -1
  224. package/dist/core/read-only-shell.d.ts +1 -1
  225. package/dist/core/retired-keys.d.ts +16 -0
  226. package/dist/core/retired-keys.js +16 -4
  227. package/dist/core/rewrite-rejudge.d.ts +60 -0
  228. package/dist/core/rewrite-rejudge.js +36 -0
  229. package/dist/core/roles.d.ts +34 -3
  230. package/dist/core/roles.js +66 -53
  231. package/dist/core/rule-lane-reads.d.ts +20 -15
  232. package/dist/core/rule-lane-reads.js +45 -17
  233. package/dist/core/rule-offer-read.d.ts +53 -0
  234. package/dist/core/rule-offer-read.js +146 -0
  235. package/dist/core/rule-owner.d.ts +46 -0
  236. package/dist/core/rule-owner.js +29 -0
  237. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  238. package/dist/core/runner/advisor-instructions.js +61 -0
  239. package/dist/core/runner/advisor-tool.d.ts +33 -0
  240. package/dist/core/runner/advisor-tool.js +112 -0
  241. package/dist/core/runner/announce-once-ledger.d.ts +18 -26
  242. package/dist/core/runner/announce-once-ledger.js +19 -46
  243. package/dist/core/runner/approval-feedback.js +6 -3
  244. package/dist/core/runner/assemble-result.d.ts +2 -1
  245. package/dist/core/runner/assemble-result.js +1 -1
  246. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  247. package/dist/core/runner/caller-roster.d.ts +21 -2
  248. package/dist/core/runner/caller-roster.js +38 -0
  249. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  250. package/dist/core/runner/capability-withheld-seat.js +24 -0
  251. package/dist/core/runner/classifier-ladder.d.ts +33 -13
  252. package/dist/core/runner/classifier-ladder.js +15 -14
  253. package/dist/core/runner/compaction-restate.d.ts +10 -6
  254. package/dist/core/runner/compaction-restate.js +9 -3
  255. package/dist/core/runner/construction-doors.js +3 -0
  256. package/dist/core/runner/contracts.d.ts +40 -33
  257. package/dist/core/runner/conversation-segment.d.ts +28 -0
  258. package/dist/core/runner/conversation-segment.js +42 -0
  259. package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
  260. package/dist/core/runner/cross-boundary-lane.js +58 -34
  261. package/dist/core/runner/decide-continuation.d.ts +7 -4
  262. package/dist/core/runner/decide-continuation.js +2 -2
  263. package/dist/core/runner/denial-limit-arms.d.ts +4 -4
  264. package/dist/core/runner/denial-limit-arms.js +1 -1
  265. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  266. package/dist/core/runner/derived-route-fallback.js +9 -7
  267. package/dist/core/runner/file-history-request.d.ts +18 -0
  268. package/dist/core/runner/file-history-request.js +21 -13
  269. package/dist/core/runner/file-history-restore.d.ts +45 -0
  270. package/dist/core/runner/file-history-restore.js +46 -0
  271. package/dist/core/runner/gate-exit.d.ts +9 -3
  272. package/dist/core/runner/gate-exit.js +11 -5
  273. package/dist/core/runner/image.d.ts +7 -17
  274. package/dist/core/runner/image.js +9 -60
  275. package/dist/core/runner/initial-run-state.js +1 -1
  276. package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
  277. package/dist/core/runner/permission-rule-lanes.js +38 -15
  278. package/dist/core/runner/person-path-rows.d.ts +12 -9
  279. package/dist/core/runner/person-path-rows.js +19 -8
  280. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  281. package/dist/core/runner/prepare-advisor.js +77 -0
  282. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  283. package/dist/core/runner/prepare-ask-lane.js +5 -2
  284. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  285. package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
  286. package/dist/core/runner/prepare-config-doors.d.ts +31 -38
  287. package/dist/core/runner/prepare-config-doors.js +57 -34
  288. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  289. package/dist/core/runner/prepare-defer-classify.js +7 -8
  290. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  291. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  292. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  293. package/dist/core/runner/prepare-file-history.js +41 -73
  294. package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
  295. package/dist/core/runner/prepare-gate-stations.js +12 -8
  296. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  297. package/dist/core/runner/prepare-hands-readface.js +15 -14
  298. package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
  299. package/dist/core/runner/prepare-inherited-gate.js +8 -6
  300. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  301. package/dist/core/runner/prepare-park-ask.js +12 -12
  302. package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
  303. package/dist/core/runner/prepare-policy-chain.js +68 -81
  304. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  305. package/dist/core/runner/prepare-project-context.js +6 -3
  306. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  307. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  308. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  309. package/dist/core/runner/prepare-prompt-inputs.js +4 -6
  310. package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
  311. package/dist/core/runner/prepare-protocol-tools.js +5 -4
  312. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  313. package/dist/core/runner/prepare-safety-scan.js +8 -23
  314. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  315. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  316. package/dist/core/runner/prepare-task.d.ts +1 -1
  317. package/dist/core/runner/prepare-task.js +41 -35
  318. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  319. package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
  320. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  321. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  322. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
  323. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  324. package/dist/core/runner/resume-admission.js +1 -1
  325. package/dist/core/runner/resume-apply.js +11 -12
  326. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  327. package/dist/core/runner/resume-claim.d.ts +4 -2
  328. package/dist/core/runner/resume-claim.js +15 -8
  329. package/dist/core/runner/resume-policy-outcome.js +1 -1
  330. package/dist/core/runner/retired-runner-deps.js +2 -1
  331. package/dist/core/runner/rewind-files.d.ts +15 -0
  332. package/dist/core/runner/rewind-files.js +132 -0
  333. package/dist/core/runner/run-attachment-seats.js +2 -2
  334. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  335. package/dist/core/runner/run-brain-sinks.js +4 -2
  336. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  337. package/dist/core/runner/run-compaction-machinery.js +2 -12
  338. package/dist/core/runner/run-git-lane.d.ts +1 -0
  339. package/dist/core/runner/run-harness-handlers.js +14 -7
  340. package/dist/core/runner/run-leg.d.ts +1 -1
  341. package/dist/core/runner/run-leg.js +43 -18
  342. package/dist/core/runner/run-settle-and-teardown.js +3 -2
  343. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  344. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  345. package/dist/core/runner/run-turn-boundary.js +15 -22
  346. package/dist/core/runner/runtask.d.ts +3 -0
  347. package/dist/core/runner/runtask.js +8 -9
  348. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  349. package/dist/core/runner/session-read-file-states.js +28 -0
  350. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  351. package/dist/core/runner/session-rule-policy.js +17 -31
  352. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  353. package/dist/core/runner/shell-env-withheld.js +51 -0
  354. package/dist/core/runner/side-call-account.d.ts +32 -8
  355. package/dist/core/runner/side-call-account.js +23 -1
  356. package/dist/core/runner/skills-seat.js +6 -2
  357. package/dist/core/runner/stream-settle-backstop.js +1 -1
  358. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  359. package/dist/core/runner/sub-agent-deny-lists.js +4 -6
  360. package/dist/core/runner/synthetic-tools.d.ts +16 -13
  361. package/dist/core/runner/synthetic-tools.js +8 -3
  362. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  363. package/dist/core/runner/tool-disclosure.js +3 -4
  364. package/dist/core/runner/tool-end-body.d.ts +1 -1
  365. package/dist/core/runner/tool-end-body.js +10 -9
  366. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  367. package/dist/core/runner/tool-face-overlay.js +17 -1
  368. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  369. package/dist/core/runner/tool-not-executed.js +11 -0
  370. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  371. package/dist/core/runner/tool-occurrence.js +7 -0
  372. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  373. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  374. package/dist/core/runner/turn-attachments.d.ts +91 -80
  375. package/dist/core/runner/turn-attachments.js +62 -37
  376. package/dist/core/runner-deps.d.ts +42 -42
  377. package/dist/core/runtime-caps.d.ts +4 -4
  378. package/dist/core/safety-axis-vocab.d.ts +6 -4
  379. package/dist/core/safety-axis-vocab.js +6 -5
  380. package/dist/core/safety-merge-corpus.js +26 -2
  381. package/dist/core/same-plain-value.d.ts +40 -0
  382. package/dist/core/same-plain-value.js +49 -0
  383. package/dist/core/scheduler.d.ts +1 -1
  384. package/dist/core/secret-env.d.ts +26 -3
  385. package/dist/core/secret-env.js +44 -8
  386. package/dist/core/select-model.js +3 -3
  387. package/dist/core/sensitive-path-policy.d.ts +1 -1
  388. package/dist/core/sensitive-path-policy.js +1 -1
  389. package/dist/core/session-policy-store.d.ts +102 -35
  390. package/dist/core/session-policy-store.js +210 -48
  391. package/dist/core/session-reconcile.d.ts +2 -2
  392. package/dist/core/session-store.d.ts +106 -37
  393. package/dist/core/session-store.js +165 -91
  394. package/dist/core/session.d.ts +101 -57
  395. package/dist/core/session.js +53 -0
  396. package/dist/core/shared-memory/tools.js +3 -1
  397. package/dist/core/shared-memory/types.d.ts +1 -1
  398. package/dist/core/shell-read-silence.d.ts +11 -12
  399. package/dist/core/shell-read-silence.js +9 -5
  400. package/dist/core/shell-run-candidates.js +3 -1
  401. package/dist/core/shell-wrapper-projection.js +1 -1
  402. package/dist/core/shell-wrapper-table.d.ts +14 -7
  403. package/dist/core/shell-wrapper-table.js +5 -4
  404. package/dist/core/side-query.d.ts +10 -0
  405. package/dist/core/side-query.js +15 -1
  406. package/dist/core/skill-grant.d.ts +7 -2
  407. package/dist/core/skill-grant.js +5 -0
  408. package/dist/core/skills-directory.js +6 -2
  409. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  410. package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
  411. package/dist/core/store-contracts/file-history-store-contract.js +74 -4
  412. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  413. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  414. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  415. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  416. package/dist/core/store-contracts/session-repo-contract.js +176 -0
  417. package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
  418. package/dist/core/store-contracts/session-store-contract.js +361 -51
  419. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  420. package/dist/core/stub-env.d.ts +2 -0
  421. package/dist/core/stub-env.js +1 -0
  422. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  423. package/dist/core/synthetic-read-verdict.js +3 -3
  424. package/dist/core/task-event.d.ts +42 -8
  425. package/dist/core/task-notification.d.ts +19 -15
  426. package/dist/core/task-registry-agent.d.ts +4 -4
  427. package/dist/core/task-registry-shared.d.ts +4 -4
  428. package/dist/core/task-registry-shared.js +1 -0
  429. package/dist/core/task-registry.d.ts +13 -4
  430. package/dist/core/task-registry.js +14 -2
  431. package/dist/core/task-result.d.ts +21 -3
  432. package/dist/core/task-spec.d.ts +69 -64
  433. package/dist/core/task-stream.d.ts +6 -6
  434. package/dist/core/task-tool-shape.d.ts +4 -4
  435. package/dist/core/tighten-task-spec.d.ts +1 -1
  436. package/dist/core/tighten-task-spec.js +2 -1
  437. package/dist/core/tool-catalog-entries.d.ts +36 -2
  438. package/dist/core/tool-catalog-entries.js +69 -43
  439. package/dist/core/tool-check-reading.d.ts +11 -0
  440. package/dist/core/tool-check-reading.js +11 -6
  441. package/dist/core/tool-conformance.js +1 -0
  442. package/dist/core/tool-errors.d.ts +2 -2
  443. package/dist/core/tool-face-reader.js +5 -3
  444. package/dist/core/tool-face.d.ts +21 -2
  445. package/dist/core/tool-face.js +1 -1
  446. package/dist/core/tool-model-gate.d.ts +5 -5
  447. package/dist/core/tool-name-aliases.d.ts +29 -8
  448. package/dist/core/tool-name-aliases.js +22 -4
  449. package/dist/core/tool-name-readings.d.ts +10 -43
  450. package/dist/core/tool-name-readings.js +2 -11
  451. package/dist/core/tool-policy.d.ts +85 -196
  452. package/dist/core/tool-policy.js +150 -175
  453. package/dist/core/tool-registry.d.ts +14 -7
  454. package/dist/core/tool-registry.js +17 -7
  455. package/dist/core/tool-result-store.js +5 -1
  456. package/dist/core/tool-roster.d.ts +57 -33
  457. package/dist/core/tool-roster.js +56 -68
  458. package/dist/core/tool-spec-members.js +8 -3
  459. package/dist/core/tool-spec.d.ts +53 -31
  460. package/dist/core/tools.js +51 -10
  461. package/dist/core/trace.d.ts +6 -2
  462. package/dist/core/types.d.ts +1 -1
  463. package/dist/core/untrusted-egress.d.ts +1 -1
  464. package/dist/core/untrusted-text.d.ts +1 -1
  465. package/dist/core/user-attachment.d.ts +8 -1
  466. package/dist/core/user-attachment.js +64 -4
  467. package/dist/core/warm-resume.d.ts +1 -1
  468. package/dist/core/wiring-manifest.d.ts +58 -0
  469. package/dist/core/wiring-manifest.js +14 -5
  470. package/dist/core/workflow-journal-store.d.ts +62 -0
  471. package/dist/core/workflow-journal-store.js +78 -2
  472. package/dist/core/workflow-run-store.d.ts +6 -0
  473. package/dist/core/workflow-run-store.js +2 -0
  474. package/dist/engine/compaction/compaction.d.ts +9 -9
  475. package/dist/engine/compaction/compaction.js +3 -2
  476. package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
  477. package/dist/engine/execution-env/node-execution-env.js +54 -24
  478. package/dist/engine/harness/agent-harness.d.ts +39 -9
  479. package/dist/engine/harness/agent-harness.js +87 -33
  480. package/dist/engine/harness/types.d.ts +58 -9
  481. package/dist/engine/harness/types.js +12 -1
  482. package/dist/engine/llm/types.d.ts +36 -19
  483. package/dist/engine/llm/validation.d.ts +4 -1
  484. package/dist/engine/llm/validation.js +13 -1
  485. package/dist/engine/loop/agent-loop.d.ts +23 -1
  486. package/dist/engine/loop/agent-loop.js +26 -34
  487. package/dist/engine/loop/types.d.ts +31 -19
  488. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  489. package/dist/engine/session/memory-repo.d.ts +18 -12
  490. package/dist/engine/session/memory-repo.js +24 -9
  491. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  492. package/dist/engine/session/parent-chain-guard.js +1 -1
  493. package/dist/engine/session/repo-utils.d.ts +32 -3
  494. package/dist/engine/session/repo-utils.js +50 -5
  495. package/dist/index.d.ts +47 -23
  496. package/dist/index.js +35 -17
  497. package/dist/internal/harness-types.d.ts +1 -1
  498. package/dist/internal/harness.d.ts +3 -3
  499. package/dist/internal/harness.js +2 -2
  500. package/dist/internal/llm.d.ts +2 -2
  501. package/dist/internal/llm.js +1 -1
  502. package/dist/orchestration/goal.js +2 -2
  503. package/dist/orchestration/run-workflow-tool.d.ts +8 -6
  504. package/dist/orchestration/run-workflow-tool.js +10 -6
  505. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  506. package/dist/orchestration/workflow-types.d.ts +18 -0
  507. package/dist/orchestration/workflow-types.js +6 -0
  508. package/dist/orchestration/workflow.d.ts +5 -13
  509. package/dist/orchestration/workflow.js +57 -49
  510. package/dist/prompt-assembly/artifact.d.ts +2 -2
  511. package/dist/prompt-assembly/artifact.js +5 -3
  512. package/dist/prompt-assembly/assemble.d.ts +3 -2
  513. package/dist/prompt-assembly/assemble.js +1 -1
  514. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  515. package/dist/prompt-assembly/catalog/schema.js +34 -2
  516. package/dist/prompt-assembly/catalog/sections.js +0 -1
  517. package/dist/prompt-assembly/composer.d.ts +3 -1
  518. package/dist/prompt-assembly/composer.js +1 -1
  519. package/dist/prompt-assembly/event-registry.js +2 -0
  520. package/dist/prompt-assembly/overlay.js +3 -3
  521. package/dist/prompt-assembly/renderers.d.ts +1 -1
  522. package/dist/prompt-assembly/renderers.js +0 -3
  523. package/dist/prompt-assembly/role-base.d.ts +15 -0
  524. package/dist/prompt-assembly/role-base.js +9 -0
  525. package/dist/prompt-assembly/select.d.ts +39 -14
  526. package/dist/prompt-assembly/select.js +47 -16
  527. package/dist/prompt-assembly/sugar.d.ts +17 -11
  528. package/dist/prompt-assembly/sugar.js +8 -3
  529. package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
  530. package/dist/prompt-assembly/tool-catalog.js +117 -4
  531. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  532. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  533. package/dist/prompt-assembly/types.d.ts +0 -7
  534. package/dist/prompts/default.d.ts +14 -14
  535. package/dist/scenarios/full-body.d.ts +15 -15
  536. package/dist/scenarios/full-body.js +4 -3
  537. package/dist/shell/lex.js +10 -1
  538. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  539. package/dist/stores/file/adoption/adopt.js +27 -33
  540. package/dist/stores/file/adoption/marker.d.ts +6 -13
  541. package/dist/stores/file/adoption/marker.js +9 -17
  542. package/dist/stores/file/checkpoint-store.d.ts +24 -0
  543. package/dist/stores/file/checkpoint-store.js +45 -7
  544. package/dist/stores/file/file-history-store.d.ts +20 -19
  545. package/dist/stores/file/file-history-store.js +157 -141
  546. package/dist/stores/file/fs-atomic.d.ts +15 -0
  547. package/dist/stores/file/fs-atomic.js +89 -14
  548. package/dist/stores/file/index.d.ts +1 -1
  549. package/dist/stores/file/index.js +2 -1
  550. package/dist/stores/file/mailbox-store.d.ts +3 -0
  551. package/dist/stores/file/mailbox-store.js +3 -1
  552. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  553. package/dist/stores/file/permission-rule-adopt.js +18 -18
  554. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  555. package/dist/stores/file/permission-rule-store.js +31 -18
  556. package/dist/stores/file/session-policy-store.d.ts +3 -3
  557. package/dist/stores/file/session-store.d.ts +54 -16
  558. package/dist/stores/file/session-store.js +114 -85
  559. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  560. package/dist/stores/file/workflow-journal-store.js +28 -13
  561. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  562. package/dist/tools/artifact/artifact-tool.js +5 -3
  563. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  564. package/dist/tools/fs/bash-program-position.js +56 -9
  565. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  566. package/dist/tools/fs/fs-bash.d.ts +2 -2
  567. package/dist/tools/fs/fs-bash.js +8 -6
  568. package/dist/tools/fs/fs-glob.d.ts +86 -0
  569. package/dist/tools/fs/fs-glob.js +226 -0
  570. package/dist/tools/fs/fs-read.js +14 -14
  571. package/dist/tools/fs/fs-search-tools.js +7 -7
  572. package/dist/tools/fs/fs-shared.d.ts +8 -8
  573. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  574. package/dist/tools/fs/notebook.d.ts +2 -2
  575. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  576. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  577. package/dist/tools/fs/pdf.d.ts +9 -6
  578. package/dist/tools/fs/pdf.js +3 -3
  579. package/dist/tools/fs/program-read-model.d.ts +57 -7
  580. package/dist/tools/fs/program-read-model.js +11 -1
  581. package/dist/tools/fs/program-read-model.rows.js +78 -21
  582. package/dist/tools/fs/read-deny-home.js +3 -2
  583. package/dist/tools/fs/read-deny.d.ts +29 -7
  584. package/dist/tools/fs/read-deny.js +63 -22
  585. package/dist/tools/fs/removal-targets.d.ts +18 -8
  586. package/dist/tools/fs/removal-targets.js +47 -20
  587. package/dist/tools/fs/safety.d.ts +9 -9
  588. package/dist/tools/fs/search.d.ts +16 -6
  589. package/dist/tools/fs/search.js +20 -26
  590. package/dist/tools/fs/shell-read-argv.js +89 -12
  591. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  592. package/dist/tools/fs/shell-read-bindings.js +41 -0
  593. package/dist/tools/fs/shell-read-check.js +12 -20
  594. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  595. package/dist/tools/fs/shell-read-environment.js +3 -2
  596. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  597. package/dist/tools/fs/shell-read-establish.js +19 -20
  598. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  599. package/dist/tools/fs/shell-read-judge.js +5 -2
  600. package/dist/tools/fs/shell-read-plan.js +24 -16
  601. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  602. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  603. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  604. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  605. package/dist/tools/fs/shell-reentry-text.js +40 -2
  606. package/dist/tools/loop-tick.d.ts +2 -2
  607. package/dist/tools/scheduler-tools.js +5 -1
  608. package/dist/tools/task-list.d.ts +7 -7
  609. package/dist/tools/task-list.js +5 -1
  610. package/dist/tools/todo.js +65 -64
  611. package/dist/tools/web.d.ts +20 -15
  612. package/dist/tools/web.js +55 -69
  613. package/dist/tools/worktree.d.ts +3 -3
  614. package/dist/tools/worktree.js +3 -1
  615. package/package.json +1 -1
  616. package/test/export-surface.snapshot.json +5894 -5638
  617. package/wire-changes/core@7.55.0.json +3318 -0
  618. package/wire-changes/core@7.56.0.json +3891 -0
  619. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  620. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  621. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -6,6 +6,7 @@ export const TASK_GET_TOOL_NAME = "TaskGet";
6
6
  export const TASK_UPDATE_TOOL_NAME = "TaskUpdate";
7
7
  export const TASK_LIST_TOOL_NAME = "TaskList";
8
8
  export const TODO_WRITE_TOOL_NAME = "TodoWrite";
9
+ export const OUTPUT_TOOL_NAME = "StructuredOutput";
9
10
  export const REFRESH_MCP_TOOLS_TOOL_NAME = "RefreshMcpTools";
10
11
  export const ARTIFACT_TOOL_NAME = "Artifact";
11
12
  const shellRuleFace = (params) => ({ grammar: "command", primaryParams: ["command"], params });
@@ -57,7 +58,7 @@ export const TOOL_CATALOG_ENTRIES = [
57
58
  },
58
59
  {
59
60
  id: "bash", name: "Bash", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"],
60
- 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"],
61
62
  face: {
62
63
  family: "shell", boundaryLegs: ["env"], effect: "write", contentOrigin: "execution", contract: c(FULL_SHELL_CONTRACT_ID),
63
64
  ruleFace: SHELL_RULE_FACE,
@@ -115,55 +116,56 @@ export const TOOL_CATALOG_ENTRIES = [
115
116
  },
116
117
  {
117
118
  id: "artifact", name: ARTIFACT_TOOL_NAME, source: "builtin", definedIn: "src/tools/artifact/artifact-tool.ts", mountedBy: ["optional"], cards: ["artifact"],
118
- face: { family: "other", boundaryLegs: "per_call", effect: "write", contract: c("core.artifact@1"), ruleFace: { primaryParams: ["action"] }, renderHints: { summaryParams: ["action", "file_path", "url"] } },
119
+ face: { family: "other", boundaryLegs: "per_call", effect: "write", contract: c("core.artifact@1"), ruleFace: { primaryParams: ["action"], params: ["action", "file_path", "url", "title", "description", "favicon", "label", "baseVersion", "force", "publishContext", "scope", "limit", "path"] }, renderHints: { summaryParams: ["action", "file_path", "url"] } },
119
120
  },
120
- { id: "enter-worktree", name: "EnterWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.enter_worktree@1") } },
121
- { id: "exit-worktree", name: "ExitWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.exit_worktree@1") } },
122
- { id: "task-output-hands", name: "TaskOutput", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", boundaryLegs: ["env"], effect: "read", contract: TASK_OUTPUT_CONTRACT } },
123
- { id: "task-stop-hands", name: "TaskStop", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", boundaryLegs: ["env"], effect: "write", contract: TASK_STOP_CONTRACT } },
124
- { id: "task-output", name: "TaskOutput", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-output"], face: { family: "delegate", boundaryLegs: "per_call", effect: "read", contract: TASK_OUTPUT_CONTRACT } },
125
- { id: "task-stop", name: "TaskStop", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-stop"], face: { family: "delegate", boundaryLegs: "per_call", effect: "write", contract: TASK_STOP_CONTRACT } },
121
+ { id: "enter-worktree", name: "EnterWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.enter_worktree@1"), ruleFace: { params: ["name", "path", "baseRef"] } } },
122
+ { id: "exit-worktree", name: "ExitWorktree", source: "builtin", definedIn: "src/tools/worktree.ts", mountedBy: ["hands"], cards: ["worktree"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.exit_worktree@1"), ruleFace: { params: ["keep", "discardChanges", "action", "discard_changes"] } } },
123
+ { id: "task-output-hands", name: "TaskOutput", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", boundaryLegs: ["env"], effect: "read", contract: TASK_OUTPUT_CONTRACT, ruleFace: { params: ["task_id", "filter"] } } },
124
+ { id: "task-stop-hands", name: "TaskStop", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"], cards: [], face: { family: "delegate", boundaryLegs: ["env"], effect: "write", contract: TASK_STOP_CONTRACT, ruleFace: { params: ["task_id", "shell_id"] } } },
125
+ { id: "task-output", name: "TaskOutput", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-output"], face: { family: "delegate", boundaryLegs: "per_call", effect: "read", contract: TASK_OUTPUT_CONTRACT, ruleFace: { params: ["task_id", "block", "timeout", "filter"] } } },
126
+ { id: "task-stop", name: "TaskStop", source: "builtin", definedIn: "src/core/task-registry.ts", mountedBy: ["delegation"], cards: ["task-stop"], face: { family: "delegate", boundaryLegs: "per_call", effect: "write", contract: TASK_STOP_CONTRACT, ruleFace: { params: ["task_id", "shell_id"] } } },
126
127
  { id: "monitor", name: "Monitor", source: "builtin", definedIn: "src/tools/monitor.ts", mountedBy: ["backgroundTasks"], cards: ["monitor-start", "readonly_out_of_root", "read_unestablished"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.monitor@1"), ruleFace: shellRuleFace(["command", "description", "timeout_ms", "persistent"]), offloadThresholdChars: 10_000 } },
127
- { id: "send-message", name: "SendMessage", protocol: ["teammate"], source: "builtin", definedIn: "src/agents/send-message-tool.ts", mountedBy: ["delegation", "hostInternals", "peerLane"], cards: ["send-message"], face: { family: "protocol", boundaryLegs: ["outside_write"], effect: "write", contract: c("core.send_message@1") } },
128
- { id: "agent-transcript", name: "AgentTranscript", source: "builtin", definedIn: "src/agents/agent-transcript-tool.ts", mountedBy: ["delegation"], cards: ["agent-transcript"], face: { family: "delegate", boundaryLegs: [], effect: "read", contract: c("core.agent_transcript@1") } },
129
- { id: "list-agents", name: "ListAgents", source: "builtin", definedIn: "src/agents/list-agents-tool.ts", mountedBy: ["delegation", "peerLane"], cards: ["list-agents"], face: { family: "protocol", boundaryLegs: [], effect: "read", aliases: ["ListPeers"], contract: c("core.list_agents@1") } },
130
- { id: "read-inbox", name: "ReadInbox", source: "builtin", definedIn: "src/agents/read-inbox-tool.ts", mountedBy: ["peerLane"], cards: ["read-inbox"], face: { family: "protocol", boundaryLegs: [], effect: "read", contract: c("core.read_inbox@1"), offload: false, budgetExempt: true } },
131
- { id: "workflow", name: "Workflow", source: "builtin", definedIn: "src/orchestration/run-workflow-tool.ts", mountedBy: ["workflow"], cards: ["workflow-run"], face: { family: "delegate", boundaryLegs: [], effect: "write", contract: c("core.workflow@1") } },
132
- { id: "report-blocked", name: "ReportBlocked", protocol: ["delegated"], source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.report_blocked@1") } },
133
- { id: "report-findings", name: "ReportFindings", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: ["report-findings"], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.report_findings@1") } },
134
- { id: "structured-output", name: "StructuredOutput", protocol: ["structured"], source: "synthetic", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.structured_output@1") } },
135
- { id: "skill", name: "Skill", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.skill@1") } },
136
- { id: "read-tool-result", name: "ReadToolResult", source: "builtin", definedIn: "src/core/tool-result-store.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.read_tool_result@1"), budgetExempt: true } },
137
- { id: "tool-search", name: "ToolSearch", source: "builtin", definedIn: "src/core/runner/tool-disclosure.ts", mountedBy: ["optional"], cards: ["tool-search"], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.tool_search@1") } },
138
- { id: "ask-user-question", name: "AskUserQuestion", source: "builtin", definedIn: "src/core/ask-question.ts", mountedBy: ["optional"], cards: ["ask-question"], face: { family: "other", boundaryLegs: [], effect: "read", contract: c("core.ask_user_question@1"), renderHints: { approvalCard: "question" } } },
139
- { id: "exit-plan-mode", name: "ExitPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["exit-plan-mode"], face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.exit_plan_mode@1"), renderHints: { userFacingName: "", approvalCard: "plan" } } },
140
- { id: "enter-plan-mode", name: "EnterPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["enter-plan-mode"], face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.enter_plan_mode@1") } },
141
- { id: "refresh-mcp-tools", name: REFRESH_MCP_TOOLS_TOOL_NAME, source: "builtin", definedIn: "src/core/runner/prepare-protocol-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "protocol", boundaryLegs: ["outside_read"], effect: "read" } },
142
- { id: "memory-search", name: "memory_search", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_search@1", "7"), offload: false } },
143
- { id: "memory-get", name: "memory_get", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_get@1", "7"), offload: false } },
144
- { id: "memory-index", name: "memory_index", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_index@1", "2"), offload: false } },
145
- { id: "memory-list", name: "memory_list", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contract: c("core.memory_list@1"), offload: false } },
146
- { id: "memory-read", name: "memory_read", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contract: c("core.memory_read@1"), offload: false } },
147
- { id: "cron-create", name: "CronCreate", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-create"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.cron_create@1") } },
148
- { id: "cron-delete", name: "CronDelete", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-delete"], face: { family: "other", boundaryLegs: ["env"], effect: "idempotent", contract: c("core.cron_delete@1") } },
149
- { id: "cron-list", name: "CronList", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-list"], face: { family: "other", boundaryLegs: ["env"], effect: "read", contract: c("core.cron_list@1") } },
150
- { id: "schedule-wakeup", name: "ScheduleWakeup", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["schedule-wakeup"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.schedule_wakeup@1") } },
128
+ { id: "send-message", name: "SendMessage", protocol: ["teammate"], source: "builtin", definedIn: "src/agents/send-message-tool.ts", mountedBy: ["delegation", "hostInternals", "peerLane"], cards: ["send-message"], face: { family: "protocol", boundaryLegs: ["outside_write"], effect: "write", contract: c("core.send_message@1"), ruleFace: { params: ["to", "message", "summary", "notify_when_idle", "urgent"] } } },
129
+ { id: "agent-transcript", name: "AgentTranscript", source: "builtin", definedIn: "src/agents/agent-transcript-tool.ts", mountedBy: ["delegation"], cards: ["agent-transcript"], face: { family: "delegate", boundaryLegs: [], effect: "read", contract: c("core.agent_transcript@1"), ruleFace: { params: ["id", "lastN"] } } },
130
+ { id: "list-agents", name: "ListAgents", source: "builtin", definedIn: "src/agents/list-agents-tool.ts", mountedBy: ["delegation", "peerLane"], cards: ["list-agents"], face: { family: "protocol", boundaryLegs: [], effect: "read", aliases: ["ListPeers"], contract: c("core.list_agents@1"), ruleFace: { params: ["includeAll"] } } },
131
+ { id: "read-inbox", name: "ReadInbox", source: "builtin", definedIn: "src/agents/read-inbox-tool.ts", mountedBy: ["peerLane"], cards: ["read-inbox"], face: { family: "protocol", boundaryLegs: [], effect: "read", contract: c("core.read_inbox@1"), offload: false, budgetExempt: true, ruleFace: { params: ["limit"] } } },
132
+ { id: "workflow", name: "Workflow", source: "builtin", definedIn: "src/orchestration/run-workflow-tool.ts", mountedBy: ["workflow"], cards: ["workflow-run"], face: { family: "delegate", boundaryLegs: [], effect: "write", contract: c("core.workflow@1"), renderHints: { approvalCard: "workflow" }, ruleFace: { params: ["script", "name", "scriptPath", "resumeFromRunId"] } } },
133
+ { id: "report-blocked", name: "ReportBlocked", protocol: ["delegated"], source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.report_blocked@1"), ruleFace: { params: ["reason"] } } },
134
+ { id: "report-findings", name: "ReportFindings", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: ["report-findings"], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.report_findings@1"), ruleFace: { params: ["level"] } } },
135
+ { id: "structured-output", name: OUTPUT_TOOL_NAME, protocol: ["structured"], source: "synthetic", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.structured_output@1") } },
136
+ { id: "skill", name: "Skill", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.skill@1"), renderHints: { approvalCard: "skill" }, ruleFace: { params: ["skill", "args"] } } },
137
+ { id: "read-tool-result", name: "ReadToolResult", source: "builtin", definedIn: "src/core/tool-result-store.ts", mountedBy: ["optional"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.read_tool_result@1"), budgetExempt: true, ruleFace: { params: ["ref", "offset", "limit"] } } },
138
+ { id: "tool-search", name: "ToolSearch", source: "builtin", definedIn: "src/core/runner/tool-disclosure.ts", mountedBy: ["optional"], cards: ["tool-search"], face: { family: "scaffold", boundaryLegs: [], effect: "read", contract: c("core.tool_search@1"), ruleFace: { params: ["query", "max_results"] } } },
139
+ { id: "advisor", name: "advisor", source: "builtin", definedIn: "src/core/runner/advisor-tool.ts", mountedBy: ["optional"], cards: ["advisor"], face: { family: "scaffold", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.advisor@1"), offload: false, budgetExempt: true, ruleFace: { params: [] } } },
140
+ { id: "ask-user-question", name: "AskUserQuestion", source: "builtin", definedIn: "src/core/ask-question.ts", mountedBy: ["optional"], cards: ["ask-question"], face: { family: "other", boundaryLegs: [], effect: "read", contract: c("core.ask_user_question@1"), renderHints: { approvalCard: "question" }, ruleFace: { params: [] } } },
141
+ { id: "exit-plan-mode", name: "ExitPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["exit-plan-mode"], face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.exit_plan_mode@1"), renderHints: { userFacingName: "", approvalCard: "plan" }, ruleFace: { params: ["plan"] } } },
142
+ { id: "enter-plan-mode", name: "EnterPlanMode", source: "builtin", definedIn: "src/core/present-plan-tool.ts", mountedBy: ["optional"], cards: ["enter-plan-mode"], face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.enter_plan_mode@1"), ruleFace: { params: [] } } },
143
+ { id: "refresh-mcp-tools", name: REFRESH_MCP_TOOLS_TOOL_NAME, source: "builtin", definedIn: "src/core/runner/prepare-protocol-tools.ts", mountedBy: ["optional"], cards: [], face: { family: "protocol", boundaryLegs: ["outside_read"], effect: "read", ruleFace: { params: ["server"] } } },
144
+ { id: "memory-search", name: "memory_search", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_search@1", "7"), offload: false, ruleFace: { params: ["query", "limit", "includeSuperseded", "includeShadowed"] } } },
145
+ { id: "memory-get", name: "memory_get", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_get@1", "7"), offload: false, ruleFace: { params: ["id", "slug", "scope", "offset", "limit", "lineCursor"] } } },
146
+ { id: "memory-index", name: "memory_index", source: "builtin", definedIn: "src/core/memory-engine/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contentOrigin: "local", contract: c("core.memory_index@1", "2"), offload: false, ruleFace: { params: ["offset", "limit", "listingRev", "scope", "includeSuperseded", "includeShadowed"] } } },
147
+ { id: "memory-list", name: "memory_list", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contract: c("core.memory_list@1"), offload: false, ruleFace: { params: ["store", "path_prefix", "cursor"] } } },
148
+ { id: "memory-read", name: "memory_read", source: "builtin", definedIn: "src/core/shared-memory/tools.ts", mountedBy: ["memory"], cards: [], face: { family: "memory", boundaryLegs: [], effect: "read", contract: c("core.memory_read@1"), offload: false, ruleFace: { params: ["store", "path"] } } },
149
+ { id: "cron-create", name: "CronCreate", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-create"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.cron_create@1"), ruleFace: { params: ["prompt", "cron", "recurring", "durable", "label"] } } },
150
+ { id: "cron-delete", name: "CronDelete", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-delete"], face: { family: "other", boundaryLegs: ["env"], effect: "idempotent", contract: c("core.cron_delete@1"), ruleFace: { params: ["id"] } } },
151
+ { id: "cron-list", name: "CronList", protocol: ["teammate"], source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["cron-list"], face: { family: "other", boundaryLegs: ["env"], effect: "read", contract: c("core.cron_list@1"), ruleFace: { params: [] } } },
152
+ { id: "schedule-wakeup", name: "ScheduleWakeup", source: "builtin", definedIn: "src/tools/scheduler-tools.ts", mountedBy: ["scheduler"], cards: ["schedule-wakeup"], face: { family: "other", boundaryLegs: ["env"], effect: "write", contract: c("core.schedule_wakeup@1"), ruleFace: { params: ["delaySeconds", "reason", "prompt", "stop", "noop"] } } },
151
153
  {
152
154
  id: "web-fetch", name: "WebFetch", source: "builtin", definedIn: "src/tools/web.ts", mountedBy: ["scenario"], cards: ["web-fetch"],
153
- face: { family: "web", boundaryLegs: ["outside_read"], effect: "read", contentOrigin: "external", contract: c("core.web_fetch@1"), ruleFace: { primaryParams: ["url"] }, renderHints: { summaryParams: ["url"], approvalCard: "fetch" }, compactable: true },
155
+ face: { family: "web", boundaryLegs: ["outside_read"], effect: "read", contentOrigin: "external", contract: c("core.web_fetch@1"), hostTarget: { param: "url" }, ruleFace: { primaryParams: ["url"], params: ["url", "prompt"] }, renderHints: { summaryParams: ["url"], approvalCard: "fetch" }, compactable: true },
154
156
  },
155
157
  {
156
158
  id: "web-search", name: "WebSearch", source: "builtin", definedIn: "src/tools/web.ts", mountedBy: ["scenario"], cards: ["web-search"],
157
- face: { family: "web", boundaryLegs: ["outside_read"], effect: "read", contentOrigin: "external", contract: c("core.web_search@1"), ruleFace: { primaryParams: ["query"] }, renderHints: { summaryParams: ["query"] }, compactable: true },
159
+ face: { family: "web", boundaryLegs: ["outside_read"], effect: "read", contentOrigin: "external", contract: c("core.web_search@1"), ruleFace: { primaryParams: ["query"], params: ["query"] }, renderHints: { summaryParams: ["query"] }, compactable: true },
158
160
  },
159
- { id: "todo-write", name: TODO_WRITE_TOOL_NAME, source: "builtin", definedIn: "src/tools/todo.ts", mountedBy: ["scenario"], cards: ["todo"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "idempotent", contract: c("core.todo_write@1") } },
160
- { id: "task-create", name: TASK_CREATE_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "write", contract: c("core.task_create@1") } },
161
- { id: "task-get", name: TASK_GET_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.task_get@1") } },
162
- { id: "task-update", name: TASK_UPDATE_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "idempotent", contract: c("core.task_update@1") } },
163
- { id: "task-list", name: TASK_LIST_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task-list"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.task_list@1") } },
164
- { id: "agent", name: "Agent", source: "builtin", definedIn: "src/agents/subagent.ts", mountedBy: ["scenario"], cards: ["agent", "fork"], face: { family: "delegate", boundaryLegs: [], contentOrigin: "local", contract: c("core.agent@1") } },
165
- { id: "observer-report", name: "ObserverReport", protocol: ["observer"], source: "builtin", definedIn: "src/agents/observer.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "write", contract: c("core.observer_report@1") } },
166
- { id: "declare-done", name: "DeclareDone", protocol: ["goal"], source: "builtin", definedIn: "src/orchestration/goal.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read" } },
161
+ { id: "todo-write", name: TODO_WRITE_TOOL_NAME, source: "builtin", definedIn: "src/tools/todo.ts", mountedBy: ["scenario"], cards: ["todo"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "idempotent", contract: c("core.todo_write@1"), ruleFace: { params: [] } } },
162
+ { id: "task-create", name: TASK_CREATE_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "write", contract: c("core.task_create@1"), ruleFace: { params: ["subject", "description", "activeForm"] } } },
163
+ { id: "task-get", name: TASK_GET_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.task_get@1"), ruleFace: { params: ["taskId"] } } },
164
+ { id: "task-update", name: TASK_UPDATE_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "idempotent", contract: c("core.task_update@1"), ruleFace: { params: ["taskId", "status", "subject", "description", "activeForm"] } } },
165
+ { id: "task-list", name: TASK_LIST_TOOL_NAME, protocol: ["teammate"], source: "builtin", definedIn: "src/tools/task-list.ts", mountedBy: ["scenario"], cards: ["task-list"], modelGate: "task-scaffold", face: { family: "plan", boundaryLegs: [], effect: "read", contract: c("core.task_list@1"), ruleFace: { params: [] } } },
166
+ { id: "agent", name: "Agent", source: "builtin", definedIn: "src/agents/subagent.ts", mountedBy: ["scenario"], cards: ["agent", "fork"], face: { family: "delegate", boundaryLegs: [], contentOrigin: "local", contract: c("core.agent@1"), ruleFace: { params: ["subagent_type", "description", "prompt", "name", "cwd", "model", "isolation", "run_in_background"] } } },
167
+ { id: "observer-report", name: "ObserverReport", protocol: ["observer"], source: "builtin", definedIn: "src/agents/observer.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "write", contract: c("core.observer_report@1"), ruleFace: { params: ["report"] } } },
168
+ { id: "declare-done", name: "DeclareDone", protocol: ["goal"], source: "builtin", definedIn: "src/orchestration/goal.ts", mountedBy: ["scenario"], cards: [], face: { family: "scaffold", boundaryLegs: [], effect: "read", ruleFace: { params: ["summary"] } } },
167
169
  ];
168
170
  export const ENGINE_CARDS = Object.freeze({
169
171
  mcp: "src/core/mcp.ts",
@@ -172,18 +174,42 @@ export const ENGINE_CARDS = Object.freeze({
172
174
  read_path_denied: "src/tools/fs/safety.ts",
173
175
  readonly_out_of_root: "src/tools/fs/shell-read-check.ts",
174
176
  read_unestablished: "src/tools/fs/shell-read-check.ts",
177
+ bash_self_kill_refused: "src/tools/fs/pattern-kill-guard.ts",
175
178
  });
176
179
  const byId = new Map();
177
180
  for (const e of TOOL_CATALOG_ENTRIES) {
178
181
  if (byId.has(e.id))
179
182
  throw new Error(`tool catalog: duplicate definition id ${JSON.stringify(e.id)}`);
183
+ if (e.face.pathTarget !== undefined && e.face.hostTarget !== undefined)
184
+ throw new Error(`tool catalog: ${JSON.stringify(e.id)} declares a path target and a host target — a face names one protected target`);
180
185
  byId.set(e.id, e);
181
186
  }
187
+ const CATALOG_CONTRACTS = new WeakSet();
182
188
  export function toolFace(id) {
183
189
  const e = byId.get(id);
184
190
  if (e === undefined)
185
191
  throw new Error(`tool catalog: no definition ${JSON.stringify(id)}`);
186
- return { contentOrigin: "local", ...structuredClone(e.face) };
192
+ const face = { contentOrigin: "local", ...structuredClone(e.face) };
193
+ if (face.contract !== undefined)
194
+ CATALOG_CONTRACTS.add(Object.freeze(face.contract));
195
+ return face;
196
+ }
197
+ export function isCatalogContract(contract) {
198
+ return typeof contract === "object" && contract !== null && CATALOG_CONTRACTS.has(contract);
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"]);
210
+ export function mountRuleFace(id) {
211
+ const primaryParams = toolFace(id).ruleFace?.primaryParams;
212
+ return primaryParams === undefined ? undefined : { primaryParams: [...primaryParams] };
187
213
  }
188
214
  function deepFreeze(value) {
189
215
  if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
@@ -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
  }
@@ -33,5 +33,6 @@ export const TOOL_CONFORMANCE_VECTORS = [
33
33
  { name: "ToolSearch", why: "needs a deferred tool" },
34
34
  { name: "RefreshMcpTools", why: "needs a declared MCP server" },
35
35
  { name: "EnterPlanMode", why: "needs a checkpoint store beside plan mode" },
36
+ { name: "advisor", why: "needs a named advisor model and a ranked pair (TaskSpec.advisorModel, RunnerDeps.tiers)" },
36
37
  ]),
37
38
  ];
@@ -2,7 +2,7 @@ import type { TSchema } from "typebox";
2
2
  /**
3
3
  * Truncate a long error to head + "[N characters truncated]" + tail (design/64 §11.2, CC parity).
4
4
  *
5
- * Anchored on CC 2.1.220 `A7e` (the current authority; the previous anchor was CC 88's `toolErrors.ts`,
5
+ * Cut on the reference's current rule (an older implementation
6
6
  * which cut at raw code-unit indices): head and tail are cut on a code-POINT boundary — an astral character
7
7
  * straddling either cut is dropped whole rather than emitted as a lone surrogate — and the reported count is
8
8
  * `len − head − tail`, i.e. derived from what was actually KEPT, so a rollback is not under-reported.
@@ -10,7 +10,7 @@ import type { TSchema } from "typebox";
10
10
  * DELIBERATE DIVERGENCE from the sibling truncators in this repo (mcp.ts `truncateMcpErrorText`,
11
11
  * engine/compaction `truncateForSummary`, untrusted-egress `boundedString`), which iterate the kept length
12
12
  * down so the marker fits INSIDE the budget (RB-152): here the marker is NOT budgeted — a barely-over input
13
- * comes back ~36 chars LONGER than the budget. That is CC-verbatim behaviour (`A7e` keeps 5000+marker+5000),
13
+ * comes back ~36 chars LONGER than the budget. That is the reference's behaviour (it keeps 5000+marker+5000),
14
14
  * it is pinned as a contract in test/core-toolgate-coverage.test.ts, and changing it would be a divergence
15
15
  * FROM the anchor, not a fix. Recorded as an intentional divergence in the cc-parity divergence registry
16
16
  * (internal assets repo, `cc-parity/`), not as an open defect.
@@ -2,11 +2,13 @@ import { dataKind, perToolEmptyName, perToolEntryRefusal, quotedName, receivePer
2
2
  import { isPlainRecord } from "./mods/kernel/receive.js";
3
3
  import { faceProblem } from "./runner/tool-face-overlay.js";
4
4
  import { inlineUntrusted } from "./untrusted-text.js";
5
- const TOOL_FACE_MEMBERS = { family: true, pathTarget: true, renderHints: true, ruleFace: true };
5
+ const TOOL_FACE_MEMBERS = { family: true, pathTarget: true, hostTarget: true, renderHints: true, ruleFace: true };
6
6
  const PATH_TARGET_KINDS = { param: "string", aliases: "list", access: "string", skillScopeEligible: "boolean", base: "string", absent: "string", patternParam: "string" };
7
7
  const PATH_TARGET_REQUIRED = ["param", "access"];
8
+ const HOST_TARGET_KINDS = { param: "string" };
9
+ const HOST_TARGET_REQUIRED = ["param"];
8
10
  const RENDER_HINT_KINDS = { userFacingName: "string", activity: "string", summaryParams: "list", resultCards: "list", approvalCard: "string" };
9
- const RULE_FACE_KINDS = { primaryParams: "list", params: "list" };
11
+ const RULE_FACE_KINDS = { primaryParams: "list", params: "list", nameValues: "list" };
10
12
  function kindProblem(label, value, kind) {
11
13
  if (value === undefined)
12
14
  return undefined;
@@ -47,7 +49,7 @@ function readOneToolFace(raw) {
47
49
  const face = membersOf(raw, "the face", Object.keys(TOOL_FACE_MEMBERS));
48
50
  if (typeof face === "string")
49
51
  return face;
50
- const records = { pathTarget: [PATH_TARGET_KINDS, PATH_TARGET_REQUIRED], renderHints: [RENDER_HINT_KINDS, []], ruleFace: [RULE_FACE_KINDS, []] };
52
+ const records = { pathTarget: [PATH_TARGET_KINDS, PATH_TARGET_REQUIRED], hostTarget: [HOST_TARGET_KINDS, HOST_TARGET_REQUIRED], renderHints: [RENDER_HINT_KINDS, []], ruleFace: [RULE_FACE_KINDS, []] };
51
53
  const entries = [];
52
54
  for (const member of Object.keys(face)) {
53
55
  const value = face[member];
@@ -40,7 +40,7 @@ import type { AssertAllKeysHandled } from "./ask-origin.js";
40
40
  /** The closed set of specialised approval cards a shell may pre-select from a render hint. The hint is a
41
41
  * PRE-FILTER: the shell owns each card's input schema and validates the call's full args before
42
42
  * mounting the card (design/388 §2.5 boundary ①). */
43
- export declare const TOOL_APPROVAL_CARDS: readonly ["file-edit", "file-write", "notebook-edit", "shell", "fetch", "plan", "question", "generic"];
43
+ export declare const TOOL_APPROVAL_CARDS: readonly ["file-edit", "file-write", "notebook-edit", "shell", "fetch", "skill", "workflow", "plan", "question", "generic"];
44
44
  export type ToolApprovalCard = (typeof TOOL_APPROVAL_CARDS)[number];
45
45
  /** Membership in the closed set — the one screen a stored or declared card word passes before it is read. */
46
46
  export declare function isToolApprovalCard(word: unknown): word is ToolApprovalCard;
@@ -141,16 +141,34 @@ export interface ToolRosterPathTarget extends ToolCallPathTarget {
141
141
  * So the floor hands over the slot and keeps its mouth shut about the resolution.
142
142
  */
143
143
  export declare function pathTargetSlotOnly(pt: ToolCallPathTarget): ToolCallPathTarget;
144
+ /**
145
+ * The parameter that names the URL a tool's call reaches — the HOST-RULE face: the slot a `<Tool>(domain:<host>)` rule of the
146
+ * tool's name is read on, in every direction (deny / ask / allow), by the one host reader (`callHostTargetOf`, host-target.ts).
147
+ * Host rules are a grammar of a tool NAME the catalog declares one for (today `WebFetch`); a face may declare a slot only on a
148
+ * tool of such a name (its wire name), and is refused on any other (`config.tool_face_invalid`). It says WHERE the named host is,
149
+ * never where the execution goes after it: only the engine's own fetch tool guarantees it connects to no host the gate did not
150
+ * judge (a cross-host redirect is handed back to the model). A face declares one protected target — this or a
151
+ * {@link ToolPathTarget}, never both. One shape for every spelling (a catalog row, a `ToolSpec`, the roster row, the call face,
152
+ * the parked approval row): the slot is all it carries.
153
+ */
154
+ export interface ToolHostTarget {
155
+ readonly param: string;
156
+ }
144
157
  /**
145
158
  * The parameter vocabulary a permission rule (`Tool(param:pattern)`) may name. DERIVED by default from
146
159
  * the tool's schema: the SCALAR top-level parameters (string/number/integer/boolean and their enum/const/
147
160
  * union forms) plus {@link ToolPathTarget.aliases}; object/array parameters never enter (a rule on them
148
- * can never match — `matchParamRules` skips non-scalar values). A declaration can only NARROW the derived
161
+ * can never match — the argument predicate `paramRuleReaches` skips non-scalar values). A declaration can only NARROW the derived
149
162
  * set; `primaryParams` defaults to the path target's `param` + aliases.
150
163
  */
151
164
  export interface ToolRuleFace {
152
165
  primaryParams?: readonly string[];
153
166
  params?: readonly string[];
167
+ /** The VALUES this mounted tool takes for the argument its name rules are read against — present on a tool whose rule row says
168
+ * its values are the mounted tool's own (the name grammar's `values: "mounted"`, the delegation tool's `Agent(<subagent_type>)`):
169
+ * the agent types this mount offers. Data, declared at mount; it rides the roster row and every call's face, and a rule of the
170
+ * tool is resolved against it (`canonicalNameValue`). Absent on such a tool ⇒ its calls cannot be read against those rules. */
171
+ nameValues?: readonly string[];
154
172
  }
155
173
  /** The roster's WIRE bounds on a tool name and a contract member (design/388 §2.5 / B20). Distinct from
156
174
  * protocol-naming's `TOOL_NAME_MAX_CHARS` (64), the provider-facing bound the MCP/A2A namespacing helper
@@ -211,6 +229,7 @@ export interface ToolFaceDeclaration {
211
229
  };
212
230
  aliases?: string[];
213
231
  pathTarget?: ToolPathTarget;
232
+ hostTarget?: ToolHostTarget;
214
233
  /**
215
234
  * The rule face ({@link ToolRuleFace}) and, for a definition whose primary parameter is a shell command line, the grammar
216
235
  * that judges it — `grammar: "command"`, the SHELL FACE. Every `Bash(<command>)` rule (the command grammar's one spelling,
@@ -1,6 +1,6 @@
1
1
  export const TOOL_FAMILIES = Object.freeze(["shell", "file-read", "file-write", "search", "web", "delegate", "plan", "scaffold", "memory", "protocol", "other"]);
2
2
  export const TOOL_MOUNT_TAGS = Object.freeze(["hands", "backgroundTasks", "workflow", "delegation", "hostInternals", "peerLane", "scheduler", "memory", "scenario", "always", "optional"]);
3
- export const TOOL_APPROVAL_CARDS = Object.freeze(["file-edit", "file-write", "notebook-edit", "shell", "fetch", "plan", "question", "generic"]);
3
+ export const TOOL_APPROVAL_CARDS = Object.freeze(["file-edit", "file-write", "notebook-edit", "shell", "fetch", "skill", "workflow", "plan", "question", "generic"]);
4
4
  export function isToolApprovalCard(word) {
5
5
  return typeof word === "string" && TOOL_APPROVAL_CARDS.includes(word);
6
6
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * design/277 — the tool-registration MODEL GATE (CC 233 counterpart, first formalized there as a
2
+ * design/277 — the tool-registration MODEL GATE (first formalized upstream as a
3
3
  * family+version-floor table over the todo/task-board tool family).
4
4
  *
5
5
  * WHAT THE GATE IS: a DEFAULT-MOUNT trim, never a capability ban. A {@link ToolSpec.modelGate}
@@ -34,15 +34,15 @@
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). */
42
42
  export interface ToolModelGateRule {
43
43
  /** claude-syntax family+floor rows — meaningful only for ids whose TAIL SEGMENT matches
44
44
  * `claude-<letters>-<digits(-digits)*>`. Version tuples compare positionally, missing positions
45
- * read 0, tuple ≥ floor ⇒ gated (CC 233 comparator, verbatim semantics). Any other id shape
45
+ * read 0, tuple ≥ floor ⇒ gated (the reference's comparator semantics). Any other id shape
46
46
  * falls through this axis entirely (fail-open). */
47
47
  floors?: ReadonlyArray<readonly [family: string, floor: ReadonlyArray<number>]>;
48
48
  /** Exact-id rows (explicit-id discipline): the resolved `Model.id`'s tail segment must equal the
@@ -52,7 +52,7 @@ export interface ToolModelGateRule {
52
52
  modelIds?: ReadonlyArray<string>;
53
53
  }
54
54
  /**
55
- * The built-in gate table: gate-class → rule. CC 233 z_S floors, verbatim (evidence D2; the
55
+ * The built-in gate table: gate-class → rule. The reference's floors (evidence D2; the
56
56
  * `mythos` row rides per the anchor). v1 vocabulary = ONE class, `"task-scaffold"` — the
57
57
  * TodoWrite/TaskCreate/TaskGet/TaskUpdate/TaskList default bundle (`assembleCodeTools`). One class
58
58
  * is evidence discipline, not mechanism limit: a family enters this table only with positive
@@ -1,4 +1,5 @@
1
1
  import { type ProtocolNamespace } from "./protocol-table.js";
2
+ import type { RuleBehavior } from "./permission-rule-model.js";
2
3
  /**
3
4
  * RB-476-A stage 2 (ruling 2026-08-02, RB-476 "no compatibility surface survives", replay
4
5
  * resolution included) — the durable-name machinery this module used to hold is RETIRED:
@@ -42,10 +43,12 @@ export declare const RULE_TOOL_NAME_VERDICTS: readonly ["current", "retired", "u
42
43
  * - `unmintable_segment` — carries a protocol prefix, but a segment of it is not one the mint produces: the peer segment
43
44
  * (the server / remote agent) is empty or not a spelling the mint produces for any peer (the name is read as written —
44
45
  * peers compare exactly — and every mounted tool carries the minted spelling, so the name reaches none of them), or the
45
- * tool segment is EMPTY (a trailing separator, `mcp__srv__`: no tool is minted under an empty segment). `guidance` says
46
- * so in one line; `currentName` is the whole name rewritten with the spelling the mint produces (`mcp__github.com__*` →
47
- * `mcp__github_com__*`), absent when a segment is empty and there is nothing to rewrite. A tool segment that is not empty
48
- * is never judged: it is a literal tool name or a glob over one, and an unmatched one is the audit's advisory.
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__*`, `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
+ * says so in one line; `currentName` is the whole name rewritten with the spelling the mint produces (`mcp__github.com__*` →
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
+ * empty is never judged: it is a literal tool name or a glob over one, and an unmatched one is the audit's advisory.
49
52
  *
50
53
  * `roster` = the tool names (aliases included) the reader knows are mounted: a run's assembled roster at prepare, the
51
54
  * names a deployment DECLARES it mounts its own tools under at a session-rule store (an empty set when it declares none).
@@ -65,7 +68,7 @@ export type RuleToolNameVerdict = {
65
68
  };
66
69
  /**
67
70
  * A name in ANY protocol namespace split into its owning namespace, its peer segment and its optional tool segment —
68
- * CC `rP` (:70710) verbatim, re-anchored on the {@link protocolOf} lookup instead of CC's literal `"mcp"` first split element.
71
+ * Re-anchored on the {@link protocolOf} lookup instead of CC's literal `"mcp"` first split element.
69
72
  * `undefined` for a name that is not namespaced (no protocol prefix). The peer is the first segment — EMPTY for `mcp____x` and
70
73
  * for the bare prefix, which name no peer; the tool segment is the REST of the split rejoined, so a tool whose minted segment
71
74
  * itself carries the separator (charset normalization maps `get..issue` → `get__issue`) decomposes back to one tool name, and
@@ -77,11 +80,29 @@ export declare function splitNamespacedName(name: string): {
77
80
  readonly peer: string;
78
81
  readonly tool?: string;
79
82
  } | undefined;
80
- /** See {@link RuleToolNameVerdict}. Pure; the one answer to "is this rule's tool name a name that reaches no tool". */
81
- export declare function judgeRuleToolName(name: string, roster: ReadonlySet<string>): RuleToolNameVerdict;
83
+ /**
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.
89
+ */
90
+ export declare function readsNameGlob(behavior: RuleBehavior | undefined): boolean;
91
+ /**
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.
96
+ */
97
+ export declare function grantWildcardRefusalOf(name: string): string | undefined;
98
+ /** See {@link RuleToolNameVerdict}. Pure; the one answer to "is this rule's tool name a name that reaches no tool".
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
+ export declare function judgeRuleToolName(name: string, roster: ReadonlySet<string>, behavior?: RuleBehavior): RuleToolNameVerdict;
82
103
  /** The two kinds of tool-name miss — a closed set. `unknown`: the name is none the engine ever mounted (a typo, a
83
104
  * guess). `expected-absent`: the name is one the engine RETIRED ({@link RETIRED_TOOL_NAMES}), so its absence is no
84
- * surprise and the table says what replaced it (CC 2.1.296 spells the same two words for its render-time miss). */
105
+ * surprise and the table says what replaced it (the reference spells the same two words for its render-time miss). */
85
106
  export declare const TOOL_MISS_KINDS: readonly ["unknown", "expected-absent"];
86
107
  declare const UNKNOWN_MISS: "unknown", ABSENT_MISS: "expected-absent";
87
108
  /** What {@link judgeToolNameMiss} answers: the kind (a {@link TOOL_MISS_KINDS} word) and, for `expected-absent`, the clause. */
@@ -53,11 +53,29 @@ 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
- function unmintableSegmentOf({ ns, peer, tool }) {
56
+ export function readsNameGlob(behavior) {
57
+ return behavior === "deny" || behavior === "ask";
58
+ }
59
+ function peerWildcardGuidance(ns) {
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);
70
+ }
71
+ function unmintableSegmentOf(split, behavior) {
72
+ const { ns, peer, tool } = split;
57
73
  if (peer === "")
58
74
  return { kind: "unmintable_segment", guidance: `the ${ns.id} name has an empty peer segment — no tool is minted under it` };
59
75
  if (tool === "")
60
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` };
77
+ if (peer.includes("*"))
78
+ return readsNameGlob(behavior) ? undefined : { kind: "unmintable_segment", guidance: peerWildcardGuidance(ns) };
61
79
  const minted = mintNamespacePrefix(ns, peer).slice(ns.prefix.length, -NAMESPACE_SEPARATOR.length);
62
80
  if (minted === peer)
63
81
  return undefined;
@@ -67,7 +85,7 @@ function unmintableSegmentOf({ ns, peer, tool }) {
67
85
  currentName: `${ns.prefix}${minted}${tool !== undefined ? `${NAMESPACE_SEPARATOR}${tool}` : ""}`,
68
86
  };
69
87
  }
70
- export function judgeRuleToolName(name, roster) {
88
+ export function judgeRuleToolName(name, roster, behavior) {
71
89
  if (roster.has(name))
72
90
  return CURRENT;
73
91
  const guidance = RETIRED_TOOL_NAMES.get(name);
@@ -77,8 +95,8 @@ export function judgeRuleToolName(name, roster) {
77
95
  }
78
96
  const split = splitNamespacedName(name);
79
97
  if (split === undefined)
80
- return carriesNamespaceSeparator(name) ? UNPREFIXED : CURRENT;
81
- return unmintableSegmentOf(split) ?? CURRENT;
98
+ return carriesNamespaceSeparator(name) && !(readsNameGlob(behavior) && name.includes("*")) ? UNPREFIXED : CURRENT;
99
+ return unmintableSegmentOf(split, behavior) ?? CURRENT;
82
100
  }
83
101
  export const TOOL_MISS_KINDS = Object.freeze(["unknown", "expected-absent"]);
84
102
  const [UNKNOWN_MISS, ABSENT_MISS] = TOOL_MISS_KINDS;