@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
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 审批扫腿([ref] 切片:`http/server.ts` 5196–5488 逐字搬家,正文一字未改)——两条不经 HTTP 路由的赎回口:
3
3
  * ①`denyExpiredApprovals`([ref] D-D,SLA 到期的 deny-sweep,main.ts 的 reaper 按拍调);
4
- * ②`redeemParkedAsk`([ref],live 回决腿的 PARKED 赎回席,装配层接进协调器的晚绑座)。
4
+ * ②`redeemParkedAsk`([ref],决断口停驻臂的 PARKED 赎回席,装配层接进协调器的晚绑座)。
5
5
  * 两者都走 resume 家族的 `resumeCheckpoint`,所以它们的属主是「谁在无 HTTP 请求的情况下替人做决定」这件事,
6
6
  * 不是请求流水线。`createWallClockJumpGuard` 建的 `denySweepClockGuard` 是 ① 的私有件,随它同居。
7
7
  * ctx 字段 3 只(`deps` / `resumeCheckpoint` / `decisionRowAdmits`),机器算(closure-free-vars)与手抄一致。
@@ -7,8 +7,8 @@ import { hostDecisionFacts } from "../host-decision.js";
7
7
  import {} from "../tool-approval.js";
8
8
  import { APPROVAL_GATE_KINDS } from "../approval-content-kind.js";
9
9
  import { createWallClockJumpGuard } from "../wall-clock-jump-guard.js";
10
- import { gatedPerson } from "./principal-gate.js";
11
- import { hasServiceAuth } from "../identity-source.js";
10
+ import { gatedPerson, verifiedIdentitySource } from "./principal-gate.js";
11
+ import { passesCredentialGate } from "../identity-source.js";
12
12
  import { costQuotaRefusalOf } from "./request-guards.js";
13
13
  import { admissionRefusalOf, readinessOf } from "./readiness.js";
14
14
  import { memberLeaseOf } from "../fleet/engine-signal.js";
@@ -19,6 +19,7 @@ import { storedBodyReplayRefusal } from "./stored-body-replay.js";
19
19
  import { refusalBody } from "./refusal-body.js";
20
20
  import { CARD_EXPIRE_OUTCOME, expireCardUnderStoredScope } from "../card-settle-stored-scope.js";
21
21
  import { DENY_SWEEP_PAGE_ROWS } from "../plugins/checkpoint-store-face.js";
22
+ import { ruleReceiptOf } from "./route-ctx.js";
22
23
  const BLOCKED_SCALAR_KEYS = ["errorCode", "blockedBy", "field", "reason", "count", "cap", "index"];
23
24
  function blockedScalars(body) {
24
25
  const out = {};
@@ -216,8 +217,8 @@ export function createApprovalSweeps(ctx) {
216
217
  if (!cs) {
217
218
  return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
218
219
  }
219
- if (!hasServiceAuth(deps.config) && !deps.config.allowUnauthedWrites) {
220
- return { status: 503, body: refusalBody({ errorCode: "auth.service_token_required", message: "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting task submissions" }) };
220
+ if (!passesCredentialGate(req.httpReq === undefined ? undefined : verifiedIdentitySource(req.httpReq, deps.config)) && !deps.config.allowUnauthedWrites) {
221
+ return { status: 503, body: refusalBody({ errorCode: "auth.service_token_required", message: "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting task submissions" }) };
221
222
  }
222
223
  const refusal = admissionRefusalOf(readinessOf(deps), memberLeaseOf(deps), "hitl-answer");
223
224
  if (refusal !== undefined)
@@ -232,7 +233,7 @@ export function createApprovalSweeps(ctx) {
232
233
  }
233
234
  }
234
235
  }
235
- const answerer = { subject: recoveredSubject(req.principal), operator: false };
236
+ const answerer = { subject: recoveredSubject(req.principal), operator: req.operator };
236
237
  let cp;
237
238
  try {
238
239
  cp = await cs.get(req.gateToken);
@@ -258,8 +259,10 @@ export function createApprovalSweeps(ctx) {
258
259
  ...(req.updatedInput !== undefined ? { updatedInput: req.updatedInput } : {}),
259
260
  };
260
261
  const remember = req.remember === "session" ? { grantedBy: req.principal ?? null, laneCannotRecord: "decide_once" } : undefined;
261
- const out = await resumeCheckpoint(cp.sessionId, req.decision, req.note, hostDecisionFacts(req.decider, req.principal), req.httpReq, undefined, binding, remember, true, answerer);
262
- return { status: out.status, body: out.body, ...(remember !== undefined ? { rememberApplied: out.rememberApplied === true } : {}), gateGeneration: checkpointRevOf(cp) };
262
+ const persistRule = req.persistRule !== undefined ? { slot: req.persistRule, inputWasEdited: req.updatedInput !== undefined } : undefined;
263
+ const out = await resumeCheckpoint(cp.sessionId, req.decision, req.note, hostDecisionFacts(req.decider, req.principal), req.httpReq, undefined, binding, remember, true, answerer, undefined, persistRule);
264
+ const rule = out.status >= 200 && out.status < 300 ? ruleReceiptOf(out, persistRule) : undefined;
265
+ return { status: out.status, body: out.body, ...(remember !== undefined ? { rememberApplied: out.rememberApplied === true } : {}), ...(rule !== undefined ? { rule } : {}) };
263
266
  }
264
267
  return { denyExpiredApprovals, redeemParkedAsk };
265
268
  }
@@ -43,6 +43,8 @@
43
43
  import type { CheckpointCtx } from "./route-ctx.js";
44
44
  import type { TaskRequestBody } from "./wire-types.js";
45
45
  import type { ProjectContext } from "../project-context.js";
46
+ import type { MemorySeed } from "../project-registry.js";
47
+ import type { PermissionModeWrite } from "../permission-mode-admission.js";
46
48
  import type { InertToolListEntry } from "../rule-entry-list.js";
47
49
  import { type Refusal } from "./refusal-body.js";
48
50
  /** allow 层读法从这一版起(7.117.0):此前的写者对 `settings.permissions.allow` 是另一种读法(≤7.114.x 名单 / 7.115.0–7.116.x 表态)。规则见顶注「allow 读法问」。 */
@@ -79,7 +81,9 @@ export declare function buildCheckpointCtx(fields: {
79
81
  unattendedLeg?: true;
80
82
  promptScreened?: true;
81
83
  projectContext?: ProjectContext | undefined;
84
+ memorySeed?: MemorySeed | null | undefined;
82
85
  writerVersion: string;
86
+ permissionModeWrite: PermissionModeWrite | undefined;
83
87
  }, sealer: CheckpointCtxSealer | undefined, sessionId: string): SealedCheckpointCtx;
