@sema-agent/core 7.51.2 → 7.52.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 (363) hide show
  1. package/CHANGELOG.md +504 -2
  2. package/dist/agents/agent-transcript-tool.d.ts +1 -1
  3. package/dist/agents/cascade.js +4 -0
  4. package/dist/agents/cumulative-stats.d.ts +3 -0
  5. package/dist/agents/cumulative-stats.js +3 -0
  6. package/dist/agents/list-agents-tool.d.ts +1 -1
  7. package/dist/agents/read-inbox-tool.d.ts +1 -1
  8. package/dist/agents/repair-loop.js +4 -0
  9. package/dist/agents/send-message-tool.d.ts +11 -16
  10. package/dist/agents/send-message-tool.js +11 -13
  11. package/dist/agents/subagent.js +6 -4
  12. package/dist/agents/tool-filter.d.ts +40 -13
  13. package/dist/agents/tool-filter.js +28 -14
  14. package/dist/bench/metrics.d.ts +1 -0
  15. package/dist/brain/anthropic.js +16 -12
  16. package/dist/brain/model-presets.d.ts +4 -5
  17. package/dist/brain/model-presets.js +4 -4
  18. package/dist/brain/open-responses.js +16 -12
  19. package/dist/brain/openai.js +16 -12
  20. package/dist/brain/request-params.d.ts +12 -33
  21. package/dist/brain/request-params.js +5 -2
  22. package/dist/brain/request-route.d.ts +9 -8
  23. package/dist/brain/request-route.js +1 -0
  24. package/dist/brain/route-adjudicator.d.ts +117 -47
  25. package/dist/brain/route-adjudicator.js +171 -42
  26. package/dist/brain/route-conformance.js +2 -2
  27. package/dist/brain/status-sink.d.ts +18 -0
  28. package/dist/brain/status-sink.js +7 -0
  29. package/dist/core/allow-entry.d.ts +40 -8
  30. package/dist/core/allow-entry.js +23 -16
  31. package/dist/core/auto-compaction.d.ts +23 -20
  32. package/dist/core/auto-compaction.js +37 -16
  33. package/dist/core/auto-promote.d.ts +2 -1
  34. package/dist/core/auto-promote.js +2 -2
  35. package/dist/core/caller-tool-name.d.ts +9 -0
  36. package/dist/core/caller-tool-name.js +13 -0
  37. package/dist/core/checkpoint-requirements.d.ts +7 -1
  38. package/dist/core/checkpoint-requirements.js +2 -0
  39. package/dist/core/checkpoint-store.d.ts +36 -12
  40. package/dist/core/checkpoint-store.js +1 -1
  41. package/dist/core/child-clamp-seats.d.ts +6 -0
  42. package/dist/core/child-clamp-seats.js +2 -1
  43. package/dist/core/credential-vocabulary.d.ts +33 -8
  44. package/dist/core/credential-vocabulary.js +32 -7
  45. package/dist/core/decision-receipt.d.ts +2 -2
  46. package/dist/core/delegation-frames.d.ts +9 -2
  47. package/dist/core/delegation-name.d.ts +18 -0
  48. package/dist/core/delegation-name.js +47 -0
  49. package/dist/core/engine-capabilities.d.ts +8 -1
  50. package/dist/core/engine-capabilities.js +1 -1
  51. package/dist/core/engine-notice.d.ts +36 -19
  52. package/dist/core/frontmatter-fence.d.ts +10 -0
  53. package/dist/core/frontmatter-fence.js +6 -0
  54. package/dist/core/gate-fold.js +5 -23
  55. package/dist/core/gate-lanes.js +356 -270
  56. package/dist/core/governance-codes.d.ts +9 -4
  57. package/dist/core/governance-codes.js +9 -3
  58. package/dist/core/hooks.d.ts +276 -734
  59. package/dist/core/hooks.js +97 -192
  60. package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
  61. package/dist/{tools/fs → core}/image-admission.js +24 -6
  62. package/dist/core/mcp-connection-pool.d.ts +4 -1
  63. package/dist/core/mcp-connection-pool.js +7 -2
  64. package/dist/core/mcp-probe.d.ts +12 -9
  65. package/dist/core/mcp-probe.js +2 -2
  66. package/dist/core/mcp-server-spec.d.ts +16 -0
  67. package/dist/core/mcp.d.ts +11 -7
  68. package/dist/core/mcp.js +11 -5
  69. package/dist/core/memory-engine/data-plane.js +5 -1
  70. package/dist/core/memory-engine/distiller.js +16 -2
  71. package/dist/core/memory-engine/engine.d.ts +8 -11
  72. package/dist/core/memory-engine/engine.js +9 -5
  73. package/dist/core/memory-engine/frontmatter.d.ts +6 -0
  74. package/dist/core/memory-engine/frontmatter.js +19 -16
  75. package/dist/core/memory.d.ts +2 -2
  76. package/dist/core/mode-policy.d.ts +4 -0
  77. package/dist/core/mode-policy.js +7 -5
  78. package/dist/core/model-seat.d.ts +4 -1
  79. package/dist/core/mods/dollar.d.ts +109 -0
  80. package/dist/core/mods/dollar.js +154 -0
  81. package/dist/core/mods/host.d.ts +23 -0
  82. package/dist/core/mods/host.js +21 -0
  83. package/dist/core/mods/kernel/budget.d.ts +43 -0
  84. package/dist/core/mods/kernel/budget.js +83 -0
  85. package/dist/core/mods/kernel/dispatch.d.ts +100 -0
  86. package/dist/core/mods/kernel/dispatch.js +701 -0
  87. package/dist/core/mods/kernel/events.d.ts +242 -0
  88. package/dist/core/mods/kernel/events.js +210 -0
  89. package/dist/core/mods/kernel/index.d.ts +6 -0
  90. package/dist/core/mods/kernel/index.js +5 -0
  91. package/dist/core/mods/kernel/receive.d.ts +65 -0
  92. package/dist/core/mods/kernel/receive.js +123 -0
  93. package/dist/core/mods/kernel/registration.d.ts +131 -0
  94. package/dist/core/mods/kernel/registration.js +102 -0
  95. package/dist/core/mods/kernel/site-rules.d.ts +84 -0
  96. package/dist/core/mods/kernel/site-rules.js +104 -0
  97. package/dist/core/mods/stations.d.ts +350 -0
  98. package/dist/core/mods/stations.js +444 -0
  99. package/dist/core/own-property-receipt.js +11 -23
  100. package/dist/core/parent-spec-seat.d.ts +18 -7
  101. package/dist/core/parent-spec-seat.js +6 -2
  102. package/dist/core/path-identity.js +2 -1
  103. package/dist/core/permission-rule-syntax.d.ts +15 -0
  104. package/dist/core/permission-rule-syntax.js +24 -16
  105. package/dist/core/permission-rules.d.ts +7 -1
  106. package/dist/core/permission-rules.js +26 -15
  107. package/dist/core/prompt-section-seat.d.ts +15 -27
  108. package/dist/core/prompt-section-seat.js +73 -40
  109. package/dist/core/protocol-http-auth.d.ts +3 -1
  110. package/dist/core/protocol-http-auth.js +2 -0
  111. package/dist/core/reminder-mint.d.ts +2 -2
  112. package/dist/core/remote-env.d.ts +24 -12
  113. package/dist/core/remote-env.js +1 -0
  114. package/dist/core/resume-startup-cause.d.ts +16 -1
  115. package/dist/core/resume-startup-cause.js +4 -1
  116. package/dist/core/retired-keys.d.ts +4 -0
  117. package/dist/core/retired-keys.js +3 -0
  118. package/dist/core/runner/announce-once-ledger.d.ts +31 -1
  119. package/dist/core/runner/announce-once-ledger.js +22 -0
  120. package/dist/core/runner/assemble-result.d.ts +9 -0
  121. package/dist/core/runner/assemble-result.js +3 -1
  122. package/dist/core/runner/call-hook-stations.d.ts +23 -27
  123. package/dist/core/runner/call-hook-stations.js +58 -42
  124. package/dist/core/runner/caller-stop-gate.d.ts +25 -0
  125. package/dist/core/runner/caller-stop-gate.js +7 -0
  126. package/dist/core/runner/compaction-seams.d.ts +8 -22
  127. package/dist/core/runner/compaction-seams.js +28 -53
  128. package/dist/core/runner/construction-doors.js +11 -1
  129. package/dist/core/runner/contracts.d.ts +85 -83
  130. package/dist/core/runner/credential-origin-seat.d.ts +2 -0
  131. package/dist/core/runner/credential-origin-seat.js +19 -0
  132. package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
  133. package/dist/core/runner/gate-exit.d.ts +47 -36
  134. package/dist/core/runner/gate-exit.js +8 -2
  135. package/dist/core/runner/image.js +1 -2
  136. package/dist/core/runner/inline-image.js +1 -1
  137. package/dist/core/runner/notice-seat-input.d.ts +11 -0
  138. package/dist/core/runner/notice-seat-input.js +1 -0
  139. package/dist/core/runner/person-path-rows.js +1 -0
  140. package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
  141. package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
  142. package/dist/core/runner/prepare-ask-lane.js +6 -15
  143. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
  144. package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
  145. package/dist/core/runner/prepare-config-doors.d.ts +5 -0
  146. package/dist/core/runner/prepare-config-doors.js +9 -0
  147. package/dist/core/runner/prepare-defer-classify.js +3 -4
  148. package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
  149. package/dist/core/runner/prepare-gate-stations.js +11 -10
  150. package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
  151. package/dist/core/runner/prepare-inherited-gate.js +8 -21
  152. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  153. package/dist/core/runner/prepare-park-ask.js +10 -14
  154. package/dist/core/runner/prepare-policy-chain.d.ts +17 -15
  155. package/dist/core/runner/prepare-policy-chain.js +95 -100
  156. package/dist/core/runner/prepare-project-context.js +7 -10
  157. package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
  158. package/dist/core/runner/prepare-prompt-assembly.js +134 -101
  159. package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
  160. package/dist/core/runner/prepare-prompt-inputs.js +5 -7
  161. package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
  162. package/dist/core/runner/prepare-protocol-tools.js +2 -2
  163. package/dist/core/runner/prepare-safety-scan.js +6 -10
  164. package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
  165. package/dist/core/runner/prepare-suspend-saga.js +7 -5
  166. package/dist/core/runner/prepare-task.js +33 -15
  167. package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
  168. package/dist/core/runner/prepare-turn-wiring.js +29 -27
  169. package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
  170. package/dist/core/runner/prepare-wiring-manifest.js +7 -7
  171. package/dist/core/runner/resume-apply.d.ts +5 -2
  172. package/dist/core/runner/resume-apply.js +24 -42
  173. package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
  174. package/dist/core/runner/resume-checkpoint-screen.js +9 -1
  175. package/dist/core/runner/resume-preflight.js +38 -16
  176. package/dist/core/runner/retired-runner-deps.js +3 -1
  177. package/dist/core/runner/run-brain-sinks.d.ts +3 -2
  178. package/dist/core/runner/run-brain-sinks.js +5 -1
  179. package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
  180. package/dist/core/runner/run-compaction-machinery.js +7 -33
  181. package/dist/core/runner/run-harness-handlers.js +4 -2
  182. package/dist/core/runner/run-identity-wiring.d.ts +3 -1
  183. package/dist/core/runner/run-identity-wiring.js +3 -2
  184. package/dist/core/runner/run-leg.js +62 -84
  185. package/dist/core/runner/run-notification-lane.js +1 -0
  186. package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
  187. package/dist/core/runner/run-recovery-lanes.js +11 -10
  188. package/dist/core/runner/run-settle-and-teardown.js +9 -28
  189. package/dist/core/runner/run-stop-and-final-verify.js +18 -25
  190. package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
  191. package/dist/core/runner/run-terminal-adoption.js +33 -22
  192. package/dist/core/runner/run-tool-mount-facts.js +5 -3
  193. package/dist/core/runner/run-turn-boundary.js +23 -34
  194. package/dist/core/runner/runtask.d.ts +6 -7
  195. package/dist/core/runner/runtask.js +14 -72
  196. package/dist/core/runner/session-rule-policy.d.ts +5 -5
  197. package/dist/core/runner/session-rule-policy.js +13 -8
  198. package/dist/core/runner/side-call-account.d.ts +68 -0
  199. package/dist/core/runner/side-call-account.js +61 -0
  200. package/dist/core/runner/stream-halt-verbs.js +12 -17
  201. package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
  202. package/dist/core/runner/stream-steer-verb.d.ts +1 -1
  203. package/dist/core/runner/stream-steer-verb.js +20 -38
  204. package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
  205. package/dist/core/runner/sub-agent-deny-lists.js +228 -71
  206. package/dist/core/runner/tool-end-body.d.ts +5 -6
  207. package/dist/core/runner/tool-end-body.js +6 -4
  208. package/dist/core/runner/tool-not-executed.d.ts +15 -0
  209. package/dist/core/runner/tool-not-executed.js +30 -0
  210. package/dist/core/runner/tool-occurrence.d.ts +8 -7
  211. package/dist/core/runner/tool-occurrence.js +5 -5
  212. package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
  213. package/dist/core/runner-deps.d.ts +20 -28
  214. package/dist/core/safety-merge-corpus.js +18 -2
  215. package/dist/core/secret-env.d.ts +88 -20
  216. package/dist/core/secret-env.js +192 -38
  217. package/dist/core/session-policy-store.d.ts +52 -16
  218. package/dist/core/session-policy-store.js +118 -28
  219. package/dist/core/session-reconcile.d.ts +4 -0
  220. package/dist/core/session-reconcile.js +2 -1
  221. package/dist/core/shell-read-silence.js +3 -32
  222. package/dist/core/side-query.d.ts +5 -3
  223. package/dist/core/skill-grant.d.ts +3 -2
  224. package/dist/core/skill-grant.js +17 -9
  225. package/dist/core/skills-directory.d.ts +31 -11
  226. package/dist/core/skills-directory.js +655 -104
  227. package/dist/core/task-event.d.ts +13 -3
  228. package/dist/core/task-result.d.ts +8 -0
  229. package/dist/core/task-spec.d.ts +20 -19
  230. package/dist/core/task-stream.d.ts +14 -4
  231. package/dist/core/tighten-task-spec.d.ts +4 -3
  232. package/dist/core/tighten-task-spec.js +2 -4
  233. package/dist/core/tool-check-reading.d.ts +74 -0
  234. package/dist/core/tool-check-reading.js +80 -0
  235. package/dist/core/tool-policy.d.ts +59 -18
  236. package/dist/core/tool-policy.js +77 -12
  237. package/dist/core/tool-registry.d.ts +20 -0
  238. package/dist/core/tool-registry.js +4 -0
  239. package/dist/core/tool-spec.d.ts +10 -6
  240. package/dist/core/tools.js +2 -0
  241. package/dist/core/trace.d.ts +51 -32
  242. package/dist/core/unc-spelling.d.ts +10 -0
  243. package/dist/core/unc-spelling.js +3 -0
  244. package/dist/core/untrusted-egress.d.ts +8 -0
  245. package/dist/core/untrusted-egress.js +4 -1
  246. package/dist/core/user-attachment.d.ts +12 -2
  247. package/dist/core/user-attachment.js +17 -2
  248. package/dist/core/wiring-manifest.d.ts +14 -13
  249. package/dist/core/wiring-manifest.js +2 -2
  250. package/dist/engine/compaction/utils.js +1 -2
  251. package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
  252. package/dist/engine/execution-env/symlink-chain.js +1 -1
  253. package/dist/engine/harness/agent-harness.d.ts +1 -1
  254. package/dist/engine/harness/agent-harness.js +3 -3
  255. package/dist/engine/harness/types.d.ts +17 -16
  256. package/dist/engine/harness/types.js +7 -1
  257. package/dist/engine/llm/types.d.ts +12 -7
  258. package/dist/engine/loop/agent-loop.js +1 -1
  259. package/dist/engine/loop/types.d.ts +1 -1
  260. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  261. package/dist/engine/session/import-validate.js +3 -10
  262. package/dist/engine/session/session.d.ts +4 -4
  263. package/dist/engine/session/session.js +4 -4
  264. package/dist/index.d.ts +20 -16
  265. package/dist/index.js +13 -11
  266. package/dist/internal/harness.d.ts +1 -1
  267. package/dist/internal/harness.js +1 -1
  268. package/dist/orchestration/run-spec.d.ts +4 -6
  269. package/dist/orchestration/run-spec.js +39 -63
  270. package/dist/orchestration/run-workflow-tool.js +1 -2
  271. package/dist/orchestration/workflow.d.ts +11 -3
  272. package/dist/orchestration/workflow.js +11 -2
  273. package/dist/prompt-assembly/artifact-store.d.ts +37 -56
  274. package/dist/prompt-assembly/artifact-store.js +31 -49
  275. package/dist/prompt-assembly/artifact.d.ts +89 -76
  276. package/dist/prompt-assembly/artifact.js +167 -146
  277. package/dist/prompt-assembly/assemble.d.ts +34 -29
  278. package/dist/prompt-assembly/assemble.js +33 -220
  279. package/dist/prompt-assembly/bands.d.ts +20 -0
  280. package/dist/prompt-assembly/bands.js +18 -0
  281. package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
  282. package/dist/prompt-assembly/catalog/constitution.js +69 -0
  283. package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
  284. package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
  285. package/dist/prompt-assembly/catalog/index.d.ts +11 -0
  286. package/dist/prompt-assembly/catalog/index.js +59 -0
  287. package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
  288. package/dist/prompt-assembly/catalog/modes.js +137 -0
  289. package/dist/prompt-assembly/catalog/role.d.ts +10 -0
  290. package/dist/prompt-assembly/catalog/role.js +157 -0
  291. package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
  292. package/dist/prompt-assembly/catalog/schema.js +25 -0
  293. package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
  294. package/dist/prompt-assembly/catalog/sections.js +98 -0
  295. package/dist/prompt-assembly/catalog/team.d.ts +4 -0
  296. package/dist/prompt-assembly/catalog/team.js +258 -0
  297. package/dist/prompt-assembly/composer.d.ts +24 -28
  298. package/dist/prompt-assembly/composer.js +124 -46
  299. package/dist/prompt-assembly/epoch.d.ts +89 -79
  300. package/dist/prompt-assembly/epoch.js +115 -142
  301. package/dist/prompt-assembly/explain.d.ts +58 -34
  302. package/dist/prompt-assembly/explain.js +21 -24
  303. package/dist/prompt-assembly/overlay.d.ts +127 -0
  304. package/dist/prompt-assembly/overlay.js +301 -0
  305. package/dist/prompt-assembly/renderers.d.ts +21 -0
  306. package/dist/prompt-assembly/renderers.js +39 -0
  307. package/dist/prompt-assembly/section-usage.d.ts +3 -3
  308. package/dist/prompt-assembly/section-usage.js +1 -1
  309. package/dist/prompt-assembly/select.d.ts +56 -0
  310. package/dist/prompt-assembly/select.js +69 -0
  311. package/dist/prompt-assembly/sugar.d.ts +31 -0
  312. package/dist/prompt-assembly/sugar.js +20 -0
  313. package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
  314. package/dist/prompt-assembly/types.d.ts +45 -148
  315. package/dist/prompts/coordinator.d.ts +2 -21
  316. package/dist/prompts/coordinator.js +3 -255
  317. package/dist/prompts/cowork.d.ts +27 -16
  318. package/dist/prompts/cowork.js +2 -23
  319. package/dist/prompts/default.d.ts +38 -500
  320. package/dist/prompts/default.js +20 -285
  321. package/dist/prompts/supervisor.d.ts +6 -71
  322. package/dist/prompts/supervisor.js +6 -117
  323. package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
  324. package/dist/tools/fs/dir-entries.d.ts +4 -2
  325. package/dist/tools/fs/dir-entries.js +16 -4
  326. package/dist/tools/fs/fs-bash.d.ts +1 -1
  327. package/dist/tools/fs/fs-bash.js +22 -11
  328. package/dist/tools/fs/fs-pdf.js +17 -13
  329. package/dist/tools/fs/fs-read.js +4 -3
  330. package/dist/tools/fs/fs-shared.d.ts +1 -10
  331. package/dist/tools/fs/fs-shared.js +3 -4
  332. package/dist/tools/fs/fs-write.js +2 -1
  333. package/dist/tools/fs/notebook.js +1 -1
  334. package/dist/tools/fs/pdf.d.ts +20 -10
  335. package/dist/tools/fs/pdf.js +19 -10
  336. package/dist/tools/fs/program-read-model.d.ts +68 -8
  337. package/dist/tools/fs/program-read-model.js +112 -33
  338. package/dist/tools/fs/program-read-model.rows.js +30 -10
  339. package/dist/tools/fs/read-deny-home.d.ts +25 -9
  340. package/dist/tools/fs/read-deny-home.js +28 -27
  341. package/dist/tools/fs/read-deny.d.ts +41 -11
  342. package/dist/tools/fs/read-deny.js +51 -5
  343. package/dist/tools/fs/safety.d.ts +4 -26
  344. package/dist/tools/fs/safety.js +10 -32
  345. package/dist/tools/fs/search.js +15 -10
  346. package/dist/tools/fs/shell-read-argv.d.ts +3 -2
  347. package/dist/tools/fs/shell-read-argv.js +118 -38
  348. package/dist/tools/fs/shell-read-establish.d.ts +5 -5
  349. package/dist/tools/fs/shell-read-establish.js +11 -61
  350. package/dist/tools/fs/shell-read-identity.js +6 -3
  351. package/dist/tools/fs/shell-read-judge.d.ts +13 -15
  352. package/dist/tools/fs/shell-read-judge.js +18 -4
  353. package/dist/tools/fs/shell-read-plan.d.ts +2 -2
  354. package/dist/tools/web.js +1 -1
  355. package/package.json +13 -1
  356. package/test/export-surface.snapshot.json +242 -99
  357. package/wire-changes/core@7.52.0.json +5859 -0
  358. package/dist/core/hook-seats.d.ts +0 -66
  359. package/dist/core/hook-seats.js +0 -37
  360. package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
  361. package/dist/prompt-assembly/packs/sema-default.js +0 -147
  362. package/dist/prompts/simple-sections.d.ts +0 -58
  363. package/dist/prompts/simple-sections.js +0 -43
