@sema-agent/server 7.132.0 → 7.134.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 (473) hide show
  1. package/MIGRATION.md +353 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +301 -64
  5. package/deploy/sema-up/README.md +35 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
  11. package/deploy/sema-up/chart/templates/server.yaml +19 -2
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/deploy/sema-up/stack/compose.yaml +3 -0
  15. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  16. package/dist/adoption/plan.d.ts +3 -2
  17. package/dist/adoption/plan.js +7 -5
  18. package/dist/adoption/runner.js +3 -10
  19. package/dist/adoption/sql.d.ts +3 -2
  20. package/dist/adoption/sql.js +3 -5
  21. package/dist/adoption/wire.d.ts +4 -1
  22. package/dist/adoption/wire.js +1 -0
  23. package/dist/approval-ask-audit-store.d.ts +32 -14
  24. package/dist/approval-ask-audit-store.js +272 -74
  25. package/dist/approval-ask-machine.d.ts +15 -0
  26. package/dist/approval-ask-machine.js +6 -0
  27. package/dist/approval-ask-retention.d.ts +136 -0
  28. package/dist/approval-ask-retention.js +102 -0
  29. package/dist/approval-card.d.ts +83 -23
  30. package/dist/approval-card.js +45 -15
  31. package/dist/approval-content-kind.d.ts +5 -2
  32. package/dist/approval-content-kind.js +16 -3
  33. package/dist/approval-deny-reasons.d.ts +1 -1
  34. package/dist/approval-gate-currency.d.ts +72 -0
  35. package/dist/approval-gate-currency.js +94 -0
  36. package/dist/approval.d.ts +15 -0
  37. package/dist/approval.js +55 -17
  38. package/dist/audit.d.ts +27 -10
  39. package/dist/audit.js +12 -16
  40. package/dist/bake-runner/main.js +3 -2
  41. package/dist/boot/coordinators.d.ts +6 -1
  42. package/dist/boot/coordinators.js +6 -3
  43. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  44. package/dist/boot/execution-env.js +9 -7
  45. package/dist/boot/execution-lane.js +11 -0
  46. package/dist/boot/leader.d.ts +2 -0
  47. package/dist/boot/leader.js +4 -1
  48. package/dist/boot/memory-boundary.js +2 -2
  49. package/dist/boot/memory-consolidation.d.ts +5 -4
  50. package/dist/boot/memory-consolidation.js +7 -6
  51. package/dist/boot/org-delivery.d.ts +28 -0
  52. package/dist/boot/org-delivery.js +20 -0
  53. package/dist/boot/read-deny-anchor-audit.js +2 -2
  54. package/dist/boot/reapers.d.ts +3 -0
  55. package/dist/boot/reapers.js +21 -1
  56. package/dist/boot/resolve-spec.d.ts +3 -0
  57. package/dist/boot/resolve-spec.js +60 -81
  58. package/dist/boot/runner-deps.d.ts +18 -5
  59. package/dist/boot/runner-deps.js +10 -0
  60. package/dist/boot/session-faces.d.ts +1 -0
  61. package/dist/boot/session-faces.js +4 -2
  62. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  63. package/dist/boot/stage-06-runners.d.ts +6 -3
  64. package/dist/boot/stage-06-runners.js +20 -4
  65. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  66. package/dist/boot/stage-07-capability-layer.js +24 -3
  67. package/dist/boot/stage-08-reapers.d.ts +4 -1
  68. package/dist/boot/stage-08-reapers.js +2 -2
  69. package/dist/boot/stage-09-leader.d.ts +5 -1
  70. package/dist/boot/stage-09-leader.js +2 -2
  71. package/dist/boot/stage-10-http-server.d.ts +5 -1
  72. package/dist/boot/stage-10-http-server.js +6 -6
  73. package/dist/boot/stores.d.ts +8 -0
  74. package/dist/boot/stores.js +10 -14
  75. package/dist/boot/web-admin.d.ts +10 -0
  76. package/dist/boot/web-admin.js +162 -65
  77. package/dist/boot/workflow-orchestration.d.ts +2 -0
  78. package/dist/boot/workflow-orchestration.js +2 -1
  79. package/dist/brain.js +8 -3
  80. package/dist/breaker-key.d.ts +6 -0
  81. package/dist/breaker-key.js +29 -0
  82. package/dist/budget.js +5 -1
  83. package/dist/caller-text-echo.d.ts +11 -6
  84. package/dist/caller-text-echo.js +10 -12
  85. package/dist/canonical-json.d.ts +2 -41
  86. package/dist/canonical-json.js +2 -13
  87. package/dist/capabilities/center-plugins.d.ts +7 -0
  88. package/dist/capabilities/center-plugins.js +1 -1
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +21 -0
  93. package/dist/capabilities/hands-lane.js +10 -0
  94. package/dist/capabilities/mcp-probe.d.ts +36 -4
  95. package/dist/capabilities/mcp-probe.js +29 -6
  96. package/dist/capabilities/scenarios.d.ts +63 -7
  97. package/dist/capabilities/scenarios.js +39 -7
  98. package/dist/capability-facts.d.ts +36 -4
  99. package/dist/capability-facts.js +30 -4
  100. package/dist/center-config-tier.d.ts +69 -0
  101. package/dist/center-config-tier.js +42 -0
  102. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  103. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  104. package/dist/checkpoint-identity.d.ts +16 -0
  105. package/dist/checkpoint-identity.js +19 -0
  106. package/dist/config-catalog.d.ts +17 -10
  107. package/dist/config-catalog.js +43 -28
  108. package/dist/config-d-migration.d.ts +3 -1
  109. package/dist/config-d-migration.js +2 -2
  110. package/dist/config-dir-trust.d.ts +114 -0
  111. package/dist/config-dir-trust.js +388 -0
  112. package/dist/config-invariants.d.ts +18 -5
  113. package/dist/config-invariants.js +35 -3
  114. package/dist/config-provider.d.ts +6 -1
  115. package/dist/config-provider.js +6 -2
  116. package/dist/config-types.d.ts +71 -14
  117. package/dist/config-types.js +8 -0
  118. package/dist/config.d.ts +13 -0
  119. package/dist/config.js +121 -59
  120. package/dist/delegated-session-owner.d.ts +185 -0
  121. package/dist/delegated-session-owner.js +119 -0
  122. package/dist/device-protocol.d.ts +5 -3
  123. package/dist/device-protocol.js +1 -1
  124. package/dist/device-ws-hub.js +21 -2
  125. package/dist/device-ws-protocol.d.ts +70 -6
  126. package/dist/device-ws-protocol.js +50 -23
  127. package/dist/elicitation.js +3 -2
  128. package/dist/entry-problems.d.ts +34 -0
  129. package/dist/entry-problems.js +14 -0
  130. package/dist/execution-lane-caps.d.ts +49 -10
  131. package/dist/execution-lane-caps.js +43 -4
  132. package/dist/field-conflict.d.ts +44 -0
  133. package/dist/field-conflict.js +21 -0
  134. package/dist/file-history-disclosure.d.ts +34 -5
  135. package/dist/file-history-disclosure.js +2 -2
  136. package/dist/fleet/fleet-bus.d.ts +84 -6
  137. package/dist/fleet/fleet-bus.js +42 -9
  138. package/dist/hooks/classic-stations.d.ts +10 -5
  139. package/dist/hooks/classic-stations.js +4 -4
  140. package/dist/hooks/command-spawn.d.ts +57 -0
  141. package/dist/hooks/command-spawn.js +139 -0
  142. package/dist/hooks/hook-llm.js +2 -2
  143. package/dist/hooks/hook-runner.d.ts +127 -25
  144. package/dist/hooks/hook-runner.js +668 -287
  145. package/dist/hooks/hook-source.d.ts +44 -0
  146. package/dist/hooks/hook-source.js +40 -0
  147. package/dist/http/active-run-conflict.d.ts +5 -13
  148. package/dist/http/active-run-conflict.js +17 -27
  149. package/dist/http/admission.js +111 -60
  150. package/dist/http/approval-sweeps.js +58 -19
  151. package/dist/http/caller-trust.d.ts +77 -0
  152. package/dist/http/caller-trust.js +143 -0
  153. package/dist/http/checkpoint-ctx.d.ts +173 -18
  154. package/dist/http/checkpoint-ctx.js +171 -12
  155. package/dist/http/claimed-run.d.ts +4 -3
  156. package/dist/http/device-placement.d.ts +2 -4
  157. package/dist/http/device-placement.js +2 -1
  158. package/dist/http/dispatch.js +13 -7
  159. package/dist/http/durable-run-leg.d.ts +4 -32
  160. package/dist/http/durable-run-leg.js +37 -12
  161. package/dist/http/idempotency.d.ts +2 -2
  162. package/dist/http/idempotency.js +2 -2
  163. package/dist/http/owner-access.d.ts +56 -0
  164. package/dist/http/owner-access.js +42 -0
  165. package/dist/http/principal-gate.d.ts +78 -27
  166. package/dist/http/principal-gate.js +64 -14
  167. package/dist/http/readiness.d.ts +11 -5
  168. package/dist/http/readiness.js +10 -3
  169. package/dist/http/refusal-body.d.ts +12 -0
  170. package/dist/http/refusal-body.js +11 -0
  171. package/dist/http/request-guards.d.ts +16 -32
  172. package/dist/http/request-guards.js +31 -30
  173. package/dist/http/resume-ctx-read.d.ts +50 -6
  174. package/dist/http/resume-ctx-read.js +33 -7
  175. package/dist/http/resume-legs.d.ts +5 -5
  176. package/dist/http/resume-legs.js +163 -91
  177. package/dist/http/retired-service-deps.d.ts +43 -0
  178. package/dist/http/retired-service-deps.js +18 -0
  179. package/dist/http/route-ctx.d.ts +44 -37
  180. package/dist/http/route-ctx.js +4 -0
  181. package/dist/http/route-table.js +2 -0
  182. package/dist/http/routes/a2a-serve.js +3 -4
  183. package/dist/http/routes/admin-config-refresh.js +1 -1
  184. package/dist/http/routes/admin-drain.js +1 -1
  185. package/dist/http/routes/admin-memory-optout.js +5 -1
  186. package/dist/http/routes/adoption.js +2 -9
  187. package/dist/http/routes/agents-roster.js +2 -3
  188. package/dist/http/routes/approvals-assistant.js +91 -56
  189. package/dist/http/routes/background.js +3 -2
  190. package/dist/http/routes/capabilities.js +20 -4
  191. package/dist/http/routes/config-catalog.d.ts +3 -3
  192. package/dist/http/routes/config-catalog.js +1 -1
  193. package/dist/http/routes/devices.js +3 -17
  194. package/dist/http/routes/diagnostics.d.ts +3 -3
  195. package/dist/http/routes/diagnostics.js +6 -2
  196. package/dist/http/routes/fleet.js +4 -4
  197. package/dist/http/routes/images.js +6 -7
  198. package/dist/http/routes/leader.js +1 -8
  199. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  200. package/dist/http/routes/mcp-reconnect.js +3 -2
  201. package/dist/http/routes/memory-bundle.js +1 -1
  202. package/dist/http/routes/memory-compliance.js +1 -1
  203. package/dist/http/routes/memory-consolidation.js +1 -1
  204. package/dist/http/routes/memory-origin.d.ts +1 -1
  205. package/dist/http/routes/memory-origin.js +1 -1
  206. package/dist/http/routes/memory-policy.d.ts +1 -1
  207. package/dist/http/routes/memory-policy.js +3 -2
  208. package/dist/http/routes/notify-wake.js +8 -21
  209. package/dist/http/routes/observability.js +2 -2
  210. package/dist/http/routes/principal-inbox.d.ts +39 -0
  211. package/dist/http/routes/principal-inbox.js +76 -0
  212. package/dist/http/routes/retention-ops.js +2 -9
  213. package/dist/http/routes/rules.js +9 -22
  214. package/dist/http/routes/runs.d.ts +5 -0
  215. package/dist/http/routes/runs.js +63 -115
  216. package/dist/http/routes/session-sync.d.ts +3 -2
  217. package/dist/http/routes/session-sync.js +53 -48
  218. package/dist/http/routes/sessions-list.d.ts +1 -1
  219. package/dist/http/routes/sessions-list.js +3 -4
  220. package/dist/http/routes/sessions.js +33 -43
  221. package/dist/http/routes/side-query.js +6 -4
  222. package/dist/http/routes/tasks.js +71 -30
  223. package/dist/http/routes/trace-usage.js +7 -9
  224. package/dist/http/routes/workflows.d.ts +351 -0
  225. package/dist/http/routes/workflows.js +153 -119
  226. package/dist/http/run-declared-families.d.ts +16 -0
  227. package/dist/http/run-declared-families.js +12 -0
  228. package/dist/http/send.d.ts +24 -3
  229. package/dist/http/send.js +14 -2
  230. package/dist/http/server.d.ts +23 -18
  231. package/dist/http/server.js +20 -15
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +4 -3
  234. package/dist/http/submit-ctx.js +23 -6
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +17 -10
  238. package/dist/index.d.ts +3 -1
  239. package/dist/index.js +1 -1
  240. package/dist/lane-home-probe.d.ts +78 -9
  241. package/dist/lane-home-probe.js +78 -12
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/leader/wire.d.ts +4 -0
  245. package/dist/leader/wire.js +8 -7
  246. package/dist/limit-refusal.d.ts +17 -5
  247. package/dist/limit-refusal.js +4 -1
  248. package/dist/main.js +1 -1
  249. package/dist/mcp-assertion-header.d.ts +31 -10
  250. package/dist/mcp-assertion-header.js +10 -3
  251. package/dist/memory-origin-fence.js +2 -2
  252. package/dist/memory-project-layer.d.ts +37 -0
  253. package/dist/memory-project-layer.js +46 -0
  254. package/dist/memory-scope.d.ts +23 -16
  255. package/dist/memory-scope.js +24 -8
  256. package/dist/memory-sync-client.d.ts +27 -13
  257. package/dist/memory-sync-client.js +107 -18
  258. package/dist/model-compat.d.ts +1 -1
  259. package/dist/model-entry-refusal.d.ts +9 -1
  260. package/dist/model-entry-refusal.js +6 -1
  261. package/dist/model-plane-face.d.ts +51 -0
  262. package/dist/model-plane-face.js +24 -0
  263. package/dist/model-provider.d.ts +5 -0
  264. package/dist/model-provider.js +4 -2
  265. package/dist/model-route-endpoint.d.ts +8 -11
  266. package/dist/model-route-endpoint.js +4 -7
  267. package/dist/model-route-env.d.ts +22 -0
  268. package/dist/model-route-env.js +2 -0
  269. package/dist/model-route-gap.d.ts +60 -30
  270. package/dist/model-route-gap.js +21 -15
  271. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  272. package/dist/observability/corrupt-read-seat.js +9 -0
  273. package/dist/observability/err-text.d.ts +6 -0
  274. package/dist/observability/err-text.js +18 -4
  275. package/dist/observability/fail-open.d.ts +35 -9
  276. package/dist/observability/fail-open.js +35 -9
  277. package/dist/observability/metrics.js +1 -0
  278. package/dist/observability/prompt-manifest.d.ts +22 -25
  279. package/dist/observability/prompt-manifest.js +54 -50
  280. package/dist/observability/tool-trace.js +9 -10
  281. package/dist/operator-ask.d.ts +10 -0
  282. package/dist/operator-ask.js +3 -0
  283. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  284. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  285. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  286. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  287. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  288. package/dist/orchestration/workflow-notify-journal.js +27 -34
  289. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  290. package/dist/orchestration/workflow-park-decision.js +119 -0
  291. package/dist/org-delivery-gate.d.ts +81 -0
  292. package/dist/org-delivery-gate.js +59 -0
  293. package/dist/panel-tool-names.d.ts +23 -0
  294. package/dist/panel-tool-names.js +8 -0
  295. package/dist/parked-decide.d.ts +43 -11
  296. package/dist/parked-decide.js +100 -51
  297. package/dist/parked-revive-surface.d.ts +9 -2
  298. package/dist/parked-revive-surface.js +11 -8
  299. package/dist/permission-rule-list.d.ts +1 -1
  300. package/dist/permission-rule-list.js +2 -2
  301. package/dist/permission-rule-vocab.d.ts +1 -23
  302. package/dist/permission-rule-vocab.js +0 -13
  303. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  304. package/dist/plugins/approval-ask-store-file.js +21 -0
  305. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  306. package/dist/plugins/approval-ask-store-memory.js +34 -2
  307. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  308. package/dist/plugins/approval-ask-store-sql.js +37 -1
  309. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  310. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  311. package/dist/plugins/blob-backend.d.ts +38 -25
  312. package/dist/plugins/blob-backend.js +29 -19
  313. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  314. package/dist/plugins/breaker-state-sql.js +4 -4
  315. package/dist/plugins/caching-session-store.d.ts +4 -1
  316. package/dist/plugins/caching-session-store.js +7 -3
  317. package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
  318. package/dist/plugins/checkpoint-store-sql.js +65 -3
  319. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  320. package/dist/plugins/file-history-store-sql.js +3 -1
  321. package/dist/plugins/file-run-store.d.ts +5 -13
  322. package/dist/plugins/file-run-store.js +9 -0
  323. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  324. package/dist/plugins/fork-routing-session-store.js +12 -1
  325. package/dist/plugins/host-platform.d.ts +2 -0
  326. package/dist/plugins/host-platform.js +2 -1
  327. package/dist/plugins/local-checkpoint-store.d.ts +15 -2
  328. package/dist/plugins/local-checkpoint-store.js +32 -1
  329. package/dist/plugins/local-session-store.d.ts +13 -10
  330. package/dist/plugins/local-session-store.js +23 -14
  331. package/dist/plugins/local-session-window.d.ts +45 -0
  332. package/dist/plugins/local-session-window.js +38 -0
  333. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  334. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  335. package/dist/plugins/mailbox-store-sql.js +77 -52
  336. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  337. package/dist/plugins/memory-run-store.d.ts +5 -13
  338. package/dist/plugins/memory-run-store.js +8 -0
  339. package/dist/plugins/one-time-migrations.d.ts +121 -5
  340. package/dist/plugins/one-time-migrations.js +332 -8
  341. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  342. package/dist/plugins/org-delivery-quota-store.js +228 -0
  343. package/dist/plugins/permission-rule-store-file.js +10 -6
  344. package/dist/plugins/permission-rule-store-sql.js +8 -8
  345. package/dist/plugins/pg-pool.js +39 -7
  346. package/dist/plugins/pg-session-storage.d.ts +18 -5
  347. package/dist/plugins/pg-session-storage.js +68 -23
  348. package/dist/plugins/remote-env-adb.d.ts +6 -12
  349. package/dist/plugins/remote-env-adb.js +12 -2
  350. package/dist/plugins/remote-env-device.d.ts +14 -7
  351. package/dist/plugins/remote-env-device.js +23 -15
  352. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  353. package/dist/plugins/remote-env-k8s.js +23 -5
  354. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  355. package/dist/plugins/remote-env-local-docker.js +12 -9
  356. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  357. package/dist/plugins/remote-env-ssh.js +17 -11
  358. package/dist/plugins/run-store-sql.d.ts +16 -14
  359. package/dist/plugins/run-store-sql.js +22 -2
  360. package/dist/plugins/schema-indexes.js +2 -0
  361. package/dist/plugins/send-user-file.js +2 -2
  362. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  363. package/dist/plugins/session-epoch-anchor.js +2 -3
  364. package/dist/plugins/session-ownership.d.ts +11 -0
  365. package/dist/plugins/session-ownership.js +11 -0
  366. package/dist/plugins/session-placement.d.ts +12 -14
  367. package/dist/plugins/session-placement.js +2 -15
  368. package/dist/plugins/session-store.d.ts +18 -8
  369. package/dist/plugins/session-store.js +15 -4
  370. package/dist/plugins/sql-driver.d.ts +74 -11
  371. package/dist/plugins/sql-driver.js +210 -12
  372. package/dist/plugins/sql-errors.d.ts +23 -0
  373. package/dist/plugins/sql-errors.js +21 -0
  374. package/dist/plugins/store-backend.d.ts +36 -1
  375. package/dist/plugins/store-backend.js +40 -14
  376. package/dist/plugins/store-contracts.d.ts +42 -0
  377. package/dist/plugins/store-contracts.js +1 -0
  378. package/dist/plugins/tidb-pool.d.ts +6 -1
  379. package/dist/plugins/tidb-pool.js +44 -10
  380. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  381. package/dist/plugins/tidb-session-storage.js +2 -2
  382. package/dist/plugins/tidb-session-store.d.ts +25 -5
  383. package/dist/plugins/tidb-session-store.js +67 -21
  384. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  385. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  386. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  387. package/dist/plugins/workflow-run-store-sql.js +50 -9
  388. package/dist/posture-source.d.ts +18 -10
  389. package/dist/posture-source.js +4 -1
  390. package/dist/project-identity.d.ts +45 -6
  391. package/dist/project-identity.js +162 -8
  392. package/dist/project-layer-key.d.ts +28 -0
  393. package/dist/project-layer-key.js +29 -0
  394. package/dist/question.js +3 -2
  395. package/dist/read-deny-entry.d.ts +25 -0
  396. package/dist/read-deny-entry.js +12 -0
  397. package/dist/read-face-posture.d.ts +37 -11
  398. package/dist/read-face-posture.js +32 -3
  399. package/dist/request-key-closure.d.ts +7 -0
  400. package/dist/request-key-closure.js +9 -1
  401. package/dist/request-tool-axes.d.ts +12 -0
  402. package/dist/request-tool-axes.js +20 -0
  403. package/dist/request-value-closure.d.ts +5 -0
  404. package/dist/request-value-closure.js +11 -3
  405. package/dist/rule-entry-list.d.ts +26 -2
  406. package/dist/rule-entry-list.js +72 -12
  407. package/dist/rules-consent.js +3 -4
  408. package/dist/run-acceptance.d.ts +19 -3
  409. package/dist/run-acceptance.js +13 -1
  410. package/dist/run-local.js +37 -6
  411. package/dist/runs.d.ts +12 -10
  412. package/dist/runs.js +25 -6
  413. package/dist/runtime-caps-resolver.d.ts +16 -6
  414. package/dist/runtime-caps-resolver.js +18 -5
  415. package/dist/sandbox-pkg-source.d.ts +19 -1
  416. package/dist/sandbox-pkg-source.js +29 -7
  417. package/dist/sealed-key.d.ts +32 -0
  418. package/dist/sealed-key.js +55 -1
  419. package/dist/security.d.ts +95 -15
  420. package/dist/security.js +52 -9
  421. package/dist/session-error-wire.d.ts +31 -7
  422. package/dist/session-error-wire.js +9 -2
  423. package/dist/session-sync-kernel.d.ts +37 -10
  424. package/dist/session-sync-kernel.js +10 -0
  425. package/dist/session-titled-frame.d.ts +33 -0
  426. package/dist/session-titled-frame.js +4 -0
  427. package/dist/session-titler.d.ts +9 -1
  428. package/dist/session-titler.js +15 -4
  429. package/dist/spec-fields.js +21 -2
  430. package/dist/sql-engine-posture.d.ts +3 -1
  431. package/dist/task-a2a.js +4 -3
  432. package/dist/task-cwd.d.ts +1 -1
  433. package/dist/task-mcp.d.ts +5 -5
  434. package/dist/task-mcp.js +27 -74
  435. package/dist/task-settings.d.ts +93 -88
  436. package/dist/task-settings.js +71 -63
  437. package/dist/text-bidi.d.ts +0 -4
  438. package/dist/text-bidi.js +1 -3
  439. package/dist/tighten-only-seats.d.ts +150 -0
  440. package/dist/tighten-only-seats.js +196 -0
  441. package/dist/tool-approval.d.ts +451 -136
  442. package/dist/tool-approval.js +733 -256
  443. package/dist/tool-rule-names.d.ts +6 -0
  444. package/dist/trace/core-keyset-guard.d.ts +108 -25
  445. package/dist/trace/exit-seat.d.ts +40 -0
  446. package/dist/trace/exit-seat.js +130 -0
  447. package/dist/trace/ledger-events.d.ts +6 -3
  448. package/dist/trace/project.d.ts +98 -13
  449. package/dist/trace/project.js +57 -32
  450. package/dist/trace/projection-table.d.ts +100 -0
  451. package/dist/trace/projection-table.js +130 -0
  452. package/dist/trace/redact.d.ts +57 -0
  453. package/dist/trace/redact.js +962 -168
  454. package/dist/trace/self-minted-wire.d.ts +349 -1
  455. package/dist/trace/self-minted-wire.js +118 -1
  456. package/dist/trace/wire-projection-faces.d.ts +304 -2
  457. package/dist/trace/wire-projection-faces.js +160 -13
  458. package/dist/url-refusal.js +2 -0
  459. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  460. package/dist/web-admin-client/apply-effective.js +56 -5
  461. package/dist/web-admin-client/facade.d.ts +1 -1
  462. package/dist/web-admin-client/facade.js +1 -1
  463. package/dist/web-admin-client/read-face.js +5 -9
  464. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  465. package/dist/web-admin-client/skills-mcp.js +6 -8
  466. package/dist/web-admin-client/types.d.ts +1 -1
  467. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  468. package/package.json +8 -4
  469. package/scripts/drain-check-local.mjs +34 -2
  470. package/scripts/drain-check.mysql.sql +20 -2
  471. package/scripts/drain-check.pg.sql +20 -2
  472. package/dist/mcp-tool-faces.d.ts +0 -69
  473. package/dist/mcp-tool-faces.js +0 -106
