@sema-agent/core 7.48.0 → 7.49.1

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 (421) hide show
  1. package/CHANGELOG.md +457 -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 +21 -28
  52. package/dist/core/arg-summary.js +235 -88
  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 +43 -11
  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 +21 -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 +29 -36
  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/tool-turn-repair-seat.d.ts +28 -4
  243. package/dist/core/runner/tool-turn-repair-seat.js +36 -13
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/secret-env.d.ts +16 -5
  249. package/dist/core/secret-env.js +23 -63
  250. package/dist/core/sensitive-path-policy.d.ts +19 -18
  251. package/dist/core/sensitive-path-policy.js +73 -49
  252. package/dist/core/session-reconcile.d.ts +3 -0
  253. package/dist/core/session-reconcile.js +5 -4
  254. package/dist/core/session-store.d.ts +5 -0
  255. package/dist/core/session-store.js +12 -0
  256. package/dist/core/session.d.ts +13 -0
  257. package/dist/core/shared-memory/normalize.d.ts +17 -4
  258. package/dist/core/shared-memory/normalize.js +7 -7
  259. package/dist/core/shell-lexer.js +5 -4
  260. package/dist/core/shell-wrapper-projection.js +1 -1
  261. package/dist/core/skill-grant.js +1 -1
  262. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  263. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  264. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  265. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  266. package/dist/core/stub-env.d.ts +2 -0
  267. package/dist/core/stub-env.js +1 -0
  268. package/dist/core/synthetic-read-verdict.js +2 -2
  269. package/dist/core/task-event.d.ts +59 -5
  270. package/dist/core/task-result.d.ts +1 -1
  271. package/dist/core/task-spec.d.ts +42 -9
  272. package/dist/core/terminal-cause.d.ts +94 -11
  273. package/dist/core/tighten-task-spec.d.ts +5 -4
  274. package/dist/core/tighten-task-spec.js +20 -25
  275. package/dist/core/tool-catalog-entries.d.ts +5 -7
  276. package/dist/core/tool-catalog-entries.js +14 -15
  277. package/dist/core/tool-face.d.ts +47 -0
  278. package/dist/core/tool-face.js +5 -0
  279. package/dist/core/tool-model-gate.d.ts +5 -5
  280. package/dist/core/tool-name-aliases.d.ts +26 -2
  281. package/dist/core/tool-name-aliases.js +13 -0
  282. package/dist/core/tool-name-list.d.ts +30 -0
  283. package/dist/core/tool-name-list.js +55 -0
  284. package/dist/core/tool-name-readings.d.ts +1 -9
  285. package/dist/core/tool-name-readings.js +1 -3
  286. package/dist/core/tool-policy.d.ts +195 -85
  287. package/dist/core/tool-policy.js +165 -380
  288. package/dist/core/tool-registry.d.ts +44 -1
  289. package/dist/core/tool-registry.js +26 -0
  290. package/dist/core/tool-roster.d.ts +19 -1
  291. package/dist/core/tool-roster.js +21 -2
  292. package/dist/core/tool-spec-members.d.ts +45 -0
  293. package/dist/core/tool-spec-members.js +169 -0
  294. package/dist/core/tool-spec.d.ts +46 -8
  295. package/dist/core/tools.d.ts +6 -2
  296. package/dist/core/tools.js +8 -4
  297. package/dist/core/untrusted-egress.js +29 -26
  298. package/dist/core/untrusted-text.d.ts +13 -10
  299. package/dist/core/untrusted-text.js +6 -44
  300. package/dist/core/workflow-journal-store.d.ts +4 -1
  301. package/dist/core/write-protect.d.ts +65 -29
  302. package/dist/core/write-protect.js +235 -177
  303. package/dist/engine/compaction/compaction.d.ts +2 -2
  304. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  305. package/dist/engine/execution-env/node-execution-env.js +16 -38
  306. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  307. package/dist/engine/execution-env/symlink-chain.js +32 -0
  308. package/dist/engine/harness/types.d.ts +7 -0
  309. package/dist/engine/llm/tool-turns.d.ts +3 -0
  310. package/dist/engine/llm/tool-turns.js +1 -0
  311. package/dist/engine/llm/types.d.ts +59 -23
  312. package/dist/engine/loop/agent-loop.js +16 -2
  313. package/dist/engine/session/memory-repo.js +11 -3
  314. package/dist/engine/session/repo-utils.d.ts +8 -0
  315. package/dist/engine/session/repo-utils.js +13 -0
  316. package/dist/index.d.ts +20 -23
  317. package/dist/index.js +17 -20
  318. package/dist/internal/harness.d.ts +1 -1
  319. package/dist/internal/harness.js +1 -1
  320. package/dist/internal/llm.d.ts +2 -2
  321. package/dist/internal/llm.js +1 -1
  322. package/dist/orchestration/governance-baseline-validity.js +1 -1
  323. package/dist/orchestration/run-spec.js +3 -3
  324. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  325. package/dist/orchestration/run-workflow-tool.js +38 -78
  326. package/dist/orchestration/workflow-governance.d.ts +21 -25
  327. package/dist/orchestration/workflow-governance.js +38 -78
  328. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  329. package/dist/orchestration/workflow-primitives.js +5 -12
  330. package/dist/orchestration/workflow-types.d.ts +1 -1
  331. package/dist/orchestration/workflow.d.ts +61 -11
  332. package/dist/orchestration/workflow.js +189 -117
  333. package/dist/scenarios/full-body.d.ts +1 -1
  334. package/dist/shell/lex.d.ts +0 -21
  335. package/dist/shell/lex.js +250 -68
  336. package/dist/shell/shell-words.d.ts +35 -0
  337. package/dist/shell/shell-words.js +65 -0
  338. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  339. package/dist/stores/file/checkpoint-store.js +5 -2
  340. package/dist/stores/file/index.d.ts +0 -8
  341. package/dist/stores/file/index.js +0 -12
  342. package/dist/stores/file/session-store.d.ts +3 -0
  343. package/dist/stores/file/session-store.js +44 -19
  344. package/dist/tools/artifact/artifact-tool.js +2 -0
  345. package/dist/tools/fs/bash-program-position.d.ts +12 -4
  346. package/dist/tools/fs/bash-program-position.js +32 -9
  347. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  348. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  349. package/dist/tools/fs/containment-face.d.ts +4 -0
  350. package/dist/tools/fs/containment-face.js +3 -0
  351. package/dist/tools/fs/fs-shared.d.ts +10 -0
  352. package/dist/tools/fs/fs-shared.js +18 -0
  353. package/dist/tools/fs/fs-write.js +4 -2
  354. package/dist/tools/fs/index.d.ts +1 -1
  355. package/dist/tools/fs/program-read-model.d.ts +46 -20
  356. package/dist/tools/fs/program-read-model.js +50 -20
  357. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  358. package/dist/tools/fs/program-read-model.rows.js +16 -15
  359. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  360. package/dist/tools/fs/read-deny-home.js +35 -49
  361. package/dist/tools/fs/read-deny.d.ts +23 -22
  362. package/dist/tools/fs/read-deny.js +114 -89
  363. package/dist/tools/fs/removal-targets.d.ts +56 -23
  364. package/dist/tools/fs/removal-targets.js +65 -87
  365. package/dist/tools/fs/safety.d.ts +29 -22
  366. package/dist/tools/fs/safety.js +17 -11
  367. package/dist/tools/fs/search.js +10 -8
  368. package/dist/tools/fs/shell-read-argv.js +1 -1
  369. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  370. package/dist/tools/fs/shell-read-bindings.js +324 -86
  371. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  372. package/dist/tools/fs/shell-read-builtins.js +43 -0
  373. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  374. package/dist/tools/fs/shell-read-check.js +67 -43
  375. package/dist/tools/fs/shell-read-establish.js +6 -6
  376. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  377. package/dist/tools/fs/shell-read-functions.js +29 -0
  378. package/dist/tools/fs/shell-read-judge.d.ts +51 -18
  379. package/dist/tools/fs/shell-read-judge.js +40 -4
  380. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  381. package/dist/tools/fs/shell-read-plan.js +118 -113
  382. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  383. package/dist/tools/fs/shell-read-start.js +16 -9
  384. package/dist/tools/fs/shell-read-word.js +4 -0
  385. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  386. package/dist/tools/fs/shell-read-workdir.js +281 -0
  387. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  388. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  389. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  390. package/dist/tools/fs/shell-reentry-text.js +3 -11
  391. package/dist/tools/task-list.d.ts +1 -2
  392. package/dist/tools/web.js +1 -1
  393. package/package.json +4 -1
  394. package/test/export-surface.snapshot.json +107 -143
  395. package/wire-changes/core@7.49.0.json +4765 -0
  396. package/dist/agents/teacher.d.ts +0 -159
  397. package/dist/agents/teacher.js +0 -577
  398. package/dist/agents/team.d.ts +0 -226
  399. package/dist/agents/team.js +0 -257
  400. package/dist/core/strategy-store.d.ts +0 -238
  401. package/dist/core/strategy-store.js +0 -253
  402. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  403. package/dist/orchestration/builtin-workflows.js +0 -159
  404. package/dist/scenarios/env.d.ts +0 -40
  405. package/dist/scenarios/env.js +0 -39
  406. package/dist/scenarios/scenario-registry.d.ts +0 -110
  407. package/dist/scenarios/scenario-registry.js +0 -140
  408. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  409. package/dist/scenarios/teacher-quickstart.js +0 -12
  410. package/dist/stores/cc/lockfile.d.ts +0 -10
  411. package/dist/stores/cc/lockfile.js +0 -98
  412. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  413. package/dist/stores/cc/mailbox-store.js +0 -255
  414. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  415. package/dist/stores/cc/roster-adapter.js +0 -117
  416. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  417. package/dist/stores/cc/sidecar-transcript.js +0 -264
  418. package/dist/stores/cc/task-list-store.d.ts +0 -2
  419. package/dist/stores/cc/task-list-store.js +0 -125
  420. package/dist/stores/file/strategy-store.d.ts +0 -97
  421. package/dist/stores/file/strategy-store.js +0 -341