@@ -1,92 +1,105 @@
1
- import type { PromptTextDeclaration } from "../prompts/default.js";
2
- /** v1 overlay slots — the same reserved rank bands the stableBlocks lane mounts into. */
3
- export type CenterOverlaySlot = "identity" | "scenario" | "behavior";
4
- export interface CenterOverlaySection {
5
- /** Same grammar as stableBlocks ids (manifest/trace/explain-safe, never `core/`). */
6
- id: string;
7
- slot: CenterOverlaySlot;
8
- /** Immutable rendered text (v1: fixed text, no renderer — center compiles before publishing). */
9
- text: string;
10
- /** REQUIRED on the center lane (unlike caller stableBlocks): sha256 of `text`. The center
11
- * publish path always mints it — it is the reconciliation anchor (digest tiering). */
12
- contentHash: string;
1
+ import { type OverlayOp, type PromptTrait } from "./catalog/schema.js";
2
+ import { type PromptOverlay, type SourcedOverlay } from "./overlay.js";
3
+ /** What an artifact needs from the engine that composes it: the targets it names (each with what kind of target it
4
+ * is), the operations it uses, the traits its `when` conditions read, and the bindings its overlays are scoped to. */
5
+ export interface PromptArtifactRequires {
6
+ readonly targets: readonly {
7
+ readonly id: string;
8
+ readonly kind: "message" | "section" | "band";
9
+ }[];
10
+ readonly ops: readonly OverlayOp[];
11
+ readonly traits: readonly PromptTrait[];
12
+ readonly bindings: readonly string[];
13
13
  }
14
- export interface PromptCatalogSnapshot {
15
- /** Center pack identity, e.g. "center:acme@3". Logical name only — history identity is digests. */
16
- packId: string;
17
- sections: ReadonlyArray<CenterOverlaySection>;
14
+ /** Why the artifact exists: an intent sentence (required) and references to the evaluations or goldens behind it. */
15
+ export interface PromptArtifactEvidence {
16
+ readonly intent: string;
17
+ readonly refs: readonly string[];
18
18
  }
19
- export interface PromptDependencyClosure {
20
- /** v1: only the bundled base is a legal foundation (exact-archive multi-base = later slice). */
21
- basePackId: string;
22
- promptCatalog: PromptCatalogSnapshot;
19
+ /** The digested part of an artifact. */
20
+ export interface PromptArtifactPayload {
21
+ readonly schemaVersion: 2;
22
+ readonly requires: PromptArtifactRequires;
23
+ /** Every overlay is of the `center` class; `scope.binding` absent ⇒ applies under every binding. */
24
+ readonly overlays: readonly PromptOverlay[];
25
+ readonly evidence: PromptArtifactEvidence;
23
26
  }
24
- /** Dependency-free core-compat range: dotted-triple compares, absent bound = unbounded. */
25
- export interface CoreCompatRange {
26
- minCore?: string;
27
- maxCoreExclusive?: string;
27
+ /** An artifact's identity: the payload and its digest (what a session pins and a store holds by digest). */
28
+ export interface PromptArtifact {
29
+ readonly payload: PromptArtifactPayload;
30
+ readonly artifactDigest: string;
28
31
  }
29
- export interface PromptEpochArtifactPayload {
30
- schemaVersion: 1;
31
- assemblyApi: 1;
32
- catalogDigest: string;
33
- compatibleCore?: CoreCompatRange;
34
- closure: PromptDependencyClosure;
32
+ /** The published form: the artifact plus its opaque source revision (never ordered, never compared for recency). */
33
+ export interface PublishedPromptArtifact extends PromptArtifact {
34
+ readonly sourceRevision: string;
35
35
  }
36
- export interface PromptEpochArtifact {
37
- payload: PromptEpochArtifactPayload;
38
- artifactDigest: string;
39
- }
40
- /** The publish envelope (§9.2): artifact + opaque source provenance. Attestation = later slice
41
- * (protocol: first phase does not require full PKI for internal artifacts). */
42
- export interface PublishedPromptArtifactEnvelope {
43
- artifact: PromptEpochArtifact;
44
- /** Opaque ETag-like revision. State transitions key off "last successfully verified response";
45
- * NEVER ordered or compared for recency. */
46
- sourceRevision: string;
47
- }
48
- /** Validator hard limits (§9.2: sections/bytes caps so a untrusted or runaway publish cannot wedge
49
- * the composer). Deliberately generous — these bound abuse, not legitimate catalogs. */
50
- export declare const ARTIFACT_LIMITS: {
51
- readonly maxSections: 64;
52
- readonly maxSectionBytes: 32000;
53
- readonly maxTotalBytes: 131072;
54
- readonly maxIdLength: 128;
55
- readonly maxPackIdLength: 200;
56
- };
57
- export declare function sha256Hex(text: string): string;
58
- export declare function computeCatalogDigest(catalog: PromptCatalogSnapshot): string;
59
- export declare function computeArtifactDigest(payload: PromptEpochArtifactPayload): string;
36
+ /** Validator bounds: they bound abuse and runaway publishes, not legitimate artifacts. */
37
+ export declare const ARTIFACT_LIMITS: Readonly<{
38
+ maxOverlays: 64;
39
+ maxOverlayTextBytes: 32000;
40
+ maxTotalTextBytes: 131072;
41
+ maxIntentChars: 2000;
42
+ maxRefs: 32;
43
+ maxRefChars: 500;
44
+ maxSourceRevisionChars: 500;
45
+ }>;
46
+ export declare function computeArtifactDigest(payload: PromptArtifactPayload): string;
47
+ /** The requirement set an overlay list implies — the one derivation the builder stores and the verifier recomputes. */
48
+ export declare function requiresOf(overlays: readonly PromptOverlay[]): PromptArtifactRequires;
49
+ /** The requirements this engine does not meet (empty ⇒ all met): a target its catalog lacks, an op or a trait outside
50
+ * its vocabulary. Bindings are the deployment's open vocabulary and are always met. */
51
+ export declare function unmetRequirements(requires: PromptArtifactRequires): string[];
60
52
  export type ArtifactVerifyResult = {
61
53
  ok: true;
62
- artifact: PromptEpochArtifact;
54
+ artifact: PublishedPromptArtifact;
55
+ } | {
56
+ ok: false;
57
+ code: ArtifactVerifyCode;
58
+ reason: string;
59
+ };
60
+ type BodyVerifyResult = {
61
+ ok: true;
62
+ artifact: PromptArtifact;
63
63
  } | {
64
64
  ok: false;
65
- code: string;
65
+ code: ArtifactVerifyCode;
66
66
  reason: string;
67
67
  };
68
+ /** Why an artifact is invalid (docs/CLOSED-SETS.md). */
69
+ export type ArtifactVerifyCode = "shape" | "schema" | "limits" | "requires" | "overlay" | "evidence" | "digest";
68
70
  /**
69
- * Full §9.2 verify pipeline over an UNTRUSTED envelope (network body or disk bytes — the store
70
- * re-verifies on read; nothing on disk is trusted by location). Every arm is a distinct coded
71
- * rejection so the source-state machine can log honestly. Verification is pure — no IO.
71
+ * Verify an UNTRUSTED published artifact (a network body or stored bytes — a store re-verifies on read). Pure. Any
72
+ * failure invalidates the whole artifact: shape, schema version, bounds, each overlay under the center class's band
73
+ * columns and the locked-text guard, the stored requirement list (recomputed, then checked against this engine),
74
+ * same-target replace conflicts, the evidence rule, and the digest.
72
75
  */
73
- export declare function verifyPromptArtifact(raw: unknown, opts: {
74
- engineVersion: string;
75
- }): ArtifactVerifyResult;
76
+ export declare function verifyPromptArtifact(raw: unknown): ArtifactVerifyResult;
77
+ /**
78
+ * The same verifier over an artifact without its provenance — what a run re-checks when it adopts an artifact from
79
+ * its source (a candidate, a pinned digest, a parent's layer): requirements are met by THIS engine, every overlay is
80
+ * legal here, the digest holds. A source is a deployment seat; what it hands the run is checked, not trusted.
81
+ */
82
+ export declare function verifyPromptArtifactBody(raw: unknown): BodyVerifyResult;
83
+ /** The center layer a run composes under: the adopted artifact and, when the source stamped one, its revision. */
84
+ export type CenterAdoption = {
85
+ artifact: PromptArtifact;
86
+ sourceRevision?: string;
87
+ };
88
+ /**
89
+ * The center class's overlays for an adopted artifact under a binding: every overlay with no `scope.binding`, and
90
+ * every one whose `scope.binding` equals the run's binding, in the artifact's order.
91
+ */
92
+ export declare function centerOverlaysOf(adoption: CenterAdoption | undefined, binding: string | undefined): readonly SourcedOverlay[];
93
+ /** An artifact a source handed a run, re-checked by this engine before the run adopts it; undefined when it fails. */
94
+ export declare function adoptCenter(artifact: PromptArtifact, sourceRevision: string | undefined): CenterAdoption | undefined;
76
95
  /**
77
- * Compile a VERIFIED artifact into the declaration lane (v1 adoption channel — see file header).
78
- * Deterministic order: catalog order preserved (it entered the digest, so it is stable).
96
+ * Build a published artifact from overlays and evidence — the one builder (a center's publish pipeline calls it):
97
+ * `requires` is derived, the digest computed over the payload's JSON form (what travels), and the result goes
98
+ * through the verifier, so the caller holds either a valid artifact or the reason it is not one.
79
99
  */
80
- export declare function artifactDeclarations(artifact: PromptEpochArtifact): PromptTextDeclaration[];
81
- /** Test/fixture helper: build a correctly-digested envelope from plain sections (the shape a
82
- * center's publish pipeline produces). Exported for tests and the fixture-center harness. */
83
- export declare function buildPromptArtifactEnvelope(opts: {
84
- packId: string;
85
- sections: ReadonlyArray<{
86
- id: string;
87
- slot: CenterOverlaySlot;
88
- text: string;
89
- }>;
100
+ export declare function buildPromptArtifact(opts: {
101
+ overlays: readonly PromptOverlay[];
102
+ evidence: PromptArtifactEvidence;
90
103
  sourceRevision: string;
91
- compatibleCore?: CoreCompatRange;
92
- }): PublishedPromptArtifactEnvelope;
104
+ }): ArtifactVerifyResult;
105
+ export {};
@@ -1,169 +1,190 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { isBandId } from "./bands.js";
3
+ import { SEMA_DEFAULT_CATALOG } from "./catalog/index.js";
4
+ import { OVERLAY_OPS, PROMPT_TRAITS, isWordOf } from "./catalog/schema.js";
2
5
  import { canonical } from "./epoch.js";
3
- export const ARTIFACT_LIMITS = {
4
- maxSections: 64,
5
- maxSectionBytes: 32_000,
6
- maxTotalBytes: 131_072,
7
- maxIdLength: 128,
8
- maxPackIdLength: 200,
9
- };
10
- const ID_RE = /^[a-z0-9][a-z0-9/._-]*$/;
6
+ import { sectionOfMessage, validateOverlay } from "./overlay.js";
7
+ export const ARTIFACT_LIMITS = Object.freeze({
8
+ maxOverlays: 64,
9
+ maxOverlayTextBytes: 32_000,
10
+ maxTotalTextBytes: 131_072,
11
+ maxIntentChars: 2_000,
12
+ maxRefs: 32,
13
+ maxRefChars: 500,
14
+ maxSourceRevisionChars: 500,
15
+ });
11
16
  const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
12
- const SLOTS = new Set(["identity", "scenario", "behavior"]);
13
- export function sha256Hex(text) {
17
+ const MESSAGE_IDS = new Set(SEMA_DEFAULT_CATALOG.messages.map((m) => m.id));
18
+ const SECTION_IDS = new Set(SEMA_DEFAULT_CATALOG.sections.map((s) => s.id));
19
+ function sha256Hex(text) {
14
20
  return `sha256:${createHash("sha256").update(text, "utf8").digest("hex")}`;
15
21
  }
16
- export function computeCatalogDigest(catalog) {
17
- return sha256Hex(canonical(catalog));
18
- }
19
22
  export function computeArtifactDigest(payload) {
20
23
  return sha256Hex(canonical(payload));
21
24
  }
22
- function triple(v) {
23
- const m = /^(\d+)\.(\d+)\.(\d+)$/.exec(v.trim());
24
- if (!m)
25
- return undefined;
26
- return [Number(m[1]), Number(m[2]), Number(m[3])];
25
+ export function requiresOf(overlays) {
26
+ const targets = new Map();
27
+ const need = (id, kind) => {
28
+ targets.set(`${kind}:${id}`, { id, kind });
29
+ };
30
+ const ops = new Set();
31
+ const traits = new Set();
32
+ const bindings = new Set();
33
+ for (const o of overlays) {
34
+ ops.add(o.op);
35
+ need(o.target, o.op === "add" ? "band" : o.op === "drop" ? "section" : "message");
36
+ if (o.message !== undefined)
37
+ need(o.message, "message");
38
+ for (const t of [...(o.when?.traits?.allOf ?? []), ...(o.when?.traits?.noneOf ?? [])])
39
+ traits.add(t);
40
+ if (o.scope?.binding !== undefined)
41
+ bindings.add(o.scope.binding);
42
+ }
43
+ const byText = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
44
+ return {
45
+ targets: [...targets.values()].sort((a, b) => byText(`${a.kind}:${a.id}`, `${b.kind}:${b.id}`)),
46
+ ops: OVERLAY_OPS.filter((op) => ops.has(op)),
47
+ traits: PROMPT_TRAITS.filter((t) => traits.has(t)),
48
+ bindings: [...bindings].sort(byText),
49
+ };
27
50
  }
28
- function tripleCmp(a, b) {
29
- for (let i = 0; i < 3; i++) {
30
- if (a[i] !== b[i])
31
- return a[i] < b[i] ? -1 : 1;
51
+ export function unmetRequirements(requires) {
52
+ const unmet = [];
53
+ for (const t of requires.targets) {
54
+ const has = t.kind === "message" ? MESSAGE_IDS.has(t.id) : t.kind === "section" ? SECTION_IDS.has(t.id) : isBandId(t.id);
55
+ if (!has)
56
+ unmet.push(`${t.kind} "${t.id}"`);
32
57
  }
33
- return 0;
58
+ for (const op of requires.ops)
59
+ if (!isWordOf(OVERLAY_OPS, op))
60
+ unmet.push(`op "${String(op)}"`);
61
+ for (const tr of requires.traits)
62
+ if (!isWordOf(PROMPT_TRAITS, tr))
63
+ unmet.push(`trait "${String(tr)}"`);
64
+ return unmet;
34
65
  }
35
- export function verifyPromptArtifact(raw, opts) {
36
- const fail = (code, reason) => ({ ok: false, code, reason });
37
- if (raw === null || typeof raw !== "object")
38
- return fail("shape", "envelope is not an object");
39
- const env = raw;
40
- if (typeof env.sourceRevision !== "string" || !env.sourceRevision || env.sourceRevision.length > 500) {
41
- return fail("shape", "sourceRevision missing/oversized");
66
+ function isRecord(v) {
67
+ return v !== null && typeof v === "object" && !Array.isArray(v);
68
+ }
69
+ function requiresShaped(v) {
70
+ if (!isRecord(v))
71
+ return false;
72
+ const strings = (a) => Array.isArray(a) && a.every((s) => typeof s === "string");
73
+ return (Object.keys(v).every((k) => k === "targets" || k === "ops" || k === "traits" || k === "bindings") &&
74
+ Array.isArray(v.targets) &&
75
+ v.targets.every((t) => isRecord(t) && typeof t.id === "string" && (t.kind === "message" || t.kind === "section" || t.kind === "band") && Object.keys(t).every((k) => k === "id" || k === "kind")) &&
76
+ strings(v.ops) &&
77
+ strings(v.traits) &&
78
+ strings(v.bindings));
79
+ }
80
+ function replaceConflict(overlays) {
81
+ const seen = new Map();
82
+ for (const o of overlays) {
83
+ if (o.op !== "replace")
84
+ continue;
85
+ const key = canonical({ target: o.target, binding: o.scope?.binding ?? null, when: o.when ?? null });
86
+ const prior = seen.get(key);
87
+ if (prior !== undefined)
88
+ return `overlays "${prior}" and "${o.id}" both replace "${o.target}" under the same binding and condition`;
89
+ seen.set(key, o.id);
90
+ }
91
+ return undefined;
92
+ }
93
+ export function verifyPromptArtifact(raw) {
94
+ if (!isRecord(raw))
95
+ return { ok: false, code: "shape", reason: "the published artifact is not an object" };
96
+ if (typeof raw.sourceRevision !== "string" || raw.sourceRevision.length === 0 || raw.sourceRevision.length > ARTIFACT_LIMITS.maxSourceRevisionChars) {
97
+ return { ok: false, code: "shape", reason: "sourceRevision missing or oversized" };
42
98
  }
43
- const art = env.artifact;
44
- if (art === null || typeof art !== "object")
45
- return fail("shape", "artifact is not an object");
46
- const payload = art.payload;
47
- if (payload === null || typeof payload !== "object")
99
+ const v = verifyPromptArtifactBody(raw);
100
+ return v.ok ? { ok: true, artifact: { ...v.artifact, sourceRevision: raw.sourceRevision } } : v;
101
+ }
102
+ export function verifyPromptArtifactBody(raw) {
103
+ const fail = (code, reason) => ({ ok: false, code, reason });
104
+ if (!isRecord(raw))
105
+ return fail("shape", "the artifact is not an object");
106
+ for (const k of Object.keys(raw))
107
+ if (k !== "payload" && k !== "artifactDigest" && k !== "sourceRevision")
108
+ return fail("shape", `the artifact carries ${JSON.stringify(k).slice(0, 60)}`);
109
+ if (typeof raw.artifactDigest !== "string" || !DIGEST_RE.test(raw.artifactDigest))
110
+ return fail("shape", "artifactDigest malformed");
111
+ const payload = raw.payload;
112
+ if (!isRecord(payload))
48
113
  return fail("shape", "payload is not an object");
49
- if (payload.schemaVersion !== 1)
50
- return fail("schema", `unsupported schemaVersion ${String(payload.schemaVersion)}`);
51
- if (payload.assemblyApi !== 1)
52
- return fail("schema", `unsupported assemblyApi ${String(payload.assemblyApi)}`);
53
- if (typeof payload.catalogDigest !== "string" || !DIGEST_RE.test(payload.catalogDigest))
54
- return fail("shape", "catalogDigest malformed");
55
- let compatibleCore;
56
- if (payload.compatibleCore !== undefined) {
57
- const cc = payload.compatibleCore;
58
- if (cc === null || typeof cc !== "object")
59
- return fail("shape", "compatibleCore malformed");
60
- compatibleCore = {};
61
- for (const key of ["minCore", "maxCoreExclusive"]) {
62
- const v = cc[key];
63
- if (v === undefined)
64
- continue;
65
- if (typeof v !== "string" || triple(v) === undefined)
66
- return fail("shape", `compatibleCore.${key} is not a dotted triple`);
67
- compatibleCore[key] = v;
68
- }
69
- const engine = triple(opts.engineVersion);
70
- if (engine === undefined)
71
- return fail("core-range", `engine version "${opts.engineVersion}" is not a dotted triple`);
72
- if (compatibleCore.minCore !== undefined && tripleCmp(engine, triple(compatibleCore.minCore)) < 0) {
73
- return fail("core-range", `engine ${opts.engineVersion} < minCore ${compatibleCore.minCore}`);
74
- }
75
- if (compatibleCore.maxCoreExclusive !== undefined && tripleCmp(engine, triple(compatibleCore.maxCoreExclusive)) >= 0) {
76
- return fail("core-range", `engine ${opts.engineVersion} >= maxCoreExclusive ${compatibleCore.maxCoreExclusive}`);
114
+ if (payload.schemaVersion !== 2)
115
+ return fail("schema", `unsupported schemaVersion ${JSON.stringify(payload.schemaVersion)?.slice(0, 40)} (this engine reads schemaVersion 2 only)`);
116
+ for (const k of Object.keys(payload))
117
+ if (k !== "schemaVersion" && k !== "requires" && k !== "overlays" && k !== "evidence")
118
+ return fail("shape", `payload carries ${JSON.stringify(k).slice(0, 60)}`);
119
+ if (!Array.isArray(payload.overlays))
120
+ return fail("shape", "overlays is not an array");
121
+ if (payload.overlays.length === 0)
122
+ return fail("shape", "overlays is empty — publish at least one overlay, or disable the source instead");
123
+ if (payload.overlays.length > ARTIFACT_LIMITS.maxOverlays)
124
+ return fail("limits", `${payload.overlays.length} overlays > max ${ARTIFACT_LIMITS.maxOverlays}`);
125
+ const requires = payload.requires;
126
+ if (!requiresShaped(requires))
127
+ return fail("shape", "requires is not { targets: { id, kind }[], ops: string[], traits: string[], bindings: string[] }");
128
+ const unmet = unmetRequirements(requires);
129
+ if (unmet.length > 0)
130
+ return fail("requires", `this engine does not meet the artifact's requirements: ${unmet.slice(0, 6).join(", ")}${unmet.length > 6 ? ` and ${unmet.length - 6} more` : ""}`);
131
+ const overlays = [];
132
+ let totalBytes = 0;
133
+ for (const rawOverlay of payload.overlays) {
134
+ const v = validateOverlay(rawOverlay, { source: "center" });
135
+ if ("violation" in v)
136
+ return fail("overlay", v.violation);
137
+ const text = v.overlay.text;
138
+ if (text !== undefined) {
139
+ const bytes = Buffer.byteLength(text, "utf8");
140
+ if (bytes > ARTIFACT_LIMITS.maxOverlayTextBytes)
141
+ return fail("limits", `overlay "${v.overlay.id}" text ${bytes} bytes > max ${ARTIFACT_LIMITS.maxOverlayTextBytes}`);
142
+ totalBytes += bytes;
77
143
  }
144
+ overlays.push(v.overlay);
78
145
  }
79
- const closure = payload.closure;
80
- if (closure === null || typeof closure !== "object")
81
- return fail("shape", "closure is not an object");
82
- if (closure.basePackId !== "sema-default@1") {
83
- return fail("base-pack", `unsupported basePackId ${JSON.stringify(closure.basePackId).slice(0, 120)} (v1: bundled base only)`);
146
+ if (totalBytes > ARTIFACT_LIMITS.maxTotalTextBytes)
147
+ return fail("limits", `overlay text ${totalBytes} bytes > max ${ARTIFACT_LIMITS.maxTotalTextBytes}`);
148
+ if (canonical(requiresOf(overlays)) !== canonical(requires))
149
+ return fail("requires", "requires differs from what the overlays require (build the artifact with buildPromptArtifact)");
150
+ const conflict = replaceConflict(overlays);
151
+ if (conflict !== undefined)
152
+ return fail("overlay", conflict);
153
+ const evidence = payload.evidence;
154
+ if (!isRecord(evidence) || typeof evidence.intent !== "string" || evidence.intent.trim() === "" || evidence.intent.length > ARTIFACT_LIMITS.maxIntentChars) {
155
+ return fail("evidence", `evidence.intent is a non-blank string of at most ${ARTIFACT_LIMITS.maxIntentChars} characters`);
84
156
  }
85
- const catalog = closure.promptCatalog;
86
- if (catalog === null || typeof catalog !== "object")
87
- return fail("shape", "promptCatalog is not an object");
88
- if (typeof catalog.packId !== "string" || !catalog.packId.trim() || catalog.packId.length > ARTIFACT_LIMITS.maxPackIdLength) {
89
- return fail("shape", "promptCatalog.packId missing/oversized");
157
+ if (!Array.isArray(evidence.refs) || evidence.refs.length > ARTIFACT_LIMITS.maxRefs || evidence.refs.some((r) => typeof r !== "string" || r.trim() === "" || r.length > ARTIFACT_LIMITS.maxRefChars)) {
158
+ return fail("evidence", `evidence.refs is a list of at most ${ARTIFACT_LIMITS.maxRefs} non-blank references`);
90
159
  }
91
- if (!Array.isArray(catalog.sections))
92
- return fail("shape", "promptCatalog.sections is not an array");
93
- if (catalog.sections.length === 0)
94
- return fail("shape", "promptCatalog.sections is empty — publish at least one section, or disable the source instead");
95
- if (catalog.sections.length > ARTIFACT_LIMITS.maxSections) {
96
- return fail("limits", `${catalog.sections.length} sections > max ${ARTIFACT_LIMITS.maxSections}`);
160
+ for (const k of Object.keys(evidence))
161
+ if (k !== "intent" && k !== "refs")
162
+ return fail("shape", `evidence carries ${JSON.stringify(k).slice(0, 60)}`);
163
+ const behaviorReplace = overlays.find((o) => o.op === "replace" && sectionOfMessage(o.target)?.band === "core-behavior");
164
+ if (behaviorReplace !== undefined && evidence.refs.length === 0) {
165
+ return fail("evidence", `overlay "${behaviorReplace.id}" replaces core-behavior text; evidence.refs names at least one evaluation or golden`);
97
166
  }
98
- const ids = new Set();
99
- let totalBytes = 0;
100
- const sections = [];
101
- for (const rawSection of catalog.sections) {
102
- if (rawSection === null || typeof rawSection !== "object")
103
- return fail("shape", "section is not an object");
104
- const s = rawSection;
105
- if (typeof s.id !== "string" || s.id.startsWith("core/") || s.id.length > ARTIFACT_LIMITS.maxIdLength || !ID_RE.test(s.id)) {
106
- return fail("shape", `invalid section id ${JSON.stringify(s.id).slice(0, 120)}`);
107
- }
108
- if (ids.has(s.id))
109
- return fail("shape", `duplicate section id "${s.id}"`);
110
- ids.add(s.id);
111
- if (typeof s.slot !== "string" || !SLOTS.has(s.slot))
112
- return fail("shape", `unknown slot ${JSON.stringify(s.slot).slice(0, 60)} ("${s.id}")`);
113
- if (typeof s.text !== "string" || s.text.length === 0)
114
- return fail("shape", `empty/missing text ("${s.id}")`);
115
- const bytes = Buffer.byteLength(s.text, "utf8");
116
- if (bytes > ARTIFACT_LIMITS.maxSectionBytes)
117
- return fail("limits", `section "${s.id}" ${bytes} bytes > max ${ARTIFACT_LIMITS.maxSectionBytes}`);
118
- totalBytes += bytes;
119
- if (typeof s.contentHash !== "string" || !DIGEST_RE.test(s.contentHash))
120
- return fail("shape", `contentHash missing/malformed ("${s.id}")`);
121
- if (s.contentHash !== sha256Hex(s.text))
122
- return fail("content-hash", `contentHash does not match text ("${s.id}")`);
123
- sections.push({ id: s.id, slot: s.slot, text: s.text, contentHash: s.contentHash });
124
- }
125
- if (totalBytes > ARTIFACT_LIMITS.maxTotalBytes)
126
- return fail("limits", `catalog ${totalBytes} bytes > max ${ARTIFACT_LIMITS.maxTotalBytes}`);
127
- const normalizedCatalog = { packId: catalog.packId, sections };
128
- const normalizedPayload = {
129
- schemaVersion: 1,
130
- assemblyApi: 1,
131
- catalogDigest: payload.catalogDigest,
132
- ...(compatibleCore !== undefined ? { compatibleCore } : {}),
133
- closure: { basePackId: "sema-default@1", promptCatalog: normalizedCatalog },
167
+ const normalized = {
168
+ schemaVersion: 2,
169
+ requires: requiresOf(overlays),
170
+ overlays,
171
+ evidence: { intent: evidence.intent, refs: [...evidence.refs] },
134
172
  };
135
- if (computeCatalogDigest(normalizedCatalog) !== payload.catalogDigest) {
136
- return fail("digest", "catalogDigest does not match canonical(promptCatalog)");
137
- }
138
- if (typeof art.artifactDigest !== "string" || !DIGEST_RE.test(art.artifactDigest))
139
- return fail("shape", "artifactDigest malformed");
140
- if (computeArtifactDigest(normalizedPayload) !== art.artifactDigest) {
173
+ if (computeArtifactDigest(normalized) !== raw.artifactDigest)
141
174
  return fail("digest", "artifactDigest does not match canonical(payload)");
142
- }
143
- return { ok: true, artifact: { payload: normalizedPayload, artifactDigest: art.artifactDigest } };
175
+ return { ok: true, artifact: { payload: normalized, artifactDigest: raw.artifactDigest } };
144
176
  }
145
- export function artifactDeclarations(artifact) {
146
- return artifact.payload.closure.promptCatalog.sections.map((s) => ({
147
- id: s.id,
148
- slot: s.slot,
149
- text: s.text,
150
- contentHash: s.contentHash,
151
- }));
177
+ const CENTER_ORIGIN = Object.freeze({ source: "center", by: "center" });
178
+ export function centerOverlaysOf(adoption, binding) {
179
+ if (adoption === undefined)
180
+ return [];
181
+ return adoption.artifact.payload.overlays.filter((o) => o.scope?.binding === undefined || o.scope.binding === binding).map((overlay) => ({ overlay, origin: CENTER_ORIGIN }));
152
182
  }
153
- export function buildPromptArtifactEnvelope(opts) {
154
- const catalog = {
155
- packId: opts.packId,
156
- sections: opts.sections.map((s) => ({ ...s, contentHash: sha256Hex(s.text) })),
157
- };
158
- const payload = {
159
- schemaVersion: 1,
160
- assemblyApi: 1,
161
- catalogDigest: computeCatalogDigest(catalog),
162
- ...(opts.compatibleCore !== undefined ? { compatibleCore: opts.compatibleCore } : {}),
163
- closure: { basePackId: "sema-default@1", promptCatalog: catalog },
164
- };
165
- return {
166
- artifact: { payload, artifactDigest: computeArtifactDigest(payload) },
167
- sourceRevision: opts.sourceRevision,
168
- };
183
+ export function adoptCenter(artifact, sourceRevision) {
184
+ const v = verifyPromptArtifactBody(artifact);
185
+ return v.ok ? { artifact: v.artifact, ...(sourceRevision !== undefined ? { sourceRevision } : {}) } : undefined;
186
+ }
187
+ export function buildPromptArtifact(opts) {
188
+ const payload = JSON.parse(JSON.stringify({ schemaVersion: 2, requires: requiresOf(opts.overlays), overlays: opts.overlays, evidence: opts.evidence }));
189
+ return verifyPromptArtifact({ payload, artifactDigest: sha256Hex(canonical(payload)), sourceRevision: opts.sourceRevision });
169
190
  }
@@ -1,42 +1,46 @@
1
+ /**
2
+ * Prepare-side assembly adapter — the SINGLE entry that drives the Composer over the bundled catalog. Prepare
3
+ * hands it the run's facts and tails and the overlays of each source class (the task class: the request-body
4
+ * sugar's, then the task seat's mods; the center class; the deploy class: the deployment seat's mods); it
5
+ * orders the classes `task < center < deploy`, composes, and reports every overlay a later one superseded.
6
+ *
7
+ * There is no "provider" here: no source owns the whole prompt, the locked bands have no writer, and a role
8
+ * text that carries locked text never reaches this point (the sugar refuses it, a mods handler's answer is
9
+ * skipped).
10
+ */
1
11
  import type { AgentTool } from "../internal/harness-types.js";
2
- import { type EnvironmentFacts, type PromptProvider, type PromptTextDeclaration } from "../prompts/default.js";
12
+ import type { HostForm, HostRole } from "./catalog/schema.js";
13
+ import { type SourcedOverlay, type SupersededOverlay } from "./overlay.js";
3
14
  import type { CompiledSection, CompiledSystemBlock, PromptRuntimeFacts } from "./types.js";
4
15
  export interface AssembleInputs {
5
- provider: PromptProvider;
6
- /** True when the provider is the built-in defaultPromptProvider (checked FIRST — its stableSystem
7
- * output contains the constitution anchors and would misroute through the M9 guard). */
8
- isDefaultProvider: boolean;
9
- userSystemPrompt?: string;
10
- userAppendSystemPrompt?: string;
11
- tools: AgentTool[];
16
+ /** The task class, in application order: the request-body sugar's overlays, then the task seat's mods. */
17
+ taskOverlays: readonly SourcedOverlay[];
18
+ /** The center class (the adopted center layer's overlays). */
19
+ centerOverlays: readonly SourcedOverlay[];
20
+ /** The deploy class: the deployment seat's mods, in chain order. */
21
+ deployOverlays: readonly SourcedOverlay[];
22
+ /** The host selector values (`TaskSpec.promptRole` / `TaskSpec.promptForm`). */
23
+ host?: {
24
+ role?: HostRole;
25
+ form?: HostForm;
26
+ };
27
+ tools: readonly AgentTool[];
12
28
  facts: PromptRuntimeFacts;
29
+ /** The task's working directory (the Cowork role base's `{{workspaceFolder}}`). */
30
+ workspaceFolder?: string;
13
31
  mcpInstructionsBlock?: string;
14
32
  memoryBlock?: string;
15
33
  /** Renders the environment tail for a given date (leg-frozen; date_change re-render seam). */
16
34
  buildEnvBlock: (date: string) => string | undefined;
17
- /** The leg's frozen date — the initial render input (design/66 date_change). */
35
+ /** The leg's frozen date — the initial render input. */
18
36
  date: string;
19
- /** The environment facts the tail renders from; a provider sees them without the date (`StablePromptContext.envFacts`). */
20
- envFacts?: EnvironmentFacts;
21
37
  modelGuidance?: string;
22
- /** design/148 S1 — declarations compiled from a VERIFIED center prompt artifact (the adoption
23
- * channel: core verifies the artifact, synthesizes these, and they ride the same mount loop as
24
- * provider stableBlocks — same manifest/epoch/contentHash faces, zero new assembly machinery).
25
- * Mounted ahead of provider declarations on every COMPOSED path; the provider-assembled
26
- * pass-through path cannot mount them (operator-visible warn, never silent). */
27
- centerDeclarations?: PromptTextDeclaration[];
28
38
  /** Structured warning channel (maps to deps.onError with a phase). */
29
39
  onWarn?: (message: string, phase: "prompt-constitution") => void;
30
40
  }
31
41
  export interface AssembledPrompt {
32
- constitution: "core" | "replaced" | "provider-assembled";
33
- /** design/148 S1: true ⇔ the supplied centerDeclarations were actually COMPILED into
34
- * this prompt. The caller must never persist a center pin when this is false — a pin that claims
35
- * an artifact the model never received is a durable lie (the assembled-identity pass-through path
36
- * warns + false). */
37
- centerMounted?: boolean;
38
42
  /** Re-render the full prompt for a date. */
39
- renderWithDate?: (date: string) => string;
43
+ renderWithDate: (date: string) => string;
40
44
  /** The initially-rendered system prompt. */
41
45
  systemPrompt: string;
42
46
  /** The `prompt.assembled` block view (the id wordlist is a downstream contract). */
@@ -44,10 +48,11 @@ export interface AssembledPrompt {
44
48
  id: string;
45
49
  text: string;
46
50
  }>;
47
- /** Compiled IR of the last render — manifest v2 source. */
48
- sections?: CompiledSection[];
49
- /** S4: physical system blocks of the last render (sema-default: ONE block, text === systemPrompt —
50
- * byte-identity). */
51
- systemBlocks?: CompiledSystemBlock[];
51
+ /** Compiled IR of the last render — the manifest's section source. */
52
+ sections: CompiledSection[];
53
+ /** Physical system blocks of the last render (one block, text === systemPrompt). */
54
+ systemBlocks: CompiledSystemBlock[];
55
+ /** The composition's {@link ComposedWithOverlays.superseded}, from the first render. */
56
+ superseded: readonly SupersededOverlay[];
52
57
  }
53
58
  export declare function assemblePrompt(inputs: AssembleInputs): AssembledPrompt;