@sema-agent/server 7.148.0 → 7.150.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 (360) hide show
  1. package/MIGRATION.md +551 -9
  2. package/README.md +17 -2
  3. package/README.zh-CN.md +5 -1
  4. package/USAGE.md +126 -68
  5. package/dist/adoption/wire.d.ts +3 -3
  6. package/dist/approval-card.d.ts +33 -33
  7. package/dist/approval-gate-currency.d.ts +1 -1
  8. package/dist/approval-leg-origin.d.ts +33 -0
  9. package/dist/approval-leg-origin.js +4 -0
  10. package/dist/audit.d.ts +1 -1
  11. package/dist/audit.js +2 -2
  12. package/dist/auth-bridge.d.ts +9 -1
  13. package/dist/auth-bridge.js +4 -4
  14. package/dist/auth-keys.d.ts +10 -1
  15. package/dist/auth-keys.js +8 -0
  16. package/dist/background-session-reap.d.ts +1 -1
  17. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  18. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  19. package/dist/boot/execution-env.js +10 -11
  20. package/dist/boot/execution-lane.d.ts +6 -4
  21. package/dist/boot/execution-lane.js +3 -1
  22. package/dist/boot/org-delivery.d.ts +3 -2
  23. package/dist/boot/parked-revive-gate.d.ts +5 -5
  24. package/dist/boot/parked-revive-gate.js +2 -3
  25. package/dist/boot/resolve-spec.d.ts +4 -5
  26. package/dist/boot/resolve-spec.js +66 -28
  27. package/dist/boot/retention-lane.d.ts +1 -1
  28. package/dist/boot/runner-deps.js +3 -1
  29. package/dist/boot/session-faces.js +21 -21
  30. package/dist/boot/stage-01-config.d.ts +1 -0
  31. package/dist/boot/stage-01-config.js +4 -3
  32. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  33. package/dist/boot/stage-02-web-admin-pull.js +10 -2
  34. package/dist/boot/stage-03-store-backend.d.ts +1 -0
  35. package/dist/boot/stage-03-store-backend.js +4 -4
  36. package/dist/boot/stage-04-stores.d.ts +1 -0
  37. package/dist/boot/stage-05-execution-env.d.ts +1 -0
  38. package/dist/boot/stage-06-runners.d.ts +2 -1
  39. package/dist/boot/stage-06-runners.js +1 -2
  40. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  41. package/dist/boot/stage-07-capability-layer.js +1 -1
  42. package/dist/boot/stage-08-reapers.d.ts +2 -1
  43. package/dist/boot/stage-09-leader.d.ts +2 -1
  44. package/dist/boot/stage-10-http-server.d.ts +35 -2
  45. package/dist/boot/stage-10-http-server.js +9 -4
  46. package/dist/boot/stores.d.ts +3 -0
  47. package/dist/boot/stores.js +22 -19
  48. package/dist/boot/web-admin.d.ts +1 -1
  49. package/dist/capabilities/tool-defer.d.ts +1 -1
  50. package/dist/capability-facts.d.ts +70 -60
  51. package/dist/capability-facts.js +45 -49
  52. package/dist/card-settle-stored-scope.d.ts +56 -0
  53. package/dist/card-settle-stored-scope.js +27 -0
  54. package/dist/card-void.d.ts +7 -12
  55. package/dist/card-void.js +2 -7
  56. package/dist/config-catalog.d.ts +12 -0
  57. package/dist/config-catalog.js +37 -33
  58. package/dist/config-invariants.d.ts +5 -4
  59. package/dist/config-invariants.js +4 -4
  60. package/dist/config-types.d.ts +49 -16
  61. package/dist/config.d.ts +6 -5
  62. package/dist/config.js +35 -24
  63. package/dist/context-window-notice.d.ts +31 -0
  64. package/dist/context-window-notice.js +28 -0
  65. package/dist/deployment-governance.d.ts +7 -28
  66. package/dist/deployment-governance.js +1 -14
  67. package/dist/deployment-shape.d.ts +20 -11
  68. package/dist/deployment-shape.js +1 -0
  69. package/dist/device-ws-hub.d.ts +1 -0
  70. package/dist/device-ws-hub.js +64 -28
  71. package/dist/device-ws-protocol.d.ts +20 -6
  72. package/dist/device-ws-protocol.js +9 -2
  73. package/dist/engine-identity.d.ts +7 -1
  74. package/dist/engine-identity.js +5 -0
  75. package/dist/env-name-allowlist-knobs.d.ts +6 -5
  76. package/dist/env-name-allowlist-knobs.js +5 -0
  77. package/dist/execution-lane-caps.d.ts +20 -5
  78. package/dist/execution-lane-caps.js +18 -4
  79. package/dist/field-conflict.d.ts +2 -2
  80. package/dist/fleet/engine-signal.d.ts +14 -1
  81. package/dist/fleet/engine-signal.js +5 -1
  82. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  83. package/dist/fleet/serving-lease.d.ts +18 -3
  84. package/dist/fleet/serving-lease.js +81 -35
  85. package/dist/fleet-client.d.ts +13 -11
  86. package/dist/fleet-client.js +53 -33
  87. package/dist/history-anchor.js +1 -1
  88. package/dist/hitl-delivery.d.ts +1 -3
  89. package/dist/hitl-delivery.js +1 -1
  90. package/dist/hooks/command-spawn.d.ts +7 -2
  91. package/dist/hooks/command-spawn.js +13 -6
  92. package/dist/hooks/hook-runner.d.ts +5 -0
  93. package/dist/hooks/hook-runner.js +11 -7
  94. package/dist/http/active-run-conflict.d.ts +3 -7
  95. package/dist/http/active-run-conflict.js +2 -2
  96. package/dist/http/admission.js +5 -5
  97. package/dist/http/approval-sweeps.js +5 -3
  98. package/dist/http/caller-trust.d.ts +2 -2
  99. package/dist/http/caller-trust.js +3 -3
  100. package/dist/http/checkpoint-ctx.d.ts +18 -63
  101. package/dist/http/checkpoint-ctx.js +1 -24
  102. package/dist/http/claim-heartbeat.d.ts +6 -6
  103. package/dist/http/claim-heartbeat.js +6 -6
  104. package/dist/http/claimed-run.d.ts +16 -9
  105. package/dist/http/claimed-run.js +8 -0
  106. package/dist/http/dispatch.js +7 -5
  107. package/dist/http/durable-run-leg.d.ts +8 -1
  108. package/dist/http/durable-run-leg.js +34 -15
  109. package/dist/http/execution-context.d.ts +115 -14
  110. package/dist/http/execution-context.js +130 -40
  111. package/dist/http/owner-access.d.ts +246 -21
  112. package/dist/http/owner-access.js +186 -8
  113. package/dist/http/principal-gate.d.ts +18 -11
  114. package/dist/http/principal-gate.js +3 -1
  115. package/dist/http/readiness.d.ts +4 -2
  116. package/dist/http/resume-ctx-read.d.ts +14 -3
  117. package/dist/http/resume-ctx-read.js +24 -3
  118. package/dist/http/resume-legs.d.ts +35 -3
  119. package/dist/http/resume-legs.js +262 -106
  120. package/dist/http/route-ctx.d.ts +29 -11
  121. package/dist/http/routes/a2a-serve.js +17 -14
  122. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  123. package/dist/http/routes/approvals-assistant.js +11 -11
  124. package/dist/http/routes/capabilities.js +5 -4
  125. package/dist/http/routes/config-catalog.d.ts +1 -1
  126. package/dist/http/routes/diagnostics.d.ts +3 -1
  127. package/dist/http/routes/diagnostics.js +30 -5
  128. package/dist/http/routes/mcp-reconnect.js +2 -2
  129. package/dist/http/routes/memory-origin.d.ts +1 -1
  130. package/dist/http/routes/notify-wake.js +2 -3
  131. package/dist/http/routes/principal-inbox.d.ts +3 -1
  132. package/dist/http/routes/principal-inbox.js +3 -2
  133. package/dist/http/routes/projects.d.ts +1 -0
  134. package/dist/http/routes/projects.js +5 -3
  135. package/dist/http/routes/retention-ops.d.ts +1 -1
  136. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  137. package/dist/http/routes/run-permission-mode.js +2 -2
  138. package/dist/http/routes/runs.d.ts +1 -1
  139. package/dist/http/routes/runs.js +33 -37
  140. package/dist/http/routes/session-memory-sync.js +4 -5
  141. package/dist/http/routes/session-sync.d.ts +24 -5
  142. package/dist/http/routes/session-sync.js +45 -37
  143. package/dist/http/routes/sessions-list.d.ts +1 -1
  144. package/dist/http/routes/sessions.d.ts +1 -1
  145. package/dist/http/routes/sessions.js +18 -44
  146. package/dist/http/routes/tasks.js +136 -101
  147. package/dist/http/routes/trace-usage.js +14 -14
  148. package/dist/http/routes/workflows.d.ts +1 -0
  149. package/dist/http/routes/workflows.js +20 -38
  150. package/dist/http/server.d.ts +12 -9
  151. package/dist/http/server.js +35 -6
  152. package/dist/http/stored-body-replay.d.ts +3 -24
  153. package/dist/http/stored-body-replay.js +2 -12
  154. package/dist/http/submit-ctx.d.ts +2 -2
  155. package/dist/http/submit-ctx.js +5 -5
  156. package/dist/http/submit-replay.d.ts +15 -2
  157. package/dist/http/submit-replay.js +10 -4
  158. package/dist/http/wire-types.d.ts +6 -3
  159. package/dist/index.d.ts +3 -1
  160. package/dist/index.js +1 -0
  161. package/dist/leader/endpoint.js +9 -8
  162. package/dist/leg-facts.d.ts +13 -2
  163. package/dist/leg-facts.js +2 -0
  164. package/dist/local-store-declaration.d.ts +54 -0
  165. package/dist/local-store-declaration.js +59 -0
  166. package/dist/mcp-assertion-header.d.ts +1 -1
  167. package/dist/mcp-assertion-header.js +1 -1
  168. package/dist/mcp-authorization-face.d.ts +18 -14
  169. package/dist/mcp-authorization-face.js +3 -2
  170. package/dist/memory-project-layer.js +1 -1
  171. package/dist/memory-scope.d.ts +4 -4
  172. package/dist/memory-scope.js +4 -4
  173. package/dist/memory-store-refusal.d.ts +1 -1
  174. package/dist/memory-sync-client.js +2 -2
  175. package/dist/model-context-window.d.ts +50 -11
  176. package/dist/model-context-window.js +20 -1
  177. package/dist/model-entry-refusal.d.ts +5 -4
  178. package/dist/model-entry-refusal.js +17 -3
  179. package/dist/model-reach-scope.d.ts +2 -1
  180. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  181. package/dist/observability/fail-open.d.ts +19 -7
  182. package/dist/observability/fail-open.js +19 -7
  183. package/dist/observability/logger.d.ts +7 -0
  184. package/dist/observability/logger.js +3 -1
  185. package/dist/observability/metrics.js +1 -1
  186. package/dist/observability/run-terminal.d.ts +1 -1
  187. package/dist/observability/run-terminal.js +1 -0
  188. package/dist/observability/secret-env-scrub.d.ts +1 -1
  189. package/dist/observability/secret-env-scrub.js +1 -1
  190. package/dist/org-delivery-gate.d.ts +31 -6
  191. package/dist/org-delivery-gate.js +7 -4
  192. package/dist/owner-faces.d.ts +30 -5
  193. package/dist/owner-faces.js +2 -0
  194. package/dist/park-row-commit.d.ts +67 -0
  195. package/dist/park-row-commit.js +76 -0
  196. package/dist/parked-decide.d.ts +9 -7
  197. package/dist/parked-decide.js +25 -6
  198. package/dist/peer-directory.d.ts +1 -1
  199. package/dist/peer-seat.d.ts +1 -1
  200. package/dist/peer-seat.js +52 -59
  201. package/dist/plugins/adoption-log-sql.d.ts +3 -3
  202. package/dist/plugins/adoption-log-sql.js +19 -19
  203. package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
  204. package/dist/plugins/approval-ask-store-sql.js +3 -5
  205. package/dist/plugins/approval-exemption-skill-cutoff.d.ts +64 -0
  206. package/dist/plugins/approval-exemption-skill-cutoff.js +122 -0
  207. package/dist/plugins/approval-exemption-skill-m46.d.ts +0 -6
  208. package/dist/plugins/approval-exemption-skill-m46.js +6 -10
  209. package/dist/plugins/approval-exemption-store.d.ts +26 -1
  210. package/dist/plugins/approval-exemption-store.js +28 -19
  211. package/dist/plugins/ensure-schema-lock-policy.d.ts +36 -3
  212. package/dist/plugins/ensure-schema-lock-policy.js +75 -9
  213. package/dist/plugins/exec-path-law.d.ts +34 -0
  214. package/dist/plugins/exec-path-law.js +13 -0
  215. package/dist/plugins/file-run-store.d.ts +22 -9
  216. package/dist/plugins/file-run-store.js +51 -23
  217. package/dist/plugins/local-checkpoint-store.d.ts +8 -1
  218. package/dist/plugins/local-checkpoint-store.js +5 -1
  219. package/dist/plugins/local-data-root-admission.d.ts +52 -0
  220. package/dist/plugins/local-data-root-admission.js +100 -0
  221. package/dist/plugins/local-engine-high-water.d.ts +28 -7
  222. package/dist/plugins/local-engine-high-water.js +27 -22
  223. package/dist/plugins/local-session-store.d.ts +134 -49
  224. package/dist/plugins/local-session-store.js +149 -108
  225. package/dist/plugins/memory-run-store.d.ts +14 -9
  226. package/dist/plugins/memory-run-store.js +48 -22
  227. package/dist/plugins/one-time-migration-marker.d.ts +19 -3
  228. package/dist/plugins/one-time-migration-marker.js +7 -1
  229. package/dist/plugins/one-time-migrations.d.ts +110 -59
  230. package/dist/plugins/one-time-migrations.js +224 -136
  231. package/dist/plugins/org-delivery-quota-store.d.ts +34 -11
  232. package/dist/plugins/org-delivery-quota-store.js +29 -14
  233. package/dist/plugins/permission-rule-store-sql.d.ts +1 -1
  234. package/dist/plugins/permission-rule-store-sql.js +5 -9
  235. package/dist/plugins/pg-pool.d.ts +1 -1
  236. package/dist/plugins/pg-pool.js +14 -12
  237. package/dist/plugins/posix-shell-fs.js +4 -2
  238. package/dist/plugins/remote-env-adb.js +3 -2
  239. package/dist/plugins/remote-env-device.d.ts +3 -2
  240. package/dist/plugins/remote-env-device.js +8 -6
  241. package/dist/plugins/remote-env-e2b.d.ts +4 -8
  242. package/dist/plugins/remote-env-e2b.js +21 -15
  243. package/dist/plugins/remote-env-host.d.ts +51 -10
  244. package/dist/plugins/remote-env-host.js +97 -31
  245. package/dist/plugins/remote-env-k8s.js +7 -4
  246. package/dist/plugins/remote-env-local-docker.d.ts +6 -3
  247. package/dist/plugins/remote-env-local-docker.js +11 -25
  248. package/dist/plugins/remote-env-ssh.js +4 -3
  249. package/dist/plugins/remote-shell.d.ts +3 -1
  250. package/dist/plugins/remote-shell.js +3 -3
  251. package/dist/plugins/replica-registration.d.ts +35 -0
  252. package/dist/plugins/replica-registration.js +48 -0
  253. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  254. package/dist/plugins/run-store-sql.d.ts +27 -8
  255. package/dist/plugins/run-store-sql.js +46 -18
  256. package/dist/plugins/scenario-prefix-switch-m42.d.ts +8 -12
  257. package/dist/plugins/scenario-prefix-switch-m42.js +9 -6
  258. package/dist/plugins/schema-consistency.d.ts +91 -5
  259. package/dist/plugins/schema-consistency.js +189 -7
  260. package/dist/plugins/schema-drift-sentence.d.ts +6 -5
  261. package/dist/plugins/schema-drift-sentence.js +13 -5
  262. package/dist/plugins/serving-requirement.d.ts +49 -0
  263. package/dist/plugins/serving-requirement.js +53 -0
  264. package/dist/plugins/session-placement.d.ts +5 -4
  265. package/dist/plugins/shell-sentinel-owner-m48.d.ts +22 -0
  266. package/dist/plugins/shell-sentinel-owner-m48.js +6 -0
  267. package/dist/plugins/stop-then-start-sentence.d.ts +55 -0
  268. package/dist/plugins/stop-then-start-sentence.js +51 -0
  269. package/dist/plugins/store-backend.d.ts +23 -9
  270. package/dist/plugins/store-backend.js +58 -24
  271. package/dist/plugins/store-contracts.d.ts +45 -5
  272. package/dist/plugins/store-contracts.js +19 -0
  273. package/dist/plugins/tidb-pool.d.ts +11 -6
  274. package/dist/plugins/tidb-pool.js +22 -12
  275. package/dist/plugins/workspace-custody.d.ts +44 -0
  276. package/dist/plugins/workspace-custody.js +47 -0
  277. package/dist/process-instance.d.ts +3 -0
  278. package/dist/process-instance.js +7 -0
  279. package/dist/project-context.d.ts +66 -0
  280. package/dist/project-context.js +70 -0
  281. package/dist/project-identity.d.ts +8 -7
  282. package/dist/project-identity.js +40 -17
  283. package/dist/project-layer-key.d.ts +13 -2
  284. package/dist/project-layer-key.js +9 -1
  285. package/dist/question.d.ts +9 -21
  286. package/dist/question.js +28 -19
  287. package/dist/read-deny-floor-notice.d.ts +36 -0
  288. package/dist/read-deny-floor-notice.js +40 -0
  289. package/dist/{plain-string-record.d.ts → request-declaration-disposition.d.ts} +9 -23
  290. package/dist/request-declaration-disposition.js +39 -0
  291. package/dist/run-cancel-card.d.ts +28 -0
  292. package/dist/run-cancel-card.js +20 -0
  293. package/dist/run-cancel-context.d.ts +10 -0
  294. package/dist/run-cancel-context.js +1 -0
  295. package/dist/run-local.js +28 -13
  296. package/dist/runs.d.ts +31 -7
  297. package/dist/runs.js +34 -16
  298. package/dist/security.d.ts +3 -3
  299. package/dist/server-secret-env.d.ts +34 -20
  300. package/dist/server-secret-env.js +61 -18
  301. package/dist/session-agent.d.ts +4 -12
  302. package/dist/session-agent.js +0 -6
  303. package/dist/session-children-retire.d.ts +6 -3
  304. package/dist/session-children-retire.js +2 -5
  305. package/dist/session-incarnation.d.ts +18 -4
  306. package/dist/session-incarnation.js +4 -1
  307. package/dist/session-notify-door.d.ts +4 -4
  308. package/dist/session-notify-door.js +5 -6
  309. package/dist/session-rules-seat.d.ts +4 -3
  310. package/dist/session-rules-seat.js +3 -11
  311. package/dist/session-sync.js +3 -3
  312. package/dist/session-workspace.d.ts +3 -3
  313. package/dist/store-admission.d.ts +33 -0
  314. package/dist/store-admission.js +49 -0
  315. package/dist/store-posture.d.ts +5 -0
  316. package/dist/store-posture.js +18 -1
  317. package/dist/stores-sql/checkpoint-store-sql.d.ts +22 -3
  318. package/dist/stores-sql/checkpoint-store-sql.js +109 -23
  319. package/dist/stores-sql/file-history-store-sql.d.ts +1 -1
  320. package/dist/stores-sql/file-history-store-sql.js +3 -5
  321. package/dist/stores-sql/retention-store-sql.d.ts +1 -1
  322. package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
  323. package/dist/stores-sql/tool-result-store-sql.js +4 -6
  324. package/dist/task-a2a.d.ts +3 -8
  325. package/dist/task-a2a.js +25 -27
  326. package/dist/task-cwd.d.ts +27 -10
  327. package/dist/task-cwd.js +3 -0
  328. package/dist/task-mcp.d.ts +3 -3
  329. package/dist/task-mcp.js +1 -1
  330. package/dist/task-settings.d.ts +13 -0
  331. package/dist/task-settings.js +14 -7
  332. package/dist/terminal.d.ts +2 -0
  333. package/dist/terminal.js +21 -6
  334. package/dist/tool-approval.d.ts +50 -41
  335. package/dist/tool-approval.js +96 -73
  336. package/dist/trace/engine-notice-wire.d.ts +38 -21
  337. package/dist/trace/engine-notice-wire.js +25 -4
  338. package/dist/trace/ledger-sink.d.ts +3 -1
  339. package/dist/trace/project.d.ts +8 -5
  340. package/dist/trace/project.js +11 -9
  341. package/dist/trace/projection-table.d.ts +33 -2
  342. package/dist/trace/redact.d.ts +12 -0
  343. package/dist/trace/redact.js +5 -1
  344. package/dist/trace/self-minted-wire.d.ts +268 -56
  345. package/dist/trace/self-minted-wire.js +110 -40
  346. package/dist/trace/tool-card.d.ts +3 -0
  347. package/dist/trace/tool-card.js +24 -0
  348. package/dist/trace/tool-output-media.d.ts +2 -1
  349. package/dist/unattended-permission-mode.d.ts +1 -1
  350. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  351. package/dist/web-admin-client/apply-effective.js +22 -9
  352. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  353. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  354. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
  355. package/docs/error-text-lexicon.json +317 -0
  356. package/package.json +4 -2
  357. package/scripts/embed-minimal.mjs +183 -0
  358. package/wire-changes/server@7.149.0.json +372 -0
  359. package/wire-changes/server@7.150.0.json +335 -0
  360. package/dist/plain-string-record.js +0 -70