84
88
  /**
85
89
  * 退役请求键问:**退役的请求键**闭集 = 两张处置表之并(新提交在键闭集门 400;存体里还带着它 = 这份体是更早的写者写下的)。键住在哪张表就是它的处置格,规则全文见头注「退役请求键问」。
@@ -44,6 +44,8 @@ export function buildCheckpointCtx(fields, sealer, sessionId) {
44
44
  ...(fields.unattendedLeg === true ? { unattendedLeg: true } : {}),
45
45
  ...(fields.promptScreened === true ? { promptScreened: true } : {}),
46
46
  ...(fields.projectContext !== undefined ? { projectContext: fields.projectContext } : {}),
47
+ ...(fields.memorySeed !== undefined ? { memorySeed: fields.memorySeed } : {}),
48
+ ...(fields.permissionModeWrite !== undefined ? { permissionModeWrite: fields.permissionModeWrite } : {}),
47
49
  };
48
50
  return sealCheckpointCtx(ctx, sealer, sessionId);
49
51
  }
@@ -33,7 +33,8 @@ export interface HealthDeploymentModsSection {
33
33
  * 配了 service token、没开 REQUIRE_PRINCIPAL 的部署上,`POST /v1/tasks` 吃凭据,这三族读路对端口全开。
34
34
  *
35
35
  * 规则(一条,三族同读;fail-closed):
36
- * · 部署**没配**任何 service 凭据(`hasServiceAuth` 假)⇒ 放行 —— 与全局门对 `/v1/tasks` 同判(run-local 形);
36
+ * · 部署**没配**任何 service 凭据(`hasServiceAuth` 假)⇒ 放行 —— 问的是「全局凭据门武装没有」,与门后各口同判(门不武装 ⇒ 门后的读口也不要凭据;
37
+ * 写门是另一问,问的是请求,见 `identity-source.ts` 头注律 5);
37
38
  * · 否则要么出示了**服务凭据**(service token 单 / 多,或只读 `TRACE_TOKEN` —— 后者正是这几族在门前的理由),
38
39
  * 要么带着**验过的** principal(registry 登录令牌 / direct-door 签名 principal 令牌;判据 = `verifiedIdentitySource`,
39
40
  * 与 off-box operator 读面同一只)。调用方自己写的 principal 头不是凭据。
@@ -42,9 +43,13 @@ export interface HealthDeploymentModsSection {
42
43
  */
43
44
  export declare function readCredentialOk(req: IncomingMessage, config: ServiceConfig): boolean;
44
45
  /**
45
- * `GET /health` 这次请求的**读者档**(`health-reader.ts` 头注:三档与每档拿什么)—— 读的是上面那一只读路谓词,不另立第二份「凭据」读法:
46
- * 没配服务凭据 ⇒ `open`(谓词的第一臂);配了而谓词认 ⇒ `credentialed`;配了而谓词不认 ⇒ `anonymous`。
46
+ * `GET /health` 这次请求的**读者档**(`health-reader.ts` 头注:四档与每档拿什么)—— 唯一判官。读的是上面那一只读路谓词与请求的通道事实(`request-channel.ts`),不另立第二份「凭据」读法:
47
+ * 没配服务凭据 ⇒ `open`(谓词的第一臂);配了而谓词认 ⇒ `credentialed`;配了而谓词不认 ⇒ 按通道穷举:经本机控制 socket ⇒ `engine-user`,经 TCP ⇒ `anonymous`
48
+ * (TCP 对端地址不读 —— 没有回环档)。`credentialed` 先于 `engine-user`:经 socket 带了凭据的读者归凭据档(两档投影相同,先后只影响「它证明了什么」)。
49
+ * 通道一臂只在这一面换档:读路谓词、全局凭据门与身份来源闭集都不读通道(通道不是凭据)。
47
50
  * 调用点必须在鉴权桥预认证**之后**(已验登录令牌是谓词的一臂,读的是预认证挂上的身份)。
51
+ * **圈禁的身份不算读路凭据**(名册的非人档;`/health` 不声明权力,判官 `requestConfinedTier`):这次请求只按它出示的 service / trace 凭据分档 ——
52
+ * 与别的空间的登录令牌([ref])同一读法:探针面从不拒,身份不算,读者按没出示凭据分档(没出示 ⇒ 照上面按通道穷举:经本机控制 socket 仍是 `engine-user`,通道不是凭据、圈禁也不改它)。
48
53
  */
49
54
  export declare function healthReaderOf(req: IncomingMessage, config: ServiceConfig): HealthReader;
