@sema-agent/server 7.147.0 → 7.148.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 (725) hide show
  1. package/MIGRATION.md +1039 -24
  2. package/README.md +20 -7
  3. package/README.zh-CN.md +14 -8
  4. package/USAGE.md +380 -163
  5. package/deploy/sema-up/README.md +16 -5
  6. package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
  7. package/deploy/sema-up/chart/templates/_helpers.tpl +20 -4
  8. package/deploy/sema-up/chart/values.yaml +3 -2
  9. package/deploy/sema-up/cluster-up.sh +74 -176
  10. package/deploy/sema-up/kube-up.sh +29 -49
  11. package/deploy/sema-up/lib/chart-run.sh +23 -0
  12. package/deploy/sema-up/lib/dataroot.sh +3 -3
  13. package/deploy/sema-up/lib/health.sh +62 -13
  14. package/deploy/sema-up/lib/helm-values-cluster.py +18 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +35 -0
  16. package/deploy/sema-up/lib/regcred.py +8 -0
  17. package/deploy/sema-up/lib/remote/helm-install.sh +3 -0
  18. package/deploy/sema-up/lib/remote/image-import.sh +6 -0
  19. package/deploy/sema-up/lib/remote/machine-precheck.sh +11 -0
  20. package/deploy/sema-up/lib/remote/region-probe.sh +3 -0
  21. package/deploy/sema-up/lib/remote/stack-ready.sh +26 -0
  22. package/deploy/sema-up/lib/remote/vxlan-guard.sh +8 -0
  23. package/deploy/sema-up/lib/render-stack.py +17 -0
  24. package/deploy/sema-up/lib/shell-text.sh +87 -0
  25. package/deploy/sema-up/lib/usage-flags.txt +10 -0
  26. package/deploy/sema-up/lib/usage-head.txt +1 -0
  27. package/deploy/sema-up/lib/usage-tail.txt +13 -0
  28. package/deploy/sema-up/preflight.sh +10 -8
  29. package/deploy/sema-up/sema-up.sh +14 -39
  30. package/deploy/sema-up/smoke.sh +7 -6
  31. package/deploy/sema-up/stack/compose.dataroot.yaml +3 -0
  32. package/deploy/sema-up/stack/compose.yaml +13 -1
  33. package/deploy/sema-up/stack/sema-stack-cluster.yaml +21 -0
  34. package/dist/adoption/plan.d.ts +24 -0
  35. package/dist/adoption/plan.js +53 -1
  36. package/dist/adoption/runner.d.ts +10 -1
  37. package/dist/adoption/runner.js +36 -16
  38. package/dist/adoption/wire.d.ts +3 -3
  39. package/dist/approval-card.d.ts +28 -30
  40. package/dist/approval-gate-currency.js +3 -2
  41. package/dist/approval-reconciler.d.ts +4 -13
  42. package/dist/approval-reconciler.js +2 -2
  43. package/dist/approval.d.ts +13 -11
  44. package/dist/approval.js +3 -3
  45. package/dist/audit.d.ts +10 -3
  46. package/dist/audit.js +15 -7
  47. package/dist/auth-bridge.d.ts +0 -14
  48. package/dist/auth-bridge.js +0 -7
  49. package/dist/auto-mode-face.d.ts +10 -7
  50. package/dist/auto-mode-face.js +7 -4
  51. package/dist/background-agent-name.d.ts +19 -1
  52. package/dist/background-agent-name.js +12 -2
  53. package/dist/background-session-reap.d.ts +1 -1
  54. package/dist/bake-runner/main.js +9 -6
  55. package/dist/bench/s1/arms.js +6 -5
  56. package/dist/bench/s1/live-deps.js +5 -2
  57. package/dist/bench/s1/run-firm.js +6 -5
  58. package/dist/bind-host.d.ts +25 -0
  59. package/dist/bind-host.js +25 -0
  60. package/dist/boot/adoption.d.ts +3 -0
  61. package/dist/boot/adoption.js +1 -0
  62. package/dist/boot/deployment-mods.d.ts +1 -1
  63. package/dist/boot/execution-env.d.ts +17 -7
  64. package/dist/boot/execution-env.js +37 -31
  65. package/dist/boot/exit-boundary.d.ts +2 -2
  66. package/dist/boot/exit-boundary.js +6 -5
  67. package/dist/boot/fatal-exit.d.ts +3 -5
  68. package/dist/boot/fatal-exit.js +2 -2
  69. package/dist/boot/leader.d.ts +15 -0
  70. package/dist/boot/leader.js +17 -15
  71. package/dist/boot/memory-consolidation.d.ts +37 -29
  72. package/dist/boot/memory-consolidation.js +11 -5
  73. package/dist/boot/org-memory.js +1 -1
  74. package/dist/boot/parked-revive-gate.js +2 -2
  75. package/dist/boot/reapers.d.ts +4 -3
  76. package/dist/boot/reapers.js +19 -16
  77. package/dist/boot/resolve-spec.d.ts +5 -3
  78. package/dist/boot/resolve-spec.js +55 -67
  79. package/dist/boot/retention-lane.d.ts +4 -4
  80. package/dist/boot/retention-lane.js +2 -2
  81. package/dist/boot/runner-deps.d.ts +28 -7
  82. package/dist/boot/runner-deps.js +11 -4
  83. package/dist/boot/runtime-caps.d.ts +2 -2
  84. package/dist/boot/runtime-caps.js +16 -2
  85. package/dist/boot/session-faces.d.ts +16 -7
  86. package/dist/boot/session-faces.js +114 -94
  87. package/dist/boot/shutdown.d.ts +5 -4
  88. package/dist/boot/shutdown.js +6 -4
  89. package/dist/boot/stage-01-config.js +9 -1
  90. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  91. package/dist/boot/stage-02-web-admin-pull.js +6 -1
  92. package/dist/boot/stage-03-store-backend.d.ts +3 -0
  93. package/dist/boot/stage-03-store-backend.js +4 -3
  94. package/dist/boot/stage-04-stores.d.ts +2 -0
  95. package/dist/boot/stage-04-stores.js +2 -2
  96. package/dist/boot/stage-05-execution-env.d.ts +7 -3
  97. package/dist/boot/stage-05-execution-env.js +2 -2
  98. package/dist/boot/stage-06-runners.d.ts +10 -12
  99. package/dist/boot/stage-06-runners.js +23 -15
  100. package/dist/boot/stage-07-capability-layer.d.ts +11 -8
  101. package/dist/boot/stage-07-capability-layer.js +5 -3
  102. package/dist/boot/stage-08-reapers.d.ts +11 -8
  103. package/dist/boot/stage-08-reapers.js +3 -3
  104. package/dist/boot/stage-09-leader.d.ts +12 -15
  105. package/dist/boot/stage-09-leader.js +12 -4
  106. package/dist/boot/stage-10-http-server.d.ts +12 -15
  107. package/dist/boot/stage-10-http-server.js +7 -4
  108. package/dist/boot/store-evidence.d.ts +20 -0
  109. package/dist/boot/store-evidence.js +13 -0
  110. package/dist/boot/stores.d.ts +3 -0
  111. package/dist/boot/stores.js +21 -10
  112. package/dist/boot/task-list-lane.d.ts +4 -4
  113. package/dist/boot/web-admin.d.ts +4 -2
  114. package/dist/boot/web-admin.js +55 -35
  115. package/dist/boot/webfetch-summarize-lane.d.ts +1 -1
  116. package/dist/boot-reclaim.d.ts +3 -1
  117. package/dist/boot-reclaim.js +1 -1
  118. package/dist/brain.d.ts +7 -18
  119. package/dist/brain.js +5 -17
  120. package/dist/budget.js +6 -6
  121. package/dist/capabilities/center-plugins.d.ts +7 -1
  122. package/dist/capabilities/center-plugins.js +32 -10
  123. package/dist/capabilities/center-wiring.js +1 -1
  124. package/dist/capabilities/composite-members.d.ts +2 -2
  125. package/dist/capabilities/composite-members.js +2 -2
  126. package/dist/capabilities/repo-tools.d.ts +2 -0
  127. package/dist/capabilities/repo-tools.js +14 -12
  128. package/dist/capabilities/scenarios.d.ts +6 -15
  129. package/dist/capabilities/scenarios.js +11 -16
  130. package/dist/capabilities/skills.d.ts +1 -1
  131. package/dist/capabilities/tool-defer.d.ts +1 -1
  132. package/dist/capability-facts.d.ts +38 -11
  133. package/dist/capability-facts.js +47 -8
  134. package/dist/card-void.d.ts +4 -4
  135. package/dist/card-void.js +1 -1
  136. package/dist/center-credential-renewer.d.ts +6 -2
  137. package/dist/center-credential-renewer.js +7 -3
  138. package/dist/config-catalog.d.ts +16 -1
  139. package/dist/config-catalog.js +62 -56
  140. package/dist/config-dir-trust.d.ts +37 -4
  141. package/dist/config-dir-trust.js +88 -44
  142. package/dist/config-invariants.d.ts +42 -3
  143. package/dist/config-invariants.js +69 -5
  144. package/dist/config-lkg.d.ts +23 -1
  145. package/dist/config-lkg.js +17 -3
  146. package/dist/config-provider.d.ts +9 -9
  147. package/dist/config-provider.js +25 -110
  148. package/dist/config-pull-failure.d.ts +50 -0
  149. package/dist/config-pull-failure.js +48 -0
  150. package/dist/config-types.d.ts +26 -17
  151. package/dist/config.d.ts +8 -16
  152. package/dist/config.js +113 -47
  153. package/dist/delegated-session-owner.d.ts +1 -1
  154. package/dist/deleted-session-ids.d.ts +3 -2
  155. package/dist/deployment-governance.d.ts +3 -3
  156. package/dist/deployment-shape.d.ts +30 -4
  157. package/dist/deployment-shape.js +7 -0
  158. package/dist/egress-redirect.d.ts +25 -7
  159. package/dist/egress-redirect.js +20 -2
  160. package/dist/elicitation.d.ts +6 -5
  161. package/dist/elicitation.js +23 -22
  162. package/dist/engine-identity.d.ts +28 -0
  163. package/dist/engine-identity.js +10 -0
  164. package/dist/entry-problems.d.ts +5 -7
  165. package/dist/entry-problems.js +1 -1
  166. package/dist/env-facts.js +2 -1
  167. package/dist/env-witness.d.ts +7 -0
  168. package/dist/env-witness.js +16 -0
  169. package/dist/execution-lane-caps.d.ts +5 -18
  170. package/dist/execution-lane-caps.js +0 -22
  171. package/dist/execution-placement.d.ts +58 -18
  172. package/dist/execution-placement.js +41 -2
  173. package/dist/field-conflict.d.ts +7 -11
  174. package/dist/field-conflict.js +3 -3
  175. package/dist/file-history-capture.d.ts +3 -3
  176. package/dist/file-history-disclosure.js +1 -0
  177. package/dist/fleet/fleet-bus.d.ts +21 -3
  178. package/dist/fleet/fleet-bus.js +35 -25
  179. package/dist/fleet/fleet-reconciler.js +2 -2
  180. package/dist/fleet/serving-lease.js +3 -3
  181. package/dist/fleet-client.js +3 -3
  182. package/dist/fleet-lease.d.ts +0 -1
  183. package/dist/fleet-lease.js +4 -5
  184. package/dist/history-anchor.d.ts +23 -3
  185. package/dist/history-anchor.js +24 -4
  186. package/dist/hitl-delivery.d.ts +90 -0
  187. package/dist/hitl-delivery.js +98 -0
  188. package/dist/hooks/classic-stations.d.ts +8 -11
  189. package/dist/hooks/classic-stations.js +0 -7
  190. package/dist/hooks/hook-llm.d.ts +5 -1
  191. package/dist/hooks/hook-llm.js +24 -15
  192. package/dist/hooks/hook-runner.d.ts +67 -57
  193. package/dist/hooks/hook-runner.js +260 -186
  194. package/dist/host-lsp-manager.d.ts +22 -8
  195. package/dist/host-lsp-manager.js +4 -1
  196. package/dist/http/active-run-conflict.d.ts +2 -43
  197. package/dist/http/active-run-conflict.js +3 -7
  198. package/dist/http/admission.d.ts +4 -18
  199. package/dist/http/admission.js +75 -78
  200. package/dist/http/approval-sweeps.d.ts +3 -3
  201. package/dist/http/approval-sweeps.js +54 -30
  202. package/dist/http/caller-trust.d.ts +8 -10
  203. package/dist/http/caller-trust.js +1 -2
  204. package/dist/http/claim-heartbeat.d.ts +49 -0
  205. package/dist/http/claim-heartbeat.js +46 -0
  206. package/dist/http/claimed-run.d.ts +4 -3
  207. package/dist/http/dispatch.d.ts +8 -1
  208. package/dist/http/dispatch.js +76 -30
  209. package/dist/http/durable-run-leg.d.ts +3 -3
  210. package/dist/http/durable-run-leg.js +17 -12
  211. package/dist/http/execution-context.d.ts +17 -43
  212. package/dist/http/execution-context.js +7 -5
  213. package/dist/http/health-reader.d.ts +36 -0
  214. package/dist/http/health-reader.js +21 -0
  215. package/dist/http/health-self-report.d.ts +9 -9
  216. package/dist/http/health-self-report.js +4 -4
  217. package/dist/http/idempotency.d.ts +9 -5
  218. package/dist/http/idempotency.js +4 -4
  219. package/dist/http/memory-compliance-failure-reply.d.ts +15 -16
  220. package/dist/http/memory-compliance-failure-reply.js +4 -2
  221. package/dist/http/memory-face-fault-reply.d.ts +67 -0
  222. package/dist/http/memory-face-fault-reply.js +71 -0
  223. package/dist/http/memory-store-refusal-reply.d.ts +1 -1
  224. package/dist/http/memory-store-refusal-reply.js +3 -0
  225. package/dist/http/owner-access.d.ts +391 -67
  226. package/dist/http/owner-access.js +371 -35
  227. package/dist/http/principal-gate.d.ts +24 -81
  228. package/dist/http/principal-gate.js +24 -68
  229. package/dist/http/refusal-body.d.ts +35 -2
  230. package/dist/http/refusal-body.js +34 -0
  231. package/dist/http/request-guards.d.ts +9 -13
  232. package/dist/http/request-guards.js +34 -68
  233. package/dist/http/resume-composition.d.ts +37 -0
  234. package/dist/http/resume-composition.js +18 -0
  235. package/dist/http/resume-ctx-read.d.ts +35 -12
  236. package/dist/http/resume-ctx-read.js +25 -6
  237. package/dist/http/resume-legs.d.ts +21 -18
  238. package/dist/http/resume-legs.js +189 -129
  239. package/dist/http/retired-skill-manifest.d.ts +1 -1
  240. package/dist/http/route-ctx.d.ts +25 -32
  241. package/dist/http/routes/a2a-serve.d.ts +43 -5
  242. package/dist/http/routes/a2a-serve.js +58 -37
  243. package/dist/http/routes/admin-config-refresh.js +2 -2
  244. package/dist/http/routes/admin-drain.js +2 -2
  245. package/dist/http/routes/admin-memory-optout.js +4 -3
  246. package/dist/http/routes/adoption.d.ts +3 -0
  247. package/dist/http/routes/adoption.js +17 -10
  248. package/dist/http/routes/agents-roster.js +13 -7
  249. package/dist/http/routes/approvals-assistant.js +70 -65
  250. package/dist/http/routes/attachments.js +2 -2
  251. package/dist/http/routes/background.d.ts +3 -3
  252. package/dist/http/routes/background.js +9 -17
  253. package/dist/http/routes/capabilities.js +15 -18
  254. package/dist/http/routes/config-catalog.js +2 -2
  255. package/dist/http/routes/devices.d.ts +3 -3
  256. package/dist/http/routes/devices.js +4 -4
  257. package/dist/http/routes/diagnostics.d.ts +27 -3
  258. package/dist/http/routes/diagnostics.js +27 -21
  259. package/dist/http/routes/engine.js +2 -2
  260. package/dist/http/routes/fleet.js +5 -3
  261. package/dist/http/routes/images.js +10 -6
  262. package/dist/http/routes/leader.d.ts +7 -2
  263. package/dist/http/routes/leader.js +12 -3
  264. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  265. package/dist/http/routes/mcp-reconnect.js +7 -15
  266. package/dist/http/routes/memory-bundle.js +4 -7
  267. package/dist/http/routes/memory-compliance.js +4 -4
  268. package/dist/http/routes/memory-consolidation.js +6 -9
  269. package/dist/http/routes/memory-origin.d.ts +2 -0
  270. package/dist/http/routes/memory-origin.js +7 -8
  271. package/dist/http/routes/memory-policy.js +17 -12
  272. package/dist/http/routes/notify-wake.js +10 -19
  273. package/dist/http/routes/observability.js +3 -3
  274. package/dist/http/routes/principal-inbox.d.ts +1 -1
  275. package/dist/http/routes/principal-inbox.js +2 -2
  276. package/dist/http/routes/projects.d.ts +1 -1
  277. package/dist/http/routes/projects.js +3 -2
  278. package/dist/http/routes/retention-ops.js +6 -9
  279. package/dist/http/routes/rules.js +20 -5
  280. package/dist/http/routes/run-memory-capture.d.ts +2 -2
  281. package/dist/http/routes/run-memory-capture.js +6 -12
  282. package/dist/http/routes/run-permission-mode.d.ts +2 -2
  283. package/dist/http/routes/run-permission-mode.js +10 -17
  284. package/dist/http/routes/runs.js +146 -231
  285. package/dist/http/routes/session-memory-sync.d.ts +2 -2
  286. package/dist/http/routes/session-memory-sync.js +7 -13
  287. package/dist/http/routes/session-sync.d.ts +4 -2
  288. package/dist/http/routes/session-sync.js +21 -20
  289. package/dist/http/routes/sessions-list.d.ts +3 -3
  290. package/dist/http/routes/sessions-list.js +9 -9
  291. package/dist/http/routes/sessions.js +87 -124
  292. package/dist/http/routes/shared-memory.js +6 -6
  293. package/dist/http/routes/side-query.js +2 -2
  294. package/dist/http/routes/tasks.js +136 -120
  295. package/dist/http/routes/trace-usage.d.ts +0 -12
  296. package/dist/http/routes/trace-usage.js +40 -46
  297. package/dist/http/routes/workflows.d.ts +39 -4
  298. package/dist/http/routes/workflows.js +42 -14
  299. package/dist/http/run-concurrency-cap.d.ts +20 -12
  300. package/dist/http/run-concurrency-cap.js +39 -26
  301. package/dist/http/run-read-face.d.ts +3 -5
  302. package/dist/http/run-read-face.js +8 -13
  303. package/dist/http/send.d.ts +12 -3
  304. package/dist/http/send.js +42 -6
  305. package/dist/http/server.d.ts +39 -40
  306. package/dist/http/server.js +36 -11
  307. package/dist/http/sse-log.d.ts +17 -10
  308. package/dist/http/sse-log.js +7 -7
  309. package/dist/http/stored-body-replay.d.ts +12 -0
  310. package/dist/http/stored-body-replay.js +2 -2
  311. package/dist/http/submit-ctx.d.ts +16 -8
  312. package/dist/http/submit-ctx.js +6 -2
  313. package/dist/http/submit-replay.d.ts +19 -6
  314. package/dist/http/submit-replay.js +18 -6
  315. package/dist/http/sync-submit-body.d.ts +3 -4
  316. package/dist/http/sync-submit-body.js +4 -5
  317. package/dist/http/wire-types.d.ts +4 -3
  318. package/dist/identity-source.d.ts +36 -5
  319. package/dist/identity-source.js +27 -0
  320. package/dist/index.d.ts +1 -0
  321. package/dist/index.js +1 -0
  322. package/dist/key-resolver.d.ts +32 -0
  323. package/dist/key-resolver.js +23 -9
  324. package/dist/leader/diffup.js +2 -1
  325. package/dist/leader/endpoint.d.ts +26 -5
  326. package/dist/leader/endpoint.js +154 -14
  327. package/dist/leader/fanout.d.ts +3 -0
  328. package/dist/leader/fanout.js +78 -63
  329. package/dist/leader/leader.d.ts +16 -0
  330. package/dist/leader/leader.js +43 -3
  331. package/dist/leader/merge.d.ts +9 -1
  332. package/dist/leader/merge.js +16 -1
  333. package/dist/leader/repair-wire.js +1 -1
  334. package/dist/leader/wire.d.ts +36 -3
  335. package/dist/leader/wire.js +59 -18
  336. package/dist/lsp-evict.d.ts +6 -4
  337. package/dist/lsp-evict.js +2 -3
  338. package/dist/memory-operator-faces.d.ts +5 -4
  339. package/dist/memory-operator-faces.js +1 -1
  340. package/dist/memory-scope.d.ts +29 -2
  341. package/dist/memory-scope.js +64 -15
  342. package/dist/memory-store-refusal.d.ts +5 -2
  343. package/dist/memory-sync-client.d.ts +3 -2
  344. package/dist/memory-sync-client.js +6 -3
  345. package/dist/model-compat.d.ts +17 -8
  346. package/dist/model-compat.js +6 -2
  347. package/dist/model-context-window.d.ts +18 -0
  348. package/dist/model-context-window.js +2 -0
  349. package/dist/model-entry-headers.d.ts +46 -4
  350. package/dist/model-entry-headers.js +2 -2
  351. package/dist/model-entry-refusal.d.ts +35 -16
  352. package/dist/model-entry-refusal.js +40 -27
  353. package/dist/model-plane-face.d.ts +19 -11
  354. package/dist/model-plane-face.js +9 -1
  355. package/dist/model-plane-probe.d.ts +2 -0
  356. package/dist/model-plane-probe.js +17 -0
  357. package/dist/model-provider.d.ts +3 -3
  358. package/dist/model-route-endpoint.d.ts +9 -5
  359. package/dist/model-route-endpoint.js +29 -7
  360. package/dist/model-select.d.ts +16 -0
  361. package/dist/model-select.js +4 -0
  362. package/dist/mountinfo.d.ts +37 -0
  363. package/dist/mountinfo.js +47 -0
  364. package/dist/namespaced-rule-name.d.ts +23 -14
  365. package/dist/namespaced-rule-name.js +8 -11
  366. package/dist/net-address.d.ts +1 -1
  367. package/dist/observability/corrupt-read-seat.d.ts +4 -4
  368. package/dist/observability/corrupt-read-seat.js +5 -3
  369. package/dist/observability/fail-open.d.ts +58 -38
  370. package/dist/observability/fail-open.js +60 -38
  371. package/dist/observability/logger.d.ts +22 -1
  372. package/dist/observability/logger.js +89 -12
  373. package/dist/observability/metrics.js +3 -4
  374. package/dist/observability/otel-exporter.js +2 -1
  375. package/dist/observability/principal-context.d.ts +14 -7
  376. package/dist/observability/principal-context.js +8 -3
  377. package/dist/observability/run-terminal.d.ts +7 -1
  378. package/dist/observability/run-terminal.js +5 -2
  379. package/dist/orchestration/hardened-vm-runner.d.ts +1 -0
  380. package/dist/orchestration/hardened-vm-runner.js +11 -5
  381. package/dist/orchestration/hardened-vm-worker-runner.d.ts +0 -14
  382. package/dist/orchestration/hardened-vm-worker-runner.js +5 -0
  383. package/dist/orchestration/hardened-vm-worker.js +2 -1
  384. package/dist/orchestration/workflow-completion-inbox.d.ts +3 -3
  385. package/dist/orchestration/workflow-completion-inbox.js +3 -2
  386. package/dist/org-delivery-gate.d.ts +5 -4
  387. package/dist/org-delivery-gate.js +7 -6
  388. package/dist/outbound-dispatcher.d.ts +1 -1
  389. package/dist/outbound-dispatcher.js +6 -12
  390. package/dist/owner-brands.d.ts +81 -0
  391. package/dist/owner-brands.js +42 -0
  392. package/dist/owner-faces.d.ts +531 -0
  393. package/dist/owner-faces.js +126 -0
  394. package/dist/parked-decide.d.ts +67 -5
  395. package/dist/parked-decide.js +127 -5
  396. package/dist/parked-revive-surface.d.ts +14 -4
  397. package/dist/parked-revive-surface.js +5 -4
  398. package/dist/peer-directory.d.ts +6 -8
  399. package/dist/peer-directory.js +3 -2
  400. package/dist/permission-rule-vocab.d.ts +53 -8
  401. package/dist/permission-rule-vocab.js +30 -2
  402. package/dist/plugins/adoption-log-sql.d.ts +0 -22
  403. package/dist/plugins/adoption-log-sql.js +5 -3
  404. package/dist/plugins/approval-ask-retired-delete-by-task-m50.d.ts +7 -0
  405. package/dist/plugins/approval-ask-retired-delete-by-task-m50.js +17 -0
  406. package/dist/plugins/approval-ask-store-file.d.ts +18 -7
  407. package/dist/plugins/approval-ask-store-file.js +37 -14
  408. package/dist/plugins/approval-ask-store-memory.d.ts +12 -4
  409. package/dist/plugins/approval-ask-store-memory.js +24 -10
  410. package/dist/plugins/approval-ask-store-sql.d.ts +39 -20
  411. package/dist/plugins/approval-ask-store-sql.js +41 -10
  412. package/dist/plugins/approval-exemption-skill-m46.d.ts +20 -0
  413. package/dist/plugins/approval-exemption-skill-m46.js +25 -0
  414. package/dist/plugins/approval-exemption-store.d.ts +6 -1
  415. package/dist/plugins/approval-exemption-store.js +14 -0
  416. package/dist/plugins/approval-nonce-store.d.ts +39 -12
  417. package/dist/plugins/approval-nonce-store.js +72 -23
  418. package/dist/plugins/blob-backend.d.ts +2 -0
  419. package/dist/plugins/blob-backend.js +9 -6
  420. package/dist/plugins/caching-session-store.d.ts +13 -1
  421. package/dist/plugins/caching-session-store.js +43 -4
  422. package/dist/plugins/checkpoint-index-columns.d.ts +32 -5
  423. package/dist/plugins/checkpoint-index-columns.js +36 -1
  424. package/dist/plugins/checkpoint-store-face.d.ts +83 -10
  425. package/dist/plugins/checkpoint-store-face.js +18 -1
  426. package/dist/plugins/device-store-sql.js +1 -0
  427. package/dist/plugins/ensure-index.d.ts +13 -1
  428. package/dist/plugins/ensure-index.js +154 -21
  429. package/dist/plugins/ensure-schema-lock-policy.d.ts +0 -15
  430. package/dist/plugins/ensure-schema-lock-policy.js +3 -2
  431. package/dist/plugins/file-run-store.d.ts +63 -23
  432. package/dist/plugins/file-run-store.js +138 -83
  433. package/dist/plugins/host-platform.d.ts +24 -3
  434. package/dist/plugins/host-platform.js +15 -1
  435. package/dist/plugins/image-bake-store-sql.js +2 -0
  436. package/dist/plugins/imported-layer-root-retirement.d.ts +2 -2
  437. package/dist/plugins/k8s-pod-reaper.d.ts +1 -3
  438. package/dist/plugins/k8s-pod-reaper.js +0 -1
  439. package/dist/plugins/leader-run-store-sql.d.ts +22 -0
  440. package/dist/plugins/leader-run-store-sql.js +34 -4
  441. package/dist/plugins/local-checkpoint-store.d.ts +58 -23
  442. package/dist/plugins/local-checkpoint-store.js +195 -76
  443. package/dist/plugins/local-data-dir-modes-m39.js +2 -1
  444. package/dist/plugins/local-docker-capacity.d.ts +93 -0
  445. package/dist/plugins/local-docker-capacity.js +194 -0
  446. package/dist/plugins/local-docker-reaper.d.ts +92 -0
  447. package/dist/plugins/local-docker-reaper.js +102 -0
  448. package/dist/plugins/local-engine-high-water.d.ts +4 -2
  449. package/dist/plugins/local-engine-high-water.js +4 -1
  450. package/dist/plugins/local-session-store.d.ts +358 -125
  451. package/dist/plugins/local-session-store.js +824 -251
  452. package/dist/plugins/local-session-window.d.ts +3 -2
  453. package/dist/plugins/local-session-window.js +3 -2
  454. package/dist/plugins/local-sidecar-quarantine.js +3 -2
  455. package/dist/plugins/local-task-attachment-store.d.ts +18 -1
  456. package/dist/plugins/local-task-attachment-store.js +22 -1
  457. package/dist/plugins/memory-embedder.js +9 -7
  458. package/dist/plugins/memory-engine-pg.d.ts +3 -2
  459. package/dist/plugins/memory-engine-pg.js +14 -5
  460. package/dist/plugins/memory-engine-sql-apply.d.ts +8 -4
  461. package/dist/plugins/memory-engine-sql-apply.js +6 -8
  462. package/dist/plugins/memory-engine-tidb.d.ts +4 -2
  463. package/dist/plugins/memory-engine-tidb.js +11 -2
  464. package/dist/plugins/memory-optout-grant-store-sql.d.ts +1 -1
  465. package/dist/plugins/memory-optout-grant-store-sql.js +3 -3
  466. package/dist/plugins/memory-run-store.d.ts +39 -27
  467. package/dist/plugins/memory-run-store.js +72 -70
  468. package/dist/plugins/one-time-migration-marker.d.ts +10 -0
  469. package/dist/plugins/one-time-migration-marker.js +7 -0
  470. package/dist/plugins/one-time-migrations.d.ts +186 -45
  471. package/dist/plugins/one-time-migrations.js +442 -119
  472. package/dist/plugins/org-delivery-quota-store.js +2 -1
  473. package/dist/plugins/permission-rule-store-file.d.ts +3 -3
  474. package/dist/plugins/permission-rule-store-sql.d.ts +4 -63
  475. package/dist/plugins/permission-rule-store-sql.js +6 -86
  476. package/dist/plugins/pg-pool.d.ts +1 -31
  477. package/dist/plugins/pg-pool.js +16 -7
  478. package/dist/plugins/remote-env-e2b.d.ts +7 -25
  479. package/dist/plugins/remote-env-e2b.js +34 -25
  480. package/dist/plugins/remote-env-host.d.ts +2 -9
  481. package/dist/plugins/remote-env-host.js +34 -22
  482. package/dist/plugins/remote-env-k8s.d.ts +40 -45
  483. package/dist/plugins/remote-env-k8s.js +107 -58
  484. package/dist/plugins/remote-env-local-docker.d.ts +148 -14
  485. package/dist/plugins/remote-env-local-docker.js +367 -72
  486. package/dist/plugins/remote-scratchpad.js +4 -0
  487. package/dist/plugins/retention-deployment.d.ts +49 -17
  488. package/dist/plugins/retention-deployment.js +39 -8
  489. package/dist/plugins/run-preview-m45.d.ts +11 -0
  490. package/dist/plugins/run-preview-m45.js +19 -0
  491. package/dist/plugins/run-store-sql.d.ts +56 -68
  492. package/dist/plugins/run-store-sql.js +127 -116
  493. package/dist/plugins/s3-answer.d.ts +2 -1
  494. package/dist/plugins/sandbox-reaper.d.ts +26 -0
  495. package/dist/plugins/sandbox-reaper.js +2 -0
  496. package/dist/plugins/scenario-prefix-switch-m42.d.ts +54 -0
  497. package/dist/plugins/scenario-prefix-switch-m42.js +55 -0
  498. package/dist/plugins/scheduler-support.d.ts +16 -1
  499. package/dist/plugins/scheduler-support.js +22 -2
  500. package/dist/plugins/schema-consistency.d.ts +42 -9
  501. package/dist/plugins/schema-consistency.js +212 -11
  502. package/dist/plugins/schema-drift-sentence.d.ts +4 -1
  503. package/dist/plugins/schema-drift-sentence.js +4 -4
  504. package/dist/plugins/schema-ensure-legs.d.ts +9 -0
  505. package/dist/plugins/schema-ensure-legs.js +1 -1
  506. package/dist/plugins/schema-indexes.js +3 -0
  507. package/dist/plugins/schema-live-columns.d.ts +14 -5
  508. package/dist/plugins/schema-live-columns.js +10 -10
  509. package/dist/plugins/send-user-file.js +2 -1
  510. package/dist/plugins/session-birth.d.ts +37 -0
  511. package/dist/plugins/session-birth.js +38 -0
  512. package/dist/plugins/session-epoch-anchor.d.ts +40 -12
  513. package/dist/plugins/session-epoch-anchor.js +33 -11
  514. package/dist/plugins/session-ext-table.d.ts +27 -3
  515. package/dist/plugins/session-ext-table.js +19 -6
  516. package/dist/plugins/session-fork.d.ts +15 -1
  517. package/dist/plugins/session-fork.js +3 -0
  518. package/dist/plugins/session-ownership.d.ts +1 -1
  519. package/dist/plugins/session-placement.d.ts +22 -16
  520. package/dist/plugins/session-placement.js +15 -12
  521. package/dist/plugins/session-row-sql.d.ts +12 -0
  522. package/dist/plugins/session-row-sql.js +3 -3
  523. package/dist/plugins/session-run-rollup.d.ts +29 -0
  524. package/dist/plugins/session-run-rollup.js +40 -0
  525. package/dist/plugins/session-store-sql.d.ts +38 -12
  526. package/dist/plugins/session-store-sql.js +130 -30
  527. package/dist/plugins/session-withdraw-sql.d.ts +36 -0
  528. package/dist/plugins/session-withdraw-sql.js +42 -0
  529. package/dist/plugins/shared-memory-store-sql.d.ts +0 -69
  530. package/dist/plugins/shared-memory-store-sql.js +2 -1
  531. package/dist/plugins/shell-sentinel-owner-m48.d.ts +20 -0
  532. package/dist/plugins/shell-sentinel-owner-m48.js +3 -0
  533. package/dist/plugins/snapshot-bucket-presence.d.ts +2 -1
  534. package/dist/plugins/sql-driver.d.ts +1 -1
  535. package/dist/plugins/sql-driver.js +2 -1
  536. package/dist/plugins/sql-errors.d.ts +32 -5
  537. package/dist/plugins/sql-errors.js +55 -7
  538. package/dist/plugins/sql-json-column.d.ts +8 -7
  539. package/dist/plugins/sql-json-column.js +10 -6
  540. package/dist/plugins/store-backend.d.ts +84 -15
  541. package/dist/plugins/store-backend.js +186 -55
  542. package/dist/plugins/store-contracts.d.ts +90 -30
  543. package/dist/plugins/store-contracts.js +22 -1
  544. package/dist/plugins/store-fault.d.ts +28 -2
  545. package/dist/plugins/store-fault.js +20 -2
  546. package/dist/plugins/task-attachment-store.d.ts +15 -3
  547. package/dist/plugins/task-attachment-store.js +22 -9
  548. package/dist/plugins/tidb-pool.js +23 -8
  549. package/dist/plugins/web-search.js +5 -3
  550. package/dist/plugins/workflow-run-store-sql.d.ts +6 -1
  551. package/dist/plugins/workflow-run-store-sql.js +11 -5
  552. package/dist/principal-jwt.d.ts +4 -4
  553. package/dist/principal-jwt.js +20 -5
  554. package/dist/principal-shape.d.ts +41 -0
  555. package/dist/principal-shape.js +19 -0
  556. package/dist/question.d.ts +13 -23
  557. package/dist/question.js +21 -39
  558. package/dist/request-declaration-refusal.d.ts +35 -12
  559. package/dist/request-declaration-refusal.js +21 -9
  560. package/dist/request-form.d.ts +58 -0
  561. package/dist/request-form.js +72 -0
  562. package/dist/request-image-urls.d.ts +8 -2
  563. package/dist/request-image-urls.js +2 -1
  564. package/dist/request-images.d.ts +20 -0
  565. package/dist/request-images.js +59 -0
  566. package/dist/request-key-closure.d.ts +6 -7
  567. package/dist/request-key-closure.js +15 -2
  568. package/dist/resource-suspend.d.ts +7 -16
  569. package/dist/resource-suspend.js +1 -1
  570. package/dist/retired-name-host-notice.d.ts +21 -0
  571. package/dist/retired-name-host-notice.js +12 -0
  572. package/dist/rule-entry-list.d.ts +2 -2
  573. package/dist/rule-entry-list.js +3 -4
  574. package/dist/rule-issue-reading.d.ts +58 -0
  575. package/dist/rule-issue-reading.js +14 -0
  576. package/dist/rules-consent.d.ts +5 -3
  577. package/dist/rules-consent.js +1 -0
  578. package/dist/run-acceptance.d.ts +3 -1
  579. package/dist/run-acceptance.js +3 -0
  580. package/dist/run-local.d.ts +14 -6
  581. package/dist/run-local.js +92 -80
  582. package/dist/run-stale-default.d.ts +7 -0
  583. package/dist/run-stale-default.js +2 -0
  584. package/dist/runs.d.ts +26 -15
  585. package/dist/runs.js +39 -27
  586. package/dist/runtime-caps-resolver.d.ts +21 -6
  587. package/dist/runtime-caps-resolver.js +17 -4
  588. package/dist/runtime-governance.d.ts +2 -2
  589. package/dist/runtime-governance.js +5 -3
  590. package/dist/sealed-key-layout.d.ts +12 -5
  591. package/dist/sealed-key-layout.js +5 -0
  592. package/dist/sealed-key.d.ts +12 -2
  593. package/dist/sealed-key.js +115 -27
  594. package/dist/security.d.ts +128 -158
  595. package/dist/security.js +163 -59
  596. package/dist/sema-config-dir.d.ts +20 -0
  597. package/dist/sema-config-dir.js +25 -0
  598. package/dist/server-secret-env.d.ts +21 -5
  599. package/dist/server-secret-env.js +14 -4
  600. package/dist/session-children-retire.d.ts +7 -5
  601. package/dist/session-children-retire.js +7 -2
  602. package/dist/session-deletion.d.ts +88 -0
  603. package/dist/session-deletion.js +8 -0
  604. package/dist/session-erase.d.ts +145 -0
  605. package/dist/session-erase.js +115 -0
  606. package/dist/session-error-wire.d.ts +5 -5
  607. package/dist/session-error-wire.js +1 -1
  608. package/dist/session-incarnation.d.ts +52 -5
  609. package/dist/session-incarnation.js +19 -2
  610. package/dist/session-policy-wire.d.ts +6 -3
  611. package/dist/session-policy-wire.js +11 -1
  612. package/dist/session-resident-background.d.ts +0 -71
  613. package/dist/session-resident-background.js +4 -3
  614. package/dist/session-row.d.ts +2 -1
  615. package/dist/session-rules-seat.d.ts +12 -0
  616. package/dist/session-rules-seat.js +19 -0
  617. package/dist/session-titler.d.ts +7 -15
  618. package/dist/session-titler.js +1 -1
  619. package/dist/spec-fields.d.ts +57 -3
  620. package/dist/spec-fields.js +72 -51
  621. package/dist/store-posture.d.ts +136 -20
  622. package/dist/store-posture.js +188 -3
  623. package/dist/stored-request-hooks-m20.js +2 -2
  624. package/dist/stores-sql/background-agent-store-sql.d.ts +11 -2
  625. package/dist/stores-sql/background-agent-store-sql.js +73 -20
  626. package/dist/stores-sql/checkpoint-store-sql.d.ts +33 -28
  627. package/dist/stores-sql/checkpoint-store-sql.js +75 -44
  628. package/dist/stores-sql/mailbox-store-sql.d.ts +7 -4
  629. package/dist/stores-sql/mailbox-store-sql.js +31 -32
  630. package/dist/stores-sql/pg-session-storage.d.ts +7 -5
  631. package/dist/stores-sql/pg-session-storage.js +54 -46
  632. package/dist/stores-sql/retention-store-sql.d.ts +87 -19
  633. package/dist/stores-sql/retention-store-sql.js +92 -27
  634. package/dist/stores-sql/session-policy-store-sql.d.ts +32 -10
  635. package/dist/stores-sql/session-policy-store-sql.js +44 -36
  636. package/dist/stores-sql/session-write-hooks.d.ts +12 -6
  637. package/dist/stores-sql/tidb-session-storage.d.ts +4 -4
  638. package/dist/stores-sql/tidb-session-storage.js +13 -8
  639. package/dist/stores-sql/tidb-session-store.d.ts +36 -17
  640. package/dist/stores-sql/tidb-session-store.js +69 -39
  641. package/dist/stores-sql/windowed-session-storage.d.ts +5 -0
  642. package/dist/stores-sql/windowed-session-storage.js +9 -0
  643. package/dist/submission-exit.d.ts +50 -0
  644. package/dist/submission-exit.js +108 -0
  645. package/dist/task-a2a.d.ts +1 -1
  646. package/dist/task-a2a.js +3 -3
  647. package/dist/task-cwd.d.ts +20 -0
  648. package/dist/task-cwd.js +8 -0
  649. package/dist/task-mcp.d.ts +1 -1
  650. package/dist/task-mcp.js +3 -3
  651. package/dist/task-settings.d.ts +14 -10
  652. package/dist/task-settings.js +18 -7
  653. package/dist/terminal.d.ts +25 -43
  654. package/dist/terminal.js +31 -11
  655. package/dist/tool-approval.d.ts +131 -129
  656. package/dist/tool-approval.js +189 -193
  657. package/dist/trace/core-keyset-guard.d.ts +13 -6
  658. package/dist/trace/core-vocab-wire.d.ts +95 -0
  659. package/dist/trace/core-vocab-wire.js +15 -0
  660. package/dist/trace/exit-seat.d.ts +30 -4
  661. package/dist/trace/exit-seat.js +40 -36
  662. package/dist/trace/extension-call-face.d.ts +3 -2
  663. package/dist/trace/extension-call-face.js +3 -1
  664. package/dist/trace/ledger-events.d.ts +4 -7
  665. package/dist/trace/ledger-sink.d.ts +1 -30
  666. package/dist/trace/ledger-sink.js +0 -11
  667. package/dist/trace/model-segment.d.ts +5 -5
  668. package/dist/trace/model-segment.js +5 -5
  669. package/dist/trace/project.d.ts +55 -42
  670. package/dist/trace/project.js +52 -19
  671. package/dist/trace/redact.d.ts +123 -27
  672. package/dist/trace/redact.js +880 -260
  673. package/dist/trace/self-minted-wire.d.ts +487 -19
  674. package/dist/trace/self-minted-wire.js +172 -23
  675. package/dist/trace/wire-projection-faces.d.ts +5 -6
  676. package/dist/trace/wire-projection-faces.js +2 -2
  677. package/dist/upstream-body.d.ts +23 -0
  678. package/dist/upstream-body.js +16 -0
  679. package/dist/url-refusal.d.ts +3 -3
  680. package/dist/url-refusal.js +11 -4
  681. package/dist/user-authored-text.d.ts +1 -1
  682. package/dist/user-input-ledger.d.ts +7 -8
  683. package/dist/user-input-ledger.js +1 -1
  684. package/dist/web-admin-client/apply-effective.d.ts +6 -3
  685. package/dist/web-admin-client/apply-effective.js +13 -16
  686. package/dist/web-admin-client/apply-ledger.d.ts +16 -7
  687. package/dist/web-admin-client/apply-ledger.js +5 -2
  688. package/dist/web-admin-client/center-request.d.ts +2 -2
  689. package/dist/web-admin-client/center-request.js +15 -15
  690. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  691. package/dist/web-admin-client/effective-keys.js +1 -1
  692. package/dist/web-admin-client/entry-metadata.d.ts +8 -0
  693. package/dist/web-admin-client/entry-metadata.js +13 -0
  694. package/dist/web-admin-client/http-client.d.ts +1 -1
  695. package/dist/web-admin-client/http-client.js +23 -4
  696. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  697. package/dist/web-admin-client/mcp-revocation.js +2 -1
  698. package/dist/web-admin-client/read-warnings.d.ts +1 -0
  699. package/dist/web-admin-client/read-warnings.js +1 -0
  700. package/dist/web-admin-client/restart-signal.js +8 -4
  701. package/dist/web-admin-client/skills-mcp.d.ts +2 -2
  702. package/dist/web-admin-client/types.d.ts +1 -2
  703. package/dist/workspace-space.d.ts +3 -2
  704. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +4 -4
  705. package/package.json +6 -3
  706. package/scripts/drain-check-local.mjs +118 -147
  707. package/scripts/drain-check.mysql.sql +22 -2
  708. package/scripts/drain-check.pg.sql +22 -2
  709. package/wire-changes/server@7.148.0.json +1517 -0
  710. package/dist/http/memory-control-plane-corrupt-reply.d.ts +0 -25
  711. package/dist/http/memory-control-plane-corrupt-reply.js +0 -19
  712. package/dist/http/memory-layer-reply.d.ts +0 -30
  713. package/dist/http/memory-layer-reply.js +0 -24
  714. package/dist/lsp/e2b-bridge.d.ts +0 -57
  715. package/dist/lsp/e2b-bridge.js +0 -139
  716. package/dist/lsp/e2b-manager.d.ts +0 -93
  717. package/dist/lsp/e2b-manager.js +0 -178
  718. package/dist/lsp/lsp-frames.d.ts +0 -14
  719. package/dist/lsp/lsp-frames.js +0 -25
  720. package/dist/lsp/manager.d.ts +0 -129
  721. package/dist/lsp/manager.js +0 -127
  722. package/dist/lsp/types.d.ts +0 -12
  723. package/dist/lsp/types.js +0 -2
  724. package/dist/lsp/ws-transport.d.ts +0 -40
  725. package/dist/lsp/ws-transport.js +0 -210