@@ -11,16 +11,30 @@
11
11
  * `policyFace` = 策略面〔面表键〕,与 `session_owner_unreadable` 那一行的 `face` = 口名分开命名:一个字段名一义)。
12
12
  *
13
13
  * 嵌套可选读(会话面板的上一腿、审批预览)与协议口(A2A、leader、提交重放)用 {@link seesRun} / {@link seesSession}:不下发,看不见 = 没有,由调用点走它自己的缺席路径。
14
+ *
15
+ * ## 读只经这里([ref] 第二阶段)
16
+ * 请求路径上带属主的 run / 会话行**只有本模块读**,交出去的只有两种:**承认**(判过的行 —— 门 `admit*`、非下发读 `readVisible*`、承认之后的重读也是这两只,
17
+ * 同一只入口再判一次)与**不带属主格的一格事实**(`*FactsOf` / `*LeafReadOf` / `latestRunIdOf` / `sessionAgentOf`:持有认领的腿与承认派生的读要的那一格 ——
18
+ * 状态 / 位置 / 所属会话 / 叶子 / 委派元组,行本身不出本模块)。列表的属主过滤落成店的过滤参数也只在这里({@link listVisibleRuns} / {@link listRunsOfScope})。
19
+ * 路由层看到的店在型上没有按 id 读口({@link RouteRunStore} / {@link RouteSessionStore}:那几口的型是 `never`,调不了;视图仍是那只店的子型,交给本模块的口与持认领腿的
20
+ * 写口照常),视图只在一处铸({@link sealRouteDeps})。
14
21
  */
