@sema-agent/server 7.150.0 → 7.152.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 (514) hide show
  1. package/MIGRATION.md +451 -0
  2. package/README.md +15 -3
  3. package/README.zh-CN.md +10 -2
  4. package/USAGE.md +144 -87
  5. package/deploy/sema-up/README.md +11 -4
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  9. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  10. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  11. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  12. package/deploy/sema-up/chart/values.yaml +8 -1
  13. package/deploy/sema-up/cluster-up.sh +7 -6
  14. package/deploy/sema-up/kube-up.sh +6 -6
  15. package/deploy/sema-up/lib/flagshape.sh +36 -8
  16. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  17. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  18. package/deploy/sema-up/machines.example.yaml +3 -1
  19. package/deploy/sema-up/sema-up.sh +22 -16
  20. package/dist/adoption/import.js +3 -3
  21. package/dist/approval-ask-audit-store.d.ts +1 -1
  22. package/dist/approval-ask-machine.d.ts +4 -10
  23. package/dist/approval-ask-retention.d.ts +1 -1
  24. package/dist/approval-card.d.ts +12 -14
  25. package/dist/approval-gate-currency.d.ts +9 -9
  26. package/dist/approval-gate-currency.js +3 -4
  27. package/dist/approval-hmac.d.ts +17 -1
  28. package/dist/approval-hmac.js +7 -1
  29. package/dist/approval-queue-kind.d.ts +1 -1
  30. package/dist/approval.d.ts +2 -2
  31. package/dist/approval.js +2 -2
  32. package/dist/auth-bridge.d.ts +20 -0
  33. package/dist/auth-bridge.js +9 -0
  34. package/dist/background-session-reap.d.ts +1 -1
  35. package/dist/bake-runner/main.d.ts +4 -2
  36. package/dist/bind-host.d.ts +3 -6
  37. package/dist/bind-host.js +4 -7
  38. package/dist/boot/budget-tracing.js +1 -1
  39. package/dist/boot/coordinators.d.ts +1 -1
  40. package/dist/boot/coordinators.js +9 -10
  41. package/dist/boot/device-lane.js +2 -0
  42. package/dist/boot/engine-lease.d.ts +5 -0
  43. package/dist/boot/engine-lease.js +1 -0
  44. package/dist/boot/execution-env.d.ts +9 -14
  45. package/dist/boot/execution-env.js +85 -22
  46. package/dist/boot/execution-lane.js +32 -5
  47. package/dist/boot/late-binds.d.ts +8 -4
  48. package/dist/boot/late-binds.js +7 -1
  49. package/dist/boot/leader.d.ts +31 -30
  50. package/dist/boot/leader.js +38 -28
  51. package/dist/boot/leg-path-adjudication.d.ts +40 -0
  52. package/dist/boot/leg-path-adjudication.js +18 -0
  53. package/dist/boot/memory-consolidation.d.ts +3 -2
  54. package/dist/boot/memory-consolidation.js +6 -6
  55. package/dist/boot/parked-revive-gate.js +3 -15
  56. package/dist/boot/reapers.d.ts +6 -1
  57. package/dist/boot/reapers.js +13 -2
  58. package/dist/boot/resolve-spec.d.ts +3 -3
  59. package/dist/boot/resolve-spec.js +43 -48
  60. package/dist/boot/runner-deps.d.ts +46 -35
  61. package/dist/boot/runner-deps.js +94 -91
  62. package/dist/boot/session-age-out.d.ts +36 -0
  63. package/dist/boot/session-age-out.js +101 -0
  64. package/dist/boot/session-faces.d.ts +5 -14
  65. package/dist/boot/session-faces.js +9 -5
  66. package/dist/boot/shutdown.d.ts +6 -0
  67. package/dist/boot/shutdown.js +10 -4
  68. package/dist/boot/stage-01-config.js +2 -0
  69. package/dist/boot/stage-02-web-admin-pull.js +4 -5
  70. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  71. package/dist/boot/stage-05-execution-env.js +3 -2
  72. package/dist/boot/stage-06-runners.d.ts +9 -4
  73. package/dist/boot/stage-06-runners.js +24 -9
  74. package/dist/boot/stage-07-capability-layer.d.ts +8 -4
  75. package/dist/boot/stage-07-capability-layer.js +3 -2
  76. package/dist/boot/stage-08-reapers.d.ts +8 -4
  77. package/dist/boot/stage-08-reapers.js +4 -2
  78. package/dist/boot/stage-09-leader.d.ts +12 -5
  79. package/dist/boot/stage-09-leader.js +14 -5
  80. package/dist/boot/stage-10-http-server.d.ts +19 -5
  81. package/dist/boot/stage-10-http-server.js +14 -21
  82. package/dist/boot/stores.js +7 -4
  83. package/dist/boot/web-admin.js +5 -8
  84. package/dist/boot/workflow-orchestration.d.ts +7 -2
  85. package/dist/boot/workflow-orchestration.js +24 -7
  86. package/dist/bounded-rotation.d.ts +29 -0
  87. package/dist/bounded-rotation.js +24 -0
  88. package/dist/capabilities/approvals-push.d.ts +3 -3
  89. package/dist/capabilities/scenarios.d.ts +28 -13
  90. package/dist/capabilities/scenarios.js +2 -2
  91. package/dist/capability-facts.d.ts +43 -32
  92. package/dist/capability-facts.js +45 -51
  93. package/dist/card-rule-offers.d.ts +32 -0
  94. package/dist/card-rule-offers.js +130 -0
  95. package/dist/center-credential.d.ts +25 -6
  96. package/dist/center-credential.js +25 -5
  97. package/dist/config-catalog.d.ts +26 -7
  98. package/dist/config-catalog.js +26 -22
  99. package/dist/config-dir-trust.js +4 -2
  100. package/dist/config-invariants.d.ts +20 -8
  101. package/dist/config-invariants.js +55 -12
  102. package/dist/config-lkg.d.ts +5 -19
  103. package/dist/config-lkg.js +8 -62
  104. package/dist/config-provider.d.ts +1 -1
  105. package/dist/config-root-migration.d.ts +2 -2
  106. package/dist/config-types.d.ts +38 -42
  107. package/dist/config.d.ts +58 -7
  108. package/dist/config.js +90 -40
  109. package/dist/control-socket.d.ts +51 -0
  110. package/dist/control-socket.js +115 -0
  111. package/dist/deployment-governance.d.ts +2 -1
  112. package/dist/deployment-shape.d.ts +9 -1
  113. package/dist/deployment-shape.js +2 -1
  114. package/dist/device-protocol.d.ts +5 -4
  115. package/dist/device-protocol.js +1 -1
  116. package/dist/device-ws-hub.d.ts +7 -0
  117. package/dist/device-ws-hub.js +10 -3
  118. package/dist/device-ws-protocol.d.ts +63 -10
  119. package/dist/device-ws-protocol.js +56 -25
  120. package/dist/elicitation.js +2 -2
  121. package/dist/engine-identity.d.ts +19 -7
  122. package/dist/engine-identity.js +10 -2
  123. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  124. package/dist/entry-problems.d.ts +40 -3
  125. package/dist/entry-problems.js +3 -1
  126. package/dist/execution-env-refusal.d.ts +29 -0
  127. package/dist/execution-env-refusal.js +8 -0
  128. package/dist/execution-lane-caps.d.ts +3 -1
  129. package/dist/field-conflict.d.ts +1 -1
  130. package/dist/file-history-capture.d.ts +11 -4
  131. package/dist/file-history-capture.js +9 -6
  132. package/dist/file-history-disclosure.d.ts +7 -5
  133. package/dist/file-history-disclosure.js +7 -5
  134. package/dist/fleet/drain-entry.d.ts +4 -0
  135. package/dist/fleet/engine-signal.d.ts +12 -29
  136. package/dist/fleet/engine-signal.js +1 -7
  137. package/dist/fleet-client.js +2 -5
  138. package/dist/gate-settlement.d.ts +1 -8
  139. package/dist/gate-settlement.js +0 -4
  140. package/dist/history-anchor.js +1 -1
  141. package/dist/hitl-delivery.d.ts +2 -3
  142. package/dist/hitl-delivery.js +0 -2
  143. package/dist/hooks/hook-llm.js +4 -2
  144. package/dist/hooks/hook-runner.d.ts +3 -2
  145. package/dist/hooks/hook-runner.js +18 -3
  146. package/dist/host-decision.d.ts +11 -11
  147. package/dist/host-lsp-manager.d.ts +2 -2
  148. package/dist/http/active-run-conflict.d.ts +35 -2
  149. package/dist/http/active-run-conflict.js +48 -19
  150. package/dist/http/admission.js +17 -2
  151. package/dist/http/approval-sweeps.d.ts +1 -1
  152. package/dist/http/approval-sweeps.js +10 -7
  153. package/dist/http/checkpoint-ctx.d.ts +4 -0
  154. package/dist/http/checkpoint-ctx.js +2 -0
  155. package/dist/http/dispatch.d.ts +8 -3
  156. package/dist/http/dispatch.js +59 -32
  157. package/dist/http/durable-run-leg.js +16 -17
  158. package/dist/http/health-reader.d.ts +16 -9
  159. package/dist/http/health-reader.js +2 -1
  160. package/dist/http/health-self-report.d.ts +9 -1
  161. package/dist/http/health-self-report.js +3 -1
  162. package/dist/http/owner-access.d.ts +33 -14
  163. package/dist/http/owner-access.js +40 -10
  164. package/dist/http/principal-gate.d.ts +49 -21
  165. package/dist/http/principal-gate.js +61 -11
  166. package/dist/http/request-channel.d.ts +23 -0
  167. package/dist/http/request-channel.js +9 -0
  168. package/dist/http/request-guards.js +17 -2
  169. package/dist/http/resume-ctx-read.js +42 -3
  170. package/dist/http/resume-legs.d.ts +4 -3
  171. package/dist/http/resume-legs.js +367 -117
  172. package/dist/http/route-ctx.d.ts +91 -15
  173. package/dist/http/route-ctx.js +17 -0
  174. package/dist/http/route-table.d.ts +5 -1
  175. package/dist/http/route-table.js +4 -0
  176. package/dist/http/routes/admin-config-refresh.js +3 -3
  177. package/dist/http/routes/admin-drain.d.ts +3 -0
  178. package/dist/http/routes/admin-drain.js +7 -7
  179. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  180. package/dist/http/routes/admin-memory-optout.js +3 -3
  181. package/dist/http/routes/adoption.js +3 -5
  182. package/dist/http/routes/agents-roster.js +2 -3
  183. package/dist/http/routes/approvals-assistant.d.ts +2 -1
  184. package/dist/http/routes/approvals-assistant.js +99 -51
  185. package/dist/http/routes/background.d.ts +3 -3
  186. package/dist/http/routes/capabilities.d.ts +4 -0
  187. package/dist/http/routes/capabilities.js +38 -10
  188. package/dist/http/routes/config-catalog.js +2 -2
  189. package/dist/http/routes/devices.js +1 -1
  190. package/dist/http/routes/diagnostics.d.ts +3 -3
  191. package/dist/http/routes/diagnostics.js +19 -7
  192. package/dist/http/routes/fleet.js +10 -8
  193. package/dist/http/routes/images.js +10 -10
  194. package/dist/http/routes/memory-bundle.js +3 -3
  195. package/dist/http/routes/memory-compliance.js +3 -3
  196. package/dist/http/routes/memory-consolidation.js +2 -2
  197. package/dist/http/routes/memory-origin.js +3 -3
  198. package/dist/http/routes/memory-policy.js +2 -2
  199. package/dist/http/routes/observability.js +3 -3
  200. package/dist/http/routes/projects.d.ts +3 -2
  201. package/dist/http/routes/projects.js +4 -5
  202. package/dist/http/routes/retention-ops.js +3 -3
  203. package/dist/http/routes/rules.js +5 -5
  204. package/dist/http/routes/run-permission-mode.d.ts +2 -1
  205. package/dist/http/routes/run-permission-mode.js +2 -2
  206. package/dist/http/routes/runs.d.ts +4 -9
  207. package/dist/http/routes/runs.js +171 -65
  208. package/dist/http/routes/session-sync.d.ts +22 -9
  209. package/dist/http/routes/session-sync.js +204 -107
  210. package/dist/http/routes/sessions-list.js +13 -7
  211. package/dist/http/routes/sessions.js +30 -15
  212. package/dist/http/routes/tasks.js +46 -41
  213. package/dist/http/routes/trace-usage.js +2 -2
  214. package/dist/http/routes/workflows.js +1 -1
  215. package/dist/http/server.d.ts +30 -30
  216. package/dist/http/server.js +16 -4
  217. package/dist/http/submit-ctx.d.ts +1 -1
  218. package/dist/http/submit-ctx.js +7 -4
  219. package/dist/http/wire-types.d.ts +14 -4
  220. package/dist/human-facing-args.d.ts +33 -0
  221. package/dist/human-facing-args.js +33 -0
  222. package/dist/identity-source.d.ts +20 -3
  223. package/dist/identity-source.js +14 -0
  224. package/dist/index.d.ts +5 -1
  225. package/dist/k8s-api-credentials.d.ts +29 -0
  226. package/dist/k8s-api-credentials.js +25 -0
  227. package/dist/lane-home-probe.d.ts +3 -7
  228. package/dist/lane-home-probe.js +2 -2
  229. package/dist/leader/diffup.d.ts +19 -0
  230. package/dist/leader/diffup.js +7 -0
  231. package/dist/leader/leader.d.ts +116 -11
  232. package/dist/leader/leader.js +69 -5
  233. package/dist/leader/repair-wire.js +2 -2
  234. package/dist/leader/run-entry.d.ts +2 -1
  235. package/dist/leader/run-entry.js +1 -1
  236. package/dist/leader/wire.d.ts +42 -132
  237. package/dist/leader/wire.js +81 -67
  238. package/dist/leg-facts.d.ts +13 -5
  239. package/dist/leg-facts.js +2 -1
  240. package/dist/memory-scope.d.ts +23 -11
  241. package/dist/memory-scope.js +18 -6
  242. package/dist/memory-sync-client.d.ts +30 -2
  243. package/dist/memory-sync-client.js +16 -9
  244. package/dist/model-entry-headers.d.ts +9 -10
  245. package/dist/model-entry-headers.js +0 -4
  246. package/dist/model-entry-refusal.d.ts +7 -4
  247. package/dist/model-entry-refusal.js +11 -5
  248. package/dist/model-plane-face.d.ts +1 -1
  249. package/dist/model-plane-face.js +3 -1
  250. package/dist/model-route-endpoint.d.ts +13 -7
  251. package/dist/model-route-endpoint.js +14 -11
  252. package/dist/model-select.d.ts +22 -0
  253. package/dist/model-select.js +9 -0
  254. package/dist/model-unreachable-notice.d.ts +11 -0
  255. package/dist/model-unreachable-notice.js +4 -4
  256. package/dist/object-store-buckets.d.ts +640 -6
  257. package/dist/object-store-buckets.js +166 -0
  258. package/dist/observability/err-text.d.ts +7 -0
  259. package/dist/observability/err-text.js +5 -0
  260. package/dist/observability/fail-open.d.ts +25 -17
  261. package/dist/observability/fail-open.js +25 -17
  262. package/dist/observability/logger.js +3 -1
  263. package/dist/observability/metrics.js +1 -0
  264. package/dist/operator-roster.d.ts +68 -0
  265. package/dist/operator-roster.js +32 -0
  266. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  267. package/dist/orchestration/workflow-notify-journal.js +12 -1
  268. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  269. package/dist/orchestration/workflow-park-decision.js +49 -10
  270. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  271. package/dist/orchestration/workflow-park-holder.js +98 -0
  272. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  273. package/dist/orchestration/workflow-record-fence.js +42 -0
  274. package/dist/outbound-dispatcher.d.ts +71 -8
  275. package/dist/outbound-dispatcher.js +48 -7
  276. package/dist/owner-faces.d.ts +2 -2
  277. package/dist/parked-decide.d.ts +106 -55
  278. package/dist/parked-decide.js +153 -117
  279. package/dist/peer-directory.d.ts +2 -2
  280. package/dist/peer-inbound-face.d.ts +2 -6
  281. package/dist/peer-inbound-face.js +0 -3
  282. package/dist/permission-mode-admission.d.ts +74 -5
  283. package/dist/permission-mode-admission.js +56 -3
  284. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  285. package/dist/plugins/adoption-log-sql.js +7 -1
  286. package/dist/plugins/approval-ask-store-file.d.ts +14 -2
  287. package/dist/plugins/approval-ask-store-file.js +11 -0
  288. package/dist/plugins/approval-ask-store-memory.d.ts +10 -1
  289. package/dist/plugins/approval-ask-store-memory.js +35 -10
  290. package/dist/plugins/approval-ask-store-sql.d.ts +69 -4
  291. package/dist/plugins/approval-ask-store-sql.js +45 -5
  292. package/dist/plugins/approval-exemption-store.js +3 -0
  293. package/dist/plugins/approval-nonce-store.js +2 -0
  294. package/dist/plugins/blob-backend.d.ts +83 -7
  295. package/dist/plugins/blob-backend.js +57 -6
  296. package/dist/plugins/breaker-state-sql.js +2 -0
  297. package/dist/plugins/caching-session-store.d.ts +9 -15
  298. package/dist/plugins/caching-session-store.js +6 -0
  299. package/dist/plugins/checkpoint-index-columns.d.ts +20 -16
  300. package/dist/plugins/checkpoint-index-columns.js +3 -6
  301. package/dist/plugins/checkpoint-store-face.d.ts +119 -61
  302. package/dist/plugins/checkpoint-store-face.js +134 -55
  303. package/dist/plugins/device-store-sql.js +6 -0
  304. package/dist/plugins/error-origin.d.ts +18 -0
  305. package/dist/plugins/error-origin.js +10 -0
  306. package/dist/plugins/execution-placement-sql.js +6 -6
  307. package/dist/plugins/image-bake-store-sql.js +6 -0
  308. package/dist/plugins/image-index-sql.js +4 -0
  309. package/dist/plugins/landed-attendants.d.ts +212 -0
  310. package/dist/plugins/landed-attendants.js +161 -0
  311. package/dist/plugins/leader-run-store-sql.js +4 -0
  312. package/dist/plugins/local-checkpoint-store.d.ts +13 -3
  313. package/dist/plugins/local-checkpoint-store.js +38 -49
  314. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  315. package/dist/plugins/local-session-live-reference.js +39 -0
  316. package/dist/plugins/local-session-store.d.ts +71 -33
  317. package/dist/plugins/local-session-store.js +129 -27
  318. package/dist/plugins/memory-engine-pg.js +4 -0
  319. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  320. package/dist/plugins/memory-engine-tidb.js +4 -0
  321. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  322. package/dist/plugins/memory-sync-store-pg.js +5 -0
  323. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  324. package/dist/plugins/one-time-migrations.d.ts +104 -80
  325. package/dist/plugins/one-time-migrations.js +226 -132
  326. package/dist/plugins/org-delivery-quota-store.js +4 -1
  327. package/dist/plugins/outcome-ledger-sql.js +2 -0
  328. package/dist/plugins/permission-rule-store-sql.js +11 -4
  329. package/dist/plugins/pg-cost-quota.js +4 -0
  330. package/dist/plugins/pg-pool.js +35 -10
  331. package/dist/plugins/pg-rate-limiter.js +2 -0
  332. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  333. package/dist/plugins/posix-shell-fs.js +4 -1
  334. package/dist/plugins/remote-env-adb.d.ts +19 -15
  335. package/dist/plugins/remote-env-adb.js +41 -15
  336. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  337. package/dist/plugins/remote-env-connect-seat.js +72 -0
  338. package/dist/plugins/remote-env-device.d.ts +22 -5
  339. package/dist/plugins/remote-env-device.js +106 -8
  340. package/dist/plugins/remote-env-e2b.d.ts +15 -6
  341. package/dist/plugins/remote-env-e2b.js +42 -32
  342. package/dist/plugins/remote-env-file-error.js +6 -2
  343. package/dist/plugins/remote-env-host.d.ts +46 -10
  344. package/dist/plugins/remote-env-host.js +124 -52
  345. package/dist/plugins/remote-env-k8s.d.ts +109 -41
  346. package/dist/plugins/remote-env-k8s.js +160 -54
  347. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  348. package/dist/plugins/remote-env-local-docker.js +34 -41
  349. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  350. package/dist/plugins/remote-env-ssh.js +60 -59
  351. package/dist/plugins/remote-shell.d.ts +98 -1
  352. package/dist/plugins/remote-shell.js +218 -0
  353. package/dist/plugins/replica-registration.d.ts +1 -1
  354. package/dist/plugins/replica-registration.js +1 -1
  355. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  356. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  357. package/dist/plugins/retention-lane-store-sql.js +4 -0
  358. package/dist/plugins/retention-sql.d.ts +20 -2
  359. package/dist/plugins/retention-sql.js +11 -0
  360. package/dist/plugins/run-store-sql.d.ts +21 -2
  361. package/dist/plugins/run-store-sql.js +31 -7
  362. package/dist/plugins/s3-presign.d.ts +23 -0
  363. package/dist/plugins/s3-presign.js +37 -3
  364. package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
  365. package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
  366. package/dist/plugins/scheduler-support.d.ts +2 -2
  367. package/dist/plugins/scheduler-support.js +0 -3
  368. package/dist/plugins/schema-consistency.d.ts +4 -2
  369. package/dist/plugins/schema-consistency.js +19 -2
  370. package/dist/plugins/schema-indexes.js +2 -0
  371. package/dist/plugins/send-file-ledger.d.ts +2 -2
  372. package/dist/plugins/send-file-ledger.js +5 -2
  373. package/dist/plugins/send-user-file.d.ts +3 -4
  374. package/dist/plugins/send-user-file.js +56 -52
  375. package/dist/plugins/serving-requirement.d.ts +26 -7
  376. package/dist/plugins/serving-requirement.js +11 -4
  377. package/dist/plugins/session-birth.d.ts +6 -2
  378. package/dist/plugins/session-blob-claim-token.d.ts +15 -0
  379. package/dist/plugins/session-blob-claim-token.js +20 -0
  380. package/dist/plugins/session-blob-namespace.d.ts +46 -0
  381. package/dist/plugins/session-blob-namespace.js +116 -0
  382. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  383. package/dist/plugins/session-ext-table.d.ts +14 -1
  384. package/dist/plugins/session-ext-table.js +5 -1
  385. package/dist/plugins/session-row-sql.d.ts +49 -2
  386. package/dist/plugins/session-row-sql.js +56 -13
  387. package/dist/plugins/session-store-sql.d.ts +34 -18
  388. package/dist/plugins/session-store-sql.js +98 -17
  389. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  390. package/dist/plugins/shared-memory-store-sql.js +6 -2
  391. package/dist/plugins/snapshot-bucket-presence.d.ts +25 -2
  392. package/dist/plugins/snapshot-bucket-presence.js +8 -2
  393. package/dist/plugins/sql-driver.d.ts +2 -1
  394. package/dist/plugins/sql-driver.js +18 -3
  395. package/dist/plugins/sql-errors.d.ts +11 -6
  396. package/dist/plugins/sql-errors.js +5 -6
  397. package/dist/plugins/sql-json-column.d.ts +1 -1
  398. package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
  399. package/dist/plugins/stop-then-start-sentence.js +14 -10
  400. package/dist/plugins/stop-then-start.d.ts +109 -0
  401. package/dist/plugins/stop-then-start.js +104 -0
  402. package/dist/plugins/store-backend.d.ts +84 -15
  403. package/dist/plugins/store-backend.js +236 -72
  404. package/dist/plugins/store-boundary.d.ts +57 -0
  405. package/dist/plugins/store-boundary.js +139 -0
  406. package/dist/plugins/store-contracts.d.ts +17 -0
  407. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  408. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  409. package/dist/plugins/store-fault.d.ts +26 -7
  410. package/dist/plugins/store-fault.js +18 -2
  411. package/dist/plugins/task-attachment-store.d.ts +2 -1
  412. package/dist/plugins/task-attachment-store.js +14 -1
  413. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  414. package/dist/plugins/task-list-store-sql.js +10 -8
  415. package/dist/plugins/tidb-cost-quota.js +4 -0
  416. package/dist/plugins/tidb-pool.js +21 -25
  417. package/dist/plugins/tidb-rate-limiter.js +4 -0
  418. package/dist/plugins/user-input-ledger-sql.js +4 -0
  419. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  420. package/dist/plugins/workflow-run-store-sql.js +64 -4
  421. package/dist/plugins/workspace-custody.d.ts +4 -3
  422. package/dist/plugins/workspace-fill.d.ts +4 -7
  423. package/dist/plugins/workspace-fill.js +2 -1
  424. package/dist/plugins/write-behind-counter.js +5 -0
  425. package/dist/project-context.d.ts +0 -2
  426. package/dist/project-context.js +4 -8
  427. package/dist/project-registry.d.ts +46 -0
  428. package/dist/project-registry.js +44 -0
  429. package/dist/question.d.ts +2 -1
  430. package/dist/question.js +5 -13
  431. package/dist/request-form.d.ts +6 -1
  432. package/dist/request-form.js +4 -1
  433. package/dist/request-key-closure.js +1 -1
  434. package/dist/request-value-closure.d.ts +4 -0
  435. package/dist/request-value-closure.js +10 -0
  436. package/dist/rule-issue-reading.d.ts +1 -1
  437. package/dist/rules-consent.d.ts +1 -1
  438. package/dist/run-acceptance.d.ts +3 -2
  439. package/dist/run-acceptance.js +4 -6
  440. package/dist/run-local.js +9 -9
  441. package/dist/runs.d.ts +54 -16
  442. package/dist/runs.js +67 -13
  443. package/dist/runtime-governance.d.ts +5 -4
  444. package/dist/security.d.ts +30 -32
  445. package/dist/security.js +41 -7
  446. package/dist/sema-config-dir.d.ts +2 -1
  447. package/dist/server-secret-env.d.ts +12 -10
  448. package/dist/server-secret-env.js +24 -15
  449. package/dist/session-bindings.d.ts +82 -0
  450. package/dist/session-bindings.js +18 -0
  451. package/dist/session-children-retire.d.ts +2 -2
  452. package/dist/session-children-retire.js +2 -6
  453. package/dist/session-deletion.d.ts +16 -1
  454. package/dist/session-error-wire.d.ts +3 -3
  455. package/dist/session-error-wire.js +3 -3
  456. package/dist/session-incarnation.d.ts +10 -0
  457. package/dist/session-incarnation.js +10 -1
  458. package/dist/session-kind.d.ts +57 -0
  459. package/dist/session-kind.js +22 -0
  460. package/dist/session-row.d.ts +21 -1
  461. package/dist/session-row.js +7 -1
  462. package/dist/session-sync-kernel.d.ts +24 -14
  463. package/dist/session-sync-kernel.js +3 -6
  464. package/dist/session-sync.d.ts +25 -103
  465. package/dist/session-sync.js +14 -76
  466. package/dist/session-titler.d.ts +10 -3
  467. package/dist/session-titler.js +19 -6
  468. package/dist/ssh-host-key.d.ts +5 -0
  469. package/dist/ssh-host-key.js +3 -0
  470. package/dist/stores-sql/blob-index-sql.d.ts +30 -9
  471. package/dist/stores-sql/blob-index-sql.js +40 -21
  472. package/dist/stores-sql/checkpoint-store-sql.d.ts +54 -27
  473. package/dist/stores-sql/checkpoint-store-sql.js +70 -146
  474. package/dist/stores-sql/file-history-store-sql.d.ts +113 -15
  475. package/dist/stores-sql/file-history-store-sql.js +205 -95
  476. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  477. package/dist/stores-sql/pg-session-storage.js +37 -13
  478. package/dist/stores-sql/retention-store-sql.d.ts +1 -9
  479. package/dist/stores-sql/retention-store-sql.js +5 -19
  480. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  481. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  482. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  483. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  484. package/dist/stores-sql/tidb-session-store.js +37 -13
  485. package/dist/submission-exit.d.ts +3 -2
  486. package/dist/submission-exit.js +9 -1
  487. package/dist/task-cwd.d.ts +2 -2
  488. package/dist/task-settings.d.ts +7 -5
  489. package/dist/task-settings.js +3 -3
  490. package/dist/terminal.d.ts +33 -2
  491. package/dist/terminal.js +139 -9
  492. package/dist/tool-approval.d.ts +465 -507
  493. package/dist/tool-approval.js +606 -1222
  494. package/dist/trace/core-keyset-guard.d.ts +1 -1
  495. package/dist/trace/ledger-events.d.ts +3 -3
  496. package/dist/trace/project.d.ts +2 -3
  497. package/dist/trace/redact.js +3 -2
  498. package/dist/trace/self-minted-wire.d.ts +571 -178
  499. package/dist/trace/self-minted-wire.js +189 -56
  500. package/dist/web-admin-client/apply-effective.js +2 -2
  501. package/dist/web-admin-client/read-warnings.d.ts +2 -2
  502. package/dist/web-admin-client/read-warnings.js +1 -1
  503. package/dist/web-admin-client/types.d.ts +1 -1
  504. package/dist/workspace-space.d.ts +10 -4
  505. package/dist/workspace-space.js +4 -1
  506. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +79 -28
  507. package/package.json +7 -3
  508. package/scripts/embed-minimal.mjs +3 -3
  509. package/wire-changes/server@7.151.0.json +762 -0
  510. package/wire-changes/server@7.152.0.json +900 -0
  511. package/dist/config-d-migration.d.ts +0 -37
  512. package/dist/config-d-migration.js +0 -60
  513. package/dist/http/session-inherit-env.d.ts +0 -36
  514. package/dist/http/session-inherit-env.js +0 -6
