@sema-agent/core 7.54.1 → 7.55.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 (399) hide show
  1. package/CHANGELOG.md +437 -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/cc-peer-directory.d.ts +36 -0
  5. package/dist/agents/cc-peer-directory.js +138 -0
  6. package/dist/agents/cc-peer-wire.d.ts +105 -0
  7. package/dist/agents/cc-peer-wire.js +98 -0
  8. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  9. package/dist/agents/cc-uds-peer-channel.js +457 -0
  10. package/dist/agents/cross-session-envelope.d.ts +4 -1
  11. package/dist/agents/cross-session-envelope.js +8 -1
  12. package/dist/agents/cross-session-judge.d.ts +2 -2
  13. package/dist/agents/list-agents-tool.js +2 -1
  14. package/dist/agents/observer.d.ts +4 -5
  15. package/dist/agents/observer.js +2 -1
  16. package/dist/agents/peer-admission.d.ts +6 -0
  17. package/dist/agents/peer-admission.js +4 -1
  18. package/dist/agents/peer-directory.d.ts +43 -9
  19. package/dist/agents/peer-directory.js +66 -23
  20. package/dist/agents/peer-notices.d.ts +1 -1
  21. package/dist/agents/peer-session-drain.d.ts +3 -1
  22. package/dist/agents/peer-session-drain.js +1 -0
  23. package/dist/agents/read-inbox-tool.js +2 -1
  24. package/dist/agents/retain-ledger.d.ts +1 -1
  25. package/dist/agents/roster-store.d.ts +1 -1
  26. package/dist/agents/send-message-tool.d.ts +10 -0
  27. package/dist/agents/send-message-tool.js +34 -5
  28. package/dist/agents/subagent.d.ts +34 -79
  29. package/dist/agents/subagent.js +45 -46
  30. package/dist/agents/tool-filter.d.ts +29 -46
  31. package/dist/agents/tool-filter.js +8 -31
  32. package/dist/agents/verify.d.ts +3 -3
  33. package/dist/brain/anthropic.js +14 -9
  34. package/dist/brain/errors.d.ts +15 -0
  35. package/dist/brain/errors.js +10 -0
  36. package/dist/brain/model-presets.d.ts +4 -4
  37. package/dist/brain/open-responses.js +15 -10
  38. package/dist/brain/openai.js +17 -12
  39. package/dist/brain/provider-dialect.d.ts +39 -3
  40. package/dist/brain/provider-dialect.js +28 -0
  41. package/dist/brain/reasoning.d.ts +1 -1
  42. package/dist/brain/request-params.d.ts +55 -5
  43. package/dist/brain/request-params.js +35 -3
  44. package/dist/brain/retry.d.ts +1 -1
  45. package/dist/brain/route-adjudicator.d.ts +15 -0
  46. package/dist/brain/route-adjudicator.js +15 -0
  47. package/dist/brain/stream-engine.js +6 -5
  48. package/dist/brain/stream-shared.d.ts +1 -1
  49. package/dist/core/advisor-verdict.d.ts +120 -0
  50. package/dist/core/advisor-verdict.js +92 -0
  51. package/dist/core/agent-definition.d.ts +7 -8
  52. package/dist/core/allow-entry.d.ts +49 -23
  53. package/dist/core/allow-entry.js +57 -32
  54. package/dist/core/allow-rule-shadow.d.ts +7 -0
  55. package/dist/core/approval-object.d.ts +2 -1
  56. package/dist/core/approval-object.js +6 -6
  57. package/dist/core/ask-origin.d.ts +63 -11
  58. package/dist/core/ask-origin.js +27 -5
  59. package/dist/core/ask-question.js +10 -4
  60. package/dist/core/auto-compaction.d.ts +11 -8
  61. package/dist/core/auto-compaction.js +4 -2
  62. package/dist/core/auto-mode-arming.d.ts +2 -2
  63. package/dist/core/auto-mode-defaults.d.ts +8 -8
  64. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  65. package/dist/core/auto-mode-prompt.d.ts +1 -1
  66. package/dist/core/auto-mode.d.ts +17 -9
  67. package/dist/core/auto-mode.js +9 -6
  68. package/dist/core/background-agent-store.d.ts +3 -3
  69. package/dist/core/canonical-json.d.ts +1 -1
  70. package/dist/core/canonical-json.js +2 -2
  71. package/dist/core/checkpoint-requirements.d.ts +6 -3
  72. package/dist/core/checkpoint-requirements.js +4 -14
  73. package/dist/core/checkpoint-store.d.ts +80 -51
  74. package/dist/core/checkpoint-store.js +56 -74
  75. package/dist/core/child-clamp-seats.d.ts +6 -0
  76. package/dist/core/child-clamp-seats.js +3 -16
  77. package/dist/core/compliance.d.ts +2 -2
  78. package/dist/core/context-edit.d.ts +6 -7
  79. package/dist/core/cross-boundary-taint.d.ts +9 -3
  80. package/dist/core/cross-boundary-taint.js +5 -3
  81. package/dist/core/decision-receipt.js +2 -2
  82. package/dist/core/effective-path-target.d.ts +1 -1
  83. package/dist/core/engine-notice.d.ts +19 -5
  84. package/dist/core/exec-output-tail.d.ts +1 -1
  85. package/dist/core/file-history-retention.d.ts +1 -1
  86. package/dist/core/file-history-store.d.ts +59 -9
  87. package/dist/core/file-history-store.js +35 -17
  88. package/dist/core/gate-fold.js +3 -2
  89. package/dist/core/gate-lanes.js +12 -8
  90. package/dist/core/gate-outcome.d.ts +17 -4
  91. package/dist/core/gate-outcome.js +30 -0
  92. package/dist/core/governance-codes.d.ts +13 -3
  93. package/dist/core/governance-codes.js +10 -0
  94. package/dist/core/hands-band.d.ts +1 -1
  95. package/dist/core/hooks.d.ts +4 -4
  96. package/dist/core/host-target.d.ts +49 -0
  97. package/dist/core/host-target.js +59 -0
  98. package/dist/core/image-downsample.d.ts +1 -1
  99. package/dist/core/lsp-diagnostics.d.ts +4 -4
  100. package/dist/core/lsp.d.ts +3 -3
  101. package/dist/core/mailbox-store.d.ts +4 -0
  102. package/dist/core/mcp-connection-pool.d.ts +18 -2
  103. package/dist/core/mcp-connection-pool.js +53 -6
  104. package/dist/core/mcp-failure.d.ts +23 -4
  105. package/dist/core/mcp-failure.js +26 -11
  106. package/dist/core/mcp-listing-drift.d.ts +10 -0
  107. package/dist/core/mcp-listing-drift.js +6 -0
  108. package/dist/core/mcp-server-link.d.ts +173 -0
  109. package/dist/core/mcp-server-link.js +127 -0
  110. package/dist/core/mcp-server-spec.d.ts +4 -2
  111. package/dist/core/mcp-session-end.d.ts +26 -0
  112. package/dist/core/mcp-session-end.js +29 -0
  113. package/dist/core/mcp-startup-request.d.ts +17 -0
  114. package/dist/core/mcp-startup-request.js +17 -0
  115. package/dist/core/mcp.d.ts +13 -13
  116. package/dist/core/mcp.js +187 -162
  117. package/dist/core/media-byte-cap.d.ts +1 -1
  118. package/dist/core/memory-engine/engine.d.ts +9 -9
  119. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  120. package/dist/core/memory-engine/tools.js +4 -1
  121. package/dist/core/mode-policy.d.ts +1 -1
  122. package/dist/core/namespaced-rule-name.d.ts +33 -7
  123. package/dist/core/namespaced-rule-name.js +39 -25
  124. package/dist/core/output-style.d.ts +1 -1
  125. package/dist/core/param-rule-reach.d.ts +15 -0
  126. package/dist/core/param-rule-reach.js +30 -0
  127. package/dist/core/parent-spec-seat.d.ts +8 -1
  128. package/dist/core/parent-spec-seat.js +4 -0
  129. package/dist/core/pause-registry.d.ts +16 -5
  130. package/dist/core/pause-registry.js +6 -2
  131. package/dist/core/peer-channel.d.ts +70 -0
  132. package/dist/core/peer-channel.js +1 -0
  133. package/dist/core/permission-rule-consent.d.ts +11 -5
  134. package/dist/core/permission-rule-consent.js +37 -30
  135. package/dist/core/permission-rule-model.d.ts +233 -64
  136. package/dist/core/permission-rule-model.js +384 -85
  137. package/dist/core/permission-rule-provider.d.ts +2 -1
  138. package/dist/core/permission-rule-store.d.ts +20 -25
  139. package/dist/core/permission-rule-store.js +1 -4
  140. package/dist/core/permission-rule-sync.d.ts +11 -2
  141. package/dist/core/permission-rule-sync.js +8 -1
  142. package/dist/core/permission-rules.d.ts +49 -11
  143. package/dist/core/permission-rules.js +123 -89
  144. package/dist/core/persisted-rule-arms.d.ts +4 -2
  145. package/dist/core/present-plan-tool.js +3 -1
  146. package/dist/core/protocol-naming.d.ts +2 -2
  147. package/dist/core/read-only-shell-table.d.ts +1 -1
  148. package/dist/core/read-only-shell.d.ts +1 -1
  149. package/dist/core/roles.d.ts +6 -2
  150. package/dist/core/roles.js +45 -44
  151. package/dist/core/rule-offer-read.d.ts +53 -0
  152. package/dist/core/rule-offer-read.js +146 -0
  153. package/dist/core/rule-owner.d.ts +46 -0
  154. package/dist/core/rule-owner.js +28 -0
  155. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  156. package/dist/core/runner/advisor-instructions.js +61 -0
  157. package/dist/core/runner/advisor-tool.d.ts +33 -0
  158. package/dist/core/runner/advisor-tool.js +112 -0
  159. package/dist/core/runner/announce-once-ledger.d.ts +4 -26
  160. package/dist/core/runner/announce-once-ledger.js +14 -46
  161. package/dist/core/runner/approval-feedback.js +6 -3
  162. package/dist/core/runner/assemble-result.d.ts +1 -1
  163. package/dist/core/runner/caller-roster.d.ts +7 -0
  164. package/dist/core/runner/caller-roster.js +11 -0
  165. package/dist/core/runner/classifier-ladder.d.ts +27 -5
  166. package/dist/core/runner/classifier-ladder.js +12 -11
  167. package/dist/core/runner/compaction-restate.d.ts +10 -6
  168. package/dist/core/runner/compaction-restate.js +9 -3
  169. package/dist/core/runner/contracts.d.ts +13 -9
  170. package/dist/core/runner/conversation-segment.d.ts +28 -0
  171. package/dist/core/runner/conversation-segment.js +42 -0
  172. package/dist/core/runner/cross-boundary-lane.d.ts +6 -5
  173. package/dist/core/runner/cross-boundary-lane.js +26 -15
  174. package/dist/core/runner/decide-continuation.d.ts +7 -4
  175. package/dist/core/runner/decide-continuation.js +2 -2
  176. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  177. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  178. package/dist/core/runner/derived-route-fallback.js +9 -7
  179. package/dist/core/runner/gate-exit.d.ts +6 -0
  180. package/dist/core/runner/gate-exit.js +7 -2
  181. package/dist/core/runner/initial-run-state.js +1 -1
  182. package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
  183. package/dist/core/runner/permission-rule-lanes.js +14 -7
  184. package/dist/core/runner/person-path-rows.js +1 -1
  185. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  186. package/dist/core/runner/prepare-advisor.js +77 -0
  187. package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
  188. package/dist/core/runner/prepare-config-doors.d.ts +6 -4
  189. package/dist/core/runner/prepare-config-doors.js +18 -12
  190. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  191. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  192. package/dist/core/runner/prepare-file-history.js +39 -39
  193. package/dist/core/runner/prepare-gate-stations.d.ts +1 -4
  194. package/dist/core/runner/prepare-gate-stations.js +2 -7
  195. package/dist/core/runner/prepare-inherited-gate.d.ts +5 -4
  196. package/dist/core/runner/prepare-inherited-gate.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.js +7 -7
  198. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  199. package/dist/core/runner/prepare-policy-chain.js +4 -10
  200. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  201. package/dist/core/runner/prepare-project-context.js +6 -3
  202. package/dist/core/runner/prepare-prompt-inputs.js +1 -1
  203. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -2
  204. package/dist/core/runner/prepare-protocol-tools.js +3 -2
  205. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  206. package/dist/core/runner/prepare-safety-scan.js +8 -6
  207. package/dist/core/runner/prepare-task.js +15 -18
  208. package/dist/core/runner/prepare-tool-disclosure-mount.js +6 -4
  209. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -3
  210. package/dist/core/runner/prepare-wiring-manifest.js +2 -2
  211. package/dist/core/runner/resume-policy-outcome.js +1 -1
  212. package/dist/core/runner/retired-runner-deps.js +1 -1
  213. package/dist/core/runner/run-attachment-seats.js +0 -1
  214. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  215. package/dist/core/runner/run-compaction-machinery.js +2 -12
  216. package/dist/core/runner/run-git-lane.d.ts +1 -0
  217. package/dist/core/runner/run-harness-handlers.js +2 -3
  218. package/dist/core/runner/run-leg.js +13 -0
  219. package/dist/core/runner/run-settle-and-teardown.js +1 -1
  220. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  221. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  222. package/dist/core/runner/run-turn-boundary.js +14 -12
  223. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  224. package/dist/core/runner/session-rule-policy.js +13 -28
  225. package/dist/core/runner/side-call-account.d.ts +32 -8
  226. package/dist/core/runner/side-call-account.js +23 -1
  227. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  228. package/dist/core/runner/sub-agent-deny-lists.js +4 -3
  229. package/dist/core/runner/synthetic-tools.d.ts +10 -13
  230. package/dist/core/runner/synthetic-tools.js +4 -2
  231. package/dist/core/runner/tool-disclosure.js +2 -1
  232. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  233. package/dist/core/runner/tool-face-overlay.js +17 -1
  234. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  235. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  236. package/dist/core/runner/turn-attachments.d.ts +60 -67
  237. package/dist/core/runner-deps.d.ts +37 -37
  238. package/dist/core/runtime-caps.d.ts +4 -4
  239. package/dist/core/safety-merge-corpus.js +17 -1
  240. package/dist/core/same-plain-value.d.ts +40 -0
  241. package/dist/core/same-plain-value.js +49 -0
  242. package/dist/core/scheduler.d.ts +1 -1
  243. package/dist/core/sensitive-path-policy.d.ts +1 -1
  244. package/dist/core/sensitive-path-policy.js +1 -1
  245. package/dist/core/session-policy-store.d.ts +77 -22
  246. package/dist/core/session-policy-store.js +56 -14
  247. package/dist/core/session-reconcile.d.ts +2 -2
  248. package/dist/core/session-store.d.ts +80 -30
  249. package/dist/core/session-store.js +118 -76
  250. package/dist/core/session.d.ts +24 -46
  251. package/dist/core/shared-memory/tools.js +3 -1
  252. package/dist/core/shared-memory/types.d.ts +1 -1
  253. package/dist/core/side-query.d.ts +10 -0
  254. package/dist/core/side-query.js +5 -0
  255. package/dist/core/store-contracts/checkpoint-store-contract.js +29 -2
  256. package/dist/core/store-contracts/file-history-store-contract.js +43 -3
  257. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  258. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  259. package/dist/core/store-contracts/session-repo-contract.js +125 -0
  260. package/dist/core/store-contracts/session-store-contract.d.ts +4 -7
  261. package/dist/core/store-contracts/session-store-contract.js +215 -41
  262. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  263. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  264. package/dist/core/task-event.d.ts +10 -4
  265. package/dist/core/task-notification.d.ts +3 -3
  266. package/dist/core/task-registry-agent.d.ts +4 -4
  267. package/dist/core/task-registry-shared.d.ts +4 -4
  268. package/dist/core/task-registry-shared.js +1 -0
  269. package/dist/core/task-registry.d.ts +4 -4
  270. package/dist/core/task-registry.js +3 -1
  271. package/dist/core/task-result.d.ts +3 -3
  272. package/dist/core/task-spec.d.ts +52 -52
  273. package/dist/core/task-stream.d.ts +6 -6
  274. package/dist/core/task-tool-shape.d.ts +4 -4
  275. package/dist/core/tighten-task-spec.d.ts +1 -1
  276. package/dist/core/tool-catalog-entries.d.ts +19 -2
  277. package/dist/core/tool-catalog-entries.js +57 -42
  278. package/dist/core/tool-conformance.js +1 -0
  279. package/dist/core/tool-errors.d.ts +2 -2
  280. package/dist/core/tool-face-reader.js +5 -3
  281. package/dist/core/tool-face.d.ts +21 -2
  282. package/dist/core/tool-face.js +1 -1
  283. package/dist/core/tool-model-gate.d.ts +3 -3
  284. package/dist/core/tool-name-aliases.d.ts +29 -8
  285. package/dist/core/tool-name-aliases.js +27 -3
  286. package/dist/core/tool-name-readings.d.ts +5 -8
  287. package/dist/core/tool-name-readings.js +1 -2
  288. package/dist/core/tool-policy.d.ts +24 -5
  289. package/dist/core/tool-policy.js +34 -10
  290. package/dist/core/tool-registry.d.ts +14 -7
  291. package/dist/core/tool-registry.js +17 -7
  292. package/dist/core/tool-result-store.js +2 -1
  293. package/dist/core/tool-roster.d.ts +47 -18
  294. package/dist/core/tool-roster.js +53 -32
  295. package/dist/core/tool-spec-members.js +1 -1
  296. package/dist/core/tool-spec.d.ts +35 -21
  297. package/dist/core/tools.js +3 -2
  298. package/dist/core/trace.d.ts +4 -0
  299. package/dist/core/untrusted-egress.d.ts +1 -1
  300. package/dist/core/untrusted-text.d.ts +1 -1
  301. package/dist/core/warm-resume.d.ts +1 -1
  302. package/dist/core/wiring-manifest.d.ts +49 -0
  303. package/dist/core/wiring-manifest.js +13 -5
  304. package/dist/core/workflow-journal-store.d.ts +62 -0
  305. package/dist/core/workflow-journal-store.js +77 -1
  306. package/dist/core/workflow-run-store.d.ts +6 -0
  307. package/dist/core/workflow-run-store.js +2 -0
  308. package/dist/engine/compaction/compaction.d.ts +9 -9
  309. package/dist/engine/execution-env/node-execution-env.d.ts +19 -5
  310. package/dist/engine/execution-env/node-execution-env.js +43 -22
  311. package/dist/engine/harness/agent-harness.d.ts +14 -8
  312. package/dist/engine/harness/agent-harness.js +33 -26
  313. package/dist/engine/harness/types.d.ts +29 -7
  314. package/dist/engine/harness/types.js +12 -1
  315. package/dist/engine/llm/types.d.ts +9 -9
  316. package/dist/engine/llm/validation.d.ts +4 -1
  317. package/dist/engine/llm/validation.js +13 -1
  318. package/dist/engine/loop/agent-loop.d.ts +1 -1
  319. package/dist/engine/loop/agent-loop.js +10 -8
  320. package/dist/engine/loop/types.d.ts +15 -13
  321. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  322. package/dist/engine/session/memory-repo.d.ts +10 -11
  323. package/dist/engine/session/memory-repo.js +13 -8
  324. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  325. package/dist/engine/session/parent-chain-guard.js +1 -1
  326. package/dist/engine/session/repo-utils.d.ts +31 -3
  327. package/dist/engine/session/repo-utils.js +42 -5
  328. package/dist/index.d.ts +27 -15
  329. package/dist/index.js +21 -11
  330. package/dist/internal/harness-types.d.ts +1 -1
  331. package/dist/internal/harness.d.ts +3 -3
  332. package/dist/internal/harness.js +2 -2
  333. package/dist/internal/llm.d.ts +1 -1
  334. package/dist/internal/llm.js +1 -1
  335. package/dist/orchestration/goal.js +2 -2
  336. package/dist/orchestration/run-workflow-tool.d.ts +2 -2
  337. package/dist/orchestration/run-workflow-tool.js +5 -3
  338. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  339. package/dist/orchestration/workflow-types.d.ts +18 -0
  340. package/dist/orchestration/workflow-types.js +6 -0
  341. package/dist/orchestration/workflow.d.ts +2 -13
  342. package/dist/orchestration/workflow.js +21 -31
  343. package/dist/prompt-assembly/event-registry.js +1 -0
  344. package/dist/prompt-assembly/tool-catalog.d.ts +3 -0
  345. package/dist/prompt-assembly/tool-catalog.js +3 -0
  346. package/dist/prompts/default.d.ts +14 -14
  347. package/dist/scenarios/full-body.d.ts +4 -4
  348. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  349. package/dist/stores/file/adoption/adopt.js +24 -31
  350. package/dist/stores/file/adoption/marker.d.ts +6 -13
  351. package/dist/stores/file/adoption/marker.js +6 -15
  352. package/dist/stores/file/checkpoint-store.d.ts +3 -0
  353. package/dist/stores/file/checkpoint-store.js +9 -3
  354. package/dist/stores/file/file-history-store.d.ts +20 -19
  355. package/dist/stores/file/file-history-store.js +152 -135
  356. package/dist/stores/file/fs-atomic.d.ts +15 -0
  357. package/dist/stores/file/fs-atomic.js +89 -14
  358. package/dist/stores/file/index.d.ts +1 -1
  359. package/dist/stores/file/mailbox-store.d.ts +3 -0
  360. package/dist/stores/file/mailbox-store.js +3 -1
  361. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  362. package/dist/stores/file/permission-rule-adopt.js +15 -16
  363. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  364. package/dist/stores/file/permission-rule-store.js +21 -14
  365. package/dist/stores/file/session-policy-store.d.ts +3 -3
  366. package/dist/stores/file/session-store.d.ts +26 -11
  367. package/dist/stores/file/session-store.js +77 -40
  368. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  369. package/dist/stores/file/workflow-journal-store.js +28 -13
  370. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  371. package/dist/tools/artifact/artifact-tool.js +2 -1
  372. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  373. package/dist/tools/fs/fs-bash.d.ts +2 -2
  374. package/dist/tools/fs/fs-bash.js +3 -1
  375. package/dist/tools/fs/fs-shared.d.ts +8 -8
  376. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  377. package/dist/tools/fs/notebook.d.ts +2 -2
  378. package/dist/tools/fs/read-deny.d.ts +29 -7
  379. package/dist/tools/fs/read-deny.js +63 -22
  380. package/dist/tools/fs/removal-targets.d.ts +1 -1
  381. package/dist/tools/fs/safety.d.ts +9 -9
  382. package/dist/tools/fs/search.d.ts +6 -6
  383. package/dist/tools/fs/shell-read-check.js +6 -1
  384. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  385. package/dist/tools/fs/shell-read-judge.js +5 -2
  386. package/dist/tools/loop-tick.d.ts +2 -2
  387. package/dist/tools/scheduler-tools.js +5 -1
  388. package/dist/tools/task-list.d.ts +7 -7
  389. package/dist/tools/task-list.js +5 -1
  390. package/dist/tools/todo.js +2 -1
  391. package/dist/tools/web.d.ts +1 -1
  392. package/dist/tools/web.js +40 -37
  393. package/dist/tools/worktree.d.ts +3 -3
  394. package/dist/tools/worktree.js +3 -1
  395. package/package.json +1 -1
  396. package/test/export-surface.snapshot.json +5756 -5638
  397. package/wire-changes/core@7.55.0.json +3318 -0
  398. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  399. 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 });
