@sema-agent/core 7.48.0 → 7.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +17 -24
  52. package/dist/core/arg-summary.js +169 -68
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +32 -7
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +4 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +27 -34
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/turn-attachments.d.ts +1 -1
  243. package/dist/core/runner/write-protection-station.d.ts +21 -9
  244. package/dist/core/runner/write-protection-station.js +20 -17
  245. package/dist/core/runner-deps.d.ts +12 -22
  246. package/dist/core/secret-env.d.ts +16 -5
  247. package/dist/core/secret-env.js +23 -63
  248. package/dist/core/sensitive-path-policy.d.ts +19 -18
  249. package/dist/core/sensitive-path-policy.js +73 -49
  250. package/dist/core/session-reconcile.d.ts +3 -0
  251. package/dist/core/session-reconcile.js +5 -4
  252. package/dist/core/session-store.d.ts +5 -0
  253. package/dist/core/session-store.js +12 -0
  254. package/dist/core/session.d.ts +13 -0
  255. package/dist/core/shared-memory/normalize.d.ts +17 -4
  256. package/dist/core/shared-memory/normalize.js +7 -7
  257. package/dist/core/shell-lexer.js +5 -4
  258. package/dist/core/skill-grant.js +1 -1
  259. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  260. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  261. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  262. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  263. package/dist/core/stub-env.d.ts +2 -0
  264. package/dist/core/stub-env.js +1 -0
  265. package/dist/core/synthetic-read-verdict.js +2 -2
  266. package/dist/core/task-event.d.ts +59 -5
  267. package/dist/core/task-result.d.ts +1 -1
  268. package/dist/core/task-spec.d.ts +42 -9
  269. package/dist/core/terminal-cause.d.ts +94 -11
  270. package/dist/core/tighten-task-spec.d.ts +5 -4
  271. package/dist/core/tighten-task-spec.js +20 -25
  272. package/dist/core/tool-catalog-entries.d.ts +5 -7
  273. package/dist/core/tool-catalog-entries.js +14 -15
  274. package/dist/core/tool-face.d.ts +47 -0
  275. package/dist/core/tool-face.js +5 -0
  276. package/dist/core/tool-model-gate.d.ts +5 -5
  277. package/dist/core/tool-name-aliases.d.ts +26 -2
  278. package/dist/core/tool-name-aliases.js +13 -0
  279. package/dist/core/tool-name-list.d.ts +30 -0
  280. package/dist/core/tool-name-list.js +55 -0
  281. package/dist/core/tool-name-readings.d.ts +1 -9
  282. package/dist/core/tool-name-readings.js +1 -3
  283. package/dist/core/tool-policy.d.ts +195 -85
  284. package/dist/core/tool-policy.js +165 -380
  285. package/dist/core/tool-registry.d.ts +44 -1
  286. package/dist/core/tool-registry.js +26 -0
  287. package/dist/core/tool-roster.d.ts +19 -1
  288. package/dist/core/tool-roster.js +21 -2
  289. package/dist/core/tool-spec-members.d.ts +45 -0
  290. package/dist/core/tool-spec-members.js +169 -0
  291. package/dist/core/tool-spec.d.ts +46 -8
  292. package/dist/core/tools.d.ts +6 -2
  293. package/dist/core/tools.js +8 -4
  294. package/dist/core/untrusted-egress.js +29 -26
  295. package/dist/core/untrusted-text.d.ts +13 -10
  296. package/dist/core/untrusted-text.js +6 -44
  297. package/dist/core/workflow-journal-store.d.ts +4 -1
  298. package/dist/core/write-protect.d.ts +65 -29
  299. package/dist/core/write-protect.js +235 -177
  300. package/dist/engine/compaction/compaction.d.ts +2 -2
  301. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  302. package/dist/engine/execution-env/node-execution-env.js +16 -38
  303. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  304. package/dist/engine/execution-env/symlink-chain.js +32 -0
  305. package/dist/engine/harness/types.d.ts +7 -0
  306. package/dist/engine/llm/tool-turns.d.ts +3 -0
  307. package/dist/engine/llm/tool-turns.js +1 -0
  308. package/dist/engine/llm/types.d.ts +59 -23
  309. package/dist/engine/loop/agent-loop.js +16 -2
  310. package/dist/engine/session/memory-repo.js +11 -3
  311. package/dist/engine/session/repo-utils.d.ts +8 -0
  312. package/dist/engine/session/repo-utils.js +13 -0
  313. package/dist/index.d.ts +20 -23
  314. package/dist/index.js +17 -20
  315. package/dist/internal/harness.d.ts +1 -1
  316. package/dist/internal/harness.js +1 -1
  317. package/dist/internal/llm.d.ts +2 -2
  318. package/dist/internal/llm.js +1 -1
  319. package/dist/orchestration/governance-baseline-validity.js +1 -1
  320. package/dist/orchestration/run-spec.js +3 -3
  321. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  322. package/dist/orchestration/run-workflow-tool.js +38 -78
  323. package/dist/orchestration/workflow-governance.d.ts +21 -25
  324. package/dist/orchestration/workflow-governance.js +38 -78
  325. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  326. package/dist/orchestration/workflow-primitives.js +5 -12
  327. package/dist/orchestration/workflow-types.d.ts +1 -1
  328. package/dist/orchestration/workflow.d.ts +61 -11
  329. package/dist/orchestration/workflow.js +189 -117
  330. package/dist/scenarios/full-body.d.ts +1 -1
  331. package/dist/shell/lex.d.ts +0 -21
  332. package/dist/shell/lex.js +250 -68
  333. package/dist/shell/shell-words.d.ts +35 -0
  334. package/dist/shell/shell-words.js +65 -0
  335. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  336. package/dist/stores/file/checkpoint-store.js +5 -2
  337. package/dist/stores/file/index.d.ts +0 -8
  338. package/dist/stores/file/index.js +0 -12
  339. package/dist/stores/file/session-store.d.ts +3 -0
  340. package/dist/stores/file/session-store.js +44 -19
  341. package/dist/tools/artifact/artifact-tool.js +2 -0
  342. package/dist/tools/fs/bash-program-position.d.ts +10 -3
  343. package/dist/tools/fs/bash-program-position.js +21 -9
  344. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  345. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  346. package/dist/tools/fs/containment-face.d.ts +4 -0
  347. package/dist/tools/fs/containment-face.js +3 -0
  348. package/dist/tools/fs/fs-shared.d.ts +10 -0
  349. package/dist/tools/fs/fs-shared.js +18 -0
  350. package/dist/tools/fs/fs-write.js +4 -2
  351. package/dist/tools/fs/index.d.ts +1 -1
  352. package/dist/tools/fs/program-read-model.d.ts +39 -18
  353. package/dist/tools/fs/program-read-model.js +29 -19
  354. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  355. package/dist/tools/fs/program-read-model.rows.js +5 -5
  356. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  357. package/dist/tools/fs/read-deny-home.js +35 -49
  358. package/dist/tools/fs/read-deny.d.ts +23 -22
  359. package/dist/tools/fs/read-deny.js +114 -89
  360. package/dist/tools/fs/removal-targets.d.ts +56 -23
  361. package/dist/tools/fs/removal-targets.js +65 -87
  362. package/dist/tools/fs/safety.d.ts +29 -22
  363. package/dist/tools/fs/safety.js +17 -11
  364. package/dist/tools/fs/search.js +10 -8
  365. package/dist/tools/fs/shell-read-argv.js +1 -1
  366. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  367. package/dist/tools/fs/shell-read-bindings.js +324 -86
  368. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  369. package/dist/tools/fs/shell-read-builtins.js +43 -0
  370. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  371. package/dist/tools/fs/shell-read-check.js +51 -42
  372. package/dist/tools/fs/shell-read-establish.js +6 -6
  373. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  374. package/dist/tools/fs/shell-read-functions.js +29 -0
  375. package/dist/tools/fs/shell-read-judge.d.ts +48 -18
  376. package/dist/tools/fs/shell-read-judge.js +33 -4
  377. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  378. package/dist/tools/fs/shell-read-plan.js +118 -113
  379. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  380. package/dist/tools/fs/shell-read-start.js +16 -9
  381. package/dist/tools/fs/shell-read-word.js +4 -0
  382. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  383. package/dist/tools/fs/shell-read-workdir.js +281 -0
  384. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  385. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  386. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  387. package/dist/tools/fs/shell-reentry-text.js +3 -11
  388. package/dist/tools/task-list.d.ts +1 -2
  389. package/dist/tools/web.js +1 -1
  390. package/package.json +4 -1
  391. package/test/export-surface.snapshot.json +107 -143
  392. package/wire-changes/core@7.49.0.json +4765 -0
  393. package/dist/agents/teacher.d.ts +0 -159
  394. package/dist/agents/teacher.js +0 -577
  395. package/dist/agents/team.d.ts +0 -226
  396. package/dist/agents/team.js +0 -257
  397. package/dist/core/strategy-store.d.ts +0 -238
  398. package/dist/core/strategy-store.js +0 -253
  399. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  400. package/dist/orchestration/builtin-workflows.js +0 -159
  401. package/dist/scenarios/env.d.ts +0 -40
  402. package/dist/scenarios/env.js +0 -39
  403. package/dist/scenarios/scenario-registry.d.ts +0 -110
  404. package/dist/scenarios/scenario-registry.js +0 -140
  405. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  406. package/dist/scenarios/teacher-quickstart.js +0 -12
  407. package/dist/stores/cc/lockfile.d.ts +0 -10
  408. package/dist/stores/cc/lockfile.js +0 -98
  409. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  410. package/dist/stores/cc/mailbox-store.js +0 -255
  411. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  412. package/dist/stores/cc/roster-adapter.js +0 -117
  413. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  414. package/dist/stores/cc/sidecar-transcript.js +0 -264
  415. package/dist/stores/cc/task-list-store.d.ts +0 -2
  416. package/dist/stores/cc/task-list-store.js +0 -125
  417. package/dist/stores/file/strategy-store.d.ts +0 -97
  418. package/dist/stores/file/strategy-store.js +0 -341