@@ -34,7 +34,6 @@ import { assertApprovalAskRuleMaterialSchema } from "../plugins/approval-ask-sto
34
34
  import { assertSchemaMatchesCode } from "../plugins/schema-consistency.js";
35
35
  import { assertCheckpointColumnSchema } from "../plugins/checkpoint-store-sql.js";
36
36
  import { assertFileHistorySchema } from "../plugins/file-history-store-sql.js";
37
- import { resolveStreamApprovalGate } from "../tool-approval.js";
38
37
  import { buildMemoryBoundaryLaneFacts, buildMemoryWriteBoundaryAudit, effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
39
38
  import { buildMemoryPosture } from "../memory-posture.js";
40
39
  import { establishSqlEnginePosture, sqlPoolsOf } from "../sql-engine-posture.js";
@@ -45,6 +44,14 @@ const DARK_REASON_PROSE = {
45
44
  multi_tenant_file_backend: () => "multi-tenant on the FILE backend (no tenant isolation; set MEMORY_ENGINE_BACKEND=pg|tidb to light up)",
46
45
  remote_lane_split: (lane) => `remote exec lane "${lane}" (worker/sandbox file planes split; MEMORY_ENGINE_REMOTE_LANE=allow overrides)`,
47
46
  };
47
+ export async function assertApprovalAskRuleMaterialOnBackend(backend) {
48
+ const mysqlPool = backend?.mysqlPool?.();
49
+ const pgPool = backend?.pgPool?.();
50
+ if (pgPool)
51
+ await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
52
+ else if (mysqlPool)
53
+ await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
54
+ }
48
55
  export async function openStores(ctx) {
49
56
  const { config, logger, metrics, localRoot } = ctx;
50
57
  let backend;
@@ -83,17 +90,6 @@ export async function openStores(ctx) {
83
90
  else if (mysqlPool)
84
91
  await assertPermissionRuleTicketSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
85
92
  }
86
- if (resolveStreamApprovalGate({
87
- toolApprovalEnabled: config.toolApprovalEnabled === true,
88
- streamApprovalEnabled: config.streamApproval.enabled,
89
- backend,
90
- parkFacility: backend?.checkpoint !== undefined && config.durableApproval === true,
91
- }).active) {
92
- if (pgPool)
93
- await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
94
- else if (mysqlPool)
95
- await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
96
- }
97
93
  if (pgPool)
98
94
  await assertFileHistorySchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
99
95
  else if (mysqlPool)
@@ -377,7 +373,7 @@ export async function openStores(ctx) {
377
373
  ...(config.memorySync.maxPushEntries !== undefined ? { maxPushEntries: config.memorySync.maxPushEntries } : {}),
378
374
  ...(config.memorySync.maxPullEntries !== undefined ? { maxPullEntries: config.memorySync.maxPullEntries } : {}),
379
375
  });
380
- logger.info("memory_sync_enabled", { url: buildDisplaySafeUrl(config.memorySync.url), scope: config.memorySync.scope, cursorPath: memorySyncRunner.cursorPath });
376
+ logger.info("memory_sync_enabled", { url: buildDisplaySafeUrl(config.memorySync.url), scope: config.memorySync.scope, cursorPath: memorySyncRunner.cursorPathFor(config.memorySync.scope) });
381
377
  memorySyncRunner.trigger("boot");
382
378
  }