@@ -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",
@@ -177,13 +179,26 @@ const byId = new Map();
177
179
  for (const e of TOOL_CATALOG_ENTRIES) {
178
180
  if (byId.has(e.id))
179
181
  throw new Error(`tool catalog: duplicate definition id ${JSON.stringify(e.id)}`);
182
+ if (e.face.pathTarget !== undefined && e.face.hostTarget !== undefined)
183
+ throw new Error(`tool catalog: ${JSON.stringify(e.id)} declares a path target and a host target — a face names one protected target`);
180
184
  byId.set(e.id, e);
181
185
  }
186
+ const CATALOG_CONTRACTS = new WeakSet();
182
187
  export function toolFace(id) {
183
188
  const e = byId.get(id);
184
189
  if (e === undefined)
185
190
  throw new Error(`tool catalog: no definition ${JSON.stringify(id)}`);
186
- return { contentOrigin: "local", ...structuredClone(e.face) };
191
+ const face = { contentOrigin: "local", ...structuredClone(e.face) };
192
+ if (face.contract !== undefined)
193
+ CATALOG_CONTRACTS.add(face.contract);
194
+ return face;
195
+ }
196
+ export function isCatalogContract(contract) {
197
+ return typeof contract === "object" && contract !== null && CATALOG_CONTRACTS.has(contract);
198
+ }
199
+ export function mountRuleFace(id) {
200
+ const primaryParams = toolFace(id).ruleFace?.primaryParams;
201
+ return primaryParams === undefined ? undefined : { primaryParams: [...primaryParams] };
187
202
  }