@@ -1,84 +1,240 @@
1
1
  /**
2
- * The TIGHTEN-ONLY CLAMP SEATS an engine-built child spec carries from the run that builds it — and the
3
- * ONE carrier every such constructor passes them through.
2
+ * The TIGHTEN-ONLY SEATS of a TaskSpec — the ONE table that says which seats only tighten, which value of each is the
3
+ * restricting one, how two declarations of a seat compose, and which carrier hands it to an engine-built child. Every
4
+ * reader reads the table: the public merge ({@link import("./tighten-task-spec.js").tightenTaskSpec}), the child-spec
5
+ * carrier ({@link childClampSeats}), the run's trusted ctx seats and the workflow mount (one {@link ChildClampSource}
6
+ * minted per prepare), and a revival's fold of the waker's restrictions ({@link clampValuesOf}). A row added here
7
+ * reaches all of them; a reader that spells a seat by hand is named by `scripts/verify-child-clamp-seats.mjs`.
4
8
  *
5
- * Why a carrier and not a convention. The engine builds child specs in several places (the delegation
6
- * lane, the observer sidecar, the wake/revival fold, the teacher's internal legs, the verify gate's two
7
- * legs, the workflow lane), and each re-deriving per seat WHICH value is the tightening one lands a new
8
- * seat one constructor at a time — the ones it does not reach staying invisible, since a `grep readFace`
9
- * census cannot see a station that carries the face through a persisted seed or a synthesized fold.
9
+ * Two mechanical halves keep it whole:
10
+ * · the COMPILER — {@link ChildClampSource} requires every clamp-carrier row as a PRESENT key, so a site that builds a
11
+ * source by hand cannot drop a row;
12
+ * · the SCAN — the gate reads this table literally, requires each registered constructor to go through the carrier,
13
+ * requires the published carriers (`ToolExecuteContext`, `ParentSpecSeat`) to declare exactly the rows they carry,
14
+ * and names any hand-written restricting projection outside the carriers.
10
15
  *
11
- * Two mechanical halves replace the census:
12
- * · the COMPILER — {@link ChildClampSource} requires every seat as a PRESENT key (an `undefined` value
13
- * is fine; a missing key is not), so adding a member to {@link CHILD_CLAMP_SEATS} reds `tsc` at every
14
- * construction site until each one says what it carries there;
15
- * · the SCAN — `scripts/verify-child-clamp-seats.mjs` reads {@link ENGINE_CHILD_SPEC_CONSTRUCTORS} and
16
- * requires each registered constructor to go through this carrier, requires the carrier's own source
17
- * to cover every seat, and requires every tighten-only seat `tightenTaskSpec` governs to be either
18
- * carried here or listed in {@link CHILD_CLAMP_SEATS_NOT_CARRIED} with a reason.
19
- *
20
- * What "tighten-only" means for this seat list: the value that travels is the RESTRICTING one and only
21
- * that one, so a parent that clamped nothing changes nothing about its children, and nothing a child can
22
- * author lifts a clamp its parent ran under. That is why the carrier omits a key rather than writing a
23
- * loosening value — a constructor may state its own stricter default and spread this after it.
16
+ * "Tighten-only" here: the value that travels is the RESTRICTING one and only that one, so a parent that clamped nothing
17
+ * changes nothing about its children, and nothing a child can author lifts a clamp its parent ran under.
24
18
  */