@@ -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 ToolMountTag, type ToolPathAccess } from "./tool-face.js";
13
+ import { type ToolCallPathTarget, type ToolCatalogEntry, type ToolFamily, 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`,
@@ -23,6 +23,49 @@ export declare function catalogToolNames(): ReadonlySet<string>;
23
23
  /** A-11/12/13/14 — tools this engine can CONFINE BY PATH on a write: `pathTarget.access ≠ read`.
24
24
  * Today {Write, Edit, NotebookEdit}. */
25
25
  export declare function pathConfinableWriteToolNames(): ReadonlySet<string>;
26
+ /**
27
+ * What the persistence judge reads off ONE tool: its name and the three face members (all optional — a mounted
28
+ * instance carries the ones its definition declared, read straight off the object). A member the tool does not
29
+ * carry falls to the catalog's declaration for its NAME (a bare caller tool wearing a catalog name, such as a
30
+ * hands-less host's own `Write`, takes that definition's face — never a wider one).
31
+ */
32
+ export interface PersistenceProbeTool {
33
+ readonly name: string;
34
+ readonly effect?: import("./tool-spec.js").ToolEffect;
35
+ readonly pathTarget?: {
36
+ readonly access: ToolPathAccess;
37
+ };
38
+ readonly family?: ToolFamily;
39
+ }
40
+ /** The leg facts the judge reads beside the tools. */
41
+ export interface PersistenceFacts {
42
+ /** Names the leg's frozen tool-face snapshot excludes — an excluded tool is unmounted, so it persists nothing. */
43
+ readonly exclude?: readonly string[];
44
+ /** The leg's by-name effect map: the fallback for a tool that declares no `effect` of its own (silent ⇒ `"write"`). */
45
+ readonly effects?: ReadonlyMap<string, import("./tool-spec.js").ToolEffect>;
46
+ /** The hand band is mounted on a REMOTE env: its file tools write the sandbox filesystem, not the host-side memory
47
+ * root, so their presence proves nothing about persistence there. */
48
+ readonly remoteHands: boolean;
49
+ }
50
+ /**
51
+ * The names, among a run's MOUNTED tools (instances, whose face members sit on the object itself), the persistence
52
+ * judgment passes. The judgment's inputs beyond the tools (the exclude snapshot, the by-name effect map, whether the
53
+ * hand band is remote) are leg facts only the run holds; {@link rosterCanPersistMemory} is the verdict built on it.
54
+ */
55
+ export declare function persistenceCapableToolNames(tools: ReadonlyArray<PersistenceProbeTool>, facts: PersistenceFacts): string[];
56
+ /**
57
+ * The roster-wide persistence verdict a run reads: the deployment's own `declared` statement wins (the only honest
58
+ * channel for a caller tool that persists through its own closure, which no inference can see); otherwise some tool
59
+ * of the mounted roster passes {@link persistenceCapableToolNames}' judgment.
60
+ */
61
+ export declare function rosterCanPersistMemory(tools: ReadonlyArray<PersistenceProbeTool>, facts: PersistenceFacts, declared?: boolean): boolean;
62
+ /**
63
+ * The CANDIDATE set, from the static catalog alone: the names whose definition passes the same judgment on no leg
64
+ * facts at all (nothing excluded, no by-name effect map, hands not remote) — the tools that COULD persist on a leg
65
+ * that mounts them. A prediction, not a verdict: whether a given run's roster persists is
66
+ * {@link rosterCanPersistMemory}, which the runner calls with the facts the run holds.
67
+ */
68
+ export declare function persistenceCandidateToolNames(): string[];
26
69
  /** A-8 — every definition that names a path target at all (read or write): the file-tool glob lane. */
27
70
  export declare function pathTargetingToolNames(): ReadonlySet<string>;
28
71
  /**
@@ -26,6 +26,32 @@ const names = (pred) => {
26
26
  export function pathConfinableWriteToolNames() {
27
27
  return names((e) => e.face.pathTarget !== undefined && e.face.pathTarget.access !== "read");
28
28
  }
29
+ function toolCanPersist(t, facts) {
30
+ if (facts.exclude?.includes(t.name) ?? false)
31
+ return false;
32
+ const effect = t.effect ?? facts.effects?.get(t.name) ?? "write";
33
+ if (effect === "read")
34
+ return false;
35
+ const pathTarget = t.pathTarget ?? pathTargetOf(t.name);
36
+ const family = t.family ?? catalogEntriesNamed(t.name)[0]?.face.family;
37
+ if (!((pathTarget !== undefined && pathTarget.access !== "read") || family === "shell"))
38
+ return false;
39
+ return !facts.remoteHands;
40
+ }
41
+ export function persistenceCapableToolNames(tools, facts) {
42
+ const out = new Set();
43
+ for (const t of tools)
44
+ if (toolCanPersist(t, facts))
45
+ out.add(t.name);
46
+ return [...out];
47
+ }
48
+ export function rosterCanPersistMemory(tools, facts, declared) {
49
+ return declared ?? tools.some((t) => toolCanPersist(t, facts));
50
+ }
51
+ export function persistenceCandidateToolNames() {
52
+ const rows = TOOL_CATALOG_ENTRIES.map((e) => ({ name: e.name, effect: e.face.effect, pathTarget: e.face.pathTarget, family: e.face.family }));
53
+ return persistenceCapableToolNames(rows, { remoteHands: false });
54
+ }
29
55
  export function pathTargetingToolNames() {
30
56
  return names((e) => e.face.pathTarget !== undefined);
31
57
  }
@@ -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 ToolFamily, type ToolRosterPathTarget, type ToolMountTag, type ToolPathTarget, type ToolRenderHints, type ToolRuleFace } from "./tool-face.js";
3
+ import { type ReservedApprovalCard, type ToolApprovalCard, type ToolFamily, 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
  export declare const ROSTER_SOURCES: readonly ["builtin", "caller", "host", "mcp", "a2a", "external", "synthetic"];
6
6
  export type RosterSource = (typeof ROSTER_SOURCES)[number];
@@ -258,6 +258,24 @@ export declare function rosterEntryNamed(roster: ToolRoster, toolName: string):
258
258
  */
259
259
  export declare function rosterToolName(roster: ToolRoster | undefined, name: string): string;
260
260
  export { ruleNamesOf } from "./tool-name-readings.js";
261
+ /** The reserved card a call owns, judged from its wire name alone — the ONE read of "is this the engine's question /
262
+ * plan tool": the card minted on a call's face, the park's question mark and the decide's answer binding all ask it. */
263
+ export declare function engineCardOf(call: {
264
+ readonly toolName: string;
265
+ }): ReservedApprovalCard | undefined;
266
+ /** The approval card a call renders under: a reserved card only for the engine tool that owns it (whatever a row
267
+ * declares), otherwise the row's declared card, else `generic`. */
268
+ export declare function approvalCardOf(call: {
269
+ readonly toolName: string;
270
+ }, declared: ToolApprovalCard | undefined): ToolApprovalCard;
271
+ /** The ask / gate member that carries a call's card: copied off the face the gate stamped, absent on a bare request. */
272
+ export declare function approvalCardMemberOf(call: {
273
+ readonly face?: {
274
+ readonly approvalCard?: ToolApprovalCard;
275
+ } | undefined;
276
+ }): {
277
+ approvalCard?: ToolApprovalCard;
278
+ };
261
279
  /** design/388 B6 — the per-call face a gated request carries, read off a roster snapshot by name (aliases resolve).
262
280
  * `names` leads with the name the face was minted under (the model's spelling at the gate), then the wire name and the
263
281
  * other aliases — the ONE order of a call's names: a reader that must pick one of them by position (a `member` seat)
@@ -3,7 +3,10 @@ import { Type } from "typebox";
3
3
  import { getToolContract } from "../prompt-assembly/tool-catalog.js";
4
4
  import { protocolOf } from "./protocol-table.js";
5
5
  import { describeToolCatalog } from "./tool-registry.js";
6
- import { RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_CHARS, RENDER_HINT_MAX_LIST, TOOL_APPROVAL_CARDS, TOOL_CARD_ID_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_FAMILIES, TOOL_KEYS_MAX, TOOL_KEY_MAX_CHARS, TOOL_MOUNT_TAGS, TOOL_WIRE_NAME_MAX_CHARS, TOOL_PATH_ABSENCES, TOOL_PATH_BASES, } from "./tool-face.js";
6
+ import { RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_CHARS, RENDER_HINT_MAX_LIST, RESERVED_APPROVAL_CARDS, isToolApprovalCard, TOOL_APPROVAL_CARDS, TOOL_CARD_ID_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_FAMILIES, TOOL_KEYS_MAX, TOOL_KEY_MAX_CHARS, TOOL_MOUNT_TAGS, TOOL_WIRE_NAME_MAX_CHARS, TOOL_PATH_ABSENCES, TOOL_PATH_BASES, } from "./tool-face.js";
7
+ import { ASK_USER_QUESTION_TOOL_NAME } from "./ask-question.js";
8
+ import { PRESENT_PLAN_TOOL_NAME } from "./present-plan-tool.js";
9
+ import { wireOf } from "./tool-name-readings.js";
7
10
  function lit(values) {
8
11
  return Type.Union(values.map((v) => Type.Literal(v)));
9
12
  }
@@ -82,6 +85,21 @@ function namesResolvingTo(roster, e) {
82
85
  return [e.name, ...e.aliases.filter((a) => a !== e.name && rosterToolName(roster, a) === e.name)];
83
86
  }
84
87
  export { ruleNamesOf } from "./tool-name-readings.js";
88
+ const RESERVED_CARD_OWNER = {
89
+ question: () => ASK_USER_QUESTION_TOOL_NAME,
90
+ plan: () => PRESENT_PLAN_TOOL_NAME,
91
+ };
92
+ export function engineCardOf(call) {
93
+ const wire = wireOf("card.reserved", call);
94
+ return RESERVED_APPROVAL_CARDS.find((card) => RESERVED_CARD_OWNER[card]() === wire);
95
+ }
96
+ export function approvalCardOf(call, declared) {
97
+ return engineCardOf(call) ?? (declared !== undefined && !RESERVED_APPROVAL_CARDS.includes(declared) ? declared : "generic");
98
+ }
99
+ export function approvalCardMemberOf(call) {
100
+ const card = call.face?.approvalCard;
101
+ return card !== undefined ? { approvalCard: card } : {};
102
+ }
85
103
  export function toolCallFaceOf(roster, toolName) {
86
104
  if (roster === undefined)
87
105
  return undefined;
@@ -97,6 +115,7 @@ export function toolCallFaceOf(roster, toolName) {
97
115
  contractId: e.contract.contractId,
98
116
  shapeDigest: e.shapeDigest,
99
117
  implementationRevision: e.contract.implementationRevision,
118
+ approvalCard: approvalCardOf({ toolName: e.name }, e.renderHints?.approvalCard),
100
119
  };
101
120
  }
102
121
  export function parkedToolIdentity(roster, toolName) {
@@ -271,7 +290,7 @@ function capRenderHints(h) {
271
290
  out.summaryParams = h.summaryParams.filter((s) => typeof s === "string");
272
291
  if (Array.isArray(h.resultCards))
273
292
  out.resultCards = h.resultCards.filter((s) => typeof s === "string");
274
- if (typeof h.approvalCard === "string" && TOOL_APPROVAL_CARDS.includes(h.approvalCard))
293
+ if (isToolApprovalCard(h.approvalCard))
275
294
  out.approvalCard = h.approvalCard;
276
295
  return Object.keys(out).length > 0 ? out : undefined;
277
296
  }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The one reading of a {@link ToolSpec} object. A spec is the caller's own mutable object graph, and the factory and the
3
+ * run's roster snapshot both turn it into something that outlives the moment it was read; each takes its copy through
4
+ * here, so a member is read once, by name, through an ordinary property read (an inherited, non-enumerable or
5
+ * Proxy-answered declaration included — how every phase reads a declaration), and the copy holds no object the caller can
6
+ * reach: declaration data (lists, schemas, faces, hints) is copied level by level — own string AND symbol keys, so a
7
+ * TypeBox schema keeps its kind marks — and frozen, and the only values kept by reference are the functions a ToolSpec
8
+ * declares as functions ({@link FUNCTION_MEMBERS}).
9
+ *
10
+ * A declaration the copy cannot take is refused, naming the member path, with the declaration door's code: a function inside
11
+ * data, an object with a prototype (a class instance, a Date, a Map), an accessor, a graph past the node or depth budget.
12
+ * A tool-name list is the one lenient place, and only at the places its judge reads one ({@link NAME_LIST_MEMBERS},
13
+ * {@link FACE_LIST_KEYS}): it is taken through the judge's own snapshot ({@link snapshotToolNameList}), so a container that
14
+ * cannot be read becomes the judge's failure marker and an entry the copy cannot take stands in as an inert value of the same
15
+ * JS type — the judge refuses either with the sentence it always had, without the caller's object ever being on the face.
16
+ */
17
+ import type { ToolSpec } from "./tool-spec.js";
18
+ /** Every {@link ToolSpec} member, by name — the type's own key set, fenced both ways (a member added to `ToolSpec` and not
19
+ * listed here, or a name here that `ToolSpec` does not declare, is a compile error). */
20
+ export declare const TOOL_SPEC_MEMBERS: readonly string[];
21
+ /** One copy's ledger: the nodes charged so far (a value is a node; a container is charged for all its slots / keys when it is
22
+ * entered, before anything is allocated, and its children are not charged again), the source objects already copied (a graph
23
+ * that shares a sub-node copies it once and charges it once — strict and lenient copies kept apart) and the sources being
24
+ * copied now (a cycle is refused). */
25
+ export interface CopyState {
26
+ nodes: number;
27
+ readonly seen: WeakMap<object, object>;
28
+ readonly seenLenient: WeakMap<object, object>;
29
+ readonly inflight: Set<object>;
30
+ }
31
+ export declare const newCopyState: () => CopyState;
32
+ /** One member's value, as the face and the factory's copy hold it. `state` is the ledger of the whole spec / entry. */
33
+ export declare function frozenMember(name: string, value: unknown, state: CopyState): unknown;
34
+ /** A value under a key that is no ToolSpec member (a contract symbol, a decoration): the engine reads no declaration off it, so
35
+ * it is carried when it is plain data and left off the face when it is not. */
36
+ export declare function frozenExtra(key: string, value: unknown, state: CopyState): {
37
+ kept: true;
38
+ value: unknown;
39
+ } | {
40
+ kept: false;
41
+ };
42
+ /** A spec as it stands now: a frozen object holding each {@link TOOL_SPEC_MEMBERS} member as read once (a member the spec does
43
+ * not answer for stays absent). The caller keeping its own object and changing it afterwards — a member, or anything inside a
44
+ * list or a schema — changes nothing here. */
45
+ export declare function frozenToolSpec<T extends ToolSpec>(spec: T): Readonly<T>;
@@ -0,0 +1,169 @@
1
+ import { UNREADABLE_LIST, snapshotToolNameList } from "./tool-name-list.js";
2
+ export const TOOL_SPEC_MEMBERS = Object.keys({
3
+ name: true, aliases: true, description: true, descriptionClassic: true, label: true, parameters: true, execute: true, effect: true,
4
+ egress: true, irreversibility: true, reversibilityProbe: true, permissionSeat: true, isConcurrencySafe: true, executionMode: true,
5
+ contentOrigin: true, offload: true, offloadThresholdChars: true, defer: true, alwaysLoad: true, prepareArguments: true,
6
+ validateInput: true, approvalPreview: true, family: true, pathTarget: true, ruleFace: true, renderHints: true, compactable: true,
7
+ budgetExempt: true, modelGate: true, contract: true, agentListing: true, agentModels: true, agentToolFaces: true,
8
+ agentToolLevelAllowTools: true, agentToolLevelDenyTools: true, agentToolPool: true, agentToolInheritsMcp: true, withAgents: true,
9
+ });
10
+ const FUNCTION_MEMBERS = new Set(["execute", "prepareArguments", "validateInput", "approvalPreview", "reversibilityProbe", "isConcurrencySafe", "withAgents"]);
11
+ const NAME_LIST_MEMBERS = new Set(["aliases", "agentModels", "agentToolLevelAllowTools", "agentToolLevelDenyTools"]);
12
+ const FACE_LIST_KEYS = new Set(["allowTools", "denyTools"]);
13
+ const FACE_PLACES = { elementKeys: FACE_LIST_KEYS };
14
+ const MAX_NODES = 20_000;
15
+ const MAX_DEPTH = 64;
16
+ const COPIED = new WeakSet();
17
+ class DeclarationRefused extends Error {
18
+ }
19
+ function refuse(path, why) {
20
+ const e = new DeclarationRefused(`ToolSpec ${path}: ${why}. A tool's declaration is data the run fixes once, before its first await — pass lists, schemas and hints as plain data (functions only in execute / prepareArguments / validateInput / approvalPreview / reversibilityProbe / isConcurrencySafe / withAgents).`);
21
+ e.code = "config.tool_mount_denied";
22
+ throw e;
23
+ }
24
+ const inertObject = () => Object.freeze(Object.create(null));
25
+ const inertFunction = () => Object.freeze(() => undefined);
26
+ function standIn(value) {
27
+ let list = false;
28
+ try {
29
+ list = Array.isArray(value);
30
+ }
31
+ catch {
32
+ }
33
+ return list ? Object.freeze([]) : inertObject();
34
+ }
35
+ function overBudget(path) {
36
+ return refuse(path, `declaration data over budget (${MAX_NODES} nodes / ${MAX_DEPTH} levels)`);
37
+ }
38
+ export const newCopyState = () => ({ nodes: 0, seen: new WeakMap(), seenLenient: new WeakMap(), inflight: new Set() });
39
+ function spendNodes(state, nodes, path) {
40
+ state.nodes += nodes;
41
+ if (state.nodes > MAX_NODES)
42
+ overBudget(path);
43
+ }
44
+ function copyNode(value, path, depth, state, lenient, places) {
45
+ if (value === null || (typeof value !== "object" && typeof value !== "function"))
46
+ return value;
47
+ if (typeof value === "function")
48
+ return lenient ? inertFunction() : refuse(path, "a function inside declaration data");
49
+ if (COPIED.has(value))
50
+ return value;
51
+ const seen = lenient ? state.seenLenient : state.seen;
52
+ const shared = seen.get(value);
53
+ if (shared !== undefined)
54
+ return shared;
55
+ if (depth > MAX_DEPTH)
56
+ overBudget(path);
57
+ if (state.inflight.has(value))
58
+ refuse(path, "a reference cycle is not declaration data");
59
+ state.inflight.add(value);
60
+ try {
61
+ if (Array.isArray(value)) {
62
+ const length = value.length;
63
+ spendNodes(state, length, path);
64
+ const items = new Array(length);
65
+ for (let i = 0; i < length; i++) {
66
+ const d = Object.getOwnPropertyDescriptor(value, i);
67
+ if (d === undefined)
68
+ continue;
69
+ if (!("value" in d)) {
70
+ if (lenient)
71
+ return standIn(value);
72
+ refuse(`${path}[${i}]`, "an accessor is not declaration data");
73
+ }
74
+ items[i] = copyNode(d.value, `${path}[${i}]`, depth + 1, state, lenient, places?.elementKeys === undefined ? undefined : { ownKeys: places.elementKeys });
75
+ }
76
+ const sealed = Object.freeze(items);
77
+ COPIED.add(sealed);
78
+ seen.set(value, sealed);
79
+ return sealed;
80
+ }
81
+ const proto = Object.getPrototypeOf(value);
82
+ if (proto !== null && proto !== Object.prototype)
83
+ return lenient ? inertObject() : refuse(path, "an object with a prototype (a class instance, a Date, a Map …) is not declaration data");
84
+ const out = Object.create(proto);
85
+ const keys = Reflect.ownKeys(value);
86
+ spendNodes(state, keys.length, path);
87
+ for (const key of keys) {
88
+ const d = Object.getOwnPropertyDescriptor(value, key);
89
+ if (d === undefined)
90
+ continue;
91
+ const at = `${path}.${String(key)}`;
92
+ if (!("value" in d)) {
93
+ if (lenient)
94
+ return inertObject();
95
+ refuse(at, "an accessor is not declaration data");
96
+ }
97
+ const kept = typeof key === "string" && places?.ownKeys?.has(key) === true ? copyNameList(d.value, at, state) : copyNode(d.value, at, depth + 1, state, lenient);
98
+ Object.defineProperty(out, key, { value: kept, enumerable: d.enumerable, writable: false, configurable: false });
99
+ }
100
+ const sealed = Object.freeze(out);
101
+ COPIED.add(sealed);
102
+ seen.set(value, sealed);
103
+ return sealed;
104
+ }
105
+ catch (cause) {
106
+ if (cause instanceof DeclarationRefused || !lenient)
107
+ throw cause;
108
+ return standIn(value);
109
+ }
110
+ finally {
111
+ state.inflight.delete(value);
112
+ }
113
+ }
114
+ function copyNameList(value, path, state) {
115
+ if (typeof value === "object" && value !== null) {
116
+ if (COPIED.has(value))
117
+ return value;
118
+ const shared = state.seenLenient.get(value);
119
+ if (shared !== undefined)
120
+ return shared;
121
+ }
122
+ let slots = 0;
123
+ try {
124
+ if (Array.isArray(value))
125
+ slots = value.length;
126
+ }
127
+ catch {
128
+ }
129
+ spendNodes(state, slots, path);
130
+ const kept = snapshotToolNameList(value);
131
+ if (kept === UNREADABLE_LIST)
132
+ return kept;
133
+ if (kept === value || !Array.isArray(kept))
134
+ return copyNode(value, path, 0, state, true);
135
+ if (kept.length > slots)
136
+ spendNodes(state, kept.length - slots, path);
137
+ const sealed = Object.freeze(kept.map((entry, i) => copyNode(entry, `${path}[${i}]`, 1, state, true)));
138
+ COPIED.add(sealed);
139
+ if (typeof value === "object" && value !== null)
140
+ state.seenLenient.set(value, sealed);
141
+ return sealed;
142
+ }
143
+ export function frozenMember(name, value, state) {
144
+ if (FUNCTION_MEMBERS.has(name) && typeof value === "function")
145
+ return value;
146
+ spendNodes(state, 1, name);
147
+ if (NAME_LIST_MEMBERS.has(name))
148
+ return copyNameList(value, name, state);
149
+ return copyNode(value, name, 0, state, false, name === "agentToolFaces" ? FACE_PLACES : undefined);
150
+ }
151
+ export function frozenExtra(key, value, state) {
152
+ try {
153
+ spendNodes(state, 1, key);
154
+ return { kept: true, value: copyNode(value, key, 0, state, false) };
155
+ }
156
+ catch {
157
+ return { kept: false };
158
+ }
159
+ }
160
+ export function frozenToolSpec(spec) {
161
+ const copy = {};
162
+ const state = newCopyState();
163
+ for (const name of TOOL_SPEC_MEMBERS) {
164
+ const value = Reflect.get(spec, name);
165
+ if (value !== undefined)
166
+ copy[name] = frozenMember(name, value, state);
167
+ }
168
+ return Object.freeze(copy);
169
+ }
@@ -221,6 +221,13 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
221
221
  aliases?: readonly string[];