@@ -2,18 +2,21 @@ import { redactHead } from "../observability/run-terminal.js";
2
2
  const errText = (e) => redactHead(e instanceof Error ? e.message : String(e), 2000);
3
3
  import { checkpointRevOf } from "@sema-agent/core";
4
4
  import { findParkOrigin } from "../parked-decide.js";
5
- import { decodeCheckpointScope } from "../security.js";
5
+ import { recoveredSubject } from "../owner-faces.js";
6
6
  import { hostDecisionFacts } from "../host-decision.js";
7
7
  import {} from "../tool-approval.js";
8
8
  import { APPROVAL_GATE_KINDS } from "../approval-content-kind.js";
9
9
  import { createWallClockJumpGuard } from "../wall-clock-jump-guard.js";
10
- import { gatedPrincipal, hasServiceAuth } from "./principal-gate.js";
10
+ import { gatedPerson } from "./principal-gate.js";
11
+ import { hasServiceAuth } from "../identity-source.js";
11
12
  import { costQuotaRefusalOf } from "./request-guards.js";
12
13
  import { admissionRefusalOf, readinessOf } from "./readiness.js";
14
+ import { rowReadRefusalAnswer } from "./resume-legs.js";
13
15
  import { readResumeCtx } from "./resume-ctx-read.js";
