@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,23 +10,24 @@ import { checkpointStoreOfSeat } from "../core/checkpoint-seat.js";
10
10
  import { buildWorkflowPrimitives } from "./workflow-primitives.js";
11
11
  import { stripSpawnTurnQuestionFace } from "../core/ask-question.js";
12
12
  import { parentSpecSeatOfCtx } from "../core/parent-spec-seat.js";
13
+ import { CLAMP_SEATS, CLAMP_SET, assertClampRecord, clampRecordError, clampSourceOf, foldClampSources } from "../core/child-clamp-seats.js";
13
14
  import { assertNoRetiredKeys } from "../core/retired-keys.js";
14
15
  const RETIRED_RUN_WORKFLOW_TOOL_DEPS_KEYS = {
15
16
  principal: "the host run's principal rides `RunWorkflowToolDeps.parentSpecSeat.principal` (the parent SPEC seat the host's prepare mints), never a seat of its own",
16
17
  oneShot: "the host run's one-shot fact rides `RunWorkflowToolDeps.parentSpecSeat.oneShot` (only `true` travels), never a seat of its own",
18
+ builtinWorkflows: "the engine ships no built-in named workflows — `{name}` resolves only the deployment's `scriptStore`; register any named workflow there, or pass `script` inline",
19
+ parentExcludeTools: "the host run's tool selector layers ride `RunWorkflowToolDeps.parentToolCeiling` (`ToolExecuteContext.toolSelector.layers`, the host's prepare-time selector) and bound every agent the workflow spawns as its ceiling — an exclusion list is no longer handed down by name",
20
+ ...Object.fromEntries(CLAMP_SEATS.filter((seat) => CLAMP_SET[seat].carrier === "clamp").map((seat) => [
21
+ `parent${seat.charAt(0).toUpperCase()}${seat.slice(1)}`,
22
+ `the host's tighten-only clamps ride ONE getter, \`RunWorkflowToolDeps.parentClamps\` (every clamp row, present keys) — return \`${seat}\` from it`,
23
+ ])),
17
24
  };
18
25
  import { parseWorkflowMeta, splitWorkflowMeta, workflowScriptReadsClockOrRandom } from "./workflow-meta.js";
19
26
  import { mergeWorkflowArgs, normalizeStringArg } from "./workflow-script-store.js";
20
- import { builtinWorkflowListings, canonicalWorkflowName, resolveBuiltinWorkflow, workflowNameProbeOrder } from "./builtin-workflows.js";
21
27
  import { workflowSizeGuidelineSection } from "./workflow-size-guideline.js";
22
28
  import { toolFace } from "../core/tool-catalog-entries.js";
23
29
  import { thrownText } from "../core/thrown-value.js";
24
30
  export const RUN_WORKFLOW_TOOL_NAME = "Workflow";
