@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
package/dist/runs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { runWithVerification, runCascade, defaultTaskRegistry, taskNotificationDedupKey, DURABLE_AGENT_HANDLE_RE } from "@sema-agent/core";
2
- import { atHostBoundary, failureCodeOf, sealResultForExit, outwardPlane } from "./terminal.js";
2
+ import { atHostBoundary, failureCodeOf, sealResultForExit, outwardPlane, outwardThrownMessage } from "./terminal.js";
3
3
  import { voidVerifierPauseCard } from "./verifier-pause-card.js";
4
4
  import { voidPendingCard } from "./card-void.js";
5
5
  import { NOT_IN_ROSTER, entryProblemsFacts } from "./entry-problems.js";
@@ -7,7 +7,10 @@ import { GOVERNANCE_HTTP_STATUS } from "./governance-http-status.js";
7
7
  import { TOOL_DECLARATION_HTTP_STATUS } from "./tool-declaration-http-status.js";
8
8
  import { isSessionErrorCode, sessionErrorHttp } from "./session-error-wire.js";
9
9
  import { redactErrorMessage } from "./observability/run-terminal.js";
10
- import { withPrincipal } from "./observability/principal-context.js";
10
+ import { withSubject } from "./observability/principal-context.js";
11
+ import { partsOf } from "./owner-brands.js";
12
+ import { recoveredSubject } from "./owner-faces.js";
13
+ import { taskSpecIdentityOf } from "./engine-identity.js";
11
14
  import { withModelReachScope } from "./model-reach-scope.js";
12
15
  import { createInstructionSelectionLeg } from "./instruction-selection.js";
13
16
  import { redactSecrets } from "./trace/redact.js";
@@ -16,7 +19,8 @@ import { createLedgerSink } from "./trace/ledger-sink.js";
16
19
  import { registerEngineNoticeLeg } from "./trace/engine-notice-wire.js";
17
20
  import { recordTurnActivity } from "./turn-activity.js";
18
21
  import { buildCancelledLedgerRow, CANCELLED_CODE, createRunAbort, mintCancelledResult } from "./run-cancel-context.js";
19
- import { createApprovalCardEmitter, resolveApprovalLeg } from "./tool-approval.js";
22
+ import { resolveApprovalLeg } from "./tool-approval.js";
23
+ import { createHitlTransport } from "./hitl-delivery.js";
20
24
  import { fleetRunResiduals } from "./fleet/fleet-bus.js";
21
25
  import { defaultSubagentTailBus } from "./fleet/subagent-tail-bus.js";
22
26
  import { emitPendingWorkflowCompletions, taskNotificationInboxEntry, taskNotificationStreamKeyOf, NotifiedKeys } from "./orchestration/workflow-completion-inbox.js";
@@ -55,7 +59,9 @@ export async function taskHandleStop(registry, handle, access, agentStore) {
55
59
  registry.markStopSource(handle, "user");
56
60
  return registry.stopTask(handle, access);
57
61
  }
