@sema-agent/server 1.322.0 → 2.0.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 (539) hide show
  1. package/dist/approval-hmac.d.ts +40 -0
  2. package/dist/approval-hmac.js +67 -0
  3. package/dist/approval.d.ts +31 -0
  4. package/dist/approval.js +72 -4
  5. package/dist/audit.d.ts +26 -0
  6. package/dist/audit.js +40 -1
  7. package/dist/auth-bridge.d.ts +10 -0
  8. package/dist/auth-bridge.js +47 -4
  9. package/dist/auth-keys.d.ts +19 -0
  10. package/dist/auth-keys.js +13 -0
  11. package/dist/bake-runner/main.d.ts +5 -0
  12. package/dist/bake-runner/main.js +43 -4
  13. package/dist/bake-runner/protocol.d.ts +57 -0
  14. package/dist/bake-runner/protocol.js +58 -3
  15. package/dist/bake-runner/runner.d.ts +54 -0
  16. package/dist/bake-runner/runner.js +87 -5
  17. package/dist/bench/l8/artifact.d.ts +63 -0
  18. package/dist/bench/l8/artifact.js +61 -2
  19. package/dist/bench/l8/escape.d.ts +36 -0
  20. package/dist/bench/l8/escape.js +25 -0
  21. package/dist/bench/l8/index.d.ts +14 -0
  22. package/dist/bench/l8/index.js +14 -0
  23. package/dist/bench/l8/probes.d.ts +74 -0
  24. package/dist/bench/l8/probes.js +60 -0
  25. package/dist/bench/l8/run-probes.d.ts +43 -0
  26. package/dist/bench/l8/run-probes.js +45 -2
  27. package/dist/bench/s1/arms.d.ts +126 -0
  28. package/dist/bench/s1/arms.js +188 -13
  29. package/dist/bench/s1/live-deps.d.ts +66 -0
  30. package/dist/bench/s1/live-deps.js +249 -11
  31. package/dist/bench/s1/oracle.d.ts +49 -0
  32. package/dist/bench/s1/oracle.js +36 -1
  33. package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
  34. package/dist/bench/s1/repair-oracle-adapter.js +30 -0
  35. package/dist/bench/s1/reviewer.d.ts +38 -0
  36. package/dist/bench/s1/reviewer.js +34 -0
  37. package/dist/bench/s1/row.d.ts +77 -0
  38. package/dist/bench/s1/row.js +62 -0
  39. package/dist/bench/s1/run-firm.d.ts +47 -0
  40. package/dist/bench/s1/run-firm.js +70 -4
  41. package/dist/bench/s1/runner-ctx.d.ts +71 -0
  42. package/dist/bench/s1/runner-ctx.js +36 -0
  43. package/dist/bench/s1/tasks.d.ts +108 -0
  44. package/dist/bench/s1/tasks.js +115 -0
  45. package/dist/boot-reclaim.d.ts +19 -0
  46. package/dist/boot-reclaim.js +20 -0
  47. package/dist/brain.d.ts +25 -0
  48. package/dist/brain.js +61 -1
  49. package/dist/budget.d.ts +66 -0
  50. package/dist/budget.js +128 -4
  51. package/dist/capabilities/builtin-tools.d.ts +3 -0
  52. package/dist/capabilities/builtin-tools.js +3 -0
  53. package/dist/capabilities/center-plugins.d.ts +17 -1
  54. package/dist/capabilities/center-plugins.js +45 -4
  55. package/dist/capabilities/center-prompts.d.ts +46 -0
  56. package/dist/capabilities/center-prompts.js +57 -3
  57. package/dist/capabilities/code-review-council.d.ts +28 -0
  58. package/dist/capabilities/code-review-council.js +40 -7
  59. package/dist/capabilities/collab-wire.d.ts +2 -0
  60. package/dist/capabilities/collab-workflows.d.ts +7 -0
  61. package/dist/capabilities/collab-workflows.js +44 -1
  62. package/dist/capabilities/oa-tools.d.ts +6 -0
  63. package/dist/capabilities/oa-tools.js +10 -0
  64. package/dist/capabilities/prompt.d.ts +14 -0
  65. package/dist/capabilities/prompt.js +14 -0
  66. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  67. package/dist/capabilities/prompts/code-review.js +14 -0
  68. package/dist/capabilities/prompts/identity.d.ts +6 -0
  69. package/dist/capabilities/prompts/identity.js +6 -0
  70. package/dist/capabilities/prompts/team.d.ts +4 -0
  71. package/dist/capabilities/prompts/team.js +4 -0
  72. package/dist/capabilities/repo-tools.d.ts +11 -0
  73. package/dist/capabilities/repo-tools.js +8 -0
  74. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  75. package/dist/capabilities/sandbox-file-send.js +91 -3
  76. package/dist/capabilities/scenarios.d.ts +130 -0
  77. package/dist/capabilities/scenarios.js +180 -7
  78. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  79. package/dist/capabilities/select-environment-tool.js +30 -0
  80. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  81. package/dist/capabilities/send-user-file-tool.js +65 -1
  82. package/dist/capabilities/skills.d.ts +29 -0
  83. package/dist/capabilities/skills.js +13 -2
  84. package/dist/capabilities/team.d.ts +22 -0
  85. package/dist/capabilities/team.js +22 -2
  86. package/dist/capabilities/tool-defer.d.ts +26 -0
  87. package/dist/capabilities/tool-defer.js +3 -0
  88. package/dist/config-center/apply-effective.d.ts +65 -0
  89. package/dist/config-center/apply-effective.js +204 -12
  90. package/dist/config-center/http-client.d.ts +34 -0
  91. package/dist/config-center/http-client.js +68 -0
  92. package/dist/config-center/restart-signal.d.ts +22 -0
  93. package/dist/config-center/restart-signal.js +39 -0
  94. package/dist/config-center/skills-mcp.d.ts +20 -1
  95. package/dist/config-center/skills-mcp.js +42 -7
  96. package/dist/config-center/types.d.ts +92 -1
  97. package/dist/config-lkg.d.ts +12 -0
  98. package/dist/config-lkg.js +41 -0
  99. package/dist/config-provider.d.ts +78 -0
  100. package/dist/config-provider.js +165 -2
  101. package/dist/config-types.d.ts +546 -0
  102. package/dist/config.d.ts +64 -0
  103. package/dist/config.js +455 -60
  104. package/dist/degenerate-instrument.d.ts +38 -0
  105. package/dist/degenerate-instrument.js +55 -3
  106. package/dist/elicitation.d.ts +39 -0
  107. package/dist/elicitation.js +87 -3
  108. package/dist/env-facts.d.ts +61 -0
  109. package/dist/env-facts.js +73 -7
  110. package/dist/fleet/fleet-bus.d.ts +185 -0
  111. package/dist/fleet/fleet-bus.js +333 -27
  112. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  113. package/dist/fleet/subagent-tail-bus.js +33 -2
  114. package/dist/fleet-client.d.ts +38 -0
  115. package/dist/fleet-client.js +44 -9
  116. package/dist/fleet-lease.d.ts +46 -0
  117. package/dist/fleet-lease.js +73 -5
  118. package/dist/hooks/branch-transcript.d.ts +8 -0
  119. package/dist/hooks/branch-transcript.js +33 -0
  120. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  121. package/dist/hooks/cc-stop-prompt.js +43 -1
  122. package/dist/hooks/hook-llm.d.ts +15 -0
  123. package/dist/hooks/hook-llm.js +47 -0
  124. package/dist/hooks/hook-runner.d.ts +89 -0
  125. package/dist/hooks/hook-runner.js +327 -18
  126. package/dist/http/idempotency.d.ts +31 -0
  127. package/dist/http/idempotency.js +34 -0
  128. package/dist/http/principal-gate.d.ts +17 -0
  129. package/dist/http/principal-gate.js +35 -3
  130. package/dist/http/route-ctx.d.ts +36 -0
  131. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  132. package/dist/http/routes/approvals-assistant.js +253 -23
  133. package/dist/http/routes/attachments.js +22 -4
  134. package/dist/http/routes/capabilities.d.ts +7 -0
  135. package/dist/http/routes/capabilities.js +202 -1
  136. package/dist/http/routes/fleet.d.ts +6 -0
  137. package/dist/http/routes/fleet.js +94 -5
  138. package/dist/http/routes/images.d.ts +17 -0
  139. package/dist/http/routes/images.js +222 -14
  140. package/dist/http/routes/leader.d.ts +7 -0
  141. package/dist/http/routes/leader.js +10 -0
  142. package/dist/http/routes/memory-policy.d.ts +6 -0
  143. package/dist/http/routes/memory-policy.js +38 -6
  144. package/dist/http/routes/notify-wake.d.ts +10 -0
  145. package/dist/http/routes/notify-wake.js +19 -3
  146. package/dist/http/routes/observability.d.ts +6 -0
  147. package/dist/http/routes/observability.js +19 -2
  148. package/dist/http/routes/runs.d.ts +15 -0
  149. package/dist/http/routes/runs.js +464 -41
  150. package/dist/http/routes/session-sync.d.ts +15 -0
  151. package/dist/http/routes/session-sync.js +229 -19
  152. package/dist/http/routes/sessions-list.d.ts +6 -0
  153. package/dist/http/routes/sessions-list.js +35 -4
  154. package/dist/http/routes/sessions.d.ts +14 -0
  155. package/dist/http/routes/sessions.js +176 -31
  156. package/dist/http/routes/side-query.d.ts +8 -0
  157. package/dist/http/routes/side-query.js +26 -1
  158. package/dist/http/routes/tasks.d.ts +18 -0
  159. package/dist/http/routes/tasks.js +501 -38
  160. package/dist/http/routes/trace-usage.d.ts +10 -0
  161. package/dist/http/routes/trace-usage.js +66 -14
  162. package/dist/http/routes/workflows.d.ts +12 -0
  163. package/dist/http/routes/workflows.js +180 -19
  164. package/dist/http/run-meta.d.ts +11 -0
  165. package/dist/http/run-meta.js +6 -0
  166. package/dist/http/send.d.ts +19 -0
  167. package/dist/http/send.js +11 -0
  168. package/dist/http/server.d.ts +255 -0
  169. package/dist/http/server.js +921 -75
  170. package/dist/http/sse-log.d.ts +15 -0
  171. package/dist/http/sse-log.js +16 -0
  172. package/dist/http/tar.d.ts +9 -0
  173. package/dist/http/tar.js +21 -5
  174. package/dist/http/wire-gate.d.ts +9 -0
  175. package/dist/http/wire-gate.js +9 -0
  176. package/dist/http/wire-types.d.ts +187 -0
  177. package/dist/http/workspace-content.d.ts +8 -0
  178. package/dist/http/workspace-content.js +10 -0
  179. package/dist/images/bake-validate.d.ts +63 -0
  180. package/dist/images/bake-validate.js +71 -1
  181. package/dist/images/manifest.d.ts +19 -0
  182. package/dist/images/manifest.js +6 -1
  183. package/dist/index.d.ts +1 -5
  184. package/dist/index.js +10 -5
  185. package/dist/key-resolver.d.ts +23 -0
  186. package/dist/key-resolver.js +27 -2
  187. package/dist/leader/diffout.d.ts +23 -0
  188. package/dist/leader/diffout.js +8 -1
  189. package/dist/leader/diffup.d.ts +32 -0
  190. package/dist/leader/diffup.js +43 -0
  191. package/dist/leader/endpoint.d.ts +20 -0
  192. package/dist/leader/endpoint.js +25 -2
  193. package/dist/leader/fanout.d.ts +60 -0
  194. package/dist/leader/fanout.js +29 -3
  195. package/dist/leader/grader-env-factory.d.ts +74 -0
  196. package/dist/leader/grader-env-factory.js +62 -3
  197. package/dist/leader/leader.d.ts +97 -0
  198. package/dist/leader/leader.js +151 -4
  199. package/dist/leader/merge.d.ts +94 -0
  200. package/dist/leader/merge.js +112 -9
  201. package/dist/leader/planner.d.ts +52 -0
  202. package/dist/leader/planner.js +47 -3
  203. package/dist/leader/repair-oracle.d.ts +61 -0
  204. package/dist/leader/repair-oracle.js +59 -1
  205. package/dist/leader/repair-wire.d.ts +78 -0
  206. package/dist/leader/repair-wire.js +79 -2
  207. package/dist/leader/wire.d.ts +79 -0
  208. package/dist/leader/wire.js +255 -8
  209. package/dist/lsp/e2b-bridge.d.ts +16 -0
  210. package/dist/lsp/e2b-bridge.js +32 -4
  211. package/dist/lsp/e2b-manager.d.ts +10 -0
  212. package/dist/lsp/e2b-manager.js +18 -2
  213. package/dist/lsp/lsp-frames.d.ts +12 -0
  214. package/dist/lsp/lsp-frames.js +12 -0
  215. package/dist/lsp/manager.d.ts +12 -0
  216. package/dist/lsp/manager.js +35 -2
  217. package/dist/lsp/types.d.ts +10 -0
  218. package/dist/lsp/ws-transport.d.ts +12 -0
  219. package/dist/lsp/ws-transport.js +53 -5
  220. package/dist/lsp-evict.d.ts +14 -0
  221. package/dist/lsp-evict.js +15 -1
  222. package/dist/main.js +2132 -96
  223. package/dist/memory-export.d.ts +1 -0
  224. package/dist/memory-export.js +4 -0
  225. package/dist/memory-scope.d.ts +49 -0
  226. package/dist/memory-scope.js +87 -4
  227. package/dist/memory-sync-client.d.ts +24 -0
  228. package/dist/memory-sync-client.js +41 -2
  229. package/dist/memory-sync.d.ts +23 -0
  230. package/dist/memory-sync.js +70 -1
  231. package/dist/model-select.d.ts +39 -0
  232. package/dist/model-select.js +42 -1
  233. package/dist/observability/cost-quota.d.ts +20 -0
  234. package/dist/observability/cost-quota.js +4 -0
  235. package/dist/observability/cost-taxonomy.d.ts +45 -0
  236. package/dist/observability/cost-taxonomy.js +34 -0
  237. package/dist/observability/logger.d.ts +1 -0
  238. package/dist/observability/logger.js +6 -0
  239. package/dist/observability/metrics.d.ts +13 -0
  240. package/dist/observability/metrics.js +63 -0
  241. package/dist/observability/otel-exporter.d.ts +9 -0
  242. package/dist/observability/otel-exporter.js +11 -3
  243. package/dist/observability/principal-context.d.ts +9 -0
  244. package/dist/observability/principal-context.js +9 -0
  245. package/dist/observability/prompt-manifest.d.ts +37 -0
  246. package/dist/observability/prompt-manifest.js +35 -1
  247. package/dist/observability/rate-limit.d.ts +10 -0
  248. package/dist/observability/rate-limit.js +1 -0
  249. package/dist/observability/tool-trace.d.ts +24 -0
  250. package/dist/observability/tool-trace.js +41 -1
  251. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  252. package/dist/orchestration/hardened-vm-runner.js +119 -4
  253. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  254. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  255. package/dist/orchestration/hardened-vm-worker.js +27 -0
  256. package/dist/orchestration/subagent-steer.d.ts +44 -0
  257. package/dist/orchestration/subagent-steer.js +45 -1
  258. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  259. package/dist/orchestration/workflow-agent-steer.js +80 -1
  260. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  261. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  262. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  263. package/dist/orchestration/workflow-notify-journal.js +187 -13
  264. package/dist/parked-decide.d.ts +61 -0
  265. package/dist/parked-decide.js +58 -1
  266. package/dist/per-task-image.d.ts +54 -0
  267. package/dist/per-task-image.js +41 -0
  268. package/dist/plan-cache-probe.d.ts +35 -0
  269. package/dist/plan-cache-probe.js +18 -3
  270. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  271. package/dist/plugins/approval-exemption-store.js +28 -2
  272. package/dist/plugins/approval-store-sql.d.ts +64 -0
  273. package/dist/plugins/approval-store-sql.js +32 -0
  274. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  275. package/dist/plugins/background-agent-store-sql.js +91 -4
  276. package/dist/plugins/background-shell-support.d.ts +98 -0
  277. package/dist/plugins/background-shell-support.js +117 -13
  278. package/dist/plugins/blob-backend.d.ts +104 -0
  279. package/dist/plugins/blob-backend.js +163 -6
  280. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  281. package/dist/plugins/breaker-state-sql.js +46 -8
  282. package/dist/plugins/caching-session-store.d.ts +42 -0
  283. package/dist/plugins/caching-session-store.js +63 -3
  284. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  285. package/dist/plugins/checkpoint-store-sql.js +239 -11
  286. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  287. package/dist/plugins/file-outcome-sink.js +9 -0
  288. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  289. package/dist/plugins/file-resume-anchor-store.js +43 -4
  290. package/dist/plugins/file-run-store.d.ts +90 -0
  291. package/dist/plugins/file-run-store.js +145 -13
  292. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  293. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  294. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  295. package/dist/plugins/file-workflow-journal-store.js +10 -0
  296. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  297. package/dist/plugins/fork-routing-session-store.js +51 -3
  298. package/dist/plugins/host-platform.d.ts +69 -0
  299. package/dist/plugins/host-platform.js +81 -2
  300. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  301. package/dist/plugins/image-bake-store-sql.js +241 -7
  302. package/dist/plugins/image-index-sql.d.ts +46 -0
  303. package/dist/plugins/image-index-sql.js +113 -4
  304. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  305. package/dist/plugins/k8s-bg-scripts.js +88 -4
  306. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  307. package/dist/plugins/k8s-exec-protocol.js +41 -0
  308. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  309. package/dist/plugins/local-checkpoint-store.js +86 -7
  310. package/dist/plugins/local-session-store.d.ts +157 -0
  311. package/dist/plugins/local-session-store.js +289 -34
  312. package/dist/plugins/local-task-attachment-store.js +14 -2
  313. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  314. package/dist/plugins/mailbox-store-sql.js +39 -6
  315. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  316. package/dist/plugins/memory-engine-pg.js +122 -4
  317. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  318. package/dist/plugins/memory-engine-tidb.js +115 -5
  319. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  320. package/dist/plugins/memory-engine-vector-util.js +5 -0
  321. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  322. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  323. package/dist/plugins/memory-run-store.d.ts +63 -0
  324. package/dist/plugins/memory-run-store.js +73 -8
  325. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  326. package/dist/plugins/memory-session-policy-store.js +17 -0
  327. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  328. package/dist/plugins/memory-sync-store-pg.js +45 -2
  329. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  330. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  331. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  332. package/dist/plugins/outcome-ledger-sql.js +97 -3
  333. package/dist/plugins/pg-approval-store.d.ts +7 -0
  334. package/dist/plugins/pg-approval-store.js +7 -0
  335. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  336. package/dist/plugins/pg-breaker-state.js +6 -0
  337. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  338. package/dist/plugins/pg-checkpoint-store.js +8 -0
  339. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  340. package/dist/plugins/pg-cost-quota.js +6 -0
  341. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  342. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  343. package/dist/plugins/pg-image-bake.d.ts +9 -0
  344. package/dist/plugins/pg-image-bake.js +9 -0
  345. package/dist/plugins/pg-image-index.d.ts +9 -0
  346. package/dist/plugins/pg-image-index.js +9 -0
  347. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  348. package/dist/plugins/pg-outcome-ledger.js +9 -0
  349. package/dist/plugins/pg-pool.d.ts +50 -0
  350. package/dist/plugins/pg-pool.js +78 -0
  351. package/dist/plugins/pg-query.d.ts +11 -0
  352. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  353. package/dist/plugins/pg-rate-limiter.js +12 -2
  354. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  355. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  356. package/dist/plugins/pg-run-store.d.ts +7 -0
  357. package/dist/plugins/pg-run-store.js +7 -0
  358. package/dist/plugins/pg-safe-json.d.ts +13 -0
  359. package/dist/plugins/pg-safe-json.js +40 -4
  360. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  361. package/dist/plugins/pg-session-policy-store.js +5 -0
  362. package/dist/plugins/pg-session-storage.d.ts +72 -0
  363. package/dist/plugins/pg-session-storage.js +152 -20
  364. package/dist/plugins/pg-session-store.d.ts +10 -0
  365. package/dist/plugins/pg-session-store.js +10 -0
  366. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  367. package/dist/plugins/pg-tool-result-store.js +7 -0
  368. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  369. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  370. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  371. package/dist/plugins/pg-workflow-run-store.js +7 -0
  372. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  373. package/dist/plugins/posix-shell-fs.js +31 -1
  374. package/dist/plugins/remote-env-adb.d.ts +25 -0
  375. package/dist/plugins/remote-env-adb.js +95 -12
  376. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  377. package/dist/plugins/remote-env-e2b.js +371 -40
  378. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  379. package/dist/plugins/remote-env-file-error.js +37 -0
  380. package/dist/plugins/remote-env-host.d.ts +151 -0
  381. package/dist/plugins/remote-env-host.js +468 -70
  382. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  383. package/dist/plugins/remote-env-k8s.js +318 -32
  384. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  385. package/dist/plugins/remote-env-local-docker.js +149 -24
  386. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  387. package/dist/plugins/remote-env-ssh.js +117 -20
  388. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  389. package/dist/plugins/remote-scratchpad.js +32 -2
  390. package/dist/plugins/remote-shell.d.ts +22 -0
  391. package/dist/plugins/remote-shell.js +27 -1
  392. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  393. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  394. package/dist/plugins/roster-store-sql.d.ts +27 -0
  395. package/dist/plugins/roster-store-sql.js +54 -0
  396. package/dist/plugins/run-store-sql.d.ts +194 -0
  397. package/dist/plugins/run-store-sql.js +210 -9
  398. package/dist/plugins/s3-presign.d.ts +20 -0
  399. package/dist/plugins/s3-presign.js +49 -2
  400. package/dist/plugins/scheduler-support.d.ts +12 -0
  401. package/dist/plugins/scheduler-support.js +75 -3
  402. package/dist/plugins/send-file-ledger.d.ts +15 -0
  403. package/dist/plugins/send-file-ledger.js +53 -4
  404. package/dist/plugins/send-user-file.d.ts +77 -0
  405. package/dist/plugins/send-user-file.js +92 -4
  406. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  407. package/dist/plugins/session-policy-store-sql.js +75 -3
  408. package/dist/plugins/session-store.d.ts +45 -0
  409. package/dist/plugins/session-store.js +51 -0
  410. package/dist/plugins/sql-driver.d.ts +77 -0
  411. package/dist/plugins/sql-driver.js +4 -0
  412. package/dist/plugins/sql-escape.d.ts +8 -0
  413. package/dist/plugins/sql-escape.js +8 -0
  414. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  415. package/dist/plugins/sql-row-helpers.js +25 -0
  416. package/dist/plugins/store-backend.d.ts +103 -0
  417. package/dist/plugins/store-backend.js +120 -27
  418. package/dist/plugins/store-contracts.d.ts +62 -0
  419. package/dist/plugins/store-contracts.js +3 -0
  420. package/dist/plugins/task-attachment-store.d.ts +60 -0
  421. package/dist/plugins/task-attachment-store.js +49 -3
  422. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  423. package/dist/plugins/task-list-store-sql.js +21 -0
  424. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  425. package/dist/plugins/tidb-approval-store.js +6 -0
  426. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  427. package/dist/plugins/tidb-breaker-state.js +5 -0
  428. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  429. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  430. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  431. package/dist/plugins/tidb-cost-quota.js +1 -0
  432. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  433. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  434. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  435. package/dist/plugins/tidb-image-bake.js +8 -0
  436. package/dist/plugins/tidb-image-index.d.ts +8 -0
  437. package/dist/plugins/tidb-image-index.js +8 -0
  438. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  439. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  440. package/dist/plugins/tidb-pool.d.ts +56 -0
  441. package/dist/plugins/tidb-pool.js +181 -1
  442. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  443. package/dist/plugins/tidb-rate-limiter.js +5 -2
  444. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  445. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  446. package/dist/plugins/tidb-run-store.d.ts +7 -0
  447. package/dist/plugins/tidb-run-store.js +7 -0
  448. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  449. package/dist/plugins/tidb-session-policy-store.js +5 -0
  450. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  451. package/dist/plugins/tidb-session-storage.js +62 -3
  452. package/dist/plugins/tidb-session-store.d.ts +142 -0
  453. package/dist/plugins/tidb-session-store.js +264 -16
  454. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  455. package/dist/plugins/tidb-tool-result-store.js +7 -0
  456. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  457. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  458. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  459. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  460. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  461. package/dist/plugins/tool-result-store-sql.js +38 -2
  462. package/dist/plugins/web-search.d.ts +35 -0
  463. package/dist/plugins/web-search.js +45 -9
  464. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  465. package/dist/plugins/workflow-journal-limits.js +10 -0
  466. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  467. package/dist/plugins/workflow-journal-store-sql.js +59 -3
  468. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  469. package/dist/plugins/workflow-run-store-sql.js +84 -6
  470. package/dist/plugins/worktree-isolation.d.ts +45 -0
  471. package/dist/plugins/worktree-isolation.js +105 -6
  472. package/dist/plugins/write-behind-counter.d.ts +56 -1
  473. package/dist/plugins/write-behind-counter.js +53 -14
  474. package/dist/principal-jwt.d.ts +24 -0
  475. package/dist/principal-jwt.js +60 -5
  476. package/dist/project-memory.d.ts +22 -0
  477. package/dist/project-memory.js +144 -15
  478. package/dist/prompts-domain-validate.d.ts +28 -0
  479. package/dist/prompts-domain-validate.js +42 -1
  480. package/dist/question.d.ts +33 -0
  481. package/dist/question.js +69 -2
  482. package/dist/resource-suspend.d.ts +21 -0
  483. package/dist/resource-suspend.js +16 -0
  484. package/dist/router/route-orchestration.d.ts +78 -0
  485. package/dist/router/route-orchestration.js +77 -0
  486. package/dist/run-local.d.ts +32 -0
  487. package/dist/run-local.js +172 -8
  488. package/dist/runs.d.ts +189 -4
  489. package/dist/runs.js +465 -24
  490. package/dist/runtime-caps-resolver.d.ts +106 -0
  491. package/dist/runtime-caps-resolver.js +89 -4
  492. package/dist/runtime-governance.d.ts +84 -0
  493. package/dist/runtime-governance.js +127 -1
  494. package/dist/sandbox-pkg-source.d.ts +23 -0
  495. package/dist/sandbox-pkg-source.js +37 -0
  496. package/dist/sealed-key.d.ts +54 -0
  497. package/dist/sealed-key.js +68 -3
  498. package/dist/security.d.ts +108 -0
  499. package/dist/security.js +145 -6
  500. package/dist/sema-registry.d.ts +21 -0
  501. package/dist/sema-registry.js +21 -0
  502. package/dist/session-leaf-bus.d.ts +31 -0
  503. package/dist/session-leaf-bus.js +32 -0
  504. package/dist/session-sync-content.d.ts +46 -0
  505. package/dist/session-sync-content.js +47 -1
  506. package/dist/session-sync-kernel.d.ts +89 -0
  507. package/dist/session-sync-kernel.js +48 -3
  508. package/dist/session-sync.d.ts +125 -0
  509. package/dist/session-sync.js +181 -8
  510. package/dist/session-titler.d.ts +26 -0
  511. package/dist/session-titler.js +41 -7
  512. package/dist/session-watch.d.ts +53 -1
  513. package/dist/session-watch.js +73 -9
  514. package/dist/sighup-idle.d.ts +30 -0
  515. package/dist/sighup-idle.js +12 -1
  516. package/dist/spec-fields.d.ts +91 -3
  517. package/dist/spec-fields.js +116 -4
  518. package/dist/task-cwd.d.ts +50 -0
  519. package/dist/task-cwd.js +68 -1
  520. package/dist/task-mcp.d.ts +47 -0
  521. package/dist/task-mcp.js +29 -0
  522. package/dist/task-settings.d.ts +175 -0
  523. package/dist/task-settings.js +226 -11
  524. package/dist/task-workflow.d.ts +67 -0
  525. package/dist/task-workflow.js +75 -8
  526. package/dist/tool-approval.d.ts +91 -0
  527. package/dist/tool-approval.js +215 -0
  528. package/dist/trace/artifacts.d.ts +9 -0
  529. package/dist/trace/artifacts.js +30 -5
  530. package/dist/trace/core-keyset-guard.d.ts +18 -0
  531. package/dist/trace/ledger-sink.d.ts +43 -0
  532. package/dist/trace/ledger-sink.js +64 -5
  533. package/dist/trace/project.d.ts +133 -0
  534. package/dist/trace/project.js +189 -2
  535. package/dist/trace/redact.d.ts +19 -0
  536. package/dist/trace/redact.js +66 -9
  537. package/dist/usage-analytics.d.ts +26 -0
  538. package/dist/usage-analytics.js +26 -3
  539. package/package.json +1 -1
