@sema-agent/core 7.51.2 → 7.53.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 (446) hide show
  1. package/CHANGELOG.md +698 -2
  2. package/README.md +3 -1
  3. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  4. package/dist/agents/cascade.js +4 -0
  5. package/dist/agents/cross-session-envelope.d.ts +8 -0
  6. package/dist/agents/cross-session-envelope.js +6 -0
  7. package/dist/agents/cross-session-judge.d.ts +21 -1
  8. package/dist/agents/cross-session-judge.js +8 -0
  9. package/dist/agents/cross-session-ref.d.ts +5 -0
  10. package/dist/agents/cross-session-ref.js +1 -0
  11. package/dist/agents/cumulative-stats.d.ts +3 -0
  12. package/dist/agents/cumulative-stats.js +3 -0
  13. package/dist/agents/list-agents-tool.d.ts +1 -1
  14. package/dist/agents/org-delivery-gate.d.ts +122 -0
  15. package/dist/agents/org-delivery-gate.js +69 -0
  16. package/dist/agents/peer-held-queue.d.ts +9 -4
  17. package/dist/agents/peer-held-queue.js +6 -5
  18. package/dist/agents/peer-session-drain.d.ts +35 -5
  19. package/dist/agents/peer-session-drain.js +271 -180
  20. package/dist/agents/read-inbox-tool.d.ts +8 -1
  21. package/dist/agents/read-inbox-tool.js +5 -1
  22. package/dist/agents/repair-loop.js +4 -0
  23. package/dist/agents/send-message-tool.d.ts +11 -16
  24. package/dist/agents/send-message-tool.js +11 -13
  25. package/dist/agents/subagent.d.ts +3 -0
  26. package/dist/agents/subagent.js +105 -76
  27. package/dist/agents/tool-filter.d.ts +58 -13
  28. package/dist/agents/tool-filter.js +34 -14
  29. package/dist/bench/metrics.d.ts +1 -0
  30. package/dist/brain/anthropic.d.ts +6 -1
  31. package/dist/brain/anthropic.js +17 -13
  32. package/dist/brain/model-presets.d.ts +4 -5
  33. package/dist/brain/model-presets.js +6 -5
  34. package/dist/brain/open-responses.js +16 -12
  35. package/dist/brain/openai.js +16 -12
  36. package/dist/brain/request-params.d.ts +12 -33
  37. package/dist/brain/request-params.js +5 -2
  38. package/dist/brain/request-route.d.ts +9 -8
  39. package/dist/brain/request-route.js +1 -0
  40. package/dist/brain/route-adjudicator.d.ts +123 -47
  41. package/dist/brain/route-adjudicator.js +171 -42
  42. package/dist/brain/route-conformance.js +2 -2
  43. package/dist/brain/routing.d.ts +24 -1
  44. package/dist/brain/routing.js +54 -19
  45. package/dist/brain/status-sink.d.ts +18 -0
  46. package/dist/brain/status-sink.js +7 -0
  47. package/dist/brain/timeout.js +5 -4
  48. package/dist/core/a2a.d.ts +5 -2
  49. package/dist/core/a2a.js +30 -13
  50. package/dist/core/allow-entry.d.ts +42 -9
  51. package/dist/core/allow-entry.js +25 -18
  52. package/dist/core/auto-compaction.d.ts +80 -20
  53. package/dist/core/auto-compaction.js +65 -18
  54. package/dist/core/auto-promote.d.ts +2 -1
  55. package/dist/core/auto-promote.js +2 -2
  56. package/dist/core/caller-tool-name.d.ts +9 -0
  57. package/dist/core/caller-tool-name.js +13 -0
  58. package/dist/core/checkpoint-requirements.d.ts +7 -1
  59. package/dist/core/checkpoint-requirements.js +2 -0
  60. package/dist/core/checkpoint-store.d.ts +57 -24
  61. package/dist/core/checkpoint-store.js +3 -3
  62. package/dist/core/child-clamp-seats.d.ts +6 -0
  63. package/dist/core/child-clamp-seats.js +2 -1
  64. package/dist/core/compliance.js +3 -1
  65. package/dist/core/credential-vocabulary.d.ts +33 -8
  66. package/dist/core/credential-vocabulary.js +32 -7
  67. package/dist/core/decision-receipt.d.ts +2 -2
  68. package/dist/core/delegation-frames.d.ts +9 -2
  69. package/dist/core/delegation-name.d.ts +18 -0
  70. package/dist/core/delegation-name.js +47 -0
  71. package/dist/core/effective-path-target.d.ts +25 -6
  72. package/dist/core/effective-path-target.js +24 -2
  73. package/dist/core/engine-capabilities.d.ts +8 -1
  74. package/dist/core/engine-capabilities.js +1 -1
  75. package/dist/core/engine-notice.d.ts +49 -21
  76. package/dist/core/frontmatter-fence.d.ts +10 -0
  77. package/dist/core/frontmatter-fence.js +6 -0
  78. package/dist/core/gate-fold.js +8 -25
  79. package/dist/core/gate-lanes.js +358 -274
  80. package/dist/core/gate-outcome.d.ts +11 -6
  81. package/dist/core/governance-codes.d.ts +11 -4
  82. package/dist/core/governance-codes.js +12 -3
  83. package/dist/core/hands-band-screen.d.ts +7 -0
  84. package/dist/core/hands-band-screen.js +32 -0
  85. package/dist/core/hooks.d.ts +283 -739
  86. package/dist/core/hooks.js +100 -193
  87. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  88. package/dist/{tools/fs → core}/image-admission.js +24 -6
  89. package/dist/core/locked-config.d.ts +84 -32
  90. package/dist/core/locked-config.js +128 -42
  91. package/dist/core/mcp-connection-pool.d.ts +4 -1
  92. package/dist/core/mcp-connection-pool.js +7 -2
  93. package/dist/core/mcp-probe.d.ts +12 -9
  94. package/dist/core/mcp-probe.js +3 -3
  95. package/dist/core/mcp-server-spec.d.ts +104 -10
  96. package/dist/core/mcp-server-spec.js +183 -33
  97. package/dist/core/mcp.d.ts +31 -20
  98. package/dist/core/mcp.js +66 -56
  99. package/dist/core/memory-engine/data-plane.js +5 -1
  100. package/dist/core/memory-engine/distiller.js +16 -2
  101. package/dist/core/memory-engine/engine.d.ts +22 -30
  102. package/dist/core/memory-engine/engine.js +16 -10
  103. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  104. package/dist/core/memory-engine/frontmatter.js +19 -16
  105. package/dist/core/memory.d.ts +2 -2
  106. package/dist/core/mode-policy.d.ts +5 -16
  107. package/dist/core/mode-policy.js +7 -19
  108. package/dist/core/model-seat.d.ts +4 -1
  109. package/dist/core/mods/dollar.d.ts +109 -0
  110. package/dist/core/mods/dollar.js +154 -0
  111. package/dist/core/mods/host.d.ts +23 -0
  112. package/dist/core/mods/host.js +21 -0
  113. package/dist/core/mods/kernel/budget.d.ts +43 -0
  114. package/dist/core/mods/kernel/budget.js +83 -0
  115. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  116. package/dist/core/mods/kernel/dispatch.js +699 -0
  117. package/dist/core/mods/kernel/events.d.ts +245 -0
  118. package/dist/core/mods/kernel/events.js +210 -0
  119. package/dist/core/mods/kernel/index.d.ts +6 -0
  120. package/dist/core/mods/kernel/index.js +5 -0
  121. package/dist/core/mods/kernel/receive.d.ts +94 -0
  122. package/dist/core/mods/kernel/receive.js +188 -0
  123. package/dist/core/mods/kernel/registration.d.ts +131 -0
  124. package/dist/core/mods/kernel/registration.js +102 -0
  125. package/dist/core/mods/kernel/site-rules.d.ts +149 -0
  126. package/dist/core/mods/kernel/site-rules.js +296 -0
  127. package/dist/core/mods/stations.d.ts +344 -0
  128. package/dist/core/mods/stations.js +437 -0
  129. package/dist/core/mounted-mcp.d.ts +57 -0
  130. package/dist/core/mounted-mcp.js +71 -2
  131. package/dist/core/own-property-receipt.d.ts +13 -0
  132. package/dist/core/own-property-receipt.js +13 -23
  133. package/dist/core/parent-spec-seat.d.ts +18 -7
  134. package/dist/core/parent-spec-seat.js +6 -2
  135. package/dist/core/path-identity.js +2 -1
  136. package/dist/core/permission-rule-model.d.ts +58 -9
  137. package/dist/core/permission-rule-model.js +81 -7
  138. package/dist/core/permission-rule-org.d.ts +163 -33
  139. package/dist/core/permission-rule-org.js +205 -71
  140. package/dist/core/permission-rule-syntax.d.ts +15 -0
  141. package/dist/core/permission-rule-syntax.js +24 -16
  142. package/dist/core/permission-rules.d.ts +14 -2
  143. package/dist/core/permission-rules.js +63 -23
  144. package/dist/core/prompt-section-seat.d.ts +15 -27
  145. package/dist/core/prompt-section-seat.js +73 -40
  146. package/dist/core/protocol-http-auth.d.ts +3 -1
  147. package/dist/core/protocol-http-auth.js +2 -0
  148. package/dist/core/reminder-mint.d.ts +2 -2
  149. package/dist/core/remote-env.d.ts +24 -12
  150. package/dist/core/remote-env.js +1 -0
  151. package/dist/core/resume-startup-cause.d.ts +16 -1
  152. package/dist/core/resume-startup-cause.js +4 -1
  153. package/dist/core/retention.js +7 -2
  154. package/dist/core/retired-keys.d.ts +12 -2
  155. package/dist/core/retired-keys.js +15 -1
  156. package/dist/core/roles.js +60 -10
  157. package/dist/core/rule-lane-reads.js +1 -1
  158. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  159. package/dist/core/runner/announce-once-ledger.js +22 -0
  160. package/dist/core/runner/assemble-result.d.ts +9 -0
  161. package/dist/core/runner/assemble-result.js +3 -1
  162. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  163. package/dist/core/runner/call-hook-stations.js +58 -42
  164. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  165. package/dist/core/runner/caller-stop-gate.js +7 -0
  166. package/dist/core/runner/compaction-seams.d.ts +8 -22
  167. package/dist/core/runner/compaction-seams.js +28 -53
  168. package/dist/core/runner/construction-doors.js +11 -1
  169. package/dist/core/runner/contracts.d.ts +86 -83
  170. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  171. package/dist/core/runner/credential-origin-seat.js +19 -0
  172. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  173. package/dist/core/runner/gate-exit.d.ts +47 -36
  174. package/dist/core/runner/gate-exit.js +12 -5
  175. package/dist/core/runner/image.js +1 -2
  176. package/dist/core/runner/inline-image.js +1 -1
  177. package/dist/core/runner/mcp-redial.d.ts +52 -10
  178. package/dist/core/runner/mcp-redial.js +38 -9
  179. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  180. package/dist/core/runner/notice-seat-input.js +1 -0
  181. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  182. package/dist/core/runner/permission-rule-lanes.js +22 -10
  183. package/dist/core/runner/person-path-rows.d.ts +3 -1
  184. package/dist/core/runner/person-path-rows.js +3 -2
  185. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  186. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  187. package/dist/core/runner/prepare-ask-lane.js +6 -15
  188. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  189. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  190. package/dist/core/runner/prepare-config-doors.d.ts +52 -1
  191. package/dist/core/runner/prepare-config-doors.js +168 -143
  192. package/dist/core/runner/prepare-defer-classify.js +7 -11
  193. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  194. package/dist/core/runner/prepare-delegation-surface.js +7 -5
  195. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  196. package/dist/core/runner/prepare-gate-stations.js +11 -10
  197. package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
  198. package/dist/core/runner/prepare-hands-readface.js +2 -1
  199. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  200. package/dist/core/runner/prepare-inherited-gate.js +10 -23
  201. package/dist/core/runner/prepare-listings.d.ts +1 -1
  202. package/dist/core/runner/prepare-listings.js +4 -2
  203. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  204. package/dist/core/runner/prepare-memory-engine-session.js +20 -7
  205. package/dist/core/runner/prepare-memory.d.ts +3 -2
  206. package/dist/core/runner/prepare-memory.js +6 -2
  207. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  208. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  209. package/dist/core/runner/prepare-park-ask.js +10 -14
  210. package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
  211. package/dist/core/runner/prepare-policy-chain.js +104 -109
  212. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  213. package/dist/core/runner/prepare-project-context.js +11 -12
  214. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  215. package/dist/core/runner/prepare-prompt-assembly.js +138 -101
  216. package/dist/core/runner/prepare-prompt-inputs.d.ts +28 -23
  217. package/dist/core/runner/prepare-prompt-inputs.js +11 -10
  218. package/dist/core/runner/prepare-protocol-tools.d.ts +11 -7
  219. package/dist/core/runner/prepare-protocol-tools.js +20 -13
  220. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  221. package/dist/core/runner/prepare-question-face.js +4 -3
  222. package/dist/core/runner/prepare-safety-scan.js +6 -10
  223. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  224. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  225. package/dist/core/runner/prepare-task.js +41 -23
  226. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  227. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  228. package/dist/core/runner/prepare-wiring-manifest.d.ts +13 -9
  229. package/dist/core/runner/prepare-wiring-manifest.js +14 -11
  230. package/dist/core/runner/resume-admission.d.ts +4 -1
  231. package/dist/core/runner/resume-admission.js +7 -5
  232. package/dist/core/runner/resume-apply.d.ts +5 -2
  233. package/dist/core/runner/resume-apply.js +24 -42
  234. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  235. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  236. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  237. package/dist/core/runner/resume-internals-and-config.js +3 -8
  238. package/dist/core/runner/resume-preflight.js +38 -16
  239. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  240. package/dist/core/runner/retired-runner-deps.js +4 -5
  241. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  242. package/dist/core/runner/run-brain-sinks.js +5 -1
  243. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  244. package/dist/core/runner/run-compaction-machinery.js +7 -33
  245. package/dist/core/runner/run-harness-handlers.js +4 -2
  246. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  247. package/dist/core/runner/run-identity-wiring.js +3 -2
  248. package/dist/core/runner/run-leg.js +103 -95
  249. package/dist/core/runner/run-notification-lane.js +1 -0
  250. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  251. package/dist/core/runner/run-recovery-lanes.js +14 -11
  252. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  253. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  254. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  255. package/dist/core/runner/run-terminal-adoption.js +34 -22
  256. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  257. package/dist/core/runner/run-turn-boundary.js +32 -37
  258. package/dist/core/runner/runtask.d.ts +6 -7
  259. package/dist/core/runner/runtask.js +15 -73
  260. package/dist/core/runner/session-rule-policy.d.ts +5 -5
  261. package/dist/core/runner/session-rule-policy.js +13 -8
  262. package/dist/core/runner/side-call-account.d.ts +68 -0
  263. package/dist/core/runner/side-call-account.js +61 -0
  264. package/dist/core/runner/skills-seat.d.ts +15 -0
  265. package/dist/core/runner/skills-seat.js +57 -0
  266. package/dist/core/runner/stream-halt-verbs.js +12 -17
  267. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  268. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  269. package/dist/core/runner/stream-steer-verb.js +20 -38
  270. package/dist/core/runner/sub-agent-deny-lists.d.ts +124 -23
  271. package/dist/core/runner/sub-agent-deny-lists.js +230 -71
  272. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  273. package/dist/core/runner/synthetic-tools.js +2 -12
  274. package/dist/core/runner/tool-end-body.d.ts +5 -6
  275. package/dist/core/runner/tool-end-body.js +6 -4
  276. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  277. package/dist/core/runner/tool-not-executed.js +30 -0
  278. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  279. package/dist/core/runner/tool-occurrence.js +5 -5
  280. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  281. package/dist/core/runner-deps.d.ts +43 -36
  282. package/dist/core/safety-merge-corpus.js +18 -2
  283. package/dist/core/secret-env.d.ts +88 -20
  284. package/dist/core/secret-env.js +192 -38
  285. package/dist/core/session-policy-store.d.ts +71 -16
  286. package/dist/core/session-policy-store.js +138 -28
  287. package/dist/core/session-reconcile.d.ts +4 -0
  288. package/dist/core/session-reconcile.js +2 -1
  289. package/dist/core/shell-read-silence.js +3 -32
  290. package/dist/core/side-query.d.ts +5 -3
  291. package/dist/core/skill-grant.d.ts +3 -2
  292. package/dist/core/skill-grant.js +17 -9
  293. package/dist/core/skills-directory.d.ts +31 -11
  294. package/dist/core/skills-directory.js +655 -104
  295. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  296. package/dist/core/task-event.d.ts +49 -3
  297. package/dist/core/task-notification.js +2 -2
  298. package/dist/core/task-result.d.ts +8 -0
  299. package/dist/core/task-spec.d.ts +20 -19
  300. package/dist/core/task-stream.d.ts +14 -4
  301. package/dist/core/tighten-task-spec.d.ts +4 -3
  302. package/dist/core/tighten-task-spec.js +2 -4
  303. package/dist/core/tool-check-reading.d.ts +74 -0
  304. package/dist/core/tool-check-reading.js +80 -0
  305. package/dist/core/tool-policy.d.ts +62 -18
  306. package/dist/core/tool-policy.js +86 -15
  307. package/dist/core/tool-registry.d.ts +20 -0
  308. package/dist/core/tool-registry.js +4 -0
  309. package/dist/core/tool-spec.d.ts +10 -6
  310. package/dist/core/tools.js +2 -0
  311. package/dist/core/trace.d.ts +51 -32
  312. package/dist/core/types.d.ts +2 -2
  313. package/dist/core/types.js +1 -1
  314. package/dist/core/unc-spelling.d.ts +10 -0
  315. package/dist/core/unc-spelling.js +3 -0
  316. package/dist/core/untrusted-egress.d.ts +8 -0
  317. package/dist/core/untrusted-egress.js +4 -1
  318. package/dist/core/untrusted-text.d.ts +16 -0
  319. package/dist/core/untrusted-text.js +7 -2
  320. package/dist/core/user-attachment.d.ts +25 -4
  321. package/dist/core/user-attachment.js +63 -42
  322. package/dist/core/wiring-manifest.d.ts +18 -15
  323. package/dist/core/wiring-manifest.js +2 -2
  324. package/dist/engine/compaction/utils.js +1 -2
  325. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  326. package/dist/engine/execution-env/symlink-chain.js +1 -1
  327. package/dist/engine/harness/agent-harness.d.ts +1 -1
  328. package/dist/engine/harness/agent-harness.js +5 -4
  329. package/dist/engine/harness/types.d.ts +20 -16
  330. package/dist/engine/harness/types.js +7 -1
  331. package/dist/engine/llm/types.d.ts +12 -7
  332. package/dist/engine/loop/agent-loop.d.ts +12 -1
  333. package/dist/engine/loop/agent-loop.js +18 -6
  334. package/dist/engine/loop/types.d.ts +8 -2
  335. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  336. package/dist/engine/session/import-validate.js +3 -10
  337. package/dist/engine/session/session.d.ts +4 -4
  338. package/dist/engine/session/session.js +4 -4
  339. package/dist/index.d.ts +33 -23
  340. package/dist/index.js +23 -15
  341. package/dist/internal/harness.d.ts +2 -1
  342. package/dist/internal/harness.js +2 -1
  343. package/dist/orchestration/goal.d.ts +24 -1
  344. package/dist/orchestration/goal.js +3 -2
  345. package/dist/orchestration/run-spec.d.ts +4 -6
  346. package/dist/orchestration/run-spec.js +39 -63
  347. package/dist/orchestration/run-workflow-tool.js +1 -2
  348. package/dist/orchestration/workflow.d.ts +11 -3
  349. package/dist/orchestration/workflow.js +11 -2
  350. package/dist/prompt-assembly/artifact-store.d.ts +72 -56
  351. package/dist/prompt-assembly/artifact-store.js +60 -52
  352. package/dist/prompt-assembly/artifact.d.ts +90 -76
  353. package/dist/prompt-assembly/artifact.js +197 -145
  354. package/dist/prompt-assembly/assemble.d.ts +36 -29
  355. package/dist/prompt-assembly/assemble.js +34 -220
  356. package/dist/prompt-assembly/bands.d.ts +20 -0
  357. package/dist/prompt-assembly/bands.js +18 -0
  358. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  359. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  360. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  361. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  362. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  363. package/dist/prompt-assembly/catalog/index.js +60 -0
  364. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  365. package/dist/prompt-assembly/catalog/memory.js +6 -0
  366. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  367. package/dist/prompt-assembly/catalog/modes.js +137 -0
  368. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  369. package/dist/prompt-assembly/catalog/role.js +157 -0
  370. package/dist/prompt-assembly/catalog/schema.d.ts +138 -0
  371. package/dist/prompt-assembly/catalog/schema.js +25 -0
  372. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  373. package/dist/prompt-assembly/catalog/sections.js +98 -0
  374. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  375. package/dist/prompt-assembly/catalog/team.js +258 -0
  376. package/dist/prompt-assembly/composer.d.ts +26 -28
  377. package/dist/prompt-assembly/composer.js +124 -46
  378. package/dist/prompt-assembly/epoch.d.ts +89 -79
  379. package/dist/prompt-assembly/epoch.js +115 -142
  380. package/dist/prompt-assembly/explain.d.ts +58 -34
  381. package/dist/prompt-assembly/explain.js +21 -24
  382. package/dist/prompt-assembly/overlay.d.ts +137 -0
  383. package/dist/prompt-assembly/overlay.js +339 -0
  384. package/dist/prompt-assembly/renderers.d.ts +21 -0
  385. package/dist/prompt-assembly/renderers.js +39 -0
  386. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  387. package/dist/prompt-assembly/section-usage.js +1 -1
  388. package/dist/prompt-assembly/select.d.ts +71 -0
  389. package/dist/prompt-assembly/select.js +106 -0
  390. package/dist/prompt-assembly/sugar.d.ts +31 -0
  391. package/dist/prompt-assembly/sugar.js +20 -0
  392. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  393. package/dist/prompt-assembly/types.d.ts +45 -148
  394. package/dist/prompts/coordinator.d.ts +2 -21
  395. package/dist/prompts/coordinator.js +3 -255
  396. package/dist/prompts/cowork.d.ts +27 -16
  397. package/dist/prompts/cowork.js +2 -23
  398. package/dist/prompts/default.d.ts +38 -511
  399. package/dist/prompts/default.js +20 -288
  400. package/dist/prompts/supervisor.d.ts +6 -71
  401. package/dist/prompts/supervisor.js +6 -117
  402. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  403. package/dist/stores/file/permission-rule-store.js +2 -1
  404. package/dist/tools/artifact/artifact-tool.js +4 -3
  405. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  406. package/dist/tools/fs/dir-entries.d.ts +4 -2
  407. package/dist/tools/fs/dir-entries.js +16 -4
  408. package/dist/tools/fs/fs-bash.d.ts +1 -1
  409. package/dist/tools/fs/fs-bash.js +22 -11
  410. package/dist/tools/fs/fs-pdf.js +17 -13
  411. package/dist/tools/fs/fs-read.js +4 -3
  412. package/dist/tools/fs/fs-shared.d.ts +1 -10
  413. package/dist/tools/fs/fs-shared.js +3 -4
  414. package/dist/tools/fs/fs-write.js +2 -1
  415. package/dist/tools/fs/notebook.js +1 -1
  416. package/dist/tools/fs/pdf.d.ts +20 -10
  417. package/dist/tools/fs/pdf.js +19 -10
  418. package/dist/tools/fs/program-read-model.d.ts +68 -8
  419. package/dist/tools/fs/program-read-model.js +112 -33
  420. package/dist/tools/fs/program-read-model.rows.js +30 -10
  421. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  422. package/dist/tools/fs/read-deny-home.js +28 -27
  423. package/dist/tools/fs/read-deny.d.ts +41 -11
  424. package/dist/tools/fs/read-deny.js +51 -5
  425. package/dist/tools/fs/safety.d.ts +4 -26
  426. package/dist/tools/fs/safety.js +10 -32
  427. package/dist/tools/fs/search.js +15 -10
  428. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  429. package/dist/tools/fs/shell-read-argv.js +118 -38
  430. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  431. package/dist/tools/fs/shell-read-establish.js +11 -61
  432. package/dist/tools/fs/shell-read-identity.js +6 -3
  433. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  434. package/dist/tools/fs/shell-read-judge.js +18 -4
  435. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  436. package/dist/tools/web.js +1 -1
  437. package/package.json +13 -1
  438. package/test/export-surface.snapshot.json +306 -103
  439. package/wire-changes/core@7.52.0.json +5859 -0
  440. package/wire-changes/core@7.53.0.json +1946 -0
  441. package/dist/core/hook-seats.d.ts +0 -66
  442. package/dist/core/hook-seats.js +0 -37
  443. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  444. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  445. package/dist/prompts/simple-sections.d.ts +0 -58
  446. package/dist/prompts/simple-sections.js +0 -43