25
- import type { ReadDenyEntry } from "../tools/fs/read-deny.js";
19
+ import { readDenyEntryProblem, type ReadDenyEntry } from "../tools/fs/read-deny.js";
20
+ import { complianceCapabilityProblem, type ComplianceCapability } from "./compliance.js";
26
21
  import type { TaskSpec } from "./types.js";
22
+ import { writeProtectedEntryIdentity, writeProtectedEntryProblem } from "./write-protect.js";
23
+ /** Which carrier hands a row to an engine-built child: the child-spec carrier ({@link childClampSeats}, ctx seats of the
24
+ * same names) or the parent spec seat (`ParentSpecSeat`, applied by `applyParentSpecSeat`). */
25
+ export type ClampCarrier = "clamp" | "specSeat";
26
+ /** The identity an add-only list folds by — case-insensitive unless the entry says otherwise (the deny matcher's reading). */
27
+ declare function readDenyIdentity(entry: ReadDenyEntry): string;
28
+ /** A capability is its own identity (a closed word). */
29
+ declare function complianceIdentity(cap: ComplianceCapability): string;
27
30
  /**
28
- * The clamp seats, as string literals (the closed set the scan and the wire-manifest reader both parse —
29
- * a spread or an identifier here reads as an empty set).
31
+ * How a governed workflow SCRIPT's untrusted list for an add-only row is read before the row's `entry` law judges it —
32
+ * the untrusted layer is bounded where the deployment and task layers are not. `atMost` is refused before any element is
33
+ * read (`why` says what each entry costs); `entry` reads ONE element, each of its properties exactly once, rebuilds it
34
+ * from the keys it recognizes (an element's extra own keys never ride along) and throws, naming `at`, on a shape it
35
+ * refuses. `shape` names the list's element grammar for the not-a-list refusal.
30
36
  */
31
- export declare const CHILD_CLAMP_SEATS: readonly ["handsReadOnly", "interactiveTools", "approvalReach", "readFace", "writeFace", "readDenyPatterns"];
32
- /** One clamp seat's name. */
33
- export type ChildClampSeat = (typeof CHILD_CLAMP_SEATS)[number];
37
+ export interface ScriptListLaw<E> {
38
+ readonly atMost: number;
39
+ readonly shape: string;
40
+ readonly why: string;
41
+ readonly entry: (el: unknown, at: string) => E;
42
+ }
34
43
  /**
35
- * The seats `tightenTaskSpec` governs that this carrier deliberately does NOT carry, each with the reason
36
- * — the "forgot" / "decided" distinction, kept where a new reader will trip over it. The scan requires
37
- * every seat named in `tightenTaskSpec` to be in this table or in {@link CHILD_CLAMP_SEATS}.
44
+ * THE CLAMP TABLE. Two laws:
45
+ * · `restricting` — the seat has ONE restricting `value`. Either side carrying it wins; a side that carries a different
46
+ * value cannot replace it (the public merge refuses that as a loosening); a seat with nothing restricting keeps what was
47
+ * authored.
48
+ * · `addOnly` — the seat is a list that only grows: every two of its lists meet in {@link unionAddOnly} (in order, folded
49
+ * by `identity`; `[]` erases nothing), and the run's effective list is that union taken with the deployment's own list
50
+ * (`deploymentLayer`, the `RunnerDeps` member it arrives through) — so the task layer can add entries and never remove
51
+ * one. `entry` is the seat's own entry law (its compiler's, never a copy); the task layer's lists meet it at the one
52
+ * door ({@link assertAddOnlySeats}), and an entry it refuses never folds into another. `script` bounds a governed
53
+ * workflow script's untrusted list for the seat before `entry` judges it.
54
+ * `script` also says whether a governed workflow SCRIPT may declare the seat for its child, under the row's law: a
55
+ * restricting row with `script: true` only as its restricting value (`false` = inherited only); an add-only row through its
56
+ * `script` list law, then `entry`. The script whitelist reads its tighten-only keys off this table ({@link SCRIPT_SEATS}),
57
+ * never off a list of its own.
58
+ * Rows are literals (the gate reads them as written).
38
59
  */