@@ -1,3 +1,10 @@
1
+ /**
2
+ * EffectiveConfig application — mutate the boot `ServiceConfig` OVER with a pulled `EffectiveConfig`
3
+ * (models/roles/tiers/projects `applyEffective`, the 6 runtime gates `applyRuntimeGates`, the per-request-hot
4
+ * governance baton `applyRuntimeHot`) plus their shared helpers (`toModel`, `mutateInPlace`,
5
+ * `resolveDefaultModelName`, `logEffectiveDiff`, `runtimeHasActiveGate`). Split out of `sema-registry.ts`
6
+ * (design/158 A13, internal-lossless — the facade re-exports every symbol below unchanged).
7
+ */
1
8
  import { isThinkingLevel } from "@sema-agent/core";
2
9
  import { resolveActiveTiers, SEALED_BOX_ALG } from "@sema-agent/registry-core";
3
10
  import { sealedKeyPoison } from "../sealed-key.js";
@@ -6,8 +13,11 @@ import { validateCommandRules } from "../runtime-governance.js";
6
13
  import { projectCollabToWorkflows, registerCollabWorkflows } from "../capabilities/collab-workflows.js";
7
14
  import { registerTeams } from "../capabilities/team.js";
8
15
  const asModelThinking = (v) => (v && isThinkingLevel(v) && v !== "off" ? v : undefined);