222
222
  contentOrigin?: ToolContentOrigin;
223
223
  }>;
224
+ /**
225
+ * TRUE ⇔ the children of this delegation tool inherit the MCP tools their spawning run mounts (no explicit pool: the pool is
226
+ * the inherited surface, and the MCP mount is part of it). Filled by `createSubagentTool` beside {@link agentToolPool}, which
227
+ * is a declaration and cannot list a run's mount: the memory content-origin face reads this to add the spawning run's MCP tools
228
+ * to the child's pool, through the same universe reader the spawn filters with.
229
+ */
230
+ agentToolInheritsMcp?: true;
224
231
  /** approval display projection (see AgentTool.approvalPreview): pure args→display value
225
232
  * for human approval surfaces; clamped + throw-swallowed by the gate; never adjudication input. */
226
233
  approvalPreview?: (args: unknown) => unknown;
@@ -793,10 +800,10 @@ export interface ToolExecuteContext {
793
800
  * root session's), so the root session's `rewindFilesTo` reaches the child's edits; a child on a
794
801
  * different tree (worktree isolation, an explicit `cwd`, a fresh per-task sandbox) starts its own
795
802
  * lineage, because root-relative keys re-joined against a different tree would name files that run
796
- * never edited. Three delegated legs deliberately carry NO lineage and keep their own scope: the
803
+ * never edited. Two delegated legs deliberately carry NO lineage and keep their own scope: the
797
804
  * Agent tool's REVIVE arm (a revival's lineage would be the REVIVER's tree, which says nothing
798
- * about the revived row's), and the workflow / team orchestration spawn legs (`run_workflow`,
799
- * `runTeamDiscussion` — they build their children's internals without this seat). Edits made by
805
+ * about the revived row's), and the workflow orchestration spawn leg (`run_workflow` — it builds its
806
+ * children's internals without this seat). Edits made by
800
807
  * those children are therefore NOT reachable from the root session's rewind, and a restore request
801
808
  * on one of them is not refused either — it converges that child's own scope.
802
809
  */
@@ -958,6 +965,18 @@ export interface ToolExecuteContext {
958
965
  * Runner-filled trusted seat, never a model argument.
959
966
  */
960
967
  readDenyPatterns?: readonly import("../tools/fs/read-deny.js").ReadDenyEntry[];
968
+ /**
969
+ * The parent task's OWN write-protection additions ({@link TaskSpec.writeProtectedAdditions}), traveling the delegation
970
+ * tree add-only (a child guards at least every row its parent's request added). Runner-filled trusted seat, never a
971
+ * model argument.
972
+ */
973
+ writeProtectedAdditions?: readonly import("./write-protect.js").WriteProtectedEntry[];
974
+ /**
975
+ * The parent task's OWN compliance deny additions ({@link TaskSpec.complianceAdditionalDenies}), traveling the
976
+ * delegation tree add-only (a child denies at least every capability its parent's request denied). Runner-filled
977
+ * trusted seat, never a model argument.
978
+ */
979
+ complianceAdditionalDenies?: readonly import("./compliance.js").ComplianceCapability[];
961
980
  /**
962
981
  * The HARD-HEADLESS clamp ({@link TaskSpec.interactiveTools} set to `false` — "never mount a
963
982
  * human-facing tool on this run, whatever faces exist"), Runner-filled read-only on the same trusted
@@ -990,11 +1009,20 @@ export interface ToolExecuteContext {
990
1009
  oneShot?: boolean;
991
1010
  /** Does this run mount THIS instance in `spec.tools` as handed, pre-gate (Runner-filled)? The parent bound on `SubagentToolOptions.inheritedTools`. */
992
1011
  mountsCallerTool?: (tool: ToolSpec) => boolean;
993
- /** — the parent's tool-face controls ({@link TaskSpec.excludeTools} /
994
- * {@link TaskSpec.deferTools}), inherited down the delegation tree like `principal` (Runner-filled,
995
- * read-only): a scenario-wide roster must not be escapable by delegating to a child that remounts
996
- * the excluded tool. Children merge these with their own spec values (union — tighten-only). */
997
- excludeTools?: readonly string[];
1012
+ /**
1013
+ * The MCP surface THIS run mounts (Runner-filled, read-only, answered at call time off the live roster): per declared server,
1014
+ * the tools of it mounted right now, and the aggregate tools no server owns. A delegation tool reads it AT SPAWN TIME for the
1015
+ * protocol half of the one universe a child's lists govern, and declares the child the servers the lists leave — the child
1016
+ * connects for itself (it outlives the spawning leg when it runs in the background or is kept for a later turn). Absent when
1017
+ * the tool runs outside a Runner task, and for a run that declared no server.
1018
+ */
1019
+ mountedMcp?: () => import("./mounted-mcp.js").MountedMcp;
1020
+ /** The run's compiled tool selector (its `allowTools` / `excludeTools` under the ceiling it was spawned with): `admits` answers
1021
+ * "may this run use this tool", and `layers` is the ceiling every child this run spawns inherits, so a scenario-wide roster cannot
1022
+ * be escaped by delegating to a child that remounts a tool this run may not use (Runner-filled, read-only, never a model argument). */
1023
+ toolSelector?: import("./tool-face.js").ToolSelector;
1024
+ /** The parent's deferred-disclosure list ({@link TaskSpec.deferTools}), inherited down the delegation tree like `principal`
1025
+ * (Runner-filled, read-only). */
998
1026
  deferTools?: readonly string[];
999
1027
  /** DD-3 — the INLINE-PIN half of the same tool-face control ({@link TaskSpec.alwaysLoadTools}),
1000
1028
  * inherited on the same seat and by the same rule as {@link deferTools} (Runner-filled, read-only).
@@ -1204,6 +1232,16 @@ export interface ToolExecuteContext {
1204
1232
  * park in its subtree). Same discipline as `principal`: inherit verbatim off the trusted seat.
1205
1233
  */
1206
1234
  checkpointStoreForChildren?: import("./checkpoint-store.js").CheckpointStore | "disabled";
1235
+ /**
1236
+ * The host run's checkpoint SCOPE, for its children — the scope this run's own parked rows land in (the one
1237
+ * value its prepare derived; a delegated host's is the scope ITS parent handed it, so a whole tree answers
1238
+ * with the root's). A delegation tool copies it verbatim into every child's `RunInternals.checkpointScope`, so
1239
+ * a child's parked row is listed where its parent's is, on the synchronous lane as on the background one.
1240
+ * Scope only: the park capability is {@link durableApprovalForChildren}'s business. Runner-filled, read-only,
1241
+ * NEVER a model/tool argument; ABSENT when the tool runs outside a Runner task (the child then derives its
1242
+ * scope from its own spec, as a root run does).
1243
+ */
1244
+ checkpointScopeForChildren?: string;
1207
1245
  /**
1208
1246
  * design/99 (nested-subagent live observability): the host run's stable taskId (`spec.taskId ?? sessionId`),
1209
1247
  * filled by the Runner. A delegation tool (`createSubagentTool`) reads it AT SPAWN TIME and threads it into the
@@ -28,7 +28,7 @@ export declare function isDefineToolProduct(x: unknown): x is AgentTool;
28
28
  * "cannot enrich" arm). `defineTool` uses it on its own product; the only OTHER legitimate caller is a
29
29
  * wrapper that (a) starts from a branded product, (b) preserves the AgentTool
30
30
  * `execute(toolCallId, rawParams, signal, onUpdate)` contract faithfully and (c) hands over a `rebind`
31
- * that re-wraps the REBOUND inner product the same way (e.g. teacher.ts's logging wrapper) — so a mount
31
+ * that re-wraps the REBOUND inner product the same way (e.g. a logging wrapper) — so a mount
32
32
  * rebinding the wrapper gets a wrapper over an enriched product, not an enriched product without the
33
33
  * wrapper. A shallow copy that does NOT re-stamp deliberately loses the brand — that is the brand's
34
34
  * documented survival contract, not an accident. Internal only. */
@@ -76,6 +76,10 @@ export interface DefineToolOptions {
76
76
  * `{toolCallId, signal}` ctx, so every mount that does not opt in stays byte-identical. */
77
77
  enrichCtx?: ToolCtxEnricher;
78
78
  }
79
- /** Adapt a friendly ToolSpec into the vendored AgentTool the agent loop expects. */
79
+ /** Adapt a friendly ToolSpec into the vendored AgentTool the agent loop expects. The product is built from the spec as it
80
+ * stands HERE: the factory takes its one frozen copy ({@link frozenToolSpec}) and builds the product, its call-time reads
81
+ * and every later rebind from that copy, so a caller that keeps the object it handed in and changes it afterwards
82
+ * (replacing `execute`, `parameters`, a mark) changes nothing about the tool. The spec's own functions are called on the
83
+ * caller's object, as they always were. */
80
84
  export declare function defineTool<TParams extends TSchema = TSchema>(spec: ToolSpec<TParams>, options?: DefineToolOptions): AgentTool<TParams>;
81
85
  export {};
@@ -1,6 +1,7 @@
1
1
  import { Value } from "typebox/value";
2
2
  import { formatToolError, formatZodValidationError } from "./tool-errors.js";
3
3
  import { readMember } from "./thrown-value.js";
4
+ import { frozenToolSpec } from "./tool-spec-members.js";
4
5
  import { attachToolContract } from "../prompt-assembly/tool-catalog.js";
5
6
  function normalizeContent(ret) {
6
7
  if (typeof ret === "string") {
@@ -68,10 +69,13 @@ function stampCallIdentity(enriched, toolCallId, signal) {
68
69
  return Object.create(Object.getPrototypeOf(enriched), { ...Object.getOwnPropertyDescriptors(enriched), toolCallId: own(toolCallId), signal: own(signal) });
69
70
  }
70
71
  export function defineTool(spec, options) {
72
+ return buildProduct(frozenToolSpec(spec), spec, options);
73
+ }
74
+ function buildProduct(spec, owner, options) {
71
75
  const executionMode = spec.executionMode ?? (spec.effect === "read" ? "parallel" : "sequential");
72
76
  const tool = {
73
77
  name: spec.name,
74
- ...(spec.aliases && spec.aliases.length > 0 ? { aliases: spec.aliases } : {}),
78
+ ...(spec.aliases && spec.aliases.length > 0 ? { aliases: [...spec.aliases] } : {}),
75
79
  description: spec.description,
76
80
  ...(spec.descriptionClassic !== undefined ? { descriptionClassic: spec.descriptionClassic } : {}),
77
81
  label: spec.label ?? spec.name,
@@ -99,7 +103,7 @@ export function defineTool(spec, options) {
99
103
  ...(spec.approvalPreview ? { approvalPreview: spec.approvalPreview } : {}),
100
104
  ...(spec.validateInput ? { validateInput: spec.validateInput } : {}),
101
105
  execute: async (toolCallId, rawParams, signal) => {
102
- const params = spec.prepareArguments ? spec.prepareArguments(rawParams) : rawParams;
106
+ const params = spec.prepareArguments ? spec.prepareArguments.call(owner, rawParams) : rawParams;
103
107
  if (!Value.Check(spec.parameters, params)) {
104
108
  const detail = formatZodValidationError(spec.parameters, params);
105
109
  return {
@@ -112,7 +116,7 @@ export function defineTool(spec, options) {
112
116
  try {
113
117
  const baseCtx = { toolCallId, signal };
114
118
  const ctx = options?.enrichCtx ? stampCallIdentity(options.enrichCtx(baseCtx), toolCallId, signal) : baseCtx;
115
- const ret = await spec.execute(params, ctx);
119
+ const ret = await spec.execute.call(owner, params, ctx);
116
120
  const { content, details, terminate, isError } = normalizeContent(ret);
117
121
  const guarded = isEmptyToolContent(content)
118
122
  ? [{ type: "text", text: isError ? `(${spec.name} reported an error with no further output)` : `(${spec.name} completed with no output)` }]
@@ -141,7 +145,7 @@ export function defineTool(spec, options) {
141
145
  }
142
146
  stampDefineToolBrand(tool, (enrich) => {
143
147
  const composed = options?.enrichCtx === undefined ? enrich : (base) => options.enrichCtx(enrich(base));
144
- const rebuilt = defineTool(spec, { ...options, enrichCtx: composed });
148
+ const rebuilt = buildProduct(spec, owner, { ...options, enrichCtx: composed });
145
149
  const { [DEFINE_TOOL_BRAND]: _brand, [DEFINE_TOOL_REBIND]: _seat, ...face } = Object.getOwnPropertyDescriptors(tool);
146
150
  const copy = Object.create(Object.getPrototypeOf(tool), { ...face, execute: { value: rebuilt.execute, enumerable: true, configurable: true, writable: true } });
147
151
  return stampDefineToolBrand(copy, (again) => rebindDefineToolCtx(rebuilt, again));
@@ -1,14 +1,13 @@
1
1
  import { delimitUntrusted, neutralizeForFence } from "./untrusted-text.js";
2
- import { scrubSecrets, SECRET_PASSES, runRedactionPasses } from "./arg-summary.js";
2
+ import { egressPasses, runRedactionPasses } from "./arg-summary.js";
3
+ import { CREDENTIAL_VOCABULARY, egressPassGroups, URI_SCHEME_SOURCE } from "./credential-vocabulary.js";
3
4
  import { sliceHeadSafe } from "./surrogate-safe-slice.js";
4
5
  export { summarizeRedactions } from "./arg-summary.js";
5
- const URI_SCHEME = String.raw `[A-Za-z][A-Za-z0-9+.\-_]{0,63}`;
6
- const CREDENTIALS_IN_AUTHORITY = new RegExp(String.raw `(${URI_SCHEME}:\/\/)((?:[^/\s"'@]*@)+)`, "gi");
7
- const URL_OF_ANY_PROTOCOL = new RegExp(String.raw `${URI_SCHEME}:\/\/[^\s"'\`]+`, "gi");
6
+ const URL_OF_ANY_PROTOCOL = new RegExp(String.raw `${URI_SCHEME_SOURCE}:\/\/[^\s"'\`]+`, "gi");
8
7
  const BARE_USERNAME_MAX_LEN = 20;
9
8
  function redactUserinfo(scheme, userinfoWithAt) {
10
9
  const userinfo = userinfoWithAt.slice(0, -1);
11
- if (userinfo.includes("@"))
10
+ if (CREDENTIAL_VOCABULARY.policy.urlUserinfo === "whole" || userinfo.includes("@"))
12
11
  return `${scheme}[redacted-credentials]@`;
13
12
  const colonIdx = userinfo.indexOf(":");
14
13
  if (colonIdx === -1) {
@@ -16,18 +15,9 @@ function redactUserinfo(scheme, userinfoWithAt) {
16
15
  }
17
16
  return `${scheme}${userinfo.slice(0, colonIdx)}:[redacted-credentials]@`;
18
17
  }
19
- const SECRET_TIER_PASSES = [
20
- ...SECRET_PASSES,
21
- {
22
- kind: "url-credentials",
23
- confidence: "medium",
24
- marker: "[redacted-credentials]",
25
- source: "untrusted-egress",
26
- re: CREDENTIALS_IN_AUTHORITY,
27
- replace: (_m, scheme, userinfo) => redactUserinfo(scheme, userinfo),
28
- },
29
- { kind: "signed-url-param", confidence: "high", marker: "[redacted]", source: "untrusted-egress", re: /([?&#](?:sig|signature|sas|code)=)[^&\s"'#]+/gi, replace: "$1[redacted]" },
30
- ];
18
+ const SECRET_TIER_PASSES = egressPasses(egressPassGroups(CREDENTIAL_VOCABULARY), {
19
+ "url-credentials": (_m, scheme, userinfo) => redactUserinfo(scheme, userinfo),
20
+ });
31
21
  export function redactSecrets(s, report) {
32
22
  return runRedactionPasses(s, SECRET_TIER_PASSES, report);
33
23
  }
@@ -99,14 +89,27 @@ export function boundedRedactedSummary(value, max) {
99
89
  }
100
90
  export function untrustedEgressForHuman(value, opts) {
101
91
  const source = boundedString(value, Number.POSITIVE_INFINITY, redactHostLeaks);
102
- let budget = opts.max;
103
- let bounded = boundedString(source, budget, (s) => s);
104
- for (let i = 0; i < 4 && budget > 0; i++) {
105
- const overflow = [...neutralizeForFence(bounded)].length - opts.max;
106
- if (overflow <= 0)
107
- break;
108
- budget = Math.max(0, budget - overflow);
109
- bounded = boundedString(source, budget, (s) => s);
92
+ const probe = (budget) => {
93
+ const bounded = boundedString(source, budget, (s) => s);
94
+ return { bounded, overflow: [...neutralizeForFence(bounded)].length - opts.max };
95
+ };
96
+ let chosen = probe(opts.max);
97
+ if (chosen.overflow > 0) {
98
+ let fits;
99
+ let lo = 0;
100
+ let hi = opts.max;
101
+ while (hi - lo > 1) {
102
+ const mid = lo + Math.floor((hi - lo) / 2);
103
+ const p = probe(mid);
104
+ if (p.overflow <= 0) {
105
+ lo = mid;
106
+ fits = p;
107
+ }
108
+ else {
109
+ hi = mid;
110
+ }
111
+ }
112
+ chosen = fits ?? probe(lo);
110
113
  }
111
- return delimitUntrusted(opts.label, bounded, opts.max);
114
+ return delimitUntrusted(opts.label, chosen.bounded, opts.max);
112
115
  }