15
22
  import type { IncomingMessage, ServerResponse } from "node:http";
16
- import type { SessionHead } from "@sema-agent/core";
23
+ import type { SessionHead, WorkflowRun, WorkflowRunStore } from "@sema-agent/core";
24
+ import type { RunStore, StoreBackend } from "../plugins/store-backend.js";
17
25
  import { type Logger } from "../observability/logger.js";
18
- import type { RunRecord } from "../plugins/store-contracts.js";
26
+ import type { LatestRunRef, RunListQuery, RunRecord } from "../plugins/store-contracts.js";
19
27
  import type { ServiceConfig } from "../config-types.js";
20
- import { type Admitted, type Caller, type FaceId, type ListFaceId, type ListFilter, type OwnedReading, type Qual, type RunFaceId, type SessionFaceId } from "../owner-faces.js";
28
+ import type { SessionAuditReadOpts } from "../audit.js";
29
+ import { type DeploymentShapeInput } from "../deployment-shape.js";
30
+ import { type SessionAgent } from "../session-agent.js";
31
+ import { type SessionFace } from "../session-incarnation.js";
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";
21
33
  import { type Person, type Subject } from "../owner-brands.js";
22
34
  import { type OwnerAwareSessionStore } from "../security.js";
23
35
  import { type OperatorRoster } from "./principal-gate.js";
36
+ import { type RouteDeps } from "./route-ctx.js";
37
+ import type { FlatServiceDeps } from "./server.js";
24
38
  import type { AgentRosterRouteId } from "./routes/agents-roster.js";
25
39
  import type { ApprovalsAssistantRouteId } from "./routes/approvals-assistant.js";
26
40
  import type { BackgroundRouteId } from "./routes/background.js";
@@ -36,6 +50,7 @@ import type { SessionSyncRouteId } from "./routes/session-sync.js";
36
50
  import type { SessionsListRouteId } from "./routes/sessions-list.js";
37
51
  import type { SessionsRouteId } from "./routes/sessions.js";
38
52
  import type { TraceUsageRouteId } from "./routes/trace-usage.js";
53
+ import type { WorkflowAgentSteerRouteId, WorkflowsRouteId } from "./routes/workflows.js";
39
54
  /** 存取器读的装配:部署配置(身份来源只从配置读,见 `identity-source.ts` 的 `configuredIdentitySources`)+ 运维日志。`FlatServiceDeps` 结构上满足。 */