25
- function parentFaceSeat(ctxSeat, dep) {
26
- if (ctxSeat !== "roots")
27
- return dep;
28
- return () => "roots";
29
- }
30
31
  function stripCodeFences(s) {
31
32
  const t = s.trim();
32
33
  const m = /^```[A-Za-z]*\r?\n([\s\S]*?)\r?\n?```$/.exec(t);
@@ -68,7 +69,7 @@ function workflowUsageBlock(run) {
68
69
  agents_error: agents.filter((a) => a.status === "failed").length,
69
70
  ...(agents.some((a) => a.status === "parked") ? { agents_parked: agents.filter((a) => a.status === "parked").length } : {}),
70
71
  agents_empty_result: agents.filter((a) => a.status === "completed" && (a.output === undefined || a.output === "")).length,
71
- agents_replayed: agents.filter((a) => a.replayed === true).length,
72
+ agents_replayed: run.resume?.replayed ?? 0,
72
73
  ...(run.journalSkips !== undefined && run.journalSkips > 0 ? { journal_skipped: run.journalSkips } : {}),
73
74
  ...(run.resume !== undefined ? { resume_journal_entries: run.resume.journalEntries } : {}),
74
75
  subagent_tokens: run.stats.tokens + run.stats.nested.tokens,
@@ -131,59 +132,28 @@ export function renderNamedWorkflowListing(entries) {
131
132
  return ("Named workflows available via {name} (registered defaults merge UNDER your `args`; a top-level key you pass wins wholesale):\n" +
132
133
  lines.join("\n"));
133
134
  }
134
- async function collectNamedWorkflowListings(store, builtinsEnabled) {
135
- const canonicalOf = (name) => (builtinsEnabled ? canonicalWorkflowName(name) : name);
135
+ async function collectNamedWorkflowListings(store) {
136
136
  const byName = new Map();
137
- const shadowSpellingBySlot = new Map();
138
- if (builtinsEnabled) {
139
- for (const b of builtinWorkflowListings()) {
140
- let shadowedBy;
141
- if (store?.resolveName) {
142
- for (const probe of workflowNameProbeOrder(b.name)) {
143
- try {
144
- if ((await store.resolveName(probe)) !== undefined)
145
- shadowedBy = probe;
146
- }
147
- catch {
148
- }
149
- if (shadowedBy !== undefined)
150
- break;
151
- }
152
- }
153
- if (shadowedBy !== undefined)
154
- shadowSpellingBySlot.set(b.name, shadowedBy);
155
- byName.set(b.name, shadowedBy === undefined
156
- ? b
157
- : {
158
- name: b.name,
159
- description: shadowedBy === b.name
160
- ? "deployment-registered workflow (shadows the built-in of the same name)"
161
- : `deployment-registered workflow (registered under the retired spelling ${JSON.stringify(shadowedBy)}; shadows the built-in)`,
162
- });
163
- }
164
- }
165
137
  try {
166
138
  const listed = await store?.list?.();
167
139
  if (Array.isArray(listed)) {
168
140
  const rows = listed.filter((e) => Boolean(e) && typeof e.name === "string" && e.name.length > 0);
169
- const listedNames = new Set(rows.map((e) => e.name));
170
- for (const e of rows) {
141
+ for (const e of rows)
171
142
  byName.set(e.name, e);
172
- const canonical = canonicalOf(e.name);
173
- if (canonical !== e.name && !listedNames.has(canonical)) {
174
- const slotShadow = shadowSpellingBySlot.get(canonical);
175
- if (slotShadow !== undefined && slotShadow !== canonical)
176
- byName.delete(canonical);
177
- }
178
- }
179
143
  }
180
144
  }
181
145
  catch {
182
146
  }
183
147
  return [...byName.values()];
184
148
  }
185
- export async function createRunWorkflowTool(d) {
149
+ export function createRunWorkflowTool(d) {
186
150
  assertNoRetiredKeys(d, RETIRED_RUN_WORKFLOW_TOOL_DEPS_KEYS, "RunWorkflowToolDeps");
151
+ if (d.parentClamps !== undefined && typeof d.parentClamps !== "function") {
152
+ throw clampRecordError(`RunWorkflowToolDeps.parentClamps must be a getter returning the host's clamp source, got ${typeof d.parentClamps}`);
153
+ }
154
+ return mountRunWorkflowTool(d);
155
+ }
156
+ async function mountRunWorkflowTool(d) {
187
157
  if (d.scriptRunner.safeForUntrustedScripts !== true) {
188
158
  throw new Error("createRunWorkflowTool: refusing to mount run_workflow on a runner that is not safeForUntrustedScripts (design/98 fail-closed)");
189
159
  }
@@ -198,7 +168,7 @@ export async function createRunWorkflowTool(d) {
198
168
  const problem = governanceBaselineProblem(d.governanceBaseline);
199
169
  if (problem !== null)
200
170
  throw governanceBaselineError(problem);
201
- const FACE_LIST_FIELDS = ["excludeTools", "deferTools", "alwaysLoadTools"];
171
+ const FACE_LIST_FIELDS = ["allowTools", "excludeTools", "deferTools", "alwaysLoadTools"];
202
172
  const dropNullFaces = (slot) => {
203
173
  let out = slot;
204
174
  for (const field of FACE_LIST_FIELDS) {
@@ -227,9 +197,6 @@ export async function createRunWorkflowTool(d) {
227
197
  const unionFaceList = (own, parent) => own === undefined ? [...new Set(parent)] : [...new Set([...own, ...parent])];
228
198
  const withParentFace = (base, inherit) => ({
229
199
  ...base,
230
- ...(d.parentExcludeTools?.length
231
- ? { excludeTools: unionFaceList(base.excludeTools ?? inherit?.excludeTools, d.parentExcludeTools) }
232
- : {}),
233
200
  ...(d.parentDeferTools?.length
234
201
  ? { deferTools: unionFaceList(base.deferTools ?? inherit?.deferTools, d.parentDeferTools) }
235
202
  : {}),
@@ -253,7 +220,7 @@ export async function createRunWorkflowTool(d) {
253
220
  })(),
254
221
  });
255
222
  const withParentProfile = (base) => d.parentPromptProfile !== undefined && base.promptProfile === undefined ? { ...base, promptProfile: d.parentPromptProfile } : base;
256
- const baselineWithParentFace = (d.parentExcludeTools?.length ?? 0) > 0 || (d.parentDeferTools?.length ?? 0) > 0 || (d.parentAlwaysLoadTools?.length ?? 0) > 0 || d.parentPromptProfile !== undefined || d.parentRestoreGatedTools !== undefined
223
+ const baselineWithParentFace = (d.parentDeferTools?.length ?? 0) > 0 || (d.parentAlwaysLoadTools?.length ?? 0) > 0 || d.parentPromptProfile !== undefined || d.parentRestoreGatedTools !== undefined
257
224
  ? {
258
225
  ...sanitizedBaseline,
259
226
  base: withParentProfile(withParentFace(sanitizedBaseline.base)),
@@ -263,8 +230,7 @@ export async function createRunWorkflowTool(d) {
263
230
  }
264
231
  : sanitizedBaseline;
265
232
  const governance = { baseline: baselineWithParentFace, models: d.models, caps: childCaps, onNotice: d.onNotice };
266
- const builtinsEnabled = d.builtinWorkflows !== false;
267
- const namedWorkflowSection = renderNamedWorkflowListing(await collectNamedWorkflowListings(d.scriptStore, builtinsEnabled));
233
+ const namedWorkflowSection = renderNamedWorkflowListing(await collectNamedWorkflowListings(d.scriptStore));
268
234
  const sizeGuidelineSection = workflowSizeGuidelineSection(d.sizeGuideline ?? lim.sizeGuideline);
269
235
  const structuredError = (message) => errorResult(JSON.stringify({ error: message }));
270
236
  return defineTool({
@@ -384,8 +350,8 @@ export async function createRunWorkflowTool(d) {
384
350
  "(one entry per phase() call, titles matched exactly; `detail`/`model` optional; never bare strings).",
385
351
  })),
386
352
  name: Type.Optional(Type.String({
387
- description: "Name of a predefined workflow (a saved script in the deployment's workflow store, or a built-in — " +
388
- "see the named-workflow list in this tool's description). Resolves to a self-contained script; the " +
353
+ description: "Name of a predefined workflow (a saved script in the deployment's workflow store — see the " +
354
+ "named-workflow list in this tool's description). Resolves to a self-contained script; the " +
389
355
  "registration's default args merge under your `args`.",
390
356
  })),
391
357
  scriptPath: Type.Optional(Type.String({
@@ -433,30 +399,19 @@ export async function createRunWorkflowTool(d) {
433
399
  script = stripCodeFences(rawScript);
434
400
  }
435
401
  else if (typeof rawName === "string" && rawName.length > 0) {
436
- if (!d.scriptStore?.resolveName && !builtinsEnabled) {
437
- return structuredError("named workflows require a deployment workflow script store — none is wired (and built-in workflows are disabled); pass `script` inline");
402
+ if (!d.scriptStore?.resolveName) {
403
+ return structuredError("named workflows require a deployment workflow script store — none is wired; pass `script` inline");
438
404
  }
439
405
  let resolved;
440
- const canonicalName = canonicalWorkflowName(rawName);
441
- const probeNames = builtinsEnabled ? workflowNameProbeOrder(rawName) : [rawName];
442
- if (d.scriptStore?.resolveName) {
443
- for (const probeName of probeNames) {
444
- try {
445
- resolved = await d.scriptStore.resolveName(probeName);
446
- }
447
- catch (err) {
448
- return structuredError(`failed to resolve workflow name: ${redactSecrets(thrownText(err)).slice(0, 300)}`);
449
- }
450
- const resolvedShape = resolved;
451
- if (resolvedShape !== undefined && (resolvedShape === null || typeof resolvedShape !== "object")) {
452
- return structuredError("the wired workflow script store's resolveName returned the retired bare-string form — the resolution shape is now { script, defaultArgs? } (one shape); upgrade the store implementation");
453
- }
454
- if (resolved !== undefined)
455
- break;
456
- }
406
+ try {
407
+ resolved = await d.scriptStore.resolveName(rawName);
457
408
  }
458
- if (resolved === undefined && builtinsEnabled) {
459
- resolved = resolveBuiltinWorkflow(canonicalName);
409
+ catch (err) {
410
+ return structuredError(`failed to resolve workflow name: ${redactSecrets(thrownText(err)).slice(0, 300)}`);
411
+ }
412
+ const resolvedShape = resolved;
413
+ if (resolvedShape !== undefined && (resolvedShape === null || typeof resolvedShape !== "object")) {
414
+ return structuredError("the wired workflow script store's resolveName returned the retired bare-string form — the resolution shape is now { script, defaultArgs? } (one shape); upgrade the store implementation");
460
415
  }
461
416
  if (resolved === undefined)
462
417
  return structuredError(`unknown workflow name: ${JSON.stringify(rawName)}`);
@@ -509,7 +464,11 @@ export async function createRunWorkflowTool(d) {
509
464
  const childParkSeat = ctx.checkpointStoreForChildren ?? d.parentCheckpointStore;
510
465
  const parkStore = checkpointStoreOfSeat(childParkSeat);
511
466
  const scriptFn = (wfCtx) => {
512
- const primitives = buildWorkflowPrimitives(wfCtx, runGovernance, d.onAgentSpawn, childParkSeat, parentFaceSeat(ctx.readFace, d.parentReadFace), parentFaceSeat(ctx.writeFace, d.parentWriteFace), d.parentReadDenyPatterns, ctx.handsReadOnly === true || d.parentHandsReadOnly === true, ctx.interactiveTools === false || d.parentInteractiveTools === false, ctx.approvalReach === "none" || d.parentApprovalReach === "none");
467
+ const primitives = buildWorkflowPrimitives(wfCtx, runGovernance, d.onAgentSpawn, childParkSeat, () => {
468
+ const host = d.parentClamps?.();
469
+ assertClampRecord(host, "RunWorkflowToolDeps.parentClamps()", "clamp");
470
+ return foldClampSources(clampSourceOf(ctx), host);
471
+ });
513
472
  return d.scriptRunner.run({ scriptSource: script, primitives, scriptArgs: effectiveArgs, signal: wfCtx.signal }).then((r) => r.result);
514
473
  };
515
474
  if (ctx.signal?.aborted) {
@@ -580,6 +539,7 @@ export async function createRunWorkflowTool(d) {
580
539
  ...((ctx.inheritedGateForChildren ?? d.inheritedGateForChildren) !== undefined
581
540
  ? { inheritedGate: (ctx.inheritedGateForChildren ?? d.inheritedGateForChildren)() }
582
541
  : {}),
542
+ ...((ctx.toolSelector?.layers ?? d.parentToolCeiling) !== undefined ? { toolCeiling: (ctx.toolSelector?.layers ?? d.parentToolCeiling) } : {}),
583
543
  ...(autoModeReview !== undefined ? { autoModeReview } : {}),
584
544
  }, { workflowDepth: d.workflowDepth });
585
545
  }
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import type { Model } from "../internal/llm.js";
24
24
  import type { EngineNotice, ImageInput, TaskSpec, ThinkingLevel, WorkflowGovernanceBaseline } from "../core/types.js";
25
- import { type ReadDenyEntry } from "../tools/fs/read-deny.js";
25
+ import { type ClampValues, type ScriptSeat } from "../core/child-clamp-seats.js";
26
26
  /** Thrown when an LLM-authored script picks a `modelName` not in the workflow model allowlist (or no
27
27
  * allowlist is configured). FAIL-CLOSED: a script can only ever name a model the deployment pre-approved. */
28
28
  export declare class WorkflowModelNotAllowedError extends Error {
@@ -30,13 +30,22 @@ export declare class WorkflowModelNotAllowedError extends Error {
30
30
  readonly code = "workflow.model_not_allowed";
31
31
  constructor(modelName: string, reason: string);
32
32
  }
33
+ /** The clamp table's script-declarable rows as a script writes them on its spec (mutable members, the shape every other
34
+ * spec field has). */
35
+ type ScriptClampSeats = {
36
+ -readonly [K in ScriptSeat]?: ClampValues[K];
37
+ };
33
38
  /**
34
39
  * The SAFE fields an LLM-authored workflow script may set per sub-agent — the WORK, never the control plane.
35
40
  * `model` is a NAME (string), NOT a `ModelRef`/`Model` object (a `Model` carries
36
41
  * `baseUrl`/`headers`/`extraBody` = endpoint + auth-header injection). No `modelRole`/`roles` (a `roles.select`
37
42
  * conditional selector is its own vector). The engine resolves `modelName` against the allowlist.
43
+ *
44
+ * The TIGHTEN-ONLY declarations a script may make are the clamp table's script-declarable rows (`ScriptSeat`), typed off
45
+ * the table (`ClampValues`: a restricting row as its restricting value only, an add-only row as its list) — never a second
46
+ * list here.
38
47
  */
39
- export interface WorkflowAgentSpec {
48
+ export interface WorkflowAgentSpec extends ScriptClampSeats {
40
49
  objective: string;
41
50
  /**
42
51
  * The canonical spelling, and the only one this type expresses. At RUNTIME the spec ALSO accepts
@@ -58,28 +67,6 @@ export interface WorkflowAgentSpec {
58
67
  maxTokens?: number;
59
68
  maxCostUsd?: number;
60
69
  };
61
- /**
62
- * design/199 件A, TIGHTEN-ONLY: `"roots"` — the read-face containment judgment — is the ONLY value a
63
- * script may set. `"open"` is the WIDENING direction (it removes the containment step), so it is
64
- * stripped and announced rather than applied; the type states the asymmetry, and
65
- * {@link pickWhitelist} enforces it on the untrusted value.
66
- */
67
- readFace?: "roots";
68
- /**
69
- * TIGHTEN-ONLY, the write seat's twin of {@link readFace}: `"roots"` — the write-face containment
70
- * judgment — is the ONLY value a script may set. `"open"` is the WIDENING direction, so it is
71
- * stripped and announced rather than applied.
72
- */
73
- writeFace?: "roots";
74
- /**
75
- * design/199 件B, TIGHTEN-ONLY: additional read-deny entries. Add-only at every layer a governed
76
- * SCRIPT can reach: the baseline's entries and the deployment-ACTIVE built-in set are always in
77
- * force and a script cannot remove or replace them (`compileReadDeny` treats additions as
78
- * add-only; `tightenTaskSpec` unions). Which built-in tiers are active is a DEPLOYMENT seat
79
- * (#245: `readDenyBuiltinTiers`/`readDenyBuiltinExclude` on RunnerDeps) that no script-side key
80
- * reaches — so anything a script writes here can only ever narrow what the child may read.
81
- */
82
- readDenyPatterns?: readonly ReadDenyEntry[];
83
70
  }
84
71
  /**
85
72
  * The SINGLE source of truth for the whitelist (a test pins that it contains no control-plane key). `objective`
@@ -96,8 +83,16 @@ export interface WorkflowAgentSpec {
96
83
  * instead of evaporating. Turning the strip into a LOUD REFUSAL that fails the spawn is a deliberate
97
84
  * NON-GOAL of this window: it would break every existing script carrying a harmless extra field, and is held
98
85
  * for a BREAKING window.
86
+ *
87
+ * The TIGHTEN-ONLY half is DERIVED: every clamp-table row a script may declare (`SCRIPT_SEATS` — the rows whose `script`
88
+ * law is not `false`). Those declarations carry no capability — everything they can express makes the child strictly
89
+ * more restricted — and each is re-checked by `tightenTaskSpec`'s own tighten-only merge below; stripping them made a
90
+ * governed script's protective intent evaporate silently, the one direction a default-deny seam has no reason to block.
91
+ * Each crosses under its row's law, by VALUE in {@link pickWhitelist}, not by key: a restricting row only as its
92
+ * restricting value, an add-only row through the row's script and entry laws. A row marked inherited-only (its
93
+ * restricting value switches off an operator-side record) is outside this set and is stripped like any other key.
99
94
  */
100
- export declare const WHITELIST_KEYS: readonly ["objective", "modelName", "thinking", "systemPrompt", "images", "limits", "readFace", "writeFace", "readDenyPatterns"];
95
+ export declare const WHITELIST_KEYS: readonly ("thinking" | "systemPrompt" | "objective" | "images" | "limits" | ScriptSeat | "modelName")[];
101
96
  /**
102
97
  * #505 ② — ACCEPTED ALIAS SPELLINGS on the spec: `alias → the {@link WHITELIST_KEYS} member it means`.
103
98
  *
@@ -244,3 +239,4 @@ export declare function resolveModelName(name: string, allowlist: string[] | und
244
239
  * sink can turn an announcement into a failed spawn.
245
240
  */
246
241
  export declare function buildGovernedChildSpec(scriptSpec: unknown, baseline: WorkflowGovernanceBaseline, models: Record<string, Model> | undefined, caps?: WorkflowChildCaps, onResourceClamp?: (notes: ResourceClampNote[]) => void, onNotice?: (n: EngineNotice) => void): TaskSpec;
242
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { deliverEngineNotice } from "../core/types.js";
2
2
  import { tightenTaskSpec } from "../core/tighten-task-spec.js";
3
3
  import { sanitizeUntrustedText } from "../core/untrusted-text.js";
4
- import { compileReadDeny } from "../tools/fs/read-deny.js";
4
+ import { CLAMP_SET, SCRIPT_SEATS } from "../core/child-clamp-seats.js";
5
5
  import { WorkflowScriptError } from "./workflow-meta.js";
6
6
  import { uuidv7 } from "../engine/session/uuid.js";
7
7
  import { retiredCheckpointStoreNull } from "../core/checkpoint-store.js";
@@ -15,18 +15,13 @@ export class WorkflowModelNotAllowedError extends Error {
15
15
  this.name = "WorkflowModelNotAllowedError";
16
16
  }
17
17
  }
18
- export const WHITELIST_KEYS = Object.freeze([
19
- "objective",
20
- "modelName",
21
- "thinking",
22
- "systemPrompt",
23
- "images",
24
- "limits",
25
- "readFace",
26
- "writeFace",
27
- "readDenyPatterns",
28
- ]);
18
+ const WORK_FIELD_KEYS = ["objective", "modelName", "thinking", "systemPrompt", "images", "limits"];
19
+ export const WHITELIST_KEYS = Object.freeze([...WORK_FIELD_KEYS, ...SCRIPT_SEATS]);
29
20
  const WHITELIST_KEY_SET = new Set(WHITELIST_KEYS);
21
+ const RESTRICTING_SCRIPT_VALUES = SCRIPT_SEATS.flatMap((seat) => {
22
+ const row = CLAMP_SET[seat];
23
+ return row.law === "restricting" ? [`${seat}: ${JSON.stringify(row.value)}`] : [];
24
+ }).join(", ");
30
25
  export const SPEC_KEY_ALIASES = new Map([["model", "modelName"]]);
31
26
  export const STRIPPED_KEYS_NOTICE_CODE = "workflow.governance_key_stripped";
32
27
  const MAX_STRIPPED_KEYS_ANNOUNCED = 20;
@@ -48,8 +43,8 @@ function emitStrippedKeysNotice(survey, onNotice) {
48
43
  const omitted = survey.total - shown.length;
49
44
  const list = shown.map((s) => JSON.stringify(s.key)).join(", ") + (omitted > 0 ? `, +${omitted} more` : "");
50
45
  const message = `workflow governance: ${survey.total} field(s) of an agent spec were NOT applied to the child (${list}). ` +
51
- `A governed workflow script may set only: ${WHITELIST_KEYS.join(", ")} — and \`readFace\`/\`writeFace\` only as "roots" ` +
52
- `(the containment-tightening direction; "open" widens and is never taken from a script). Every other field ` +
46
+ `A governed workflow script may set only: ${WHITELIST_KEYS.join(", ")} — and each tighten-only seat only in its ` +
47
+ `tightening direction (${RESTRICTING_SCRIPT_VALUES}; the list seats only add entries). Every other field ` +
53
48
  `of the child comes from the deployment baseline.`;
54
49
  try {
55
50
  deliverEngineNotice(onNotice, {
@@ -142,25 +137,7 @@ function pickImageInput(el, i) {
142
137
  }
143
138
  return { data, mimeType };
144
139
  }
145
- const MAX_SCRIPT_DENY_ENTRIES = 16;
146
- const MAX_SCRIPT_DENY_PATTERN_CHARS = 256;
147
- const MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT = 1;
148
140
  const MAX_SCRIPT_IMAGES = 32;
149
- function assertScriptDenyPatternBounded(pattern, at) {
150
- if (pattern.length > MAX_SCRIPT_DENY_PATTERN_CHARS) {
151
- throw new WorkflowScriptError(`${at} is ${pattern.length} characters — a workflow script's deny pattern is limited to ${MAX_SCRIPT_DENY_PATTERN_CHARS} (the matcher runs on every read of the child's run).`);
152
- }
153
- for (const segment of pattern.split("/")) {
154
- const wildcards = segment.split("*").length - 1;
155
- if (wildcards > MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT) {
156
- throw new WorkflowScriptError(`${at} has a path segment with ${wildcards} \`*\` wildcards — a workflow script's deny pattern allows at most ` +
157
- `${MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT} per path segment (the same expressiveness the engine's built-in deny table ` +
158
- `uses). Each \`*\` compiles to a greedy match, and more than one in a single segment makes the judgment cost grow ` +
159
- `superlinearly with the path length, on every read the child performs. Write the intent as separate entries ` +
160
- `(the set is a union, so more entries deny strictly more) or anchor it with literal segments.`);
161
- }
162
- }
163
- }
164
141
  function mapUntrustedArray(value, at, atMost, why, build) {
165
142
  const declared = value.length;
166
143
  if (typeof declared !== "number" || !Number.isSafeInteger(declared) || declared < 0) {
@@ -174,29 +151,6 @@ function mapUntrustedArray(value, at, atMost, why, build) {
174
151
  out.push(build(value[i], i));
175
152
  return out;
176
153
  }
177
- function pickReadDenyEntry(el, i) {
178
- const at = `agent(spec): \`readDenyPatterns[${i}]\``;
179
- if (typeof el === "string") {
180
- if (el.length === 0)
181
- throw new WorkflowScriptError(`${at} must be a non-empty pattern string`);
182
- assertScriptDenyPatternBounded(el, at);
183
- return el;
184
- }
185
- if (typeof el !== "object" || el === null || Array.isArray(el)) {
186
- throw new WorkflowScriptError(`${at} must be a pattern string or an object { pattern, caseSensitive? }`);
187
- }
188
- const o = el;
189
- const pattern = o.pattern;
190
- const caseSensitive = o.caseSensitive;
191
- if (typeof pattern !== "string" || pattern.length === 0) {
192
- throw new WorkflowScriptError(`${at}.pattern must be a non-empty string, e.g. ".ssh" or "secrets/*.json"`);
193
- }
194
- if (caseSensitive !== undefined && typeof caseSensitive !== "boolean") {
195
- throw new WorkflowScriptError(`${at}.caseSensitive must be a boolean`);
196
- }
197
- assertScriptDenyPatternBounded(pattern, at);
198
- return caseSensitive === undefined ? { pattern } : { pattern, caseSensitive };
199
- }
200
154
  function pickWhitelist(scriptSpec) {
201
155
  if (typeof scriptSpec !== "object" || scriptSpec === null || Array.isArray(scriptSpec)) {
202
156
  throw new WorkflowScriptError("agent(spec): spec must be an object with at least an `objective` string");
@@ -279,33 +233,39 @@ function pickWhitelist(scriptSpec) {
279
233
  readAxis("maxCostUsd", "spend ceiling");
280
234
  safe.limits = limits;
281
235
  }
282
- for (const faceKey of ["readFace", "writeFace"]) {
283
- const declared = s[faceKey];
236
+ for (const seat of SCRIPT_SEATS) {
237
+ const row = CLAMP_SET[seat];
238
+ const declared = s[seat];
284
239
  if (declared === undefined)
285
240
  continue;
286
- if (declared === "roots") {
287
- safe[faceKey] = "roots";
288
- }
289
- else {
290
- stripped.total++;
291
- stripped.sample.unshift({ key: faceKey, reason: "not_a_tightening_value" });
292
- if (stripped.sample.length > MAX_STRIPPED_KEYS_ANNOUNCED)
293
- stripped.sample.pop();
294
- }
295
- }
296
- const readDenyPatternsRaw = s.readDenyPatterns;
297
- if (readDenyPatternsRaw !== undefined) {
298
- if (!Array.isArray(readDenyPatternsRaw)) {
299
- throw new WorkflowScriptError('agent(spec): `readDenyPatterns` must be an array of deny entries (a "/"-separated segment run such as ".ssh", or { pattern, caseSensitive? })');
300
- }
301
- const entries = mapUntrustedArray(readDenyPatternsRaw, "agent(spec): `readDenyPatterns`", MAX_SCRIPT_DENY_ENTRIES, "Every entry is judged against every path the child reads, for the child's whole run; the deployment's own entries, and whichever built-in tiers the deployment has on (by default the credentials and home agent-config tiers), are in force on top of these.", pickReadDenyEntry);
302
- try {
303
- compileReadDeny(entries, "agent(spec).readDenyPatterns");
241
+ if (row.law === "restricting") {
242
+ if (declared === row.value)
243
+ Object.assign(safe, { [seat]: row.value });
244
+ else {
245
+ stripped.total++;
246
+ stripped.sample.unshift({ key: seat, reason: "not_a_tightening_value" });
247
+ if (stripped.sample.length > MAX_STRIPPED_KEYS_ANNOUNCED)
248
+ stripped.sample.pop();
249
+ }
250
+ continue;
304
251
  }
305
- catch (err) {
306
- throw new WorkflowScriptError(thrownText(err));
252
+ const at = `agent(spec): \`${seat}\``;
253
+ if (!Array.isArray(declared))
254
+ throw new WorkflowScriptError(`${at} must be an array of ${row.script.shape}`);
255
+ const entries = mapUntrustedArray(declared, at, row.script.atMost, row.script.why, (el, i) => {
256
+ try {
257
+ return row.script.entry(el, `agent(spec): \`${seat}[${i}]\``);
258
+ }
259
+ catch (err) {
260
+ throw new WorkflowScriptError(thrownText(err));
261
+ }
262
+ });
263
+ for (const entry of entries) {
264
+ const problem = row.entry(entry, `agent(spec).${seat}`);
265
+ if (problem !== undefined)
266
+ throw new WorkflowScriptError(problem);
307
267
  }
308
- safe.readDenyPatterns = entries;
268
+ Object.assign(safe, { [seat]: entries });
309
269
  }
310
270
  const readModelName = (raw, spelling) => {
311
271
  if (raw === undefined)
@@ -13,10 +13,11 @@
13
13
  * full `TaskSpec` straight through (the author IS the deployment).
14
14
  */
15
15
  import type { Model } from "../internal/llm.js";
16
- import type { TaskSpec, WorkflowGovernanceBaseline } from "../core/types.js";
16
+ import type { WorkflowGovernanceBaseline } from "../core/types.js";
17
17
  import type { CheckpointStore } from "../core/checkpoint-store.js";
18
18
  import type { WorkflowAgentHandle, WorkflowRunContext } from "./workflow.js";
19
19
  import type { WorkflowPrimitives } from "./workflow-script-runner.js";
20
+ import { type ChildClampSource } from "../core/child-clamp-seats.js";
20
21
  import { type WorkflowChildCaps } from "./workflow-governance.js";
21
22
  /** What an LLM-authored workflow needs to GOVERN each spawned sub-agent (design/98 §2.5). */
22
23
  export interface WorkflowGovernance {
@@ -42,24 +43,8 @@ export declare function buildWorkflowPrimitives(ctx: WorkflowRunContext, governa
42
43
  /** The host run's RESOLVED checkpoint seat — the store object it parks in, else the word `"disabled"`.
43
44
  * Every agent this workflow spawns inherits it; see the injection below. */
44
45
  parentCheckpointStore?: CheckpointStore | "disabled",
45
- /** 5.30 merge-rescan (design/199 parity gap) — the host run's RESOLVED read-face containment
46
- * (post deps/org/mount resolution, not the raw spec value). `TaskSpec.readFace`'s own JSDoc
47
- * promises "roots pins this task, and via the tighten-only clamp, its whole delegation subtree" —
48
- * a workflow child is that subtree; the Task/SendMessage delegation lane already carries this,
49
- * the workflow lane was the one gap. Lazy (read at spawn time, after prepare has resolved it). */
50
- parentReadFace?: () => TaskSpec["readFace"],
51
- /** The WRITE seat's twin of the above — the host run's RESOLVED write-face containment, folded
52
- * stricter-wins into every spawned child on its own seat (the two seats never read each other). */
53
- parentWriteFace?: () => TaskSpec["writeFace"],
54
- /** Twin of the above for the deny-set additions (the extra entries the host's own deployment/task
55
- * layers stacked on; the built-in rows the DEPLOYMENT's tier selection activates apply beside them). */
56
- parentReadDenyPatterns?: () => TaskSpec["readDenyPatterns"],
57
- /** #345 ③ — the HOST task's write-hands clamp is ON (`spec.handsReadOnly === true`). Injected
58
- * tighten-only into every spawned child, like the read-face clamp above; see the injection
59
- * below for why it outranks even a `worktreeBase: { handsReadOnly: false }` overlay. */
60
- parentHandsReadOnly?: boolean,
61
- /** #345 ③ — the HOST task's hard-headless clamp is ON (`spec.interactiveTools === false`).
62
- * Same tighten-only injection; only the disabling value ever arrives here as `true`. */
63
- parentInteractiveToolsOff?: boolean,
64
- /** The HOST task declared that nobody on it can be asked (`approvalReach: "none"`). Same tighten-only injection. */
65
- parentApprovalReachNone?: boolean): WorkflowPrimitives;
46
+ /** The host run's tighten-only clamps — every clamp-carrier row of the clamp table as the host holds it (RESOLVED
47
+ * faces, the effective deny list, the approval declaration, the write-hands and hard-headless clamps). Lazy: read at
48
+ * spawn time, after prepare has resolved them. Injected into every spawned child; see the injection below for why it
49
+ * outranks even a `worktreeBase: { handsReadOnly: false }` overlay. */
50
+ parentClamps?: () => ChildClampSource): WorkflowPrimitives;
@@ -1,5 +1,5 @@
1
1
  import { assertSupportedAgentIsolation } from "./workflow.js";
2
- import { childClampSeats, postureUnderClamps } from "../core/child-clamp-seats.js";
2
+ import { childClampSeats, foldClampSources, postureUnderClamps } from "../core/child-clamp-seats.js";
3
3
  import { WorkflowScriptError } from "./workflow-meta.js";
4
4
  import { buildGovernedChildSpec, emitIgnoredAgentOptionsNotice, overlayWorktreeBaseline, MAX_ANNOUNCED_KEYS, SPEC_KEY_ALIASES, WHITELIST_KEYS, } from "./workflow-governance.js";
5
5
  const ACCEPTED_AGENT_OPTION_KEYS = ["label", "phase", "schema", "agentType", "isolation"];
@@ -66,7 +66,7 @@ function formatResourceClampNote(notes) {
66
66
  const parts = notes.map((n) => `${n.field}: requested ${n.requested === undefined ? "unset" : n.requested} → applied ${n.applied}`);
67
67
  return `workflow governance tightened this agent's resource limits (${parts.join("; ")})`;
68
68
  }
69
- export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn, parentCheckpointStore, parentReadFace, parentWriteFace, parentReadDenyPatterns, parentHandsReadOnly, parentInteractiveToolsOff, parentApprovalReachNone) {
69
+ export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn, parentCheckpointStore, parentClamps) {
70
70
  const agent = (spec, opts) => {
71
71
  if (typeof spec === "string")
72
72
  spec = { objective: spec };
@@ -78,17 +78,10 @@ export function buildWorkflowPrimitives(ctx, governance, onAgentSpawn, parentChe
78
78
  if (parentCheckpointStore !== undefined && (parentCheckpointStore === "disabled" || childSpec.checkpointStore === undefined)) {
79
79
  childSpec.checkpointStore = parentCheckpointStore;
80
80
  }
81
- const pd = parentReadDenyPatterns?.();
82
- const workflowChildClamps = childClampSeats({
83
- handsReadOnly: parentHandsReadOnly,
84
- interactiveTools: parentInteractiveToolsOff === true ? false : undefined,
85
- approvalReach: parentApprovalReachNone === true ? "none" : undefined,
86
- readFace: parentReadFace?.() === "roots" ? "roots" : childSpec.readFace,
87
- writeFace: parentWriteFace?.() === "roots" ? "roots" : childSpec.writeFace,
88
- readDenyPatterns: pd !== undefined && pd.length > 0 ? [...(childSpec.readDenyPatterns ?? []), ...pd] : childSpec.readDenyPatterns,
89
- });
81
+ const hostClamps = parentClamps?.();
82
+ const workflowChildClamps = childClampSeats(foldClampSources(childSpec, hostClamps));
90
83
  Object.assign(childSpec, workflowChildClamps);
91
- const posture = postureUnderClamps(childSpec.interactionPosture, { interactiveTools: parentInteractiveToolsOff === true ? false : undefined, approvalReach: parentApprovalReachNone === true ? "none" : undefined });
84
+ const posture = postureUnderClamps(childSpec.interactionPosture, { interactiveTools: workflowChildClamps.interactiveTools, approvalReach: workflowChildClamps.approvalReach });
92
85
  if (posture !== undefined)
93
86
  childSpec.interactionPosture = posture;
94
87
  if (onAgentSpawn) {
@@ -619,7 +619,7 @@ export declare const WORKFLOW_AGENT_PARKED_ERROR_CODE = "workflow.agent_parked";
619
619
  * under the host's forwarded `durableApproval` (the workflow lane's park family, the background delegation's
620
620
  * twin): the wa* row records `status:"parked"` + `parkedCheckpointToken`, the journal records the parked leg at
621
621
  * its ordinal, and the RUN SUSPENDS — every later spawn is refused with this same error and the run's terminal
622
- * is this park whatever the script body returns (the team-discussion `teamPause` shape). Nothing after the
622
+ * is this park whatever the script body returns. Nothing after the
623
623
  * parked call runs; the script must not retry it (an identical call parks again). A resume of the run
624
624
  * (`resumeFromRunId`) with the host's decision for the token drives the parked child on and the script
625
625
  * continues from here; without a decision the ordinal re-parks.