14
16
  import { isResumeBlockedByPolicy } from "./checkpoint-ctx.js";
15
17
  import { storedBodyReplayRefusal } from "./stored-body-replay.js";
16
18
  import { refusalBody } from "./refusal-body.js";
19
+ import { DENY_SWEEP_PAGE_ROWS } from "../plugins/checkpoint-store-face.js";
17
20
  const BLOCKED_SCALAR_KEYS = ["errorCode", "blockedBy", "field", "reason", "count", "cap", "index"];
18
21
  function blockedScalars(body) {
19
22
  const out = {};
@@ -28,14 +31,16 @@ function blockedScalars(body) {
28
31
  }
29
32
  const BLOCKED_WARNED_MAX = 1024;
30
33
  export function createApprovalSweeps(ctx) {
31
- const { deps, resumeCheckpoint, mayDiscloseRowError } = ctx;
34
+ const { deps, resumeCheckpoint, decisionRowAdmits } = ctx;
32
35
  const blockedWarned = new Map();
36
+ let sweepAfter;
37
+ let sweepCycle = 0;
33
38
  const noteResumeBlocked = (cardToken, sessionId, status, body) => {
34
39
  deps.metrics?.inc("deny_sweep_resume_blocked_total");
35
40
  const fields = { status, ...blockedScalars(body) };
36
41
  if (cardToken !== undefined) {
37
42
  const fingerprint = JSON.stringify(fields);
38
- if (blockedWarned.get(cardToken) === fingerprint)
43
+ if (blockedWarned.get(cardToken)?.fingerprint === fingerprint)
39
44
  return;
40
45
  blockedWarned.delete(cardToken);
41
46
  if (blockedWarned.size >= BLOCKED_WARNED_MAX) {
@@ -43,7 +48,7 @@ export function createApprovalSweeps(ctx) {
43
48
  if (oldest.done !== true)
44
49
  blockedWarned.delete(oldest.value);
45
50
  }
46
- blockedWarned.set(cardToken, fingerprint);
51
+ blockedWarned.set(cardToken, { fingerprint, cycle: sweepCycle });
47
52
  }
48
53
  deps.logger?.warn?.("deny_sweep_resume_blocked", { sessionId, ...fields });
49
54
  };
@@ -70,7 +75,7 @@ export function createApprovalSweeps(ctx) {
70
75
  return;
71
76
  let expired;
72
77
  try {
73
- expired = await cs.listExpiredApprovalGates(now);
78
+ expired = await cs.listExpiredApprovalGates(now, DENY_SWEEP_PAGE_ROWS, sweepAfter);
74
79
  }
75
80
  catch (e) {
76
81
  deps.metrics?.inc("deny_sweep_list_failed_total");
@@ -80,42 +85,50 @@ export function createApprovalSweeps(ctx) {
80
85
  });
81
86
  return;
82
87
  }
88
+ const cycleEnds = expired.length < DENY_SWEEP_PAGE_ROWS;
89
+ sweepAfter = cycleEnds ? undefined : expired[expired.length - 1]?.position;
83
90
  const parkSources = deps.backgroundAgentStore !== undefined || deps.workflowAgentSessionIndex !== undefined;
84
91
  const cardOf = async (sessionId) => {
85
92
  let token;
86
93
  let binding = {};
94
+ let runSessionId;
87
95
  try {
88
96
  token = (await cs.findPendingTokenBySession(sessionId, undefined, { gateKinds: APPROVAL_GATE_KINDS })) ?? undefined;
89
97
  if (!token)
90
- return { token, parked: false, rev: undefined, binding };
98
+ return { token, parked: false, rev: undefined, binding, runSessionId };
99
+ runSessionId = (await cs.hostSessionOfCard(token)) ?? undefined;
91
100
  const cp = await cs.get(token);
92
101
  if (!cp)
93
- return { token, parked: false, rev: undefined, binding };
102
+ return { token, parked: false, rev: undefined, binding, runSessionId };
94
103
  const pa = cp.pendingAction;
95
104
  binding = { checkpointToken: token, ...(pa.kind === "tool_approval" ? { boundCallId: pa.toolCallId, boundInputHash: pa.boundInputHash } : {}) };
96
105
  const rev = checkpointRevOf(cp);
97
106
  if (!parkSources)
98
- return { token, parked: false, rev, binding };
107
+ return { token, parked: false, rev, binding, runSessionId };
99
108
  const origin = await findParkOrigin({
100
109
  ...(deps.backgroundAgentStore !== undefined ? { agentStore: deps.backgroundAgentStore } : {}),
101
110
  ...(deps.workflowAgentSessionIndex !== undefined && deps.workflowRunStore !== undefined
102
111
  ? { workflowIndex: deps.workflowAgentSessionIndex, workflowRunStore: deps.workflowRunStore }
103
112
  : {}),
104
113
  }, { token, scope: cp.scope, sessionId: cp.sessionId });
105
- return { token, parked: origin !== undefined, rev, binding };
114
+ return { token, parked: origin !== undefined, rev, binding, runSessionId };
106
115
  }
107
116
  catch {
108
- return { token, parked: false, rev: undefined, binding };
117
+ return { token, parked: false, rev: undefined, binding, runSessionId };
109
118
  }
110
119
  };
111
- const storedBodyUnservable = async (sessionId) => {
112
- const read = await readResumeCtx(cs.getCtx(sessionId), { sessionId, opener: deps.checkpointCtxSealing });
120
+ const storedBodyUnservable = async (runSessionId) => {
121
+ if (runSessionId === undefined)
122
+ return undefined;
123
+ const read = await readResumeCtx(cs.getCtx(runSessionId), { sessionId: runSessionId, opener: deps.checkpointCtxSealing });
113
124
  if (read.kind === "corrupt")
114
125
  return undefined;
115
126
  if (read.kind === "unsealable")
116
127
  return undefined;
117
128
  if (read.kind === "absent")
118
129
  return undefined;
130
+ if (read.kind === "unreadable")
131
+ return undefined;
119
132
  return storedBodyReplayRefusal(read.ctx, deps.config);
120
133
  };
121
134
  const expirePolicyBlockedCard = async (cardToken, observedRev, sessionId, body) => {
@@ -141,16 +154,24 @@ export function createApprovalSweeps(ctx) {
141
154
  };
142
155
  let parkedSkipped = 0;
143
156
  const replaySkipped = [];
144
- const seenCards = new Set();
145
157
  for (const { sessionId } of expired) {
146
- const { token: cardToken, parked, rev: cardRev, binding: cardBinding } = await cardOf(sessionId);
147
- if (cardToken !== undefined)
148
- seenCards.add(cardToken);
158
+ const { token: cardToken, parked, rev: cardRev, binding: cardBinding, runSessionId } = await cardOf(sessionId);
159
+ const warned = cardToken === undefined ? undefined : blockedWarned.get(cardToken);
160
+ if (warned !== undefined)
161
+ warned.cycle = sweepCycle;
149
162
  if (parked) {
150
163
  parkedSkipped += 1;
151
164
  continue;
152
165
  }
153
- const unservable = await storedBodyUnservable(sessionId);
166
+ let unservable;
167
+ try {
168
+ unservable = await storedBodyUnservable(runSessionId);
169
+ }
170
+ catch (e) {
171
+ deps.metrics?.inc("deny_sweep_row_failed_total");
172
+ deps.logger?.warn?.("deny_sweep_row_failed", { sessionId, err: errText(e), note: "reading this expired approval's stored request threw, so it was not resumed this tick; the rest of the page was swept, and this row is tried again when the sweep comes round to it" });
173
+ continue;
174
+ }
154
175
  if (unservable !== undefined) {
155
176
  replaySkipped.push({ sessionId, kind: unservable.kind });
156
177
  continue;
@@ -172,9 +193,12 @@ export function createApprovalSweeps(ctx) {
172
193
  if (isResumeBlockedByPolicy(out) && cardToken !== undefined && cardRev !== undefined)
173
194
  await expirePolicyBlockedCard(cardToken, cardRev, sessionId, out.body);
174
195
  }
175
- for (const token of [...blockedWarned.keys()])
176
- if (!seenCards.has(token))
177
- blockedWarned.delete(token);
196
+ if (cycleEnds) {
197
+ for (const [token, warned] of [...blockedWarned])
198
+ if (warned.cycle !== sweepCycle)
199
+ blockedWarned.delete(token);
200
+ sweepCycle += 1;
201
+ }
178
202
  if (parkedSkipped > 0)
179
203
  deps.logger?.info?.("deny_sweep_parked_skipped", { count: parkedSkipped });
180
204
  if (replaySkipped.length > 0) {
@@ -197,31 +221,31 @@ export function createApprovalSweeps(ctx) {
197
221
  if (refusal !== undefined)
198
222
  return { status: refusal.status, body: refusal.body };
199
223
  if (deps.costQuota && req.httpReq) {
200
- const quotaPrincipal = gatedPrincipal(req.httpReq, deps.config);
201
- if (quotaPrincipal !== undefined) {
202
- const d = deps.costQuota.check(quotaPrincipal);
224
+ const quotaPerson = gatedPerson(req.httpReq, deps.config);
225
+ if (quotaPerson !== undefined) {
226
+ const d = deps.costQuota.check(quotaPerson);
203
227
  if (!d.allowed) {
204
228
  deps.metrics?.inc("cost_quota_rejected_total");
205
229
  return costQuotaRefusalOf(d);
206
230
  }
207
231
  }
208
232
  }
233
+ const answerer = { subject: recoveredSubject(req.principal), operator: false };
209
234
  let cp;
210
235
  try {
211
236
  cp = await cs.get(req.gateToken);
212
237
  }
213
238
  catch (e) {
214
- if (!(await mayDiscloseRowError(cs, req.gateToken, { principal: req.principal, explicitOperator: false }))) {
239
+ if (!(await decisionRowAdmits(cs, req.gateToken, answerer, undefined))) {
215
240
  deps.logger?.warn?.("parked_late_decision_unreadable_row_withheld", { askId: req.askId });
216
241
  return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
217
242
  }
218
- return { status: 409, body: refusalBody({ errorCode: "conflict.checkpoint_unreadable", message: e instanceof Error ? e.message : String(e) }) };
243
+ return rowReadRefusalAnswer(e);
219
244
  }
220
245
  if (!cp) {
221
246
  return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
222
247
  }
223
- const cpPrincipal = decodeCheckpointScope(cp.scope);
224
- if (cpPrincipal !== undefined && cpPrincipal !== req.principal) {
248
+ if (!(await decisionRowAdmits(cs, req.gateToken, answerer, cp.scope))) {
225
249
  deps.logger?.warn?.("parked_late_decision_scope_mismatch", { askId: req.askId });
226
250
  return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
227
251
  }
@@ -232,8 +256,8 @@ export function createApprovalSweeps(ctx) {
232
256
  ...(req.updatedInput !== undefined ? { updatedInput: req.updatedInput } : {}),
233
257
  };
234
258
  const remember = req.remember === "session" ? { grantedBy: req.principal ?? null, laneCannotRecord: "decide_once" } : undefined;
235
- const out = await resumeCheckpoint(cp.sessionId, req.decision, req.note, hostDecisionFacts(req.decider, req.principal), req.httpReq, undefined, binding, remember, true, { principal: req.principal, explicitOperator: false });
236
- return { status: out.status, body: out.body, ...(remember !== undefined ? { rememberApplied: out.rememberApplied === true } : {}) };
259
+ const out = await resumeCheckpoint(cp.sessionId, req.decision, req.note, hostDecisionFacts(req.decider, req.principal), req.httpReq, undefined, binding, remember, true, answerer);
260
+ return { status: out.status, body: out.body, ...(remember !== undefined ? { rememberApplied: out.rememberApplied === true } : {}), gateGeneration: checkpointRevOf(cp) };
237
261
  }
238
262
  return { denyExpiredApprovals, redeemParkedAsk };
239
263
  }
@@ -19,9 +19,12 @@
19
19
  * **判的是哪些表**:请求体上不经人答就生效的规则表 —— `settings.permissions` 的每个成员桶(逐 `membersOf("permissions")`),以及请求**按名点用**(`userInvokedSkills`)的
20
20
  * 自带技能的两只清单(引擎 `seedSkillGrants`:人点的名就是表态,不出 `Skill` 卡 ⇒ `allowedTools` 是 `allow` 成员的孪生、`disallowedTools` 是 `deny` 的孪生,键 → 成员一张表
21
21
  * {@link SKILL_LIST_MEMBER})。没点用的自带技能不判:它的清单要经 `Skill` 卡上的人点头才生效 —— 那正是契约给低于门槛的放宽指定的同意出口。
22
+ * **部署 / 中心的技能不判**(点名了也不判):它们的两只清单是运维授权,与 `APPROVAL_GRANT` 同级 —— 来处只有部署的 `SKILLS_DIR` / 本地配置源与中心的 `skills` · `plugins` 域,
23
+ * 契约给这两个域的写角色(`domainWriteRole`)不低于本表 `global` 的门槛(治理写角色),同名时部署的那只胜出、请求体那只被丢(`buildRunSkills`)⇒ 调用方没有改写它们清单的路;
24
+ * 点名只是选用。契约哪天把那两个域的写角色压到治理写角色之下,`test/caller-trust.test.ts` 的角色阶钉红,这条读法要重审。
22
25
  * 准入只经契约导出:桶非空且 `!isAtLeast(档, memberAdmission(…).minTrust)` ⇒ 不准入;不按方向开特例(契约的层准入同样先判 floor)。
23
- * 不准入 ⇒ 受理口 400,体与条目问题同形(`entry-problems.ts`:`field` + `detail.problems` + `total`),原因词 = 契约 `LAYER_ADMISSION_VERDICTS` 的 `below_trust_floor`,
24
- * 另带 `detail.callerTrust`(这次请求的档)。响亮拒而不是静默丢:契约要求低于门槛的放宽不得静默吞,出路是同意(答卡)或运维的 allow 表。
26
+ * 不准入 ⇒ 受理口 400,体与条目问题同形(`entry-problems.ts`:根上的 `field` + `problems` + `total`),原因词 = 契约 `LAYER_ADMISSION_VERDICTS` 的 `below_trust_floor`,
27
+ * 另带根上的 `callerTrust`(这次请求的档)。响亮拒而不是静默丢:契约要求低于门槛的放宽不得静默吞,出路是同意(答卡)或运维的 allow 表。
25
28
  *
26
29
  * 读者(都读同一次求值,不各算一份):提交受理口(`admission.ts` `prepareSpec`,三提交面共用)与能力位 `settings.permissions.callerTrust`(`routes/capabilities.ts`)。
27
30
  * 续跑腿不读本档:存储体在自己的受理口按当时的档准入过。
@@ -30,7 +33,7 @@ import type { IncomingMessage } from "node:http";
30
33
  import { type MinTrust, type SafetyMergeMember, type UserRole } from "@sema-agent/settings-schema";
31
34
  import type { SkillSpec } from "@sema-agent/core";
32
35
  import type { ServiceConfig } from "../config-types.js";
33
- import { type EntryProblem } from "../entry-problems.js";
36
+ import { type EntryProblemsFacts } from "../entry-problems.js";
34
37
  import type { ParsedTaskSettings } from "../task-settings.js";
35
38
  /**
36
39
  * 档是**怎么**推出来的(闭集;拒句按它说出路)。加一个词 ⇒ {@link basisClause} 的穷举 switch 编译红。
@@ -61,13 +64,8 @@ export interface RequestRuleTables {
61
64
  /** 受理口拒体:句子 + 机读位(原样进 `sendError` 的 facts)。 */
62
65
  export interface RequestTrustRefusal {
63
66
  readonly message: string;
64
- readonly facts: {
65
- readonly field: string;
66
- readonly detail: {
67
- readonly problems: readonly EntryProblem[];
68
- readonly total: number;
69
- readonly callerTrust: MinTrust;
70
- };
67
+ readonly facts: EntryProblemsFacts & {
68
+ readonly callerTrust: MinTrust;
71
69
  };
72
70
  }
73
71
  /**
@@ -72,10 +72,9 @@ export function requestTrustRefusal(tables, reading) {
72
72
  }
73
73
  if (first === undefined)
74
74
  return undefined;
75
- const facts = entryProblemsFacts(problems);
76
75
  return {
77
76
  message: `${first.table.field} needs trust "${first.minTrust}" (${whatItDoes(first.table.source, first.loosens)}) and this request is admitted at "${reading.trust}": ${basisClause(reading)}. Below that trust these rules are not applied — ${outletOf(first.table.source, first.loosens)}.`,
78
- facts: { field: facts.field, detail: { ...facts.detail, callerTrust: reading.trust } },
77
+ facts: { ...entryProblemsFacts(problems), callerTrust: reading.trust },
79
78
  };
80
79
  }
81
80
  function whatItDoes(source, loosens) {
@@ -0,0 +1,49 @@
1
+ /**
2
+ * **认领之后、起跑之前**的两件事(三条提交腿 —— 流式 / 同步 / 后台 —— 同一只):
3
+ * · {@link startClaimHeartbeat}:认领赢的那一拍起心跳(落点 / 续跑输入 / 决定落行几笔店写都在起跑之前,任何一笔卡过收割窗,收割器就会把这条还活着的行判死、放掉认领);
4
+ * 起跑那一拍交给腿自己的心跳,每条收场出口停掉它;
5
+ * · {@link claimStillHeld}:引擎起跑之前的最后一读 —— 认领此刻还是不是这条 run 的(一次栅栏写,也是一次心跳)。不是 ⇒ 不起引擎(收割已放掉认领,会话可能已被删、
6
+ * 已归别的 run;起跑就是在一只别人的会话上跑,或让引擎在原 id 上重建一只无主的根)。
7
+ * 如实的边:栅栏的担保止于它那一拍 —— 复核之后、引擎起跑之前腿上还有一两次店读(停驻决定 / 受理账本),这一窗里心跳持续失败到收割窗以外
8
+ * (或进程停住那么久)⇒ 仍可能在失去认领之后起跑。「失认领后绝不起跑」要一只把认领带进引擎的栅栏,不在本模块。
9
+ */
10
+ import { type RunHeartbeatStore } from "../runs.js";
11
+ import { type ClaimFenceStore } from "../plugins/store-contracts.js";
12
+ import type { RunStore } from "../plugins/store-backend.js";
13
+ import type { FlatServiceDeps } from "./server.js";
14
+ import { buildActiveRunConflict } from "./active-run-conflict.js";
15
+ import { rootSessionAbsentAnswer } from "./execution-context.js";
16
+ import { type RefusalBody } from "./refusal-body.js";
17
+ import { headReadOf } from "../session-incarnation.js";
18
+ /** 认领赢的那一拍起心跳(与后台腿 `runInBackground` 同一只周期、同一条带属主的刷新);交回停表。行已不在跑 ⇒ 心跳自停(起跑之前的复核随后答失认领)。刷新失败不抛(计数),下一拍再刷。 */
19
+ export declare function startClaimHeartbeat(runStore: RunHeartbeatStore, taskId: string, owner: string | null, metrics: {
20
+ inc(name: string, labels?: Record<string, string>): void;
21
+ } | undefined): () => void;
22
+ /** 起跑之前的认领复核:栅栏里什么都不写,只问「还持有吗」(一次栅栏写也是一次心跳)。 */
23
+ export declare function claimStillHeld(runStore: ClaimFenceStore, sessionId: string, taskId: string): Promise<boolean>;
24
+ /**
25
+ * 三条提交腿起跑之前的那一只复核(唯一调用形):持有 ⇒ `undefined`(照起);没持有 ⇒ {@link refusalAfterLostClaim} 的答复;栅栏自己抛(店一时不通)⇒
26
+ * 先按 {@link releaseClaimedRun} 撤掉本请求刚认领的这条 run(终结行 + 放幂等键,不留一条没起跑的 `running` 行占着会话等收割),再原样上抛。
27
+ */
28
+ export declare function recheckClaimBeforeLaunch(deps: Pick<FlatServiceDeps, "checkpointStore" | "config" | "logger"> & LostClaimSessionFace, runStore: ClaimFenceStore & LostClaimStore, sessionId: string, taskId: string): Promise<Awaited<ReturnType<typeof refusalAfterLostClaim>> | undefined>;
29
+ /** 失认领答复读会话店的那一面:只问头读(`headReadOf` 判店有没有它)—— 不要整只会话店。 */
30
+ export interface LostClaimSessionFace {
31
+ readonly sessionStorage?: Parameters<typeof headReadOf>[0];
32
+ }
33
+ /** 失认领答复与撤回本次 run 读写的那几面。 */
34
+ export type LostClaimStore = Pick<RunStore, "getActiveTaskId" | "getRun" | "setTerminal" | "releaseIdemKey">;
35
+ /**
36
+ * 起跑之前认领复核没过的答复(三条提交腿同一只;三臂按「此刻是谁的事实」分,各读各的):
37
+ * · 认领此刻在别的 run 上 ⇒ 409 冲突体(与建行时认领输同一只材料,`conflict.session_active_run`);
38
+ * · 会话店的头读答「没有这只会话」⇒ 404 `resume.session_not_found`(四个建行点「会话不在」同一只答复)—— 只有读到它不在才这么答;
39
+ * · 否则(本条行已被死亡判决终局 —— 观察口 / 认领冲突 / 收割器之一 —— 没人持认领,会话在;或店没有头读、说不出它不在)⇒ 409 `conflict.claim_lost`:说的是本条 run 的事实(判决在起跑之前结清了它),不说会话。
40
+ * 三臂都不放键、不终结行(行已被收割终局;键随那条终局行,与收割的既有读法同 —— 撤回出口删本次那一条 run 行时键随行去,`plugins/session-birth.ts`)。
41
+ */
42
+ export declare function refusalAfterLostClaim(deps: Pick<FlatServiceDeps, "checkpointStore" | "config"> & LostClaimSessionFace, runStore: LostClaimStore, sessionId: string, taskId: string): Promise<{
43
+ status: 409;
44
+ body: Awaited<ReturnType<typeof buildActiveRunConflict>>;
45
+ } | ReturnType<typeof rootSessionAbsentAnswer> | {
46
+ status: 409;
47
+ body: RefusalBody;
48
+ }>;
49
+ //# sourceMappingURL=claim-heartbeat.d.ts.map
@@ -0,0 +1,46 @@
1
+ import { beatRunHeartbeat, HEARTBEAT_MS } from "../runs.js";
2
+ import { FENCE_LANDED } from "../plugins/store-contracts.js";
3
+ import { buildActiveRunConflict } from "./active-run-conflict.js";
4
+ import { rootSessionAbsentAnswer } from "./execution-context.js";
5
+ import { readTurnActivityMs } from "../turn-activity.js";
6
+ import { releaseClaimedRun } from "./claimed-run.js";
7
+ import { refusalBody } from "./refusal-body.js";
8
+ import { headReadOf } from "../session-incarnation.js";
9
+ export function startClaimHeartbeat(runStore, taskId, owner, metrics) {
10
+ const timer = setInterval(() => {
11
+ beatRunHeartbeat(runStore, taskId, owner, () => clearInterval(timer), () => {
12
+ metrics?.inc("run_signal_poll_errors_total", { kind: "heartbeat" });
13
+ });
14
+ }, HEARTBEAT_MS);
15
+ timer.unref?.();
16
+ return () => clearInterval(timer);
17
+ }
18
+ export async function claimStillHeld(runStore, sessionId, taskId) {
19
+ if ("db" in runStore)
20
+ return (await runStore.whileHoldingClaim(sessionId, taskId, async () => undefined)).held;
21
+ return runStore.whileHoldingClaim(sessionId, taskId, () => FENCE_LANDED);
22
+ }
23
+ export async function recheckClaimBeforeLaunch(deps, runStore, sessionId, taskId) {
24
+ let held;
25
+ try {
26
+ held = await claimStillHeld(runStore, sessionId, taskId);
27
+ }
28
+ catch (err) {
29
+ await releaseClaimedRun(runStore, taskId, `the claim re-check before launch failed: ${err instanceof Error ? err.message : String(err)}`, (releaseErr, step) => {
30
+ deps.logger?.warn?.("claim_recheck_release_failed", { taskId, sessionId, step, err: releaseErr instanceof Error ? releaseErr.message : String(releaseErr) });
31
+ });
32
+ throw err;
33
+ }
34
+ return held ? undefined : await refusalAfterLostClaim(deps, runStore, sessionId, taskId);
35
+ }
36
+ export async function refusalAfterLostClaim(deps, runStore, sessionId, taskId) {
37
+ const holder = await runStore.getActiveTaskId(sessionId);
38
+ if (holder !== undefined && holder !== taskId) {
39
+ return { status: 409, body: await buildActiveRunConflict({ runStore, checkpointStore: deps.checkpointStore, governance: deps.config, turnActivity: readTurnActivityMs }, sessionId, holder) };
40
+ }
41
+ const headOf = headReadOf(deps.sessionStorage);
42
+ if (headOf !== undefined && (await headOf(sessionId)) === undefined)
43
+ return rootSessionAbsentAnswer();
44
+ return { status: 409, body: refusalBody({ errorCode: "conflict.claim_lost", message: "the run this request claimed was settled by the stale-run verdict before the engine started it (its claim heartbeat did not land within the reap window) — nothing ran" }) };
45
+ }
46
+ //# sourceMappingURL=claim-heartbeat.js.map
@@ -1,7 +1,8 @@
1
1
  /**
2
- * 一条提交腿**刚认领**的 run 在起跑之前就收场 —— 撤掉本请求建的东西的**唯一**写法。三个调用点:device 落点拒
3
- * (`execution-context.ts` `commitExecutionContext`)、续跑输入写不进(`submit-ctx.ts` `persistSubmitCtx`)与 workflow 决定行没落成
4
- * (`durable-run-leg.ts` 的 fresh 投递腿;此刻认领可能已被收割归了别人 —— 两步都按这一跑自己的 taskId,碰不到别人的认领)。
2
+ * 一条提交腿**刚认领**的 run 在起跑之前就收场 —— 撤掉本请求建的东西的**唯一**写法。四个调用点:device 落点拒
3
+ * (`execution-context.ts` `commitExecutionContext`)、续跑输入写不进(`submit-ctx.ts` `persistSubmitCtx`)、workflow 决定行没落成
4
+ * (`durable-run-leg.ts` 的 fresh 投递腿;此刻认领可能已被收割归了别人 —— 两步都按这一跑自己的 taskId,碰不到别人的认领)与
5
+ * 起跑之前的认领复核答不出(`claim-heartbeat.ts` `recheckClaimBeforeLaunch`,同理按自己的 taskId)。
5
6
  *
6
7
  * 撤两步,**各自独立**(一步失败不拦另一步,残余最小):
7
8
  * · 终结这条 run 行(`setTerminal` 是按 taskId 的 CAS,首写者赢 ⇒ 重复调用是 no-op)—— 随之释放它的 `task_active` 认领;
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import type { IncomingMessage, ServerResponse } from "node:http";
18
18
  import type { ServiceConfig } from "../config-types.js";
19
+ import { type HealthReader } from "./health-reader.js";
19
20
  import type { RouteCtxBase, RunRegistry } from "./route-ctx.js";
20
21
  import type { FlatServiceDeps } from "./server.js";
21
22
  /** `/health` 的 `mods` 段(运维声明的 mod 包装上了几只;present-iff 装上了)—— 段的键集属主,自铸 wire 值登记表 `healthModsKey` 绑它。 */
@@ -28,7 +29,7 @@ export interface HealthDeploymentModsSection {
28
29
  *
29
30
  * 病:这几族(trace-usage / workflows / fleet)排在全局门之前,理由只有一条 —— 只读 `TRACE_TOKEN` 单凭据的调用方
30
31
  * (registry 用量 / 轨迹中继)在全局门会被 401。可排在门前之后,每一族只剩**块内**自己那道门:fleet / workflows
31
- * 只在 `REQUIRE_PRINCIPAL` 时要身份,trace 认 `gatedPrincipal`(BFF 形上就是调用方自己写的 principal 头)。于是
32
+ * 只在 `REQUIRE_PRINCIPAL` 时要身份,trace 认 `gatedSubject`(BFF 形上就是调用方自己写的 principal 头)。于是
32
33
  * 配了 service token、没开 REQUIRE_PRINCIPAL 的部署上,`POST /v1/tasks` 吃凭据,这三族读路对端口全开。
33
34
  *
34
35
  * 规则(一条,三族同读;fail-closed):
@@ -40,6 +41,12 @@ export interface HealthDeploymentModsSection {
40
41
  * 「这个请求带没带这台部署认的凭据」,不回答「它能看谁的行」。
41
42
  */
42
43
  export declare function readCredentialOk(req: IncomingMessage, config: ServiceConfig): boolean;
44
+ /**
45
+ * `GET /health` 这次请求的**读者档**(`health-reader.ts` 头注:三档与每档拿什么)—— 读的是上面那一只读路谓词,不另立第二份「凭据」读法:
46
+ * 没配服务凭据 ⇒ `open`(谓词的第一臂);配了而谓词认 ⇒ `credentialed`;配了而谓词不认 ⇒ `anonymous`。
47
+ * 调用点必须在鉴权桥预认证**之后**(已验登录令牌是谓词的一臂,读的是预认证挂上的身份)。
48
+ */
49
+ export declare function healthReaderOf(req: IncomingMessage, config: ServiceConfig): HealthReader;
43
50
  export declare function createDispatch(ctx: {
44
51
  deps: FlatServiceDeps;
45
52
  noteActivity: (url: string) => void;
@@ -1,16 +1,22 @@
1
1
  import { createHash } from "node:crypto";
2
- import { setSsoPrincipal, setSsoScope, setSsoRole, setSsoPrincipalInc, isDestructiveSessionWrite, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../security.js";
2
+ import { setSsoPrincipal, setSsoScope, setSsoRole, setSsoPrincipalInc, isDestructiveSessionWrite, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER, HttpError, SCENARIO_HEADER, scenarioHeaderOf, scenarioHeaderUnknownError, verifiedPerson } from "../security.js";
3
+ import { partsOf } from "../owner-brands.js";
4
+ import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
3
5
  import { publicStoreProbeError } from "../store-live-probe.js";
4
6
  import { looksLikeJwt } from "@sema-agent/settings-schema/api/auth-bridge";
5
7
  import { admitBridgeIdentity } from "../auth-bridge.js";
6
8
  import { ROUTE_METHOD_ORDER } from "./route-ctx.js";
7
9
  import { READ_CREDENTIAL_ROUTES, PUBLIC_ROUTES, POST_CREDENTIAL_ROUTES, routeLabel, isBillableSubmitPath, billableKindOf, isCredentialGatedRewrite, isMethodDispatchedSubmitPath, lookupRoute, isProbePath, isSubscriptionRequest } from "./route-table.js";
8
- import { sendJson, sendError, isSseResponse, endSseWithError } from "./send.js";
10
+ import { sendJson, sendError, sendHttpError, isSseResponse, endSseWithError } from "./send.js";
9
11
  import { admissionRefusalOf, readinessOf, healthReadinessKeys, sendReadyz, sendBillableRefusal, billableRefusalOf, billableRefusalFrame } from "./readiness.js";
10
12
  import { ENGINE_SIGNAL_KEY, buildEngineSignal, fleetMembershipKeys, healthConfigLedgerKeys, healthDrainingKeys, mintEngineSignal, restartActionable } from "../fleet/engine-signal.js";
11
13
  import { buildHealthSelfReport } from "./health-self-report.js";
12
- import { deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
13
- import { actsForDeployment, admitRunIdentity, authorized, systemFor, gatedPrincipal, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource, hasServiceAuth, devOpenDeployment } from "./principal-gate.js";
14
+ import { projectHealthBody } from "./health-reader.js";
15
+ import { projectHealthStoreSection, unwiredStorePosture } from "../store-posture.js";
16
+ import { autoBackgroundOnTimeout as autoBackgroundOnTimeoutFact, autoBackgroundOnTimeoutWord, deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
17
+ import { hostBackgroundShellEnabled } from "../config.js";
18
+ import { actsForDeployment, admitRunIdentity, authorized, bearerPresentedButUnverified, systemFor, gatedSubject, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource, devOpenDeployment } from "./principal-gate.js";
19
+ import { hasServiceAuth } from "../identity-source.js";
14
20
  import { inflightTotal } from "../fleet/drain-entry.js";
15
21
  const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
16
22
  export function readCredentialOk(req, config) {
@@ -20,6 +26,11 @@ export function readCredentialOk(req, config) {
20
26
  return true;
21
27
  return traceTokenPresented(req, config);
22
28
  }
29
+ export function healthReaderOf(req, config) {
30
+ if (!hasServiceAuth(config))
31
+ return "open";
32
+ return readCredentialOk(req, config) ? "credentialed" : "anonymous";
33
+ }
23
34
  function cors(res, req, origins, principalHeader) {
24
35
  if (!origins || origins.length === 0)
25
36
  return;
@@ -36,7 +47,7 @@ function cors(res, req, origins, principalHeader) {
36
47
  return;
37
48
  res.setHeader("access-control-allow-origin", allow);
38
49
  res.setHeader("access-control-allow-methods", [...ROUTE_METHOD_ORDER, "OPTIONS"].join(", "));
39
- res.setHeader("access-control-allow-headers", `content-type, authorization, last-event-id, ${principalHeader}, idempotency-key, x-detach-on-disconnect, ${PRINCIPAL_TOKEN_HEADER}, ${APPROVAL_MAC_HEADER}, ${APPROVAL_MAC_KID_HEADER}, if-none-match`);
50
+ res.setHeader("access-control-allow-headers", `content-type, authorization, last-event-id, ${principalHeader}, ${SCENARIO_HEADER}, idempotency-key, x-detach-on-disconnect, ${PRINCIPAL_TOKEN_HEADER}, ${APPROVAL_MAC_HEADER}, ${APPROVAL_MAC_KID_HEADER}, if-none-match`);
40
51
  res.setHeader("access-control-expose-headers", "x-task-id, retry-after");
41
52
  }
42
53
  export function createDispatch(ctx) {
@@ -60,7 +71,29 @@ export function createDispatch(ctx) {
60
71
  endSseWithError(r, frame);
61
72
  };
62
73
  }
63
- async function dispatchSegment(rows, req, res, url, search, method, allow, ctx, admit) {
74
+ function scenarioHeaderAnswered(req, res) {
75
+ if (scenarioHeaderOf(req) === undefined)
76
+ return false;
77
+ try {
78
+ if (DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(deps.config) && (bearerPresentedButUnverified(req, deps.config) || verifiedPerson(req, deps.config) === undefined)) {
79
+ sendPrincipalRefusal(res, req, deps.config);
80
+ return true;
81
+ }
82
+ const subject = gatedSubject(req, deps.config);
83
+ const scenario = subject === undefined ? undefined : partsOf(subject).scenario;
84
+ const known = deps.scenarioGate.known();
85
+ if (scenario === undefined || !known.includes(scenario))
86
+ throw scenarioHeaderUnknownError(String(scenario), known);
87
+ return false;
88
+ }
89
+ catch (e) {
90
+ if (!(e instanceof HttpError))
91
+ throw e;
92
+ sendHttpError(res, e);
93
+ return true;
94
+ }
95
+ }
96
+ async function dispatchSegment(rows, req, res, url, search, method, allow, ctx, admit, judgesIdentity = true) {
64
97
  for (const row of rows) {
65
98
  if (row.enabled !== undefined && !row.enabled(deps))
66
99
  continue;
@@ -74,11 +107,32 @@ export function createDispatch(ctx) {
74
107
  sendUnauthorized(res, "credential");
75
108
  return true;
76
109
  }
110
+ if (judgesIdentity && scenarioHeaderAnswered(req, res))
111
+ return true;
77
112
  await row.handler(req, res, { decl: found.decl, params: found.params, search }, ctx);
78
113
  return true;
79
114
  }
80
115
  return false;
81
116
  }
117
+ async function attachBridgeIdentity(req) {
118
+ if (deps.webAdminJwtVerifier) {
119
+ const authz = req.headers.authorization ?? "";
120
+ const rawBearer = /^Bearer\s/i.test(authz) ? authz.replace(/^Bearer\s+/i, "") : "";
121
+ if (rawBearer && looksLikeJwt(rawBearer)) {
122
+ const identity = admitBridgeIdentity(await deps.webAdminJwtVerifier.verify(rawBearer), { logger: deps.logger, metrics: deps.metrics });
123
+ if (identity) {
124
+ setSsoPrincipal(req, identity.principal);
125
+ req.headers[deps.config.principalHeader.toLowerCase()] = identity.principal;
126
+ setSsoScope(req, identity.scope);
127
+ if (identity.role)
128
+ setSsoRole(req, identity.role);
129
+ if (identity.principalInc !== undefined)
130
+ setSsoPrincipalInc(req, identity.principalInc);
131
+ deps.logger?.info?.("auth_bridge_principal_accepted", { principal: identity.principal, scope: identity.scope });
132
+ }
133
+ }
134
+ }
135
+ }
82
136
  async function handle(req, res) {
83
137
  const startedAt = Date.now();
84
138
  const method = req.method ?? "GET";
@@ -127,6 +181,8 @@ export function createDispatch(ctx) {
127
181
  return;
128
182
  }
129
183
  if (req.method === "GET" && url === "/health") {
184
+ await attachBridgeIdentity(req);
185
+ const reader = healthReaderOf(req, deps.config);
130
186
  const signal = mintEngineSignal(deps);
131
187
  const engineSignal = buildEngineSignal(signal);
132
188
  const declaredMods = deploymentModPackagesFact(deps);
@@ -134,7 +190,7 @@ export function createDispatch(ctx) {
134
190
  .update(JSON.stringify({ model: deps.config.model.id, sessionBackend: deps.config.sessionBackend, dbBackend: deps.config.dbBackend, dataRoot: deps.config.localDataRoot, configProvider: deps.config.configProvider, remoteExec: deps.config.remoteExec.provider, port: deps.config.port }))
135
191
  .digest("hex")
136
192
  .slice(0, 16);
137
- sendJson(res, 200, {
193
+ const fullBody = {
138
194
  status: "ok",
139
195
  ...(typeof deps.capabilities?.version === "string" ? { version: deps.capabilities.version } : {}),
140
196
  ...healthDrainingKeys(signal),
@@ -158,7 +214,10 @@ export function createDispatch(ctx) {
158
214
  },
159
215
  };
160
216
  })(),
161
- ...(deps.storePosture?.degradedReason !== undefined ? { durable: false, storeDegraded: true } : {}),
217
+ ...(deps.sandboxCapacity !== undefined ? { sandboxCapacity: deps.sandboxCapacity.health() } : {}),
218
+ ...(deps.storePosture?.degradedReason !== undefined ? { storeDegraded: true } : {}),
219
+ store: projectHealthStoreSection(deps.storePosture ?? unwiredStorePosture(deps.config.dbBackend)),
220
+ autoBackgroundOnTimeout: autoBackgroundOnTimeoutWord(autoBackgroundOnTimeoutFact(deps.config, hostBackgroundShellEnabled())),
162
221
  ...healthReadinessKeys(signal.verdict),
163
222
  model: deps.config.model.id,
164
223
  sessionBackend: deps.sessionStoreLabel ?? deps.config.sessionBackend,
@@ -201,7 +260,8 @@ export function createDispatch(ctx) {
201
260
  };
202
261
  })(),
203
262
  [ENGINE_SIGNAL_KEY]: engineSignal,
204
- });
263
+ };
264
+ sendJson(res, 200, projectHealthBody(reader, fullBody));
205
265
  return;
206
266
  }
207
267
  if (req.method === "GET" && url === "/readyz") {
@@ -214,8 +274,8 @@ export function createDispatch(ctx) {
214
274
  return;
215
275
  }
216
276
  const mt = deps.config.metricsToken;
217
- const devOpen = devOpenDeployment(deps) && !mt;
218
- const ok = devOpen || (!!mt && authorized(req, mt)) || actsForDeployment(req, deps.config, () => gatedPrincipal(req, deps.config));
277
+ const devOpen = devOpenDeployment(deps.config) && !mt;
278
+ const ok = devOpen || (!!mt && authorized(req, mt)) || actsForDeployment(req, deps.config, () => gatedSubject(req, deps.config));
219
279
  if (!ok) {
220
280
  sendUnauthorized(res, "operator");
221
281
  return;
@@ -232,26 +292,10 @@ export function createDispatch(ctx) {
232
292
  res.end(deps.metrics.render());
233
293
  return;
234
294
  }
235
- if (deps.webAdminJwtVerifier) {
236
- const authz = req.headers.authorization ?? "";
237
- const rawBearer = /^Bearer\s/i.test(authz) ? authz.replace(/^Bearer\s+/i, "") : "";
238
- if (rawBearer && looksLikeJwt(rawBearer)) {
239
- const identity = admitBridgeIdentity(await deps.webAdminJwtVerifier.verify(rawBearer), { logger: deps.logger, metrics: deps.metrics });
240
- if (identity) {
241
- setSsoPrincipal(req, identity.principal);
242
- req.headers[deps.config.principalHeader.toLowerCase()] = identity.principal;
243
- setSsoScope(req, identity.scope);
244
- if (identity.role)
245
- setSsoRole(req, identity.role);
246
- if (identity.principalInc !== undefined)
247
- setSsoPrincipalInc(req, identity.principalInc);
248
- deps.logger?.info?.("auth_bridge_principal_accepted", { principal: identity.principal, scope: identity.scope });
249
- }
250
- }
251
- }
295
+ await attachBridgeIdentity(req);
252
296
  if (await dispatchSegment(READ_CREDENTIAL_ROUTES, req, res, url, search, method, allow.pre, ctx, (r) => readCredentialOk(r, deps.config)))
253
297
  return;
254
- if (await dispatchSegment(PUBLIC_ROUTES, req, res, url, search, method, allow.pre, ctx))
298
+ if (await dispatchSegment(PUBLIC_ROUTES, req, res, url, search, method, allow.pre, ctx, undefined, false))
255
299
  return;
256
300
  const identitySource = verifiedIdentitySource(req, deps.config);
257
301
  admitRunIdentity(req, identitySource, deps.logger);
@@ -298,7 +342,9 @@ export function createDispatch(ctx) {
298
342
  if (await dispatchSegment(POST_CREDENTIAL_ROUTES, req, res, url, search, method, allow.post, ctx))
299
343
  return;
300
344
  if (allow.pre.length > 0 || allow.post.length > 0) {
301
- if (allow.post.length > 0 && deps.config.requirePrincipal && gatedPrincipal(req, deps.config) === undefined) {
345
+ if (allow.post.length > 0 && scenarioHeaderAnswered(req, res))
346
+ return;
347
+ if (allow.post.length > 0 && deps.config.requirePrincipal && gatedSubject(req, deps.config) === undefined) {
302
348
  sendPrincipalRefusal(res, req, deps.config);
303
349
  return;
304
350
  }
@@ -13,17 +13,17 @@ export interface DurableRunLegArgs {
13
13
  idem?: RunIdemBinding;
14
14
  /** 🔒 这条 run 的 **fleet 行 scope** —— 必须与 `GET /v1/fleet/stream` 过滤用的是同一个身份,且绝不是
15
15
  * 自报的 `x-agent-principal` 头(自报头会把行打到受害者的 scope 上,或打到 `default` 而真属主的流把它
16
- * 过滤掉)。提交门传 `gatedPrincipal(req) ?? "default"`;`/decide` 的第三条车道传 resume 家族的
16
+ * 过滤掉)。提交门传 `gatedSubject(req) ?? "default"`;`/decide` 的第三条车道传 resume 家族的
17
17
  * `resumeFleetScope(req, auth)`(同一条 wire 上两条腿因此同答)。 */
18
18
  fleetScope: string;
19
19
  /** 🔒 这条 run 的 **elicit / question 应答方**(E23:与 respond 门读的是同一个已验身份,不是自报头)。
20
- * 提交门传 `gatedPrincipal(req) ?? null` = 提交者本人;`/decide` 的第三条车道传**卡属主**(= 原提交者,
20
+ * 提交门传 `gatedSubject(req) ?? null` = 提交者本人;`/decide` 的第三条车道传**卡属主**(= 原提交者,
21
21
  * 不是代为按下按钮的 operator —— 与 resume 腿那条成文口径逐字同源)。`null` = 匿名/开放部署。 */
22
22
  elicitOwner: string | null;
23
23
  /** run 行元数据的 `source` 列(调用方的系统身份;内部车道传自己的车道名)。只作归因。 */
24
24
  source: string | null;
25
25
  /** run 行身份元组(`RunRecord.identity`)—— 调用方经 `runIdentityOf(req, config, 属主)` 读凭据门铸下的那一份交进来(本腿不碰请求);
26
- * 属主 = `prepared.auth.principal`(本腿建行写进 `owner` 的同一个值)。`/decide` 第三条车道同一只读法:按下按钮的不是卡属主 ⇒ 空。 */
26
+ * 属主 = `prepared.auth.subject`(本腿建行写进 `owner` 的同一个值)。`/decide` 第三条车道同一只读法:按下按钮的不是卡属主 ⇒ 空。 */
27
27
  identity: RunIdentity | null;
28
28
  /** `/decide` 第三条车道的 fresh 投递腿交来的那一件决定投递(带着的决定 + 起跑之前落行的那一笔;语义与 TRUSTED 纪律的属主 =
29
29
  * `route-ctx.ts` 的 {@link WorkflowDecisionDelivery} 顶注)。缺席 ⇒ 只摊本会话已受理的决定行。 */