@@ -100,9 +100,10 @@ export async function runGoal(runner, spec) {
100
100
  verificationKind,
101
101
  accepted: false,
102
102
  cumulativeTokens,
103
- checkpointToken: over?.checkpointToken,
103
+ checkpointToken: over?.paused?.token,
104
104
  errorCode: over?.errorCode,
105
105
  ...(status === "budget" && over?.budgetCause !== undefined ? { budgetCause: over.budgetCause } : {}),
106
+ ...(status === "suspended" && over?.paused !== undefined ? { suspendGate: over.paused.gate } : {}),
106
107
  };
107
108
  if (verificationKind === "mechanical" && status !== "suspended" && status !== "needs_review") {
108
109
  runner.emitTaskOutcome?.({
@@ -145,7 +146,7 @@ export async function runGoal(runner, spec) {
145
146
  spentCostMicroUsd += (result.stats.costMicroUsd ?? 0) + (result.stats.nested?.costMicroUsd ?? 0);
146
147
  spentTurns += (result.stats.turns ?? 0) + (result.stats.nested?.turns ?? 0);
147
148
  if (isDurablePause(result.terminal)) {
148
- return mk(pauseFamily(result.terminal), iteration, { result, checkpointToken: result.terminal.token });
149
+ return mk(pauseFamily(result.terminal), iteration, { result, paused: result.terminal });
149
150
  }
150
151
  const midStop = classifyStop();
151
152
  if (midStop)
@@ -8,10 +8,8 @@
8
8
  * (green→`spec.not_red`、error→`spec.oracle_error`,均 fail-loud);捕获 baseline 计数。
9
9
  * 2. frozen deny policy 经 {@link combinePolicies} 合入部署基线(deny 短路不可被顶);绝不裸赋顶掉
10
10
  * `taskSpec.toolPolicy`(TRAP #1)。
11
- * 3. Hooks 多路复用:runSpec 的 stop gate 先跑(guard-restore → oracle 判)——red ⇒ block 短路(失败
12
- * 尾部经 `delimitUntrusted` 围栏后置入:oracle 输出是模型可影响面);green ⇒ **链式调用**用户 stop
13
- * (不吞其否决权);error ⇒ block 一次并注明 oracle 基础设施故障,**连续 2 次 error 放弃把关**走终态
14
- * 判定(防 oracle 自坏死循环)。其它 hook 槽原样透传。
11
+ * 3. stop gate = 任务座位上的一条注册(在调用方注册之前):red ⇒ block(失败尾部经 `delimitUntrusted` 围栏);green ⇒
12
+ * `next(e)` 交下游;error ⇒ block 一次,**连续 2 次 error 放弃把关**走终态判定。
15
13
  * 4. 收口:终态亲跑 oracle = 最终判定;`emitTaskOutcome`(mechanical):`oracleHadRedRun` = 任一
16
14
  * 「真跑过且判 red」的观察(preflight ∨ stop-gate ∨ 终态;error 永不置位)。durable pause
17
15
  * (suspended/needs_review)非终态,不发射(同 goal.ts 先例:无半事实、resume 不重复计数)。
@@ -34,8 +32,8 @@ import { type OracleBaseline, type OracleGateResult, type OracleVerdict, type Sp
34
32
  export interface RunSpecOptions {
35
33
  /** Workcopy root — the containment root for frozenPaths, oracle cwd, and `spec.path` resolution. */
36
34
  rootDir: string;
37
- /** Per-run base spec (model/tools/toolPolicy/hooks/limits/…). `objective` is owned by runSpec (the
38
- * spec framing); `toolPolicy` and `hooks` are COMPOSED with runSpec's, never replaced. */
35
+ /** Per-run base spec (model/tools/toolPolicy/mods/limits/…). `objective` is owned by runSpec (the
36
+ * spec framing); `toolPolicy` and `mods` are COMPOSED with runSpec's, never replaced. */
39
37
  taskSpec: Omit<TaskSpec, "objective">;
40
38
  /** Receives the oracle gates' once-per-process `config.secret_env_scrubbed` notice (`runOracle`'s `onNotice`);
41
39
  * absent ⇒ the console line. */
@@ -9,6 +9,8 @@ import { writeTargetPath } from "../tools/fs/safety.js";
9
9
  import { callTargetViewsOf } from "../core/effective-path-target.js";
10
10
  import { captureBaseline, resolveFrozenPaths, restoreFrozenPaths, runOracle, snapshotFrozenPaths, specError, } from "../core/spec-contract.js";
11
11
  import { isProtectedWrite } from "../core/tool-registry.js";
12
+ const RUN_SPEC_ORACLE_GATE = "run-spec-oracle-gate";
13
+ const RUN_SPEC_ORACLE_GATE_BUDGET_MS = 600_000;
12
14
  const CASE_INSENSITIVE_FS = process.platform === "darwin" || process.platform === "win32";
13
15
  const pathKey = (p) => {
14
16
  let n = p.replace(/\\/g, "/");
@@ -100,81 +102,55 @@ export async function runSpec(runner, contract, opts) {
100
102
  const frozenPolicy = frozenDenyPolicy(rootDir, frozenResolved);
101
103
  const policies = [deployBaseline?.toolPolicy, opts.taskSpec.toolPolicy, frozenPolicy].filter((p) => p !== undefined);
102
104
  const toolPolicy = policies.length === 1 ? policies[0] : combinePolicies(...policies);
103
- const userHooks = opts.taskSpec.hooks && deployBaseline?.hooks
104
- ? {
105
- preToolUse: (opts.taskSpec.hooks.preToolUse ?? deployBaseline.hooks.preToolUse)?.bind(opts.taskSpec.hooks.preToolUse ? opts.taskSpec.hooks : deployBaseline.hooks),
106
- ...((opts.taskSpec.hooks.preToolUse ? opts.taskSpec.hooks : deployBaseline.hooks).preToolUseObservational === true
107
- ? { preToolUseObservational: true }
108
- : {}),
109
- postToolUse: (opts.taskSpec.hooks.postToolUse ?? deployBaseline.hooks.postToolUse)?.bind(opts.taskSpec.hooks.postToolUse ? opts.taskSpec.hooks : deployBaseline.hooks),
110
- userPromptSubmit: (opts.taskSpec.hooks.userPromptSubmit ?? deployBaseline.hooks.userPromptSubmit)?.bind(opts.taskSpec.hooks.userPromptSubmit ? opts.taskSpec.hooks : deployBaseline.hooks),
111
- stop: (opts.taskSpec.hooks.stop ?? deployBaseline.hooks.stop)?.bind(opts.taskSpec.hooks.stop ? opts.taskSpec.hooks : deployBaseline.hooks),
112
- postToolUseFailure: (opts.taskSpec.hooks.postToolUseFailure ?? deployBaseline.hooks.postToolUseFailure)?.bind(opts.taskSpec.hooks.postToolUseFailure ? opts.taskSpec.hooks : deployBaseline.hooks),
113
- postToolBatch: (opts.taskSpec.hooks.postToolBatch ?? deployBaseline.hooks.postToolBatch)?.bind(opts.taskSpec.hooks.postToolBatch ? opts.taskSpec.hooks : deployBaseline.hooks),
114
- preCompact: (opts.taskSpec.hooks.preCompact ?? deployBaseline.hooks.preCompact)?.bind(opts.taskSpec.hooks.preCompact ? opts.taskSpec.hooks : deployBaseline.hooks),
115
- postCompact: (opts.taskSpec.hooks.postCompact ?? deployBaseline.hooks.postCompact)?.bind(opts.taskSpec.hooks.postCompact ? opts.taskSpec.hooks : deployBaseline.hooks),
116
- stopFailure: (opts.taskSpec.hooks.stopFailure ?? deployBaseline.hooks.stopFailure)?.bind(opts.taskSpec.hooks.stopFailure ? opts.taskSpec.hooks : deployBaseline.hooks),
117
- permissionDenied: (opts.taskSpec.hooks.permissionDenied ?? deployBaseline.hooks.permissionDenied)?.bind(opts.taskSpec.hooks.permissionDenied ? opts.taskSpec.hooks : deployBaseline.hooks),
118
- ...((opts.taskSpec.hooks.timeoutMs ?? deployBaseline.hooks.timeoutMs) !== undefined
119
- ? { timeoutMs: opts.taskSpec.hooks.timeoutMs ?? deployBaseline.hooks.timeoutMs }
120
- : {}),
121
- }
122
- : (opts.taskSpec.hooks ?? deployBaseline?.hooks);
123
105
  let guardRestores = 0;
124
106
  let consecutiveOracleErrors = 0;
125
107
  let gateAbandoned = false;
126
- const hooks = {
127
- ...(userHooks?.preToolUse && { preToolUse: userHooks.preToolUse.bind(userHooks) }),
128
- ...(userHooks?.preToolUse && userHooks.preToolUseObservational === true ? { preToolUseObservational: true } : {}),
129
- ...(userHooks?.postToolUse && { postToolUse: userHooks.postToolUse.bind(userHooks) }),
130
- ...(userHooks?.userPromptSubmit && { userPromptSubmit: userHooks.userPromptSubmit.bind(userHooks) }),
131
- ...(userHooks?.postToolUseFailure && { postToolUseFailure: userHooks.postToolUseFailure.bind(userHooks) }),
132
- ...(userHooks?.postToolBatch && { postToolBatch: userHooks.postToolBatch.bind(userHooks) }),
133
- ...(userHooks?.preCompact && { preCompact: userHooks.preCompact.bind(userHooks) }),
134
- ...(userHooks?.postCompact && { postCompact: userHooks.postCompact.bind(userHooks) }),
135
- ...(userHooks?.stopFailure && { stopFailure: userHooks.stopFailure.bind(userHooks) }),
136
- ...(userHooks?.permissionDenied && { permissionDenied: userHooks.permissionDenied.bind(userHooks) }),
137
- ...(userHooks?.timeoutMs !== undefined ? { timeoutMs: userHooks.timeoutMs } : {}),
138
- async stop(ctx) {
139
- guardRestores += restoreFrozenPaths(snapshot, rootDir);
140
- if (!gateAbandoned) {
141
- const gateSignal = ctx.signal !== undefined && opts.taskSpec.signal !== undefined ? AbortSignal.any([ctx.signal, opts.taskSpec.signal]) : (ctx.signal ?? opts.taskSpec.signal);
142
- const report = await runOracle(contract.oracle, rootDir, { baseline, ...(gateSignal !== undefined ? { signal: gateSignal } : {}), ...noticeSeat });
143
- if (ctx.signal?.aborted === true)
144
- return undefined;
145
- oracleRuns++;
146
- if (report.verdict === "red") {
147
- oracleHadRedRun = true;
148
- oracleRedRuns++;
149
- stopGateBlocks++;
150
- consecutiveOracleErrors = 0;
151
- return { block: redFeedback(report.gates) };
152
- }
153
- if (report.verdict === "error") {
154
- consecutiveOracleErrors++;
155
- if (consecutiveOracleErrors < 2) {
156
- const broken = report.gates.filter((g) => g.verdict === "error");
108
+ const oracleGate = {
109
+ name: RUN_SPEC_ORACLE_GATE,
110
+ uses: { events: ["classic.Stop"], calls: [] },
111
+ budgetMs: RUN_SPEC_ORACLE_GATE_BUDGET_MS,
112
+ register(on) {
113
+ on("classic.Stop", async (_$, e, next) => {
114
+ guardRestores += restoreFrozenPaths(snapshot, rootDir);
115
+ if (!gateAbandoned) {
116
+ const gateSignal = opts.taskSpec.signal !== undefined ? AbortSignal.any([next.signal, opts.taskSpec.signal]) : next.signal;
117
+ const report = await runOracle(contract.oracle, rootDir, { baseline, signal: gateSignal, ...noticeSeat });
118
+ if (next.signal.aborted)
119
+ return {};
120
+ oracleRuns++;
121
+ if (report.verdict === "red") {
122
+ oracleHadRedRun = true;
123
+ oracleRedRuns++;
157
124
  stopGateBlocks++;
158
- return {
159
- block: `The verification oracle itself FAILED TO RUN (${broken.map((g) => `gate "${g.name}": ${g.reason}`).join("; ")}). ` +
160
- `This is an infrastructure error, not a test failure — you may have broken the build/test environment. ` +
161
- `Restore it so the oracle can run.`,
162
- };
125
+ consecutiveOracleErrors = 0;
126
+ return { block: redFeedback(report.gates) };
127
+ }
128
+ if (report.verdict === "error") {
129
+ consecutiveOracleErrors++;
130
+ if (consecutiveOracleErrors < 2) {
131
+ const broken = report.gates.filter((g) => g.verdict === "error");
132
+ stopGateBlocks++;
133
+ return {
134
+ block: `The verification oracle itself FAILED TO RUN (${broken.map((g) => `gate "${g.name}": ${g.reason}`).join("; ")}). ` +
135
+ `This is an infrastructure error, not a test failure — you may have broken the build/test environment. ` +
136
+ `Restore it so the oracle can run.`,
137
+ };
138
+ }
139
+ gateAbandoned = true;
140
+ }
141
+ else {
142
+ consecutiveOracleErrors = 0;
163
143
  }
164
- gateAbandoned = true;
165
- }
166
- else {
167
- consecutiveOracleErrors = 0;
168
144
  }
169
- }
170
- return userHooks?.stop ? userHooks.stop(ctx) : undefined;
145
+ return next(e);
146
+ });
171
147
  },
172
148
  };
173
149
  const result = await runner.runTask({
174
150
  ...opts.taskSpec,
175
151
  objective: buildObjective(specText, contract),
176
152
  toolPolicy,
177
- hooks,
153
+ mods: [oracleGate, ...(opts.taskSpec.mods ?? [])],
178
154
  });
179
155
  guardRestores += restoreFrozenPaths(snapshot, rootDir);
180
156
  const final = await runOracle(contract.oracle, rootDir, { baseline, ...noticeSeat });
@@ -539,9 +539,8 @@ async function mountRunWorkflowTool(d) {
539
539
  ...((ctx.inheritedGateForChildren ?? d.inheritedGateForChildren) !== undefined
540
540
  ? { inheritedGate: (ctx.inheritedGateForChildren ?? d.inheritedGateForChildren)() }
541
541
  : {}),
542
- ...((ctx.toolSelector?.layers ?? d.parentToolCeiling) !== undefined ? { toolCeiling: (ctx.toolSelector?.layers ?? d.parentToolCeiling) } : {}),
543
542
  ...(autoModeReview !== undefined ? { autoModeReview } : {}),
544
- }, { workflowDepth: d.workflowDepth });
543
+ }, { workflowDepth: d.workflowDepth, ...((ctx.toolSelector?.layers ?? d.parentToolCeiling) !== undefined ? { toolCeiling: (ctx.toolSelector?.layers ?? d.parentToolCeiling) } : {}) });
545
544
  }
546
545
  catch (err) {
547
546
  return structuredError(thrownText(err));
@@ -153,6 +153,11 @@ export declare class WorkflowJournalAppendTimeoutError extends Error {
153
153
  */
154
154
  export interface WorkflowInternals {
155
155
  workflowDepth?: number;
156
+ /** The tool selector layers of the prepared run that launched this workflow (`ToolExecuteContext.toolSelector.layers`), threaded into
157
+ * EVERY spawned agent as its ceiling (`RunInternals.toolCeiling`) on both spawn legs. The run that holds them judged them where it
158
+ * wrote them, so they are not asked again here; a ceiling a host writes itself is {@link RunWorkflowOptions.toolCeiling}, which is.
159
+ * Given both, both bound every agent (these layers first) and only the host-written one is judged. */
160
+ toolCeiling?: readonly import("../core/tool-face.js").ToolSelectorLayer[];
156
161
  }
157
162
  export interface WorkflowBudget {
158
163
  /** The token ceiling, or null when none was set (then `remaining()` is Infinity). */
@@ -565,9 +570,12 @@ export interface RunWorkflowOptions {
565
570
  * `run_workflow` tool wiring; a directly-started workflow may pass its own. Absent ⇒ children run
566
571
  * under only their own gates (pre-seam behavior). TRUSTED: never a script/model argument. */
567
572
  inheritedGate?: import("../core/runner/contracts.js").InheritedGate;
568
- /** The HOST task's tool selector layers (`ToolExecuteContext.toolSelector.layers`), threaded into EVERY spawned agent's trusted
569
- * internals as its ceiling (`RunInternals.toolCeiling`) on both spawn legs: nothing a workflow agent's spec names can widen what
570
- * the host may use. Set by the `run_workflow` tool wiring; absent ⇒ the agents are bounded only by their own lists. TRUSTED. */
573
+ /** A tool selector ceiling the HOST writes, threaded into EVERY spawned agent's trusted internals as its ceiling
574
+ * (`RunInternals.toolCeiling`) on both spawn legs: nothing a workflow agent's spec names can widen it. Nobody judged what the host
575
+ * wrote, so each agent's spec is asked of it before it launches: another spelling of a tool the agent carries (a caller tool, the
576
+ * catalog, a listable delegation pool) refuses that agent — `config.tool_face_control`, `detail.reason: "near_miss"`. The ceiling of the
577
+ * prepared run that launched the workflow rides {@link WorkflowInternals.toolCeiling} instead; given both, both bound every agent and only
578
+ * this one is judged. Absent ⇒ the agents are bounded only by their own lists. */
571
579
  toolCeiling?: readonly import("../core/tool-face.js").ToolSelectorLayer[];
572
580
  /** RB-201 FO-3 (workflow lane) — the session's auto-mode classifier, consulted BEFORE each script-spawned
573
581
  * child starts (objective + toolset + output schema, finalized). The delegation-tool lane reviews its
@@ -20,7 +20,7 @@ import { boundInputHashOf } from "../core/canonical-json.js";
20
20
  import { boundedRedactedSummary, egressThrownText } from "../core/untrusted-egress.js";
21
21
  import { delimitUntrusted } from "../core/untrusted-text.js";
22
22
  import { OUTPUT_TOOL_NAME } from "../core/runner/synthetic-tools.js";
23
- import { deniedToolNamesOf } from "../core/runner/sub-agent-deny-lists.js";
23
+ import { deniedToolNamesOf, judgeHostToolCeiling } from "../core/runner/sub-agent-deny-lists.js";
24
24
  import { compileOutputSchema } from "../core/runner/strict-output-schema.js";
25
25
  import { WorkflowBudgetExceededError, WorkflowNestingError, WorkflowAgentBlockedError, WorkflowAgentParkedError, WorkflowAgentSchemaError, WorkflowAgentStalledError, WorkflowMaxAgentsError, WORKFLOW_SPAWN_BLOCKED_ERROR_CODE } from "./workflow-types.js";
26
26
  import { WorkflowScriptError } from "./workflow-meta.js";
@@ -705,6 +705,13 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
705
705
  o.close();
706
706
  };
707
707
  const sem = createSemaphore(concurrency);
708
+ const launchingCeiling = internals?.toolCeiling ?? undefined;
709
+ const hostCeiling = opts.toolCeiling ?? undefined;
710
+ const agentCeiling = launchingCeiling === undefined ? hostCeiling : hostCeiling === undefined ? launchingCeiling : [...launchingCeiling, ...hostCeiling];
711
+ const judgeHostCeiling = (spec) => {
712
+ if (hostCeiling !== undefined)
713
+ judgeHostToolCeiling(hostCeiling, spec, launchingCeiling);
714
+ };
708
715
  const spawnAttribution = {
709
716
  isDelegatedChild: true,
710
717
  ...(opts.questionFaceStripped === true ? { questionFaceStripped: true } : {}),
@@ -715,7 +722,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
715
722
  ...(opts.parentCenterSourceRevision !== undefined ? { parentCenterSourceRevision: opts.parentCenterSourceRevision } : {}),
716
723
  ...(opts.onForwardEvent ? { onForwardEvent: opts.onForwardEvent } : {}),
717
724
  ...(opts.inheritedGate !== undefined ? { inheritedGate: opts.inheritedGate } : {}),
718
- ...(opts.toolCeiling !== undefined ? { toolCeiling: opts.toolCeiling } : {}),
725
+ ...(agentCeiling !== undefined ? { toolCeiling: agentCeiling } : {}),
719
726
  ...((opts.rootSessionId ?? opts.originatingSessionId) !== undefined ? { rootSessionId: opts.rootSessionId ?? opts.originatingSessionId } : {}),
720
727
  ...(opts.placementRoot !== undefined ? { placementRoot: opts.placementRoot } : {}),
721
728
  ...(opts.originatingSessionId !== undefined ? { parentSessionId: opts.originatingSessionId } : {}),
@@ -1645,6 +1652,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
1645
1652
  const preReviewSpec = agentOpts.schema
1646
1653
  ? { ...seatedSpec, ...authInherit, ...parkInherit, signal: effectiveSignal, outputSchema: agentOpts.schema }
1647
1654
  : { ...seatedSpec, ...authInherit, ...parkInherit, signal: effectiveSignal };
1655
+ judgeHostCeiling(preReviewSpec);
1648
1656
  const runSpec = await reviewSpawnBeforeLaunch("ctx.agent", label, callKey, preReviewSpec, effectiveSignal);
1649
1657
  const enrichedForward = opts.onForwardEvent !== undefined
1650
1658
  ? (e) => {
@@ -2010,6 +2018,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
2010
2018
  ? { ...seatedSpec, ...authInherit, ...parkInherit, signal: effectiveSignal, outputSchema: agentOpts.schema }
2011
2019
  : { ...seatedSpec, ...authInherit, ...parkInherit, signal: effectiveSignal };
2012
2020
  const preReviewSpec = childSessionId !== undefined ? { ...baseRunSpec, sessionId: childSessionId } : baseRunSpec;
2021
+ judgeHostCeiling(preReviewSpec);
2013
2022
  const runSpec = await reviewSpawnBeforeLaunch("ctx.agentStream", label, callKey, preReviewSpec, effectiveSignal);
2014
2023
  const enrichedForwardS = opts.onForwardEvent !== undefined
2015
2024
  ? (e) => {
@@ -1,28 +1,46 @@
1
- import { type PromptEpochArtifact, type PublishedPromptArtifactEnvelope } from "./artifact.js";
1
+ import type { RunnerDeps } from "../core/runner-deps.js";
2
+ import { type ArtifactVerifyCode, type PromptArtifact, type PublishedPromptArtifact } from "./artifact.js";
3
+ /** Why a copy a store holds could not be used: the verifier refused it (its code and reason — a retired schema's reason
4
+ * names the republish rewrite), or the store could not read it back (`unreadable`, the reason naming the read error). */
5
+ export interface StoredArtifactRefusal {
6
+ readonly code: ArtifactVerifyCode | "unreadable";
7
+ readonly reason: string;
8
+ }
9
+ /** What a read tells its caller when a copy was there and could not be used. */
10
+ export type OnArtifactRefused = (refusal: StoredArtifactRefusal) => void;
11
+ /** The clause every reader says of a copy that could not be used, by its cause — one wording, wherever it is said. */
12
+ export declare function refusalClause(refusal: StoredArtifactRefusal): string;
13
+ /**
14
+ * The operator line for a stored center artifact that could not be read back: which copy, why — refused or unreadable
15
+ * (the clause above), or no copy at all — and what follows from it. The one sentence a boot restore and a pinned resume
16
+ * say.
17
+ */
18
+ export declare function storedArtifactLine(artifactDigest: string, refusal: StoredArtifactRefusal | undefined, consequence: string): string;
2
19
  export interface PromptArtifactStore {
3
- /** Verified read by digest — undefined on miss OR on any verification failure of stored bytes. */
4
- get(artifactDigest: string, opts: {
5
- engineVersion: string;
6
- }): Promise<PublishedPromptArtifactEnvelope | undefined>;
7
- /** Idempotent immutable write (same digest ⇒ same bytes; the caller verified before putting). */
8
- put(envelope: PublishedPromptArtifactEnvelope): Promise<void>;
20
+ /**
21
+ * Verified read by digest — undefined on a miss OR on a copy that cannot be used. When a copy was there and could not
22
+ * be used — the verifier refused its bytes, or the store could not read them — `onRefused` is told once before the
23
+ * read answers undefined, so a caller can tell a refused or unreadable copy (a retired schema, a corrupt file, a file
24
+ * the process may not read) from a missing one. A store that holds a copy it cannot use calls it.
25
+ */
26
+ get(artifactDigest: string, onRefused?: OnArtifactRefused): Promise<PublishedPromptArtifact | undefined>;
27
+ /** Write by digest (the caller verified before putting). */
28
+ put(artifact: PublishedPromptArtifact): Promise<void>;
9
29
  }
10
30
  export declare class MemoryPromptArtifactStore implements PromptArtifactStore {
11
31
  private readonly byDigest;
12
- get(artifactDigest: string, opts: {
13
- engineVersion: string;
14
- }): Promise<PublishedPromptArtifactEnvelope | undefined>;
15
- put(envelope: PublishedPromptArtifactEnvelope): Promise<void>;
32
+ get(artifactDigest: string, onRefused?: OnArtifactRefused): Promise<PublishedPromptArtifact | undefined>;
33
+ put(artifact: PublishedPromptArtifact): Promise<void>;
16
34
  }
17
- /** `artifacts/<hex>.json` under a caller-owned directory; atomic tmp+rename writes (§9.2). */
35
+ /** `artifacts/<hex>.json` under a caller-owned directory; atomic tmp+rename writes. */
18
36
  export declare class FilePromptArtifactStore implements PromptArtifactStore {
19
37
  private readonly dir;
20
38
  constructor(dir: string);
21
39
  private fileFor;
22
- get(artifactDigest: string, opts: {
23
- engineVersion: string;
24
- }): Promise<PublishedPromptArtifactEnvelope | undefined>;
25
- put(envelope: PublishedPromptArtifactEnvelope): Promise<void>;
40
+ /** A file that is not there is a miss; one that is there and cannot be read (a directory in its place, a file the
41
+ * process may not open, too many open files) is told to `onRefused` as `unreadable`, by its error code. */
42
+ get(artifactDigest: string, onRefused?: OnArtifactRefused): Promise<PublishedPromptArtifact | undefined>;
43
+ put(artifact: PublishedPromptArtifact): Promise<void>;
26
44
  }
27
45
  export type PromptSourceState = {
28
46
  state: "active";
@@ -49,60 +67,58 @@ export declare class FilePromptSourceStateStore implements PromptSourceStateStor
49
67
  load(): Promise<PromptSourceState | undefined>;
50
68
  save(state: PromptSourceState): Promise<void>;
51
69
  }
52
- /** The narrow face the Runner consumes (RunnerDeps.promptSource) — resolution only, no publish. */
70
+ /** The narrow face the Runner consumes (`RunnerDeps.promptSource`) — resolution only, no publish. */
53
71
  export interface PromptArtifactSource {
54
- /** The current validated candidate for NEW sessions, with its publish provenance
55
- * (undefined = bundled-only, today's shape). */
56
- current(): {
57
- artifact: PromptEpochArtifact;
58
- sourceRevision: string;
59
- } | undefined;
60
- /** Resolve a PINNED digest (resume path). Undefined = unavailable — the caller fails loud. */
61
- get(artifactDigest: string): Promise<PromptEpochArtifact | undefined>;
62
- /** RB-31 — the tri-state the adoption boundary keys on: `"disabled"` = an EXPLICIT
63
- * validated revocation (applyDisabled) ⇒ pinned sessions roll back to bundled at the next
64
- * compaction; `"active"` = a validated candidate is live; `"unavailable"` = no verified state
65
- * (never-configured face, store-miss boot) ⇒ conservative restate — an outage must never strip
66
- * policy, only an explicit revocation does. Optional (older sources read as "unavailable"). */
67
- sourceState?(): "active" | "disabled" | "unavailable";
72
+ /** The current verified candidate new sessions (and every top-level session at a compaction) adopt; undefined = none. */
73
+ current(): PublishedPromptArtifact | undefined;
74
+ /** Resolve a PINNED digest (the resume path). Undefined = unavailable — the caller fails loud. `onRefused` is the
75
+ * store's (see {@link PromptArtifactStore.get}): told when a copy was there and could not be used, so the caller says
76
+ * why. */
77
+ get(artifactDigest: string, onRefused?: OnArtifactRefused): Promise<PromptArtifact | undefined>;
78
+ /** The tri-state every adoption decision keys on: `"active"` = a verified candidate is live; `"disabled"` = an
79
+ * EXPLICIT verified revocation (`applyDisabled`) — the one state that empties a pinned center layer;
80
+ * `"unavailable"` = no verified state (never configured, or a store miss at boot) — an outage never strips policy,
81
+ * only an explicit revocation does. */
82
+ sourceState(): "active" | "disabled" | "unavailable";
68
83
  }
69
84
  /**
70
- * The candidate state machine (§9.2 full pipeline). Publish-side entry points:
71
- * - `applySnapshot(raw)` — a fetched effective-snapshot body: verify → store.put → persist
72
- * active state → atomic in-memory swap. Any verification failure leaves EVERYTHING unchanged.
73
- * - `applyDisabled(sourceRevision)` — an explicit, successful disable/delete response: persist
74
- * disabled state + drop the candidate. (Network failure/304 = simply don't call anything.)
75
- * - `restore()` — boot: re-resolve persisted active state through the verified store; a miss or
76
- * verify failure boots stateless (no candidate) without touching the persisted record.
85
+ * The candidate state machine. Publish-side entry points:
86
+ * - `applySnapshot(raw)` — a fetched published artifact: verify → store.put → persist active state → atomic
87
+ * in-memory swap. Any verification failure leaves EVERYTHING unchanged.
88
+ * - `applyDisabled(sourceRevision)` — an explicit, successful disable/delete response: persist disabled state +
89
+ * drop the candidate. (Network failure/304 = simply don't call anything.)
90
+ * - `restore()` — boot: re-resolve the persisted active state through the verified store; a miss, an unreadable copy
91
+ * or a verify failure boots stateless (no candidate) without touching the persisted record, and says which on
92
+ * `onError` (a refused copy — a retired schema's reason names the republish rewrite — and an unreadable one are told
93
+ * apart from no copy at all).
77
94
  */
78
95
  export declare class CenterPromptSource implements PromptArtifactSource {
79
96
  private readonly store;
80
97
  private readonly stateStore;
81
- private readonly engineVersion;
98
+ private readonly onError;
99
+ private readonly notifier;
82
100
  private candidate;
83
101
  private state;
84
- /** Hardening 2026-07-31 — serialization tail for the three STATE-MUTATING entry points. Each of
85
- * them is a multi-await sequence ending in a synchronous swap of (candidate, state); with two in
86
- * flight, an interleaving where B's `stateStore.save` resolves and swaps before A's leaves the
87
- * persisted record naming B's digest while the in-memory candidate names A's — `current()` then
88
- * serves A to every new session until the next `restore()` silently switches to B. `CenterPromptSource`
89
- * is a public export driven by a caller's poll loop, so two overlapping applies are an ordinary
90
- * schedule, not an exotic race. Serializing costs nothing (these are publish-rate operations) and
91
- * makes the durable record and the in-memory candidate agree by construction. */
102
+ /** Serialization tail for the three STATE-MUTATING entry points. Each is a multi-await sequence ending in a
103
+ * synchronous swap of (candidate, state); with two in flight, an interleaving where B's `stateStore.save`
104
+ * resolves and swaps before A's would leave the persisted record naming B's digest while the in-memory candidate
105
+ * names A's. `CenterPromptSource` is driven by a caller's poll loop, so overlapping applies are an ordinary
106
+ * schedule. Serializing costs nothing (publish-rate operations) and makes the durable record and the in-memory
107
+ * candidate agree by construction. */
92
108
  private tail;
93
- /** Run `fn` after every previously-queued mutation settles (success OR failure — a failed apply
94
- * must not wedge the queue). */
109
+ /** Run `fn` after every previously-queued mutation settles (success OR failure — a failed apply must not wedge the queue). */
95
110
  private exclusive;
111
+ /** `onError` is the operator channel of the source's own acts (a boot restore that finds its persisted artifact
112
+ * refused, unreadable or gone) — the Runner's sink, in its shape (`RunnerDeps.onError`): pass the Runner's. A boot
113
+ * restore belongs to no session: its context is `{ phase: "prompt-constitution", sessionId: "", classification:
114
+ * "center-source-restore" }`. Omitted = those acts are silent. */
96
115
  constructor(opts: {
97
116
  store: PromptArtifactStore;
98
117
  stateStore?: PromptSourceStateStore;
99
- engineVersion: string;
118
+ onError?: RunnerDeps["onError"];
100
119
  });
101
- current(): {
102
- artifact: PromptEpochArtifact;
103
- sourceRevision: string;
104
- } | undefined;
105
- get(artifactDigest: string): Promise<PromptEpochArtifact | undefined>;
120
+ current(): PublishedPromptArtifact | undefined;
121
+ get(artifactDigest: string, onRefused?: OnArtifactRefused): Promise<PromptArtifact | undefined>;
106
122
  restore(): Promise<void>;
107
123
  sourceState(): "active" | "disabled" | "unavailable";
108
124
  applySnapshot(raw: unknown): Promise<{
@@ -110,7 +126,7 @@ export declare class CenterPromptSource implements PromptArtifactSource {
110
126
  artifactDigest: string;
111
127
  } | {
112
128
  ok: false;
113
- code: string;
129
+ code: ArtifactVerifyCode;
114
130
  reason: string;
115
131
  }>;
116
132
  applyDisabled(sourceRevision: string): Promise<void>;
@@ -1,29 +1,40 @@
1
1
  import { mkdirSync, promises as fs } from "node:fs";
2
2
  import path from "node:path";
3
- import { verifyPromptArtifact, } from "./artifact.js";
4
- function normalizedEnvelope(parsed, artifact) {
5
- return { ...parsed, artifact };
3
+ import { createSafeNotifier, observeThenableRejection } from "../core/safe-notify.js";
4
+ import { verifyPromptArtifact } from "./artifact.js";
5
+ export function refusalClause(refusal) {
6
+ return refusal.code === "unreadable" ? `unreadable (${refusal.reason})` : `refused by this engine (${refusal.code}: ${refusal.reason})`;
7
+ }
8
+ export function storedArtifactLine(artifactDigest, refusal, consequence) {
9
+ return `center prompt artifact ${artifactDigest.slice(0, 23)}… ${refusal !== undefined ? `is ${refusalClause(refusal)}` : "has no stored copy"} — ${consequence}`;
10
+ }
11
+ function tellRefused(onRefused, refusal) {
12
+ const notifier = createSafeNotifier();
13
+ notifier.notify(() => observeThenableRejection(onRefused?.(refusal), notifier, "artifact-store.onRefused"), "artifact-store.onRefused");
14
+ return undefined;
15
+ }
16
+ function verifiedRead(bytes, artifactDigest, onRefused) {
17
+ const refuse = (refusal) => tellRefused(onRefused, refusal);
18
+ let parsed;
19
+ try {
20
+ parsed = JSON.parse(bytes);
21
+ }
22
+ catch {
23
+ return refuse({ code: "shape", reason: "the stored bytes are not JSON" });
24
+ }
25
+ const v = verifyPromptArtifact(parsed);
26
+ if (!v.ok)
27
+ return refuse({ code: v.code, reason: v.reason });
28
+ return v.artifact.artifactDigest === artifactDigest ? v.artifact : refuse({ code: "digest", reason: "the stored artifact is not the one its digest names" });
6
29
  }
7
30
  export class MemoryPromptArtifactStore {
8
31
  byDigest = new Map();
9
- async get(artifactDigest, opts) {
32
+ async get(artifactDigest, onRefused) {
10
33
  const bytes = this.byDigest.get(artifactDigest);
11
- if (bytes === undefined)
12
- return undefined;
13
- let parsed;
14
- try {
15
- parsed = JSON.parse(bytes);
16
- }
17
- catch {
18
- return undefined;
19
- }
20
- const v = verifyPromptArtifact(parsed, opts);
21
- if (!v.ok || v.artifact.artifactDigest !== artifactDigest)
22
- return undefined;
23
- return normalizedEnvelope(parsed, v.artifact);
34
+ return bytes === undefined ? undefined : verifiedRead(bytes, artifactDigest, onRefused);
24
35
  }
25
- async put(envelope) {
26
- this.byDigest.set(envelope.artifact.artifactDigest, JSON.stringify(envelope));
36
+ async put(artifact) {
37
+ this.byDigest.set(artifact.artifactDigest, JSON.stringify(artifact));
27
38
  }
28
39
  }
29
40
  export class FilePromptArtifactStore {
@@ -36,7 +47,7 @@ export class FilePromptArtifactStore {
36
47
  const m = /^sha256:([0-9a-f]{64})$/.exec(artifactDigest);
37
48
  return m ? path.join(this.dir, "artifacts", `${m[1]}.json`) : undefined;
38
49
  }
39
- async get(artifactDigest, opts) {
50
+ async get(artifactDigest, onRefused) {
40
51
  const file = this.fileFor(artifactDigest);
41
52
  if (file === undefined)
42
53
  return undefined;
@@ -44,27 +55,20 @@ export class FilePromptArtifactStore {
44
55
  try {
45
56
  bytes = await fs.readFile(file, "utf8");
46
57
  }
47
- catch {
48
- return undefined;
58
+ catch (err) {
59
+ const code = typeof err === "object" && err !== null ? err.code : undefined;
60
+ if (code === "ENOENT")
61
+ return undefined;
62
+ return tellRefused(onRefused, { code: "unreadable", reason: `the store could not read its file: ${typeof code === "string" ? code : "an error with no code"}` });
49
63
  }
50
- let parsed;
51
- try {
52
- parsed = JSON.parse(bytes);
53
- }
54
- catch {
55
- return undefined;
56
- }
57
- const v = verifyPromptArtifact(parsed, opts);
58
- if (!v.ok || v.artifact.artifactDigest !== artifactDigest)
59
- return undefined;
60
- return normalizedEnvelope(parsed, v.artifact);
64
+ return verifiedRead(bytes, artifactDigest, onRefused);
61
65
  }
62
- async put(envelope) {
63
- const file = this.fileFor(envelope.artifact.artifactDigest);
66
+ async put(artifact) {
67
+ const file = this.fileFor(artifact.artifactDigest);
64
68
  if (file === undefined)
65
- throw new Error(`prompt-artifact store: malformed digest ${JSON.stringify(envelope.artifact.artifactDigest).slice(0, 120)}`);
69
+ throw new Error(`prompt-artifact store: malformed digest ${JSON.stringify(artifact.artifactDigest).slice(0, 120)}`);
66
70
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
67
- await fs.writeFile(tmp, JSON.stringify(envelope), "utf8");
71
+ await fs.writeFile(tmp, JSON.stringify(artifact), "utf8");
68
72
  await fs.rename(tmp, file);
69
73
  }
70
74
  }
@@ -113,7 +117,8 @@ export class FilePromptSourceStateStore {
113
117
  export class CenterPromptSource {
114
118
  store;
115
119
  stateStore;
116
- engineVersion;
120
+ onError;
121
+ notifier = createSafeNotifier();
117
122
  candidate;
118
123
  state = "unavailable";
119
124
  tail = Promise.resolve();
@@ -125,16 +130,15 @@ export class CenterPromptSource {
125
130
  constructor(opts) {
126
131
  this.store = opts.store;
127
132
  this.stateStore = opts.stateStore ?? new MemoryPromptSourceStateStore();
128
- this.engineVersion = opts.engineVersion;
133
+ this.onError = opts.onError;
129
134
  }
130
135
  current() {
131
136
  return this.candidate;
132
137
  }
133
- async get(artifactDigest) {
134
- if (this.candidate?.artifact.artifactDigest === artifactDigest)
135
- return this.candidate.artifact;
136
- const env = await this.store.get(artifactDigest, { engineVersion: this.engineVersion });
137
- return env?.artifact;
138
+ async get(artifactDigest, onRefused) {
139
+ if (this.candidate?.artifactDigest === artifactDigest)
140
+ return this.candidate;
141
+ return this.store.get(artifactDigest, onRefused);
138
142
  }
139
143
  async restore() {
140
144
  return this.exclusive(async () => {
@@ -149,23 +153,27 @@ export class CenterPromptSource {
149
153
  this.state = "unavailable";
150
154
  return;
151
155
  }
152
- const env = await this.store.get(state.artifactDigest, { engineVersion: this.engineVersion });
153
- this.candidate = env !== undefined ? { artifact: env.artifact, sourceRevision: state.sourceRevision } : undefined;
154
- this.state = env !== undefined ? "active" : "unavailable";
156
+ const refused = {};
157
+ const stored = await this.store.get(state.artifactDigest, (r) => void (refused.current = r));
158
+ this.candidate = stored !== undefined ? { ...stored, sourceRevision: state.sourceRevision } : undefined;
159
+ this.state = stored !== undefined ? "active" : "unavailable";
160
+ if (stored === undefined) {
161
+ const line = new Error(storedArtifactLine(state.artifactDigest, refused.current, "the source boots unavailable: a new session has no center layer until a verified artifact is applied"));
162
+ this.notifier.notify(() => observeThenableRejection(this.onError?.(line, { phase: "prompt-constitution", sessionId: "", classification: "center-source-restore" }), this.notifier, "center-source.onError"), "center-source.onError");
163
+ }
155
164
  });
156
165
  }
157
166
  sourceState() {
158
167
  return this.state;
159
168
  }
160
169
  async applySnapshot(raw) {
161
- const v = verifyPromptArtifact(raw, { engineVersion: this.engineVersion });
170
+ const v = verifyPromptArtifact(raw);
162
171
  if (!v.ok)
163
172
  return v;
164
- const envelope = raw;
165
173
  return this.exclusive(async () => {
166
- await this.store.put(envelope);
167
- await this.stateStore.save({ state: "active", artifactDigest: v.artifact.artifactDigest, sourceRevision: envelope.sourceRevision });
168
- this.candidate = { artifact: v.artifact, sourceRevision: envelope.sourceRevision };
174
+ await this.store.put(v.artifact);
175
+ await this.stateStore.save({ state: "active", artifactDigest: v.artifact.artifactDigest, sourceRevision: v.artifact.sourceRevision });
176
+ this.candidate = v.artifact;
169
177
  this.state = "active";
170
178
  return { ok: true, artifactDigest: v.artifact.artifactDigest };
171
179
  });