40
55
  export interface OwnerAccessWiring {
41
56
  readonly config: ServiceConfig;
@@ -43,8 +58,9 @@ export interface OwnerAccessWiring {
43
58
  }
44
59
  /**
45
60
  * 🔴 **一次请求的调用方**(唯一铸点之一;另一只是决定口的 {@link callerOfDecision}、提交挂接的 `security.ts` `claimCallerOf`)。
46
- * 主体 = `gatedSubject`(验身份的那一只;带场景头 ⇒ 这个人的那一格分区);运维 = `explicitOperatorOk(personOf(主体))`(唯一读法,读人);fleet = 部署没有身份边界(`devOpenDeployment`)或出示 service 凭据、
47
- * 不报主体、部署没声明关掉(`actsForDeployment`),两者互斥(前者要求没配凭据);只读 trace 凭据单列(它只在读档算 fleet,见面表 `fleet` 列)。
61
+ * 主体 = `gatedSubject`(验身份的那一只;带场景头 ⇒ 这个人的那一格分区);运维 = `explicitOperatorOk(personOf(主体))`(唯一读法,读人);fleet = `actsForDeployment`
62
+ * (唯一读法:报了主体 ⇒ 不是 fleet;不报主体 ⇒ 部署没有身份边界时 `dev_open`、出示部署让它代自己说话的 service 凭据时 `deployment_token`,两者互斥 —— 前者要求没配凭据);
63
+ * 只读 trace 凭据单列(它只在读档算 fleet,见面表 `fleet` 列)。报了主体的调用方因此在每一口都是那位主体,与提交挂接的 `claimCallerOf`(fleet 恒缺)同读。
48
64
  */
49
65
  export declare function callerOf(req: IncomingMessage, w: Pick<OwnerAccessWiring, "config">): Caller;
50
66
  /**
@@ -55,10 +71,10 @@ export declare function callerOf(req: IncomingMessage, w: Pick<OwnerAccessWiring
55
71
  export declare function callerOfDecision(base: Caller, decider: Person | undefined, roster: OperatorRoster): Caller;
56
72
  /** 决定者的主体(唯一读法;{@link callerOfDecision} 与只要主体 + 运维位的决断腿同读):证明推出的人 × 请求的场景(请求没带场景 ⇒ 与人逐字节同)。 */
57
73
  export declare function deciderSubjectOf(requestSubject: Subject | undefined, decider: Person | undefined): Subject | undefined;
58
- /** 属主面与列表面所在十六个域的路由 id(全部;无属主门的那几条登 `null`)。 */
59
- export type OwnedRouteId = RunsRouteId | RunVerbsRouteId | RunPermissionModeRouteId | RunMemoryCaptureRouteId | SessionsRouteId | SessionSyncRouteId | SessionMemorySyncRouteId | BackgroundRouteId | McpReconnectRouteId | NotifyWakeRouteId | TraceUsageRouteId | ApprovalsAssistantRouteId | SessionsListRouteId | FleetRouteId | ProjectsRouteId | AgentRosterRouteId;
74
+ /** 属主面与列表面所在十八个域的路由 id(全部;无属主门的那几条登 `null`)。 */
75
+ export type OwnedRouteId = WorkflowsRouteId | WorkflowAgentSteerRouteId | RunsRouteId | RunVerbsRouteId | RunPermissionModeRouteId | RunMemoryCaptureRouteId | SessionsRouteId | SessionSyncRouteId | SessionMemorySyncRouteId | BackgroundRouteId | McpReconnectRouteId | NotifyWakeRouteId | TraceUsageRouteId | ApprovalsAssistantRouteId | SessionsListRouteId | FleetRouteId | ProjectsRouteId | AgentRosterRouteId;
60
76
  /**
61
- * 🔴 **路由 → 面**(闭集穷举;`satisfies Record<…>`:十六个路由域里加一条路由不登 = 编译红,登错资源的面由 {@link admitRunRow} / {@link admitSessionRow} 的签名挡)。
77
+ * 🔴 **路由 → 面**(闭集穷举;`satisfies Record<…>`:十八个路由域里加一条路由不登 = 编译红,登错资源的面由 {@link admitRunRow} / {@link admitSessionRow} / {@link admitWorkflowRun} 的签名挡)。
62
78
  * 列表 / 舰队读面登列表面(`list.read` / `session.list`:属主视域经 `owner-faces.ts` 的 `listFilterOf` 从这一行派生)。
63
79
  * `null` = 这条路由不在本表判属主:提交面、ask / 检查点面(属主门在腿里经 `owner-faces.ts` 的 `keyAdmits` 判:决定 / 应答的属主是停驻行与问账行,不是路径上的这一行)。
64
80
  */
@@ -133,6 +149,11 @@ export declare const ROUTE_FACES: {
133
149
  readonly "assistant-task-preempt": "run.preempt";
134
150
  readonly "assistant-task-resume": "run.resume";
135
151
  readonly "assistant-task-plan-review": "run.decision";
152
+ readonly "workflows-list": "workflow.read";
153
+ readonly "workflow-detail": "workflow.read";
154
+ readonly "workflow-journal": "workflow.read";
155
+ readonly "workflow-stream": "workflow.read";
156
+ readonly "workflow-agent-steer": "workflow.steer";
136
157
  readonly "sessions-list": "session.list";
137
158
  readonly "sendfile-links": "list.read";
138
159
  readonly "fleet-stream": "list.read";
@@ -152,7 +173,11 @@ export type SessionRouteId = {
152
173
  export type ListRouteId = {
153
174
  [R in keyof RouteFaces]: RouteFaces[R] extends ListFaceId ? R : never;
154
175
  }[keyof RouteFaces];
155
- type RoutedId = RunRouteId | SessionRouteId | ListRouteId;
176
+ /** 登到工作流面的路由(由表派生)。 */
177
+ export type WorkflowRouteId = {
178
+ [R in keyof RouteFaces]: RouteFaces[R] extends WorkflowFaceId ? R : never;
179
+ }[keyof RouteFaces];
180
+ type RoutedId = RunRouteId | SessionRouteId | ListRouteId | WorkflowRouteId;
156
181
  /** 协议口 / 嵌套读的面(不经路由表的那几只;路由面一律经 {@link ROUTE_FACES})。 */
157
182
  export type ProtocolFaceId = "run.a2a" | "run.leader" | "run.replay" | "run.preview" | "run.panel" | "run.anchor";
158
183
  /** 读 run 行的口:登到 run 面的路由 + 协议口 / 嵌套读(由两张既有闭集派生)。 */
@@ -342,14 +367,18 @@ export declare function deliverVerdict<R extends OwnedReading>(entry: Entry, res
342
367
  * 交回承认(行 + 全部资格)或 `undefined`(已应答)。`id` = 路径上的 run id(句子的句柄指路;按幂等键读的口不传)。
343
368
  */
344
369
  export declare function admitRunRow(entry: Entry, res: ServerResponse, runStore: RunObserver, row: RunRecord | null | undefined, id?: string): Promise<Admitted<RunRecord> | undefined>;
370
+ /** 本模块门读的 run 店:按 id 读口 + 观察口(路由层的视图上这一读口封着 —— 视图交得进来,路由自己调不了)。 */
371
+ export type RunGateStore = Pick<RunStore, "getRun"> & RunObserver;
345
372
  /** run 面的门,行由本模块读(店唯一的按 id 读 `getRun`):路由不再自己读行(裸读普查门 ④ 的路由基线据此归零)。 */
346
- export declare function admitRunById(entry: Entry, res: ServerResponse, runStore: {
347
- getRun(taskId: string): Promise<RunRecord | null | undefined>;
348
- } & RunObserver, taskId: string): Promise<Admitted<RunRecord> | undefined>;
349
- /** 嵌套可选读 / 协议口的 run 行读(不下发):本模块按 id 读一行并判,看不见 ≡ 没有(`undefined`),调用点走它自己的缺席路径。 */
350
- export declare function readVisibleRun(entry: Entry, runStore: {
351
- getRun(taskId: string): Promise<RunRecord | null | undefined>;
352
- } & RunObserver, taskId: string): Promise<RunRecord | undefined>;
373
+ export declare function admitRunById(entry: Entry, res: ServerResponse, runStore: RunGateStore, taskId: string): Promise<Admitted<RunRecord> | undefined>;
374
+ /** run 面的门,按提交幂等键读行(`GET /v1/runs?idempotencyKey=`;键由调用方的身份铸,别人的键算出的是另一把):没有 / 看不见同一只投影,没有路径 id ⇒ 常量句。 */
375
+ export declare function admitRunByIdem(entry: Entry, res: ServerResponse, runStore: Pick<RunStore, "getRunByIdem"> & RunObserver, idemKey: string): Promise<Admitted<RunRecord> | undefined>;
376
+ /**
377
+ * run 行的非下发读:本模块按 id 读一行并判(属主门 + 本口的 `RUN_STATE_FACES`),看不见 ≡ 没有(`undefined`),调用点走它自己的缺席路径。
378
+ * 两种读者同用:嵌套可选读 / 协议口,与**承认之后的重读**(取消 / 抢占 / steer / 中断的竞态重读、流的逐拍复读、A2A 的等待循环)—— 重读用承认它的同一只入口,
379
+ * 对新读数再判一次同一只(run 行的属主不变,这一判对同一位调用方恒同答;行没了 ⇒ 没有)。交回承认(行 + 资格)。
380
+ */
381
+ export declare function readVisibleRun(entry: Entry, runStore: RunGateStore, taskId: string): Promise<Admitted<RunRecord> | undefined>;
353
382
  /** run 行可见吗(不下发;嵌套可选读与协议口):看不见 ≡ 没有。 */
354
383
  export declare function seesRun(entry: Entry, owner: string | null | undefined): boolean;
355
384
  /**
@@ -375,16 +404,35 @@ export declare function readOwnerCell<T>(entry: Entry, sessionId: string, read:
375
404
  * 会话面的门:调用点读到的那一读(`undefined` / `null` = 没有;读不出按面折过的也是 `undefined`)交进来 —— 没有 ⇒ 投影;行格(无主、且 placement 改得了判时问一次);
376
405
  * 运维旁路 → 前门 → 看不见 ⇒ 同一投影。交回承认(读数 + 全部资格)或 `undefined`(已应答)。
377
406
  */
378
- export declare function admitSessionRow<T extends OwnedReading>(entry: Entry, res: ServerResponse, store: Pick<OwnerAwareSessionStore, "placementOf"> | undefined, sessionId: string, reading: T | null | undefined): Promise<Admitted<T> | undefined>;
407
+ export declare function admitSessionRow<T extends OwnedReading>(entry: Entry, res: ServerResponse, store: PlacementReadingStore | undefined, sessionId: string, reading: T | null | undefined): Promise<Admitted<T> | undefined>;
379
408
  /**
380
409
  * 会话行的判(不下发):行格只经 `security.ts` 的 {@link sessionCellFor}(无主行的 placed 位只在两种假设不都放行时问店;存档读不出按面表 `placementUnreadable` 列;
381
410
  * 别的读故障照常上抛)。事件流把这一判整个框进它的读期上限,判完再 {@link deliverVerdict}。
382
411
  */
383
- export declare function judgeSessionRow<T extends OwnedReading>(entry: Entry, store: Pick<OwnerAwareSessionStore, "placementOf"> | undefined, sessionId: string, reading: T): Promise<OwnerVerdict<T>>;
384
- /** 会话面的门,头由本模块读(会话店唯一的按 id 读 `headOf`;读不出按面的 `unreadable` 列折):路由不再自己读头。 */
385
- export declare function admitSessionById(entry: Entry, res: ServerResponse, store: Pick<OwnerAwareSessionStore, "placementOf"> & Required<Pick<OwnerAwareSessionStore, "headOf">>, sessionId: string): Promise<Admitted<SessionHead> | undefined>;
412
+ export declare function judgeSessionRow<T extends OwnedReading>(entry: Entry, store: PlacementReadingStore | undefined, sessionId: string, reading: T): Promise<OwnerVerdict<T>>;
413
+ /** 本模块门读的会话店:按 id 头读(路由层的视图上封着)+ 无主行 placed 位的问询(可缺)。 */
414
+ export type SessionGateStore = Required<Pick<OwnerAwareSessionStore, "headOf">> & PlacementReadingStore;
415
+ /** 交 placed 位问询的店(可缺:店不交 ⇒ 无主行读作普通无主行,`security.ts` 的 `sessionOwnerCellOf`)。 */
416
+ export type PlacementReadingStore = Pick<OwnerAwareSessionStore, "placementOf">;
417
+ /**
418
+ * 会话面按 id 的判(不下发):头由本模块读(会话店唯一的按 id 读 `headOf`;读不出按面的 `unreadable` 列折)并判;`undefined` = 没有这一行。
419
+ * 门 {@link admitSessionById} 与非下发读 {@link readVisibleSession} 都是它;事件流把它整个框进自己的读期上限,判完再 {@link deliverVerdict}。
420
+ */
421
+ export declare function judgeSessionById(entry: Entry, store: SessionGateStore, sessionId: string): Promise<OwnerVerdict<SessionHead> | undefined>;
422
+ /** 会话面的门,头由本模块读:路由不再自己读头。没有 ⇒ 投影;前门 / 看不见经各自的下发口。 */
423
+ export declare function admitSessionById(entry: Entry, res: ServerResponse, store: SessionGateStore, sessionId: string): Promise<Admitted<SessionHead> | undefined>;
424
+ /**
425
+ * 会话行的非下发读:看不见 ≡ 没有。**承认之后的重读**用它(同一只入口对新读数再判一次同一只:两读之间易主 ⇒ 按新主判;行没了 ⇒ 没有)——
426
+ * 记忆同步栅栏的叶子复读等。住客(化身)绑定不在这里(见 `owner-faces.ts` 的 `Admitted`)。
427
+ */
428
+ export declare function readVisibleSession(entry: Entry, store: SessionGateStore, sessionId: string): Promise<Admitted<SessionHead> | undefined>;
429
+ /**
430
+ * 承认之后的**世代围栏**(会话事件流的心跳拍):这只会话此刻的属主还是承认时读到的那一格吗 —— 删了(没有这一行 / 读不出按面折)或换主 ⇒ 否。
431
+ * 与 {@link readVisibleSession} 的「再判可见」不同:比的是同一行前后两次读到的属主(删建 / 易主 ⇒ 作废),两侧都是行上的属主,不是调用方身份。
432
+ */
433
+ export declare function sessionOwnerUnchanged(entry: Entry, store: SessionGateStore, sessionId: string, admittedOwner: string | null): Promise<boolean>;
386
434
  /** 会话行的完整判(不下发,交回承认 / `undefined`):两读之间要再判一次的口(同步导入的提交前复判)与「看不见按自己的形答」的口用。 */
387
- export declare function judgeSession<T extends OwnedReading>(entry: Entry, store: Pick<OwnerAwareSessionStore, "placementOf"> | undefined, sessionId: string, reading: T): Promise<Admitted<T> | undefined>;
435
+ export declare function judgeSession<T extends OwnedReading>(entry: Entry, store: PlacementReadingStore | undefined, sessionId: string, reading: T): Promise<Admitted<T> | undefined>;
388
436
  /** 这一份承认里的调用方是 fleet 吗(本口 `fleet` 列里的一格成立):fork 新属主「继承源属主」那一支读它。 */
389
437
  export declare function admittedAsFleet(entry: Entry, admitted: {
390
438
  readonly quals: ReadonlySet<Qual>;
@@ -396,5 +444,182 @@ export declare function entryIsFleet(entry: Entry): boolean;
396
444
  * 路由 id 查表得列表面,`owner-faces.ts` 的 `listFilterOf` 从那一行派生(一只读法;trace 列表经 {@link enter} 拿入口后同读它)。
397
445
  */
398
446
  export declare function routeListFilter<R extends ListRouteId>(req: IncomingMessage, w: Pick<OwnerAccessWiring, "config">, route: R): ListFilter;
447
+ /** run 店上读出带属主行的口(闭集):按 id、按提交幂等键、按会话(最近一条腿)、列表。 */
448
+ export type RunRowReadName = "getRun" | "getRunByIdem" | "latestRunForSession" | "listRuns";
449
+ /** 会话店上按 id 读出带属主行的口(闭集):头读、删除门的头读、委派子代的 placed 位 / 元组。 */
450
+ export type SessionRowReadName = "headOf" | "deletionHeadOf" | "placementOf";
451
+ /**
452
+ * 封口:这几口在型上调不了 —— 值上原样在。每一口的可缺与否照抄店形(`keyof Pick<T, K>` 同态保留修饰):店必交的读口 ⇒ 必有的 `never`;可缺的读口 ⇒ 可缺的 `never`(读作 `undefined`,
453
+ * 「在场」仍要能力事实证明:判过在场的见证上那一格是必有的 `never`,交得进要它在场的口)。修饰不能统一写成可缺:必有的方法与可缺的 `never` 相交,TS 把整只交叉型约成 `never`。
454
+ * 视图是那只店的**子型**:本模块的口与持认领腿的写口收完整的店形,视图交得进去。
455
+ */
456
+ type ReadsSealed<T, K extends keyof T> = {
457
+ readonly [P in keyof Pick<T, K>]: never;
458
+ };
459
+ /** 路由层看到的 run 店({@link RunRowReadName} 封着)。 */
460
+ export type RouteRunStore = RunStore & ReadsSealed<RunStore, RunRowReadName>;
461
+ /** 路由层看到的会话店({@link SessionRowReadName} 封着)。 */
462
+ export type RouteSessionStore = OwnerAwareSessionStore & ReadsSealed<OwnerAwareSessionStore, SessionRowReadName>;
463
+ /** 路由层看到的存储后端:铸 run 店 / 会话店的两只工厂封着(路由从后端拿不到一只没封的店;后端的其余面照常)。 */
464
+ export type RouteBackend = StoreBackend & ReadsSealed<StoreBackend, "run" | "session">;
465
+ /**
466
+ * 🔴 **铸路由层的 deps 视图 —— 全仓唯一的一处**(`route-ctx.ts` 的 `RouteDeps`;值就是服务的那一只 deps,只在型上封住带属主的读口)。
467
+ * 子型收窄只能在铸点上说一次:之后路由拿到的 run / 会话店读不出带属主的行(编译红),交给本模块的口照读。
468
+ */
469
+ export declare function sealRouteDeps(deps: FlatServiceDeps): RouteDeps;
470
+ /**
471
+ * 一条 run **不带属主格**的事实:状态、位置(哪一副本在跑)、所属会话。读者两种 —— 持有会话认领的腿读它持有 / 输给的那一条(认领冲突的 409 材料、
472
+ * 决定投递的回执幂等、提交流的兜底收场、取消动词会不会结算那张卡),与承认派生的读(承认过的会话上那条在飞 run 的状态;决定口的证明要绑的会话)。
473
+ * 行不出本模块:要属主或整行就走门 / {@link readVisibleRun}。`undefined` = 没有这一行。
474
+ */
475
+ export interface RunFacts {
476
+ readonly status: RunRecord["status"];
477
+ readonly instanceId: RunRecord["instanceId"];
478
+ readonly sessionId: string;
479
+ }
480
+ export declare function runFactsOf(store: Pick<RunStore, "getRun">, taskId: string): Promise<RunFacts | undefined>;
481
+ /** 会话最近一条腿的 run id(不交属主;没有腿 ⇒ `undefined`):审批预览与记忆同步的栅栏只要 id —— 要行再经 {@link readVisibleRun} 判。 */
482
+ export declare function latestRunIdOf(store: Pick<RunStore, "latestRunForSession">, sessionId: string): Promise<string | undefined>;
483
+ /** 一只会话**不带属主 / 住客**的事实:叶子(`null` = 空会话)。叶子是惰性读(展开即读会话内容 —— 坏档在这里抛),只要「在不在」的读者不碰它。 */
484
+ export interface SessionFacts {
485
+ readonly leafId: string | null;
486
+ }
487
+ /**
488
+ * 会话事实的读口:`undefined` = 没有这只会话。店没有按 id 头读 ⇒ 交回 `undefined`(这台部署读不出,调用方按自己的缺席臂)。
489
+ * 读者:回退锚的逐轮捕获(两条起跑腿读叶子)、失认领答复的「会话在不在」(不碰叶子)、同步拉取清单的当前叶子。
490
+ */
491
+ export declare function sessionFactsReadOf(store: Pick<OwnerAwareSessionStore, "headOf"> | undefined): ((sessionId: string) => Promise<SessionFacts | undefined>) | undefined;
492
+ /**
493
+ * 会话在委派树里的位置(wire 键 `agent` 的值;唯一读口):店的 placed 位一读 → `session-agent.ts` 的 `sessionAgentOf`(元组不带属主)。店不交这一面 ⇒ `undefined`
494
+ * (这台部署不存元组,不探)。探针抛 ⇒ 原样上抛 —— 读不出怎么说归读者(视图读响亮失败;队列只缺那一行的键并计数),本函数不替任何一面把故障说成「不是子代」。
495
+ */
496
+ export declare function readSessionAgent(store: Pick<OwnerAwareSessionStore, "placementOf"> | undefined, sessionId: string): Promise<SessionAgent | undefined>;
497
+ /**
498
+ * 会话通知投递之前的住客复核(律在 `session-notify-door.ts` 头注「复核住客」):此刻的住客还是门承认过的那一位吗 —— `same` / `gone`(会话没了)/ `replaced`(换了住客)。
499
+ * 店没有按 id 头读 ⇒ 交回 `undefined`(调用方先判;门响亮拒)。
500
+ */
501
+ export declare function occupantRecheckOf(store: Pick<OwnerAwareSessionStore, "headOf"> | undefined): ((sessionId: string, occupant: Pick<SessionHead, "owner" | "incarnation">) => Promise<"same" | "gone" | "replaced">) | undefined;
502
+ /**
503
+ * 引擎会话规则席的键(律在 `session-rules-seat.ts` 头注):引擎交来的人恰是这只会话属主背后的人 ⇒ 键 = 会话属主;否则原样(没带场景的会话属主与人字节相同)。
504
+ * 属主只经会话店的头读一处;读不到头(会话不在 / 店不交头读)⇒ 原样。
505
+ */
506
+ export declare function engineRulesKeyOf(store: Pick<OwnerAwareSessionStore, "headOf"> | undefined, sessionId: string, principal: string | undefined): Promise<string | undefined>;
507
+ /**
508
+ * 会话最近一条腿的 run 指针(`LatestRunRef`:id + 属主 + 排序键;刻意不是整行 —— 不把结果 blob 拖进按会话的读)经本口的属主门判:看不见 ≡ 没有。
509
+ * 读者:会话面板的上一腿(面 `run.panel`,看不见 = 不投那个键)。
510
+ */
511
+ 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} 从视域派生,只在这里落成店的过滤参数。 */
515
+ export declare function listVisibleRuns(store: Pick<RunStore, "listRuns">, filter: ListFilter, named: string | undefined, query: Omit<RunListQuery, "owner">): Promise<RunRecord[]>;
516
+ /** 审批 / 助手面按停驻 scope 列 run:属主过滤 = scope 的属主键(公共 scope `_` ⇒ 属主为 null 的 run,主体 ⇒ 恰它的;`security.ts` 的唯一编解码),只在这里落成店的过滤参数。 */
517
+ export declare function listRunsOfScope(store: Pick<RunStore, "listRuns">, scope: string, limit: number): Promise<RunRecord[]>;
518
+ /** 一把提交钥匙命中的行对这位调用方算什么:`visible` = 读得到的那一行;`occupied` = 有行但不是这次提交拿得到的(看不见 / 自带 taskId 而键指着别的行)—— 回执 409,不回显那一行。 */
519
+ export type ReplayHit = {
520
+ readonly kind: "visible";
521
+ readonly row: RunRecord;
522
+ } | {
523
+ readonly kind: "occupied";
524
+ };
525
+ /** 提交重放的判(纯):命中的行(进门按钥匙读到的 / 建行撞唯一键时观察到的)对这位提交者(认领面的调用方 `claimCallerOf`:不放 fleet、不放运维)算什么。 */
526
+ export declare function replayHitOf(subject: Subject | undefined, config: DeploymentShapeInput<"principal">, row: RunRecord, clientTaskId: string | undefined): ReplayHit;
527
+ /** 提交重放读:按一把钥匙读行(`Idempotency-Key` 铸的键,或调用方自铸的 `body.taskId`)并判;没有命中 ⇒ `undefined`(这是一次新提交)。 */
528
+ export declare function readReplayHit(subject: Subject | undefined, config: DeploymentShapeInput<"principal">, store: Pick<RunStore, "getRun" | "getRunByIdem">, key: {
529
+ readonly idemKey: string;
530
+ } | {
531
+ readonly taskId: string;
532
+ }, clientTaskId: string | undefined): Promise<ReplayHit | undefined>;
533
+ /** 会话视图读(`sessionAudit`:存档读出的视图 + 头读的属主)。 */
534
+ type SessionViewRead = NonNullable<FlatServiceDeps["sessionAudit"]>;
535
+ /**
536
+ * 读**会话视图**的三口(`GET /v1/sessions/:id` / `…/memory-status` / `…/memory/erase`)的「归属 + 读存档」**唯一**一段([ref];律在 `routes/sessions.ts` 的调用点注):
537
+ * 会话店有头读 ⇒ 先判归属(门同 head / fork / sync 各口),非属主拿到的应答与「属主的会话完好」时逐字相同;只接了视图面 ⇒ 视图只能先读,读失败时归属还没判出来 ⇒
538
+ * 换成一只不带码的错上抛。视图读完之后再判一次同一只(两读之间换主 ⇒ 按新主拒;读后会话消失 ⇒ 没有这一行)。交回视图,`undefined` = 已应答。
539
+ */
540
+ export declare function admitSessionView(entry: Entry, res: ServerResponse, store: Pick<OwnerAwareSessionStore, "headOf" | "placementOf"> | undefined, sessionAudit: SessionViewRead, sessionId: string, readOpts?: SessionAuditReadOpts): Promise<({
541
+ owner: string | null;
542
+ } & Record<string, unknown>) | undefined>;
543
+ /** 同步族的门读结果:活行的住客(拉取只认它)、占着这个 id 的那一位(活行 ∪ 在删行)、这位调用方碰不碰得了占着的那一行(面 `session.own`)。 */
544
+ export interface SyncGateReading {
545
+ readonly face: SessionFace | undefined;
546
+ readonly occupant: SessionFace | undefined;
547
+ readonly mayTouch: boolean;
548
+ }
549
+ /**
550
+ * 同步族(拉取 / 推送 / 干跑 / 导入第二阶段)的门读 —— 一只判据、两个时刻(律在 `routes/session-sync.ts` 的门注):会话店的头读投成活住客;「这个 id 被占着吗」只有
551
+ * 一种读法,与认领面同一只 `deletionHeadReadOf`(活行 ∪ 在删行:在删的行对活行读法是「不在」,但它仍占着这个 id);占着的那一行准不准这位调用方碰 = 面表 `session.own`。
552
+ */
553
+ export declare function readSyncGate(entry: Entry, store: DeletionGateStore, sessionId: string): Promise<SyncGateReading>;
554
+ /** 工具结果店的出处读口(core `ToolResultStore.ownerOf`:这枚 ref 写下时声明的会话 / task)。 */
555
+ export interface ToolResultProvenanceReader {
556
+ ownerOf?(ref: string): Promise<{
557
+ readonly sessionId: string;
558
+ readonly taskId?: string;
559
+ } | undefined> | {
560
+ readonly sessionId: string;
561
+ readonly taskId?: string;
562
+ } | undefined;
563
+ }
564
+ /**
565
+ * 一枚工具结果 ref 属于这条**已承认**的 run 吗(律在 `routes/trace-usage.ts` 的 ②-a 段):店记着的出处是这条 run 的会话,且出处若点名了 task 则必须是这条。
566
+ * 店不交出处 / 出处缺席 ⇒ 判不过(fail-closed:读面对没有出处的 ref 一律 404)。
567
+ */
568
+ export declare function toolResultRefOwned(store: ToolResultProvenanceReader | undefined, ref: string, run: Pick<RunRecord, "sessionId" | "taskId">): Promise<boolean>;
569
+ /**
570
+ * leader 登记表的请求口读(协议面 `run.leader`;`GET /v1/leader/:id` 与取消口,含取消口 CAS 输之后的重读):按 id 读一行,按交来的可见判
571
+ * (boot 装的 `seesRunAs("run.leader")`)判,看不见 ≡ 没有。驱动腿与旗读拍读本副本自己在驱动的行,不经这里。
572
+ */
573
+ export declare function readVisibleLeaderRow<R extends {
574
+ readonly owner: string | null;
575
+ }>(store: {
576
+ getRun(id: string): Promise<R | undefined>;
577
+ }, id: string, visible: (owner: string | null) => boolean): Promise<R | undefined>;
578
+ /** 工作流按 id 四口的会话断言(受理相;`label` = 发过的日志字段 `face`;判法与 run 面同一只 {@link sessionAsserted})。列表口不判(摘要没有那一格)。 */
579
+ export declare const WORKFLOW_SESSION_ASSERTION: {
580
+ readonly "workflow-detail": {
581
+ readonly phase: "accept";
582
+ readonly label: "workflow.detail";
583
+ };
584
+ readonly "workflow-journal": {
585
+ readonly phase: "accept";
586
+ readonly label: "workflow.journal";
587
+ };
588
+ readonly "workflow-stream": {
589
+ readonly phase: "accept";
590
+ readonly label: "workflow.stream";
591
+ };
592
+ readonly "workflow-agent-steer": {
593
+ readonly phase: "accept";
594
+ readonly label: "workflow.agent-steer";
595
+ };
596
+ };
597
+ /** 工作流行的承认:门放过的那一行 + 调用方(换成引擎身份之后)对它持有的全部资格。 */
598
+ export interface WorkflowAdmission {
599
+ readonly row: WorkflowRun;
600
+ readonly quals: ReadonlySet<Qual>;
601
+ }
602
+ /** 工作流门的一次判(不下发):承认,或拒因(没有 / 前门 / 看不见 / 会话断言不符)。 */
603
+ export type WorkflowVerdict = WorkflowAdmission | "missing" | "door" | "not_visible" | "session_mismatch";
604
+ /**
605
+ * 工作流列表(`GET /v1/workflows`)—— 属主过滤只在这里落成店参数:调用方换成它的引擎身份(与 {@link judgeWorkflowRun} 同一只换算),店按 `scope` 列筛。
606
+ * 面表 `workflow.read` 只给属主(不放 fleet / 运维)⇒ 列表 = 调用方自己那一格的行。
607
+ */
608
+ export declare function listVisibleWorkflows(entry: Entry, store: Pick<WorkflowRunStore, "listByScope">, opts: Parameters<WorkflowRunStore["listByScope"]>[1]): ReturnType<WorkflowRunStore["listByScope"]>;
609
+ /**
610
+ * 🔴 **工作流行的判(唯一一处;[ref] 第二阶段)**:按 id 读一行(店的 `get`,不带 scope —— 修前是 core 按 scope 读 + 路由再比一次 scope,两读答同一问),
611
+ * 行格 = `scope` 列的属主键(引擎写下的引擎身份,恒有主);调用方一侧换成它的引擎身份(`engine-identity.ts` 的 `engineScopeOf`:引擎按它写 scope ——
612
+ * 带场景的请求是那个人,匿名是 `"default"`)再过事实函数 {@link qualsOf} + 面表;前门按这次请求的调用方判。承认之后按 {@link WORKFLOW_SESSION_ASSERTION} 判会话断言。
613
+ */
614
+ export declare function judgeWorkflowRun(entry: Entry, store: Pick<WorkflowRunStore, "get">, runId: string): Promise<WorkflowVerdict>;
615
+ /** 工作流按 id 读面的门:没有 / 看不见 / 会话断言不符同一只投影(`workflow_missing`),前门经它的下发口。交回承认或 `undefined`(已应答)。 */
616
+ export declare function admitWorkflowRun(entry: Entry, res: ServerResponse, store: Pick<WorkflowRunStore, "get">, runId: string): Promise<WorkflowAdmission | undefined>;
617
+ /** 删除门读的会话店:头读在场(能力事实 `sessionDelete` 的见证)+ 店可交的删除门头读与 placed 位问询。 */
618
+ export type DeletionGateStore = SessionGateStore & Pick<OwnerAwareSessionStore, "deletionHeadOf">;
619
+ /**
620
+ * 会话删除门(`DELETE /v1/sessions/:id`):读的头是删除门那一只(`session-incarnation.ts` 的 `deletionHeadReadOf`:local 店删到一半的行 —— 读者早已读作不在 —— 也答得出
621
+ * 开始删它的那位属主:那位重发收得完,别人得到与「不在」同一句;别的店 = `headOf`,与协调器围栏读同一只),行格的 placed 位问询 = 店自己的那一只(绑好宿主)。其余同 {@link admitSessionById}。
622
+ */
623
+ export declare function admitSessionForDeletion(entry: Entry, res: ServerResponse, store: DeletionGateStore, sessionId: string): Promise<Admitted<SessionHead> | undefined>;
399
624
  export {};
400
625
  //# sourceMappingURL=owner-access.d.ts.map
@@ -1,20 +1,23 @@
1
1
  import { createLogger } from "../observability/logger.js";
2
2
  import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
3
- import { FACES, fleetOn, listFilterOf, ownerCellOf, qualsOf, visibleOn } from "../owner-faces.js";
3
+ import { engineScopeOf } from "../engine-identity.js";
4
+ import { sameOccupant } from "../execution-placement.js";
5
+ import { sessionAgentOf } from "../session-agent.js";
6
+ import { deletionHeadReadOf, sessionFaceOfHead } from "../session-incarnation.js";
7
+ import { FACES, fleetOn, listFilterOf, ownerCellOf, qualsOf, recoveredSubject, visibleOn } from "../owner-faces.js";
4
8
  import { mintOwnedRow, partsOf, personOf, subjectOf } from "../owner-brands.js";
5
- import { sessionCellFor } from "../security.js";
9
+ import { claimCallerOf, ownerOfCheckpointScope, sessionCellFor } from "../security.js";
6
10
  import { openFaceFaultWire, SessionOwnerUnreadableError } from "../session-error-wire.js";
7
11
  import { seatText } from "../trace/exit-seat.js";
8
- import { actsForDeployment, devOpenDeployment, explicitOperatorOk, gatedSubject, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented } from "./principal-gate.js";
12
+ import { actsForDeployment, explicitOperatorOk, gatedSubject, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented } from "./principal-gate.js";
9
13
  import { RUN_NOT_FOUND_MESSAGE, runNotFoundMessage, SESSION_NOT_FOUND_MESSAGE } from "./route-ctx.js";
10
14
  import { sendError, sendJson } from "./send.js";
11
15
  export function callerOf(req, w) {
12
16
  const subject = gatedSubject(req, w.config);
13
- const fleet = devOpenDeployment(w.config) ? "dev_open" : actsForDeployment(req, w.config, () => subject) ? "deployment_token" : undefined;
14
17
  return {
15
18
  subject,
16
19
  operator: explicitOperatorOk(subject === undefined ? undefined : personOf(subject), w.config),
17
- fleet,
20
+ fleet: actsForDeployment(req, w.config, () => subject),
18
21
  traceRead: traceTokenPresented(req, w.config),
19
22
  principalRequired: DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(w.config),
20
23
  multiTenant: DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(w.config),
@@ -97,6 +100,11 @@ export const ROUTE_FACES = {
97
100
  "assistant-task-preempt": "run.preempt",
98
101
  "assistant-task-resume": "run.resume",
99
102
  "assistant-task-plan-review": "run.decision",
103
+ "workflows-list": "workflow.read",
104
+ "workflow-detail": "workflow.read",
105
+ "workflow-journal": "workflow.read",
106
+ "workflow-stream": "workflow.read",
107
+ "workflow-agent-steer": "workflow.steer",
100
108
  "sessions-list": "session.list",
101
109
  "sendfile-links": "list.read",
102
110
  "fleet-stream": "list.read",
@@ -277,6 +285,9 @@ export function refuse(entry, res, reason, id) {
277
285
  case "deleted_false":
278
286
  sendJson(res, 200, { deleted: false });
279
287
  return;
288
+ case "workflow_missing":
289
+ sendError(res, 404, "not_found.workflow", "workflow not found");
290
+ return;
280
291
  case "run_exists":
281
292
  case "attach_absent":
282
293
  case "omit":
@@ -291,8 +302,10 @@ function rowRead(reading) {
291
302
  return reading !== undefined && reading !== null;
292
303
  }
293
304
  function verdictOn(entry, cell) {
305
+ return verdictOnQuals(entry, qualsOf(entry.caller, cell));
306
+ }
307
+ function verdictOnQuals(entry, quals) {
294
308
  const face = FACES[entry.face];
295
- const quals = qualsOf(entry.caller, cell);
296
309
  if (face.operator && quals.has("operator"))
297
310
  return quals;
298
311
  if (doorRefusal(face, entry.face, entry.caller) !== undefined)
@@ -326,14 +339,23 @@ export async function admitRunRow(entry, res, runStore, row, id) {
326
339
  refuse(entry, res, "session_mismatch", id);
327
340
  return undefined;
328
341
  }
342
+ return observedAdmission(entry, runStore, admitted);
343
+ }
344
+ async function observedAdmission(entry, runStore, admitted) {
329
345
  return { ...admitted, row: mintOwnedRow(await runRowAt(entry.mouth, runStore, admitted.row)) };
330
346
  }
331
347
  export async function admitRunById(entry, res, runStore, taskId) {
332
348
  return admitRunRow(entry, res, runStore, await runStore.getRun(taskId), taskId);
333
349
  }
350
+ export async function admitRunByIdem(entry, res, runStore, idemKey) {
351
+ return admitRunRow(entry, res, runStore, await runStore.getRunByIdem(idemKey));
352
+ }
334
353
  export async function readVisibleRun(entry, runStore, taskId) {
335
354
  const row = await runStore.getRun(taskId);
336
- return rowRead(row) && seesRun(entry, row.owner) ? runRowAt(entry.mouth, runStore, row) : undefined;
355
+ if (!rowRead(row))
356
+ return undefined;
357
+ const admitted = judgeRun(entry, row);
358
+ return admitted === undefined ? undefined : observedAdmission(entry, runStore, admitted);
337
359
  }
338
360
  export function seesRun(entry, owner) {
339
361
  const verdict = verdictOn(entry, ownerCellOf(owner));
@@ -372,9 +394,25 @@ export async function admitSessionRow(entry, res, store, sessionId, reading) {
372
394
  export async function judgeSessionRow(entry, store, sessionId, reading) {
373
395
  return judge(entry, reading, await sessionCellFor(entry.face, entry.caller, store, sessionId, reading.owner));
374
396
  }
397
+ export async function judgeSessionById(entry, store, sessionId) {
398
+ const head = await readOwnerCell(entry, sessionId, () => store.headOf(sessionId));
399
+ return sessionRowPresent(head) ? judgeSessionRow(entry, store, sessionId, head) : undefined;
400
+ }
375
401
  export async function admitSessionById(entry, res, store, sessionId) {
402
+ const verdict = await judgeSessionById(entry, store, sessionId);
403
+ if (verdict === undefined) {
404
+ refuse(entry, res, "missing");
405
+ return undefined;
406
+ }
407
+ return deliverVerdict(entry, res, verdict);
408
+ }
409
+ export async function readVisibleSession(entry, store, sessionId) {
410
+ const verdict = await judgeSessionById(entry, store, sessionId);
411
+ return verdict === undefined || verdict === "door" || verdict === "not_visible" ? undefined : verdict;
412
+ }
413
+ export async function sessionOwnerUnchanged(entry, store, sessionId, admittedOwner) {
376
414
  const head = await readOwnerCell(entry, sessionId, () => store.headOf(sessionId));
377
- return admitSessionRow(entry, res, store, sessionId, head);
415
+ return sessionRowPresent(head) && head.owner === admittedOwner;
378
416
  }
379
417
  export async function judgeSession(entry, store, sessionId, reading) {
380
418
  if (!sessionRowPresent(reading))
@@ -391,4 +429,144 @@ export function entryIsFleet(entry) {
391
429
  export function routeListFilter(req, w, route) {
392
430
  return listFilterOf(faceOfRoute(route), callerOf(req, w));
393
431
  }
432
+ export function sealRouteDeps(deps) {
433
+ return deps;
434
+ }
435
+ export async function runFactsOf(store, taskId) {
436
+ const row = await store.getRun(taskId);
437
+ return rowRead(row) ? { status: row.status, instanceId: row.instanceId, sessionId: row.sessionId } : undefined;
438
+ }
439
+ export async function latestRunIdOf(store, sessionId) {
440
+ return (await store.latestRunForSession(sessionId))?.taskId;
441
+ }
442
+ export function sessionFactsReadOf(store) {
443
+ const headOf = store?.headOf;
444
+ if (typeof headOf !== "function")
445
+ return undefined;
446
+ return async (sessionId) => {
447
+ const head = await headOf.call(store, sessionId);
448
+ return rowRead(head) ? { get leafId() { return head.leafId; } } : undefined;
449
+ };
450
+ }
451
+ export async function readSessionAgent(store, sessionId) {
452
+ const placementOf = store?.placementOf;
453
+ if (placementOf === undefined)
454
+ return undefined;
455
+ return sessionAgentOf(await placementOf.call(store, sessionId));
456
+ }
457
+ export function occupantRecheckOf(store) {
458
+ const headOf = store?.headOf;
459
+ if (typeof headOf !== "function")
460
+ return undefined;
461
+ return async (sessionId, occupant) => {
462
+ const head = await headOf.call(store, sessionId);
463
+ if (!rowRead(head))
464
+ return "gone";
465
+ return sameOccupant(occupant, head) ? "same" : "replaced";
466
+ };
467
+ }
468
+ export async function engineRulesKeyOf(store, sessionId, principal) {
469
+ if (principal === undefined || typeof store?.headOf !== "function")
470
+ return principal;
471
+ const owner = (await store.headOf(sessionId))?.owner;
472
+ if (owner === undefined || owner === null)
473
+ return principal;
474
+ return personOf(recoveredSubject(owner)) === principal ? owner : principal;
475
+ }
476
+ export async function readVisibleLatestRun(entry, store, sessionId) {
477
+ const latest = await store.latestRunForSession(sessionId);
478
+ return rowRead(latest) && seesRun(entry, latest.owner) ? latest : undefined;
479
+ }
480
+ export function runListOwnerOf(filter, named) {
481
+ return filter.gateOwner ?? named;
482
+ }
483
+ export function listVisibleRuns(store, filter, named, query) {
484
+ const owner = runListOwnerOf(filter, named);
485
+ return store.listRuns({ ...query, ...(owner ? { owner } : {}) });
486
+ }
487
+ export function listRunsOfScope(store, scope, limit) {
488
+ return store.listRuns({ owner: ownerOfCheckpointScope(scope), limit });
489
+ }
490
+ export function replayHitOf(subject, config, row, clientTaskId) {
491
+ const sameRun = clientTaskId === undefined || clientTaskId === row.taskId;
492
+ return sameRun && seesRunAs("run.replay", claimCallerOf(subject, config), row.owner) ? { kind: "visible", row } : { kind: "occupied" };
493
+ }
494
+ export async function readReplayHit(subject, config, store, key, clientTaskId) {
495
+ const row = "idemKey" in key ? await store.getRunByIdem(key.idemKey) : await store.getRun(key.taskId);
496
+ return rowRead(row) ? replayHitOf(subject, config, row, clientTaskId) : undefined;
497
+ }
498
+ export async function admitSessionView(entry, res, store, sessionAudit, sessionId, readOpts) {
499
+ const gated = store !== undefined && typeof store.headOf === "function";
500
+ if (gated && (await admitSessionById(entry, res, store, sessionId)) === undefined)
501
+ return undefined;
502
+ let audit;
503
+ try {
504
+ audit = await sessionAudit(sessionId, readOpts);
505
+ }
506
+ catch (e) {
507
+ if (gated)
508
+ throw e;
509
+ throw new Error(`session view read failed before ownership could be established: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
510
+ }
511
+ if ((await admitSessionRow(entry, res, store, sessionId, audit)) === undefined)
512
+ return undefined;
513
+ return audit;
514
+ }
515
+ export async function readSyncGate(entry, store, sessionId) {
516
+ const live = await store.headOf(sessionId);
517
+ const face = rowRead(live) ? sessionFaceOfHead(sessionId, live) : undefined;
518
+ const held = face === undefined ? await deletionHeadReadOf(store)(sessionId) : undefined;
519
+ const occupant = face ?? (rowRead(held) ? sessionFaceOfHead(sessionId, held) : undefined);
520
+ const mayTouch = occupant !== undefined && (await judgeSession(entry, store, sessionId, occupant)) !== undefined;
521
+ return { face, occupant, mayTouch };
522
+ }
523
+ export async function toolResultRefOwned(store, ref, run) {
524
+ const provenance = store?.ownerOf ? await store.ownerOf(ref) : undefined;
525
+ return provenance !== undefined && provenance.sessionId === run.sessionId && (provenance.taskId === undefined || provenance.taskId === run.taskId);
526
+ }
527
+ export async function readVisibleLeaderRow(store, id, visible) {
528
+ const row = await store.getRun(id);
529
+ return row !== undefined && visible(row.owner) ? row : undefined;
530
+ }
531
+ export const WORKFLOW_SESSION_ASSERTION = {
532
+ "workflow-detail": { phase: "accept", label: "workflow.detail" },
533
+ "workflow-journal": { phase: "accept", label: "workflow.journal" },
534
+ "workflow-stream": { phase: "accept", label: "workflow.stream" },
535
+ "workflow-agent-steer": { phase: "accept", label: "workflow.agent-steer" },
536
+ };
537
+ export function listVisibleWorkflows(entry, store, opts) {
538
+ return store.listByScope(engineScopeOf(entry.caller.subject), opts);
539
+ }
540
+ export async function judgeWorkflowRun(entry, store, runId) {
541
+ const row = await store.get(runId);
542
+ if (!rowRead(row))
543
+ return "missing";
544
+ const engineCaller = { ...entry.caller, subject: recoveredSubject(engineScopeOf(entry.caller.subject)) };
545
+ const verdict = verdictOnQuals(entry, qualsOf(engineCaller, ownerCellOf(row.scope)));
546
+ if (verdict === "door" || verdict === "not_visible")
547
+ return verdict;
548
+ const rule = Object.hasOwn(WORKFLOW_SESSION_ASSERTION, entry.mouth) ? WORKFLOW_SESSION_ASSERTION[entry.mouth] : undefined;
549
+ if (rule === undefined)
550
+ throw new Error(`owner access: mouth ${entry.mouth} judges a workflow row but is not registered in WORKFLOW_SESSION_ASSERTION`);
551
+ return sessionAsserted(rule, entry.req, row.originatingSessionId, verdict.has("operator")) ? { row, quals: verdict } : "session_mismatch";
552
+ }
553
+ export async function admitWorkflowRun(entry, res, store, runId) {
554
+ const verdict = await judgeWorkflowRun(entry, store, runId);
555
+ switch (verdict) {
556
+ case "missing":
557
+ case "not_visible":
558
+ case "session_mismatch":
559
+ refuse(entry, res, verdict);
560
+ return undefined;
561
+ case "door":
562
+ sendDoorRefusal(entry, res, doorRefusal(FACES[entry.face], entry.face, entry.caller));
563
+ return undefined;
564
+ default:
565
+ return verdict;
566
+ }
567
+ }
568
+ export async function admitSessionForDeletion(entry, res, store, sessionId) {
569
+ const placementOf = store.placementOf?.bind(store);
570
+ return admitSessionById(entry, res, { headOf: deletionHeadReadOf(store), ...(placementOf !== undefined ? { placementOf } : {}) }, sessionId);
571
+ }
394
572
  //# sourceMappingURL=owner-access.js.map