@@ -16,7 +16,7 @@ export function callerOf(req, w) {
16
16
  const subject = gatedSubject(req, w.config);
17
17
  return {
18
18
  subject,
19
- operator: explicitOperatorOk(subject === undefined ? undefined : personOf(subject), w.config),
19
+ operator: explicitOperatorOk(subject === undefined ? undefined : personOf(subject), w.config, "operate"),
20
20
  fleet: actsForDeployment(req, w.config, () => subject),
21
21
  traceRead: traceTokenPresented(req, w.config),
22
22
  principalRequired: DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(w.config),
@@ -24,7 +24,7 @@ export function callerOf(req, w) {
24
24
  };
25
25
  }
26
26
  export function callerOfDecision(base, decider, roster) {
27
- return { ...base, subject: deciderSubjectOf(base.subject, decider), operator: explicitOperatorOk(decider, roster), fleet: undefined, traceRead: false };
27
+ return { ...base, subject: deciderSubjectOf(base.subject, decider), operator: explicitOperatorOk(decider, roster, "operate"), fleet: undefined, traceRead: false };
28
28
  }
29
29
  export function deciderSubjectOf(requestSubject, decider) {
30
30
  return decider === undefined ? undefined : subjectOf(decider, requestSubject === undefined ? undefined : partsOf(requestSubject).scenario);
@@ -47,9 +47,8 @@ export const ROUTE_FACES = {
47
47
  "run-task-stop": "run.supervise",
48
48
  "elicitation-respond": null,
49
49
  "question-respond": null,
50
- "tool-approval-respond": null,
51
- "tool-approval-read": null,
52
50
  "task-ask-decision": null,
51
+ "task-ask-read": null,
53
52
  "run-permission-mode": "run.supervise",
54
53
  "run-memory-capture-optout": "run.drive",
55
54
  "session-init": null,
@@ -410,9 +409,24 @@ export async function readVisibleSession(entry, store, sessionId) {
410
409
  const verdict = await judgeSessionById(entry, store, sessionId);
411
410
  return verdict === undefined || verdict === "door" || verdict === "not_visible" ? undefined : verdict;
412
411
  }
413
- export async function sessionOwnerUnchanged(entry, store, sessionId, admittedOwner) {
412
+ export async function sessionOccupantUnchanged(entry, store, sessionId, admitted) {
414
413
  const head = await readOwnerCell(entry, sessionId, () => store.headOf(sessionId));
415
- return sessionRowPresent(head) && head.owner === admittedOwner;
414
+ return sessionRowPresent(head) && sameOccupant(admitted, head);
415
+ }
416
+ export async function recheckSyncGate(store, sessionId, admitted, port) {
417
+ const live = await store.headOf(sessionId);
418
+ switch (port) {
419
+ case "pull":
420
+ return rowRead(live) && sameOccupant(admitted, live);
421
+ case "push": {
422
+ const held = rowRead(live) ? live : await deletionHeadReadOf(store)(sessionId);
423
+ return rowRead(held) && sameOccupant(admitted, held);
424
+ }
425
+ default: {
426
+ const unknownPort = port;
427
+ throw new Error(`recheckSyncGate: no port ${JSON.stringify(unknownPort)}`);
428
+ }
429
+ }
416
430
  }
417
431
  export async function judgeSession(entry, store, sessionId, reading) {
418
432
  if (!sessionRowPresent(reading))
@@ -448,6 +462,15 @@ export function sessionFactsReadOf(store) {
448
462
  return rowRead(head) ? { get leafId() { return head.leafId; } } : undefined;
449
463
  };
450
464
  }
465
+ export function sessionOccupantReadOf(store) {
466
+ const headOf = store?.headOf;
467
+ if (typeof headOf !== "function")
468
+ return undefined;
469
+ return async (sessionId) => {
470
+ const head = await headOf.call(store, sessionId);
471
+ return rowRead(head) ? sessionFaceOfHead(sessionId, head) : undefined;
472
+ };
473
+ }
451
474
  export async function readSessionAgent(store, sessionId) {
452
475
  const placementOf = store?.placementOf;
453
476
  if (placementOf === undefined)
@@ -477,13 +500,17 @@ export async function readVisibleLatestRun(entry, store, sessionId) {
477
500
  const latest = await store.latestRunForSession(sessionId);
478
501
  return rowRead(latest) && seesRun(entry, latest.owner) ? latest : undefined;
479
502
  }
480
- export function runListOwnerOf(filter, named) {
503
+ export function listOwnerOf(filter, named) {
481
504
  return filter.gateOwner ?? named;
482
505
  }
483
506
  export function listVisibleRuns(store, filter, named, query) {
484
- const owner = runListOwnerOf(filter, named);
507
+ const owner = listOwnerOf(filter, named);
485
508
  return store.listRuns({ ...query, ...(owner ? { owner } : {}) });
486
509
  }
510
+ export function listVisibleSessions(lister, filter, named, query) {
511
+ const owner = listOwnerOf(filter, named);
512
+ return lister({ ...query, ...(owner !== undefined ? { owner } : {}), ...(filter.includeUnowned ? { includeUnowned: true } : {}) });
513
+ }
487
514
  export function listRunsOfScope(store, scope, limit) {
488
515
  return store.listRuns({ owner: ownerOfCheckpointScope(scope), limit });
489
516
  }
@@ -534,14 +561,17 @@ export const WORKFLOW_SESSION_ASSERTION = {
534
561
  "workflow-stream": { phase: "accept", label: "workflow.stream" },
535
562
  "workflow-agent-steer": { phase: "accept", label: "workflow.agent-steer" },
536
563
  };
564
+ export function workflowScopeOf(subject) {
565
+ return engineScopeOf(subject);
566
+ }
537
567
  export function listVisibleWorkflows(entry, store, opts) {
538
- return store.listByScope(engineScopeOf(entry.caller.subject), opts);
568
+ return store.listByScope(workflowScopeOf(entry.caller.subject), opts);
539
569
  }
540
570
  export async function judgeWorkflowRun(entry, store, runId) {
541
571
  const row = await store.get(runId);
542
572
  if (!rowRead(row))
543
573
  return "missing";
544
- const engineCaller = { ...entry.caller, subject: recoveredSubject(engineScopeOf(entry.caller.subject)) };
574
+ const engineCaller = { ...entry.caller, subject: recoveredSubject(workflowScopeOf(entry.caller.subject)) };
545
575
  const verdict = verdictOnQuals(entry, qualsOf(engineCaller, ownerCellOf(row.scope)));
546
576
  if (verdict === "door" || verdict === "not_visible")
547
577
  return verdict;
@@ -1,7 +1,8 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { ServiceConfig } from "../config-types.js";
3
+ import { type NonPersonTier, type OperatorPower, type OperatorRoster } from "../operator-roster.js";
3
4
  import { type Person, type Subject } from "../owner-brands.js";
4
- import type { Caller } from "../owner-faces.js";
5
+ import { type Caller } from "../owner-faces.js";
5
6
  import { type IdentitySource, type RunIdentity } from "../identity-source.js";
6
7
  import type { Logger } from "../observability/logger.js";
7
8
  /** Coerce a possibly-repeated request header to a single string (or undefined). */
@@ -126,23 +127,50 @@ export declare function actsForDeployment(req: IncomingMessage, config: ServiceC
126
127
  */
127
128
  export declare function serviceTokenDeclaredActsForDeployment(config: Pick<ServiceConfig, "serviceTokenActsForDeployment">): boolean;
128
129
  /**
129
- * 运维名册 —— 「谁是 operator」读的两格(都住在部署配置里):具名名单 `OPERATOR_PRINCIPALS` 与单用户形的显式声明 `OPERATOR_SINGLE_USER`。
130
- * 两者互斥(声明只在单用户形、名单为空时成立;否则拒启 —— 一个事实一个来源,`config-invariants.ts` 的 `operator-single-user`)。
131
- */
132
- export type OperatorRoster = Pick<ServiceConfig, "operatorPrincipals" | "operatorSingleUser">;
133
- /**
134
- * 🔴 **「谁是 operator」的唯一读法**([ref],[ref] ① 裁 A;IMAGE-API-DESIGN.md §P2.4a MUST-FIX 的那一只门)。
130
+ * 🔴 **「这位验过的人在这台部署上持不持这只运维权力」的唯一读法**([ref],[ref] ① 裁 A;IMAGE-API-DESIGN.md §P2.4a MUST-FIX 的那一只门)。
131
+ * 档表与人 → 档的读法住在叶子 `operator-roster.ts`(`ROSTER_TIERS` / `rosterTierOf`);本函数 = 「人落在某档 ∧ 那一档持 `power`」。
135
132
  * · 名单为空 ⇒ **没人是**(没有任何形把「空名单」读成「人人是」—— 那条读法 `isOperator` 已删);
136
- * · 名单非空 ⇒ 验过的主体在名单里才是;
137
- * · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**都是(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
138
- * 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形成立(起服不变量)。
133
+ * · 名单非空 ⇒ 验过的人在名单里才是;全运维档(`OPERATOR_PRINCIPALS`)持每一只权力,排空档(`OPERATOR_DRAIN_PRINCIPALS`)只持 `drain`;
134
+ * · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**落全运维档(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
135
+ * 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形、且各档名单都空时成立(起服不变量)。
136
+ * `power` 必填、零缺省:运维面的门与放宽位传 `"operate"`,排空口传它声明行的 `power`(`routes/admin-drain.ts`)。
139
137
  * `person` 必须是验过的人(`gatedPerson` / `personOf(主体)`),绝不是自述头,也不是带场景的主体(名册登记的是人)。全部运维面(审批队列、steer / interrupt / wake 的属主门旁路、记忆运维口、bake 门……)读这一只 —— 只答授权;
140
138
  * 送话口的文本框架(`trusted`)从不读它(调用方的话恒 `trusted: false`,见 `routes/runs.ts` steer 口的注);
141
139
  * 🔴 SINGLE mint point (E1):不要再造兄弟。
142
140
  */
143
- export declare function explicitOperatorOk(person: Person | undefined, roster: OperatorRoster): boolean;
144
- /** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane` 读这一只(整理阀门的可达性告警随本条退役)。单用户形上,装了运维面的进程里它恒真(`operator-declaration-required`:服务进程起服第 1 段、`createHttpServer` 对不声明的单用户形拒),多租形上空名单 ⇒ 假。 */
145
- export declare function operatorRosterPresent(roster: OperatorRoster): boolean;
141
+ export declare function explicitOperatorOk(person: Person | undefined, roster: OperatorRoster, power: OperatorPower): boolean;
142
+ /** 「这台部署上**有没有**人能持这只权力」的唯一读法(持它的某档名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane` 读这一只(整理阀门的可达性告警随本条退役)。单用户形上,装了运维面的进程里它恒真(`operator-declaration-required`:服务进程起服第 1 段、`createHttpServer` 对不声明的单用户形拒),多租形上持它的各档名单都空 ⇒ 假。 */
143
+ export declare function operatorRosterPresent(roster: OperatorRoster, power: OperatorPower): boolean;
144
+ /**
145
+ * 🔴 **圈禁的唯一判官**(三个读点,同一只判:请求的人 —— {@link requestConfinedTier},分派层整次请求判一次;决定证明推出的决定者 —— 直连门决定口验过证明之后,
146
+ * `routes/approvals-assistant.ts` 的 `admitDirectDoorDecider`;设备行的属主 —— {@link deviceOwnerConfinedTier},设备 hello 准入,`device-ws-hub.ts`)。`person` 落在**非人档** ∧ 这一条路由没声明那一档持的权力(`power` = 路由声明行的 `power` 列,缺席 = 没声明)
147
+ * ⇒ 答那一档(调用方 403 `auth.principal_confined`,{@link sendPrincipalConfined});人档 / 不在名册 / 路由声明了它持的权力 ⇒ `undefined`(照常往下判)。
148
+ * 不是第二套鉴权:身份读法、名册来源都不新;它答的是「这只验过的身份在本请求上能不能用」——与 [ref] `auth.scope_mismatch` 同一位置的第二个原因。
149
+ */
150
+ export declare function confinedTierOf(person: Person | undefined, roster: OperatorRoster, power: OperatorPower | undefined): NonPersonTier | undefined;
151
+ /**
152
+ * 请求读点:这次请求的人在本路由上被不被圈禁。**只在名册里有非人档的名字时读人**(`rosterHasNonPersonNames`;没声明的部署零新读、逐字节同今天)。
153
+ * 读的是这次请求里**任一只验得过的人**(`verifiedPerson`:三来源按身份边界的序),**不**因同一请求另带了一枚验不过的 Bearer 而读成「没有人」——
154
+ * 那条律(`gatedSubject`)只收窄身份、从不授权;圈禁是收窄的另一面,请求里只要出示了一只被圈禁的身份就判它(读路凭据谓词照样会认那只身份,
155
+ * 例如直连门 principal 令牌 + 坏 Bearer 的 `/health`,所以这里不能比它少认)。**不判场景头**(不把「REQUIRE 401 先于场景头 400」的既有序提前改掉)。
156
+ * 读人只在人名坏形时抛(`assertPrincipalShape` 的 400):非人档的名字由起服 / 装配不变量 `operator-roster-well-formed` 保证都是合形的主体名,坏形的串
157
+ * 永远对不上任何一个 ⇒ 本请求没有可圈禁的身份 ⇒ 不判(下游每一次读人都抛同一只、同一处答 400)。这不是放宽臂:名单里的人永远读得出来。
158
+ */
159
+ export declare function requestConfinedTier(req: IncomingMessage, config: ServiceConfig, power: OperatorPower | undefined): NonPersonTier | undefined;
160
+ /**
161
+ * 设备读点:设备行的属主此刻被不被圈禁。设备车道不经 HTTP(`GET /v1/device/ws` 凭设备密钥对握手,不带任何一枚人的凭据),所以请求读点看不到它;设备行按**属主**绑定,
162
+ * 登记那一刻的属主是验过的人 —— `http/execution-context.ts` 的 `deviceOwnerDomainOf` 是复合身份 `{ tenant, subject }` 的唯一铸点,`subject` 格逐字节取自 `gatedPerson` ——
163
+ * 于是行里存的就是一只持久的属主串,按恢复管线(`recoveredSubject` → `personOf`;与组织信封的发件人同一条)读回那位人,再交同一只判官。设备车道上没有任何路由声明过权力
164
+ * (`power` 缺席):落在非人档的属主在这条车道上整个不算数 —— 它登记的设备不许连上、不许为它执行指令(HTTP 面同一位置已 403)。
165
+ * 读的是名册**现态**(`roster` 每次现读,不拍快照、不把「登记时在哪一档」记在设备行里)。名册只来自 env、起服冻结 ⇒ 进程内连着的设备不会被挪档;挪档后的重启,新进程的每一次 hello 按新名册判。
166
+ */
167
+ export declare function deviceOwnerConfinedTier(owner: {
168
+ readonly subject: string;
169
+ }, roster: OperatorRoster): NonPersonTier | undefined;
170
+ /** 圈禁拒句(一档一句,模块级常量;冻结门按常量解引用逐字钉)。不回显主体名;点名名单所在的 env 与这一档能用的那一条路由。 */
171
+ export declare const PRINCIPAL_CONFINED_DRAIN = "forbidden \u2014 this caller is a drain-only service principal on this deployment (it is named in OPERATOR_DRAIN_PRINCIPALS), and that identity counts only on POST /v1/admin/drain: every other endpoint refuses it; use an identity that is not on that list for anything else";
172
+ /** `403 auth.principal_confined` 的唯一铸点(一档一句,穷举 switch:加一只非人档不接句子 = 编译红)。 */
173
+ export declare function sendPrincipalConfined(res: ServerResponse, tier: NonPersonTier): void;
146
174
  /**
147
175
  * 起服一行:部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` ⇒ `service_token_posture { actsForDeployment: false }`(info);缺省不打。
148
176
  * 声明形让运维面板开位当天成片 401,而「位关了」与「token 错了」在 wire 上同体(反探测律),这一行是起服时唯一一处说清这台部署选了哪一读法的地方。
@@ -154,14 +182,14 @@ export declare function buildServiceTokenPostureNotice(config: Pick<ServiceConfi
154
182
  actsForDeployment: false;
155
183
  };
156
184
  } | undefined;
157
- /** operator 面族在「名单为空」这一形上的**唯一**拒发口:事实 `operatorLane`(`capability-facts.ts`)为假 ⇒ 这一面对任何
158
- * 身份都打不通 = 这台部署上不可用 ⇒ 501,不是鉴权拒(403 只留给「名单非空而你不在名单上」)。能力位读的是同一只事实。 */
159
- export declare function sendOperatorPrincipalsRequired(res: ServerResponse): void;
185
+ /** operator 面族在「持这只权力的名单都空」这一形上的**唯一**拒发口:事实 `operatorLane(d, power)`(`capability-facts.ts`)为假 ⇒ 这一面对任何
186
+ * 身份都打不通 = 这台部署上不可用 ⇒ 501,不是鉴权拒(403 只留给「名单非空而你不在名单上」)。能力位读的是同一只事实。一只权力一句(穷举 switch)。 */
187
+ export declare function sendOperatorPrincipalsRequired(res: ServerResponse, power: OperatorPower): void;
160
188
  /**
161
- * 「这台部署没有运维名册」时**唯一**的出路句 —— 与 {@link operatorRosterPresent} 同一对旋钮,所以句子不比事实少说一条出路:
162
- * 名单 `OPERATOR_PRINCIPALS`(具名运维;多租形只有这一条),或单用户形的显式声明 `OPERATOR_SINGLE_USER=true`(只在 `REQUIRE_PRINCIPAL` 未开且名单为空时成立,
163
- * 否则起服拒 —— 句子把它限定在单用户部署上)。拒发口 {@link sendOperatorPrincipalsRequired}、能力事实闭集 `operator_principals_empty` 的义、记忆整理阀门的起服告警
164
- * 都说这一句,别处不再各写一份。
189
+ * 「这台部署上没有人持这只权力」时**唯一**的出路句 —— 与 {@link operatorRosterPresent} 同一组旋钮(档表里持 `power` 的各档名单 + 单用户声明),所以句子不比事实少说一条出路:
190
+ * 持它的每一档名单(按档表的规范序列出;`operate` 只有 `OPERATOR_PRINCIPALS`,`drain` 另有 `OPERATOR_DRAIN_PRINCIPALS`),或单用户形的显式声明 `OPERATOR_SINGLE_USER=true`
191
+ * (只在 `REQUIRE_PRINCIPAL` 未开且各档名单都空时成立,否则起服拒 —— 句子把它限定在单用户部署上)。拒发口 {@link sendOperatorPrincipalsRequired}、能力事实闭集 `operator_principals_empty` 的义、
192
+ * 记忆整理阀门的起服告警都说这一句,别处不再各写一份。
165
193
  */
166
- export declare function buildOperatorRosterWayOut(): string;
194
+ export declare function buildOperatorRosterWayOut(power: OperatorPower): string;
167
195
  //# sourceMappingURL=principal-gate.d.ts.map
@@ -1,7 +1,9 @@
1
1
  import { timingSafeEqual } from "node:crypto";
2
2
  import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
3
- import { PRINCIPAL_TOKEN_HEADER, verifiedPerson, verifiedSubject, scenarioHeaderOf, scenarioWithoutPrincipalError, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope } from "../security.js";
3
+ import { HttpError, PRINCIPAL_TOKEN_HEADER, verifiedPerson, verifiedSubject, scenarioHeaderOf, scenarioWithoutPrincipalError, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope } from "../security.js";
4
+ import { ROSTER_TIERS, ROSTER_TIER_ORDER, rosterHasNonPersonNames, rosterNamesOf, rosterTierOf, tierHolds, tierIsPerson } from "../operator-roster.js";
4
5
  import { personOf } from "../owner-brands.js";
6
+ import { recoveredSubject } from "../owner-faces.js";
5
7
  import { IDENTITY_SOURCES, runIdentityClaimOverflow } from "../identity-source.js";
6
8
  import { sendError } from "./send.js";
7
9
  import { canonicalAddress } from "../net-address.js";
@@ -159,23 +161,71 @@ export function actsForDeployment(req, config, subject) {
159
161
  export function serviceTokenDeclaredActsForDeployment(config) {
160
162
  return config.serviceTokenActsForDeployment === true;
161
163
  }
162
- export function explicitOperatorOk(person, roster) {
163
- if (roster.operatorSingleUser === true)
164
- return true;
165
- return roster.operatorPrincipals.length > 0 && person !== undefined && roster.operatorPrincipals.includes(person);
164
+ export function explicitOperatorOk(person, roster, power) {
165
+ const tier = rosterTierOf(person, roster);
166
+ return tier !== undefined && tierHolds(tier, power);
166
167
  }
167
- export function operatorRosterPresent(roster) {
168
- return roster.operatorSingleUser === true || roster.operatorPrincipals.length > 0;
168
+ export function operatorRosterPresent(roster, power) {
169
+ return roster.operatorSingleUser === true || ROSTER_TIER_ORDER.some((tier) => tierHolds(tier, power) && rosterNamesOf(tier, roster).length > 0);
170
+ }
171
+ export function confinedTierOf(person, roster, power) {
172
+ const tier = rosterTierOf(person, roster);
173
+ if (tier === undefined || tierIsPerson(tier))
174
+ return undefined;
175
+ if (power !== undefined && tierHolds(tier, power))
176
+ return undefined;
177
+ return tier;
178
+ }
179
+ export function requestConfinedTier(req, config, power) {
180
+ if (!rosterHasNonPersonNames(config))
181
+ return undefined;
182
+ let person;
183
+ try {
184
+ person = verifiedPerson(req, config);
185
+ }
186
+ catch (e) {
187
+ if (e instanceof HttpError)
188
+ return undefined;
189
+ throw e;
190
+ }
191
+ return confinedTierOf(person, config, power);
192
+ }
193
+ export function deviceOwnerConfinedTier(owner, roster) {
194
+ return confinedTierOf(personOf(recoveredSubject(owner.subject)), roster, undefined);
195
+ }
196
+ export const PRINCIPAL_CONFINED_DRAIN = "forbidden — this caller is a drain-only service principal on this deployment (it is named in OPERATOR_DRAIN_PRINCIPALS), and that identity counts only on POST /v1/admin/drain: every other endpoint refuses it; use an identity that is not on that list for anything else";
197
+ export function sendPrincipalConfined(res, tier) {
198
+ switch (tier) {
199
+ case "drain":
200
+ sendError(res, 403, "auth.principal_confined", PRINCIPAL_CONFINED_DRAIN);
201
+ return;
202
+ default: {
203
+ const unknownTier = tier;
204
+ throw new Error(`sendPrincipalConfined: unknown confined tier ${String(unknownTier)}`);
205
+ }
206
+ }
169
207
  }
170
208
  export function buildServiceTokenPostureNotice(config) {
171
209
  if (serviceTokenDeclaredActsForDeployment(config))
172
210
  return undefined;
173
211
  return { event: "service_token_posture", fields: { actsForDeployment: false } };
174
212
  }
175
- export function sendOperatorPrincipalsRequired(res) {
176
- sendError(res, 501, "capability.operator_principals_required", `this endpoint is operator-only and this deployment has no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can be an operator; ${buildOperatorRosterWayOut()}`);
213
+ export function sendOperatorPrincipalsRequired(res, power) {
214
+ switch (power) {
215
+ case "operate":
216
+ sendError(res, 501, "capability.operator_principals_required", `this endpoint is operator-only and this deployment has no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can be an operator; ${buildOperatorRosterWayOut(power)}`);
217
+ return;
218
+ case "drain":
219
+ sendError(res, 501, "capability.operator_principals_required", `this endpoint is open to this deployment's operators and its drain-only service principals, and it names neither (OPERATOR_PRINCIPALS and OPERATOR_DRAIN_PRINCIPALS are empty and OPERATOR_SINGLE_USER is not declared), so no caller can call it; ${buildOperatorRosterWayOut(power)}`);
220
+ return;
221
+ default: {
222
+ const unknownPower = power;
223
+ throw new Error(`sendOperatorPrincipalsRequired: unknown power ${String(unknownPower)}`);
224
+ }
225
+ }
177
226
  }
178
- export function buildOperatorRosterWayOut() {
179
- return "configure OPERATOR_PRINCIPALS with the named operator principals, or — on a single-user deployment (REQUIRE_PRINCIPAL off) — declare OPERATOR_SINGLE_USER=true";
227
+ export function buildOperatorRosterWayOut(power) {
228
+ const rosters = ROSTER_TIER_ORDER.filter((tier) => tierHolds(tier, power)).map((tier) => `${ROSTER_TIERS[tier].env} with the named ${ROSTER_TIERS[tier].holders}`);
229
+ return `configure ${rosters.join(" or ")}, or — on a single-user deployment (REQUIRE_PRINCIPAL off) — declare OPERATOR_SINGLE_USER=true`;
180
230
  }
181
231
  //# sourceMappingURL=principal-gate.js.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * **通道事实**(纯叶,只依赖 `node:http` 的型):一条请求从本服务的哪一只监听口进来。
3
+ *
4
+ * ## 律(一条)
5
+ * 闭集 {@link REQUEST_CHANNELS} = `tcp`(TCP 监听口)· `control-socket`(本机控制 socket,`control-socket.ts`)。
6
+ * 唯一写者 = 控制 socket 那只 `http.Server` 的请求监听器({@link markControlSocketRequest},`http/server.ts` 里恰一处调用);唯一读法 = {@link requestChannelOf}。
7
+ * **缺标 ⇒ `tcp`**(fail-closed):没被那只监听器标过的请求一律按 TCP 读。不按 `req.socket.remoteAddress` 缺席反推 —— TCP 连接断开之后它同样缺席,反推形是 fail-open。
8
+ *
9
+ * ## 通道换来什么(不换来什么)
10
+ * 控制 socket 证明的是「对端是引擎的 OS 用户(或 root)」—— 能穿过私有目录的只有他们。宿主车道上模型跑的命令也是这个用户,所以**通道不是凭据**:
11
+ * 它不进读路谓词(`dispatch.ts` 的 `readCredentialOk`)、不进全局凭据门、不进身份来源闭集(`identity-source.ts` 的 `IDENTITY_SOURCES`);
12
+ * 它只换来 `/health` 的读者档 `engine-user`(引擎自描述的全键,`health-reader.ts`)、诊断面远程来源门的「本机」一读、限流的地址回落键。
13
+ * 读它的每一处都**穷举**本闭集(`switch` + `never`),没有一处写「等于某一词」的比较 —— 加一种通道不接 ⇒ 编译红,而不是默认得到某一档。
14
+ */
15
+ import type { IncomingMessage } from "node:http";
16
+ /** 请求通道的闭集(顺序无语义)。 */
17
+ export declare const REQUEST_CHANNELS: readonly ["tcp", "control-socket"];
18
+ export type RequestChannel = (typeof REQUEST_CHANNELS)[number];
19
+ /** **唯一写者**:控制 socket 那只 `http.Server` 的请求监听器在把请求交给共享监听器之前调一次。别处调用 = 把 TCP 请求读成本机用户(源码门钉调用点恰一处)。 */
20
+ export declare function markControlSocketRequest(req: IncomingMessage): void;
21
+ /** 这条请求从哪一只监听口进来 —— 唯一读法;缺标 ⇒ `tcp`。 */
22
+ export declare function requestChannelOf(req: IncomingMessage): RequestChannel;
23
+ //# sourceMappingURL=request-channel.d.ts.map
@@ -0,0 +1,9 @@
1
+ export const REQUEST_CHANNELS = ["tcp", "control-socket"];
2
+ const controlSocketRequests = new WeakSet();
3
+ export function markControlSocketRequest(req) {
4
+ controlSocketRequests.add(req);
5
+ }
6
+ export function requestChannelOf(req) {
7
+ return controlSocketRequests.has(req) ? "control-socket" : "tcp";
8
+ }
9
+ //# sourceMappingURL=request-channel.js.map
@@ -9,6 +9,7 @@ import { escapedStatementBytes, packetWallStatementBytes, rowWallPayloadBytes }
9
9
  import { MAX_JSON_BODY_BYTES } from "../json-body-limit.js";
10
10
  import { deliverVia } from "../submission-exit.js";
11
11
  import { canonicalAddress } from "../net-address.js";
12
+ import { requestChannelOf } from "./request-channel.js";
12
13
  export function refuseSubmitBody(walls, body) {
13
14
  const rowWall = walls.maxRowBytes;
14
15
  const packetWall = walls.maxPacketBytes;
@@ -171,8 +172,7 @@ export function createRequestGuards(ctx) {
171
172
  function rateLimited(req, res) {
172
173
  if (!deps.rateLimiter)
173
174
  return false;
174
- const peer = req.socket.remoteAddress;
175
- const key = (deps.config.directDoorActive ? undefined : principalFrom(req, deps.config)) ?? (peer === undefined ? "anon" : (canonicalAddress(peer) ?? peer));
175
+ const key = (deps.config.directDoorActive ? undefined : principalFrom(req, deps.config)) ?? rateLimitAddressKeyOf(req);
176
176
  const d = deps.rateLimiter.check(key);
177
177
  if (d.allowed)
178
178
  return false;
@@ -220,4 +220,19 @@ export function createRequestGuards(ctx) {
220
220
  }
221
221
  return { quotaExceeded, ownerCostQuotaDenied, ownerFleetLeaseDenied, ownerLeaseDenied, ownerQuotaDenied, leaseDenied, usageWindowDenialFor, usageWindowDenied, rateLimited, safeDecode, readJson, readRawBody };
222
222
  }
223
+ function rateLimitAddressKeyOf(req) {
224
+ const channel = requestChannelOf(req);
225
+ switch (channel) {
226
+ case "tcp": {
227
+ const peer = req.socket.remoteAddress;
228
+ return peer === undefined ? "anon" : (canonicalAddress(peer) ?? peer);
229
+ }
230
+ case "control-socket":
231
+ return "control-socket";
232
+ default: {
233
+ const unknownChannel = channel;
234
+ throw new Error(`rate limit: request channel ${String(unknownChannel)} has no address key`);
235
+ }
236
+ }
237
+ }
223
238
  //# sourceMappingURL=request-guards.js.map
@@ -2,6 +2,8 @@ import { openCheckpointCtx } from "./checkpoint-ctx.js";
2
2
  import { storeFaultClassOf } from "../plugins/store-fault.js";
3
3
  import { refusalBody } from "./refusal-body.js";
4
4
  import { frozenProjectContextOf } from "../project-context.js";
5
+ import { frozenMemorySeedOf } from "../project-registry.js";
6
+ import { permissionModeWriteOf } from "../permission-mode-admission.js";
5
7
  export async function readResumeCtx(load, opening) {
6
8
  const read = await readStoredCtx(load);
7
9
  if (read.kind !== "ok")
@@ -9,19 +11,56 @@ export async function readResumeCtx(load, opening) {
9
11
  const opened = openCheckpointCtx(read.ctx, opening.opener, opening.sessionId);
10
12
  if (opened.kind !== "ok")
11
13
  return { kind: "unsealable", field: opened.field, reason: opened.reason };
14
+ const where = (key) => ({ kind: "corrupt", where: `checkpoint ctx for session ${JSON.stringify(opening.sessionId)}: ${key}` });
15
+ const { memorySeed: _storedSeed, projectContext: _storedContext, permissionModeWrite: _storedWrite, ...rest } = opened.ctx;
16
+ const seed = frozenMemorySeedOf(opened.ctx.memorySeed);
12
17
  const frozen = frozenProjectContextOf(opened.ctx.projectContext);
18
+ const written = permissionModeWriteOf(opened.ctx.permissionModeWrite);
19
+ let seedPart;
20
+ switch (seed.kind) {
21
+ case "absent":
22
+ seedPart = {};
23
+ break;
24
+ case "none":
25
+ seedPart = { memorySeed: null };
26
+ break;
27
+ case "malformed":
28
+ return where("memorySeed");
29
+ case "ok":
30
+ seedPart = { memorySeed: seed.seed };
31
+ break;
32
+ default: {
33
+ const unhandled = seed;
34
+ throw new Error(`resume-ctx-read: unplaced frozen memory seed reading ${JSON.stringify(unhandled)}`);
35
+ }
36
+ }
37
+ let contextPart;
13
38
  switch (frozen.kind) {
14
39
  case "absent":
15
- return { kind: "ok", ctx: opened.ctx };
40
+ contextPart = {};
41
+ break;
16
42
  case "malformed":
17
- return { kind: "corrupt", where: `checkpoint ctx for session ${JSON.stringify(opening.sessionId)}: projectContext` };
43
+ return where("projectContext");
18
44
  case "ok":
19
- return { kind: "ok", ctx: { ...opened.ctx, projectContext: frozen.context } };
45
+ contextPart = { projectContext: frozen.context };
46
+ break;
20
47
  default: {
21
48
  const unhandled = frozen;
22
49
  throw new Error(`resume-ctx-read: unplaced frozen project context reading ${JSON.stringify(unhandled)}`);
23
50
  }
24
51
  }
52
+ switch (written.kind) {
53
+ case "absent":
54
+ return { kind: "ok", ctx: { ...rest, ...seedPart, ...contextPart } };
55
+ case "malformed":
56
+ return where("permissionModeWrite");
57
+ case "ok":
58
+ return { kind: "ok", ctx: { ...rest, ...seedPart, ...contextPart, permissionModeWrite: written.write } };
59
+ default: {
60
+ const unhandled = written;
61
+ throw new Error(`resume-ctx-read: unplaced permission-mode write reading ${JSON.stringify(unhandled)}`);
62
+ }
63
+ }
25
64
  }
26
65
  async function readStoredCtx(load) {
27
66
  let stored;
@@ -21,7 +21,7 @@ import type { HostDecision } from "../host-decision.js";
21
21
  import { type GateSighting } from "../approval-gate-currency.js";
22
22
  import { type CancelRunReader } from "../run-cancel-card.js";
23
23
  import { type PlanApprovePermissionModeAfter } from "../task-settings.js";
24
- import type { RouteCtxBase, DriveResumeArgs, PreparedPlanReview, RememberSessionRequest, ResumeCheckpointOutcome, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
24
+ import type { RouteCtxBase, DriveResumeArgs, PersistRuleRequest, PreparedPlanReview, RememberSessionRequest, ResumeCheckpointOutcome, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
25
25
  import type { RunRegistry, RouteHelpers, RouteLegs } from "./route-ctx.js";
26
26
  import type { createRequestGuards } from "./request-guards.js";
27
27
  import type { FlatServiceDeps } from "./server.js";
@@ -121,7 +121,7 @@ export declare function createResumeLegs(ctx: {
121
121
  runnerFor: FlatServiceDeps["runnerFor"];
122
122
  } & RunRegistry & RouteHelpers & Pick<RouteLegs, "prepareSpec" | "finalizeTaskResult"> & Pick<ReturnType<typeof createRequestGuards>, "ownerCostQuotaDenied" | "ownerFleetLeaseDenied" | "usageWindowDenialFor">): {
123
123
  routeCtxBase: RouteCtxBase;
124
- resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding, remember?: RememberSessionRequest, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement) => Promise<ResumeCheckpointOutcome>;
124
+ resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding, remember?: RememberSessionRequest, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement, persistRule?: PersistRuleRequest) => Promise<ResumeCheckpointOutcome>;
125
125
  driveResumeIntoRunLog: (args: DriveResumeArgs) => Promise<ResumeLegOutcome>;
126
126
  driveResumeLeg: (args: DriveResumeArgs, onAccepted?: (receipt: {
127
127
  status: number;
@@ -129,7 +129,7 @@ export declare function createResumeLegs(ctx: {
129
129
  }) => void) => Promise<ResumeLegOutcome>;
130
130
  decisionRowAdmits: (cs: CheckpointStoreFull, token: CheckpointToken, who: KeyCaller | undefined, bodyScope: string | undefined) => Promise<boolean>;
131
131
  resumePreempted: (sessionId: string, req: IncomingMessage | undefined, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
132
- startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
132
+ startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage | undefined, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
133
133
  resumeWake: (sessionId: string, message: PendingSteerInput | undefined, caller: Subject | undefined, req: IncomingMessage | undefined, acceptEarly?: boolean, workflowDecision?: WorkflowDecisionDelivery, ownerLeaseAdmittedFor?: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
134
134
  preparePlanReview: (sessionId: string, log?: {
135
135
  taskId?: string;
@@ -146,6 +146,7 @@ export declare function createResumeLegs(ctx: {
146
146
  }>;
147
147
  drivePlanReview: (prepared: PreparedPlanReview, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, acceptEarly?: boolean, permissionModeAfter?: PlanApprovePermissionModeAfter) => Promise<ResumeLegOutcome>;
148
148
  sessionNotifyDoor: import("../session-notify-door.js").SessionNotifyDoor;
149
+ handOverRunEndedDecisions: (runId: string) => Promise<void>;
149
150
  };
150
151
  export {};
151
152
  //# sourceMappingURL=resume-legs.d.ts.map