188
203
  function deepFreeze(value) {
189
204
  if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
@@ -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}
@@ -42,7 +42,7 @@ export declare function modelIdTail(id: string): string;
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__*__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`
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
+ * 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.
87
+ */
88
+ export declare function wholeProtocolOf(name: string): ProtocolNamespace | undefined;
89
+ /**
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.
94
+ */
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;
99
+ /** 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`. */
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,28 @@ 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
+ 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) {
65
+ return behavior === "deny" || behavior === "ask";
66
+ }
67
+ 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`;
69
+ }
70
+ function unmintableSegmentOf(split, behavior) {
71
+ const { ns, peer, tool } = split;
57
72
  if (peer === "")
58
73
  return { kind: "unmintable_segment", guidance: `the ${ns.id} name has an empty peer segment — no tool is minted under it` };
59
74
  if (tool === "")
60
75
  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
+ if (peer.includes("*"))
77
+ return spellsWholeProtocol(split) && readsWholeProtocol(behavior) ? undefined : { kind: "unmintable_segment", guidance: peerWildcardGuidance(ns) };
61
78
  const minted = mintNamespacePrefix(ns, peer).slice(ns.prefix.length, -NAMESPACE_SEPARATOR.length);
62
79
  if (minted === peer)
63
80
  return undefined;
@@ -67,7 +84,14 @@ function unmintableSegmentOf({ ns, peer, tool }) {
67
84
  currentName: `${ns.prefix}${minted}${tool !== undefined ? `${NAMESPACE_SEPARATOR}${tool}` : ""}`,
68
85
  };
69
86
  }
70
- export function judgeRuleToolName(name, roster) {
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
+ export function judgeRuleToolName(name, roster, behavior) {
71
95
  if (roster.has(name))
72
96
  return CURRENT;
73
97
  const guidance = RETIRED_TOOL_NAMES.get(name);
@@ -78,7 +102,7 @@ export function judgeRuleToolName(name, roster) {
78
102
  const split = splitNamespacedName(name);
79
103
  if (split === undefined)
80
104
  return carriesNamespaceSeparator(name) ? UNPREFIXED : CURRENT;
81
- return unmintableSegmentOf(split) ?? CURRENT;
105
+ return unmintableSegmentOf(split, behavior) ?? CURRENT;
82
106
  }
83
107
  export const TOOL_MISS_KINDS = Object.freeze(["unknown", "expected-absent"]);
84
108
  const [UNKNOWN_MISS, ABSENT_MISS] = TOOL_MISS_KINDS;
@@ -98,14 +98,6 @@ export declare const NAME_READINGS: {
98
98
  readonly kind: "wire";
99
99
  readonly file: string;
100
100
  };
101
- readonly "lanes.persistedEditSkip": {
102
- readonly kind: "wire";
103
- readonly file: string;
104
- };
105
- readonly "lanes.persistedLaneSkip": {
106
- readonly kind: "wire";
107
- readonly file: string;
108
- };
109
101
  readonly "lanes.allowLayerQuestionSkip": {
110
102
  readonly kind: "wire";
111
103
  readonly file: string;
@@ -163,6 +155,11 @@ export declare const NAME_READINGS: {
163
155
  readonly rank: "member";
164
156
  readonly file: string;
165
157
  };
158
+ readonly "floor.protectiveHostTarget": {
159
+ readonly kind: "seat";
160
+ readonly rank: "member";
161
+ readonly file: string;
162
+ };
166
163
  readonly "mode.planRosterRow": {
167
164
  readonly kind: "wire";
168
165
  readonly file: string;
@@ -26,8 +26,6 @@ export const NAME_READINGS = {
26
26
  "lanes.modeFileCommand": wire(LANES),
27
27
  "lanes.contentAskRoute": wire(LANES),
28
28
  "lanes.orgContentAskExemption": wire(LANES),
29
- "lanes.persistedEditSkip": wire(LANES),
30
- "lanes.persistedLaneSkip": wire(LANES),
31
29
  "lanes.allowLayerQuestionSkip": wire(LANES),
32
30
  "lanes.sandboxQuestionSkip": wire(LANES),
33
31
  "policy.nameLists": any(POLICY),
@@ -42,6 +40,7 @@ export const NAME_READINGS = {
42
40
  "policy.durableQuestion": any("src/core/ask-question.ts"),
43
41
  "policy.sensitivePathGuardedByName": any("src/core/sensitive-path-policy.ts"),
44
42
  "floor.protectivePathTarget": seat("member", "src/core/tool-registry.ts"),
43
+ "floor.protectiveHostTarget": seat("member", "src/core/host-target.ts"),
45
44
  "mode.planRosterRow": wire("src/core/mode-policy.ts"),
46
45
  "offer.laneTool": wire(OFFER),
47
46
  "offer.orgQuestionExemption": wire(OFFER),
@@ -5,6 +5,7 @@ export { policyCannotAnswer, rowDemandsAPerson } from "./real-approval.js";
5
5
  import { type BindingFault } from "./canonical-json.js";
6
6
  import { type DecisionReason } from "./decision-receipt.js";
7
7
  export { isEngineRefusal } from "./decision-receipt.js";
8
+ import { type RuleBehavior } from "./permission-rule-model.js";
8
9
  import { type RemovalGuardSeat } from "../tools/fs/removal-targets.js";
9
10
  /** A tool call presented to a policy before it executes. */
10
11
  /** design/388 B6 — the per-call face (see {@link ToolCallRequest.face}). */
@@ -16,6 +17,14 @@ export interface ToolCallFace {
16
17
  names?: readonly string[];
17
18
  family: import("./tool-face.js").ToolFamily;
18
19
  pathTarget?: import("./tool-face.js").ToolRosterPathTarget;
20
+ /** The URL slot a host rule of the tool's name is read on (`callHostTargetOf`), as the tool declared it — absent when it
21
+ * declares none, so no allow by host reaches the call (a deny or an ask still reads the catalog's slot for the name). */
22
+ hostTarget?: import("./tool-face.js").ToolHostTarget;
23
+ /** The values the mounted tool takes for the argument its name rules are read against (`ToolRuleFace.nameValues`, off the
24
+ * roster row — the delegation tool's offered agent types): a name rule of such a tool resolves its value and the call's against
25
+ * them (`nameRuleReach`). Absent where the tool declares none, and on a face rebuilt from a park row: a rule that needs them
26
+ * then cannot be read against the call (a deny refuses, an ask asks a person, an allow grants nothing). */
27
+ nameValues?: readonly string[];
19
28
  capabilityId: string;
20
29
  contractId: string;
21
30
  shapeDigest: string;
@@ -25,6 +34,10 @@ export interface ToolCallFace {
25
34
  * ask, the parked gate and the pending row, so no reader recovers the card from a name. Absent on a face rebuilt
26
35
  * from a park row (a re-judgment reads no card). */
27
36
  approvalCard?: import("./tool-face.js").ToolApprovalCard;
37
+ /** Present (`true`) iff one of the ENGINE's own mount sites mounted the tool the call dispatches to — a built-in or synthetic tool
38
+ * the engine minted for the leg, never a caller's `TaskSpec.tools` entry or a protocol peer's tool (`engineMountedRow`). The one
39
+ * identity a caller cannot wear: a name and a contract id can be declared. Absent on a face rebuilt from a park row. */
40
+ engineMounted?: true;
28
41
  }
29
42
  export interface ToolCallRequest {
30
43
  /** The tool's wire name — the Runner's gate resolves a call made under an alias to the wire name of the tool it
@@ -384,7 +397,7 @@ export type PermissionResult = {
384
397
  decisionReason?: DecisionReason;
385
398
  requiresRealApproval?: boolean;
386
399
  /** This ask is the classifier DENIAL-LIMIT fallback — the block that reached a
387
- * bound (CC 2.1.250 `FO`, count-then-judge) handed to a person instead of being denied.
400
+ * bound (count-then-judge) handed to a person instead of being denied.
388
401
  * ENGINE-STAMPED beside `requiresRealApproval: true` and `decisionReason: "classifier"` at the
389
402
  * classifier block sites (the gate's own and the inherited-lane arms); carries the COUNTS ONLY —
390
403
  * the auto-deny window is a fact of the ask's ROUTE, so this type has no member to hold one
@@ -410,7 +423,9 @@ export type PermissionResult = {
410
423
  /** backlog #239 disclosure (additive): WHY the reversibility probe did not clear this call, in the
411
424
  * probe's own words. ENGINE-STAMPED at the irreversibility tighten (which constructs this decision
412
425
  * wholesale), already neutralized + capped there; a `"maybe"` tier whose probe supplied no cause,
413
- * and the `"always"` tier (which runs no probe), leave it absent. Same DISPLAY-ONLY posture as
426
+ * and the `"always"` tier (which runs no probe), leave it absent. Also stamped beside a mandate merged onto an
427
+ * ask another layer raised (the read station's account of its finding): it is the one sentence that says why
428
+ * a matching allow rule did not clear a `probe_mandate` ask, on the card and in the parked row alike. Same DISPLAY-ONLY posture as
414
429
  * {@link allowRuleShadowed}: a policy that self-declares it can only put its own prose on its
415
430
  * own card — nothing reads this member to decide anything, so it is not an authority channel. */
416
431
  probeReason?: string;
@@ -780,6 +795,10 @@ export interface ToolPolicyProjection {
780
795
  *
781
796
  * The list is usually empty, which is why every call site tests it before scanning.
782
797
  *
798
+ * `behavior` = what the list does with a call it reaches: `deny` / `ask` (restricting) lists also read the whole-protocol
799
+ * spelling (`mcp__*`, `mcp__*__*`) as a covering entry — every tool of the namespace — and an `allow` list does not (the
800
+ * spelling names no peer there; the constructors and the prepare-time audit refuse it, and a stored allowlist reads it as nothing).
801
+ *
783
802
  * Exported for the OTHER name-keyed lane in this engine — the persisted session/ancestor rules in
784
803
  * `session-rule-policy.ts`. Not part of the public API (`src/index.ts` re-exports by name and does not
785
804
  * list these two): every publisher of {@link ToolPolicyNameSets} must resolve a covering entry the same
@@ -791,7 +810,7 @@ export interface ToolPolicyProjection {
791
810
  * the package index: an external lane either compiles through `createPermissionRulePolicy` or
792
811
  * self-checks with those.
793
812
  */
794
- export declare function namespacedCoveringEntries(entries: readonly string[] | undefined): readonly string[];
813
+ export declare function namespacedCoveringEntries(entries: readonly string[] | undefined, behavior: RuleBehavior): readonly string[];
795
814
  /** Does any covering entry reach the call — under ANY name it answers to, the same reading the exact lists take through
796
815
  * `nameListHolds` (a covering entry and an exact entry in one list are one rule: it reaches the call iff its name is on the
797
816
  * list)? See {@link namespacedCoveringEntries}. */
@@ -1162,7 +1181,7 @@ export declare function createCoarseCommandNamePolicy(opts: {
1162
1181
  tools?: string[];
1163
1182
  }): ToolPolicy;
1164
1183
  /**
1165
- * CC 220 "Unverifiable Deletion Target" parity (auto-mode rule; its text is in 220–245, gone from 2.1.250 on): ASK on a recursive+forced delete whose
1184
+ * "Unverifiable Deletion Target" (auto-mode rule; since dropped upstream): ASK on a recursive+forced delete whose
1166
1185
  * target is a variable / substitution that cannot be resolved from the command itself — fail-closed in the
1167
1186
  * sense that with no live classifier/approver the ask degrades to deny (see {@link PermissionResult}'s
1168
1187
  * `ask` doc), never to allow. The guard reads ONE plan, the read station's (`removalReadingOf`,
@@ -1176,7 +1195,7 @@ export declare function createCoarseCommandNamePolicy(opts: {
1176
1195
  * RB-341 (2026-07-29) re-checked that citation against the 220 corpus and corrected it in BOTH directions.
1177
1196
  * The RB-203 note claimed the phrase "traces to the 206 bundle; it does not appear anywhere in the 220
1178
1197
  * corpus for THIS rule" — that sentence was wrong and is retracted. The phrase has 8 hits in 220, and two
1179
- * of them are this exact rule's own message text: `pretty220` 461365 (the `rm -rf $UNSET/*`
1198
+ * of them are this exact rule's own message text: (the `rm -rf $UNSET/*`
1180
1199
  * variable-expansion arm, verbatim «e.g. `rm -rf $UNSET/*` becomes `rm -rf /*`. This requires explicit
1181
1200
  * approval and cannot be auto-allowed by permission rules.») and 461444 (its command-substitution twin).
1182
1201
  * Five more are the sibling deterministic `rm`/`rmdir` arms (457337/457364/457379/457387/457402) and one is