39
- export declare const CHILD_CLAMP_SEATS_NOT_CARRIED: Readonly<Record<string, string>>;
60
+ export declare const CLAMP_SET: Readonly<{
61
+ handsReadOnly: Readonly<{
62
+ readonly law: "restricting";
63
+ readonly value: true;
64
+ readonly script: true;
65
+ readonly carrier: "clamp";
66
+ }>;
67
+ interactiveTools: Readonly<{
68
+ readonly law: "restricting";
69
+ readonly value: false;
70
+ readonly script: true;
71
+ readonly carrier: "clamp";
72
+ }>;
73
+ approvalReach: Readonly<{
74
+ readonly law: "restricting";
75
+ readonly value: "none";
76
+ readonly script: true;
77
+ readonly carrier: "clamp";
78
+ }>;
79
+ readFace: Readonly<{
80
+ readonly law: "restricting";
81
+ readonly value: "roots";
82
+ readonly script: true;
83
+ readonly carrier: "clamp";
84
+ }>;
85
+ writeFace: Readonly<{
86
+ readonly law: "restricting";
87
+ readonly value: "roots";
88
+ readonly script: true;
89
+ readonly carrier: "clamp";
90
+ }>;
91
+ readDenyPatterns: Readonly<{
92
+ readonly law: "addOnly";
93
+ readonly identity: typeof readDenyIdentity;
94
+ readonly entry: typeof readDenyEntryProblem;
95
+ readonly script: ScriptListLaw<ReadDenyEntry>;
96
+ readonly deploymentLayer: "readDenyPatterns";
97
+ readonly carrier: "clamp";
98
+ }>;
99
+ writeProtectedAdditions: Readonly<{
100
+ readonly law: "addOnly";
101
+ readonly identity: typeof writeProtectedEntryIdentity;
102
+ readonly entry: typeof writeProtectedEntryProblem;
103
+ readonly script: ScriptListLaw<import("./write-protect.js").WriteProtectedEntry>;
104
+ readonly deploymentLayer: "writeProtectedPaths";
105
+ readonly carrier: "clamp";
106
+ }>;
107
+ complianceAdditionalDenies: Readonly<{
108
+ readonly law: "addOnly";
109
+ readonly identity: typeof complianceIdentity;
110
+ readonly entry: typeof complianceCapabilityProblem;
111
+ readonly script: ScriptListLaw<ComplianceCapability>;
112
+ readonly deploymentLayer: "compliancePostureResolver";
113
+ readonly carrier: "clamp";
114
+ }>;
115
+ oneShot: Readonly<{
116
+ readonly law: "restricting";
117
+ readonly value: true;
118
+ readonly script: true;
119
+ readonly carrier: "specSeat";
120
+ }>;
121
+ memoryPersistenceCapable: Readonly<{
122
+ readonly law: "restricting";
123
+ readonly value: false;
124
+ readonly script: true;
125
+ readonly carrier: "specSeat";
126
+ }>;
127
+ fileHistory: Readonly<{
128
+ readonly law: "restricting";
129
+ readonly value: "disabled";
130
+ readonly script: false;
131
+ readonly carrier: "specSeat";
132
+ }>;
133
+ }>;
134
+ /** One row's seat name. */
135
+ export type ClampSeat = keyof typeof CLAMP_SET;
136
+ /** The add-only rows' seats. */
137
+ export type AddOnlySeat = {
138
+ [K in ClampSeat]: (typeof CLAMP_SET)[K]["law"] extends "addOnly" ? K : never;
139
+ }[ClampSeat];
140
+ /** One entry of an add-only seat's list. */
141
+ export type AddOnlyEntry<S extends AddOnlySeat> = NonNullable<TaskSpec[S]> extends ReadonlyArray<infer E> ? E : never;
142
+ /** The seats the child-spec carrier hands on. */
143
+ export type ChildClampSeat = {
144
+ [K in ClampSeat]: (typeof CLAMP_SET)[K]["carrier"] extends "clamp" ? K : never;
145
+ }[ClampSeat];
146
+ /** Every row's value as some record carries it — present keys, `undefined` where the record has none. */
147
+ export type ClampSource = {
148
+ [K in ClampSeat]: TaskSpec[K] | undefined;
149
+ };
150
+ /** The clamp source a construction site hands the carrier: EVERY clamp-carrier row as a PRESENT key. */
151
+ export type ChildClampSource = Pick<ClampSource, ChildClampSeat>;
152
+ /** Only the restricting values (add-only rows: a non-empty list) — the shape a waker's clamp seat and a projection take. */
153
+ export type ClampValues = {
154
+ readonly [K in ClampSeat]?: (typeof CLAMP_SET)[K] extends {
155
+ readonly value: infer V;
156
+ } ? V : NonNullable<TaskSpec[K]>;
157
+ };
158
+ /** Every row's seat name, in table order. */
159
+ export declare const CLAMP_SEATS: readonly ClampSeat[];
160
+ /** The rows a governed workflow script may declare for its child (every row whose `script` is not `false`). */
161
+ export type ScriptSeat = {
162
+ [K in ClampSeat]: (typeof CLAMP_SET)[K]["script"] extends false ? never : K;
163
+ }[ClampSeat];
164
+ /** {@link ScriptSeat}, in table order — the script whitelist's tighten-only half. */
165
+ export declare const SCRIPT_SEATS: readonly ScriptSeat[];
166
+ /** Two declarations of one seat under its row's law (`b` is the later one): the restricting value if either carries it,
167
+ * else what was authored (`b` over `a`); an add-only list is the union of both, in order, by the row's identity. */
168
+ export declare function composeClampSeat(seat: ClampSeat, a: unknown, b: unknown): unknown;
169
+ /**
170
+ * THE union of an add-only seat's lists — the ONE merge every add-only row reads, wherever two of its lists meet: two
171
+ * declarations of the seat (the public merge, a fold of records) and the run's EFFECTIVE list (the deployment's list
172
+ * first, then every task-layer list). In order; a lawful entry folds into an earlier one with the same `identity`; `[]`
173
+ * and absent add nothing, and nothing here removes an entry — so a later layer can only add. An entry the row's entry
174
+ * law refuses is kept as it is, never folded into a lawful one: it reaches the door or the compiler that refuses it
175
+ * instead of vanishing behind a namesake. A list that is not a list refuses here (it would be read letter by letter).
176
+ */
177
+ export declare function unionAddOnly<S extends AddOnlySeat>(seat: S, ...lists: ReadonlyArray<ReadonlyArray<AddOnlyEntry<S>> | undefined>): AddOnlyEntry<S>[];
40
178
  /**
41
- * The engine-built child-spec constructors, as `<repo-relative file>#<name>` — the closed registry the
42
- * scan enumerates. A constructor that builds a spec for a child RUN belongs here; the scan requires each
43
- * row to resolve to exactly one declaration IN ITS OWN FILE that calls {@link childClampSeats}.
179
+ * THE task layer's door for the add-only rows: every add-only seat a spec carries is a list of entries its row's entry
180
+ * law accepts, or the prepare refuses — one code (`config.invalid_argument`, the table's own refusal), one sentence for a
181
+ * value that is not a list, and the seat's own entry law (labelled `TaskSpec.<seat>`) for a bad entry. Runs before any
182
+ * list is folded or compiled, so a task-layer value is judged as the caller wrote it. Absent ⇒ nothing to judge.
183
+ */
184
+ export declare function assertAddOnlySeats(spec: object): void;
185
+ /** Would `override` LOOSEN `base` on this seat? Only a restricting row can be loosened: a base carrying the restricting
186
+ * value meeting an override that states a different one. */
187
+ export declare function loosensClampSeat(seat: ClampSeat, base: unknown, override: unknown): boolean;
188
+ /** Read every row (`carrier`: that carrier's rows only) off a record that carries the seats under their own names (a spec, a ctx, a seat). */
189
+ export declare function clampSourceOf(record: object | undefined): ClampSource;
190
+ export declare function clampSourceOf(record: object | undefined, carrier: "clamp"): ChildClampSource;
191
+ /** Fold several records' declarations of every row, in order, under each row's law — "either side restricting wins",
192
+ * add-only lists unioned. The fold of a spawn snapshot and its waker, of a workflow child's own spec and its host's
193
+ * clamps, of a ctx and its spec seat. */
194
+ export declare function foldClampSources(...records: ReadonlyArray<object | undefined>): ClampSource;
195
+ /** The restricting values of every row (`carrier` narrows it to one carrier's rows): a row with nothing restricting adds
196
+ * NO KEY, so the result spreads onto a spec without ever writing a loosening value. */
197
+ export declare function clampSeatsOf(source: Partial<Record<ClampSeat, unknown>>, carrier?: ClampCarrier): ClampValues;
198
+ /** The coded refusal of a clamp record a caller handed in (`config.invalid_argument`). */
199
+ export declare function clampRecordError(message: string): Error & {
200
+ code: "config.invalid_argument";
201
+ };
202
+ /**
203
+ * Refuse a caller-supplied clamp record that names a seat the table does not have (or, with `carrier`, a row another
204
+ * carrier hands on): a name nobody reads would sit on the record as if wired — the silent drop the retired-key door
205
+ * exists to prevent. `extra` names the record's own members that are not rows. Absent ⇒ nothing to judge; a member
206
+ * whose value is `undefined` carries nothing and is read as absent (the retired-key door's presence rule).
207
+ */
208
+ export declare function assertClampRecord(record: unknown, owner: string, carrier?: ClampCarrier, extra?: readonly string[]): void;
209
+ /** The restricting values of every row that ANY of `records` carries — the clamp seat a waker hands a revival. */
210
+ export declare function clampValuesOf(...records: ReadonlyArray<object | undefined>): ClampValues;
211
+ /**
212
+ * Project a parent's clamps onto a child spec — the clamp-carrier rows of the table, the ONE place a source becomes the
213
+ * seats a child spec carries. Spread the result onto the child spec; a seat with nothing to clamp contributes NO KEY, so
214
+ * a constructor may state its own stricter value above the spread and keep it (a `false` from the parent can never lift it).
44
215
  *
45
- * Why the file is half the key, and why a shape the scan cannot read is a RED rather than an absence: a
46
- * registry keyed on a bare NAME asks a syntactic scan to enumerate every shape that binds a callable, and
47
- * that list has no end — every shape it misses leaves the real constructor invisible while a namesake
48
- * answers for it.
216
+ * @contract child_spec.clamps_travel_whole — every child spec the ENGINE builds carries the whole of its parent's
217
+ * tighten-only clamp seats (the `CLAMP_SET` rows whose carrier is `"clamp"`) through this one carrier: only the
218
+ * restricting value of each seat travels, arrays are copied at spawn, and a seat the parent did not clamp adds no key —
219
+ * so a clamp can never end one level deep, and a new seat cannot reach some constructors and not others.
49
220
  */