58
- export function markChildrenStoppedByUserOnAbort(signal, taskId, principal) {
62
+ export function markChildrenStoppedByUserOnAbort(signal, taskId, subject) {
63
+ const recovered = recoveredSubject(subject);
64
+ const principal = taskSpecIdentityOf(recovered === undefined ? undefined : partsOf(recovered)).principal;
59
65
  const mark = () => {
60
66
  try {
61
67
  defaultTaskRegistry.markStopSourceForOwner({ owner: taskId, scope: principal ?? "default" }, "user", { skipSessionScoped: true });
@@ -85,6 +91,7 @@ const PREPARE_REFUSAL_HTTP_STATUS = {
85
91
  "config.invalid_checkpoint_store": 400,
86
92
  "config.skill_listing_budget_invalid": 400,
87
93
  "config.user_invoked_skill_unknown": 400,
94
+ "config.skill_deny_unreadable": 409,
88
95
  "config.image_invalid": 400,
89
96
  "config.user_attachment_invalid": 400,
90
97
  "config.tool_face_control": 400,
@@ -127,6 +134,15 @@ export function syncRefusalHttpStatus(result) {
127
134
  return resumeAtHttpStatus(result);
128
135
  }
129
136
  const ZERO_WORK_REFUSAL_DETAIL_CODES = new Set(["config.user_attachment_invalid"]);
137
+ function attachmentCauseFacts(cause) {
138
+ if (cause === null || typeof cause !== "object")
139
+ return {};
140
+ const c = cause;
141
+ return {
142
+ ...(typeof c.path === "string" && c.path !== "" ? { field: c.path } : {}),
143
+ ...(typeof c.index === "number" && Number.isInteger(c.index) && c.index >= 0 ? { index: c.index } : {}),
144
+ };
145
+ }
130
146
  const ENGINE_ENTRY_SPELLING_REASONS = new Set(["near_miss", "unknown_name"]);
131
147
  function engineReasonOf(detail) {
132
148
  if (detail === null || typeof detail !== "object")
@@ -155,7 +171,7 @@ export function zeroWorkRefusalFacts(terminal, admissionReadings = []) {
155
171
  if (cause === null || typeof cause !== "object")
156
172
  return {};
157
173
  const c = cause;
158
- return c.kind === "coded" && c.detail !== undefined ? { detail: c.detail } : {};
174
+ return c.kind === "coded" ? attachmentCauseFacts(c.detail) : {};
159
175
  }
160
176
  const RETRY_CLASS_WORDS = { transient: true, terminal: true };
161
177
  function engineRetryClassOf(terminal) {
@@ -339,7 +355,7 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
339
355
  });
340
356
  }
341
357
  const heartbeat = setInterval(() => {
342
- void runStore.heartbeat(taskId, owner).catch(() => { metrics?.inc("run_signal_poll_errors_total", { kind: "heartbeat" }); });
358
+ beatRunHeartbeat(runStore, taskId, owner, () => cancelCtrl.abort("stall_verdict"), () => { metrics?.inc("run_signal_poll_errors_total", { kind: "heartbeat" }); });
343
359
  if (!cancelCtrl.signal.aborted) {
344
360
  void runStore.isCancelRequested(taskId, owner).then((c) => { if (c)
345
361
  cancelCtrl.abort("cancel_verb"); }).catch(() => { metrics?.inc("run_signal_poll_errors_total", { kind: "cancel" }); });
@@ -372,7 +388,7 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
372
388
  acceptance?.settle(sealed);
373
389
  };
374
390
  const settleLegResult = async (engineResult) => {
375
- const result = atHostBoundary(engineResult, spec.sessionId);
391
+ const result = atHostBoundary(engineResult);
376
392
  const parkWord = result.terminal.kind === "paused" ? outwardPlane(result.terminal).status : undefined;
377
393
  if (parkWord !== undefined && isParkLedgerEventType(parkWord)) {
378
394
  await parkLeg(parkWord, result);
@@ -397,18 +413,7 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
397
413
  modelUsage?.register(taskId);
398
414
  const manifestSeat = createPromptManifestSeat(promptManifests, taskId);
399
415
  const flushPromptManifest = () => manifestSeat.drain(append);
400
- const elicitEmit = (frame) => {
401
- const { type, ...rest } = frame;
402
- return append(type, rest);
403
- };
404
- const questionEmit = (frame) => {
405
- const { type, ...rest } = frame;
406
- return append(type, rest);
407
- };
408
- const approvalEmit = (frame) => {
409
- const { type, ...rest } = frame;
410
- return append(type, rest);
411
- };
416
+ const hitlTransport = createHitlTransport({ ledger: append });
412
417
  const unregisterEngineNotice = registerEngineNoticeLeg({
413
418
  sessionId: spec.sessionId,
414
419
  ...(pendingEngineNotices !== undefined ? { pending: pendingEngineNotices } : {}),
@@ -532,12 +537,12 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
532
537
  await append("suggestions", { suggestions: suggestions.map((s) => redactSecrets(s)) });
533
538
  }
534
539
  };
535
- await instructionLeg.run(spec.sessionId, () => withModelReachScope({ sessionId: spec.sessionId, taskId }, () => withPrincipal(principal, () => {
540
+ await instructionLeg.run(spec.sessionId, () => withModelReachScope({ sessionId: spec.sessionId, taskId }, () => withSubject(recoveredSubject(principal), () => {
536
541
  const withElicit = elicitation
537
- ? () => elicitation.runWithContext({ taskId, owner: elicitOwner ?? owner, emit: elicitEmit, abortSignal: cancelCtrl.signal }, runBody)
542
+ ? () => elicitation.runWithContext({ taskId, owner: elicitOwner ?? owner, transport: hitlTransport, abortSignal: cancelCtrl.signal }, runBody)
538
543
  : runBody;
539
544
  const withQuestion = () => question
540
- ? question.runWithContext({ taskId, owner: elicitOwner ?? owner, emit: questionEmit, abortSignal: cancelCtrl.signal }, withElicit)
545
+ ? question.runWithContext({ taskId, owner: elicitOwner ?? owner, transport: hitlTransport, abortSignal: cancelCtrl.signal }, withElicit)
541
546
  : withElicit();
542
547
  const withApproval = () => approval && approvalLeg.active && approvalLeg.unattended === undefined
543
548
  ? approval.coordinator.runWithContext({
@@ -546,8 +551,8 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
546
551
  abortSignal: cancelCtrl.signal,
547
552
  ...(spec.sessionId ? { sessionId: spec.sessionId } : {}),
548
553
  executionLane: approval.executionLane,
549
- emitCard: createApprovalCardEmitter({ appendDurable: (f) => approvalEmit(f) }),
550
- emitRevoke: (f) => approvalEmit(f),
554
+ family: "approval_request",
555
+ transport: hitlTransport,
551
556
  legKey: "",
552
557
  ...(legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic } : {}),
553
558
  }, withQuestion)
@@ -610,8 +615,9 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
610
615
  }
611
616
  else {
612
617
  settledAsCancel = false;
613
- const safeMsg = redactErrorMessage(message) ?? message;
614
- await voidHeldParkCard(observedDone === undefined ? undefined : atHostBoundary(observedDone, spec.sessionId), spec.sessionId, checkpointCards, "bg");
618
+ const outwardMsg = outwardThrownMessage(err, message);
619
+ const safeMsg = redactErrorMessage(outwardMsg) ?? outwardMsg;
620
+ await voidHeldParkCard(observedDone === undefined ? undefined : atHostBoundary(observedDone), spec.sessionId, checkpointCards, "bg");
615
621
  try {
616
622
  await append("failed", { errorMessage: safeMsg });
617
623
  }
@@ -644,7 +650,7 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
644
650
  if (verdict.kind === "park")
645
651
  fleetPublisher.onTerminal(verdict.word);
646
652
  else if (verdict.result !== null)
647
- fleetPublisher.onTerminal(verdict.label, fleetRunResiduals(verdict.result));
653
+ fleetPublisher.onTerminal(verdict.label, fleetRunResiduals(verdict.result, failureCodeOf(verdict.result.terminal)));
648
654
  else
649
655
  fleetPublisher.onTerminal(verdict.label, {
650
656
  ...(verdict.label === CANCELLED_CODE ? { stoppedBy: "user" } : {}),
@@ -667,5 +673,11 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
667
673
  }
668
674
  }
669
675
  }
676
+ export function beatRunHeartbeat(runStore, taskId, owner, onLost, onError) {
677
+ void runStore.heartbeat(taskId, owner).then((running) => {
678
+ if (!running)
679
+ onLost();
680
+ }, onError);
681
+ }
670
682
  export const HEARTBEAT_MS = LIVENESS_HEARTBEAT_MS;
671
683
  //# sourceMappingURL=runs.js.map
@@ -23,8 +23,8 @@
23
23
  * · `forceDurableGate`— prepare-task.js 的 durable/content mandate、活 content-ask 抑制、
24
24
  * durable question face(该处合取 `resolveCheckpointStore(spec, deps) !== undefined`
25
25
  * ⇒ **无 checkpoint 店的部署上这一面本就不成立**,该键在那里 inert)
26
- * · `autoMode` — prepare-task.js `=== true` **∧** `deps.autoMode !== undefined`(部署需先具备分类器;
27
- * 显式 opt-in 极性,且 [ref] 起本侧传的是三态 org deny 位,见 toCoreRuntimeCaps 头注)
26
+ * · `autoMode` — 武装式 `spec.permissionMode === "auto"` **∧** `deps.autoMode !== undefined` **∧** `runtimeCaps?.autoMode !== false`
27
+ * (部署需先具备分类器;三态 org deny 位:`true` 与缺席同义、只有 `false` 是拒,见 toCoreRuntimeCaps 头注)
28
28
  * · `bypassPermissions` — `dist/core/mode-policy.js` 的模式折叠(请求 `bypassPermissions` ∧ 本位 `=== false` ⇒ 这条腿跑在
29
29
  * `default`、发 `config.permission_mode_unavailable{by:"operator_deny"}`、回执 `foldedBy:"operator_deny"`);
30
30
  * deny 形,缺席 = 不阻。[ref] D2 起由 center 的 `allowBypassPermissions` 写(此前本仓零写点)
@@ -107,6 +107,15 @@ export interface EntitlementsResolverOpts {
107
107
  /** Observability hook for a resolve failure (defaults to a `runtime_caps_resolve_failed` warn). */
108
108
  onError?: (err: Error, principal: string) => void;
109
109
  }
110
+ /**
111
+ * 中心拒了 auto 时**是哪一键拒的**(闭集)。中心的 entitlement 里 auto 的拒位今天有两个键(`autoMode` 与 `allowAutoMode`,settings-schema 里一个事实两个源 ——
112
+ * 折成一键归那个仓),引擎只有一只拒位;读者(`GET /v1/capabilities` 的 `permissionModeAuto.refusedBy`)靠这一词分清该去改中心的哪一键。
113
+ * 中心折成一键之后两词退役、本词集随之删(零别名)。
114
+ */
115
+ export declare const AUTO_MODE_REFUSED_BY: readonly ["center.autoMode", "center.allowAutoMode", "both"];
116
+ export type AutoModeRefusedBy = (typeof AUTO_MODE_REFUSED_BY)[number];
117
+ /** 中心这一答拒没拒 auto、哪一键拒的 —— 拒位与来源词的**同一只判**({@link toCoreRuntimeCaps} 的拒位读它)。缺席 = 中心没拒(任一键的 `true` 都不是授予,不覆盖另一键的 `false`)。 */
118
+ export declare function autoModeRefusedByOf(ent: Pick<EntitlementRuntimeCaps, "autoMode" | "allowAutoMode">): AutoModeRefusedBy | undefined;
110
119
  /** Map center's `EntitlementRuntimeCaps` → the subset core's engine enforces. `allowUltracode` (shell/UX) is
111
120
  * dropped on purpose (not a core primitive); `allowWorkflows` / `forceDurableGate` / `allowFork` are **three of the
112
121
  * six** the engine reads — the other three (`allowObservers` / `autoMode` / `allowMemoryOptOut`) are documented
@@ -151,6 +160,12 @@ export declare function toCoreRuntimeCaps(ent: EntitlementRuntimeCaps | null | u
151
160
  * 所以本谓词为 false **不再**意味着 auto 不武装;「会不会武装」由 `auto-mode-face.ts` 的三项合取答。
152
161
  */
153
162
  export declare function centerEntitlementSourceWired(config: Pick<ServiceConfig, "webAdmin">): boolean;
163
+ /** 只读腿的一次读数:拒位(caps)与中心拒 auto 的来源词出自**同一个**缓存项。 */
164
+ export interface RuntimeCapsReading {
165
+ readonly caps: RuntimeCaps | undefined;
166
+ /** 只在中心亲口拒了 auto 时在场({@link AutoModeRefusedBy})。 */
167
+ readonly autoModeRefusedBy?: AutoModeRefusedBy;
168
+ }
154
169
  /** The two per-principal faces served off ONE caps fetch + cache. */
155
170
  export interface PrincipalEntitlementsClient {
156
171
  /** core's `RunnerDeps.runtimeCapsResolver` seam — FAIL-CLOSED on error (deny workflows/fork/autoMode/bypassPermissions;
@@ -171,7 +186,7 @@ export interface PrincipalEntitlementsClient {
171
186
  *
172
187
  * 🔴 **界画在「这句话是谁说的」**(codex r2 [high] 逐条核后的定界,不是「读面完全不碰缓存」):
173
188
  * · **成功项 = center 亲口答的那份** —— 与提交腿自己抓到的**逐字同一份**、同一条 `ttlMs`、同一个**已验证**
174
- * 身份(读面的 principal 走 `gatedPrincipal` → `verifiedPrincipal`,与提交腿同源,读不到别人的格)。读面
189
+ * 身份(读面的 principal 走 `gatedSubject` → `verifiedPrincipal`,与提交腿同源,读不到别人的格)。读面
175
190
  * 只是把这个 principal 自己那一格**预热**了一下;org 撤销后的陈旧窗由部署级 `ttlMs` 定义,与哪一腿预热
176
191
  * 的无关(提交腿自己预热同样如此),本批**零改动**。
177
192
  * · **降级项 = server 自铸的判决** —— center 从没说过这句 deny,是本层在故障时替它说的。让一次**读**铸的
@@ -185,17 +200,17 @@ export interface PrincipalEntitlementsClient {
185
200
  * 而它硬失败 ⇒ 该降级项当场升格为执法项(codex r1 [medium]:否则一条总抢在提交前面的轮询会让每次提交
186
201
  * 都重抓,denyTtl 的界对提交腿失效)。让它升格的是一次真提交自己吃到的硬失败,不是那次读。
187
202
  */
188
- peekRuntimeCaps: (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
203
+ peekRuntimeCapsReading: (principal: string | undefined) => Promise<RuntimeCapsReading>;
189
204
  /** The resolved per-principal scenario ruling for resolveSpec's gateScenarioRequest — a three-state read
190
205
  * ({@link ScenarioRulingRead}): the ruling; `undefined` = absent (no principal ⇒ no center call; older center without
191
206
  * the scenario keys) = no governance; `"unavailable"` = the center could not answer (hard fetch failure — same error entry
192
207
  * as the caps face's fail-closed deny — or malformed ruling keys) ⇒ the gate refuses the run. */
193
208
  scenarioRuling: (principal: string | undefined) => Promise<ScenarioRulingRead>;
194
209
  /**
195
- * {@link PrincipalEntitlementsClient.scenarioRuling} 的**只读**孪生(同 {@link PrincipalEntitlementsClient.peekRuntimeCaps} 的界):同一只缓存 / 同一条抓取 /
210
+ * {@link PrincipalEntitlementsClient.scenarioRuling} 的**只读**孪生(同 {@link PrincipalEntitlementsClient.peekRuntimeCapsReading} 的界):同一只缓存 / 同一条抓取 /
196
211
  * 同一份三态读数(故障 ⇒ `"unavailable"`,读面与提交腿同拒),唯一的差别是 center 硬失败时本腿铸的降级项**只对读面自己算数**,提交腿不认、照常重抓。
197
212
  * 读面(`GET /v1/capabilities/mcp?scenario=` 的场景门)问中心裁定时必须走这一只 —— 经 `scenarioRuling` 问,center 抖动的那一拍会替这个主体的**真提交**
198
- * 留下 `{allowWorkflows:false, allowFork:false, autoMode:false}` 的短窗 deny(读面成了别人被拒的原因,与 `peekRuntimeCaps` 的病灶同一类)。
213
+ * 留下 `{allowWorkflows:false, allowFork:false, autoMode:false}` 的短窗 deny(读面成了别人被拒的原因,与 `peekRuntimeCapsReading` 的病灶同一类)。
199
214
  */
200
215
  peekScenarioRuling: (principal: string | undefined) => Promise<ScenarioRulingRead>;
201
216
  /** (stage7 P5) The resolved per-principal execution-lane ruling for resolveSpec's
@@ -37,6 +37,12 @@ const CENTER_ENGINE_CAP_KEYS = [
37
37
  "allowBypassPermissions",
38
38
  "allowMemoryOptOut",
39
39
  ];
40
+ export const AUTO_MODE_REFUSED_BY = ["center.autoMode", "center.allowAutoMode", "both"];
41
+ export function autoModeRefusedByOf(ent) {
42
+ const byAutoMode = ent.autoMode === false;
43
+ const byAllowAutoMode = ent.allowAutoMode === false;
44
+ return byAutoMode && byAllowAutoMode ? "both" : byAutoMode ? "center.autoMode" : byAllowAutoMode ? "center.allowAutoMode" : undefined;
45
+ }
40
46
  export function toCoreRuntimeCaps(ent) {
41
47
  if (!ent)
42
48
  return undefined;
@@ -53,7 +59,7 @@ export function toCoreRuntimeCaps(ent) {
53
59
  caps.allowFork = ent.allowFork;
54
60
  if (typeof ent.allowObservers === "boolean")
55
61
  caps.allowObservers = ent.allowObservers;
56
- if (ent.autoMode === false || ent.allowAutoMode === false)
62
+ if (autoModeRefusedByOf(ent) !== undefined)
57
63
  caps.autoMode = false;
58
64
  else if (ent.autoMode === true)
59
65
  caps.autoMode = true;
@@ -87,7 +93,6 @@ export function gateExecutionLane(ruling, ownLane, logger = defaultLogger) {
87
93
  export function createPrincipalEntitlementsClient(opts) {
88
94
  const ttlMs = opts.ttlMs ?? 60_000;
89
95
  const denyTtlMs = opts.denyTtlMs ?? Math.min(ttlMs, 10_000);
90
- const fetchImpl = opts.fetchImpl ?? fetch;
91
96
  const fetchCaps = opts.fetchCaps ?? fetchPrincipalCaps;
92
97
  const now = opts.now ?? (() => Date.now());
93
98
  const onError = opts.onError ?? ((err, principal) => defaultLogger.warn("runtime_caps_resolve_failed", { principal, err: String(err) }));
@@ -130,12 +135,13 @@ export function createPrincipalEntitlementsClient(opts) {
130
135
  return dup;
131
136
  const p = (async () => {
132
137
  try {
133
- const r = await fetchCaps(bin.center, principal, cached?.etag, fetchImpl, opts.worker);
138
+ const r = await fetchCaps(bin.center, principal, cached?.etag, opts.fetchImpl, opts.worker);
134
139
  if (r === null) {
135
140
  const entry = {
136
141
  caps: cached?.caps,
137
142
  ...(cached?.scenario ? { scenario: cached.scenario } : {}),
138
143
  ...(cached?.execution ? { execution: cached.execution } : {}),
144
+ ...(cached?.autoModeRefusedBy ? { autoModeRefusedBy: cached.autoModeRefusedBy } : {}),
139
145
  ...(cached?.etag ? { etag: cached.etag } : {}),
140
146
  expiresAt: now() + ttlMs,
141
147
  };
@@ -148,8 +154,10 @@ export function createPrincipalEntitlementsClient(opts) {
148
154
  if (r.scenarioDrift) {
149
155
  audit(new Error(`scenario ruling wire drift: ${r.scenarioDrift}`), principal);
150
156
  }
157
+ const refusedBy = r.runtimeCaps ? autoModeRefusedByOf(r.runtimeCaps) : undefined;
151
158
  const entry = {
152
159
  caps: toCoreRuntimeCaps(r.runtimeCaps),
160
+ ...(refusedBy !== undefined ? { autoModeRefusedBy: refusedBy } : {}),
153
161
  ...(r.scenarioDrift ? { scenario: "unavailable" } : r.scenario ? { scenario: r.scenario } : {}),
154
162
  ...(r.execution ? { execution: r.execution } : {}),
155
163
  ...(r.etag ? { etag: r.etag } : {}),
@@ -182,7 +190,12 @@ export function createPrincipalEntitlementsClient(opts) {
182
190
  }
183
191
  return {
184
192
  resolveRuntimeCaps: async (principal) => (principal ? (await load(principal)).caps : undefined),
185
- peekRuntimeCaps: async (principal) => (principal ? (await load(principal, false)).caps : undefined),
193
+ peekRuntimeCapsReading: async (principal) => {
194
+ if (!principal)
195
+ return { caps: undefined };
196
+ const entry = await load(principal, false);
197
+ return { caps: entry.caps, ...(entry.autoModeRefusedBy !== undefined ? { autoModeRefusedBy: entry.autoModeRefusedBy } : {}) };
198
+ },
186
199
  scenarioRuling: async (principal) => (principal ? (await load(principal)).scenario : undefined),
187
200
  peekScenarioRuling: async (principal) => (principal ? (await load(principal, false)).scenario : undefined),
188
201
  executionRuling: async (principal) => (principal ? (await load(principal)).execution : undefined),
@@ -24,7 +24,7 @@
24
24
  * name). Real isolation is the `executionEnv` sandbox. Same caveat core documents on `createCoarseCommandNamePolicy`.
25
25
  */
26
26
  import { type PermissionMode, type ShellGateDoctrine, type TaskSpec, type ToolPolicy } from "@sema-agent/core";
27
- import { AUTONOMY_MODES, type GovernanceConfig } from "@sema-agent/settings-schema";
27
+ import { AUTONOMY_MODES, GovernanceConfig } from "@sema-agent/settings-schema";
28
28
  import { type GovernanceAskMarks } from "./governance-ask-marks.js";
29
29
  import { type GovernanceOverrides } from "./governance-overrides.js";
30
30
  /** 运维 autonomy 四档的**闭集**(契约成员表本尊,照旧从本模块转出)。`config.ts` 的 `parseAutonomy` 也从这里读 —— 四档词表全仓一份。 */
@@ -38,7 +38,7 @@ export type Autonomy = NonNullable<GovernanceConfig["autonomy"]>;
38
38
  /** 导出给 `test/coarse-shell-tools-mirror.test.ts` 的同源钉用(见那里的顶注)。 */
39
39
  export declare const COARSE_SHELL_TOOLS_MIRROR: readonly string[];
40
40
  /** Validate `commandPolicy` rules — the shape (array of {command, decision}), the `command` (a bare argv[0] name,
41
- * see {@link VALID_COMMAND_NAME}), AND the `decision` enum. Returns the list of human-readable errors (empty =
41
+ * judged by the contract's own cell, see {@link commandNameRefused}), AND the `decision` enum. Returns the list of human-readable errors (empty =
42
42
  * OK). Called at config-apply (web-admin-client/facade.ts `applyRuntimeHot`) so a malformed rule that BYPASSED the
43
43
  * registry schema (a hand-edited config.d / a non-conformant publish) is rejected LOUDLY rather than
44
44
  * silently mis-compiling — review MEDIUM: an out-of-enum `decision` (e.g. "DENY") would otherwise fall through
@@ -1,5 +1,5 @@
1
1
  import { clampPermissionMode, combinePolicies, COARSE_SHELL_TOOLS as CORE_COARSE_SHELL_TOOLS, createCoarseCommandNamePolicy, modePolicyOf, parseLeadingCommandName, wrapToolPolicy, } from "@sema-agent/core";
2
- import { AUTONOMY_MODES, COMMAND_DECISIONS } from "@sema-agent/settings-schema";
2
+ import { AUTONOMY_MODES, COMMAND_DECISIONS, GovernanceConfig } from "@sema-agent/settings-schema";
3
3
  import { currentGovernanceAskMarks } from "./governance-ask-marks.js";
4
4
  import { tightenGoverned } from "./governance-overrides.js";
5
5
  import { createDeploymentAuthoredPolicy, operatorAsk } from "./operator-ask.js";
@@ -25,7 +25,9 @@ function createCommandAskListPolicy(askCommands, tools = COARSE_SHELL_TOOLS) {
25
25
  },
26
26
  };
27
27
  }
28
- const VALID_COMMAND_NAME = /^[A-Za-z0-9._+-]+$/;
28
+ function commandNameRefused(command) {
29
+ return GovernanceConfig.safeParse({ commandPolicy: [{ command, decision: COMMAND_DECISIONS[0] }] }).error?.issues.some((issue) => issue.path[2] === "command") ?? false;
30
+ }
29
31
  function isCommandDecision(raw) {
30
32
  return typeof raw === "string" && COMMAND_DECISIONS.includes(raw);
31
33
  }
@@ -39,7 +41,7 @@ export function validateCommandRules(rules) {
39
41
  continue;
40
42
  }
41
43
  const { command, decision } = r;
42
- if (typeof command !== "string" || !VALID_COMMAND_NAME.test(command)) {
44
+ if (commandNameRefused(command)) {
43
45
  errors.push(`commandPolicy command "${String(command)}" is not a bare argv[0] name — core matches the EXACT command name (no glob/path/operators). ` +
44
46
  `Use e.g. "git" not "git*"; to gate sub-commands or pipes, deny the interpreter ("sh"/"bash") + rely on the sandbox.`);
45
47
  }
@@ -1,10 +1,11 @@
1
1
  /**
2
- * 钥匙保管目录的布局常量 —— 引擎建目录、建停驻行封签子目录时用的**唯一**值(`src/sealed-key.ts` 读它们)。
3
- * 钥匙文件的权限位不在这里:它就是本服务文件的那一个值 `plugins/owner-only-file-mode.ts` 的 `OWNER_ONLY_FILE_MODE`(部署事实同读它)。
4
- *
5
- * 单独成一只零依赖的叶子模块:随包部署事实 `deploy/facts/sealed-key.json`(`src/deploy-facts.ts` 投影、`scripts/gen-deploy-lanes.ts` 生成)
6
- * 读的是同一份值,生成器不必为了三个常量把整只保管模块(libsodium / 中心上报)装载进来。
2
+ * 保管目录的**唯一解析**:`SEALED_KEY_DIR`(配置席 `sealedKeyDir`,唯一 env 读点在 `config.ts`)或缺省 `<数据根>/sealed-key`。
3
+ * 两个读者同读这一只:起服第 2 段建保管店(`boot/web-admin.ts`),与店的持久性判者取证(`store-posture.ts` 的三根之一,`boot/store-evidence.ts` 递路径)。
7
4
  */
5
+ export declare function sealedKeyDirOf(config: {
6
+ readonly sealedKeyDir?: string;
7
+ readonly localDataRoot?: string;
8
+ }, localRoot: string): string;
8
9
  /** 保管目录的权限位:每次建店都 `mkdir` + `chmod` 成它(目录预先存在时 `mkdir` 的 mode 不生效,所以另 `chmod` 一次)。 */
9
10
  export declare const SEALED_KEY_DIR_MODE = 448;
10
11
  /**
@@ -13,4 +14,10 @@ export declare const SEALED_KEY_DIR_MODE = 448;
13
14
  * 放在模型钥匙目录之下是为了「多副本共享 / 跨重启持久」只有一个目录要管(整个保管目录);模型钥匙店只读这一层的 `*.json`,子目录不进它的视野。
14
15
  */
15
16
  export declare const CHECKPOINT_CTX_KEY_SUBDIR = "checkpoint-ctx-keys";
17
+ /**
18
+ * 首把钥匙的**创建口**的互斥文件名(在保管目录里,`<保管目录>/.keygen.lock`):目录里一把可装载的钥匙都没有时,谁以 `wx`(`O_CREAT | O_EXCL`)独占建成它,谁生成并发布那一把;
19
+ * 发布之后(或失败退出时)删除。不以 `.json` 结尾 ⇒ 装载不会把它当钥匙文件,目录里恒不留它(崩溃在生成中途的极窄窗口除外 —— 那时拒句点名这个文件的路径)。
20
+ * 模型钥匙目录与它之下的 {@link CHECKPOINT_CTX_KEY_SUBDIR} 各是一只目录、各有一把自己的锁。
21
+ */
22
+ export declare const KEYGEN_LOCK_FILE = ".keygen.lock";
16
23
  //# sourceMappingURL=sealed-key-layout.d.ts.map
@@ -1,3 +1,8 @@
1
+ import { join } from "node:path";
2
+ export function sealedKeyDirOf(config, localRoot) {
3
+ return config.sealedKeyDir ?? join(config.localDataRoot ?? localRoot, "sealed-key");
4
+ }
1
5
  export const SEALED_KEY_DIR_MODE = 0o700;
2
6
  export const CHECKPOINT_CTX_KEY_SUBDIR = "checkpoint-ctx-keys";
7
+ export const KEYGEN_LOCK_FILE = ".keygen.lock";
3
8
  //# sourceMappingURL=sealed-key-layout.js.map
@@ -73,14 +73,24 @@ export declare class SealedKeyPublicKeyRefusedError extends Error {
73
73
  * 前置:libsodium 已就绪(三处调用方都先等过它);没就绪 ⇒ 当场抛普通错误(不是判决)。
74
74
  */
75
75
  export declare function judgeSealedKeyPublicKey(publicKeyB64: string): Uint8Array;
76
+ /** {@link ensureSealedKeyStore} 的选项。 */
77
+ export interface EnsureSealedKeyStoreOptions {
78
+ /** 目录里没有钥匙、别人正拿着创建互斥时,最多等多久(毫秒;缺省 15 s)。测试缝;生产不设。 */
79
+ readonly genesisLockWaitMs?: number;
80
+ }
76
81
  /**
77
82
  * Load every keypair under `dir` (creating dir + ONE fresh keypair when none exist) and return the
78
83
  * custody store. Invalid/corrupt files are skipped with a warn (they may be an OLD format or a
79
84
  * half-write — deleting operator key material on a parse error would destroy decryptability, so we
80
85
  * never do; we just don't serve them). Throws only when the store cannot exist at all (fs errors,
81
- * zero loadable keys AND generation failed).
86
+ * zero loadable keys AND generation failed, or another process holds the key-creation lock past the wait).
87
+ *
88
+ * **首把钥匙只有一个创建口**(共享卷上多个副本在空目录上同时首启,全体只出一把):一把可装载的钥匙都没有 ⇒ 取创建互斥({@link takeKeygenLock},`wx` 独占);
89
+ * 拿到的那一个**再读一次目录**(读目录到拿互斥之间别人可能已发布)—— 仍空才生成并发布({@link mintFirstKey}),然后撤互斥;没拿到(`EEXIST`)⇒ 重读目录:
90
+ * 有钥匙了就采用,没有就隔 {@link KEYGEN_LOCK_POLL_MS} 再读,等到 `genesisLockWaitMs` 仍没有 ⇒ 响亮拒({@link keygenLockTimeout}),**不**越过别人的互斥自己生成。
91
+ * 互斥只在「目录里没有可装载的钥匙」时被问到:已有钥匙的目录(含上次崩溃遗留互斥文件的)起服零等待;共享卷须提供原子的 `O_EXCL` 独占创建(本地盘、NFSv3+、常见 RWX 存储类满足)。
82
92
  */
83
- export declare function ensureSealedKeyStore(dir: string, logger?: Logger): Promise<SealedKeyStore>;
93
+ export declare function ensureSealedKeyStore(dir: string, logger?: Logger, opts?: EnsureSealedKeyStoreOptions): Promise<SealedKeyStore>;
84
94
  declare const checkpointCtxKeyStoreBrand: unique symbol;
85
95
  /**
86
96
  * 停驻行封签那一域的保管店(品牌型):读口与 {@link SealedKeyStore} 同形,型不同 —— {@link createCheckpointCtxSealing} 只收它,模型钥匙那只店交进去是 tsc 错
@@ -1,15 +1,16 @@
1
1
  import { createHash } from "node:crypto";
2
- import { chmod, readdir, readFile, writeFile } from "node:fs/promises";
2
+ import { chmod, open, readdir, readFile, rm, stat } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { ensureDir } from "@sema-agent/core";
5
5
  import _sodium from "libsodium-wrappers";
6
- import { CHECKPOINT_CTX_KEY_SUBDIR, SEALED_KEY_DIR_MODE } from "./sealed-key-layout.js";
7
- import { OWNER_ONLY_FILE_MODE } from "./plugins/owner-only-file-mode.js";
6
+ import { CHECKPOINT_CTX_KEY_SUBDIR, KEYGEN_LOCK_FILE, SEALED_KEY_DIR_MODE } from "./sealed-key-layout.js";
7
+ import { OWNER_ONLY_FILE_MODE, atomicWriteFileAsync } from "./plugins/owner-only-file-mode.js";
8
8
  import { buildDisplaySafeUrl } from "./trace/redact.js";
9
9
  import { createCenterCredentialSource } from "./center-credential.js";
10
10
  import { centerFetch } from "./web-admin-client/center-request.js";
11
11
  import { WEB_ADMIN_ENV } from "@sema-agent/settings-schema";
12
12
  import { CHECKPOINT_CTX_SEAL_ALG } from "./http/checkpoint-ctx.js";
13
+ import { readUpstreamJson } from "./upstream-body.js";
13
14
  export const SEALED_KEY_ALG = "libsodium-sealedbox-x25519";
14
15
  const SEAL_OVERHEAD_BYTES = 48;
15
16
  const BASE64_STRICT = /^[A-Za-z0-9+/]+={0,2}$/;
@@ -61,12 +62,10 @@ export function judgeSealedKeyPublicKey(publicKeyB64) {
61
62
  }
62
63
  return bytes;
63
64
  }
64
- export async function ensureSealedKeyStore(dir, logger) {
65
- await _sodium.ready;
65
+ async function scanKeyDir(dir) {
66
66
  const sodium = _sodium;
67
- ensureDir(dir);
68
- await chmod(dir, SEALED_KEY_DIR_MODE);
69
67
  const keys = new Map();
68
+ const notes = [];
70
69
  for (const name of (await readdir(dir)).filter((n) => n.endsWith(".json")).sort()) {
71
70
  const path = join(dir, name);
72
71
  try {
@@ -79,34 +78,123 @@ export async function ensureSealedKeyStore(dir, logger) {
79
78
  if (privateKey.length !== sodium.crypto_box_SECRETKEYBYTES)
80
79
  throw new Error("bad key length");
81
80
  if (name !== `${raw.publicKeyId}.json`)
82
- logger?.warn("sealed_key_filename_drift", { file: name, publicKeyId: raw.publicKeyId, note: "content publicKeyId wins; rename the file to silence this" });
81
+ notes.push({ msg: "sealed_key_filename_drift", fields: { file: name, publicKeyId: raw.publicKeyId, note: "content publicKeyId wins; rename the file to silence this" } });
83
82
  if (keys.has(raw.publicKeyId)) {
84
- logger?.warn("sealed_key_duplicate_id", { file: name, publicKeyId: raw.publicKeyId, note: "duplicate publicKeyId — keeping the first, skipping this file" });
83
+ notes.push({ msg: "sealed_key_duplicate_id", fields: { file: name, publicKeyId: raw.publicKeyId, note: "duplicate publicKeyId — keeping the first, skipping this file" } });
85
84
  continue;
86
85
  }
87
86
  keys.set(raw.publicKeyId, { publicKey, privateKey, publicKeyB64: raw.publicKey, createdAt: typeof raw.createdAt === "string" ? raw.createdAt : "" });
88
87
  }
89
88
  catch (err) {
90
- logger?.warn("sealed_key_file_unreadable", { file: path, errKind: err instanceof Error ? err.name : "unknown", ...(err instanceof SealedKeyPublicKeyRefusedError ? { flaw: err.flaw } : {}), note: "skipped (NOT deleted) — ciphertexts sealed for this key will fail loud per-model" });
89
+ notes.push({
90
+ msg: "sealed_key_file_unreadable",
91
+ fields: { file: path, errKind: err instanceof Error ? err.name : "unknown", ...(err instanceof SealedKeyPublicKeyRefusedError ? { flaw: err.flaw } : {}), note: "skipped (NOT deleted) — ciphertexts sealed for this key will fail loud per-model" },
92
+ });
91
93
  }
92
94
  }
93
- if (keys.size === 0) {
94
- const kp = sodium.crypto_box_keypair();
95
- const publicKeyB64 = Buffer.from(kp.publicKey).toString("base64");
96
- const record = {
97
- v: 1,
98
- alg: SEALED_KEY_ALG,
99
- publicKeyId: deriveKeyId(kp.publicKey),
100
- publicKey: publicKeyB64,
101
- privateKey: Buffer.from(kp.privateKey).toString("base64"),
102
- createdAt: new Date().toISOString(),
103
- };
104
- const path = join(dir, `${record.publicKeyId}.json`);
105
- await writeFile(path, JSON.stringify(record, null, 2) + "\n", { mode: OWNER_ONLY_FILE_MODE });
106
- await chmod(path, OWNER_ONLY_FILE_MODE);
107
- keys.set(record.publicKeyId, { publicKey: kp.publicKey, privateKey: kp.privateKey, publicKeyB64, createdAt: record.createdAt });
108
- logger?.info("sealed_key_generated", { publicKeyId: record.publicKeyId, publicKey: publicKeyB64, dir, note: "new X25519 sealed-box keypair in this directory — the private key exists only here: keep the directory across restarts and identical on every replica that has to open what it sealed, and back it up as a private key" });
95
+ return { keys, notes };
96
+ }
97
+ const isExists = (err) => typeof err === "object" && err !== null && "code" in err && err.code === "EEXIST";
98
+ const KEYGEN_LOCK_POLL_MS = 50;
99
+ const KEYGEN_LOCK_WAIT_MS = 15_000;
100
+ async function takeKeygenLock(dir) {
101
+ const path = join(dir, KEYGEN_LOCK_FILE);
102
+ let handle;
103
+ try {
104
+ handle = await open(path, "wx", OWNER_ONLY_FILE_MODE);
105
+ }
106
+ catch (err) {
107
+ if (isExists(err))
108
+ return undefined;
109
+ throw err;
110
+ }
111
+ try {
112
+ await handle.close();
113
+ }
114
+ catch (error) {
115
+ await releaseKeygenLock(path, { error }, undefined);
116
+ throw error;
117
+ }
118
+ return path;
119
+ }
120
+ async function releaseKeygenLock(path, primary, logger) {
121
+ try {
122
+ await rm(path, { force: true });
123
+ }
124
+ catch (cleanup) {
125
+ if (primary !== undefined) {
126
+ const text = (e) => (e instanceof Error ? e.message : String(e));
127
+ throw new Error(`sealed-key custody: ${text(primary.error)} — and the key-creation lock ${path} this process took could not be removed (${text(cleanup)}): remove it by hand, an empty directory is otherwise blocked on it`, { cause: primary.error });
128
+ }
129
+ logger?.warn("sealed_key_keygen_lock_not_released", { lock: path, errKind: cleanup instanceof Error ? cleanup.name : "unknown", note: "the key-creation lock this process took could not be removed — harmless while the directory holds a key; with an empty directory every start waits on it until it is removed by hand" });
130
+ }
131
+ }
132
+ async function keygenLockTimeout(dir, lock, waitedMs) {
133
+ const heldFor = await stat(lock).then((s) => Math.max(0, Math.round((Date.now() - s.mtimeMs) / 1000)), () => undefined);
134
+ return new Error(`sealed-key custody ${dir}: the key-creation lock ${lock} is held${heldFor !== undefined ? ` (for ${heldFor}s)` : ""} and no key file appeared within ${waitedMs} ms — ` +
135
+ `if no replica is starting right now, an earlier start died while generating the key: remove ${lock} and start again`);
136
+ }
137
+ async function mintFirstKey(dir, logger) {
138
+ const sodium = _sodium;
139
+ const kp = sodium.crypto_box_keypair();
140
+ const publicKeyB64 = Buffer.from(kp.publicKey).toString("base64");
141
+ const record = {
142
+ v: 1,
143
+ alg: SEALED_KEY_ALG,
144
+ publicKeyId: deriveKeyId(kp.publicKey),
145
+ publicKey: publicKeyB64,
146
+ privateKey: Buffer.from(kp.privateKey).toString("base64"),
147
+ createdAt: new Date().toISOString(),
148
+ };
149
+ const path = join(dir, `${record.publicKeyId}.json`);
150
+ await atomicWriteFileAsync(path, JSON.stringify(record, null, 2) + "\n", { durability: "best-effort" });
151
+ await chmod(path, OWNER_ONLY_FILE_MODE);
152
+ logger?.info("sealed_key_generated", { publicKeyId: record.publicKeyId, publicKey: publicKeyB64, dir, note: "new X25519 sealed-box keypair in this directory — the private key exists only here: keep the directory across restarts and identical on every replica that has to open what it sealed, and back it up as a private key" });
153
+ return { id: record.publicKeyId, key: { publicKey: kp.publicKey, privateKey: kp.privateKey, publicKeyB64, createdAt: record.createdAt } };
154
+ }
155
+ export async function ensureSealedKeyStore(dir, logger, opts = {}) {
156
+ await _sodium.ready;
157
+ const sodium = _sodium;
158
+ ensureDir(dir);
159
+ await chmod(dir, SEALED_KEY_DIR_MODE);
160
+ const waitMs = opts.genesisLockWaitMs ?? KEYGEN_LOCK_WAIT_MS;
161
+ const deadline = Date.now() + waitMs;
162
+ let scan = await scanKeyDir(dir);
163
+ let minted;
164
+ try {
165
+ while (scan.keys.size === 0 && minted === undefined) {
166
+ const lock = await takeKeygenLock(dir);
167
+ if (lock !== undefined) {
168
+ let failure;
169
+ try {
170
+ scan = await scanKeyDir(dir);
171
+ if (scan.keys.size === 0)
172
+ minted = await mintFirstKey(dir, logger);
173
+ }
174
+ catch (error) {
175
+ failure = { error };
176
+ throw error;
177
+ }
178
+ finally {
179
+ await releaseKeygenLock(lock, failure, logger);
180
+ }
181
+ }
182
+ else if (Date.now() >= deadline) {
183
+ throw await keygenLockTimeout(dir, join(dir, KEYGEN_LOCK_FILE), waitMs);
184
+ }
185
+ else {
186
+ await new Promise((resolve) => setTimeout(resolve, KEYGEN_LOCK_POLL_MS));
187
+ scan = await scanKeyDir(dir);
188
+ }
189
+ }
190
+ }
191
+ finally {
192
+ for (const n of scan.notes)
193
+ logger?.warn(n.msg, n.fields);
109
194
  }
195
+ const keys = new Map(scan.keys);
196
+ if (minted !== undefined)
197
+ keys.set(minted.id, minted.key);
110
198
  const latestEntry = [...keys.entries()].sort((a, b) => (a[1].createdAt < b[1].createdAt ? 1 : a[1].createdAt > b[1].createdAt ? -1 : a[0] < b[0] ? -1 : 1))[0];
111
199
  return {
112
200
  latest: { publicKeyId: latestEntry[0], publicKey: latestEntry[1].publicKeyB64, createdAt: latestEntry[1].createdAt },
@@ -209,7 +297,7 @@ export async function reportExecutionPublicKey(opts) {
209
297
  if (res.ok) {
210
298
  let idempotent = false;
211
299
  try {
212
- idempotent = (await res.json())?.idempotent === true;
300
+ idempotent = (await readUpstreamJson(res))?.idempotent === true;
213
301
  }
214
302
  catch { }
215
303
  logger?.info(idempotent ? "sealed_key_already_registered" : "sealed_key_reported", { publicKeyId: key.publicKeyId, status: res.status });