50
55
  export declare function createDispatch(ctx: {
@@ -4,19 +4,21 @@ import { partsOf } from "../owner-brands.js";
4
4
  import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
5
5
  import { publicStoreProbeError } from "../store-live-probe.js";
6
6
  import { looksLikeJwt } from "@sema-agent/settings-schema/api/auth-bridge";
7
- import { admitBridgeIdentity } from "../auth-bridge.js";
7
+ import { admitBridgeIdentity, ssoForeignScope } from "../auth-bridge.js";
8
8
  import { ROUTE_METHOD_ORDER } from "./route-ctx.js";
9
- import { READ_CREDENTIAL_ROUTES, PUBLIC_ROUTES, POST_CREDENTIAL_ROUTES, routeLabel, isBillableSubmitPath, billableKindOf, isCredentialGatedRewrite, isMethodDispatchedSubmitPath, lookupRoute, isProbePath, isSubscriptionRequest } from "./route-table.js";
9
+ import { READ_CREDENTIAL_ROUTES, PUBLIC_ROUTES, POST_CREDENTIAL_ROUTES, routeLabel, isBillableSubmitPath, billableKindOf, isCredentialGatedRewrite, isMethodDispatchedSubmitPath, lookupRoute, isProbePath, isSubscriptionRequest, declaredPowerOf } from "./route-table.js";
10
10
  import { sendJson, sendError, sendHttpError, isSseResponse, endSseWithError } from "./send.js";
11
11
  import { admissionRefusalOf, readinessOf, healthReadinessKeys, sendReadyz, sendBillableRefusal, billableRefusalOf, billableRefusalFrame } from "./readiness.js";
12
- import { ENGINE_SIGNAL_KEY, buildEngineSignal, fleetMembershipKeys, healthConfigLedgerKeys, healthDrainingKeys, memberLeaseOf, mintEngineSignal, restartActionable } from "../fleet/engine-signal.js";
12
+ import { ENGINE_SIGNAL_KEY } from "@sema-agent/settings-schema/fleet";
13
+ import { buildEngineSignal, fleetMembershipKeys, healthConfigLedgerKeys, memberLeaseOf, mintEngineSignal, restartActionable } from "../fleet/engine-signal.js";
13
14
  import { buildHealthSelfReport } from "./health-self-report.js";
14
15
  import { projectHealthBody } from "./health-reader.js";
16
+ import { requestChannelOf } from "./request-channel.js";
15
17
  import { projectHealthStoreSection, unwiredStorePosture } from "../store-posture.js";
16
18
  import { autoBackgroundOnTimeout as autoBackgroundOnTimeoutFact, autoBackgroundOnTimeoutWord, deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
17
19
  import { hostBackgroundShellEnabled } from "../config.js";
18
- import { actsForDeployment, admitRunIdentity, authorized, bearerPresentedButUnverified, devOpenDeployment, systemFor, gatedSubject, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource } from "./principal-gate.js";
19
- import { hasServiceAuth } from "../identity-source.js";
20
+ import { actsForDeployment, admitRunIdentity, authorized, bearerPresentedButUnverified, devOpenDeployment, requestConfinedTier, systemFor, gatedSubject, sendPrincipalConfined, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource } from "./principal-gate.js";
21
+ import { hasServiceAuth, passesCredentialGate } from "../identity-source.js";
20
22
  import { inflightTotal } from "../fleet/drain-entry.js";
21
23
  const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
22
24
  export function readCredentialOk(req, config) {
@@ -29,7 +31,33 @@ export function readCredentialOk(req, config) {
29
31
  export function healthReaderOf(req, config) {
30
32
  if (!hasServiceAuth(config))
31
33
  return "open";
32
- return readCredentialOk(req, config) ? "credentialed" : "anonymous";
34
+ const confined = requestConfinedTier(req, config, declaredPowerOf("GET", "/health")) !== undefined;
35
+ const credentialed = confined ? systemFor(req, config) !== undefined || traceTokenPresented(req, config) : readCredentialOk(req, config);
36
+ if (credentialed)
37
+ return "credentialed";
38
+ const channel = requestChannelOf(req);
39
+ switch (channel) {
40
+ case "control-socket":
41
+ return "engine-user";
42
+ case "tcp":
43
+ return "anonymous";
44
+ default: {
45
+ const unknownChannel = channel;
46
+ throw new Error(`health reader: request channel ${String(unknownChannel)} has no reader tier`);
47
+ }
48
+ }
49
+ }
50
+ function credentialAttribution(req, credential, config) {
51
+ switch (credential) {
52
+ case "service_token":
53
+ return systemFor(req, config) ?? null;
54
+ case "sso":
55
+ return "sso";
56
+ default: {
57
+ const unknownCredential = credential;
58
+ throw new Error(`credential gate: credential ${String(unknownCredential)} has no attribution`);
59
+ }
60
+ }
33
61
  }
34
62
  function cors(res, req, origins, principalHeader) {
35
63
  if (!origins || origins.length === 0)
@@ -120,6 +148,11 @@ export function createDispatch(ctx) {
120
148
  const rawBearer = /^Bearer\s/i.test(authz) ? authz.replace(/^Bearer\s+/i, "") : "";
121
149
  if (rawBearer && looksLikeJwt(rawBearer)) {
122
150
  const identity = admitBridgeIdentity(await deps.webAdminJwtVerifier.verify(rawBearer), { logger: deps.logger, metrics: deps.metrics });
151
+ const foreign = identity === undefined ? undefined : ssoForeignScope(identity, deps.config);
152
+ if (identity !== undefined && foreign !== undefined) {
153
+ deps.logger?.warn?.("auth_bridge_scope_refused", { principal: identity.principal, tokenScope: foreign.tokenScope, boundScope: foreign.boundScope });
154
+ return systemFor(req, deps.config) === undefined ? "foreign_scope" : undefined;
155
+ }
123
156
  if (identity) {
124
157
  setSsoPrincipal(req, identity.principal);
125
158
  req.headers[deps.config.principalHeader.toLowerCase()] = identity.principal;
@@ -132,6 +165,7 @@ export function createDispatch(ctx) {
132
165
  }
133
166
  }
134
167
  }
168
+ return undefined;
135
169
  }
136
170
  async function handle(req, res) {
137
171
  const startedAt = Date.now();
@@ -193,7 +227,6 @@ export function createDispatch(ctx) {
193
227
  const fullBody = {
194
228
  status: "ok",
195
229
  ...(typeof deps.capabilities?.version === "string" ? { version: deps.capabilities.version } : {}),
196
- ...healthDrainingKeys(signal),
197
230
  ...(() => {
198
231
  const breakdown = deps.drainState?.inflightBreakdown?.();
199
232
  return breakdown ? { inflight: inflightTotal(breakdown), inflightBreakdown: breakdown } : {};
@@ -209,6 +242,7 @@ export function createDispatch(ctx) {
209
242
  lingerMs: lease.lingerMs,
210
243
  tickMs: lease.tickMs,
211
244
  lane: lease.lane,
245
+ attached: lease.attached,
212
246
  ...(fa ? { firstAttach: { windowMs: fa.windowMs, since: fa.since, attachedAt: fa.attachedAt } } : {}),
213
247
  ...(ho ? { handover: { since: ho.since, reason: ho.reason, lingerMs: ho.lingerMs, backgroundShells: ho.backgroundShells } } : {}),
214
248
  },
@@ -294,39 +328,32 @@ export function createDispatch(ctx) {
294
328
  res.end(deps.metrics.render());
295
329
  return;
296
330
  }
297
- await attachBridgeIdentity(req);
331
+ if ((await attachBridgeIdentity(req)) === "foreign_scope") {
332
+ sendError(res, 403, "auth.scope_mismatch", "forbidden — the sign-in token was issued for a different scope than the one this worker serves: send a sign-in token issued for this worker's scope, or send this request to a worker of your token's scope");
333
+ return;
334
+ }
335
+ const confined = requestConfinedTier(req, deps.config, declaredPowerOf(method, url));
336
+ if (confined !== undefined) {
337
+ sendPrincipalConfined(res, confined);
338
+ return;
339
+ }
298
340
  if (await dispatchSegment(READ_CREDENTIAL_ROUTES, req, res, url, search, method, allow.pre, ctx, (r) => readCredentialOk(r, deps.config)))
299
341
  return;
300
342
  if (await dispatchSegment(PUBLIC_ROUTES, req, res, url, search, method, allow.pre, ctx, undefined, false))
301
343
  return;
302
344
  const identitySource = verifiedIdentitySource(req, deps.config);
303
345
  admitRunIdentity(req, identitySource, deps.logger);
304
- let source = null;
305
- const anyServiceAuth = hasServiceAuth(deps.config);
306
- if (anyServiceAuth) {
307
- switch (identitySource) {
308
- case "service_token":
309
- source = systemFor(req, deps.config) ?? null;
310
- break;
311
- case "sso":
312
- source = "sso";
313
- break;
314
- case "direct_door_jwt":
315
- case undefined:
316
- sendUnauthorized(res, "credential");
317
- return;
318
- default: {
319
- const unknownSource = identitySource;
320
- throw new Error(`credential gate: identity source ${String(unknownSource)} has no gate row`);
321
- }
322
- }
346
+ const credential = passesCredentialGate(identitySource) ? identitySource : undefined;
347
+ if (credential === undefined && hasServiceAuth(deps.config)) {
348
+ sendUnauthorized(res, "credential");
349
+ return;
323
350
  }
324
- reqState.source = source;
325
- if (!anyServiceAuth &&
351
+ reqState.source = credential === undefined ? null : credentialAttribution(req, credential, deps.config);
352
+ if (credential === undefined &&
326
353
  !deps.config.allowUnauthedWrites &&
327
354
  ((req.method === "POST" && (isBillableSubmitPath(url) || url.startsWith("/v1/images/bakes"))) ||
328
355
  isCredentialGatedRewrite(req.method ?? "", url))) {
329
- sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting task submissions");
356
+ sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting task submissions");
330
357
  return;
331
358
  }
332
359
  const billableKind = req.method === "POST" && !isMethodDispatchedSubmitPath(url) ? billableKindOf(url) : undefined;
@@ -337,8 +364,8 @@ export function createDispatch(ctx) {
337
364
  return;
338
365
  }
339
366
  }
340
- if (isDestructiveSessionWrite(req.method ?? "", url) && !anyServiceAuth && !deps.config.allowUnauthedWrites) {
341
- sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting destructive session writes (policy / sync-import / fork / delete)");
367
+ if (isDestructiveSessionWrite(req.method ?? "", url) && credential === undefined && !deps.config.allowUnauthedWrites) {
368
+ sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting destructive session writes (policy / sync-import / fork / delete)");
342
369
  return;
343
370
  }
344
371
  if (await dispatchSegment(POST_CREDENTIAL_ROUTES, req, res, url, search, method, allow.post, ctx))
@@ -1,6 +1,6 @@
1
1
  import { uuidv7 } from "@sema-agent/core";
2
2
  import { heldWorkflowParkDecisions } from "../parked-decide.js";
3
- import { runInBackground } from "../runs.js";
3
+ import { createRunAnchorWriter, runInBackground } from "../runs.js";
4
4
  import { recheckClaimBeforeLaunch, refusalAfterLostClaim, startClaimHeartbeat } from "./claim-heartbeat.js";
5
5
  import { heldFor } from "../peer-seat.js";
6
6
  import { fleetRunPublisher, fleetRunLabels, nameFleetRowOnDelivery } from "../fleet/fleet-bus.js";
@@ -11,12 +11,12 @@ import { buildActiveRunConflict } from "./active-run-conflict.js";
11
11
  import { commitExecutionContext, faultedAnswerOf } from "./execution-context.js";
12
12
  import { rootSessionAbsentAnswer } from "./execution-context.js";
13
13
  import { timeClaim } from "./claim-latency.js";
14
- import { commitSessionInheritEnv } from "./session-inherit-env.js";
14
+ import { commitLegBindings } from "../session-bindings.js";
15
15
  import { clearTurnActivity, readTurnActivityMs } from "../turn-activity.js";
16
16
  import { recordResourceWindow } from "../resource-window.js";
17
17
  import { persistSubmissionCtx, SUBMIT_CTX_CLAIM_LOST } from "./submit-ctx.js";
18
18
  import { withdrawClaimedRun } from "./claimed-run.js";
19
- import { sessionFactsReadOf } from "./owner-access.js";
19
+ import { sessionFactsReadOf, sessionOccupantReadOf } from "./owner-access.js";
20
20
  import { createSessionWorkspaceRecorder, sessionWorkspaceStoreOf } from "../session-workspace.js";
21
21
  export async function mintAndDriveDurableRun(ctx, runStore, args) {
22
22
  const { deps } = ctx;
@@ -82,24 +82,24 @@ async function claimAndCommit(ctx, runStore, args, sessionId, taskId) {
82
82
  finally {
83
83
  stopPreLaunchHeartbeat();
84
84
  }
85
- commitSessionInheritEnv(deps, args.prepared.spec.sessionId, args.prepared.body);
85
+ commitLegBindings(deps, undefined, args.prepared.spec.sessionId, args.prepared.legFacts?.sessionBindings);
86
86
  return { holdingLeg: created.legId };
87
87
  }
88
88
  function launchDurableRun(ctx, runStore, args, sessionId, taskId, trustedInternals, legId) {
89
89
  const { deps } = ctx;
90
90
  const { inflightRuns, preemptableRuns, steerableRuns } = ctx.registry;
91
- const anchorOwner = args.prepared.auth?.subject ?? null;
92
91
  const sessionFactsOf = sessionFactsReadOf(deps.sessionStorage);
93
- const captureTurnAnchor = deps.resumeAnchorStore && sessionFactsOf
94
- ? async (eventId) => {
95
- const leaf = (await sessionFactsOf(sessionId))?.leafId;
96
- if (leaf)
97
- await deps.resumeAnchorStore.put(sessionId, eventId, leaf, anchorOwner);
98
- }
99
- : undefined;
100
- const captureUserMessageAnchor = deps.resumeAnchorStore
101
- ? async (entryId) => { await deps.resumeAnchorStore.put(sessionId, taskId, entryId, anchorOwner); }
102
- : undefined;
92
+ const anchors = createRunAnchorWriter({
93
+ seat: deps.backend?.landedAttendants(),
94
+ sessionId,
95
+ owner: args.prepared.auth?.subject ?? null,
96
+ promptKey: taskId,
97
+ witness: args.prepared.legFacts?.sessionWitness,
98
+ occupantOf: sessionOccupantReadOf(deps.sessionStorage),
99
+ leafOf: sessionFactsOf === undefined ? undefined : async (id) => (await sessionFactsOf(id))?.leafId,
100
+ });
101
+ const captureTurnAnchor = anchors.turn;
102
+ const captureUserMessageAnchor = anchors.prompt;
103
103
  const fleetPub = fleetRunPublisher(deps.fleetBus, {
104
104
  runId: taskId,
105
105
  scope: args.fleetScope,
@@ -113,7 +113,6 @@ function launchDurableRun(ctx, runStore, args, sessionId, taskId, trustedInterna
113
113
  coordinator: deps.toolApproval,
114
114
  streamApprovalOn: resolveStreamApprovalGate({
115
115
  toolApprovalEnabled: true,
116
- streamApprovalEnabled: deps.config.streamApproval?.enabled === true,
117
116
  backend: deps.backend,
118
117
  checkpointStore: deps.checkpointStore,
119
118
  }).active,
@@ -122,7 +121,7 @@ function launchDurableRun(ctx, runStore, args, sessionId, taskId, trustedInterna
122
121
  declaredFamilies: declaredApprovalFrameFamilies(args.prepared.body.settings),
123
122
  origin: approvalLegOriginOf(args.prepared.execution),
124
123
  }
125
- : undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), args.prepared.legFacts?.sessionWitness), args.prepared.legFacts?.skills, args.prepared.legFacts?.registeredCwd));
124
+ : undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), args.prepared.legFacts?.sessionWitness), args.prepared.legFacts?.skills, args.prepared.legFacts?.sessionBindings.cwd));
126
125
  args.runSlot?.release();
127
126
  args.prepared.seat.markRecord();
128
127
  return { status: 202, body: { taskId, sessionId, status: "running", ...(args.prepared.warnings !== undefined ? { warnings: args.prepared.warnings } : {}) } };
@@ -1,12 +1,18 @@
1
1
  /**
2
- * `GET /health` 的**读者分档** —— 同一张面四种读者(k8s / Docker 探针、壳在带凭据之前读的自报位、嵌入宿主的引擎身份验证、持凭运维),
2
+ * `GET /health` 的**读者分档** —— 同一张面五种读者(k8s / Docker 探针、壳在带凭据之前读的自报位、嵌入宿主的引擎身份验证、同机附着方、持凭运维),
3
3
  * 键集按**读者**而不是按「这个键敏不敏感」定。
4
4
  *
5
- * ## 规则(一条)
6
- * 读者三档,答案只有一处:
5
+ * ## 律:证明只有两种,判官只有一只
6
+ * 一次请求的读者能向本服务证明的只有两件事 —— **凭据**(读路谓词 `dispatch.ts` 的 `readCredentialOk`:service token ∨ 只读 trace token ∨ 已验 principal)
7
+ * 与**通道**(请求从本机控制 socket 进来,`request-channel.ts`:能穿过数据根下私有目录的只有引擎的 OS 用户与 root)。TCP 对端地址**不是**证明 ——
8
+ * 它说的是包从哪只接口进来,不说包是谁发的(同机反代 / TCP 中继 / 共享绑址上更具体的回环绑定都让它失真),所以没有「回环档」,转发头也不读。
9
+ * 读者四档,答案只有一处(`dispatch.ts` 的 `healthReaderOf`;本文件只持有闭集与出口):
7
10
  * · `open` —— 部署没配任何服务凭据(单机 / loopback 开发形;全局凭据门不武装):全键,字节同分档之前;
8
- * · `credentialed` —— 配了服务凭据,且这次请求出示了**读路谓词**认的凭据(`dispatch.ts` 的 `readCredentialOk`:service token ∨ 只读 trace token ∨ 已验 principal):全键;
9
- * · `anonymous` —— 配了服务凭据而这次请求没出示:**只拿显式白名单** {@link ANONYMOUS_HEALTH_KEYS}。
11
+ * · `credentialed` —— 配了服务凭据,且这次请求出示了**读路谓词**认的凭据:全键;
12
+ * · `engine-user` —— 配了服务凭据、没出示凭据,但请求经**本机控制 socket** 到达:全键。它换来的只是这一面的自描述(本面按构造不带任何秘密),
13
+ * **不是凭据**:别的任何口照旧要凭据(通道不进读路谓词、全局门与身份来源闭集 —— 宿主车道上模型跑的命令也是引擎的 OS 用户);
14
+ * 这是一条显式的披露政策 —— 「引擎的 OS 用户有权读引擎的自描述」;
15
+ * · `anonymous` —— 配了服务凭据,这次请求既没出示凭据、也不是经控制 socket 来的:**只拿显式白名单** {@link ANONYMOUS_HEALTH_KEYS}。
10
16
  * 白名单 = 存活位(`status`)+ 壳的 pre-credential 自报位三键(`auth` / `operator` / `center`,`health-self-report.ts` 铸;壳在带凭据**之前**要读的就是它们)。
11
17
  * 其余的键 —— 现有的(`dataRoot` / `pid` / `configHash` / `sessionBackend` / `startedAt` / `port` / `version` / `engineSignal` …)与将来新长的 —— 对匿名读者一律不出:
12
18
  * 这是**白名单**(挑出四键),不是黑名单(剥掉几键)—— 黑名单形下每个新键默认漏出,这一面又恒在凭据门之前、缺省全网卡监听(安全轴 fail-closed)。
@@ -14,14 +20,15 @@
14
20
  * ## 谁读哪一档
15
21
  * · 探针(k8s `httpGet` / Docker `HEALTHCHECK`):只要 HTTP 200 —— 匿名也是 200,存活位在白名单里;摘流语义的探针读 `/readyz`(不分档,体只有就绪位);
16
22
  * · 壳的 pre-credential 读路:`auth` / `operator` / `center` 三键(7.121.0)—— 白名单;
17
- * · 嵌入宿主的引擎身份验证(`pid` ∧ `dataRoot`,见 `test/health-identity-contract.test.ts`):宿主就是带着部署的服务凭据起的引擎,身份验证带同一枚凭据读 —— 在 `credentialed` 档;
23
+ * · 嵌入宿主的引擎身份验证(`pid` ∧ `dataRoot`,见 `test/health-identity-contract.test.ts`):带部署的服务凭据读 ⇒ `credentialed`;经控制 socket 读 ⇒ `engine-user`;
18
24
  * 没配服务凭据的嵌入形(桌面宿主自起、不配凭据)在 `open` 档,与改前逐字节同;
25
+ * · 同机附着方(没有令牌的壳 / 桌面宿主附着别的进程起的引擎):经控制 socket 读 ⇒ `engine-user`(读法见 USAGE「同机附着方怎么读身份」);
19
26
  * · 持凭运维 / 编排器:`credentialed` 档,全键。
20
27
  *
21
28
  * 没有旋钮:一个放宽用的旋钮就是一把「把路径指纹重新开给匿名方」的钥匙,而本规则要的恰是它没有这把钥匙。
22
29
  */
23
- /** 读者三档(闭集;顺序无语义)。 */
24
- export declare const HEALTH_READERS: readonly ["open", "credentialed", "anonymous"];
30
+ /** 读者四档(闭集;顺序无语义)。 */
31
+ export declare const HEALTH_READERS: readonly ["open", "credentialed", "engine-user", "anonymous"];
25
32
  export type HealthReader = (typeof HEALTH_READERS)[number];
26
33
  /**
27
34
  * 匿名读者的**显式白名单**:存活位 + 自报位三键。穷举 —— 加一个进来是一次有意的、要过评审的放宽(它会对没有凭据的任何人可见)。
@@ -29,7 +36,7 @@ export type HealthReader = (typeof HEALTH_READERS)[number];
29
36
  */
30
37
  export declare const ANONYMOUS_HEALTH_KEYS: readonly ["status", "auth", "operator", "center"];
31
38
  /**
32
- * 键集判官 —— `/health` 体按读者出口的**唯一**一道:`open` / `credentialed` 原样,`anonymous` 只挑白名单。
39
+ * 键集判官 —— `/health` 体按读者出口的**唯一**一道:`open` / `credentialed` / `engine-user` 原样,`anonymous` 只挑白名单。
33
40
  * 入参是按全键铸好的体(铸点不分读者:一个事实一个铸点,读者分档只在出口);返回新对象,不改入参。
34
41
  */
35
42
  export declare function projectHealthBody(reader: HealthReader, body: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>>;
@@ -1,9 +1,10 @@
1
- export const HEALTH_READERS = ["open", "credentialed", "anonymous"];
1
+ export const HEALTH_READERS = ["open", "credentialed", "engine-user", "anonymous"];
2
2
  export const ANONYMOUS_HEALTH_KEYS = ["status", "auth", "operator", "center"];
3
3
  export function projectHealthBody(reader, body) {
4
4
  switch (reader) {
5
5
  case "open":
6
6
  case "credentialed":
7
+ case "engine-user":
7
8
  return body;
8
9
  case "anonymous": {
9
10
  const closed = {};
@@ -23,6 +23,9 @@
23
23
  * 中心铸的中继令牌,不带 service token)∧ 会话枚举面在(事实 `sessionList`,web 面中继 `GET /v1/sessions`);缺任一 ⇒ `false`。
24
24
  * 四件齐时:多租户(`REQUIRE_PRINCIPAL`)每条会话都落着验过的属主 ⇒ `true`;单用户形下一条会话归谁取决于提交它的那次请求带没带
25
25
  * 身份(web 面只列调用人自己的会话)—— 部署级答不了 ⇒ `"unknown"`。
26
+ * · `center.assertionToken` = web-admin 断言令牌的**声明读数**(配置 `webAdmin.assertionToken`,读口 `center-credential.ts` 的 `readWebAdminCredentialDeclaration`,
27
+ * 与主凭证同一只判官):`declared` ⇔ 两键之一设了,`absent` ⇔ 都没设;只在接了中心时在场(没接中心的部署不读这一对键,答不了)。只说声明,不说令牌
28
+ * 有效、也不说引擎向中心出示了它(本版不出示)。
26
29
  *
27
30
  * ## 无鉴权面
28
31
  * `/health` 排在凭据门之前、缺省全网卡监听:本模块只出闭集词、布尔与运维要发布的 URL。两只 URL 值都过 display-safe 律
@@ -33,7 +36,8 @@
33
36
  * 所以那一键不是闭集词:调用方不要往里放秘密或人名。
34
37
  *
35
38
  * ## 在场律
36
- * 三键**恒在场**;缺席 = 老 worker(≤7.120.x)。`center.issuer` / `center.webBaseUrl` 缺席即缺席(没有鉴权桥 / 没配旋钮),不拼不猜。
39
+ * 三键**恒在场**;缺席 = 老 worker(≤7.120.x)。`center.issuer` / `center.webBaseUrl` 缺席即缺席(没有鉴权桥 / 没配旋钮),不拼不猜;
40
+ * `center.assertionToken` 在场 ⇔ 接了中心(接了中心却缺席 = 老 worker)。
37
41
  */
38
42
  import type { FlatServiceDeps } from "./server.js";
39
43
  import { type IdentitySource } from "../identity-source.js";
@@ -43,6 +47,9 @@ export type IdentityAttach = (typeof IDENTITY_ATTACH_WORDS)[number];
43
47
  /** `operator` 的词表。 */
44
48
  export declare const OPERATOR_PRESENCE_WORDS: readonly ["present", "absent"];
45
49
  export type OperatorPresence = (typeof OPERATOR_PRESENCE_WORDS)[number];
50
+ /** `center.assertionToken` 的词表(声明读数:两键之一设了 / 都没设)。 */
51
+ export declare const ASSERTION_TOKEN_DECLARATION_WORDS: readonly ["declared", "absent"];
52
+ export type AssertionTokenDeclaration = (typeof ASSERTION_TOKEN_DECLARATION_WORDS)[number];
46
53
  /** `center.sessionsVisible` 的值域(两个布尔 + 一个词;`"unknown"` = 接线齐了,但会话归谁要看提交它的那次请求)。 */
47
54
  export declare const SESSIONS_VISIBLE_VALUES: readonly [true, false, "unknown"];
48
55
  export type SessionsVisible = (typeof SESSIONS_VISIBLE_VALUES)[number];
@@ -59,6 +66,7 @@ export interface HealthSelfReport {
59
66
  readonly issuer?: string;
60
67
  readonly webBaseUrl?: string;
61
68
  readonly sessionsVisible: SessionsVisible;
69
+ readonly assertionToken?: AssertionTokenDeclaration;
62
70
  };
63
71
  }
64
72
  /**
@@ -5,6 +5,7 @@ import { centerLaneConfigured } from "../web-admin-client/center-request.js";
5
5
  import { buildDisplaySafeUrl } from "../trace/redact.js";
6
6
  export const IDENTITY_ATTACH_WORDS = ["available", "unavailable"];
7
7
  export const OPERATOR_PRESENCE_WORDS = ["present", "absent"];
8
+ export const ASSERTION_TOKEN_DECLARATION_WORDS = ["declared", "absent"];
8
9
  export const SESSIONS_VISIBLE_VALUES = [true, false, "unknown"];
9
10
  function carriesCallerIdentity(kind) {
10
11
  switch (kind) {
@@ -29,11 +30,12 @@ export function buildHealthSelfReport(deps) {
29
30
  const required = kinds.includes("service_token");
30
31
  return {
31
32
  auth: { required, kinds, identityAttach: kinds.some(carriesCallerIdentity) ? "available" : "unavailable", serviceTokenActsForDeployment: required && serviceTokenDeclaredActsForDeployment(config) },
32
- operator: operatorLane(deps).available ? "present" : "absent",
33
+ operator: operatorLane(deps, "operate").available ? "present" : "absent",
33
34
  center: {
34
35
  ...(issuer !== undefined ? { issuer: buildDisplaySafeUrl(issuer) } : {}),
35
36
  ...(webBaseUrl !== undefined ? { webBaseUrl: buildDisplaySafeUrl(webBaseUrl) } : {}),
36
37
  sessionsVisible,
38
+ ...(config.webAdmin !== undefined ? { assertionToken: config.webAdmin.assertionToken !== undefined ? "declared" : "absent" } : {}),
37
39
  },
38
40
  };
39
41
  }
@@ -23,7 +23,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
23
23
  import type { SessionHead, WorkflowRun, WorkflowRunStore } from "@sema-agent/core";
24
24
  import type { RunStore, StoreBackend } from "../plugins/store-backend.js";
25
25
  import { type Logger } from "../observability/logger.js";
26
- import type { LatestRunRef, RunListQuery, RunRecord } from "../plugins/store-contracts.js";
26
+ import type { LatestRunRef, RunListQuery, RunRecord, SessionListQuery } from "../plugins/store-contracts.js";
27
27
  import type { ServiceConfig } from "../config-types.js";
28
28
  import type { SessionAuditReadOpts } from "../audit.js";
29
29
  import { type DeploymentShapeInput } from "../deployment-shape.js";
@@ -31,8 +31,8 @@ import { type SessionAgent } from "../session-agent.js";
31
31
  import { type SessionFace } from "../session-incarnation.js";
32
32
  import { type Admitted, type Caller, type FaceId, type ListFaceId, type ListFilter, type OwnedReading, type Qual, type RunFaceId, type SessionFaceId, type WorkflowFaceId } from "../owner-faces.js";
33
33
  import { type Person, type Subject } from "../owner-brands.js";
34
- import { type OwnerAwareSessionStore } from "../security.js";
35
- import { type OperatorRoster } from "./principal-gate.js";
34
+ import { type OwnerAwareSessionStore, type SessionListItem } from "../security.js";
35
+ import type { OperatorRoster } from "../operator-roster.js";
36
36
  import { type RouteDeps } from "./route-ctx.js";
37
37
  import type { FlatServiceDeps } from "./server.js";
38
38
  import type { AgentRosterRouteId } from "./routes/agents-roster.js";
@@ -96,9 +96,8 @@ export declare const ROUTE_FACES: {
96
96
  readonly "run-task-stop": "run.supervise";
97
97
  readonly "elicitation-respond": null;
98
98
  readonly "question-respond": null;
99
- readonly "tool-approval-respond": null;
100
- readonly "tool-approval-read": null;
101
99
  readonly "task-ask-decision": null;
100
+ readonly "task-ask-read": null;
102
101
  readonly "run-permission-mode": "run.supervise";
103
102
  readonly "run-memory-capture-optout": "run.drive";
104
103
  readonly "session-init": null;
@@ -427,10 +426,15 @@ export declare function admitSessionById(entry: Entry, res: ServerResponse, stor
427
426
  */
428
427
  export declare function readVisibleSession(entry: Entry, store: SessionGateStore, sessionId: string): Promise<Admitted<SessionHead> | undefined>;
429
428
  /**
430
- * 承认之后的**世代围栏**(会话事件流的心跳拍):这只会话此刻的属主还是承认时读到的那一格吗 —— 删了(没有这一行 / 读不出按面折)或换主 ⇒ 否。
431
- * 与 {@link readVisibleSession} 的「再判可见」不同:比的是同一行前后两次读到的属主(删建 / 易主 ⇒ 作废),两侧都是行上的属主,不是调用方身份。
429
+ * 承认之后的**世代围栏**(会话事件流的心跳拍):这只会话此刻的住客还是承认时读到的那一位吗 —— 删了(没有这一行 / 读不出按面折)、删后同 id 重建(包括同一属主)
430
+ * 或换主 ⇒ 否。比较器 = 住客复核的唯一判 `sameOccupant`(属主 ∧ 化身);与 {@link readVisibleSession} 的「再判可见」不同:两侧都是同一行前后两次的住客读数,不是调用方身份。
432
431
  */
433
- export declare function sessionOwnerUnchanged(entry: Entry, store: SessionGateStore, sessionId: string, admittedOwner: string | null): Promise<boolean>;
432
+ export declare function sessionOccupantUnchanged(entry: Entry, store: SessionGateStore, sessionId: string, admitted: Pick<SessionHead, "owner" | "incarnation">): Promise<boolean>;
433
+ /**
434
+ * 同步族门读之后的**住客复判**(律在 `routes/session-sync.ts` 门注「门后读」):门承认过的那一位此刻还占着这只 id 吗 —— 同一只比较器 `sameOccupant`,读法是门的两种读法之一:
435
+ * `pull` = 活行头(拉取口只认活行);`push` = 占位头(活行 ∪ 在删行,与门同一只 `deletionHeadReadOf`)。此刻无行 ⇒ 不是。只在门判**有住客**时调(门判空闲的口门后不读会话数据)。
436
+ */
437
+ export declare function recheckSyncGate(store: DeletionGateStore, sessionId: string, admitted: SessionFace, port: "pull" | "push"): Promise<boolean>;
434
438
  /** 会话行的完整判(不下发,交回承认 / `undefined`):两读之间要再判一次的口(同步导入的提交前复判)与「看不见按自己的形答」的口用。 */
435
439
  export declare function judgeSession<T extends OwnedReading>(entry: Entry, store: PlacementReadingStore | undefined, sessionId: string, reading: T): Promise<Admitted<T> | undefined>;
436
440
  /** 这一份承认里的调用方是 fleet 吗(本口 `fleet` 列里的一格成立):fork 新属主「继承源属主」那一支读它。 */
@@ -489,6 +493,11 @@ export interface SessionFacts {
489
493
  * 读者:回退锚的逐轮捕获(两条起跑腿读叶子)、失认领答复的「会话在不在」(不碰叶子)、同步拉取清单的当前叶子。
490
494
  */
491
495
  export declare function sessionFactsReadOf(store: Pick<OwnerAwareSessionStore, "headOf"> | undefined): ((sessionId: string) => Promise<SessionFacts | undefined>) | undefined;
496
+ /**
497
+ * 会话此刻的住客(属主 + 化身,同一行同一次头读,经 {@link sessionFaceOfHead} 投影 —— 活行上读到空化身响亮拒)。读者:运行腿的回退锚写座在见证里还没有化身时
498
+ * 钉住这条 run 自己的那一位(`runs.ts` 的 `createRunAnchorWriter`;调用发生在 run 在跑、认领在手的时刻)。店不交头读 ⇒ `undefined`。
499
+ */
500
+ export declare function sessionOccupantReadOf(store: Pick<OwnerAwareSessionStore, "headOf"> | undefined): ((sessionId: string) => Promise<SessionFace | undefined>) | undefined;
492
501
  /**
493
502
  * 会话在委派树里的位置(wire 键 `agent` 的值;唯一读口):店的 placed 位一读 → `session-agent.ts` 的 `sessionAgentOf`(元组不带属主)。店不交这一面 ⇒ `undefined`
494
503
  * (这台部署不存元组,不探)。探针抛 ⇒ 原样上抛 —— 读不出怎么说归读者(视图读响亮失败;队列只缺那一行的键并计数),本函数不替任何一面把故障说成「不是子代」。
@@ -509,10 +518,16 @@ export declare function engineRulesKeyOf(store: Pick<OwnerAwareSessionStore, "he
509
518
  * 读者:会话面板的上一腿(面 `run.panel`,看不见 = 不投那个键)。
510
519
  */
511
520
  export declare function readVisibleLatestRun(entry: Entry, store: Pick<RunStore, "latestRunForSession">, sessionId: string): Promise<LatestRunRef | undefined>;
512
- /** run 列表的属主过滤参数(一只派生,读与游标指纹同读):视域钉住一位主体 ⇒ 强制那一位(调用方点名的 `owner` 不算);不钉人(fleet)⇒ 点名的照用(运维视图)。 */
513
- export declare function runListOwnerOf(filter: ListFilter, named: string | undefined): string | undefined;
514
- /** run 列表的读口(列表面 `list.read`):过滤参数由 {@link runListOwnerOf} 从视域派生,只在这里落成店的过滤参数。 */
521
+ /** 列表的属主过滤参数(run 列表与会话列表同一只派生,读与游标指纹同读):视域钉住一位主体 ⇒ 强制那一位(调用方点名的 `owner` 不算);不钉人(fleet)⇒ 点名的照用(运维视图)。 */
522
+ export declare function listOwnerOf(filter: ListFilter, named: string | undefined): string | undefined;
523
+ /** run 列表的读口(列表面 `list.read`):过滤参数由 {@link listOwnerOf} 从视域派生,只在这里落成店的过滤参数。 */
515
524
  export declare function listVisibleRuns(store: Pick<RunStore, "listRuns">, filter: ListFilter, named: string | undefined, query: Omit<RunListQuery, "owner">): Promise<RunRecord[]>;
525
+ /**
526
+ * 会话列表的读口(列表面 `session.list`;`GET /v1/sessions`):「读 + 过滤」只在这里落成店的过滤参数 —— 属主(由 {@link listOwnerOf} 从视域派生;`""` 是合法的精确属主,
527
+ * 只有「没给」才不过滤)、无主行的并入(视域的 `includeUnowned`)、视图(`sessionKind`,律 `session-kind.ts`:缺席 = 缺省视图)。谓词都打在店里(同一条 SELECT),
528
+ * 路由层不另滤行。peer 目录读同一只 lister 的缺省视图(`peer-directory.ts`)。
529
+ */
530
+ export declare function listVisibleSessions(lister: (opts: SessionListQuery) => Promise<SessionListItem[]>, filter: ListFilter, named: string | undefined, query: Omit<SessionListQuery, "owner" | "includeUnowned">): Promise<SessionListItem[]>;
516
531
  /** 审批 / 助手面按停驻 scope 列 run:属主过滤 = scope 的属主键(公共 scope `_` ⇒ 属主为 null 的 run,主体 ⇒ 恰它的;`security.ts` 的唯一编解码),只在这里落成店的过滤参数。 */
517
532
  export declare function listRunsOfScope(store: Pick<RunStore, "listRuns">, scope: string, limit: number): Promise<RunRecord[]>;
518
533
  /** 一把提交钥匙命中的行对这位调用方算什么:`visible` = 读得到的那一行;`occupied` = 有行但不是这次提交拿得到的(看不见 / 自带 taskId 而键指着别的行)—— 回执 409,不回显那一行。 */
@@ -602,14 +617,18 @@ export interface WorkflowAdmission {
602
617
  /** 工作流门的一次判(不下发):承认,或拒因(没有 / 前门 / 看不见 / 会话断言不符)。 */
603
618
  export type WorkflowVerdict = WorkflowAdmission | "missing" | "door" | "not_visible" | "session_mismatch";
604
619
  /**
605
- * 工作流列表(`GET /v1/workflows`)—— 属主过滤只在这里落成店参数:调用方换成它的引擎身份(与 {@link judgeWorkflowRun} 同一只换算),店按 `scope` 列筛。
620
+ * 🔴 **一位调用方的工作流行住在 `scope` 列的哪一格**(唯一读法):调用方的主体换成它的引擎身份(`engine-identity.ts` 的 `engineScopeOf` —— 引擎按它写 scope:
621
+ * 带场景的请求今天是那个人,匿名是 `"default"`)。列表({@link listVisibleWorkflows})、按 id 的门({@link judgeWorkflowRun})与舰队流的工作流行 / 终态窗(`routes/fleet.ts`)同读这一只。
622
+ */
623
+ export declare function workflowScopeOf(subject: Subject | undefined): string;
624
+ /**
625
+ * 工作流列表(`GET /v1/workflows`)—— 属主过滤只在这里落成店参数:{@link workflowScopeOf},店按 `scope` 列筛。
606
626
  * 面表 `workflow.read` 只给属主(不放 fleet / 运维)⇒ 列表 = 调用方自己那一格的行。
607
627
  */
608
628
  export declare function listVisibleWorkflows(entry: Entry, store: Pick<WorkflowRunStore, "listByScope">, opts: Parameters<WorkflowRunStore["listByScope"]>[1]): ReturnType<WorkflowRunStore["listByScope"]>;
609
629
  /**
610
630
  * 🔴 **工作流行的判(唯一一处;[ref] 第二阶段)**:按 id 读一行(店的 `get`,不带 scope —— 修前是 core 按 scope 读 + 路由再比一次 scope,两读答同一问),
611
- * 行格 = `scope` 列的属主键(引擎写下的引擎身份,恒有主);调用方一侧换成它的引擎身份(`engine-identity.ts` 的 `engineScopeOf`:引擎按它写 scope ——
612
- * 带场景的请求是那个人,匿名是 `"default"`)再过事实函数 {@link qualsOf} + 面表;前门按这次请求的调用方判。承认之后按 {@link WORKFLOW_SESSION_ASSERTION} 判会话断言。
631
+ * 行格 = `scope` 列的属主键(引擎写下的引擎身份,恒有主);调用方一侧换成它的引擎身份({@link workflowScopeOf})再过事实函数 {@link qualsOf} + 面表;前门按这次请求的调用方判。承认之后按 {@link WORKFLOW_SESSION_ASSERTION} 判会话断言。
613
632
  */
614
633
  export declare function judgeWorkflowRun(entry: Entry, store: Pick<WorkflowRunStore, "get">, runId: string): Promise<WorkflowVerdict>;
615
634
  /** 工作流按 id 读面的门:没有 / 看不见 / 会话断言不符同一只投影(`workflow_missing`),前门经它的下发口。交回承认或 `undefined`(已应答)。 */