50
- export declare const ENGINE_CHILD_SPEC_CONSTRUCTORS: readonly ["src/agents/subagent.ts#buildChildSpec", "src/agents/subagent.ts#observerSpec", "src/agents/subagent.ts#resumeSpec", "src/agents/teacher.ts#inheritedDeploymentConfig", "src/agents/verify.ts#verifierSpec", "src/agents/verify.ts#fixLegSpec", "src/orchestration/workflow-primitives.ts#workflowChildClamps"];
221
+ export declare function childClampSeats(source: ChildClampSource): Pick<ClampValues, ChildClampSeat>;
51
222
  /**
52
- * The clamp source a construction site hands the carrier: EVERY seat as a present key. A site whose lane
53
- * has no value for a seat writes `undefined` explicitly — which is the point, since that is a sentence
54
- * a reader (and a diff) can see, unlike an absent key.
223
+ * The seats `tightenTaskSpec` governs OUTSIDE the table, each with the reason it is not a row — the "forgot" / "decided"
224
+ * distinction, kept where a new reader will trip over it. The scan requires every seat `tightenTaskSpec` names to be a
225
+ * row or listed here.
55
226
  */
56
- export interface ChildClampSource {
57
- /** The write-hands clamp: only `true` travels. */
58
- handsReadOnly: boolean | undefined;
59
- /** The hard-headless clamp: only `false` travels. */
60
- interactiveTools: boolean | undefined;
61
- /** The declaration that nobody on the run can be asked to approve: only `"none"` travels. */
62
- approvalReach: TaskSpec["approvalReach"] | undefined;
63
- /** The read containment face: only `"roots"` travels. */
64
- readFace: TaskSpec["readFace"] | undefined;
65
- /** The write containment face: only `"roots"` travels. */
66
- writeFace: TaskSpec["writeFace"] | undefined;
67
- /** The deny-set additions: an add-only axis, so a non-empty list travels as a spawn-time copy. */
68
- readDenyPatterns: readonly ReadDenyEntry[] | undefined;
69
- }
227
+ export declare const CHILD_CLAMP_SEATS_NOT_CARRIED: Readonly<Record<string, string>>;
70
228
  /**
71
- * Project a parent's clamps onto a child spec — the ONE place that decides, per seat, which value is the
72
- * tightening one and how it is copied. Spread the result onto the child spec; a seat with nothing to
73
- * clamp contributes NO KEY, so a constructor may state its own stricter value above the spread and keep
74
- * it (a `false` from the parent can never lift it).
229
+ * The engine-built child-spec constructors, as `<repo-relative file>#<name>` — the closed registry the scan enumerates.
230
+ * A constructor that builds a spec for a child RUN belongs here; the scan requires each row to resolve to exactly one
231
+ * declaration IN ITS OWN FILE that calls {@link childClampSeats}.
75
232
  *
76
- * @contract child_spec.clamps_travel_whole — every child spec the ENGINE builds carries the whole of its
77
- * parent's tighten-only clamp seats (`CHILD_CLAMP_SEATS`) through this one carrier: only the restricting
78
- * value of each seat travels, arrays are copied at spawn, and a seat the parent did not clamp adds no key
79
- * — so a clamp can never end one level deep, and a new seat cannot reach some constructors and not others.
233
+ * Why the file is half the key, and why a shape the scan cannot read is a RED rather than an absence: a registry keyed
234
+ * on a bare NAME asks a syntactic scan to enumerate every shape that binds a callable, and that list has no end — every
235
+ * shape it misses leaves the real constructor invisible while a namesake answers for it.
80
236
  */
81
- export declare function childClampSeats(source: ChildClampSource): Partial<TaskSpec>;
237
+ export declare const ENGINE_CHILD_SPEC_CONSTRUCTORS: readonly ["src/agents/subagent.ts#buildChildSpec", "src/agents/subagent.ts#observerSpec", "src/agents/subagent.ts#resumeSpec", "src/agents/verify.ts#verifierSpec", "src/agents/verify.ts#fixLegSpec", "src/orchestration/workflow-primitives.ts#workflowChildClamps"];
82
238
  /**
83
239
  * The interaction posture a leg keeps under the clamps it inherited: `"interactive"` promises a person on the leg, and a
84
240
  * leg that inherited the hard-headless clamp (`interactiveTools: false`) or the declaration that nobody can be asked
@@ -92,13 +248,16 @@ export declare function postureUnderClamps(posture: "interactive" | "headless" |
92
248
  readonly approvalReach: TaskSpec["approvalReach"] | undefined;
93
249
  }): "interactive" | "headless" | undefined;
94
250
  /**
95
- * The OWN posture of an engine-built leg that never asks the person (the observer sidecar, the verifier): no
96
- * human-facing tool is mounted AND the leg declares itself headless. Both, always together — the spec's posture
97
- * outranks the one a leg inherits from its parent or its deployment, and the prepare door refuses an
98
- * "interactive" posture paired with `interactiveTools: false`, so a leg that stated only the clamp was refused
99
- * under every interactive parent. Spread ABOVE {@link childClampSeats}: a caller clamp can only tighten it.
251
+ * The OWN seats of an engine-built leg that never asks the person (the observer sidecar, the verifier) — ONE declaration
252
+ * the leg's own resolutions read: no human-facing tool is mounted, the leg is headless, and nobody on it can be asked to
253
+ * approve (the approval seat resolves without the deployment's live approver: refused, or parked where the deployment's
254
+ * park facility is armed). The spec's posture outranks the one a leg inherits, and the prepare door refuses an
255
+ * "interactive" posture beside either clamp, so the three travel together. Spread ABOVE {@link childClampSeats}: a caller
256
+ * clamp can only tighten it.
100
257
  */