16
+ /** design/123: accept only a positive finite roster charsPerToken (fail-safe to env default / core 4). */
9
17
  const charsPerTokenOf = (v) => (typeof v === "number" && Number.isFinite(v) && v > 0 ? v : undefined);
10
18
  function toModel(m, envDefaults = {}) {
19
+ // design/111 L2②: a center model MAY declare defaultThinking/reasoningEffortLevels; absent → inherit the env-derived
20
+ // model's values (BL-8 — same class as reasoning/contextWindow/maxTokens, else a roster silently drops the env default).
11
21
  const thinkingDefault = asModelThinking(m.defaultThinking) ?? envDefaults.defaultThinking;
12
22
  const effortLevels = (m.reasoningEffortLevels ? m.reasoningEffortLevels.map(asModelThinking).filter((x) => x !== undefined) : undefined) ?? envDefaults.reasoningEffortLevels ?? [];
13
23
  const model = {
@@ -15,46 +25,93 @@ function toModel(m, envDefaults = {}) {
15
25
  name: m.name,
16
26
  provider: m.provider,
17
27
  api: m.api,
28
+ // 实机 /model 切 Kimi 404 定谳: a catalog model MAY carry its own gateway URL — the
29
+ // hardcoded "" made core's brain fall back to the boot-env endpoint, so cross-endpoint `body.model`
30
+ // selection hit the WRONG gateway (kimi id → Qwen vLLM → 404). Absent still = "" (brain env default;
31
+ // byte-compat for single-gateway rosters). core brain honors model.baseUrl; keys stay per-model via apiKeyEnv.
18
32
  baseUrl: m.baseUrl ?? "",
33
+ // BL-8 extended (systematic-audit): fall back to the ENV-derived model's reasoning, not Boolean(undefined)=false —
34
+ // else a center roster that omits `reasoning` SILENTLY disables it even though the env lane defaults it ON
35
+ // (config.ts MODEL_REASONING="true"). A center model MAY set false to override. Same class as contextWindow/maxTokens.
19
36
  reasoning: m.reasoning !== undefined ? Boolean(m.reasoning) : (envDefaults.reasoning ?? true),
20
37
  input: m.vision ? ["text", "image"] : ["text"],
38
+ // BL-8: fall back to the ENV-derived model's value (MODEL_CONTEXT_WINDOW / MODEL_MAX_TOKENS), not a
39
+ // hardcoded literal — else a center roster that replaces the env model SILENTLY clamps maxTokens to 4096
40
+ // (the prod review-gw runs deepseek at 32000), shrinking every response. A center model MAY still set its
41
+ // own value to override. (ROBUSTNESS-BACKLOG:28 / BL-8.)
21
42
  contextWindow: m.contextWindow ?? envDefaults.contextWindow ?? 262144,
22
43
  maxTokens: m.maxTokens ?? envDefaults.maxTokens ?? 4096,
44
+ // design/123 D2 (BL-8 class): center override ?? env default (MODEL_CHARS_PER_TOKEN) ?? omit = core 4.
45
+ // Positive-finite guard mirrors the env lane — a bad roster value must not zero structural estimates.
23
46
  ...(charsPerTokenOf(m.charsPerToken) !== undefined || envDefaults.charsPerToken !== undefined
24
47
  ? { charsPerToken: charsPerTokenOf(m.charsPerToken) ?? envDefaults.charsPerToken }
25
48
  : {}),
26
49
  cost: m.cost
27
50
  ? { input: m.cost.input, output: m.cost.output, cacheRead: m.cost.cacheRead ?? 0, cacheWrite: m.cost.cacheWrite ?? 0 }
28
51
  : { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
52
+ // Explicit cache family by provider (core 1.23) — same as the env path in config.ts. Anthropic brain
53
+ // reports input EXCLUDING cached; the openai gateway INCLUDES it (design/18).
29
54
  params: { ...(m.tier ? { tier: m.tier } : {}), promptCacheFamily: m.provider === "anthropic" ? "input-excludes-cached" : "input-includes-cached" },
55
+ // design/111 L2②: per-model default thinking + endpoint-accepted tiers (center override ?? env default, BL-8).
30
56
  ...(thinkingDefault ? { defaultThinking: thinkingDefault } : {}),
31
57
  ...(effortLevels.length > 0 && m.provider !== "anthropic" ? { compat: { reasoningEffortLevels: effortLevels } } : {}),
58
+ // Generation tuning (1.60) carried verbatim — without this a center roster that replaces the env model
59
+ // would silently drop the degenerate-looping prevention (freq/pres penalties). Absent → unchanged.
32
60
  ...(m.extraBody ? { extraBody: m.extraBody } : {}),
61
+ // Per-model behavior-slot sentences ([998]⑤c consumer half) — verbatim, same posture as extraBody.
33
62
  ...(Array.isArray(m.promptGuidance) && m.promptGuidance.length > 0 ? { promptGuidance: m.promptGuidance.map(String) } : {}),
34
63
  };
64
+ // [818]① 1M dual-window: an explicit roster `autoCompactTokens` (structural, like tier passthroughs) wins;
65
+ // else a >=1M contextWindow derives the CC-aligned 967000; else absent. Same helper as the env lane.
35
66
  const explicitAct = m.autoCompactTokens;
36
67
  applyAutoCompactWindow(model, typeof explicitAct === "number" ? explicitAct : undefined);
37
68
  return model;
38
69
  }
70
+ /** Apply center config OVER the env-derived config (mutates `config`). Empty domains keep env defaults. */
71
+ /** Replace a record's contents IN PLACE (clear keys, copy source) so holders of the SAME reference see the
72
+ * change. This is what makes models/roles/pricing HOT-apply: core's Runner reads
73
+ * `this.deps.models/roles/pricing` LIVE per-task and `/v1/models` reads `config.models` — both share the
74
+ * reference captured at boot, so mutating it (vs reassigning) updates both with no split, no Runner rebuild. */
39
75
  export function mutateInPlace(target, source) {
40
76
  for (const k of Object.keys(target))
41
77
  delete target[k];
42
78
  Object.assign(target, source);
43
79
  }
44
80
  export function applyEffective(config, eff, logger, opts = {}) {
81
+ // version 0 / empty effective = the sema-registry has nothing for us yet — typically CONFIG_PUBLISH_MODE
82
+ // is ON but nothing has been published. We do NOT wipe: models/roles fall back to env (the enabled>0
83
+ // guard below), teams to BUILTIN_TEAMS (registerTeams resets to built-ins). Warn once at boot so the
84
+ // operator knows their config isn't live (publish a version, or disable the publish gate). See the
85
+ // sema-registry's ORCHESTRATOR-REVIEW §④ publish-gate contract.
45
86
  if (!opts.teamsOnly && !eff.version) {
46
87
  logger?.warn("sema_registry_unpublished", {
47
88
  version: eff.version,
48
89
  note: "empty/unpublished effective config — using env + built-in fallback; publish a config or unset CONFIG_PUBLISH_MODE",
49
90
  });
50
91
  }
92
+ // models/roles HOT-apply on BOTH boot and refresh (TOC "save = effective"). We MUTATE
93
+ // config.models/roles IN PLACE (mutateInPlace) — NOT reassign — so the live Runner (reads `this.deps.models/
94
+ // roles` per-task by reference) and `/v1/models` (reads config.models) share the one updated object with NO
95
+ // split, no Runner rebuild, no core change. Caller (main.ts refresh) additionally refreshes `pricing` (same
96
+ // ref) + rebuilds `keyResolver`. (Was startup-only when reassignment split the Runner's ref from config.)
51
97
  const enabled = (eff.models?.models ?? []).filter((m) => m.enabled !== false);
98
+ // codex R10: `deferModelPlane` skips the WHOLE model plane (models/roles/tiers + per-model keys) — main.ts
99
+ // sets it when the Runner is tier-frozen (private expanded copy) and the plane changed: hot-applying would
100
+ // split admission (/v1/models, catalog gates) from the Runner's frozen generation, letting a same-key retarget
101
+ // silently route/bill the stale Model object through the restart window. Deferred = live plane stays on the
102
+ // Runner's generation; the models-tiers restart slice signals the orchestrator; the restarted process applies
103
+ // the new plane at boot BEFORE Runner construction. Caller logs the deferral (never silent).
52
104
  if (enabled.length > 0 && opts.deferModelPlane !== true) {
53
105
  const models = {};
54
106
  const modelApiKeyEnv = {};
55
- const modelApiKeys = {};
107
+ const modelApiKeys = {}; // sealed-box 解封明文(内存-only,绝不日志/落盘)或毒丸标记(解封失败,见下)
108
+ // Capture the env-derived model's generation bounds BEFORE the loop overwrites config.model (line below):
109
+ // a center model that omits maxTokens/contextWindow inherits the operator's env values, not a literal (BL-8).
56
110
  const envDefaults = { maxTokens: config.model.maxTokens, contextWindow: config.model.contextWindow, reasoning: config.model.reasoning, charsPerToken: config.model.charsPerToken, defaultThinking: config.model.defaultThinking, reasoningEffortLevels: config.model.compat?.reasoningEffortLevels };
57
111
  for (const m of enabled) {
112
+ // Guard (since 1.128.0): a registry baseUrl now DIRECTS model traffic (incl. that model's
113
+ // Authorization key) — a registry editor is a lower-trust writer than the env, so a non-http(s)/unparsable
114
+ // value is REJECTED back to "" (boot-env gateway) and every honored override is logged (observable routing).
58
115
  const rawBaseUrl = m.baseUrl;
59
116
  let safeUrl = rawBaseUrl;
60
117
  if (rawBaseUrl) {
@@ -74,6 +131,22 @@ export function applyEffective(config, eff, logger, opts = {}) {
74
131
  }
75
132
  }
76
133
  models[m.name] = toModel(safeUrl === rawBaseUrl ? m : { ...m, baseUrl: safeUrl }, envDefaults);
134
+ // Sealed-box custody (registry-core 0.10.5): a model MAY carry `sealedApiKey` — the
135
+ // api key pasted in the web UI and sealed BROWSER-SIDE against this host's X25519 public key; the
136
+ // center stores only the ciphertext. We unseal with the private key registered under the EXACT
137
+ // `publicKeyId` (no try-every-key scanning — the contract selects precisely) and inject the
138
+ // plaintext into the in-memory per-model key pipeline (config.modelApiKeys → getApiKeyAndHeaders).
139
+ // Mutual exclusion (contract): sealed OUTRANKS apiKeyEnv when both are set — and STRICTLY so: a
140
+ // sealed key that fails to unseal (missing private key / bad base64 / MAC failure) does NOT fall
141
+ // back to the env-NAME reference. Falling back would turn "the key I pasted isn't live" into a
142
+ // silent misroute onto some stale env key; we fail LOUD (warn). And since a merely-ABSENT map
143
+ // entry is indistinguishable from "no per-model key configured" — which with a gateway
144
+ // MODEL_API_KEY deployed meant the model's tasks silently burned the shared account — a failed
145
+ // unseal plants a POISON PILL in the map instead of injecting nothing: the key resolver turns it
146
+ // into a task-level SealedKeyPoisonedError on every brain call (the gateway key is NEVER a silent
147
+ // fallback for a broken sealed key) until the operator fixes custody and a later apply delivers a
148
+ // decryptable ciphertext (the rebuild below makes recovery automatic). 🔴 Neither the plaintext
149
+ // NOR the ciphertext ever reaches a log line or the poison object (write-only discipline).
77
150
  if (m.sealedApiKey) {
78
151
  const s = m.sealedApiKey;
79
152
  if (s.alg !== SEALED_BOX_ALG) {
@@ -98,18 +171,30 @@ export function applyEffective(config, eff, logger, opts = {}) {
98
171
  }
99
172
  }
100
173
  }
174
+ // Per-model key: center declares the env var NAME (never the secret) holding this model's upstream
175
+ // key. Drives the spec's getApiKeyAndHeaders so each model authenticates with its own account; the
176
+ // value is resolved from process.env in THIS service (secrets stay in env, design/15). A model
177
+ // without apiKeyEnv (or whose env var is unset) falls back to the gateway key — purely additive.
178
+ // (`else if` on sealedApiKey ABSENCE: a sealed model never consults the env reference — see above.)
101
179
  else if (m.apiKeyEnv) {
102
180
  if (process.env[m.apiKeyEnv])
103
181
  modelApiKeyEnv[m.name] = m.apiKeyEnv;
104
182
  else
105
183
  logger?.warn("sema_registry_model_key_env_missing", { model: m.name, apiKeyEnv: m.apiKeyEnv, hint: "env var not set in this service — model falls back to the gateway key" });
106
184
  }
185
+ // A center model whose provider has no matching brain in THIS service's env will mis-route:
186
+ // createRoutingBrain falls back to the gateway brain. The anthropic route needs ANTHROPIC_API_KEY.
107
187
  if (m.provider === "anthropic" && !config.anthropic) {
108
188
  logger?.warn("sema_registry_model_no_brain", { model: m.name, provider: m.provider, hint: "set ANTHROPIC_API_KEY in this service's env, else it mis-routes to the gateway brain" });
109
189
  }
110
190
  }
111
- config.modelApiKeyEnv = modelApiKeyEnv;
112
- config.modelApiKeys = modelApiKeys;
191
+ config.modelApiKeyEnv = modelApiKeyEnv; // reassign ok — keyResolver is rebuilt from it on refresh (main.ts)
192
+ // same rebuild contract; plaintext values — memory-only, never logged. Poison markers ride the same
193
+ // map (they ARE per-model key state: "configured but broken"); the cast bridges config.ts's
194
+ // plaintext-only field type until it is widened to Record<string, string | SealedKeyPoison>.
195
+ config.modelApiKeys = modelApiKeys; // 类型已放真(string | SealedKeyPoison),桥接 cast 退役
196
+ // weight-at-burn 源:quotaWeight 按 name+id 双键索引(tracer 的 brain.call e.model=模型 id,
197
+ // 目录键=name——双键免猜);非法值(≤0/NaN)按缺省 1 丢弃。IN PLACE 与 models 同批 hot-apply。
113
198
  const quotaWeights = {};
114
199
  for (const m of enabled) {
115
200
  const qw = typeof m.quotaWeight === "number" && Number.isFinite(m.quotaWeight) && m.quotaWeight > 0 ? m.quotaWeight : undefined;
@@ -127,27 +212,53 @@ export function applyEffective(config, eff, logger, opts = {}) {
127
212
  else if ("select" in tgt)
128
213
  roles[role] = { select: tgt.select };
129
214
  }
215
+ // registry-core 0.9.0: tier groups → the engine's single active tier table. `resolveActiveTiers`
216
+ // is registry-core's ONE resolution point (active group → its bound tiers; no active / dangling / all-unbound
217
+ // → undefined = INERT). Values are catalog NAME strings (open, not enum'd); dangling bindings were already
218
+ // culled center-side. mutateInPlace keeps the reference RunnerDeps.tiers holds — the expansion itself happens
219
+ // at Runner CONSTRUCTION (core 1.265 expandTiers), so a refresh-time change is restart-to-apply like models.
220
+ // NOTE: the wire face (this module's EffectiveConfig) carries the JSON body verbatim, so tierGroups ride
221
+ // eff.models even though CenterModel doesn't type them — resolveActiveTiers reads them structurally.
130
222
  const activeTiers = resolveActiveTiers(eff.models) ?? {};
223
+ // [865]①(clay 生产实锤:onboard 选 kimi 实跑 Qwen)显式默认解析——enabled[0] 会被任何改变 pool 顺序的写
224
+ // 静默翻转,default 必须消费 wire 里已有的显式意图。解析单源 = resolveDefaultModelName(dry-run 的
225
+ // wouldDefaultModel 共用同一只,报数与真 apply 永不撕裂——codex M2)。
131
226
  const picked = resolveDefaultModelName(eff, (n) => models[n] !== undefined, enabled[0].name, (source, name) => logger?.warn("sema_registry_default_dangling", { source, name, hint: "explicit default names a model that is not in the enabled catalog — falling to the next source" }));
132
227
  const defaultName = picked.name;
133
228
  const defaultSource = picked.source;
134
229
  models.default = models[defaultName];
135
- mutateInPlace(config.models, models);
230
+ mutateInPlace(config.models, models); // IN PLACE: keep the ref the Runner + /v1/models share (hot-apply)
136
231
  config.model = config.models.default;
137
232
  if (Object.keys(roles).length > 0)
138
- mutateInPlace(config.roles, roles);
233
+ mutateInPlace(config.roles, roles); // IN PLACE: Runner reads this.deps.roles live
139
234
  mutateInPlace(config.tiers, activeTiers);
140
235
  logger?.info("sema_registry_models", { count: enabled.length, default: config.model.id, defaultSource, roles: Object.keys(roles), tiers: Object.keys(config.tiers), sealedKeys: Object.values(modelApiKeys).filter((v) => typeof v === "string").length, sealedPoisoned: Object.values(modelApiKeys).filter((v) => typeof v !== "string").length });
141
236
  }
237
+ // Runtime governance/limit gates (phase-2): STARTUP only (restart-to-apply) — the live RateLimiter / CostQuota
238
+ // / approval gate are built from `config` AFTER this in main.ts, so mutating it here before they're constructed
239
+ // is what takes effect; a refresh (teamsOnly) must NOT touch them (the running gates hold their boot values).
240
+ // governance 切新位:治理三件优先读 governance 域(真值),runtime 旧位(双写镜像)fallback——
241
+ // 双写期两处逐键相等语义不变;center 撤双写后 governance 即唯一来源。限额残余(rateLimit/cost 五件)仍在 runtime。
142
242
  const gatesView = eff.governance ? { ...eff.runtime, ...eff.governance } : eff.runtime;
143
243
  if (!opts.teamsOnly)
144
244
  applyRuntimeGates(config, gatesView, logger);
245
+ // Runtime governance "second baton" (center §10): autonomy + commandPolicy are per-request HOT (read live in
246
+ // resolveSpec), NOT baked into boot middleware → apply on BOTH boot and refresh (outside the teamsOnly guard) so
247
+ // they hot-reload. No restart-to-apply signal (they take effect on the next task without a restart).
145
248
  applyRuntimeHot(config, gatesView, logger);
249
+ // Teams → registry (hot-reloadable; center overrides/extends the built-ins).
250
+ // codex R11: teams + collab workflows carry MODEL REFERENCES (member.model / workflow model args) — when the
251
+ // model plane is deferred (tier-frozen Runner, see the deferModelPlane guard above) these faces must defer
252
+ // WITH it, or a candidate that atomically adds/retargets a model AND updates a team/workflow to reference it
253
+ // publishes a mixed generation: the new template goes live while config.models/the Runner stay old (a new ref
254
+ // fails as unknown; a same-name retarget silently executes stale). One catalog generation = one visibility.
146
255
  if (opts.deferModelPlane !== true) {
147
256
  const teams = {};
148
257
  for (const t of (eff.teams?.teams ?? []).filter((t) => t.enabled !== false)) {
149
258
  teams[t.name] = {
150
259
  name: t.name,
260
+ // F8: honor member.model (core TeamMember.model supports it) — was silently dropped, leaving the
261
+ // member to fall back to the "team" role instead of the operator's chosen model.
151
262
  members: t.members.map((mm) => ({ role: mm.role, ...(mm.model ? { model: mm.model } : {}), modelRole: mm.modelRole, systemPrompt: mm.systemPrompt })),
152
263
  rounds: t.rounds,
153
264
  synthesizer: t.synthesizer ? { role: t.synthesizer.role, modelRole: t.synthesizer.modelRole, systemPrompt: t.synthesizer.systemPrompt } : undefined,
@@ -156,6 +267,11 @@ export function applyEffective(config, eff, logger, opts = {}) {
156
267
  registerTeams(teams);
157
268
  if (Object.keys(teams).length > 0)
158
269
  logger?.info("sema_registry_teams", { teams: Object.keys(teams) });
270
+ // collab → named-workflow projection(切片 1.5,design/140 统一解;切片① 的
271
+ // TeamTemplate 投影已整体替换——纪律「别留双路径降级」)。可投影子集翻译成命名 workflow 注册条目
272
+ // (执行体=core 内置 team-discussion 脚本,center 模板=defaultArgs 合并链第二级;键=collab id,shell
273
+ // `/team`/LLM 经 Workflow({name}) 调用);子集外整条跳过+结构化上报,绝不静默降级。HOT:boot+refresh
274
+ // 双腿整表替换(非粘——center 停发即空表,内置 workflow 不受影响)。
159
275
  const projected = projectCollabToWorkflows(eff.collab?.templates);
160
276
  registerCollabWorkflows(projected.workflows);
161
277
  if (Object.keys(projected.workflows).length > 0)
@@ -165,6 +281,11 @@ export function applyEffective(config, eff, logger, opts = {}) {
165
281
  if (projected.notes.length > 0)
166
282
  logger?.info("sema_registry_collab_notes", { notes: projected.notes });
167
283
  }
284
+ // 142-S4 projects 域(registry-core 0.10.0):center 项目登记簿 → config.projects(键=
285
+ // projectId)。消费是 per-request 查表(memoryScope 派生 + defaultScopes 种子,security.ts/main.ts),
286
+ // 所以 boot+refresh 双腿都 mutateInPlace 热应用(整表替换,非粘——center 停发即清空);env lane 恒空。
287
+ // 宽读:域包裹 `{projects:{...}}`(registry-core ProjectsConfig 真形状)与裸 Record 都认(projectId=UUID,
288
+ // 永不撞 "projects" 字面键);防御:非 object 条目跳过,字段逐个验型(wire verbatim,不信任形状)。
168
289
  const projDomain = eff.projects;
169
290
  const rawProjects = (projDomain && typeof projDomain === "object" && !Array.isArray(projDomain)
170
291
  ? "projects" in projDomain && typeof projDomain.projects === "object"
@@ -174,7 +295,7 @@ export function applyEffective(config, eff, logger, opts = {}) {
174
295
  const projects = {};
175
296
  for (const [pid, reg] of Object.entries(rawProjects)) {
176
297
  if (!reg || typeof reg !== "object" || Array.isArray(reg))
177
- continue;
298
+ continue; // defensive: non-object entry → skip
178
299
  const r = reg;
179
300
  projects[pid] = {
180
301
  ...(typeof r.displayName === "string" ? { displayName: r.displayName } : {}),
@@ -182,11 +303,36 @@ export function applyEffective(config, eff, logger, opts = {}) {
182
303
  ...(Array.isArray(r.defaultScopes) ? { defaultScopes: r.defaultScopes.filter((x) => typeof x === "string") } : {}),
183
304
  };
184
305
  }
185
- mutateInPlace(config.projects, projects);
306
+ mutateInPlace(config.projects, projects); // IN PLACE: keep the ref per-request consumers captured at boot
186
307
  if (Object.keys(projects).length > 0)
187
308
  logger?.info("sema_registry_projects", { projects: Object.keys(projects) });
188
309
  }
310
+ /**
311
+ * Apply the center `runtime` governance/limit gates OVER the env-derived config (mutates `config`).
312
+ *
313
+ * UNIFORM presence semantics across all 6 gates (center `f95438a` adopted this from our sentinel flag —
314
+ * SERVICE-INTEGRATION「Runtime 治理/限额闸」): all six fields are center `.optional()`, so
315
+ * `undefined` = center isn't managing it → KEEP env;
316
+ * present (any value, INCLUDING an explicit 0 / [] = "publish the gate OFF") → OVERRIDE env.
317
+ * (Earlier center had `rateLimitPerMin`/`approvalRequire` as `.default(0/[])`, which would have let a default
318
+ * silently disable an env-set gate — we flagged it, center made all six optional, so a plain presence rule is
319
+ * now both correct and uniform. No sentinel special-casing.)
320
+ *
321
+ * Only guard: `costQuotaWindowSec` must be `> 0` (a 0 window is nonsensical — core divides by it). Center's
322
+ * schema is `.positive()` so it can't send 0; this is belt-and-suspenders.
323
+ *
324
+ * Per-worker overrides ride the per-worker `/effective?worker=` response (center merges WorkerSpec.runtime over
325
+ * the fleet default server-side), so this single "effective beats env" rule already honors per-worker > fleet.
326
+ */
327
+ /** The 6 runtime governance/limit gates, in ONE place (council DRY): the consume loop, the restart-to-apply
328
+ * signal, and the dry-run diff all derive from this list, so adding a 7th gate is a single edit and can't
329
+ * silently miss `runtimeHasActiveGate` (which would break the restart-to-apply warning). All six share keys
330
+ * across `EffectiveConfig["runtime"]` and `ServiceConfig`. Exported (not in the original single-file form) so
331
+ * the sibling restart-signal module can share the identical key list + presence rule. */
189
332
  export const RUNTIME_GATE_KEYS = ["rateLimitPerMin", "approvalRequire", "maxTaskCostUsd", "maxTaskTokens", "maxPrincipalCostUsd", "costQuotaWindowSec"];
333
+ /** Uniform presence rule (center f95438a): a gate is "managed" when the field is present — any number (incl. 0),
334
+ * or an array for approvalRequire. Sole guard: costQuotaWindowSec must be > 0 (a 0 window is nonsensical — core
335
+ * divides by it; center's `.positive()` already enforces, belt-and-suspenders here). */
190
336
  export function runtimeGatePresent(rt, key) {
191
337
  const v = rt[key];
192
338
  if (key === "approvalRequire")
@@ -201,21 +347,42 @@ export function applyRuntimeGates(config, rt, logger) {
201
347
  const applied = {};
202
348
  for (const key of RUNTIME_GATE_KEYS) {
203
349
  if (!runtimeGatePresent(rt, key))
204
- continue;
205
- config[key] = rt[key];
350
+ continue; // undefined / sentinel → keep env
351
+ config[key] = rt[key]; // present (incl. explicit 0/[]) → override
206
352
  applied[key] = rt[key];
207
353
  }
208
354
  if (Object.keys(applied).length > 0)
209
355
  logger?.info("sema_registry_runtime", applied);
210
356
  }
357
+ /**
358
+ * Apply the runtime governance "second baton" (center §10): `autonomy` + `commandPolicy`. UNLIKE the 6 gates in
359
+ * {@link applyRuntimeGates}, these are per-request HOT (read live in main.ts `resolveSpec` via
360
+ * `applyRuntimeGovernance`), so they apply on BOTH boot and refresh (NOT via RUNTIME_GATE_KEYS / restart-to-apply).
361
+ *
362
+ * 🔴 NON-STICKY (differs from the restart-to-apply gates on purpose — adversarial-review HIGH): a hot field that
363
+ * center STOPS publishing must REVERT to the env baseline, not keep the last center value. The restart-to-apply
364
+ * gates can be sticky because a refresh never touches them (the running middleware holds boot values until a
365
+ * restart re-reads env+center); a HOT field has no such reset, so "absent ⇒ keep" would silently freeze a stale
366
+ * center override (e.g. center published `auto`, then un-published it — the gate would stay OFF forever). So we
367
+ * recompute every call as `present ? center : envBaseline`. The env baseline = `AUTONOMY` (re-derived, env is
368
+ * immutable at runtime) for autonomy; `undefined` (no env scalar source) for commandPolicy.
369
+ *
370
+ * 🔴 commandPolicy is VALIDATED here (adversarial-review HIGH): an invalid command (glob/path/operator — which
371
+ * core's EXACT-name matcher would silently never match → a hole) is rejected FAIL-LOUD and the prior good policy
372
+ * is KEPT (a broken publish never half-applies a silently-weakened gate).
373
+ */
211
374
  export function applyRuntimeHot(config, rt, logger) {
212
375
  const applied = {};
376
+ // autonomy: present ⇒ center value; absent ⇒ revert to the env baseline (never a stale center override).
213
377
  const envAutonomy = parseAutonomy(process.env.AUTONOMY);
214
378
  const nextAutonomy = rt?.autonomy !== undefined ? rt.autonomy : envAutonomy;
215
379
  if (config.autonomy !== nextAutonomy) {
216
380
  config.autonomy = nextAutonomy;
217
381
  applied.autonomy = nextAutonomy ?? "(env-baseline)";
218
382
  }
383
+ // commandPolicy: present+valid ⇒ apply; present+invalid ⇒ fail-loud + keep prior; absent ⇒ revert to baseline
384
+ // (undefined — no env scalar source for structured command rules). Only re-set + log on an ACTUAL change
385
+ // (deep-equal compare) — refresh runs every ~60s and the policy is usually unchanged; logging every tick = noise.
219
386
  if (rt?.commandPolicy !== undefined) {
220
387
  const errors = validateCommandRules(rt.commandPolicy);
221
388
  if (errors.length > 0) {
@@ -223,17 +390,32 @@ export function applyRuntimeHot(config, rt, logger) {
223
390
  }
224
391
  else if (JSON.stringify(config.commandPolicy) !== JSON.stringify(rt.commandPolicy)) {
225
392
  config.commandPolicy = rt.commandPolicy;
226
- applied.commandPolicy = rt.commandPolicy.length;
393
+ applied.commandPolicy = rt.commandPolicy.length; // log the COUNT, not the rules (avoid leaking on every refresh)
227
394
  }
228
395
  }
229
396
  else if (config.commandPolicy !== undefined) {
230
- config.commandPolicy = undefined;
397
+ config.commandPolicy = undefined; // center stopped managing → revert to baseline (no env source)
231
398
  applied.commandPolicy = "(env-baseline)";
232
399
  }
233
400
  if (Object.keys(applied).length > 0)
234
401
  logger?.info("sema_registry_runtime_hot", applied);
235
402
  }
403
+ /** [865]①/H3:activeTierGroup 档绑定当默认时的档梯,与 core 单一语义源逐字对齐(core roles.js:
404
+ * `ROLE_TIER_DEFAULTS.default = "pro"` + `resolveTier` 从本档位置**只向低档**扫 DEFAULT_TIER_ORDER
405
+ * [ultra,max,pro,flash,lite] ⇒ pro→flash→lite,绝不向上抓 max/ultra——引擎运行时对 "default" 角色就是
406
+ * 这么解析的,applyEffective 的 default 若用别的梯子会与真路由再度撕裂,codex H3)。 */
236
407
  const DEFAULT_ROLE_TIER_LADDER = ["pro", "flash", "lite"];
408
+ /**
409
+ * [865]① 显式默认解析——applyEffective 与 dry-run(logEffectiveDiff.wouldDefaultModel)共用的单源。优先级
410
+ * (显式源指向不在目录/未启用的名 ⇒ onDangling 回调后落下一级,绝不静默指错模型):
411
+ * 1) eff.models.default 结构键 —— ✅ 既得路径([874] registry-core 0.10.11 落 `default?: string` schema
412
+ * 键+per-worker /effective 直通;本地 lane 由 config-provider mapToServiceEffective 直通)。写面悬空 ref
413
+ * 由 registry-core superRefine fail-loud;存量/未经 schema 路径仍走本函数的 warn 降级(双层姿势与
414
+ * activeTierGroup 同构)。(1.200-1.202 期间此级恒空=当时如实的前行 seam,codex H2 注记已兑现。)
415
+ * 2) roles.default 的显式 {model} 绑定(现有 wire 真源)。
416
+ * 3) activeTierGroup 档绑定,按 {@link DEFAULT_ROLE_TIER_LADDER}(= core 对 "default" 角色的档语义)。
417
+ * 4) fallback(enabled[0]——原兜底,唯一不触发 onDangling 的落点)。
418
+ */
237
419
  export function resolveDefaultModelName(eff, has, fallback, onDangling) {
238
420
  const activeTiers = resolveActiveTiers(eff.models) ?? {};
239
421
  const structural = eff.models?.default;
@@ -252,6 +434,11 @@ export function resolveDefaultModelName(eff, has, fallback, onDangling) {
252
434
  }
253
435
  return { name: fallback, source: "enabled[0]" };
254
436
  }
437
+ /**
438
+ * Read-only comparison (SEMA_REGISTRY_DRY_RUN): log what the center config WOULD change vs the current
439
+ * (env-derived) config, WITHOUT applying it. The safe-rollout step the sema-registry recommends — verify
440
+ * the center's models/roles/teams match (or intentionally differ from) the env baseline before going live.
441
+ */
255
442
  export function logEffectiveDiff(config, eff, logger) {
256
443
  const enabled = (eff.models?.models ?? []).filter((m) => m.enabled !== false);
257
444
  const centerModels = enabled.map((m) => ({ name: m.name, id: m.id, provider: m.provider, apiKeyEnv: m.apiKeyEnv ?? null, tier: m.tier ?? null }));
@@ -261,7 +448,9 @@ export function logEffectiveDiff(config, eff, logger) {
261
448
  logger?.warn("sema_registry_dry_run", {
262
449
  note: "DRY RUN — registry config NOT applied; unset SEMA_REGISTRY_DRY_RUN to go live",
263
450
  version: eff.version,
264
- wouldOverrideModels: enabled.length > 0,
451
+ wouldOverrideModels: enabled.length > 0, // empty/unpublished center → env baseline kept (no override)
452
+ // [865]①/codex M2:与 applyEffective 同一只解析器——dry-run 的上线前核验必须报真 apply 会选的默认,
453
+ // 报 enabled[0] 会让核验对显式默认(roles.default/tier 档)配置给出错误结论。
265
454
  wouldDefaultModel: enabled.length > 0 ? resolveDefaultModelName(eff, (n) => enabled.some((m) => m.name === n), enabled[0].name).name : null,
266
455
  currentDefaultModel: config.model.id,
267
456
  models: { center: centerModels, envDerived: envModels },
@@ -270,11 +459,14 @@ export function logEffectiveDiff(config, eff, logger) {
270
459
  skills: { centerWouldLoad: (eff.skills?.skills ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
271
460
  mcp: { centerWouldRegister: (eff.mcp?.servers ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
272
461
  runtime: {
462
+ // What the gates would become if applied (present center value overrides; absent → kept env shown as current).
273
463
  center: eff.runtime ?? null,
274
464
  current: Object.fromEntries(RUNTIME_GATE_KEYS.map((k) => [k, config[k]])),
275
465
  },
276
466
  });
277
467
  }
468
+ /** True if the center `runtime` carries any managed gate (a PRESENT field) — i.e. a refresh that changed it
469
+ * needs a restart to take effect (restart-to-apply). Same key list + presence rule as applyRuntimeGates. */
278
470
  export function runtimeHasActiveGate(rt) {
279
471
  if (!rt)
280
472
  return false;
@@ -1,10 +1,30 @@
1
1
  import type { EntitlementRuntimeCaps } from "@sema-agent/registry-core";
2
2
  import type { ScenarioRuling } from "../capabilities/scenarios.js";
3
3
  import type { EffectiveConfig, ExecutionRuling } from "./types.js";
4
+ /** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error. */
4
5
  export declare function fetchEffective(baseUrl: string, token: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
5
6
  effective: EffectiveConfig;
6
7
  etag?: string;
7
8
  } | null>;
9
+ /**
10
+ * design/99 §K (core 1.157 `RunnerDeps.runtimeCapsResolver`) — GET the PER-PRINCIPAL runtime
11
+ * ENTITLEMENTS the engine enforces server-side, from center's `GET /api/config/effective?principal=&worker=`.
12
+ * Center pre-resolves the tighten-only intersection (fleet defaults ∩ tier ⊕ roles + overrides) and returns a
13
+ * `runtimeCaps` block — the service passes it through verbatim (no further tightening, per center's ruling).
14
+ *
15
+ * 🔐 TOKEN/WORKER (center ruling, sema-registry `aeb4979`): two valid postures —
16
+ * • FULL `SERVICE_PULL_TOKEN` + `?principal=` → full per-user body (caps + per-user config).
17
+ * • worker-scoped `wpt_<self>` + `?principal=&worker=<self>` → **caps-only** body (`{principal, configured,
18
+ * runtimeCaps, budget}`; never other tenants' config) — a worker MAY resolve its OWN worker's principals.
19
+ * A `wpt_` with NO `?worker=` (or a mismatched worker) still 403s. So we ALWAYS pass `?worker=` when the
20
+ * deployment has one (`SEMA_REGISTRY_WORKER`): it authorizes the wpt_ path AND is harmless on the full token
21
+ * (the caps value is worker-independent — `resolveEntitlement` resolves from the principal alone; worker only
22
+ * scopes the config view we ignore). This re-adds the `worker` arg dropped in 1.14.0 (L2-3) — center's ruling
23
+ * makes it load-bearing for AUTHORIZATION, not for the caps value.
24
+ * `null` = 304 (caller keeps its cached value). THROWS on transport / non-304 HTTP error → the resolver
25
+ * fail-closes (core then DENIES the optional `allowWorkflows` cap — an outage must never silently GRANT). ETag is
26
+ * content-hashed (`p-<hash>`); an `if-none-match` poll is cheap. Mirrors `fetchEffective` (Bearer + 8s + scheme guard).
27
+ */
8
28
  export declare function fetchPrincipalCaps(baseUrl: string, token: string, principal: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
9
29
  runtimeCaps: EntitlementRuntimeCaps | null;
10
30
  configured: boolean;
@@ -13,11 +33,25 @@ export declare function fetchPrincipalCaps(baseUrl: string, token: string, princ
13
33
  executionDrift?: string;
14
34
  etag?: string;
15
35
  } | null>;
36
+ /** An HTTP error from a sema-registry fetch that carries the response status so callers can branch on it
37
+ * (e.g. translate a 404 to "unknown hash → undefined") WITHOUT parsing the message string. */
16
38
  export declare class ConfigCenterHttpError extends Error {
17
39
  readonly status: number;
18
40
  constructor(message: string, status: number);
19
41
  }
42
+ /**
43
+ * Fetch one skill's body by content hash (`GET /api/config/skills/content/<hash>`, Bearer) and VERIFY its
44
+ * sha256 matches the manifest hash (integrity + tamper check). The content is immutable per hash, so the
45
+ * caller caches by hash and never re-fetches an unchanged skill. Throws a {@link ConfigCenterHttpError}
46
+ * (carrying `.status`) on an HTTP error — INCLUDING 404 — or a plain Error on hash mismatch. Callers that
47
+ * want "unknown hash → undefined" parity with the local backend inspect `.status === 404` and swallow it;
48
+ * the legacy `applyCenterSkills` path keeps treating every throw as "skip this skill, keep baseline".
49
+ */
20
50
  export declare function fetchSkillContent(baseUrl: string, token: string, contentHash: string, fetchImpl?: typeof fetch): Promise<string>;
51
+ /** [985]b / [1285]① — §9.4 by-digest 补拉二函(fetchSkillContent 同姿势:HTTP+Bearer+8s 超时+
52
+ * 消费侧自证)。artifact=envelope JSON(验真=调用方过 core verifyPromptArtifact,canonical 重算——
53
+ * 本函数只做传输与形读,不越权解释);blob=段文本 raw-byte(sha256 逐位自证,fetchSkillContent 同款)。
54
+ * digest 参数收带前缀/裸 hex 两形([1285] 参数口径)。 */
21
55
  export declare function fetchPromptArtifact(baseUrl: string, token: string, artifactDigest: string, fetchImpl?: typeof fetch): Promise<unknown>;
22
56
  export declare function fetchPromptBlob(baseUrl: string, token: string, contentDigest: string, fetchImpl?: typeof fetch): Promise<string>;
23
57
  //# sourceMappingURL=http-client.d.ts.map
@@ -1,8 +1,19 @@
1
+ /**
2
+ * sema-registry HTTP client — the transport calls the service makes against the config-center
3
+ * (`fetchEffective`/`fetchPrincipalCaps`/`fetchSkillContent`/`fetchPromptArtifact`/`fetchPromptBlob`) plus
4
+ * the shared HTTP-error type. Split out of `sema-registry.ts` (design/158 A13, internal-lossless — the
5
+ * facade re-exports every symbol below unchanged).
6
+ */
1
7
  import { createHash } from "node:crypto";
8
+ /** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error. */
2
9
  export async function fetchEffective(baseUrl, token, etag, fetchImpl = fetch, worker) {
10
+ // Defensive scheme guard: Node's fetch supports file:// — a mis-set
11
+ // SEMA_REGISTRY_URL must not turn into a local-file read. Reject anything but http(s).
3
12
  const scheme = new URL(baseUrl).protocol;
4
13
  if (scheme !== "http:" && scheme !== "https:")
5
14
  throw new Error(`SEMA_REGISTRY_URL must be http(s), got "${scheme}"`);
15
+ // worker-scoped pull: `?worker=<name>` returns that worker's roster; omitted → the global roster
16
+ // (backward compatible — the center returns today's global config when no worker is given).
6
17
  const url = `${baseUrl.replace(/\/+$/, "")}/api/config/effective${worker ? `?worker=${encodeURIComponent(worker)}` : ""}`;
7
18
  const res = await fetchImpl(url, {
8
19
  headers: { authorization: `Bearer ${token}`, ...(etag ? { "if-none-match": etag } : {}) },
@@ -14,10 +25,30 @@ export async function fetchEffective(baseUrl, token, etag, fetchImpl = fetch, wo
14
25
  throw new Error(`sema-registry HTTP ${res.status}`);
15
26
  return { effective: (await res.json()), etag: res.headers.get("etag") ?? undefined };
16
27
  }
28
+ /**
29
+ * design/99 §K (core 1.157 `RunnerDeps.runtimeCapsResolver`) — GET the PER-PRINCIPAL runtime
30
+ * ENTITLEMENTS the engine enforces server-side, from center's `GET /api/config/effective?principal=&worker=`.
31
+ * Center pre-resolves the tighten-only intersection (fleet defaults ∩ tier ⊕ roles + overrides) and returns a
32
+ * `runtimeCaps` block — the service passes it through verbatim (no further tightening, per center's ruling).
33
+ *
34
+ * 🔐 TOKEN/WORKER (center ruling, sema-registry `aeb4979`): two valid postures —
35
+ * • FULL `SERVICE_PULL_TOKEN` + `?principal=` → full per-user body (caps + per-user config).
36
+ * • worker-scoped `wpt_<self>` + `?principal=&worker=<self>` → **caps-only** body (`{principal, configured,
37
+ * runtimeCaps, budget}`; never other tenants' config) — a worker MAY resolve its OWN worker's principals.
38
+ * A `wpt_` with NO `?worker=` (or a mismatched worker) still 403s. So we ALWAYS pass `?worker=` when the
39
+ * deployment has one (`SEMA_REGISTRY_WORKER`): it authorizes the wpt_ path AND is harmless on the full token
40
+ * (the caps value is worker-independent — `resolveEntitlement` resolves from the principal alone; worker only
41
+ * scopes the config view we ignore). This re-adds the `worker` arg dropped in 1.14.0 (L2-3) — center's ruling
42
+ * makes it load-bearing for AUTHORIZATION, not for the caps value.
43
+ * `null` = 304 (caller keeps its cached value). THROWS on transport / non-304 HTTP error → the resolver
44
+ * fail-closes (core then DENIES the optional `allowWorkflows` cap — an outage must never silently GRANT). ETag is
45
+ * content-hashed (`p-<hash>`); an `if-none-match` poll is cheap. Mirrors `fetchEffective` (Bearer + 8s + scheme guard).
46
+ */
17
47
  export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchImpl = fetch, worker) {
18
48
  const scheme = new URL(baseUrl).protocol;
19
49
  if (scheme !== "http:" && scheme !== "https:")
20
50
  throw new Error(`SEMA_REGISTRY_URL must be http(s), got "${scheme}"`);
51
+ // `?principal=<id>[&worker=<self>]` — worker authorizes the wpt_<self> caps-only path; harmless on a full token.
21
52
  const params = new URLSearchParams({ principal });
22
53
  if (worker)
23
54
  params.set("worker", worker);
@@ -27,6 +58,9 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
27
58
  signal: AbortSignal.timeout(8000),
28
59
  });
29
60
  if (res.status === 304) {
61
+ // A 304 is only valid as a reply to OUR conditional. If we sent no etag and still got 304, center is
62
+ // misbehaving — DON'T treat it as "unchanged" (that surfaces undefined caps = no restriction = fail OPEN).
63
+ // Throw so the resolver fail-closes (review B). With an etag, 304 = genuine "unchanged" → null.
30
64
  if (!etag)
31
65
  throw new Error("sema-registry returned 304 to a non-conditional principal-caps request");
32
66
  return null;
@@ -37,6 +71,10 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
37
71
  return {
38
72
  runtimeCaps: body.runtimeCaps ?? null,
39
73
  configured: Boolean(body.configured),
74
+ // The caps view carries the RESOLVED per-principal scenario ruling (two keys, shape pinned
75
+ // by center tests). An older center has NO such keys → undefined (no governance, legacy passthrough) —
76
+ // distinct from the "assigned nothing" ruling {scenario:null, allowlist:[]} a newer center returns.
77
+ // Defensive on shape (scenario face is fail-open — see gateScenarioRequest): non-string entries dropped.
40
78
  ...("scenario" in body || "allowlist" in body
41
79
  ? {
42
80
  scenario: {
@@ -45,6 +83,15 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
45
83
  },
46
84
  }
47
85
  : {}),
86
+ // (stage7 P5, registry-core 0.8 execution 域): the caps view's per-principal execution
87
+ // ruling `{required, allowedLanes}` — same car, same no-cache semantics as the scenario ruling. An
88
+ // older center has no key → undefined (no enforcement). allowedLanes is an OPEN value domain
89
+ // (adding a lane is never BREAKING) — tolerate unknown names, drop non-string ELEMENTS defensively.
90
+ // shape DRIFT (required non-boolean / allowedLanes non-array) must NOT be
91
+ // coerced — the old coercion turned "allowedLanes came as a comma string" + required=true into
92
+ // allowedLanes=[] = fleet-wide deny-all (fail-CLOSED on a wire glitch, opposite of the fail-open posture)
93
+ // and a drifted `required` into silent non-enforcement. Now: drift ⇒ DROP the whole ruling (fail-open,
94
+ // gate passes) + `executionDrift` so the caller's audit line fires (the resolver routes it to onError).
48
95
  ...((() => {
49
96
  const ex = body.execution;
50
97
  if (ex === undefined || ex === null)
@@ -54,6 +101,10 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
54
101
  if (!Array.isArray(ex.allowedLanes))
55
102
  return { executionDrift: `execution.allowedLanes is ${typeof ex.allowedLanes}, expected string[] — ruling dropped (fail-open)` };
56
103
  const execution = { required: ex.required, allowedLanes: ex.allowedLanes.filter((s) => typeof s === "string") };
104
+ // registry-core 0.10.1-0.10.2:execution.sessionMirror 宽读。observation-only 子面
105
+ // (server 非执法端,见 ExecutionRuling.sessionMirror 注),所以形状漂移只丢**本子面**并走 executionDrift
106
+ // 审计线(resolver 路由到 onError),**绝不**连带丢 lane ruling(那是真执法面,不能被观测子面拖垮)。
107
+ // required 缺省 false = registry-core zod 默认(便利态);engineUrl 必须非空 string。
57
108
  if (ex.sessionMirror !== undefined && ex.sessionMirror !== null) {
58
109
  const sm = ex.sessionMirror;
59
110
  const smOk = typeof sm === "object" && typeof sm.engineUrl === "string" && sm.engineUrl.length > 0 && (sm.required === undefined || typeof sm.required === "boolean");
@@ -67,6 +118,8 @@ export async function fetchPrincipalCaps(baseUrl, token, principal, etag, fetchI
67
118
  etag: res.headers.get("etag") ?? undefined,
68
119
  };
69
120
  }
121
+ /** An HTTP error from a sema-registry fetch that carries the response status so callers can branch on it
122
+ * (e.g. translate a 404 to "unknown hash → undefined") WITHOUT parsing the message string. */
70
123
  export class ConfigCenterHttpError extends Error {
71
124
  status;
72
125
  constructor(message, status) {
@@ -75,6 +128,14 @@ export class ConfigCenterHttpError extends Error {
75
128
  this.name = "ConfigCenterHttpError";
76
129
  }
77
130
  }
131
+ /**
132
+ * Fetch one skill's body by content hash (`GET /api/config/skills/content/<hash>`, Bearer) and VERIFY its
133
+ * sha256 matches the manifest hash (integrity + tamper check). The content is immutable per hash, so the
134
+ * caller caches by hash and never re-fetches an unchanged skill. Throws a {@link ConfigCenterHttpError}
135
+ * (carrying `.status`) on an HTTP error — INCLUDING 404 — or a plain Error on hash mismatch. Callers that
136
+ * want "unknown hash → undefined" parity with the local backend inspect `.status === 404` and swallow it;
137
+ * the legacy `applyCenterSkills` path keeps treating every throw as "skip this skill, keep baseline".
138
+ */
78
139
  export async function fetchSkillContent(baseUrl, token, contentHash, fetchImpl = fetch) {
79
140
  const url = `${baseUrl.replace(/\/+$/, "")}/api/config/skills/content/${encodeURIComponent(contentHash)}`;
80
141
  const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
@@ -87,6 +148,10 @@ export async function fetchSkillContent(baseUrl, token, contentHash, fetchImpl =
87
148
  throw new Error(`skill content hash mismatch for ${contentHash}: computed sha256:${got}`);
88
149
  return content;
89
150
  }
151
+ /** [985]b / [1285]① — §9.4 by-digest 补拉二函(fetchSkillContent 同姿势:HTTP+Bearer+8s 超时+
152
+ * 消费侧自证)。artifact=envelope JSON(验真=调用方过 core verifyPromptArtifact,canonical 重算——
153
+ * 本函数只做传输与形读,不越权解释);blob=段文本 raw-byte(sha256 逐位自证,fetchSkillContent 同款)。
154
+ * digest 参数收带前缀/裸 hex 两形([1285] 参数口径)。 */
90
155
  export async function fetchPromptArtifact(baseUrl, token, artifactDigest, fetchImpl = fetch) {
91
156
  const url = `${baseUrl.replace(/\/+$/, "")}/api/config/prompts/epoch-artifacts/${encodeURIComponent(artifactDigest)}`;
92
157
  const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
@@ -99,6 +164,9 @@ export async function fetchPromptBlob(baseUrl, token, contentDigest, fetchImpl =
99
164
  const res = await fetchImpl(url, { headers: { authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(8000) });
100
165
  if (!res.ok)
101
166
  throw new ConfigCenterHttpError(`prompt blob HTTP ${res.status} for ${contentDigest}`, res.status);
167
+ // codex F2(补拉批):哈希必须打在**响应原始字节**上(res.text() 的 UTF-8 宽容解码会剥 BOM/替换坏序列
168
+ // ——验的就不再是送来的字节,content-addressed 完整性破功);验过再严格解码(fatal:true,坏 UTF-8
169
+ // 掷错而非静默替换)。
102
170
  const bytes = new Uint8Array(await res.arrayBuffer());
103
171
  const want = contentDigest.replace(/^sha256:/, "").toLowerCase();
104
172
  const got = createHash("sha256").update(bytes).digest("hex");