383
379
  else {
@@ -436,7 +432,7 @@ export async function openStores(ctx) {
436
432
  const breakerState = backend?.breaker && config.resilience.circuitBreaker
437
433
  ? backend
438
434
  .breaker((streak) => {
439
- metrics.setGauge("counter_flush_fail_streak", streak, { table: "circuit_breaker", kind: "write_through" });
435
+ metrics.setGauge("counter_flush_fail_streak", streak, { table: "breaker_state", kind: "write_through" });
440
436
  if (streak > 0)
441
437
  metrics.inc("breaker_writethrough_failed_total", { backend: backend.kind });
442
438
  if (streak === 3)
@@ -4,11 +4,13 @@ import { buildPricing } from "../budget.js";
4
4
  import { type Scenario, type ScenarioDeps, type ScenarioDetail } from "../capabilities/scenarios.js";
5
5
  import type { LoadedSkill } from "../capabilities/skills.js";
6
6
  import { type ServiceConfig } from "../config.js";
7
+ import { type CenterIdentityNotice } from "../center-config-tier.js";
7
8
  import { type CenterCredentialHealthView } from "../center-credential-renewer.js";
8
9
  import { type ModelKeyRef } from "../key-resolver.js";
9
10
  import type { Logger } from "../observability/logger.js";
10
11
  import type { Metrics } from "../observability/metrics.js";
11
12
  import { type SealedKeyPublicFace } from "../sealed-key.js";
13
+ import type { CheckpointCtxSealing } from "../http/checkpoint-ctx.js";
12
14
  import type { UnpricedCeilingVerdict } from "./unpriced-ceiling-verdict.js";
13
15
  import type { ConsolidationSeatWatch } from "./memory-consolidation.js";
14
16
  import type { DegradeRouteWatch } from "../brain.js";
@@ -44,6 +46,11 @@ export interface WebAdminRuntime {
44
46
  * 三形都建),失败 ⇒ `undefined`(`sealed_key_store_unavailable` 那一行已响亮告警)。店只在 boot 建一次、进程内不换钥匙,
45
47
  * 所以这是一个值,不是 getter。唯一读者 = `GET /v1/capabilities` 的 `sealedKey` 段(stage-10 经 deps 交过去)。 */
46
48
  readonly sealedKeyPublic: SealedKeyPublicFace | undefined;
49
+ /** S-1907:**停驻行凭据封签器**(`sealed-key.ts` `ensureCheckpointCtxSealing`:这一域自己的保管店 `<数据根>/sealed-key/checkpoint-ctx-keys/` —— 一个域一对钥匙,
50
+ * 与模型钥匙那只店不共用;封 = 最新公钥;开 = 按封签上的 id 精确选私钥、只认绑着本行会话的停驻行信封)。present-iff 这一域建店并自检成功(与模型钥匙店各自成败)。
51
+ * 读者:HTTP 面(`ServiceDeps.checkpointCtxSealing`,stage-10)、leader worker 的续跑上下文(stage-09)与一次性迁移 M28(stage-06);起服第 6 段对
52
+ * 「checkpoint 店在、它不在」拒启。私钥、保管目录、持有 id 列表照旧够不着(S-737 的结构性那一半不变)。 */
53
+ readonly checkpointCtxSealing: CheckpointCtxSealing | undefined;
47
54
  /** core `CenterPromptSource`(RunnerDeps / subRunner 必须同实例)。 */
48
55
  readonly promptSource: CenterPromptSource;
49
56
  /** center skills overlay → plugins 消费 → boot LKG 落盘/skill-stale 判定 → mcp 解析。返回新的 skills 表。 */
@@ -83,6 +90,9 @@ export interface WebAdminRuntime {
83
90
  stopRefreshLoop(): void;
84
91
  /** S-698:`/health.centerCredential` 的取值口 —— 凭证来源的健康态 + 续签器状态;都健康 / 没有中心 ⇒ `undefined`(键缺席)。 */
85
92
  centerCredentialState(): CenterCredentialHealthView | undefined;
93
+ /** S-667:`/health.centerIdentityNotice` 的取值口 —— 中心凭证换人后的**最近一条**通告(`center_identity_demoted` 已降到无中心配置档 / `center_identity_landed`
94
+ * 新身份的配置已换上;码、冻结句与状态机见 `center-config-tier.ts`)。从未换过人 / 没有中心 ⇒ `undefined`(键缺席)。值形就是 wire 形 `{ code, message, at }`。 */
95
+ centerIdentityNoticeState(): CenterIdentityNotice | undefined;
86
96
  /** [ref](core 5.50 [ref]):mid-turn MCP 撤销台账读口,喂 `RunnerDeps.mcpRevocations` 席。
87
97
  * **取走即声明接线**——调用本方法后,restart 信号的 mcp 片对纯删除向豁免(台账即时承接);
88
98
  * 不取 ⇒ 旧 restart 语义逐字保留(fail-closed)。 */
@@ -11,14 +11,17 @@ import { applyCenterPlugins } from "../capabilities/center-plugins.js";
11
11
  import { applyCenterArtifact, centerSourceOnError, withPromptArtifactBackfill } from "../capabilities/center-prompts.js";
12
12
  import { centerScenarios, centerScenarioDetails } from "../capabilities/scenarios.js";
13
13
  import { isRosterGateArmed } from "../config.js";
14
+ import { toolsRunOnThisHost } from "../task-cwd.js";
14
15
  import { defaultLkgPath, defaultSkillCacheDir, saveLkg, loadLkg, legacyV1LkgPath, migrateV1Lkg } from "../config-lkg.js";
15
16
  import { answerStillCurrent, centerStateBin, credentialIdentityNow, judgeCenterCredentialAtBoot } from "../center-credential.js";
17
+ import { createCenterConfigTier } from "../center-config-tier.js";
16
18
  import { buildCenterCredentialHealthView, createCenterCredentialRenewer } from "../center-credential-renewer.js";
17
19
  import { centerManagedConfigKeys } from "../web-admin-client/apply-effective.js";
18
20
  import { createConfigProvider, raceBootFetch, serviceConfigSourceKind, BOOT_FETCH_DEFERRED } from "../config-provider.js";
21
+ import { ConfigDirUntrustedError } from "../config-dir-trust.js";
19
22
  import { createKeyResolver } from "../key-resolver.js";
20
- import { buildSealedKeyPublicFace, ensureSealedKeyStore, reportExecutionPublicKey } from "../sealed-key.js";
21
- import { applyEffective, applyCenterReadFace, buildReadFaceBaseline, buildReadFaceSwapCandidate, restoreReadFaceBaseline, mutateInPlace, logEffectiveDiff, applySkillsManifest, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged, withModelPlaneOf, fullyLandedForLkg, fetchPromptArtifact } from "../web-admin-client/facade.js";
23
+ import { buildSealedKeyPublicFace, ensureCheckpointCtxSealing, ensureSealedKeyStore, reportExecutionPublicKey } from "../sealed-key.js";
24
+ import { applyEffective, applyCenterReadFace, buildReadFaceBaseline, buildReadFaceSwapCandidate, restoreReadFaceBaseline, mutateInPlace, logEffectiveDiff, applySkillsManifest, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged, withModelPlaneOf, fullyLandedForLkg, NO_CENTER_EFFECTIVE, isNoCenterEffective, fetchPromptArtifact } from "../web-admin-client/facade.js";
22
25
  import { buildConfigHandoff, buildRestartSignal, configHandoffMissing } from "../fleet/engine-signal.js";
23
26
  import { createMcpRevocationLedger, enabledMcpEntries } from "../web-admin-client/mcp-revocation.js";
24
27
  import { buildUnreadConfigFileFields, buildUnreadConfigKeyFields } from "../web-admin-client/read-warnings.js";
@@ -26,6 +29,7 @@ import { CONFIG_DOMAIN_INVALID_NOTE, buildCandidateRejectedFields, candidateReje
26
29
  import { SHA256_HEX_RE } from "../digest-form.js";
27
30
  import { BOOT_REJUDGE_OF_REFUSED_GROUP, createConfigApplyLedger, modelPlaneCommitted, refusedGroups } from "../web-admin-client/apply-ledger.js";
28
31
  import { announceReadDenyRows, buildDeploymentPostureSeats } from "./runner-deps.js";
32
+ import { echoCallerText } from "../caller-text-echo.js";
29
33
  function lkgReadNote(scope) {
30
34
  switch (scope) {
31
35
  case "whole":
@@ -86,6 +90,21 @@ export async function createWebAdminRuntime(ctx) {
86
90
  ? createCenterCredentialRenewer({ source: cc.credential, centerUrl: cc.baseUrl, leadMs: config.centerCredentialRenewLeadMs, logger })
87
91
  : undefined;
88
92
  const currentIdentity = () => (cc === undefined ? undefined : credentialIdentityNow(cc.credential));
93
+ const tier = createCenterConfigTier();
94
+ const announceTier = (n) => {
95
+ switch (n.code) {
96
+ case "center_identity_demoted":
97
+ logger.warn(n.code, { at: n.at, message: n.message, ...(n.retained !== undefined ? { retained: n.retained } : {}), note: "the credential identity changed: the previous account's center configuration is dropped (every center-supplied hot face is back on its env base, the center prompt layer is withdrawn, the Runners run the env model table) and a pull for the new identity is under way; skills / MCP / A2A / scenarios are baked at boot and stay the previous account's until a restart (see /health.restart)" });
98
+ return;
99
+ case "center_identity_landed":
100
+ logger.info(n.code, { at: n.at, message: n.message });
101
+ return;
102
+ default: {
103
+ const unknownCode = n.code;
104
+ throw new Error(`announceTier: unknown notice code ${JSON.stringify(unknownCode)}`);
105
+ }
106
+ }
107
+ };
89
108
  const candidateIdentity = new WeakMap();
90
109
  const candidateIdentityOf = (eff) => candidateIdentity.get(eff);
91
110
  const validatorIdentity = new Map();
@@ -114,9 +133,10 @@ export async function createWebAdminRuntime(ctx) {
114
133
  }
115
134
  return r;
116
135
  };
136
+ const sealedKeyDir = join(config.localDataRoot ?? localRoot, "sealed-key");
117
137
  let sealedKeys;
118
138
  try {
119
- sealedKeys = await ensureSealedKeyStore(join(config.localDataRoot ?? localRoot, "sealed-key"), logger);
139
+ sealedKeys = await ensureSealedKeyStore(sealedKeyDir, logger);
120
140
  void reportExecutionPublicKey({
121
141
  baseUrl: cc?.baseUrl,
122
142
  adminToken: process.env[WEB_ADMIN_ENV.adminToken],
@@ -128,11 +148,19 @@ export async function createWebAdminRuntime(ctx) {
128
148
  catch (err) {
129
149
  logger.warn("sealed_key_store_unavailable", { err: String(err), note: "sealed api keys cannot be unsealed on this host — models carrying sealedApiKey will fail loud per-model" });
130
150
  }
151
+ let checkpointCtxSealing;
152
+ try {
153
+ checkpointCtxSealing = await ensureCheckpointCtxSealing(sealedKeyDir, logger);
154
+ }
155
+ catch (err) {
156
+ logger.warn("checkpoint_ctx_sealing_unavailable", { err: err instanceof Error ? err.message : String(err), note: "suspended tasks' request credentials cannot be sealed on this host; with durable approvals on the boot refuses — make <data root>/sealed-key/checkpoint-ctx-keys/ creatable and chmod-able by the service, or repair / remove a key file there whose public and private halves do not belong together" });
157
+ }
131
158
  const configProvider = serviceConfigSourceKind(config) !== undefined
132
159
  ? createConfigProvider({
133
160
  ...(config.configProvider ? { provider: config.configProvider } : {}),
134
161
  ...(cc ? { webAdmin: { baseUrl: cc.baseUrl, credential: cc.credential, worker: cc.worker, dryRun: cc.dryRun } } : {}),
135
162
  localDir: localRoot,
163
+ localOwnerUid: config.configLocalOwnerUid,
136
164
  ...(config.configLkgEnabled ? { skillBodyCacheDir: defaultSkillCacheDir(config) } : {}),
137
165
  })
138
166
  : undefined;
@@ -301,6 +329,10 @@ export async function createWebAdminRuntime(ctx) {
301
329
  if (configProvider && !cc?.dryRun)
302
330
  await rebasePromptState(promptStateIdentity, "boot");
303
331
  const adoptCenterPrompts = async (eff, prompts, phase) => {
332
+ if (isNoCenterEffective(eff)) {
333
+ await rebasePromptState(undefined, phase);
334
+ return;
335
+ }
304
336
  const adoptedIdentity = candidateIdentityOf(eff);
305
337
  if (adoptedIdentity !== undefined && adoptedIdentity !== promptStateIdentity) {
306
338
  await rebasePromptState(adoptedIdentity, phase);
@@ -348,14 +380,20 @@ export async function createWebAdminRuntime(ctx) {
348
380
  return ledger;
349
381
  };
350
382
  const noteHandoff = (next) => {
351
- const applied = next.applied ?? handoff.applied;
383
+ const applied = next.noneApplied === true ? undefined : (next.applied ?? handoff.applied);
352
384
  const durable = next.durable ?? handoff.durable;
353
385
  handoff = { ...(applied !== undefined ? { applied } : {}), ...(durable !== undefined ? { durable } : {}) };
354
386
  latchHandoff();
355
387
  };
356
- const markApplied = (gen, version) => {
357
- applyLedger.applied(gen, version);
358
- noteHandoff({ applied: version });
388
+ const markApplied = (gen, eff) => {
389
+ applyLedger.applied(gen, eff.version);
390
+ if (isNoCenterEffective(eff))
391
+ noteHandoff({ noneApplied: true });
392
+ else
393
+ noteHandoff({ applied: eff.version });
394
+ const landed = tier.committed(candidateIdentityOf(eff));
395
+ if (landed !== undefined)
396
+ announceTier(landed);
359
397
  };
360
398
  let lkgBooted = false;
361
399
  let bootLkgCandidate;
@@ -480,7 +518,7 @@ export async function createWebAdminRuntime(ctx) {
480
518
  const lkgIdentity = candidateIdentityOf(lkgR.effective);
481
519
  if (lkgSurvivesRestart && lkgIdentity !== undefined)
482
520
  noteHandoff({ durable: { version: lkgR.effective.version, identity: lkgIdentity } });
483
- markApplied(lkgGen, lkgR.effective.version);
521
+ markApplied(lkgGen, lkgR.effective);
484
522
  await adoptCenterPrompts(lkgR.effective, lkgR.prompts, "boot-lkg");
485
523
  const lkgPlane = modelPlaneCommitted(lkgReport);
486
524
  if (lkgPlane)
@@ -585,7 +623,7 @@ export async function createWebAdminRuntime(ctx) {
585
623
  recordApply(rep);
586
624
  },
587
625
  });
588
- markApplied(bootGen, r.effective.version);
626
+ markApplied(bootGen, r.effective);
589
627
  const bootClean = fullyLandedForLkg(r, bootReport);
590
628
  if (bootClean)
591
629
  ccEtag = r.etag;
@@ -622,11 +660,13 @@ export async function createWebAdminRuntime(ctx) {
622
660
  }
623
661
  }
624
662
  catch (err) {
663
+ if (err instanceof ConfigDirUntrustedError)
664
+ throw err;
625
665
  if (bootApplyPhase)
626
666
  logger.warn("config_apply_refused", { source: configProvider.kind, err: String(err), note: "the pulled candidate failed to apply at boot — falling back to the LKG / env; this is not a reachability failure" });
627
667
  else
628
668
  logger.warn("config_source_unreachable_using_env", { source: configProvider.kind, err: String(err) });
629
- await bootFallBackWhole(`${bootApplyPhase ? "boot apply refused" : "boot fetch failed"}: ${String(err).slice(0, 120)}`);
669
+ await bootFallBackWhole(`${bootApplyPhase ? "boot apply refused" : "boot fetch failed"}: ${echoCallerText(String(err), { maxChars: 120 })}`);
630
670
  }
631
671
  if (!dryRun && cc !== undefined && currentIdentity() !== promptStateIdentity)
632
672
  await rebasePromptState(currentIdentity(), "boot-end");
@@ -669,9 +709,11 @@ export async function createWebAdminRuntime(ctx) {
669
709
  announceReadDenyRows(config, logger);
670
710
  };
671
711
  let ccTimer;
712
+ let unwatchCredential;
672
713
  return {
673
714
  providerKind: configProvider?.kind,
674
715
  sealedKeyPublic: sealedKeys === undefined ? undefined : buildSealedKeyPublicFace(sealedKeys),
716
+ checkpointCtxSealing,
675
717
  promptSource,
676
718
  takeMcpRevocations: () => {
677
719
  mcpRevocationWired = true;
@@ -707,6 +749,7 @@ export async function createWebAdminRuntime(ctx) {
707
749
  const pluginOut = await applyCenterPlugins(skills, effective, {
708
750
  cacheRoot: join(config.localDataRoot ?? join(homedir(), ".ai-agent"), "plugin-cache"),
709
751
  allowHosts: config.pluginsAllowHosts,
752
+ toolsShareThisFilesystem: toolsRunOnThisHost(config),
710
753
  logger,
711
754
  }).catch((err) => {
712
755
  logger.warn("center_plugins_apply_failed", { error: err instanceof Error ? err.message : String(err) });
@@ -839,6 +882,69 @@ export async function createWebAdminRuntime(ctx) {
839
882
  if (configProvider) {
840
883
  const ccRef = config.webAdmin;
841
884
  let refreshInFlight = false;
885
+ let followUp = false;
886
+ let ownRead = false;
887
+ const commitHot = async (c) => {
888
+ const { eff, prompts, gen, phase } = c;
889
+ const noCenter = isNoCenterEffective(eff);
890
+ const planeChanged = noCenter || modelPlaneChanged(appliedPlaneEff, eff);
891
+ let report;
892
+ const committed = applyEffective(config, eff, logger, {
893
+ leg: "hot",
894
+ checkpointStorePresent,
895
+ sealedKeys,
896
+ generation: gen,
897
+ report: (rep) => {
898
+ report = rep;
899
+ recordApply(rep);
900
+ },
901
+ ...(planeChanged ? { swapPlane: swapRunnerDeps } : {}),
902
+ });
903
+ if (!committed)
904
+ return { committed: false, report, planeCommitted: false };
905
+ mutateInPlace(pricing, buildPricing(config.models));
906
+ keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
907
+ limitSync?.sync();
908
+ ceilingVerdict?.judge();
909
+ if (phase !== "boot-deferred")
910
+ mcpRevocations.applyEnabledEntries(enabledMcpEntries(eff.mcp));
911
+ applyLiveReadFace(eff, swapRunnerDeps, phase);
912
+ markApplied(gen, eff);
913
+ const planeCommitted = modelPlaneCommitted(report);
914
+ if (planeCommitted)
915
+ appliedPlaneEff = noCenter ? undefined : eff;
916
+ planeDeferredNoHandoff = undefined;
917
+ await adoptCenterPrompts(eff, prompts, phase);
918
+ if (planeCommitted)
919
+ markRosterLanded(eff);
920
+ if (tier.drifted(currentIdentity()))
921
+ requestTick();
922
+ return { committed: true, report, planeCommitted };
923
+ };
924
+ const demoteToNoCenter = async (awaiting) => {
925
+ const gen = reserveArrivalGeneration();
926
+ applyLedger.seenTarget(gen, NO_CENTER_EFFECTIVE.version);
927
+ const hot = await commitHot({ eff: NO_CENTER_EFFECTIVE, prompts: undefined, gen, phase: "no-center" });
928
+ if (!hot.committed) {
929
+ throw new Error("the no-center tier was refused (the Runners did not accept the env model table) — the previous account's center configuration is still in force; retried next tick");
930
+ }
931
+ if (hot.report !== undefined && !hot.report.fullyApplied) {
932
+ logger.warn("center_identity_demotion_partial", { groups: refusedGroups(hot.report).map((g) => g.group), note: "a group of the no-center tier was refused — that group keeps its previous values (loud; the env base for that group could not be applied)" });
933
+ }
934
+ noteCandidateVerdict(gen, undefined);
935
+ latestEffective = undefined;
936
+ ccEtag = undefined;
937
+ announceTier(tier.demote(awaiting, hot.report !== undefined ? refusedGroups(hot.report).map((g) => g.group) : []));
938
+ };
939
+ const reconcileCenterIdentity = async (identity) => {
940
+ if (identity === undefined || !tier.drifted(identity))
941
+ return;
942
+ if (tier.isDemoted()) {
943
+ tier.retarget(identity);
944
+ return;
945
+ }
946
+ await demoteToNoCenter(identity);
947
+ };
842
948
  const refreshTick = async (arrival) => {
843
949
  if (refreshInFlight)
844
950
  return "ok";
@@ -850,6 +956,15 @@ export async function createWebAdminRuntime(ctx) {
850
956
  const refreshTickRan = async (arrival) => {
851
957
  refreshInFlight = true;
852
958
  try {
959
+ let ownIdentity;
960
+ ownRead = true;
961
+ try {
962
+ ownIdentity = currentIdentity();
963
+ }
964
+ finally {
965
+ ownRead = false;
966
+ }
967
+ await reconcileCenterIdentity(ownIdentity);
853
968
  await retryPendingCatalog("refresh-retry");
854
969
  if (planeDeferredNoHandoff) {
855
970
  metrics.inc("models_tiers_plane_deferred_stuck_total");
@@ -875,6 +990,7 @@ export async function createWebAdminRuntime(ctx) {
875
990
  }
876
991
  }
877
992
  if (r) {
993
+ await reconcileCenterIdentity(candidateIdentityOf(r.effective));
878
994
  const tickGen = arrival !== undefined ? useArrivalGeneration(r.effective.version, arrival.ordinal) : generationOf(r.effective.version);
879
995
  applyLedger.seenTarget(tickGen, r.effective.version);
880
996
  const verdict = judgeConfigCandidate(r);
@@ -889,35 +1005,10 @@ export async function createWebAdminRuntime(ctx) {
889
1005
  ccEtag = r.etag;
890
1006
  }
891
1007
  else {
892
- const planeChanged = modelPlaneChanged(appliedPlaneEff, r.effective);
893
- let applyReport;
894
- const committed = applyEffective(config, r.effective, logger, {
895
- leg: "hot",
896
- checkpointStorePresent,
897
- sealedKeys,
898
- generation: tickGen,
899
- report: (rep) => {
900
- applyReport = rep;
901
- recordApply(rep);
902
- },
903
- ...(planeChanged ? { swapPlane: swapRunnerDeps } : {}),
904
- });
905
- if (!committed)
1008
+ const hot = await commitHot({ eff: r.effective, prompts: verdict.prompts, gen: tickGen, phase: "refresh" });
1009
+ if (!hot.committed)
906
1010
  return "ok";
907
- mutateInPlace(pricing, buildPricing(config.models));
908
- keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
909
- limitSync?.sync();
910
- ceilingVerdict?.judge();
911
- mcpRevocations.applyEnabledEntries(enabledMcpEntries(r.effective.mcp));
912
- applyLiveReadFace(r.effective, swapRunnerDeps, "refresh");
913
- markApplied(tickGen, r.effective.version);
914
- const tickPlane = modelPlaneCommitted(applyReport);
915
- if (tickPlane)
916
- appliedPlaneEff = r.effective;
917
- planeDeferredNoHandoff = undefined;
918
- await adoptCenterPrompts(r.effective, verdict.prompts, "refresh");
919
- if (tickPlane)
920
- markRosterLanded(r.effective);
1011
+ const applyReport = hot.report;
921
1012
  if (!fullyLandedForLkg(r, applyReport)) {
922
1013
  ccEtag = undefined;
923
1014
  const refused = applyReport ? refusedGroups(applyReport) : [];
@@ -962,13 +1053,39 @@ export async function createWebAdminRuntime(ctx) {
962
1053
  return inFlight;
963
1054
  const p = refreshTick(arrival).finally(() => {
964
1055
  inFlight = undefined;
1056
+ afterLane();
965
1057
  });
966
1058
  inFlight = p;
967
1059
  return p;
968
1060
  };
1061
+ const requestTick = () => {
1062
+ if (ccTimer === undefined || ownRead)
1063
+ return;
1064
+ if (inFlight !== undefined || refreshInFlight) {
1065
+ followUp = true;
1066
+ return;
1067
+ }
1068
+ queueMicrotask(() => void runTick());
1069
+ };
1070
+ const afterLane = () => {
1071
+ if (!followUp)
1072
+ return;
1073
+ followUp = false;
1074
+ if (tier.drifted(currentIdentity()))
1075
+ requestTick();
1076
+ };
1077
+ unwatchCredential =
1078
+ ccRef !== undefined && !ccRef.dryRun && configProvider.kind === "remote"
1079
+ ? ccRef.credential.onRead((read) => {
1080
+ if (tier.drifted(read.identity))
1081
+ requestTick();
1082
+ })
1083
+ : undefined;
969
1084
  manualRefresh = runTick;
970
1085
  ccTimer = setInterval(() => void runTick(), 60_000);
971
1086
  ccTimer.unref?.();
1087
+ if (tier.drifted(currentIdentity()))
1088
+ requestTick();
972
1089
  const deferredBootApply = async (r, arrivalGen) => {
973
1090
  if (!r)
974
1091
  return;
@@ -985,6 +1102,7 @@ export async function createWebAdminRuntime(ctx) {
985
1102
  }
986
1103
  finally {
987
1104
  refreshInFlight = false;
1105
+ afterLane();
988
1106
  }
989
1107
  };
990
1108
  const deferredBootApplyInner = async (r, lateGen) => {
@@ -1001,34 +1119,10 @@ export async function createWebAdminRuntime(ctx) {
1001
1119
  ccEtag = r.etag;
1002
1120
  return;
1003
1121
  }
1004
- const planeChangedLate = modelPlaneChanged(appliedPlaneEff, r.effective);
1005
- let applyReportLate;
1006
- const committedLate = applyEffective(config, r.effective, logger, {
1007
- leg: "hot",
1008
- checkpointStorePresent,
1009
- sealedKeys,
1010
- generation: lateGen,
1011
- report: (rep) => {
1012
- applyReportLate = rep;
1013
- recordApply(rep);
1014
- },
1015
- ...(planeChangedLate ? { swapPlane: swapRunnerDeps } : {}),
1016
- });
1017
- if (!committedLate)
1122
+ const hotLate = await commitHot({ eff: r.effective, prompts: lateVerdict.prompts, gen: lateGen, phase: "boot-deferred" });
1123
+ if (!hotLate.committed)
1018
1124
  return;
1019
- mutateInPlace(pricing, buildPricing(config.models));
1020
- keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1021
- limitSync?.sync();
1022
- ceilingVerdict?.judge();
1023
- applyLiveReadFace(r.effective, swapRunnerDeps, "boot-deferred");
1024
- markApplied(lateGen, r.effective.version);
1025
- const latePlane = modelPlaneCommitted(applyReportLate);
1026
- if (latePlane)
1027
- appliedPlaneEff = r.effective;
1028
- planeDeferredNoHandoff = undefined;
1029
- await adoptCenterPrompts(r.effective, lateVerdict.prompts, "boot-deferred");
1030
- if (latePlane)
1031
- markRosterLanded(r.effective);
1125
+ const applyReportLate = hotLate.report;
1032
1126
  if (!fullyLandedForLkg(r, applyReportLate)) {
1033
1127
  ccEtag = undefined;
1034
1128
  const refusedLate = applyReportLate ? refusedGroups(applyReportLate) : [];
@@ -1069,10 +1163,13 @@ export async function createWebAdminRuntime(ctx) {
1069
1163
  ccTimer = undefined;
1070
1164
  }
1071
1165
  credentialRenewer?.stop();
1166
+ unwatchCredential?.();
1167
+ unwatchCredential = undefined;
1072
1168
  },
1073
1169
  centerCredentialState() {
1074
1170
  return cc === undefined ? undefined : buildCenterCredentialHealthView(cc.credential.health(), credentialRenewer);
1075
1171
  },
1172
+ centerIdentityNoticeState: () => tier.notice(),
1076
1173
  };
1077
1174
  }
1078
1175
  //# sourceMappingURL=web-admin.js.map
@@ -15,6 +15,7 @@ import { type WorkflowRun, type WorkflowRunStore } from "@sema-agent/core";
15
15
  import type { ServiceConfig } from "../config.js";
16
16
  import { FleetEventBus } from "../fleet/fleet-bus.js";
17
17
  import { type WorkflowAgentSessionIndex } from "../orchestration/workflow-agent-session-index.js";
18
+ import type { WorkflowParkDecisionStore } from "../orchestration/workflow-park-decision.js";
18
19
  import type { Logger } from "../observability/logger.js";
19
20
  import type { Metrics } from "../observability/metrics.js";
20
21
  import { type WorkflowCompletionInbox } from "../orchestration/workflow-completion-inbox.js";
@@ -49,5 +50,6 @@ export declare function createWorkflowOrchestration(ctx: WorkflowOrchestrationCt
49
50
  publishTerminalFleetRow?: (id: string, run: WorkflowRun) => void;
50
51
  };
51
52
  workflowAgentSessionIndex: WorkflowAgentSessionIndex | undefined;
53
+ workflowParkDecisions: WorkflowParkDecisionStore | undefined;
52
54
  };
53
55
  //# sourceMappingURL=workflow-orchestration.d.ts.map
@@ -66,6 +66,7 @@ export function createWorkflowOrchestration(ctx) {
66
66
  ? backend.workflowAgentSessionIndex()
67
67
  : new LocalWorkflowAgentSessionIndex(join(config.localDataRoot ?? localRoot, "workflows"), undefined))
68
68
  : undefined;
69
+ const workflowParkDecisions = config.selfOrchestrationEnabled && backend !== undefined && (sqlWorkflowRunStore !== undefined || backend.kind === "local") ? backend.workflowParkDecisions?.() : undefined;
69
70
  const workflowRunStore = baseWorkflowRunStore
70
71
  ? new JournalingWorkflowRunStore(baseWorkflowRunStore, workflowNotifyGate, fleetBus, workflowAgentSessionIndex)
71
72
  : undefined;
@@ -82,7 +83,7 @@ export function createWorkflowOrchestration(ctx) {
82
83
  return {
83
84
  sqlWorkflowRunStore, workflowNotifyJournal, workflowCompletionInbox, deliverWorkflowCompletion,
84
85
  workflowNotifyGate, fleetBus, workflowRunStore, workflowJournalStore, outcomeSink,
85
- workflowAgentRegistry, subagentSteerRegistry, workflowRecoverOpts, workflowAgentSessionIndex,
86
+ workflowAgentRegistry, subagentSteerRegistry, workflowRecoverOpts, workflowAgentSessionIndex, workflowParkDecisions,
86
87
  };
87
88
  }
88
89
  //# sourceMappingURL=workflow-orchestration.js.map
package/dist/brain.js CHANGED
@@ -9,6 +9,7 @@ import { openaiRouteBaseUrl } from "./model-route-endpoint.js";
9
9
  import { catalogEntryFingerprint } from "./web-admin-client/restart-signal.js";
10
10
  import { buildDisplaySafeRefusal, buildDisplaySafeUrl } from "./trace/redact.js";
11
11
  import { createModelReachBrain } from "./model-unreachable-notice.js";
12
+ import { breakerKeyOf, routeDigestOf } from "./breaker-key.js";
12
13
  function isOffDeploymentRoot(baseUrl, config) {
13
14
  if (!baseUrl)
14
15
  return false;
@@ -20,6 +21,9 @@ function isOffDeploymentRoot(baseUrl, config) {
20
21
  function deploymentGatewayRoots(config) {
21
22
  return config.gatewayBaseUrl !== undefined ? [config.gatewayBaseUrl, ...config.gatewayFallbackUrls] : [];
22
23
  }
24
+ function breakerRoutesOf(config, r) {
25
+ return r.circuitBreaker ? deploymentGatewayRoots(config).slice(0, -1) : [];
26
+ }
23
27
  function deploymentGatewayKey(config) {
24
28
  return config.gatewayBaseUrl !== undefined ? config.gatewayApiKey : undefined;
25
29
  }
@@ -53,6 +57,7 @@ export function createBrainAssembly(config, deps = {}) {
53
57
  ? { maxRetries: FAST_FAIL_MAX_RETRIES }
54
58
  : {};
55
59
  const routes = deploymentGatewayRoots(config);
60
+ const breakerRoutes = breakerRoutesOf(config, r);
56
61
  const openaiBrains = routes.map((baseUrl, i) => {
57
62
  const gatewayKey = deploymentGatewayKey(config);
58
63
  const brain = constructRouteBrain(i === 0 ? "gateway route" : `gateway fallback route[${i - 1}]`, [baseUrl], () => createOpenAIBrain({
@@ -62,13 +67,12 @@ export function createBrainAssembly(config, deps = {}) {
62
67
  fetchImpl,
63
68
  ...timeouts,
64
69
  }));
65
- const isLast = i === routes.length - 1;
66
- return r.circuitBreaker && !isLast
70
+ return i < breakerRoutes.length
67
71
  ? createCircuitBreakerBrain(brain, {
68
72
  failureThreshold: r.failureThreshold,
69
73
  cooldownMs: r.cooldownMs,
70
74
  state: breakerState,
71
- key: (m) => `${m.provider ?? "openai"}:${m.id}@${baseUrl}`,
75
+ key: (m) => breakerKeyOf(m, baseUrl),
72
76
  })
73
77
  : brain;
74
78
  });
@@ -206,6 +210,7 @@ export function brainSummary(config) {
206
210
  idleTimeoutMs: r.idleTimeoutMs,
207
211
  circuitBreaker: breakerActive,
208
212
  circuitBreakerRequested: r.circuitBreaker,
213
+ circuitBreakerRoutes: breakerRoutesOf(config, r).map((u) => ({ route: buildDisplaySafeUrl(u), digest: routeDigestOf(u) })),
209
214
  gatewayRetryCap: config.gatewayMaxRetries !== undefined
210
215
  ? `env:${config.gatewayMaxRetries}`
211
216
  : hasFailover || r.circuitBreaker || config.degrade?.reactive
@@ -0,0 +1,6 @@
1
+ import { type Model } from "@sema-agent/core";
2
+ /** 一条路由的身份摘要(键的路由段;启动日志把它与该路由的展示串并排印出,运维据此把错误文本 / 表行对回路由)。 */
3
+ export declare function routeDigestOf(baseUrl: string): string;
4
+ /** 断路器键:`<头段>@<路由摘要>`,头段 = `<provider>:<model id>`(放不下列宽预算时见 {@link boundedHead})。provider 缺席按 `openai`(与 core 默认键同一个前半)。恒 ≤ 190 字节。 */
5
+ export declare function breakerKeyOf(model: Pick<Model, "provider" | "id">, baseUrl: string): string;
6
+ //# sourceMappingURL=breaker-key.d.ts.map
@@ -0,0 +1,29 @@
1
+ import { createHash } from "node:crypto";
2
+ import { routeKeyOf } from "@sema-agent/core";
3
+ const ROUTE_DIGEST_HEX = 24;
4
+ const BREAKER_KEY_MAX_BYTES = 190;
5
+ const HEAD_MAX_BYTES = BREAKER_KEY_MAX_BYTES - 1 - ROUTE_DIGEST_HEX;
6
+ const HEAD_DIGEST_HEX = 16;
7
+ const sha256Hex = (text) => createHash("sha256").update(text, "utf8").digest("hex");
8
+ export function routeDigestOf(baseUrl) {
9
+ return sha256Hex(routeKeyOf(baseUrl)).slice(0, ROUTE_DIGEST_HEX);
10
+ }
11
+ export function breakerKeyOf(model, baseUrl) {
12
+ return `${boundedHead(`${model.provider ?? "openai"}:${model.id}`)}@${routeDigestOf(baseUrl)}`;
13
+ }
14
+ function boundedHead(head) {
15
+ if (Buffer.byteLength(head, "utf8") <= HEAD_MAX_BYTES)
16
+ return head;
17
+ const tail = `~${sha256Hex(head).slice(0, HEAD_DIGEST_HEX)}`;
18
+ let prefix = "";
19
+ let used = 0;
20
+ for (const ch of head) {
21
+ const n = Buffer.byteLength(ch, "utf8");
22
+ if (used + n > HEAD_MAX_BYTES - tail.length)
23
+ break;
24
+ prefix += ch;
25
+ used += n;
26
+ }
27
+ return `${prefix}${tail}`;
28
+ }
29
+ //# sourceMappingURL=breaker-key.js.map
package/dist/budget.js CHANGED
@@ -2,6 +2,7 @@ import { isModelPriced, modelCostToPricing } from "@sema-agent/core";
2
2
  import { currentPrincipal } from "./observability/principal-context.js";
3
3
  import { isPermissionRuleEventKind, permissionRuleEventWordOf } from "./observability/permission-rule-events.js";
4
4
  import { promptManifestRecordOf, configAssembledRecordOf } from "./observability/prompt-manifest.js";
5
+ import { crossBoundaryTaintEventData } from "./trace/project.js";
5
6
  export function buildPricing(models) {
6
7
  const pricing = {};
7
8
  for (const m of Object.values(models))
@@ -114,7 +115,10 @@ export function createTracer(metrics, costQuota, modelUsage, fleetUsage, fleetLe
114
115
  else if (e.kind === "config.assembled") {
115
116
  const rec = configAssembledRecordOf(e);
116
117
  if (rec)
117
- promptManifests?.recordConfig(e.taskId, rec);
118
+ promptManifests?.recordCompanion(e.taskId, "config_assembled", rec);
119
+ }
120
+ else if (e.kind === "permission.cross_boundary_taint") {
121
+ promptManifests?.recordCompanion(e.taskId, "cross_boundary_taint", crossBoundaryTaintEventData(e));
118
122
  }
119
123
  else if (e.kind === "compaction.phase_timings") {
120
124
  const d = e.durationMs;