101
258
  export declare function engineHeadlessLegSeats(): {
102
259
  interactiveTools: false;
260
+ approvalReach: "none";
103
261
  interactionPosture: "headless";
104
262
  };
263
+ export {};
@@ -1,37 +1,231 @@
1
- export const CHILD_CLAMP_SEATS = Object.freeze(["handsReadOnly", "interactiveTools", "approvalReach", "readFace", "writeFace", "readDenyPatterns"]);
1
+ import { readDenyEntryProblem } from "../tools/fs/read-deny.js";
2
+ import { COMPLIANCE_CAPABILITIES, complianceCapabilityProblem } from "./compliance.js";
3
+ import { writeProtectedEntryIdentity, writeProtectedEntryProblem } from "./write-protect.js";
4
+ function readDenyIdentity(entry) {
5
+ return typeof entry === "string" ? `i:${entry}` : `${entry.caseSensitive === true ? "s" : "i"}:${entry.pattern}`;
6
+ }
7
+ function complianceIdentity(cap) {
8
+ return cap;
9
+ }
10
+ const MAX_SCRIPT_LIST_ENTRIES = 16;
11
+ const MAX_SCRIPT_ENTRY_CHARS = 256;
12
+ const MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT = 1;
13
+ function assertScriptEntryLength(text, at, what, why) {
14
+ if (text.length > MAX_SCRIPT_ENTRY_CHARS)
15
+ throw new Error(`${at} is ${text.length} characters — a workflow script's ${what} is limited to ${MAX_SCRIPT_ENTRY_CHARS} (${why}).`);
16
+ }
17
+ function assertScriptDenyPatternBounded(pattern, at) {
18
+ assertScriptEntryLength(pattern, at, "deny pattern", "the matcher runs on every read of the child's run");
19
+ for (const segment of pattern.split("/")) {
20
+ const wildcards = segment.split("*").length - 1;
21
+ if (wildcards > MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT) {
22
+ throw new Error(`${at} has a path segment with ${wildcards} \`*\` wildcards — a workflow script's deny pattern allows at most ` +
23
+ `${MAX_SCRIPT_DENY_WILDCARDS_PER_SEGMENT} per path segment (the same expressiveness the engine's built-in deny table ` +
24
+ `uses). Each \`*\` compiles to a greedy match, and more than one in a single segment makes the judgment cost grow ` +
25
+ `superlinearly with the path length, on every read the child performs. Write the intent as separate entries ` +
26
+ `(the set is a union, so more entries deny strictly more) or anchor it with literal segments.`);
27
+ }
28
+ }
29
+ }
30
+ function readDenyScriptEntry(el, at) {
31
+ if (typeof el === "string") {
32
+ if (el.length === 0)
33
+ throw new Error(`${at} must be a non-empty pattern string`);
34
+ assertScriptDenyPatternBounded(el, at);
35
+ return el;
36
+ }
37
+ if (typeof el !== "object" || el === null || Array.isArray(el))
38
+ throw new Error(`${at} must be a pattern string or an object { pattern, caseSensitive? }`);
39
+ const o = el;
40
+ const pattern = o.pattern;
41
+ const caseSensitive = o.caseSensitive;
42
+ if (typeof pattern !== "string" || pattern.length === 0)
43
+ throw new Error(`${at}.pattern must be a non-empty string, e.g. ".ssh" or "secrets/*.json"`);
44
+ if (caseSensitive !== undefined && typeof caseSensitive !== "boolean")
45
+ throw new Error(`${at}.caseSensitive must be a boolean`);
46
+ assertScriptDenyPatternBounded(pattern, at);
47
+ return caseSensitive === undefined ? { pattern } : { pattern, caseSensitive };
48
+ }
49
+ function writeProtectedScriptEntry(el, at) {
50
+ const why = "the judge runs on every write the child names";
51
+ if (typeof el === "string") {
52
+ if (el.length === 0)
53
+ throw new Error(`${at} must be a non-empty name string`);
54
+ assertScriptEntryLength(el, at, "write-protected name", why);
55
+ return el;
56
+ }
57
+ if (typeof el !== "object" || el === null || Array.isArray(el))
58
+ throw new Error(`${at} must be a name string or an object { name, kind }`);
59
+ const o = el;
60
+ const name = o.name;
61
+ const kind = o.kind;
62
+ if (typeof name !== "string" || name.length === 0)
63
+ throw new Error(`${at}.name must be a non-empty string, e.g. ".npmrc" or ".config/app"`);
64
+ if (typeof kind !== "string")
65
+ throw new Error(`${at}.kind must be a string ("basename", "segment" or "segment-run")`);
66
+ assertScriptEntryLength(name, at, "write-protected name", why);
67
+ return { name, kind };
68
+ }
69
+ function complianceScriptEntry(el, at) {
70
+ if (typeof el !== "string")
71
+ throw new Error(`${at} must be a capability word (${COMPLIANCE_CAPABILITIES.join(", ")})`);
72
+ return el;
73
+ }
74
+ const READ_DENY_SCRIPT_LAW = Object.freeze({
75
+ atMost: MAX_SCRIPT_LIST_ENTRIES,
76
+ shape: 'deny entries (a "/"-separated segment run such as ".ssh", or { pattern, caseSensitive? })',
77
+ why: "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.",
78
+ entry: readDenyScriptEntry,
79
+ });
80
+ const WRITE_PROTECTED_SCRIPT_LAW = Object.freeze({
81
+ atMost: MAX_SCRIPT_LIST_ENTRIES,
82
+ shape: 'write-protected names (a literal name such as ".npmrc", a "/"-separated run such as ".config/app", or { name, kind })',
83
+ why: "Every row is judged against every write the child names, for the child's whole run; the deployment's own table is in force beside these.",
84
+ entry: writeProtectedScriptEntry,
85
+ });
86
+ const COMPLIANCE_SCRIPT_LAW = Object.freeze({
87
+ atMost: MAX_SCRIPT_LIST_ENTRIES,
88
+ shape: `capability words (${COMPLIANCE_CAPABILITIES.join(", ")})`,
89
+ why: "The capability set is closed; a longer list can only repeat it.",
90
+ entry: complianceScriptEntry,
91
+ });
92
+ export const CLAMP_SET = Object.freeze({
93
+ handsReadOnly: Object.freeze({ law: "restricting", value: true, script: true, carrier: "clamp" }),
94
+ interactiveTools: Object.freeze({ law: "restricting", value: false, script: true, carrier: "clamp" }),
95
+ approvalReach: Object.freeze({ law: "restricting", value: "none", script: true, carrier: "clamp" }),
96
+ readFace: Object.freeze({ law: "restricting", value: "roots", script: true, carrier: "clamp" }),
97
+ writeFace: Object.freeze({ law: "restricting", value: "roots", script: true, carrier: "clamp" }),
98
+ readDenyPatterns: Object.freeze({ law: "addOnly", identity: readDenyIdentity, entry: readDenyEntryProblem, script: READ_DENY_SCRIPT_LAW, deploymentLayer: "readDenyPatterns", carrier: "clamp" }),
99
+ writeProtectedAdditions: Object.freeze({ law: "addOnly", identity: writeProtectedEntryIdentity, entry: writeProtectedEntryProblem, script: WRITE_PROTECTED_SCRIPT_LAW, deploymentLayer: "writeProtectedPaths", carrier: "clamp" }),
100
+ complianceAdditionalDenies: Object.freeze({ law: "addOnly", identity: complianceIdentity, entry: complianceCapabilityProblem, script: COMPLIANCE_SCRIPT_LAW, deploymentLayer: "compliancePostureResolver", carrier: "clamp" }),
101
+ oneShot: Object.freeze({ law: "restricting", value: true, script: true, carrier: "specSeat" }),
102
+ memoryPersistenceCapable: Object.freeze({ law: "restricting", value: false, script: true, carrier: "specSeat" }),
103
+ fileHistory: Object.freeze({ law: "restricting", value: "disabled", script: false, carrier: "specSeat" }),
104
+ });
105
+ const ROWS = Object.freeze(Object.entries(CLAMP_SET));
106
+ export const CLAMP_SEATS = Object.freeze(ROWS.map(([seat]) => seat));
107
+ export const SCRIPT_SEATS = Object.freeze(ROWS.filter(([, row]) => row.script !== false).map(([seat]) => seat));
108
+ export function composeClampSeat(seat, a, b) {
109
+ const row = CLAMP_SET[seat];
110
+ if (row.law === "restricting")
111
+ return a === row.value || b === row.value ? row.value : (b ?? a);
112
+ const lists = [a, b];
113
+ return unionAddOnly(seat, ...lists);
114
+ }
115
+ function notAListSentence(owner, value) {
116
+ return `${owner} must be an array or absent (got ${value === null ? "null" : typeof value}) — a non-array here would be iterated character by character, so it refuses loudly instead.`;
117
+ }
118
+ export function unionAddOnly(seat, ...lists) {
119
+ const row = CLAMP_SET[seat];
120
+ const identity = row.identity;
121
+ const seen = new Set();
122
+ const out = [];
123
+ for (const list of lists) {
124
+ if (list === undefined)
125
+ continue;
126
+ if (!Array.isArray(list))
127
+ throw clampRecordError(notAListSentence(seat, list));
128
+ for (const e of list) {
129
+ if (row.entry(e, seat) !== undefined) {
130
+ out.push(e);
131
+ continue;
132
+ }
133
+ const key = identity(e);
134
+ if (!seen.has(key))
135
+ (seen.add(key), out.push(e));
136
+ }
137
+ }
138
+ return out;
139
+ }
140
+ export function assertAddOnlySeats(spec) {
141
+ for (const [seat, row] of ROWS) {
142
+ if (row.law !== "addOnly")
143
+ continue;
144
+ const value = spec[seat];
145
+ if (value === undefined)
146
+ continue;
147
+ const owner = `TaskSpec.${seat}`;
148
+ if (!Array.isArray(value))
149
+ throw clampRecordError(notAListSentence(owner, value));
150
+ const entries = value;
151
+ for (const e of entries) {
152
+ const problem = row.entry(e, owner);
153
+ if (problem !== undefined)
154
+ throw clampRecordError(problem);
155
+ }
156
+ }
157
+ }
158
+ export function loosensClampSeat(seat, base, override) {
159
+ const row = CLAMP_SET[seat];
160
+ return row.law === "restricting" && base === row.value && override !== undefined && override !== row.value;
161
+ }
162
+ function projected(seat, v) {
163
+ const row = CLAMP_SET[seat];
164
+ if (row.law === "restricting")
165
+ return v === row.value ? row.value : undefined;
166
+ return Array.isArray(v) && v.length > 0 ? Object.freeze(v.map((e) => (typeof e === "object" && e !== null ? { ...e } : e))) : undefined;
167
+ }
168
+ export function clampSourceOf(record, carrier) {
169
+ const r = (record ?? {});
170
+ return Object.fromEntries(ROWS.filter(([, row]) => carrier === undefined || row.carrier === carrier).map(([seat]) => [seat, r[seat]]));
171
+ }
172
+ export function foldClampSources(...records) {
173
+ return Object.fromEntries(CLAMP_SEATS.map((seat) => [seat, records.reduce((acc, rec) => composeClampSeat(seat, acc, rec?.[seat]), undefined)]));
174
+ }
175
+ export function clampSeatsOf(source, carrier) {
176
+ const out = {};
177
+ for (const [seat, row] of ROWS) {
178
+ if (carrier !== undefined && row.carrier !== carrier)
179
+ continue;
180
+ const v = projected(seat, source[seat]);
181
+ if (v !== undefined)
182
+ out[seat] = v;
183
+ }
184
+ return out;
185
+ }
186
+ export function clampRecordError(message) {
187
+ const e = new Error(message);
188
+ e.code = "config.invalid_argument";
189
+ return e;
190
+ }
191
+ export function assertClampRecord(record, owner, carrier, extra = []) {
192
+ if (record === undefined)
193
+ return;
194
+ if (record === null || typeof record !== "object")
195
+ throw clampRecordError(`${owner} must be a record of clamp seats, got ${record === null ? "null" : typeof record}`);
196
+ const legal = [...ROWS.filter(([, row]) => carrier === undefined || row.carrier === carrier).map(([seat]) => seat), ...extra];
197
+ const unknown = Object.keys(record).filter((k) => record[k] !== undefined && !legal.includes(k));
198
+ if (unknown.length > 0) {
199
+ throw clampRecordError(`${owner} names ${unknown.map((k) => JSON.stringify(k)).join(", ")}, which the clamp table does not carry there — the legal seats are ${legal.join(", ")}. Refused rather than ignored: a seat nobody reads would read to the caller as wired.`);
200
+ }
201
+ }
202
+ export function clampValuesOf(...records) {
203
+ return clampSeatsOf(foldClampSources(...records));
204
+ }
205
+ export function childClampSeats(source) {
206
+ return clampSeatsOf(source, "clamp");
207
+ }
2
208
  export const CHILD_CLAMP_SEATS_NOT_CARRIED = Object.freeze({
3
209
  toolPolicy: "not a clamp a child spec copies: a parent's denies reach its children through the ancestor-constraint chain the child's own prepare folds, not by putting the parent's policy object on the child seat",
4
210
  shellGate: "travels on the inherited-gate lane (`InheritedGate.shellGate`, a trusted internals seat), not on the child spec — a spec-level copy would be a second source for the same clamp",
5
211
  permissionMode: "travels on the inherited-gate lane (`InheritedGate.permissionMode` / `permissionModeCeiling` — the parent's declared word and its LIVE seat): a child with no word of its own inherits that ceiling on every read, and a word it does declare is clamped under it; a spec-level copy would freeze the parent's word at spawn and be a second source for the same clamp",
6
212
  onAsk: "per-lane by construction: the delegation lane wraps the parent's approver with spawn provenance before it becomes the child's seat, and a lane with no approver must hand down none (a parent that declared nobody can be asked hands down no approver — its frozen seat is empty — and the declaration rides `approvalReach`)",
7
213
  hooks: "a deployment seat, not an inherited clamp — `tightenTaskSpec` refuses to merge two hook sets rather than composing them, so there is no tightening value to carry",
8
- excludeTools: "roster control rather than containment: the lanes that copy a parent's roster do so beside these seats, and the workflow lane authors its child roster from the governance baseline instead of the host's",
9
- deferTools: "roster control, same reading as `excludeTools` above",
214
+ allowTools: "the tool selector's own layer — a parent bounds its children through the selector's ceiling (`RunInternals.toolCeiling`, a trusted internals seat every engine lane fills), not by copying its own list onto the child seat, which would be a second source for the same bound",
215
+ excludeTools: "the deny half of the same layer as `allowTools` above, same reading: the parent's reaches its children through the ceiling",
216
+ deferTools: "roster disclosure control rather than containment: the lanes that copy it do so beside these seats, and the workflow lane authors its child roster from the governance baseline instead of the host's",
10
217
  });
