@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
@@ -20,6 +20,8 @@ import { assertNoRetiredKeys, assertNoRetiredToolPolicyKeys, RETIRED_DECISION_ME
20
20
  import { DECISION_MEMBER_ARMS, isEngineRefusal, nestedRecordsOf, receiveContract, receiveNestedRecords, refusedOutOfContract, screenContractValues } from "./decision-receipt.js";
21
21
  export { isEngineRefusal } from "./decision-receipt.js";
22
22
  import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "./permission-rules.js";
23
+ import { ruleContentOf } from "./permission-rule-model.js";
24
+ import { wildcardPeerRefusalOf } from "./tool-name-aliases.js";
23
25
  import { ruleSpellingOf } from "./permission-rule-syntax.js";
24
26
  import { protocolOf } from "./protocol-table.js";
25
27
  import { anchorSpelling, isAbsoluteForFamily, normalizeAbsPathLexically, pathFamilyOf, writeTargetPath } from "../tools/fs/safety.js";
@@ -194,8 +196,18 @@ export function toolPolicyWriteGuardRows(policies) {
194
196
  return undefined;
195
197
  return async (at) => (await Promise.all(sources.map((rowsOf) => rowsOf(at)))).flat();
196
198
  }
197
- export function namespacedCoveringEntries(entries) {
198
- return (entries ?? []).filter(isNamespacedCoveringRuleName);
199
+ export function namespacedCoveringEntries(entries, behavior) {
200
+ return (entries ?? []).filter((entry) => isNamespacedCoveringRuleName(entry, behavior));
201
+ }
202
+ function allowlistNameRefusal(who, entry, list) {
203
+ if (typeof entry !== "string")
204
+ return undefined;
205
+ const sentence = wildcardPeerRefusalOf(ruleSpellingOf(entry)?.toolName ?? entry, "allow");
206
+ if (sentence === undefined)
207
+ return undefined;
208
+ const e = new Error(`${who}: ${list} entry "${entry}" — ${sentence}`);
209
+ e.code = "config.invalid_tool_name_set";
210
+ return e;
199
211
  }
200
212
  export function namespacedCoveringHit(covering, call) {
201
213
  return covering.length > 0 && nameListHolds({ has: (name) => covering.some((e) => namespacedRuleNameCovers(e, name)) }, call);
@@ -207,13 +219,13 @@ export function checkToolPolicyProjection(projection, req) {
207
219
  const listed = (list) => heldBy("policy.projectionReplay", { has: (n) => list.includes(n) }, req);
208
220
  for (const c of projection.components) {
209
221
  if (c.kind === "tool_deny") {
210
- if (listed(c.names) || namespacedCoveringHit(namespacedCoveringEntries(c.names), req)) {
222
+ if (listed(c.names) || namespacedCoveringHit(namespacedCoveringEntries(c.names, "deny"), req)) {
211
223
  return { action: "deny", message: `tool "${req.toolName}" is denied by a frozen inherited policy projection` };
212
224
  }
213
225
  continue;
214
226
  }
215
227
  if (c.kind === "tool_allowlist") {
216
- if (!listed(c.names) && !namespacedCoveringHit(namespacedCoveringEntries(c.names), req)) {
228
+ if (!listed(c.names) && !namespacedCoveringHit(namespacedCoveringEntries(c.names, "allow"), req)) {
217
229
  return { action: "deny", message: `tool "${req.toolName}" is not in a frozen inherited policy projection's allowlist` };
218
230
  }
219
231
  continue;
@@ -403,13 +415,18 @@ export function createAllowDenyPolicy(opts) {
403
415
  invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
404
416
  continue;
405
417
  }
406
- if (spelled.ruleContent === undefined) {
418
+ if (ruleContentOf(spelled) === undefined) {
407
419
  if (spelled.toolName === "*" && list === "deny") {
408
420
  const lesson = `the wildcard — \`*\` names no tool, and a deny entry reaches the tool it names, so this one would be kept and never match ` +
409
421
  `(a deny that reads protective and denies nothing). Name the tools to deny; to leave a run no tools, write an empty allow list.`;
410
422
  invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
411
423
  continue;
412
424
  }
425
+ const wild = list === "allow" ? wildcardPeerRefusalOf(spelled.toolName, "allow") : undefined;
426
+ if (wild !== undefined) {
427
+ invalid.push({ entry, list, message: `"${entry}": ${wild}`, lesson: wild });
428
+ continue;
429
+ }
413
430
  if (!seen.has(spelled.toolName)) {
414
431
  seen.add(spelled.toolName);
415
432
  kept.push(spelled.toolName);
@@ -448,8 +465,8 @@ export function createAllowDenyPolicy(opts) {
448
465
  opts = { ...opts, ...(screenedAllow ? { allow: screenedAllow } : {}), ...(screenedDeny ? { deny: screenedDeny } : {}) };
449
466
  const allow = opts.allow ? new Set(opts.allow) : undefined;
450
467
  const deny = new Set(opts.deny ?? []);
451
- const denyCovering = namespacedCoveringEntries(opts.deny);
452
- const allowCovering = namespacedCoveringEntries(opts.allow);
468
+ const denyCovering = namespacedCoveringEntries(opts.deny, "deny");
469
+ const allowCovering = namespacedCoveringEntries(opts.allow, "allow");
453
470
  return {
454
471
  projection: {
455
472
  components: [
@@ -480,12 +497,19 @@ export function createApprovalPolicy(opts) {
480
497
  if (opts.approvalTimeoutMs !== undefined && opts.approvalTimeoutMs > 2_147_483_647) {
481
498
  throw new Error(`createApprovalPolicy: approvalTimeoutMs must not exceed 2147483647ms (~24.8 days) (got ${opts.approvalTimeoutMs}) — a host timer truncates a larger delay and fires immediately, denying every request at once; omit it to wait indefinitely`);
482
499
  }
500
+ for (const [list, entries] of [["autoAllow", opts.autoAllow ?? []], ["requireApproval", opts.denyByDefault === true ? opts.requireApproval : []]]) {
501
+ for (const entry of entries) {
502
+ const refusal = allowlistNameRefusal("createApprovalPolicy", entry, list);
503
+ if (refusal !== undefined)
504
+ throw refusal;
505
+ }
506
+ }
483
507
  const need = new Set(opts.requireApproval);
484
508
  const deny = new Set(opts.deny ?? []);
485
509
  const auto = new Set(opts.autoAllow ?? []);
486
- const needCovering = namespacedCoveringEntries(opts.requireApproval);
487
- const denyCovering = namespacedCoveringEntries(opts.deny);
488
- const autoCovering = namespacedCoveringEntries(opts.autoAllow);
510
+ const needCovering = namespacedCoveringEntries(opts.requireApproval, "ask");
511
+ const denyCovering = namespacedCoveringEntries(opts.deny, "deny");
512
+ const autoCovering = namespacedCoveringEntries(opts.autoAllow, "allow");
489
513
  return {
490
514
  projection: {
491
515
  components: [
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * Layer-0 vocabulary: depends on the leaf catalog and the face vocabulary only.
12
12
  */
13
- import { type ToolCallPathTarget, type ToolCatalogEntry, type ToolFamily, type ToolMountTag, type ToolPathAccess } from "./tool-face.js";
13
+ import { type ToolCallPathTarget, type ToolCatalogEntry, type ToolFamily, type ToolHostTarget, type ToolMountTag, type ToolPathAccess } from "./tool-face.js";
14
14
  /** The whole static catalog, one frozen row per definition (design/388 §2.1 `describeToolCatalog()`).
15
15
  * Replaces the retired name-keyed exports `HAND_TOOL_EFFECTS` / `DEFAULT_BUDGET_EXEMPT_TOOLS` /
16
16
  * `COMPACTABLE_TOOLS`: filter this instead (`e.mountedBy.includes("hands")`, `e.face.budgetExempt`,
@@ -68,6 +68,8 @@ export declare function rosterCanPersistMemory(tools: ReadonlyArray<PersistenceP
68
68
  export declare function persistenceCandidateToolNames(): string[];
69
69
  /** A-8 — every definition that names a path target at all (read or write): the file-tool glob lane. */
70
70
  export declare function pathTargetingToolNames(): ReadonlySet<string>;
71
+ /** Every definition that names a host target (the URL its call reaches): the names a host rule is written for. */
72
+ export declare function hostTargetingToolNames(): ReadonlySet<string>;
71
73
  /**
72
74
  * The SHELL FACE: every definition whose `command` argument is a shell command line the command grammar judges (today the two
73
75
  * `Bash` definitions and `Monitor`). A `Bash(<command>)` rule reaches a call that answers to any of these names; the coarse
@@ -117,6 +119,7 @@ export interface ToolCallLike {
117
119
  args: unknown;
118
120
  face?: {
119
121
  pathTarget?: ToolCallPathTarget;
122
+ hostTarget?: ToolHostTarget;
120
123
  names?: readonly string[];
121
124
  } | undefined;
122
125
  }
@@ -165,13 +168,17 @@ export declare function isDeclaredWrite(call: ToolCallLike): boolean;
165
168
  * records nothing (retired spellings in persisted transcripts read the frozen history table at the call site). */
166
169
  export declare function fileOpAccessOf(name: string): ToolPathAccess | undefined;
167
170
  export declare function pathTargetOf(name: string): ToolCatalogEntry["face"]["pathTarget"];
171
+ /** The host target a wire name's catalog definition declares (the URL slot a host rule of that name is read on), the
172
+ * {@link pathTargetOf} of the host face: the first definition under the name that declares one. */
173
+ export declare function hostTargetOf(name: string): ToolCatalogEntry["face"]["hostTarget"];
168
174
  /**
169
- * The rule vocabulary of a wire name from the STATIC catalog: `primaryParams` = the declared primaries, else
170
- * the path target's `param` + aliases; `params` = the declared vocabulary, else the path target's names —
171
- * and UNDEFINED when the catalog cannot know the full vocabulary (a definition whose schema is built inside
172
- * its factory and declares no `ruleFace.params`): the static half never claims a vocabulary it has not
173
- * read, so the rule compiler judges only what it knows and the leg's roster (which reads the schema)
174
- * judges the rest. `undefined` as a whole for a name with nothing to say.
175
+ * The rule vocabulary of a wire name from the STATIC catalog, over every definition the name (or an alias) answers to:
176
+ * `primaryParams` = the first definition's declared primaries, else its path target's `param` + aliases; `params` = every
177
+ * definition's declared vocabulary, else its path target's names, primaries included — UNDEFINED when no definition
178
+ * under the name declares one (StructuredOutput: its schema is each task's), whose face then names no parameter at all.
179
+ * A definition whose schema is built inside its factory declares its FULLEST mount's vocabulary; a mounted instance's
180
+ * is the roster's, read off the schema it carries (`ruleFaceOfInstance`). `undefined` as a whole for a name the
181
+ * catalog does not carry.
175
182
  */
176
183
  export declare function catalogRuleFaceOf(name: string): {
177
184
  primaryParams: string[];
@@ -55,6 +55,9 @@ export function persistenceCandidateToolNames() {
55
55
  export function pathTargetingToolNames() {
56
56
  return names((e) => e.face.pathTarget !== undefined);
57
57
  }
58
+ export function hostTargetingToolNames() {
59
+ return names((e) => e.face.hostTarget !== undefined);
60
+ }
58
61
  const onShellFace = (e) => e.face.ruleFace?.grammar === "command";
59
62
  export function shellFaceToolNames() {
60
63
  return names(onShellFace);
@@ -125,18 +128,25 @@ export function pathTargetOf(name) {
125
128
  return e.face.pathTarget;
126
129
  return undefined;
127
130
  }
131
+ export function hostTargetOf(name) {
132
+ for (const e of TOOL_CATALOG_ENTRIES)
133
+ if (e.name === name && e.face.hostTarget !== undefined)
134
+ return e.face.hostTarget;
135
+ return undefined;
136
+ }
128
137
  export function catalogRuleFaceOf(name) {
138
+ let face;
129
139
  for (const e of TOOL_CATALOG_ENTRIES) {
130
- if (e.name !== name)
140
+ if (e.name !== name && !(e.face.aliases ?? []).includes(name))
131
141
  continue;
132
142
  const pt = e.face.pathTarget;
133
- const primary = e.face.ruleFace?.primaryParams ?? (pt !== undefined ? [pt.param, ...(pt.aliases ?? [])] : []);
134
- const params = e.face.ruleFace?.params ?? (pt !== undefined ? [pt.param, ...(pt.aliases ?? [])] : undefined);
135
- if (params === undefined && primary.length === 0)
136
- continue;
137
- return { primaryParams: [...primary], ...(params !== undefined ? { params: [...new Set([...params, ...primary])] } : {}) };
143
+ const target = pt !== undefined ? [pt.param, ...(pt.aliases ?? [])] : undefined;
144
+ const primary = e.face.ruleFace?.primaryParams ?? target ?? [];
145
+ const declared = e.face.ruleFace?.params ?? target;
146
+ const params = declared === undefined ? face?.params : [...new Set([...(face?.params ?? []), ...declared, ...primary])];
147
+ face = { primaryParams: face?.primaryParams ?? [...primary], ...(params !== undefined ? { params } : {}) };
138
148
  }
139
- return undefined;
149
+ return face;
140
150
  }
141
151
  export function handBandEffects() {
142
152
  const out = new Map();
@@ -4,7 +4,7 @@ import { uuidv7 } from "../engine/session/uuid.js";
4
4
  import { defineTool, errorResult } from "./tools.js";
5
5
  import { deliverEngineNotice } from "./types.js";
6
6
  import { TOOL_SEARCH_NAME } from "./runner/tool-disclosure.js";
7
- import { toolFace } from "./tool-catalog-entries.js";
7
+ import { mountRuleFace, toolFace } from "./tool-catalog-entries.js";
8
8
  import { thrownText } from "./thrown-value.js";
9
9
  export const TOOL_RESULT_REF_CONFLICT_CODE = "tool_result.ref_conflict";
10
10
  export class ToolResultRefConflictError extends Error {
@@ -385,6 +385,7 @@ export function createReadToolResultTool(store) {
385
385
  return defineTool({
386
386
  name: OFFLOAD_TOOL_NAME,
387
387
  ...toolFace("read-tool-result"),
388
+ ruleFace: mountRuleFace("read-tool-result"),
388
389
  description: `Read the full content of a tool result that was too large and persisted (you saw it as ` +
389
390
  `<persisted-output ref="..."> with a preview). Pass the ref; use offset/limit to page through it.`,
390
391
  parameters: Type.Object({
@@ -1,6 +1,6 @@
1
1
  import { Type, type Static, type TSchema } from "typebox";
2
2
  import type { AgentTool } from "../internal/harness-types.js";
3
- import { type ReservedApprovalCard, type ToolApprovalCard, type ToolFamily, type ToolRosterPathTarget, type ToolMountTag, type ToolPathTarget, type ToolRenderHints, type ToolRuleFace } from "./tool-face.js";
3
+ import { type ReservedApprovalCard, type ToolApprovalCard, type ToolFamily, type ToolHostTarget, type ToolRosterPathTarget, type ToolMountTag, type ToolPathTarget, type ToolRenderHints, type ToolRuleFace } from "./tool-face.js";
4
4
  import type { ToolContentOrigin, ToolEffect } from "./tool-spec.js";
5
5
  import type { ToolMarkSource } from "./ask-origin.js";
6
6
  export declare const ROSTER_SOURCES: readonly ["builtin", "caller", "host", "mcp", "a2a", "external", "synthetic"];
@@ -10,7 +10,7 @@ export declare const ToolRosterRenderHints: Type.TObject<{
10
10
  activity: Type.TOptional<Type.TString>;
11
11
  summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
12
12
  resultCards: Type.TOptional<Type.TArray<Type.TString>>;
13
- approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
13
+ approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"skill">, Type.TLiteral<"workflow">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
14
14
  }>;
15
15
  export declare const ToolRosterEntry: Type.TObject<{
16
16
  name: Type.TString;
@@ -63,9 +63,17 @@ export declare const ToolRosterEntry: Type.TObject<{
63
63
  absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
64
64
  patternParam: Type.TOptional<Type.TString>;
65
65
  }>>;
66
+ /** The URL slot a host rule of the row's name is read on, as the definition declared it ({@link ToolHostTarget}); absent when
67
+ * it declares none. Exclusive with `pathTarget`. */
68
+ hostTarget: Type.TOptional<Type.TObject<{
69
+ param: Type.TString;
70
+ }>>;
71
+ /** `nameValues`: the values the mounted tool takes for the argument its name rules are read against (`ToolRuleFace.nameValues`,
72
+ * the delegation tool's offered agent types) — present exactly when the definition declares them, copied as declared. */
66
73
  ruleFace: Type.TObject<{
67
74
  primaryParams: Type.TArray<Type.TString>;
68
75
  params: Type.TArray<Type.TString>;
76
+ nameValues: Type.TOptional<Type.TArray<Type.TString>>;
69
77
  }>;
70
78
  approvalPreview: Type.TBoolean;
71
79
  validateInput: Type.TBoolean;
@@ -78,7 +86,7 @@ export declare const ToolRosterEntry: Type.TObject<{
78
86
  activity: Type.TOptional<Type.TString>;
79
87
  summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
80
88
  resultCards: Type.TOptional<Type.TArray<Type.TString>>;
81
- approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
89
+ approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"skill">, Type.TLiteral<"workflow">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
82
90
  }>>;
83
91
  /** The ONE mount condition that fired for this instance. */
84
92
  mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
@@ -140,9 +148,17 @@ export declare const ToolRoster: Type.TObject<{
140
148
  absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
141
149
  patternParam: Type.TOptional<Type.TString>;
142
150
  }>>;
151
+ /** The URL slot a host rule of the row's name is read on, as the definition declared it ({@link ToolHostTarget}); absent when
152
+ * it declares none. Exclusive with `pathTarget`. */
153
+ hostTarget: Type.TOptional<Type.TObject<{
154
+ param: Type.TString;
155
+ }>>;
156
+ /** `nameValues`: the values the mounted tool takes for the argument its name rules are read against (`ToolRuleFace.nameValues`,
157
+ * the delegation tool's offered agent types) — present exactly when the definition declares them, copied as declared. */
143
158
  ruleFace: Type.TObject<{
144
159
  primaryParams: Type.TArray<Type.TString>;
145
160
  params: Type.TArray<Type.TString>;
161
+ nameValues: Type.TOptional<Type.TArray<Type.TString>>;
146
162
  }>;
147
163
  approvalPreview: Type.TBoolean;
148
164
  validateInput: Type.TBoolean;
@@ -155,7 +171,7 @@ export declare const ToolRoster: Type.TObject<{
155
171
  activity: Type.TOptional<Type.TString>;
156
172
  summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
157
173
  resultCards: Type.TOptional<Type.TArray<Type.TString>>;
158
- approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
174
+ approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"skill">, Type.TLiteral<"workflow">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
159
175
  }>>;
160
176
  /** The ONE mount condition that fired for this instance. */
161
177
  mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
@@ -225,9 +241,17 @@ export declare const ToolRosterDelta: Type.TObject<{
225
241
  absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
226
242
  patternParam: Type.TOptional<Type.TString>;
227
243
  }>>;
244
+ /** The URL slot a host rule of the row's name is read on, as the definition declared it ({@link ToolHostTarget}); absent when
245
+ * it declares none. Exclusive with `pathTarget`. */
246
+ hostTarget: Type.TOptional<Type.TObject<{
247
+ param: Type.TString;
248
+ }>>;
249
+ /** `nameValues`: the values the mounted tool takes for the argument its name rules are read against (`ToolRuleFace.nameValues`,
250
+ * the delegation tool's offered agent types) — present exactly when the definition declares them, copied as declared. */
228
251
  ruleFace: Type.TObject<{
229
252
  primaryParams: Type.TArray<Type.TString>;
230
253
  params: Type.TArray<Type.TString>;
254
+ nameValues: Type.TOptional<Type.TArray<Type.TString>>;
231
255
  }>;
232
256
  approvalPreview: Type.TBoolean;
233
257
  validateInput: Type.TBoolean;
@@ -240,7 +264,7 @@ export declare const ToolRosterDelta: Type.TObject<{
240
264
  activity: Type.TOptional<Type.TString>;
241
265
  summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
242
266
  resultCards: Type.TOptional<Type.TArray<Type.TString>>;
243
- approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
267
+ approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"skill">, Type.TLiteral<"workflow">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
244
268
  }>>;
245
269
  /** The ONE mount condition that fired for this instance. */
246
270
  mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
@@ -296,7 +320,7 @@ export declare function toolCallFaceOf(roster: ToolRoster | undefined, toolName:
296
320
  * (the row then reads pre-identity and the resume binds the name alone). */
297
321
  export declare function parkedToolIdentity(roster: ToolRoster | undefined, toolName: string): Partial<ToolIdentity>;
298
322
  /** design/388 B6 × B18 — the FACE members a park row carries beside its identity: the display family, the declared
299
- * path target and the names the parked call was judged under. `names` is copied from the face the gate stamped on the
323
+ * path target or URL slot, and the names the parked call was judged under. `names` is copied from the face the gate stamped on the
300
324
  * request (the model's spelling first — the row carries the judged fact, it is not re-derived); a request with no face
301
325
  * takes the roster's names for its row. A recheck that runs before the leg's roster exists (the pre-CAS resume-edit
302
326
  * re-adjudication) rebuilds the call face from the row through {@link parkedCallFaceOf}, so it judges the same object
@@ -310,6 +334,7 @@ export declare function parkedToolFace(roster: ToolRoster | undefined, req: {
310
334
  }): {
311
335
  family?: ToolFamily;
312
336
  pathTarget?: ToolRosterEntry["pathTarget"];
337
+ hostTarget?: ToolHostTarget;
313
338
  names?: readonly string[];
314
339
  };
315
340
  /** The live face a resumed park row is re-judged under: minted under the row's recorded spelling (`names[0]`) when that
@@ -325,6 +350,7 @@ export declare function parkedRowLiveFace(roster: ToolRoster | undefined, row: {
325
350
  export declare function parkedCallFaceOf(pending: {
326
351
  family?: ToolFamily;
327
352
  pathTarget?: ToolRosterPathTarget;
353
+ hostTarget?: ToolHostTarget;
328
354
  names?: readonly string[];
329
355
  capabilityId?: string;
330
356
  contractId?: string;
@@ -387,6 +413,10 @@ export declare function rosterMemberBoundProblem(m: RosterBoundMembers): {
387
413
  code: RosterBoundCode;
388
414
  message: string;
389
415
  } | undefined;
416
+ /** Did one of the ENGINE's own mount sites mount this row — a built-in or synthetic tool the engine minted for the leg — rather than a
417
+ * caller's `TaskSpec.tools` entry (`scenario`) or a protocol peer's tool? The one identity a caller cannot declare: a name, a contract
418
+ * id and a source word all can be worn, the mount site cannot. Read onto the call's face ({@link toolCallFaceOf}, `engineMounted`). */
419
+ export declare function engineMountedRow(e: Pick<ToolRosterEntry, "source" | "mountedBy">): boolean;
390
420
  /**
391
421
  * The rule vocabulary of ONE mounted instance (design/388 §2.2 ③ / D-3): DERIVED = the scalar top-level
392
422
  * keys ∪ the path target's `param` + aliases; a declared `params` list can only NARROW it (a declared
@@ -427,6 +457,7 @@ export interface MountedToolFace {
427
457
  mcpAlwaysLoad?: boolean;
428
458
  family?: ToolFamily;
429
459
  pathTarget?: ToolPathTarget;
460
+ hostTarget?: ToolHostTarget;
430
461
  ruleFace?: ToolRuleFace;
431
462
  renderHints?: ToolRenderHints;
432
463
  compactable?: true;
@@ -437,7 +468,7 @@ export interface MountedToolFace {
437
468
  export declare const faceOf: (t: AgentTool) => MountedToolFace;
438
469
  /** The leg facts the snapshot reads beside the instances — the safety scan's folds and the per-task knobs. */
439
470
  export interface RosterSnapshotFacts {
440
- /** The leg's by-name effect map (the builder is its mount-time writer; the protocol folds also write it). */
471
+ /** The leg's by-name effect map (the builder writes it at every mount and unmount; the protocol folds write a protocol member's). */
441
472
  effects: ReadonlyMap<string, ToolEffect>;
442
473
  egress: ReadonlySet<string>;
443
474
  irreversibilityTier: ReadonlyMap<string, "never" | "maybe" | "always">;
@@ -464,15 +495,11 @@ export declare class RosterBuilder {
464
495
  get tools(): readonly AgentTool[];
465
496
  get length(): number;
466
497
  metaOf(tool: AgentTool): RosterMountMeta | undefined;
467
- /** Mount one instance at the tail. An engine-lane instance that DECLARES an effect writes it into the leg's effect
468
- * map — the later mount under a name is the one the harness dispatches to (`snapshot`'s yield rule), so its
469
- * declaration is the map's truth for that name — an engine tool's effect reaches the map from its own declaration, here at its
470
- * mount (nothing writes it by name beforehand; a protocol axis fills a name no mounted instance declares, and the gate's
471
- * post-assembly sync a kept instance the map still lacks). The `scenario` lane never writes the map: its
472
- * declarations were latched by the safety scan BEFORE any mount (on the kept instance of each name, on the
473
- * synchronous doors+scan stretch — a microtask cannot flip them), so a scenario mount, kept or dropped, leaves
474
- * the map as the scan made it; an engine lane's mount under that name still displaces it, and the aliases the displaced
475
- * instance answered to move to the member they now resolve to (`#resettleAliases`). */
498
+ /** Mount one instance at the tail; the leg's effect map then follows the mounted set (`#settleEffects`). The later mount under
499
+ * a name is the one the harness dispatches to (`snapshot`'s yield rule). A `scenario` mount (a caller's own `TaskSpec.tools`
500
+ * entry, the driver's frozen face — the declaration the safety scan judged) leaves the three safety axes as the scan wrote them;
501
+ * any other mount under a name displaces the instance there, and the axes of the aliases the displaced instance answered to
502
+ * move to the member they now resolve to (`#resettleAliases`). */
476
503
  mount(tool: AgentTool, meta: RosterMountMeta): void;
477
504
  /** An ENGINE-INJECTED instance the harness list carries outside the mount array (the ToolSearch lane): a roster
478
505
  * row — the model can call it — never a mount-array element (the disclosure lane owns that list and appends the
@@ -555,13 +582,15 @@ export declare class ToolRosterDeltaSeat {
555
582
  /**
556
583
  * design/388 B15 — the rule-face resolver a leg hands the rule compiler: every roster row answers with its
557
584
  * derived vocabulary, the carried-but-non-scalar keys (so `Edit(edits:x)` reads `param_non_scalar`, not
558
- * `param_unknown`) and whether it names a path target; a name off the roster answers undefined.
585
+ * `param_unknown`) and the values a name rule of it is resolved against when the definition declares them (`nameValues`);
586
+ * a name off the roster answers undefined. Which lane a rule takes is the rule name's grammar, not the row's: the resolver
587
+ * says which parameters the mounted tool carries and which name values it declares.
559
588
  */
560
589
  export declare function ruleFacesFromRoster(roster: ToolRoster): (toolName: string) => {
561
590
  primaryParams: readonly string[];
562
591
  params: readonly string[];
563
592
  nonScalar: readonly string[];
564
- pathTargeting: boolean;
593
+ nameValues?: readonly string[];
565
594
  } | undefined;
566
595
  /** The delta between two snapshots (design/388 §2.5): the whole `next` roster plus the name summary. */
567
596
  export declare function diffToolRoster(prev: ToolRoster, next: ToolRoster): ToolRosterDelta;
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { types } from "node:util";
3
3
  import { Type } from "typebox";
4
- import { findToolByName } from "../internal/llm.js";
4
+ import { toolNameIndex } from "../internal/llm.js";
5
5
  import { getToolContract } from "../prompt-assembly/tool-catalog.js";
6
6
  import { protocolOf } from "./protocol-table.js";
7
7
  import { describeToolCatalog } from "./tool-registry.js";
@@ -60,7 +60,8 @@ export const ToolRosterEntry = Type.Object({
60
60
  absent: Type.Optional(lit(TOOL_PATH_ABSENCES)),
61
61
  patternParam: Type.Optional(Key),
62
62
  }, { additionalProperties: false })),
63
- ruleFace: Type.Object({ primaryParams: Type.Array(Key), params: Type.Array(Key) }, { additionalProperties: false }),
63
+ hostTarget: Type.Optional(Type.Object({ param: Key }, { additionalProperties: false })),
64
+ ruleFace: Type.Object({ primaryParams: Type.Array(Key), params: Type.Array(Key), nameValues: Type.Optional(Type.Array(Type.String())) }, { additionalProperties: false }),
64
65
  approvalPreview: Type.Boolean(),
65
66
  validateInput: Type.Boolean(),
66
67
  deferred: Type.Boolean(),
@@ -116,11 +117,14 @@ export function toolCallFaceOf(roster, toolName) {
116
117
  names: resolving.includes(toolName) ? [toolName, ...resolving.filter((n) => n !== toolName)] : resolving,
117
118
  family: e.family,
118
119
  ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}),
120
+ ...(e.hostTarget !== undefined ? { hostTarget: e.hostTarget } : {}),
121
+ ...(e.ruleFace?.nameValues !== undefined ? { nameValues: Object.freeze([...e.ruleFace.nameValues]) } : {}),
119
122
  capabilityId: e.capabilityId,
120
123
  contractId: e.contract.contractId,
121
124
  shapeDigest: e.shapeDigest,
122
125
  implementationRevision: e.contract.implementationRevision,
123
126
  approvalCard: approvalCardOf({ toolName: e.name }, e.renderHints?.approvalCard),
127
+ ...(engineMountedRow(e) ? { engineMounted: true } : {}),
124
128
  };
125
129
  }
126
130
  export function parkedToolIdentity(roster, toolName) {
@@ -136,7 +140,7 @@ export function parkedToolFace(roster, req) {
136
140
  if (e === undefined)
137
141
  return {};
138
142
  const judged = req.face?.names;
139
- return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), names: judged !== undefined && judged.includes(req.toolName) ? [...judged] : namesResolvingTo(roster, e) };
143
+ return { family: e.family, ...(e.pathTarget !== undefined ? { pathTarget: e.pathTarget } : {}), ...(e.hostTarget !== undefined ? { hostTarget: e.hostTarget } : {}), names: judged !== undefined && judged.includes(req.toolName) ? [...judged] : namesResolvingTo(roster, e) };
140
144
  }
141
145
  export function parkedRowLiveFace(roster, row) {
142
146
  const spelled = row.names?.[0];
@@ -150,6 +154,7 @@ export function parkedCallFaceOf(pending) {
150
154
  ...(pending.names !== undefined ? { names: pending.names } : {}),
151
155
  family: pending.family,
152
156
  ...(pending.pathTarget !== undefined ? { pathTarget: pending.pathTarget } : {}),
157
+ ...(pending.hostTarget !== undefined ? { hostTarget: pending.hostTarget } : {}),
153
158
  capabilityId: pending.capabilityId,
154
159
  contractId: pending.contractId,
155
160
  shapeDigest: pending.shapeDigest,
@@ -268,6 +273,9 @@ export function rosterMemberBoundProblem(m) {
268
273
  return { code: "config.tool_roster_bound", message: of(over("cardId", m.cardId, TOOL_CARD_ID_MAX_CHARS)) };
269
274
  return undefined;
270
275
  }
276
+ export function engineMountedRow(e) {
277
+ return e.mountedBy !== "scenario" && (e.source === "builtin" || e.source === "synthetic");
278
+ }
271
279
  export function ruleFaceOfInstance(schema, declared, pathTarget) {
272
280
  const { scalar } = inputKeysOf(schema);
273
281
  const derived = new Set(scalar);
@@ -304,6 +312,7 @@ export function survivorsByName(mounted) {
304
312
  return winner;
305
313
  }
306
314
  export const faceOf = (t) => t;
315
+ const protocolFolded = (source) => source === "mcp" || source === "a2a";
307
316
  const setOrClear = (m, key, value) => {
308
317
  if (value === undefined)
309
318
  m.delete(key);
@@ -341,18 +350,19 @@ export class RosterBuilder {
341
350
  return this.#meta.get(tool);
342
351
  }
343
352
  mount(tool, meta) {
353
+ this.#settleEffects(this.#mountOne(tool, meta, this.#tools));
354
+ }
355
+ #mountOne(tool, meta, lane) {
344
356
  const displaced = this.#survivorNamed(tool.name);
345
357
  this.#admit(tool, meta);
346
- this.#tools.push(tool);
358
+ lane.push(tool);
359
+ const aliases = [...(displaced?.aliases ?? []), ...(tool.aliases ?? [])];
347
360
  if (meta.mountedBy !== "scenario")
348
- this.#resettleAliases([...(displaced?.aliases ?? []), ...(tool.aliases ?? [])]);
361
+ this.#resettleAliases(aliases);
362
+ return [tool.name, ...aliases];
349
363
  }
350
364
  mountEngineLane(tool, meta) {
351
- const displaced = this.#survivorNamed(tool.name);
352
- this.#admit(tool, meta);
353
- this.#engineLane.push(tool);
354
- if (meta.mountedBy !== "scenario")
355
- this.#resettleAliases([...(displaced?.aliases ?? []), ...(tool.aliases ?? [])]);
365
+ this.#settleEffects(this.#mountOne(tool, meta, this.#engineLane));
356
366
  }
357
367
  #admit(tool, meta) {
358
368
  if ((meta.source === "mcp" || meta.source === "a2a" || meta.source === "external") !== (meta.origin !== undefined)) {
@@ -361,9 +371,20 @@ export class RosterBuilder {
361
371
  if (!TOOL_MOUNT_TAGS.includes(meta.mountedBy))
362
372
  throw configError("config.tool_roster_mount_tag", `tool ${JSON.stringify(tool.name)}: mount tag ${JSON.stringify(meta.mountedBy)} is outside the closed set`);
363
373
  this.#meta.set(tool, meta);
364
- const eff = faceOf(tool).effect;
365
- if (eff !== undefined && meta.mountedBy !== "scenario")
366
- this.#effects.set(tool.name, eff);
374
+ }
375
+ #settleEffects(names) {
376
+ const answering = toolNameIndex([...survivorsByName([...this.#tools, ...this.#engineLane]).values()]);
377
+ for (const name of new Set(names)) {
378
+ const owner = answering(name);
379
+ const declared = owner === undefined ? undefined : faceOf(owner).effect;
380
+ if (declared !== undefined)
381
+ this.#effects.set(name, declared);
382
+ else if (owner === undefined || !protocolFolded(this.#meta.get(owner)?.source))
383
+ this.#effects.delete(name);
384
+ }
385
+ }
386
+ #namesAfterRemoval(removed) {
387
+ return [...this.#tools, ...this.#engineLane, ...removed].flatMap((t) => [t.name, ...(t.aliases ?? [])]);
367
388
  }
368
389
  #survivorNamed(name) {
369
390
  return survivorsByName([...this.#tools, ...this.#engineLane]).get(name);
@@ -371,20 +392,19 @@ export class RosterBuilder {
371
392
  #resettleAliases(aliases) {
372
393
  if (aliases.length === 0)
373
394
  return;
374
- const live = [...survivorsByName([...this.#tools, ...this.#engineLane]).values()];
395
+ const answering = toolNameIndex([...survivorsByName([...this.#tools, ...this.#engineLane]).values()]);
375
396
  for (const a of new Set(aliases)) {
376
- const owner = findToolByName(live, a);
397
+ const owner = answering(a);
377
398
  if (owner?.name === a)
378
399
  continue;
379
400
  this.#repoint(a, owner?.name);
380
401
  }
381
402
  }
382
403
  #repoint(key, from) {
383
- const pick = (m) => (from === undefined ? undefined : m.get(from));
384
- const marks = this.#axes === undefined ? undefined : pick(this.#axes.toolMarkSources);
385
- setOrClear(this.#effects, key, pick(this.#effects));
386
404
  if (this.#axes === undefined)
387
405
  return;
406
+ const pick = (m) => (from === undefined ? undefined : m.get(from));
407
+ const marks = pick(this.#axes.toolMarkSources);
388
408
  setOrClear(this.#axes.irreversibilityTier, key, pick(this.#axes.irreversibilityTier));
389
409
  setOrClear(this.#axes.reversibilityProbes, key, pick(this.#axes.reversibilityProbes));
390
410
  setOrClear(this.#axes.toolMarkSources, key, marks === undefined ? undefined : new Set(marks));
@@ -392,8 +412,7 @@ export class RosterBuilder {
392
412
  memberIf(this.#axes.egressTools, key, from !== undefined && this.#axes.egressTools.has(from));
393
413
  }
394
414
  mountAll(tools, meta) {
395
- for (const t of tools)
396
- this.mount(t, meta);
415
+ this.#settleEffects(tools.flatMap((t) => this.#mountOne(t, meta, this.#tools)));
397
416
  }
398
417
  unmountWhere(pred) {
399
418
  const removed = [];
@@ -404,9 +423,7 @@ export class RosterBuilder {
404
423
  removed.unshift(t);
405
424
  }
406
425
  }
407
- for (const t of removed)
408
- if (this.#survivorNamed(t.name) === undefined)
409
- this.#effects.delete(t.name);
426
+ this.#settleEffects(this.#namesAfterRemoval(removed));
410
427
  this.#resettleAliases(removed.flatMap((t) => t.aliases ?? []));
411
428
  return removed;
412
429
  }
@@ -421,22 +438,20 @@ export class RosterBuilder {
421
438
  }
422
439
  replaceDomain(prefix, fresh, meta) {
423
440
  let anchor = -1;
441
+ const removed = [];
424
442
  for (let i = this.#tools.length - 1; i >= 0; i--) {
425
443
  if (this.#tools[i].name.startsWith(prefix)) {
426
444
  anchor = i;
427
- this.#tools.splice(i, 1);
445
+ removed.push(...this.#tools.splice(i, 1));
428
446
  }
429
447
  }
430
- for (const t of fresh) {
448
+ for (const t of fresh)
431
449
  this.#meta.set(t, meta);
432
- const eff = faceOf(t).effect;
433
- if (eff !== undefined)
434
- this.#effects.set(t.name, eff);
435
- }
436
450
  if (anchor >= 0)
437
451
  this.#tools.splice(anchor, 0, ...fresh);
438
452
  else
439
453
  this.#tools.push(...fresh);
454
+ this.#settleEffects(this.#namesAfterRemoval(removed));
440
455
  return { anchor };
441
456
  }
442
457
  snapshot(facts) {
@@ -542,7 +557,7 @@ export function mintRosterEntry(tool, meta, facts) {
542
557
  const declaredEffect = face.effect;
543
558
  const foldedEffect = facts.effects.get(tool.name);
544
559
  const effect = declaredEffect ?? foldedEffect ?? "write";
545
- const effectProvenance = declaredEffect !== undefined ? (meta.source === "synthetic" ? "synthetic" : "declared") : foldedEffect !== undefined && (meta.source === "mcp" || meta.source === "a2a") ? "caller" : "default";
560
+ const effectProvenance = declaredEffect !== undefined ? (meta.source === "synthetic" ? "synthetic" : "declared") : foldedEffect !== undefined && protocolFolded(meta.source) ? "caller" : "default";
546
561
  const boundaryLegs = rosterBoundaryLegs(meta.source, face.boundaryLegs, effect);
547
562
  if (boundaryLegs === undefined)
548
563
  throw boundaryLegsRefusal(tool.name);
@@ -554,6 +569,11 @@ export function mintRosterEntry(tool, meta, facts) {
554
569
  const contentOriginProvenance = face.contentOrigin !== undefined ? (meta.source === "mcp" || meta.source === "a2a" ? "server" : "declared") : facts.trustedTools.has(tool.name) ? "exempted" : "default";
555
570
  const pathTarget = face.pathTarget;
556
571
  const rf = ruleFaceOfInstance(tool.parameters, face.ruleFace, pathTarget);
572
+ const declaredValues = face.ruleFace?.nameValues;
573
+ const isStringList = (v) => Array.isArray(v) && Array.from(v).every((s) => typeof s === "string");
574
+ if (declaredValues !== undefined && !isStringList(declaredValues))
575
+ throw configError("config.tool_roster_bound", `tool ${JSON.stringify(tool.name)}: ruleFace.nameValues must be a list of strings`);
576
+ const nameValues = declaredValues;
557
577
  const hints = face.renderHints !== undefined ? capRenderHints(face.renderHints) : undefined;
558
578
  const bound = rosterMemberBoundProblem({
559
579
  name: tool.name,
@@ -604,7 +624,8 @@ export function mintRosterEntry(tool, meta, facts) {
604
624
  },
605
625
  }
606
626
  : {}),
607
- ruleFace: rf,
627
+ ...(face.hostTarget !== undefined ? { hostTarget: { param: face.hostTarget.param } } : {}),
628
+ ruleFace: { ...rf, ...(nameValues !== undefined ? { nameValues: [...nameValues] } : {}) },
608
629
  approvalPreview: typeof tool.approvalPreview === "function",
609
630
  validateInput: typeof tool.validateInput === "function",
610
631
  deferred: facts.deferred.has(tool.name),
@@ -672,7 +693,7 @@ export function ruleFacesFromRoster(roster) {
672
693
  primaryParams: e.ruleFace.primaryParams,
673
694
  params: e.ruleFace.params,
674
695
  nonScalar: e.inputKeys.filter((k) => !params.has(k.name) && (k.type === "object" || k.type === "array")).map((k) => k.name),
675
- pathTargeting: e.pathTarget !== undefined,
696
+ ...(e.ruleFace.nameValues !== undefined ? { nameValues: Object.freeze([...e.ruleFace.nameValues]) } : {}),
676
697
  };
677
698
  };
678
699
  }