11
218
  export const ENGINE_CHILD_SPEC_CONSTRUCTORS = Object.freeze([
12
219
  "src/agents/subagent.ts#buildChildSpec",
13
220
  "src/agents/subagent.ts#observerSpec",
14
221
  "src/agents/subagent.ts#resumeSpec",
15
- "src/agents/teacher.ts#inheritedDeploymentConfig",
16
222
  "src/agents/verify.ts#verifierSpec",
17
223
  "src/agents/verify.ts#fixLegSpec",
18
224
  "src/orchestration/workflow-primitives.ts#workflowChildClamps",
19
225
  ]);
20
- export function childClampSeats(source) {
21
- return {
22
- ...(source.handsReadOnly === true ? { handsReadOnly: true } : {}),
23
- ...(source.interactiveTools === false ? { interactiveTools: false } : {}),
24
- ...(source.approvalReach === "none" ? { approvalReach: "none" } : {}),
25
- ...(source.readFace === "roots" ? { readFace: "roots" } : {}),
26
- ...(source.writeFace === "roots" ? { writeFace: "roots" } : {}),
27
- ...(source.readDenyPatterns !== undefined && source.readDenyPatterns.length > 0
28
- ? { readDenyPatterns: [...source.readDenyPatterns] }
29
- : {}),
30
- };
31
- }
32
226
  export function postureUnderClamps(posture, clamps) {
33
227
  return posture === "interactive" && (clamps.interactiveTools === false || clamps.approvalReach === "none") ? "headless" : posture;
34
228
  }
35
229
  export function engineHeadlessLegSeats() {
36
- return { interactiveTools: false, interactionPosture: "headless" };
230
+ return { interactiveTools: false, approvalReach: "none", interactionPosture: "headless" };
37
231
  }
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import { type AutoModeClassifierRound, type AutoModeDenialTracker, type AutoModeFallbackCause, type UnarmedDenialLimitFallback } from "./auto-mode.js";
19
19
  import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "./tool-policy.js";
20
+ import type { Settlement } from "./gate-outcome.js";
20
21
  /** Where a classification that did not rule sent the call: `asked` = on to the approval seat, `denied` = refused. */
21
22
  export type ClassifierUnavailableDisposition = "asked" | "denied";
22
23
  /** What the stations' observer receives — the facts the `classifier.unavailable` notice is composed from. `cause` is why
@@ -71,6 +72,9 @@ export declare function classifierNoRulingArm<A extends Extract<PermissionResult
71
72
  export declare function settleNoRulingAsk(opts: {
72
73
  ask: PermissionResult;
73
74
  mintedHere: boolean;
74
- resolved: Pick<ResolvedAsk, "action" | "settlement">;
75
+ resolved: {
76
+ action: ResolvedAsk["action"];
77
+ settlement?: Settlement;
78
+ };
75
79
  tracker: AutoModeDenialTracker | undefined;
76
80
  }): UnarmedDenialLimitFallback | undefined;
@@ -1,5 +1,5 @@
1
1
  import { classifierNoRulingAskMessage, classifierUnavailableDenyMessage } from "./auto-mode.js";
2
- import { attestClassifierDenyCause, carryEngineAttestations } from "./tool-policy.js";
2
+ import { attest } from "./tool-policy.js";
3
3
  export function classifierNoRulingArm(args) {
4
4
  const { ask, req, cause } = args;
5
5
  const seated = args.seat?.approvalSeat === true;
@@ -11,11 +11,11 @@ export function classifierNoRulingArm(args) {
11
11
  }
12
12
  }
13
13
  if (seated)
14
- return { kind: "asked", ask: carryEngineAttestations(ask, { ...ask, message: classifierNoRulingAskMessage(ask.message ?? `approval required for "${req.toolName}"`, cause), requiresRealApproval: true, classifierNoRuling: cause }) };
14
+ return { kind: "asked", ask: { ...ask, message: classifierNoRulingAskMessage(ask.message ?? `approval required for "${req.toolName}"`, cause), requiresRealApproval: true, classifierNoRuling: cause } };
15
15
  if (cause === "parse_error")
16
16
  return { kind: "counted" };
17
17
  const deny = { action: "deny", message: classifierUnavailableDenyMessage(req.toolName, cause, args.attribution), decisionReason: "classifier" };
18
- return { kind: "denied", deny: attestClassifierDenyCause(deny, "unavailable", req) };
18
+ return { kind: "denied", deny: attest(deny, req, { classifierCause: "unavailable" }) };
19
19
  }
20
20
  export function settleNoRulingAsk(opts) {
21
21
  const { ask, resolved } = opts;