@sema-agent/server 7.149.0 → 7.151.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 (441) hide show
  1. package/MIGRATION.md +307 -9
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +92 -40
  5. package/deploy/sema-up/README.md +7 -1
  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 +1 -0
  14. package/deploy/sema-up/kube-up.sh +1 -1
  15. package/deploy/sema-up/lib/flagshape.sh +1 -1
  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/dist/adoption/import.js +3 -3
  19. package/dist/approval-ask-machine.d.ts +1 -1
  20. package/dist/approval-card.d.ts +3 -3
  21. package/dist/approval-gate-currency.d.ts +2 -2
  22. package/dist/audit.d.ts +1 -1
  23. package/dist/audit.js +2 -2
  24. package/dist/auth-bridge.d.ts +20 -0
  25. package/dist/auth-bridge.js +9 -0
  26. package/dist/background-session-reap.d.ts +2 -2
  27. package/dist/bake-runner/main.d.ts +4 -2
  28. package/dist/bind-host.d.ts +2 -3
  29. package/dist/bind-host.js +2 -4
  30. package/dist/boot/budget-tracing.js +1 -1
  31. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  32. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  33. package/dist/boot/engine-lease.d.ts +5 -0
  34. package/dist/boot/engine-lease.js +1 -0
  35. package/dist/boot/execution-env.d.ts +8 -14
  36. package/dist/boot/execution-env.js +54 -17
  37. package/dist/boot/execution-lane.js +32 -5
  38. package/dist/boot/late-binds.d.ts +8 -4
  39. package/dist/boot/late-binds.js +7 -1
  40. package/dist/boot/memory-consolidation.d.ts +3 -2
  41. package/dist/boot/memory-consolidation.js +6 -6
  42. package/dist/boot/parked-revive-gate.d.ts +5 -5
  43. package/dist/boot/parked-revive-gate.js +2 -3
  44. package/dist/boot/reapers.d.ts +5 -0
  45. package/dist/boot/reapers.js +12 -1
  46. package/dist/boot/resolve-spec.d.ts +7 -8
  47. package/dist/boot/resolve-spec.js +80 -35
  48. package/dist/boot/retention-lane.d.ts +1 -1
  49. package/dist/boot/runner-deps.d.ts +9 -2
  50. package/dist/boot/runner-deps.js +3 -3
  51. package/dist/boot/session-age-out.d.ts +36 -0
  52. package/dist/boot/session-age-out.js +101 -0
  53. package/dist/boot/session-faces.d.ts +5 -14
  54. package/dist/boot/session-faces.js +28 -24
  55. package/dist/boot/stage-01-config.js +2 -0
  56. package/dist/boot/stage-03-store-backend.js +2 -2
  57. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  58. package/dist/boot/stage-05-execution-env.js +2 -2
  59. package/dist/boot/stage-06-runners.d.ts +7 -4
  60. package/dist/boot/stage-06-runners.js +16 -8
  61. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  62. package/dist/boot/stage-07-capability-layer.js +3 -2
  63. package/dist/boot/stage-08-reapers.d.ts +7 -4
  64. package/dist/boot/stage-08-reapers.js +4 -2
  65. package/dist/boot/stage-09-leader.d.ts +11 -5
  66. package/dist/boot/stage-09-leader.js +12 -3
  67. package/dist/boot/stage-10-http-server.d.ts +44 -6
  68. package/dist/boot/stage-10-http-server.js +12 -10
  69. package/dist/boot/web-admin.d.ts +1 -1
  70. package/dist/boot/web-admin.js +3 -1
  71. package/dist/boot/workflow-orchestration.d.ts +7 -2
  72. package/dist/boot/workflow-orchestration.js +24 -7
  73. package/dist/bounded-rotation.d.ts +29 -0
  74. package/dist/bounded-rotation.js +24 -0
  75. package/dist/capability-facts.d.ts +84 -66
  76. package/dist/capability-facts.js +58 -41
  77. package/dist/center-credential.d.ts +25 -6
  78. package/dist/center-credential.js +25 -5
  79. package/dist/config-catalog.d.ts +26 -7
  80. package/dist/config-catalog.js +15 -12
  81. package/dist/config-invariants.d.ts +2 -1
  82. package/dist/config-invariants.js +4 -4
  83. package/dist/config-types.d.ts +22 -15
  84. package/dist/config.d.ts +51 -2
  85. package/dist/config.js +35 -24
  86. package/dist/deployment-governance.d.ts +7 -28
  87. package/dist/deployment-governance.js +1 -14
  88. package/dist/deployment-shape.d.ts +9 -1
  89. package/dist/deployment-shape.js +2 -1
  90. package/dist/device-protocol.d.ts +5 -4
  91. package/dist/device-protocol.js +1 -1
  92. package/dist/device-ws-hub.d.ts +1 -0
  93. package/dist/device-ws-hub.js +66 -29
  94. package/dist/device-ws-protocol.d.ts +79 -12
  95. package/dist/device-ws-protocol.js +64 -26
  96. package/dist/engine-identity.d.ts +23 -5
  97. package/dist/engine-identity.js +13 -0
  98. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  99. package/dist/execution-env-refusal.d.ts +23 -0
  100. package/dist/execution-env-refusal.js +5 -0
  101. package/dist/execution-lane-caps.d.ts +3 -1
  102. package/dist/field-conflict.d.ts +3 -3
  103. package/dist/file-history-capture.d.ts +11 -4
  104. package/dist/file-history-capture.js +9 -6
  105. package/dist/file-history-disclosure.d.ts +7 -5
  106. package/dist/file-history-disclosure.js +7 -5
  107. package/dist/fleet/drain-entry.d.ts +4 -0
  108. package/dist/fleet/engine-signal.d.ts +14 -1
  109. package/dist/fleet/engine-signal.js +5 -1
  110. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  111. package/dist/fleet/serving-lease.d.ts +18 -3
  112. package/dist/fleet/serving-lease.js +81 -35
  113. package/dist/fleet-client.d.ts +13 -11
  114. package/dist/fleet-client.js +53 -33
  115. package/dist/history-anchor.js +1 -1
  116. package/dist/hitl-delivery.d.ts +1 -3
  117. package/dist/hitl-delivery.js +1 -1
  118. package/dist/hooks/hook-runner.js +2 -2
  119. package/dist/host-lsp-manager.d.ts +2 -2
  120. package/dist/http/active-run-conflict.d.ts +3 -7
  121. package/dist/http/active-run-conflict.js +2 -2
  122. package/dist/http/admission.js +19 -4
  123. package/dist/http/approval-sweeps.js +7 -6
  124. package/dist/http/caller-trust.d.ts +2 -2
  125. package/dist/http/caller-trust.js +3 -3
  126. package/dist/http/checkpoint-ctx.d.ts +20 -63
  127. package/dist/http/checkpoint-ctx.js +2 -24
  128. package/dist/http/claim-heartbeat.d.ts +4 -4
  129. package/dist/http/claim-heartbeat.js +3 -3
  130. package/dist/http/dispatch.d.ts +2 -1
  131. package/dist/http/dispatch.js +36 -29
  132. package/dist/http/durable-run-leg.js +17 -17
  133. package/dist/http/health-self-report.d.ts +9 -1
  134. package/dist/http/health-self-report.js +2 -0
  135. package/dist/http/owner-access.d.ts +264 -20
  136. package/dist/http/owner-access.js +215 -5
  137. package/dist/http/readiness.d.ts +4 -2
  138. package/dist/http/resume-ctx-read.js +38 -1
  139. package/dist/http/resume-legs.d.ts +2 -1
  140. package/dist/http/resume-legs.js +273 -89
  141. package/dist/http/route-ctx.d.ts +41 -19
  142. package/dist/http/route-table.d.ts +1 -1
  143. package/dist/http/routes/a2a-serve.js +15 -14
  144. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  145. package/dist/http/routes/agents-roster.js +2 -3
  146. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  147. package/dist/http/routes/approvals-assistant.js +12 -12
  148. package/dist/http/routes/background.d.ts +3 -3
  149. package/dist/http/routes/capabilities.js +10 -6
  150. package/dist/http/routes/config-catalog.d.ts +1 -1
  151. package/dist/http/routes/fleet.js +10 -8
  152. package/dist/http/routes/mcp-reconnect.js +2 -2
  153. package/dist/http/routes/memory-origin.d.ts +1 -1
  154. package/dist/http/routes/notify-wake.js +2 -3
  155. package/dist/http/routes/projects.d.ts +4 -2
  156. package/dist/http/routes/projects.js +7 -6
  157. package/dist/http/routes/retention-ops.d.ts +1 -1
  158. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  159. package/dist/http/routes/run-permission-mode.js +2 -2
  160. package/dist/http/routes/runs.d.ts +1 -1
  161. package/dist/http/routes/runs.js +125 -66
  162. package/dist/http/routes/session-memory-sync.js +4 -5
  163. package/dist/http/routes/session-sync.d.ts +4 -3
  164. package/dist/http/routes/session-sync.js +174 -83
  165. package/dist/http/routes/sessions-list.js +13 -7
  166. package/dist/http/routes/sessions.d.ts +1 -1
  167. package/dist/http/routes/sessions.js +26 -48
  168. package/dist/http/routes/tasks.js +38 -23
  169. package/dist/http/routes/trace-usage.js +14 -14
  170. package/dist/http/routes/workflows.d.ts +1 -0
  171. package/dist/http/routes/workflows.js +20 -38
  172. package/dist/http/server.d.ts +28 -30
  173. package/dist/http/server.js +7 -3
  174. package/dist/http/stored-body-replay.d.ts +3 -24
  175. package/dist/http/stored-body-replay.js +2 -12
  176. package/dist/http/submit-ctx.d.ts +1 -2
  177. package/dist/http/submit-ctx.js +8 -6
  178. package/dist/http/submit-replay.d.ts +15 -2
  179. package/dist/http/submit-replay.js +10 -4
  180. package/dist/http/wire-types.d.ts +19 -6
  181. package/dist/identity-source.d.ts +20 -3
  182. package/dist/identity-source.js +14 -0
  183. package/dist/index.d.ts +4 -0
  184. package/dist/lane-home-probe.d.ts +3 -7
  185. package/dist/lane-home-probe.js +0 -1
  186. package/dist/leader/endpoint.js +9 -8
  187. package/dist/leader/leader.d.ts +2 -1
  188. package/dist/leg-facts.d.ts +19 -5
  189. package/dist/leg-facts.js +3 -1
  190. package/dist/mcp-authorization-face.d.ts +18 -14
  191. package/dist/mcp-authorization-face.js +3 -2
  192. package/dist/memory-scope.d.ts +5 -4
  193. package/dist/memory-scope.js +4 -4
  194. package/dist/memory-store-refusal.d.ts +1 -1
  195. package/dist/memory-sync-client.d.ts +30 -2
  196. package/dist/memory-sync-client.js +16 -9
  197. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  198. package/dist/observability/err-text.d.ts +7 -0
  199. package/dist/observability/err-text.js +5 -0
  200. package/dist/observability/fail-open.d.ts +12 -8
  201. package/dist/observability/fail-open.js +12 -8
  202. package/dist/observability/logger.d.ts +7 -0
  203. package/dist/observability/logger.js +3 -1
  204. package/dist/observability/metrics.js +1 -0
  205. package/dist/observability/run-terminal.d.ts +1 -1
  206. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  207. package/dist/orchestration/workflow-notify-journal.js +12 -1
  208. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  209. package/dist/orchestration/workflow-park-decision.js +49 -10
  210. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  211. package/dist/orchestration/workflow-park-holder.js +98 -0
  212. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  213. package/dist/orchestration/workflow-record-fence.js +42 -0
  214. package/dist/owner-faces.d.ts +28 -4
  215. package/dist/owner-faces.js +2 -0
  216. package/dist/parked-decide.d.ts +104 -53
  217. package/dist/parked-decide.js +153 -117
  218. package/dist/peer-directory.d.ts +2 -2
  219. package/dist/peer-inbound-face.d.ts +2 -6
  220. package/dist/peer-inbound-face.js +0 -3
  221. package/dist/peer-seat.d.ts +1 -1
  222. package/dist/peer-seat.js +52 -59
  223. package/dist/permission-mode-admission.d.ts +41 -5
  224. package/dist/permission-mode-admission.js +29 -3
  225. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  226. package/dist/plugins/adoption-log-sql.js +7 -1
  227. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  228. package/dist/plugins/approval-ask-store-file.js +8 -0
  229. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  230. package/dist/plugins/approval-ask-store-memory.js +28 -9
  231. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  232. package/dist/plugins/approval-ask-store-sql.js +34 -5
  233. package/dist/plugins/approval-exemption-store.js +3 -0
  234. package/dist/plugins/approval-nonce-store.js +2 -0
  235. package/dist/plugins/breaker-state-sql.js +2 -0
  236. package/dist/plugins/caching-session-store.d.ts +9 -15
  237. package/dist/plugins/caching-session-store.js +6 -0
  238. package/dist/plugins/device-store-sql.js +6 -0
  239. package/dist/plugins/error-origin.d.ts +18 -0
  240. package/dist/plugins/error-origin.js +10 -0
  241. package/dist/plugins/exec-path-law.d.ts +34 -0
  242. package/dist/plugins/exec-path-law.js +13 -0
  243. package/dist/plugins/execution-placement-sql.js +6 -6
  244. package/dist/plugins/file-run-store.js +1 -1
  245. package/dist/plugins/image-bake-store-sql.js +6 -0
  246. package/dist/plugins/image-index-sql.js +4 -0
  247. package/dist/plugins/landed-attendants.d.ts +212 -0
  248. package/dist/plugins/landed-attendants.js +161 -0
  249. package/dist/plugins/leader-run-store-sql.js +4 -0
  250. package/dist/plugins/local-checkpoint-store.d.ts +4 -1
  251. package/dist/plugins/local-checkpoint-store.js +3 -0
  252. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  253. package/dist/plugins/local-session-live-reference.js +39 -0
  254. package/dist/plugins/local-session-store.d.ts +71 -33
  255. package/dist/plugins/local-session-store.js +129 -27
  256. package/dist/plugins/memory-engine-pg.js +4 -0
  257. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  258. package/dist/plugins/memory-engine-tidb.js +4 -0
  259. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  260. package/dist/plugins/memory-run-store.js +1 -1
  261. package/dist/plugins/memory-sync-store-pg.js +5 -0
  262. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  263. package/dist/plugins/one-time-migrations.d.ts +80 -61
  264. package/dist/plugins/one-time-migrations.js +241 -104
  265. package/dist/plugins/org-delivery-quota-store.js +4 -1
  266. package/dist/plugins/outcome-ledger-sql.js +2 -0
  267. package/dist/plugins/permission-rule-store-sql.js +11 -4
  268. package/dist/plugins/pg-cost-quota.js +4 -0
  269. package/dist/plugins/pg-pool.js +28 -1
  270. package/dist/plugins/pg-rate-limiter.js +2 -0
  271. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  272. package/dist/plugins/posix-shell-fs.js +8 -3
  273. package/dist/plugins/remote-env-adb.d.ts +19 -15
  274. package/dist/plugins/remote-env-adb.js +44 -17
  275. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  276. package/dist/plugins/remote-env-connect-seat.js +72 -0
  277. package/dist/plugins/remote-env-device.d.ts +22 -5
  278. package/dist/plugins/remote-env-device.js +114 -14
  279. package/dist/plugins/remote-env-e2b.d.ts +18 -7
  280. package/dist/plugins/remote-env-e2b.js +53 -40
  281. package/dist/plugins/remote-env-file-error.js +6 -2
  282. package/dist/plugins/remote-env-host.d.ts +18 -1
  283. package/dist/plugins/remote-env-host.js +48 -47
  284. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  285. package/dist/plugins/remote-env-k8s.js +56 -32
  286. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  287. package/dist/plugins/remote-env-local-docker.js +37 -43
  288. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  289. package/dist/plugins/remote-env-ssh.js +64 -62
  290. package/dist/plugins/remote-shell.d.ts +101 -2
  291. package/dist/plugins/remote-shell.js +221 -3
  292. package/dist/plugins/replica-registration.d.ts +35 -0
  293. package/dist/plugins/replica-registration.js +48 -0
  294. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  295. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  296. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  297. package/dist/plugins/retention-lane-store-sql.js +4 -0
  298. package/dist/plugins/retention-sql.d.ts +20 -2
  299. package/dist/plugins/retention-sql.js +11 -0
  300. package/dist/plugins/run-store-sql.d.ts +22 -3
  301. package/dist/plugins/run-store-sql.js +33 -9
  302. package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
  303. package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
  304. package/dist/plugins/schema-consistency.d.ts +9 -5
  305. package/dist/plugins/schema-consistency.js +48 -18
  306. package/dist/plugins/schema-drift-sentence.js +1 -1
  307. package/dist/plugins/send-file-ledger.js +3 -0
  308. package/dist/plugins/serving-requirement.d.ts +68 -0
  309. package/dist/plugins/serving-requirement.js +60 -0
  310. package/dist/plugins/session-birth.d.ts +6 -2
  311. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  312. package/dist/plugins/session-ext-table.d.ts +14 -1
  313. package/dist/plugins/session-ext-table.js +5 -1
  314. package/dist/plugins/session-row-sql.d.ts +49 -2
  315. package/dist/plugins/session-row-sql.js +56 -13
  316. package/dist/plugins/session-store-sql.d.ts +34 -18
  317. package/dist/plugins/session-store-sql.js +98 -17
  318. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  319. package/dist/plugins/shared-memory-store-sql.js +6 -2
  320. package/dist/plugins/sql-driver.d.ts +2 -1
  321. package/dist/plugins/sql-driver.js +18 -3
  322. package/dist/plugins/sql-errors.d.ts +11 -6
  323. package/dist/plugins/sql-errors.js +5 -6
  324. package/dist/plugins/stop-then-start-sentence.d.ts +48 -3
  325. package/dist/plugins/stop-then-start-sentence.js +48 -0
  326. package/dist/plugins/stop-then-start.d.ts +109 -0
  327. package/dist/plugins/stop-then-start.js +104 -0
  328. package/dist/plugins/store-backend.d.ts +40 -13
  329. package/dist/plugins/store-backend.js +169 -27
  330. package/dist/plugins/store-boundary.d.ts +57 -0
  331. package/dist/plugins/store-boundary.js +139 -0
  332. package/dist/plugins/store-contracts.d.ts +29 -2
  333. package/dist/plugins/store-contracts.js +3 -0
  334. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  335. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  336. package/dist/plugins/store-fault.d.ts +26 -7
  337. package/dist/plugins/store-fault.js +18 -2
  338. package/dist/plugins/task-attachment-store.js +9 -0
  339. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  340. package/dist/plugins/task-list-store-sql.js +10 -8
  341. package/dist/plugins/tidb-cost-quota.js +4 -0
  342. package/dist/plugins/tidb-pool.js +6 -1
  343. package/dist/plugins/tidb-rate-limiter.js +4 -0
  344. package/dist/plugins/user-input-ledger-sql.js +4 -0
  345. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  346. package/dist/plugins/workflow-run-store-sql.js +64 -4
  347. package/dist/plugins/workspace-fill.d.ts +4 -7
  348. package/dist/plugins/workspace-fill.js +2 -1
  349. package/dist/plugins/write-behind-counter.js +5 -0
  350. package/dist/process-instance.d.ts +3 -0
  351. package/dist/process-instance.js +7 -0
  352. package/dist/project-context.d.ts +64 -0
  353. package/dist/project-context.js +66 -0
  354. package/dist/project-registry.d.ts +46 -0
  355. package/dist/project-registry.js +44 -0
  356. package/dist/question.d.ts +9 -21
  357. package/dist/question.js +28 -19
  358. package/dist/request-key-closure.js +1 -1
  359. package/dist/request-value-closure.d.ts +4 -0
  360. package/dist/request-value-closure.js +10 -0
  361. package/dist/run-acceptance.d.ts +3 -2
  362. package/dist/run-acceptance.js +4 -6
  363. package/dist/run-cancel-card.d.ts +1 -1
  364. package/dist/run-cancel-card.js +2 -1
  365. package/dist/run-local.js +1 -0
  366. package/dist/runs.d.ts +37 -8
  367. package/dist/runs.js +53 -12
  368. package/dist/runtime-governance.d.ts +5 -4
  369. package/dist/security.d.ts +31 -33
  370. package/dist/security.js +41 -7
  371. package/dist/server-secret-env.d.ts +12 -10
  372. package/dist/server-secret-env.js +24 -15
  373. package/dist/session-agent.d.ts +1 -10
  374. package/dist/session-agent.js +0 -6
  375. package/dist/session-bindings.d.ts +82 -0
  376. package/dist/session-bindings.js +18 -0
  377. package/dist/session-children-retire.d.ts +2 -2
  378. package/dist/session-children-retire.js +2 -6
  379. package/dist/session-deletion.d.ts +16 -1
  380. package/dist/session-error-wire.d.ts +3 -3
  381. package/dist/session-error-wire.js +3 -3
  382. package/dist/session-incarnation.d.ts +28 -4
  383. package/dist/session-incarnation.js +14 -2
  384. package/dist/session-kind.d.ts +57 -0
  385. package/dist/session-kind.js +22 -0
  386. package/dist/session-notify-door.d.ts +4 -4
  387. package/dist/session-notify-door.js +5 -6
  388. package/dist/session-row.d.ts +21 -1
  389. package/dist/session-row.js +7 -1
  390. package/dist/session-rules-seat.d.ts +4 -3
  391. package/dist/session-rules-seat.js +3 -11
  392. package/dist/session-sync-kernel.d.ts +24 -14
  393. package/dist/session-sync-kernel.js +3 -6
  394. package/dist/session-sync.d.ts +4 -98
  395. package/dist/session-sync.js +4 -74
  396. package/dist/session-titler.d.ts +10 -3
  397. package/dist/session-titler.js +19 -6
  398. package/dist/ssh-host-key.d.ts +5 -0
  399. package/dist/ssh-host-key.js +3 -0
  400. package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
  401. package/dist/stores-sql/checkpoint-store-sql.js +106 -18
  402. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  403. package/dist/stores-sql/file-history-store-sql.js +108 -70
  404. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  405. package/dist/stores-sql/pg-session-storage.js +37 -13
  406. package/dist/stores-sql/retention-store-sql.d.ts +2 -10
  407. package/dist/stores-sql/retention-store-sql.js +2 -10
  408. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  409. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  410. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  411. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  412. package/dist/stores-sql/tidb-session-store.js +37 -13
  413. package/dist/submission-exit.d.ts +3 -2
  414. package/dist/submission-exit.js +9 -1
  415. package/dist/task-cwd.d.ts +6 -5
  416. package/dist/task-settings.d.ts +19 -5
  417. package/dist/task-settings.js +13 -7
  418. package/dist/terminal.d.ts +33 -2
  419. package/dist/terminal.js +139 -9
  420. package/dist/tool-approval.d.ts +147 -12
  421. package/dist/tool-approval.js +206 -109
  422. package/dist/trace/engine-notice-wire.d.ts +14 -0
  423. package/dist/trace/engine-notice-wire.js +18 -1
  424. package/dist/trace/project.d.ts +4 -3
  425. package/dist/trace/project.js +3 -2
  426. package/dist/trace/projection-table.d.ts +33 -2
  427. package/dist/trace/self-minted-wire.d.ts +422 -26
  428. package/dist/trace/self-minted-wire.js +149 -23
  429. package/dist/trace/tool-card.d.ts +3 -0
  430. package/dist/trace/tool-card.js +24 -0
  431. package/dist/trace/tool-output-media.d.ts +2 -1
  432. package/dist/unattended-permission-mode.d.ts +1 -1
  433. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  434. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  435. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  436. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
  437. package/package.json +3 -3
  438. package/wire-changes/server@7.150.0.json +335 -0
  439. package/wire-changes/server@7.151.0.json +762 -0
  440. package/dist/http/session-inherit-env.d.ts +0 -36
  441. package/dist/http/session-inherit-env.js +0 -6
@@ -39,6 +39,7 @@ import type { RememberLaneCannotRecord } from "../parked-decide.js";
39
39
  import type { RowWayOut } from "./resume-legs.js";
40
40
  import type { KeyCaller } from "../owner-faces.js";
41
41
  import type { Subject } from "../owner-brands.js";
42
+ import type { RouteBackend, RouteRunStore, RouteSessionStore } from "./owner-access.js";
42
43
  /** 跨域可变状态 = lens1 §C2 实测的那 8 条「运行期登记簿」,一个对象。
43
44
  * [ref]:`cancelledViaVerb`(按 taskId 键控的「这次是取消动词」旁表)删除 —— 中止成因改挂在每条腿自己的
44
45
  * {@link RunAbort} 句柄上(`inflightRuns` 的值),同寿同删,不再有一张与腿不同寿的旁表。 */
@@ -199,14 +200,6 @@ export interface CheckpointCtx {
199
200
  * 传原 ctx / 其展开 ⇒ 标随行。缺席 = 不是无人值守腿(HTTP 提交腿;7.106.0 前落盘的行 —— 那时这些腿不铸模式,checkpoint 里也没有)。
200
201
  */
201
202
  unattendedLeg?: true;
202
- /**
203
- * 体里**模式词的读法记号**(闭集只有当前一词 `"entry_word"`):在场 = 这一行体的顶层 `permissionMode` 是这条 run 模式词唯一的源(提交入口盖过运维
204
- * `AUTONOMY=plan` 的地板;`plan_review` 写回改它),续跑照它读。**服务端写、不来自请求体**。缺席(7.121.x 及以前写下的行 —— 那时运维的 plan 由治理层每段重钳)
205
- * 而本部署此刻有入口地板、体的词被地板钳会变 ⇒ 续跑腿响亮拒、行字节不动(规则与删除条件的属主 = `http/checkpoint-ctx.ts` 顶注「模式词问」)。
206
- * 写点两个(写模式词的人盖记号,同模块):`buildCheckpointCtx`(每一次新的持久化写都写)与 `withPermissionModeRewritten`(`plan_review` 改词的写回);
207
- * 不改词的续跑腿写回传原 ctx ⇒ 记号随行。
208
- */
209
- permissionModeReading?: import("./checkpoint-ctx.js").PermissionModeReading;
210
203
  /**
211
204
  * 🔴 [ref] —— **写这份上下文的服务版本**(`package.json` 的 `version`),**服务端写、不来自请求体**(与 {@link unattendedLeg} 同为 `body` 的兄弟键)。
212
205
  * 写点两个:`buildCheckpointCtx`(每一次新的持久化写)与续跑腿的写回({@link DriveResumeArgs.resumeCtx} 的唯一写点,CAS 赢点盖本进程的版本 —— 接下来写下一张停车行的就是它)。
@@ -226,6 +219,24 @@ export interface CheckpointCtx {
226
219
  * 缺席 = 体里的目标就是交付的那一份(腿上没有屏)。
227
220
  */
228
221
  promptScreened?: true;
222
+ /**
223
+ * 这条 run 继承到的**项目上下文**(`project-context.ts` 的 {@link import("../project-context.js").ProjectContext}:项目 id · 继承的 `cwd` · 项目简报)——
224
+ * 新提交腿在装配器头部判一次,**服务端写、不来自请求体**(与 {@link memoryScope} 同为 `body` 的兄弟键,先例同形:提交腿推导、落盘,续跑原样读回)。
225
+ * 写点:`buildCheckpointCtx`(提交腿那一笔,经 `persistSubmissionCtx` 读这条腿的部署事实);leader worker 的写者不带(它的 spec 不经新提交腿的判)。续跑腿的写回传原 ctx / 其展开 ⇒ 随行。
226
+ * 读者只有一只:`resume-legs.ts` `resolveResumeSpec` 把它原样递给装配器(`opts.projectContext`)—— 续跑腿不再读登记簿、不再推观者(停驻期间登记被改 / 被删 / 看不见了,续跑照旧用这一份)。
227
+ * 缺席 = 没继承(含 7.150.0 之前写下的行:不回填,续跑不继承 = 那时的行为)。
228
+ */
229
+ projectContext?: import("../project-context.js").ProjectContext;
230
+ /**
231
+ * 这条 run 的**登记簿默认读层种子**(`project-registry.ts` 的 {@link import("../project-registry.js").MemorySeed}:种子项目 + 判出它的那一位观者)—— 新提交腿判一次:
232
+ * 这次提交带的项目对提交者可见(与 `GET /v1/projects/:id` 同一只判,观者 = 读面同一只推导)⇒ 种子;带了而判不出 ⇒ `null`(判过,无);没带项目 ⇒ 缺席。**服务端写、不来自请求体**(与 {@link memoryScope} 同为
233
+ * `body` 的兄弟键:提交腿推导、落盘,续跑原样读回)。冻结的是**观者**不是词:续跑以这一位观者经同一只可见性判重读此刻的登记(停驻期间改了词 ⇒ 新词;删了 / 换了主人 /
234
+ * 不再对他可见 ⇒ 没有种子)。写点:`buildCheckpointCtx`(提交腿那一笔,经 `persistSubmissionCtx` 读这条腿的部署事实);leader worker 的写者不带(它的体不带项目)。
235
+ * 续跑腿的写回传原 ctx / 其展开 ⇒ 随行。读者只有一只:`resume-legs.ts` `resolveResumeSpec` 把它原样递给装配器(`opts.memorySeed`)—— 续跑腿不推观者、不按 `body.projectId` 现查。
236
+ * 缺席而存体带了项目 = 本格出现之前写下的行(不回填:那时的提交腿没有判过可见性)⇒ 续跑不取种子,装配器记运维一行 `resume_memory_seed_unjudged`。
237
+ * 形只有一种读法(`frozenMemorySeedOf`,读口 `resume-ctx-read.ts`)。
238
+ */
239
+ memorySeed?: import("../project-registry.js").MemorySeed | null;
229
240
  }
230
241
  /**
231
242
  * `/decide` 第三条车道交给宿主投递腿(wake:`DriveResumeArgs` / fresh:`DurableRunLegArgs`)的**一件**:这一跑在内存里带着的决定,
@@ -377,7 +388,8 @@ export interface DriveResumeArgs {
377
388
  /**
378
389
  * 🔴 **[ref](codex 交叉复审 r2-[medium] 验真后修):这条腿是**调用方发起**的吗?**
379
390
  *
380
- * `true` = 有人在 HTTP 上点了按钮(resume / plan_review / wake / decide / 赎回席)⇒ 吃按**付费方**
391
+ * `true` = 有人在 HTTP 上点了按钮(resume / plan_review / wake / decide / 赎回席),或这一跑交付的是一条**已受理的人的决定**
392
+ * (workflow 停驻卡的 run 收场送达把它交给宿主会话的下一跑 —— 没有请求,但花的是卡属主的钱)⇒ 吃按**付费方**
381
393
  * (卡属主)判的成本配额准入(`ownerCostQuotaDenied`)。缺席/`false` = **部署自己的结算腿**
382
394
  * (内部 D-D SLA deny-sweep)⇒ **不吃**那道门。
383
395
  *
@@ -391,9 +403,8 @@ export interface DriveResumeArgs {
391
403
  * 并且整段时间攥着会话 claim。**方向也自洽**:deny 是**停下**这条 run 的动作,为了省钱而拒绝执行「停」
392
404
  * 与 preempt 路由早就成文的那句同一条(「否则超顶租户连自己的花费都停不下来」)。
393
405
  *
394
- * 判别子取 `req` 的在场与否 —— 这在 `resumeCheckpoint` 里**已经是**「系统腿 vs 调用方腿」的既有判据
395
- * (绑定强制、parked 分流两处都写着 `req !== undefined` 与「内部 D-D SLA deny-sweep(req 缺席)豁免」),
396
- * 本位只是把同一条判据显式化成一个有名字的位,而不是让下游去猜。
406
+ * 判别子**不再**只是 `req` 的在场与否:`req` 缺席的腿有两种 —— SLA 拒扫(结算,不吃门)与 workflow 停驻卡的 run 收场送达(交付一条人的决定,
407
+ * 吃门,fail-closed)。所以本位是一个**有名字的事实**,由起腿的那一处写明(wake 腿:`req` 在场 ∨ 这一跑带着一件决定投递),下游只读这一位、不去猜 `req`。
397
408
  * ⚠️ **射程覆盖两道门**:紧邻的 fleet-lease 准入(`ownerFleetLeaseDenied`)读**同一位** —— [ref] 件⑤②
398
409
  * (codex r3-[high])把它一并改吃了 `callerInitiated`,理由与三问逐字同 cost 半场。
399
410
  * 🔴 本句是 [ref] R4 改写的(2026-09-03,7.57.0 发车前合并重扫 wf_1abaaa9a):此处原文写着「紧邻的
@@ -416,7 +427,7 @@ export interface DriveResumeArgs {
416
427
  *
417
428
  * 所以由上游把「已受理」这个事实传下来,`driveResumeLeg` 据此跳过重复协商。**安全性**:两处的键是
418
429
  * **同一个表达式**(`decodeCheckpointScope(cp.scope)`,上游门与下游 `auth.principal` 同源),射程条件也
419
- * 同一条(`req !== undefined` ⇔ `callerInitiated`)⇒ 跳过的是一次**逐字相同**的判定,不是一道门。
430
+ * 同一条(上游判过两门 ⇔ 下游 `callerInitiated`:`/decide` 与 workflow 停驻卡的 run 收场送达都在交下来之前按卡属主判过)⇒ 跳过的是一次**逐字相同**的判定,不是一道门。
420
431
  * 缺席/`false` ⇒ 照常自己判(其余三条驱动腿与 sweep 一字不变)。
421
432
  */
422
433
  ownerLeaseAdmitted?: boolean;
@@ -442,13 +453,13 @@ export interface RouteLegs {
442
453
  /** POST /v1/tasks · /v1/tasks/stream · /v1/runs 的共同前段:读体 → 校验 → resolveSpec。null = 已应答(400/…)。
443
454
  *
444
455
  * `body` = **已解析好的**请求体,给那些体不是「这条 HTTP 请求的 JSON 正文」的调用方
445
- * (DESIGN-269 车2:A2A JSON-RPC 腿已经把正文读成了一条 `message/send` 请求,再 `readJson(req)`
456
+ * ([ref] 车2:A2A JSON-RPC 腿已经把正文读成了一条 `message/send` 请求,再 `readJson(req)`
446
457
  * 一次只会读到空流)。缺席 ⇒ 照旧自己读体,既有三个调用方一字不改。
447
458
  * ⚠️ 这是**入口形**的分歧,不是校验面的分歧:传进来的体与自己读的体走**同一段**校验/授权/
448
459
  * resolveSpec —— 分叉出第二条校验路径正是本参数存在的理由的反面。
449
460
  *
450
461
  * `onTypedFailure` = 「typed 拒绝**别写响应**,交回给我」。默认(缺席)行为不变:`HttpError` 走
451
- * `sendError` 连 `extra` 一起回显。DESIGN-269 车2 的 A2A 腿必须传它 —— 那些 `extra`(尤其
462
+ * `sendError` 连 `extra` 一起回显。[ref] 车2 的 A2A 腿必须传它 —— 那些 `extra`(尤其
452
463
  * `scenario_unknown` 的**全部场景名**)对壳是指路材料,对一个外部 peer 是内部词表外泄。 */
453
464
  prepareSpec(req: IncomingMessage, res: ServerResponse, body?: TaskRequestBody, onTypedFailure?: (err: import("../security.js").HttpError) => void,
454
465
  /** [ref] 件C:**腿身份**(不是能力表态)。`liveStream: true` 只由 `POST /v1/tasks/stream` 的装配点按
@@ -600,8 +611,19 @@ export declare function sendResumeOutcome(res: ServerResponse, out: {
600
611
  }, logger: {
601
612
  info?: (msg: string, fields?: Record<string, unknown>) => void;
602
613
  } | undefined, extraBody?: Record<string, unknown>): void;
614
+ /**
615
+ * 🔴 **路由层的服务 deps(类型墙,[ref] 第二阶段)**:run 店 / 会话店上带属主的读口(按 id / 按键 / 按会话 / 列表 —— `owner-access.ts` 的 {@link RouteRunStore} /
616
+ * {@link RouteSessionStore})、会话视图读 `sessionAudit` 与后端铸这两只店的工厂(`backend.run()` / `backend.session()`,{@link RouteBackend})在型上调不了:路由在不在照判(能力事实只问方法在不在,见证随视图封着),带属主的行只经属主存取器读。
617
+ * 值上就是服务的那一只 deps,只在 `owner-access.ts` 的 `sealRouteDeps` 铸一次;视图是完整 deps 的子型(交给持认领腿的写口照常)。
618
+ */
619
+ export type RouteDeps = Omit<FlatServiceDeps, "runStore" | "sessionStorage" | "sessionAudit" | "backend"> & {
620
+ runStore?: RouteRunStore;
621
+ sessionStorage?: RouteSessionStore;
622
+ sessionAudit?: never;
623
+ backend?: RouteBackend;
624
+ };
603
625
  export interface RouteCtxBase {
604
- deps: FlatServiceDeps;
626
+ deps: RouteDeps;
605
627
  registry: RunRegistry;
606
628
  helpers: RouteHelpers;
607
629
  local: RouteLocals;
@@ -663,15 +685,15 @@ export interface RouteDeclFacts {
663
685
  * 编排器片 2 件 2:值 = 这一种计费请求的**种类**(`submit` 新工作 / `hitl-answer` 对等人的卡作答 / `resume` 续跑;闭集属主
664
686
  * `http/readiness.ts` 的 `BILLABLE_KINDS`)—— 排空与租约过期只拒 `submit`(放行闭集表 `ADMISSION_TABLE`),无凭证门不看种类。 */
665
687
  readonly billable?: import("./readiness.js").BillableKind;
666
- /** 「本条 url 在**没有任何 service credential** 的部署形下,这几个方法必须 fail-closed」。
688
+ /** 「本条 url 上这几个方法在**请求没带凭据门认的凭据**(service 凭据 / 鉴权桥验过的登录令牌;`identity-source.ts` 头注律 5)时必须 fail-closed」。
667
689
  * 判据(两个合取项)= 「授权的唯一输入是 principal 头」∧「持久改写,或爆炸半径跨租户的治理读」;
668
690
  * 逐口论证在各 `routes/*.ts` 的头注里,声明行只记结论。 */
669
691
  readonly credentialGated?: readonly RouteMethod[];
670
692
  /** 「这条 url **是**计费提交面,但它到底提不提交由**请求体里的方法**决定」—— 单 URL 多方法的
671
693
  * JSON-RPC 端点。两道**可用性** 503(drain / roster-pending)按 url 一刀切会把同端点上的纯读一起
672
694
  * 关掉,所以分派器对本行**跳过**那两道,改由域模块在写分支里施加同样的两道(文案逐字同源)。
673
- * 🔴 只豁免那两道,**不豁免安全轴**:`billable` 本身仍为 true,无 service token 那道 fail-closed
674
- * 503 照旧罩着(它判的是「这台机能不能收写」,与方法无关,且必须在解析请求体之前)。 */
695
+ * 🔴 只豁免那两道,**不豁免安全轴**:`billable` 本身仍为 true,写门那道 fail-closed
696
+ * 503 照旧罩着(它判的是「这次请求带没带过门的凭据」,与方法无关,且必须在解析请求体之前)。 */
675
697
  readonly methodDispatched?: true;
676
698
  }
677
699
  /** **可分派行**多出来的列([ref] 第三刀):身份 + 它真认的方法(+ [ref] 的订阅类)。纯门行一列都没有(见下)。 */
@@ -136,7 +136,7 @@ export declare function routeLabel(_method: string, url: string): string;
136
136
  export declare function isBillableSubmitPath(url: string): boolean;
137
137
  /** 编排器片 2 件 2:这条 url 是哪一**种**计费请求(`undefined` = 不在计费面)。声明序第一条命中的行定种类(今天每条 url 至多命中一行)。 */
138
138
  export declare function billableKindOf(url: string): BillableKind | undefined;
139
- /** [ref]([ref] 件5)—— **改写门**:不烧模型、但在没有任何 service credential 的部署形下必须
139
+ /** [ref]([ref] 件5)—— **改写门**:不烧模型、但在请求没带凭据门认的凭据时(`identity-source.ts` 头注律 5)必须
140
140
  * 与 billable / bake 两族一样 fail-closed 的写门。与 `isBillableSubmitPath` **刻意分开**:这几扇门
141
141
  * `billable=false`(零模型工作),塞进那张名单会让它们连带吃 drain 与 roster-pending 两道 503 ——
142
142
  * 而收编与规则读写在排空期/roster 未落时做完全无害。 */
@@ -4,12 +4,13 @@ import { memoRedactedRead, redactErrorMessage } from "../../observability/run-te
4
4
  import { isParkedRunStatus, isTerminalRunStatus } from "../../plugins/store-contracts.js";
5
5
  import { HttpError } from "../../security.js";
6
6
  import { idemCallerOf, idemIdentityOf, idemKeyOf, inflightKeyOf } from "../idempotency.js";
7
- import { isRunExistsConflictBody, replayOfExistingRun } from "../submit-replay.js";
7
+ import { answerReplay, isRunExistsConflictBody } from "../submit-replay.js";
8
8
  import { isActiveRunConflictBody } from "../active-run-conflict.js";
9
9
  import { sendJson, sendError, sendHttpError } from "../send.js";
10
10
  import { admissionRefusalOf, readinessOf, sendBillableRefusal } from "../readiness.js";
11
+ import { memberLeaseOf } from "../../fleet/engine-signal.js";
11
12
  import { gatedPerson, gatedSubject, sendPrincipalRefusal, verifiedIdentitySource } from "../principal-gate.js";
12
- import { callerOf, protocolEntry, readVisibleRun, runRowAt } from "../owner-access.js";
13
+ import { callerOf, protocolEntry, readReplayHit, readVisibleRun, runRowAt } from "../owner-access.js";
13
14
  import { assertNever } from "../route-ctx.js";
14
15
  import * as facts from "../../capability-facts.js";
15
16
  import { createDurableRun } from "./runs.js";
@@ -181,7 +182,7 @@ function rpcErrorFromTypedFailure(err) {
181
182
  }
182
183
  function submitUnavailable(res, ctx) {
183
184
  const { deps } = ctx;
184
- const refusal = admissionRefusalOf(readinessOf(deps), deps.servingLease?.(), "submit");
185
+ const refusal = admissionRefusalOf(readinessOf(deps), memberLeaseOf(deps), "submit");
185
186
  if (refusal === undefined)
186
187
  return false;
187
188
  sendBillableRefusal(res, refusal);
@@ -197,15 +198,14 @@ function readBlocking(params) {
197
198
  throw new RpcError(JSONRPC_INVALID_PARAMS, "params.configuration.blocking must be a boolean");
198
199
  return c.blocking;
199
200
  }
200
- async function waitForRun(ctx, store, res, taskId, budgetMs) {
201
+ async function waitForRun(ctx, entry, store, res, taskId, budgetMs) {
201
202
  const { deps } = ctx;
202
203
  const deadline = Date.now() + budgetMs;
203
204
  let last = null;
204
205
  for (;;) {
205
206
  let run;
206
207
  try {
207
- const raw = await store.getRun(taskId);
208
- run = raw ? await runRowAt("run.a2a", store, raw) : null;
208
+ run = (await readVisibleRun(entry, store, taskId))?.row ?? null;
209
209
  }
210
210
  catch (e) {
211
211
  deps.logger?.warn?.("a2a_serve_wait_read_failed", { error: e?.message });
@@ -254,10 +254,11 @@ async function handleMessageSend({ req, res, ctx, params, serve, runStore }) {
254
254
  ...(contextId !== undefined ? { sessionId: contextId } : {}),
255
255
  ...(scenario !== undefined ? { scenario } : {}),
256
256
  };
257
- const keyed = (await runStore.getRunByIdem(idem.key).catch(() => undefined)) ?? (await runStore.getRun(body.taskId).catch(() => undefined));
258
- const replay = keyed ? await replayOfExistingRun(keyed, { subject: submitter, clientTaskId: body.taskId, idem }, "durable", deps, runStore) : undefined;
259
- if (keyed && replay?.status === 202) {
260
- return taskFromRun(await runRowAt("run.a2a", runStore, keyed));
257
+ const keyed = (await readReplayHit(submitter, deps.config, runStore, { idemKey: idem.key }, body.taskId).catch(() => undefined)) ??
258
+ (await readReplayHit(submitter, deps.config, runStore, { taskId: body.taskId }, body.taskId).catch(() => undefined));
259
+ const replay = keyed ? await answerReplay(keyed, { subject: submitter, clientTaskId: body.taskId, idem }, "durable", runStore) : undefined;
260
+ if (keyed?.kind === "visible" && replay?.status === 202) {
261
+ return taskFromRun(await runRowAt("run.a2a", runStore, keyed.row));
261
262
  }
262
263
  const inflight = replay === undefined ? ctx.registry.idemCache.peek(inflightKeyOf(idem, "durable", body.taskId)) : undefined;
263
264
  let receipt;
@@ -298,7 +299,7 @@ async function handleMessageSend({ req, res, ctx, params, serve, runStore }) {
298
299
  }
299
300
  const taskId = receiptBody.taskId;
300
301
  const sessionId = receiptBody.sessionId;
301
- const run = await waitForRun(ctx, runStore, res, taskId, blocking ? serve.blockingWaitMs : 0);
302
+ const run = await waitForRun(ctx, protocolEntry(req, deps, "run.a2a", callerOf(req, deps)), runStore, res, taskId, blocking ? serve.blockingWaitMs : 0);
302
303
  if (run)
303
304
  return taskFromRun(run);
304
305
  return {
@@ -330,10 +331,10 @@ function durableIdempotencyTaskId(scope, messageId) {
330
331
  async function handleTasksGet({ req, ctx, params, runStore }) {
331
332
  const { deps } = ctx;
332
333
  const id = asNonEmptyString(params.id, "params.id", MAX_TASK_ID_CHARS);
333
- const run = await readVisibleRun(protocolEntry(req, deps, "run.a2a", callerOf(req, deps)), runStore, id);
334
- if (!run)
334
+ const admitted = await readVisibleRun(protocolEntry(req, deps, "run.a2a", callerOf(req, deps)), runStore, id);
335
+ if (!admitted)
335
336
  throw new RpcError(A2A_TASK_NOT_FOUND, A2A_TASK_NOT_FOUND_MESSAGE);
336
- return taskFromRun(run);
337
+ return taskFromRun(admitted.row);
337
338
  }
338
339
  async function handleExtendedCard({ req, ctx, serve }) {
339
340
  return buildAgentCard(serve, cardReaderOf(req, ctx.deps.config), A2A_METHODS);
@@ -26,7 +26,7 @@
26
26
  * 的调用方不该从「这台有没有授权表」上读出部署形态。
27
27
  * 🔴 四口都在 `isCredentialGatedRewrite`(server.ts)门内(codex R1-[high] 验真后补):授权的**唯一**输入是
28
28
  * principal 头 ∧ 一次调用的爆炸半径跨租户(改缺省行 = 改整台部署每个 principal 的 verdict;读面 = 全部授权行 +
29
- * operator 手写的 note)—— 无 service 凭证且未开 `ALLOW_UNAUTHED_WRITES` 的 worker 上那个头**可自造**,与
29
+ * operator 手写的 note)—— 请求没带凭据门认的凭据(且部署未开 `ALLOW_UNAUTHED_WRITES`)时那个头**可自造**,与
30
30
  * `/v1/memory/erase` / `POST /v1/memory/export` 同一条论证。
31
31
  *
32
32
  * ── 为什么缺席形是 **501 `capability.*`** 而不是 404(与 consolidation 阀门刻意分家)──────────────────
@@ -2,8 +2,7 @@ import { chosenAgentName } from "@sema-agent/core";
2
2
  import { sendJson, sendError } from "../send.js";
3
3
  import { gatedSubject, sendUnauthorized } from "../principal-gate.js";
4
4
  import { PRINCIPAL_MAX_BYTES } from "../../principal-shape.js";
5
- import { partsOf } from "../../owner-brands.js";
6
- import { taskSpecIdentityOf } from "../../engine-identity.js";
5
+ import { engineScopeOf } from "../../engine-identity.js";
7
6
  import { routeListFilter } from "../owner-access.js";
8
7
  import { assertNever } from "../route-ctx.js";
9
8
  import * as facts from "../../capability-facts.js";
@@ -99,7 +98,7 @@ export async function handleAgentRoster(req, res, match, ctx) {
99
98
  }
100
99
  const status = statusRaw === null ? undefined : statusRaw;
101
100
  const subject = gatedSubject(req, deps.config);
102
- const ownScope = taskSpecIdentityOf(subject === undefined ? undefined : partsOf(subject)).principal ?? "default";
101
+ const ownScope = engineScopeOf(subject);
103
102
  let scope;
104
103
  if (gateOwner !== null) {
105
104
  scope = ownScope;
@@ -2,12 +2,13 @@ import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { QuestionAnswer } from "@sema-agent/core";
3
3
  import type { CheckpointStoreFull } from "../../plugins/store-backend.js";
4
4
  import { type ToolApprovalCoordinator } from "../../tool-approval.js";
5
+ import { type RouteSessionStore } from "../owner-access.js";
5
6
  import { type GovernancePosture } from "../../runtime-governance.js";
6
7
  import { type GateIntentView } from "../../approval.js";
7
8
  import { type RouteCtx, type RouteDecl, type RouteMatch, type RouteIdsOf } from "../route-ctx.js";
8
9
  import { type KeyClosureIssue } from "../../request-key-closure.js";
9
10
  import { type PeerInboundPendingRow } from "../../peer-inbound-face.js";
10
- import { type PlacementReadingSessionStore, type SessionAgent } from "../../session-agent.js";
11
+ import type { SessionAgent } from "../../session-agent.js";
11
12
  /** 族的成员 = 路由表行 id(改名 / 删行 ⇒ 下表的键当场编译红)。 */
12
13
  export type DecisionDoorId = Extract<ApprovalsAssistantRouteId, "approval-decide" | "assistant-task-plan-review">;
13
14
  /** 一道门的静态描述 —— 只写**这道门自己**的东西;路径、路径段、别门的键一概不在这里写(从来源读)。 */
@@ -164,7 +165,7 @@ peerInbound: (() => readonly PeerInboundPendingRow[]) | undefined,
164
165
  * 🔴 [ref]:停驻行 `agent` 的会话店面 —— 与 `GET /v1/approvals` 同一只(`deps.sessionStorage`),经同一只整批投影 {@link projectDurableQueue}。
165
166
  * `undefined` / 店不交 `placementOf` = 这台部署不存委派元组 ⇒ 没有一帧带 `agent`(帧字节与 [ref] 之前逐字相同)。位置在 `scope` 之前、与 `live` 并列:每个生产调用点都必须表态。
166
167
  */
167
- sessions: PlacementReadingSessionStore | undefined, scope: string | undefined,
168
+ sessions: Pick<RouteSessionStore, "placementOf"> | undefined, scope: string | undefined,
168
169
  /** [ref]②:出身归因的部署侧一半 + 三张审批名单(问的属主)。缺席 ⇒ 归不出治理出身(键缺席,与 best-effort 同方向)、没有一行读作
169
170
  * 部署名单的问(记不住,方向是多问)。**位置在 `pollMs` 之前**是刻意的:`pollMs` 只有测试传,而本参数是每个生产调用点都必须给的那一个。 */
170
171
  governance?: PendingProjectionDeployment, pollMs?: number): Promise<void>;
@@ -8,7 +8,7 @@ import { approvalPayloadFingerprint } from "../../plugins/approval-payload-finge
8
8
  import { carriesDeploymentListQuestion, standingAnswerDurablyRecordable } from "../../tool-approval.js";
9
9
  import { APPROVAL_GATE_KINDS } from "../../approval-content-kind.js";
10
10
  import { isParkedRunStatus } from "../../plugins/store-contracts.js";
11
- import { principalFrom, ownerOfCheckpointScope, scopeCellOf, CHECKPOINT_PUBLIC_SCOPE, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../../security.js";
11
+ import { principalFrom, scopeCellOf, CHECKPOINT_PUBLIC_SCOPE, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../../security.js";
12
12
  import { keyAdmits } from "../../owner-faces.js";
13
13
  import { personOf } from "../../owner-brands.js";
14
14
  import { editedPlanBinding, verifyDirectDoorProof } from "../../principal-jwt.js";
@@ -23,7 +23,7 @@ import { sleep } from "../sse-log.js";
23
23
  import { bindSseLifecycle } from "../sse-lifecycle.js";
24
24
  import { sendJson, sendError, sseHeaders, logRequestError, SSE_MAX_STREAM_MS, SSE_HEARTBEAT_IDLE_MS } from "../send.js";
25
25
  import { gatedSubject, explicitOperatorOk, sendPrincipalRefusal } from "../principal-gate.js";
26
- import { admitRunById, admitSessionById, callerEntry, callerOf, callerOfDecision, deciderSubjectOf, enter, judgeRun, protocolEntry, readVisibleRun, refuse, withCaller } from "../owner-access.js";
26
+ import { admitRunById, admitSessionById, callerEntry, callerOf, callerOfDecision, deciderSubjectOf, enter, latestRunIdOf, listRunsOfScope, protocolEntry, readSessionAgent, readVisibleRun, refuse, runFactsOf, withCaller } from "../owner-access.js";
27
27
  import { governanceOriginOf } from "../../runtime-governance.js";
28
28
  import { deploymentListAsks } from "../../approval.js";
29
29
  import { grantBindingOf } from "../../standing-answer-grant.js";
@@ -38,9 +38,9 @@ import { fieldConflictFacts } from "../../field-conflict.js";
38
38
  import { buildSettlementEvidence } from "../../gate-settlement.js";
39
39
  import { seatText } from "../../trace/exit-seat.js";
40
40
  import { approvalQueueKindOfDoorId } from "../../approval-queue-kind.js";
41
- import { defaultPeerInboundFace, parsePeerInboundId, peerBoxScope } from "../../peer-inbound-face.js";
41
+ import { defaultPeerInboundFace, parsePeerInboundId } from "../../peer-inbound-face.js";
42
+ import { engineScopeOfOwner } from "../../engine-identity.js";
42
43
  import { RESUME_RESTATABLE_KEYS, readResumeRestatement } from "../resume-restatement.js";
43
- import { readSessionAgent } from "../../session-agent.js";
44
44
  const DECIDE_BODY_DECLARED_KEYS = [
45
45
  "answer", "boundCallId", "boundInputHash", "checkpointToken", "decidedBy", "decidedVia", "decision", "feedback", "reason", "remember", "updatedInput",
46
46
  ...RESUME_RESTATABLE_KEYS,
@@ -280,8 +280,8 @@ async function decideIdempotentReplay(cs, args) {
280
280
  };
281
281
  }
282
282
  async function gateObjectivePreview(reader, runStore, agentStore, gate, runSessionId) {
283
- const previewOf = (taskId) => readVisibleRun(reader, runStore, taskId);
284
- const own = typeof runSessionId === "string" ? ((await runStore.getActiveTaskId(runSessionId)) ?? (await runStore.latestRunForSession(runSessionId))?.taskId) : undefined;
283
+ const previewOf = async (taskId) => (await readVisibleRun(reader, runStore, taskId))?.row;
284
+ const own = typeof runSessionId === "string" ? ((await runStore.getActiveTaskId(runSessionId)) ?? (await latestRunIdOf(runStore, runSessionId))) : undefined;
285
285
  if (own !== undefined)
286
286
  return (await previewOf(own))?.objectivePreview ?? null;
287
287
  if (agentStore === undefined)
@@ -462,7 +462,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
462
462
  if (typeof host === "string")
463
463
  byGate.set(host, s);
464
464
  });
465
- const runs = await runStore.listRuns({ owner: ownerOfCheckpointScope(scope), limit: 100 });
465
+ const runs = await listRunsOfScope(runStore, scope, 100);
466
466
  const tasks = runs
467
467
  .filter((r) => r.status === "running" || isParkedRunStatus(r.status))
468
468
  .map((r) => {
@@ -511,7 +511,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
511
511
  let flagged = await runStore.requestPreempt(taskId, run.owner);
512
512
  const PREEMPT_RECLASSIFY_ATTEMPTS = 3;
513
513
  for (let attempt = 0; !flagged; attempt++) {
514
- const now = await runStore.getRun(taskId);
514
+ const now = (await readVisibleRun(preemptEntry, runStore, taskId))?.row;
515
515
  if (now !== undefined && isParkedRunStatus(now.status)) {
516
516
  sendError(res, 409, "conflict.already_suspended", "task is already suspended", { taskId, status: now.status });
517
517
  return;
@@ -661,7 +661,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
661
661
  }
662
662
  const sighting = typeof body.checkpointId === "string" ? { face: "checkpointId", value: body.checkpointId } : undefined;
663
663
  const decisionEntry = callerEntry(req, deps, match.decl.id);
664
- const run = await runStore.getRun(taskId);
664
+ const run = await runFactsOf(runStore, taskId);
665
665
  if (!run) {
666
666
  if (!deps.config.directDoorActive)
667
667
  deps.logger?.info?.("decide_404", { reason: "no-row", taskId, principalPresent: principal !== undefined });
@@ -694,7 +694,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
694
694
  singleUse = proof.singleUse === undefined ? undefined : { proof: proof.singleUse, store };
695
695
  }
696
696
  const deciderEntry = withCaller(decisionEntry, callerOfDecision(decisionEntry.caller, deciderPrincipal, deps.config));
697
- const decisionAdmitted = judgeRun(deciderEntry, run);
697
+ const decisionAdmitted = await readVisibleRun(deciderEntry, runStore, taskId);
698
698
  if (decisionAdmitted === undefined) {
699
699
  deps.logger?.info?.("decide_404", { reason: "owner-mismatch", taskId, principalPresent: principal !== undefined });
700
700
  refuse(deciderEntry, res, "not_visible");
@@ -950,7 +950,7 @@ async function decidePeerInbound(req, res, id, env) {
950
950
  decider = proof.principal;
951
951
  }
952
952
  const coord = parsePeerInboundId(id);
953
- const outcome = coord === undefined ? { kind: "not_found" } : await env.face.decide(peerBoxScope(decider), coord, decision);
953
+ const outcome = coord === undefined ? { kind: "not_found" } : await env.face.decide(engineScopeOfOwner(decider), coord, decision);
954
954
  switch (outcome.kind) {
955
955
  case "not_found":
956
956
  sendError(res, 404, "not_found.approval", "approval not found");
@@ -1017,7 +1017,7 @@ function redactPendingDisclosures(row) {
1017
1017
  function peerInboundRowsFor(face, principal, operatorOwnerParam) {
1018
1018
  if (operatorOwnerParam !== undefined && operatorOwnerParam !== principal)
1019
1019
  return () => [];
1020
- const scope = peerBoxScope(principal);
1020
+ const scope = engineScopeOfOwner(principal);
1021
1021
  return () => face.list(scope);
1022
1022
  }
1023
1023
  function projectPendingForWire(row, deployment, agent) {
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * ── 读口:逐字投 core `list()` 行 ─────────────────────────────────────────────────────────────────
11
11
  * 读的是**进程内**注册表(`defaultTaskRegistry.list`),访问元组 = 会话自己的 `{ owner: sid, sessionId: sid, scope }`
12
- * (scope = 会话行属主 `owner ?? "default"`,与 core 注册铸值同源)⇒ 可见集完全由 core 的 `canAccess` 判(fail-closed:
12
+ * (scope = 会话的引擎租户分区 `sessionTenantScope`,经唯一换算 `engineScopeOfOwner`,与 core 注册铸值同源)⇒ 可见集完全由 core 的 `canAccess` 判(fail-closed:
13
13
  * 缺轴即拒;本会话的会话驻留行、task id 即会话 id 的 run 行、本会话发起的 workflow、根会话是本会话的后台 agent)。
14
14
  * 键逐个处置(下面的 {@link ROW_KEY_DISPOSITION},core 给行加键 ⇒ 编译红):`task_id` 改名 `id`;`retained` **真才带**
15
15
  * (core:缺席 ⇒ 这一行在 `includeRetained:false` 的硬面上会停);`description` 是模型写的描述、缺席时是启动时的命令文本 ——
@@ -40,8 +40,8 @@
40
40
  *
41
41
  * 🔴 **停止口在无凭据写门内**(`credentialGated: ["POST"]`;车OL F1 = 7.102.0 合并复审 gpt-6 腿 [high]):门的两个合取项它都中
42
42
  * —— ① 授权的唯一输入是 principal 头(属主判 `admitSessionRow` 与 operator 臂 `explicitOperatorOk` 读的都是 `gatedSubject`,
43
- * 无 service 凭证的部署上它收调用方自报的头);② 不可撤销、爆炸半径跨租户(知道会话 id + 自报它的属主 ⇒ 停掉那个会话的后台
44
- * 进程,`includeRetained:true` 连显式 retain 的活服务一起停)。于是无 service 凭证且未开 `ALLOW_UNAUTHED_WRITES` 的部署上它与
43
+ * 没带过门凭据的请求上它收调用方自报的头);② 不可撤销、爆炸半径跨租户(知道会话 id + 自报它的属主 ⇒ 停掉那个会话的后台
44
+ * 进程,`includeRetained:true` 连显式 retain 的活服务一起停)。于是无 service 凭证且未开 `ALLOW_UNAUTHED_WRITES` 的部署上,不带过门凭据的请求打它与
45
45
  * 其余改写门同码同句 503 `auth.service_token_required`(在路由之前,`dispatch.ts` 那一道),同一只会话级收敛函数的另一个调用点
46
46
  * `DELETE /v1/sessions/:id` 早在同一形下被 `isDestructiveSessionWrite` 拒。读口 `GET …/background` 不进:它有属主门兜底、只读、
47
47
  * 只列本会话,与 `GET /v1/rules` 同判。已知同族缺口(不在本口单独打补丁):能力位 `exitFaces` 不含「凭据就绪」这一项,见契约
@@ -19,7 +19,7 @@ import { sendJson, sendError } from "../send.js";
19
19
  import { codeFieldOf } from "../../terminal.js";
20
20
  import { engineRefusalAnswerOf } from "../engine-refusal.js";
21
21
  import { assertNever } from "../route-ctx.js";
22
- import { fileHistoryCaptureOf } from "../../file-history-capture.js";
22
+ import { fileHistoryCaptureOf, fileHistoryWired } from "../../file-history-capture.js";
23
23
  import { projectMemoryEngineCapability } from "../../memory-posture.js";
24
24
  import { projectWriteProtectionCapability } from "../../write-protection.js";
25
25
  import { projectStoreCapability, unwiredStorePosture } from "../../store-posture.js";
@@ -27,6 +27,7 @@ import { projectWebSearchCapability } from "../../plugins/web-search.js";
27
27
  import { projectExecutionLaneCapability } from "../../capabilities/execution-lane.js";
28
28
  import { SETTINGS_CONTRACT_CAPABILITY } from "../../capabilities/settings-contract.js";
29
29
  import { judgeSandboxGitPlane, sandboxGitPlanePremisesOf } from "../../sandbox-git-plane.js";
30
+ import { SESSION_KINDS } from "../../session-kind.js";
30
31
  import { MCP_ASSERTION_HEADER_SENT, MCP_REQUEST_TRANSPORT_KINDS } from "../../mcp-assertion-header.js";
31
32
  import { gateCompositeMembers } from "../../capabilities/composite-members.js";
32
33
  import { projectApprovalsStreamLiveCapability } from "../../capabilities/approvals-push.js";
@@ -37,7 +38,7 @@ import { judgeAutoModeArming } from "../../auto-mode-face.js";
37
38
  import { coercePermissionModeStrict, PERMISSION_MODE_WORDS, taskHooksHonored } from "../../task-settings.js";
38
39
  import { gatedPerson, sendPrincipalRefusal } from "../principal-gate.js";
39
40
  import { readAdoptionImportCapability } from "../../adoption/import.js";
40
- import { headReadOf } from "../../session-incarnation.js";
41
+ import { headReadPresent } from "../../session-incarnation.js";
41
42
  import { callerTrust } from "../caller-trust.js";
42
43
  import { sessionRulesNamespaceFormsHonored } from "../../session-policy-wire.js";
43
44
  function routePairingOf(deps, name, m) {
@@ -84,6 +85,7 @@ export async function handleCapabilities(req, res, match, ctx) {
84
85
  deps.logger?.warn("auto_mode_face_resolver_fault", { fault: autoModeFault });
85
86
  const rulesLaneForCaller = facts.ruleLaneForCaller(deps, gatedPerson(req, deps.config)).available;
86
87
  const streamApprovalFact = facts.streamApproval(deps);
88
+ const historyWired = fileHistoryWired(deps.backend);
87
89
  sendJson(res, 200, gateCompositeMembers({
88
90
  ...deps.capabilities,
89
91
  ...facts.engineCapabilityBits(),
@@ -207,22 +209,24 @@ export async function handleCapabilities(req, res, match, ctx) {
207
209
  sideQuery: true,
208
210
  agentRoster: facts.agentRoster(deps).available,
209
211
  projects: facts.projectRegistry(deps).available,
212
+ projectInheritance: facts.projectRegistry(deps).available,
210
213
  retention: retentionAdvertisement(deps.config),
211
214
  peerLane: Boolean(deps.peerDirectory),
212
215
  scenarioSubject: true,
213
216
  sessionList: facts.sessionList(deps).available,
214
217
  sessionSearch: facts.sessionList(deps).available,
218
+ sessionKinds: facts.sessionKinds(deps).available ? [...SESSION_KINDS] : [],
215
219
  sessionFork: facts.sessionFork(deps).available,
216
220
  sessionDelete: facts.sessionDelete(deps).available,
217
- resumeAt: Boolean(deps.resumeAnchorStore && headReadOf(deps.sessionStorage)),
221
+ resumeAt: deps.backend !== undefined && headReadPresent(deps.sessionStorage),
218
222
  promptSuggestions: true,
219
223
  sessionPolicy: facts.sessionPolicy(deps).available,
220
224
  sessionRulesNamespaceForms: sessionRulesNamespaceFormsHonored(),
221
- restoreFiles: Boolean(deps.fileHistoryStore),
222
- rewindFilesTo: Boolean(deps.fileHistoryStore && deps.resumeAnchorStore && headReadOf(deps.sessionStorage)),
225
+ restoreFiles: historyWired,
226
+ rewindFilesTo: historyWired && headReadPresent(deps.sessionStorage),
223
227
  sessionRewindFiles: facts.sessionRewindFiles(deps).available,
224
228
  sessionRewindFilesPreview: facts.sessionRewindFilesPreview(deps).available,
225
- fileHistoryCapture: fileHistoryCaptureOf(deps.fileHistoryStore, deps.config.fileHistoryCapture),
229
+ fileHistoryCapture: fileHistoryCaptureOf(historyWired, deps.config.fileHistoryCapture),
226
230
  scheduler: facts.hostScheduler(deps.config).available,
227
231
  sessionSync: facts.sessionSync(deps).available,
228
232
  sessionSyncFileHistory: facts.sessionSyncFileHistory(deps).available,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * DESIGN-278 §5 S2([ref])—— `GET /v1/config/catalog`:配置目录自描述端点(operator lane)。
2
+ * [ref] §5 S2([ref])—— `GET /v1/config/catalog`:配置目录自描述端点(operator lane)。
3
3
  *
4
4
  * TOB 运维在 web 上要一个**不撒谎**的配置目录:哪个键、什么腿(env/center)、改了何时生效
5
5
  * (hot/restart-片名/deploy/inert)、本机实际值 —— 今天这些事实散在 config.ts 数千行与三份文档里,
@@ -3,7 +3,7 @@ import { FLEET_SNAPSHOT_TERMINAL_MAX_ROWS, isTerminalWorkflowRowStatus, recentTe
3
3
  import { taskNotificationFoldKey } from "../../orchestration/workflow-completion-inbox.js";
4
4
  import { sendJson, sendError, sseHeaders } from "../send.js";
5
5
  import { gatedSubject, sendPrincipalRefusal } from "../principal-gate.js";
6
- import { routeListFilter } from "../owner-access.js";
6
+ import { routeListFilter, workflowScopeOf } from "../owner-access.js";
7
7
  import { assertNever } from "../route-ctx.js";
8
8
  import * as facts from "../../capability-facts.js";
9
9
  export async function handleFleet(req, res, match, ctx) {
@@ -24,22 +24,24 @@ export async function handleFleet(req, res, match, ctx) {
24
24
  const fleetParams = new URLSearchParams(match.search);
25
25
  const callerSession = fleetParams.get("session");
26
26
  const observeOnly = fleetParams.get("observe") === "1";
27
- await streamFleet(req, res, fleet.fleetBus, fleetWide ? null : (principal ?? "default"), callerSession || null, observeOnly ? undefined : deps.workflowCompletionInbox, { store: deps.workflowRunStore, scope: fleetWide ? null : (principal ?? "default"), pullScope: principal ?? "default", ready: deps.fleetRecoveryDone });
27
+ const workflowScope = workflowScopeOf(principal);
28
+ const viewer = fleetWide ? null : { rows: principal ?? "default", workflows: workflowScope };
29
+ await streamFleet(req, res, fleet.fleetBus, viewer, callerSession || null, observeOnly ? undefined : deps.workflowCompletionInbox, { store: deps.workflowRunStore, scope: viewer?.workflows ?? null, pullScope: workflowScope, ready: deps.fleetRecoveryDone });
28
30
  return;
29
31
  }
30
32
  default:
31
33
  return assertNever(match.decl.id);
32
34
  }
33
35
  }
34
- function streamFleet(req, res, bus, callerScope, callerSession = null, completionInbox, terminal) {
36
+ function streamFleet(req, res, bus, viewer, callerSession = null, completionInbox, terminal) {
35
37
  return new Promise((resolve) => {
36
38
  sseHeaders(res);
37
- res.write(`event: meta\ndata: ${JSON.stringify({ type: "meta", version: 1, scoped: callerScope !== null, sessionScoped: callerSession !== null, ...(callerSession !== null ? { session: callerSession } : {}), bgNotifyFailClosed: true })}\n\n`);
39
+ res.write(`event: meta\ndata: ${JSON.stringify({ type: "meta", version: 1, scoped: viewer !== null, sessionScoped: callerSession !== null, ...(callerSession !== null ? { session: callerSession } : {}), bgNotifyFailClosed: true })}\n\n`);
38
40
  const seenTasks = new Set();
39
41
  const seenWf = new Set();
40
42
  const sessionOk = (rowSession) => callerSession === null || rowSession === undefined || rowSession === callerSession;
41
- const visT = (r) => (callerScope === null || r.scope === callerScope) && sessionOk(r.sessionId);
42
- const visW = (r) => (callerScope === null || r.scope === callerScope) && sessionOk(r.sessionId);
43
+ const visT = (r) => (viewer === null || r.scope === viewer.rows) && sessionOk(r.sessionId);
44
+ const visW = (r) => (viewer === null || r.scope === viewer.workflows) && sessionOk(r.sessionId);
43
45
  const SCOPED_TASK_KEY_DISPOSITION = {
44
46
  id: "keep", parentId: "keep", parentToolCallId: "keep", workflowRunId: "keep", status: "keep",
45
47
  startedAt: "keep", elapsedMs: "keep", tokens: "keep",
@@ -144,7 +146,7 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
144
146
  break;
145
147
  case "hook_notice": {
146
148
  const hn = frame.notice;
147
- const hScopeOk = callerScope === null || hn.ownerScope === callerScope;
149
+ const hScopeOk = viewer === null || hn.ownerScope === viewer.rows;
148
150
  const hSessionOk = callerSession === null || hn.ownerSessionId === callerSession;
149
151
  if (hScopeOk && hSessionOk) {
150
152
  send("hook_notice", { type: "hook_notice", ...hookNoticeWire(hn), ts: frame.ts });
@@ -153,7 +155,7 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
153
155
  }
154
156
  case "bg_notification": {
155
157
  const n = frame.notification;
156
- const scopeOk = callerScope === null || n.ownerScope === callerScope;
158
+ const scopeOk = viewer === null || n.ownerScope === viewer.rows;
157
159
  const sessionInjectOk = callerSession === null || n.ownerSessionId === callerSession;
158
160
  if (scopeOk && sessionInjectOk) {
159
161
  const { ownerScope: _os, ownerSessionId: _osid, ...wire } = n;
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { isParkedRunStatus, isTerminalRunStatus, runProvenElsewhere } from "../../plugins/store-contracts.js";
3
3
  import { DeadlineExceeded, MCP_DIAL_DEADLINE_MS, raceDeadline } from "../mcp-dial-deadline.js";
4
4
  import { sendJson, sendError } from "../send.js";
5
- import { admitSessionById, enter } from "../owner-access.js";
5
+ import { admitSessionById, enter, runFactsOf } from "../owner-access.js";
6
6
  import { assertNever } from "../route-ctx.js";
7
7
  import * as facts from "../../capability-facts.js";
8
8
  import { seatText } from "../../trace/exit-seat.js";
@@ -118,7 +118,7 @@ export async function handleMcpReconnect(req, res, match, ctx) {
118
118
  }
119
119
  }
120
120
  }
121
- const run = activeTaskId === undefined ? undefined : await runStore.getRun(activeTaskId);
121
+ const run = activeTaskId === undefined ? undefined : await runFactsOf(runStore, activeTaskId);
122
122
  if (run && isParkedRunStatus(run.status)) {
123
123
  sendError(res, 409, "steering.not_running", "run is waiting on a pending decision — the MCP re-dial verb needs a live turn; a resumed continuation dials every declared server afresh (the re-dial applies to the current turn only and is not persisted), so resume this run first — a re-dial cannot be queued behind the decision");
124
124
  return;
@@ -116,7 +116,7 @@ export declare function buildClearanceRowWire(r: OriginClearanceRow): {
116
116
  baseRev: string;
117
117
  origin: {
118
118
  at: number;
119
- cause?: "static" | "unattributed" | "observed" | "derived" | undefined;
119
+ cause?: "static" | "observed" | "derived" | "unattributed" | undefined;
120
120
  taint: "external";
121
121
  };
122
122
  };
@@ -1,6 +1,6 @@
1
1
  import { sendJson, sendError } from "../send.js";
2
2
  import { gatedSubject, sendPrincipalRefusal } from "../principal-gate.js";
3
- import { admitSessionRow, enter, refuse } from "../owner-access.js";
3
+ import { admitSessionById, enter, refuse } from "../owner-access.js";
4
4
  import { sendResumeOutcome } from "../route-ctx.js";
5
5
  import { assertNever } from "../route-ctx.js";
6
6
  import * as facts from "../../capability-facts.js";
@@ -54,8 +54,7 @@ export async function handleNotifyWake(req, res, match, ctx) {
54
54
  sendError(res, 501, "capability.session_ownership_required", "external notify requires the session-ownership face (sessionStorage.headOf)");
55
55
  return;
56
56
  }
57
- const notifyHead = await owned.sessionStorage.headOf(notifySession);
58
- const notifyAdmitted = await admitSessionRow(notifyEntry, res, owned.sessionStorage, notifySession, notifyHead);
57
+ const notifyAdmitted = await admitSessionById(notifyEntry, res, owned.sessionStorage, notifySession);
59
58
  if (notifyAdmitted === undefined)
60
59
  return;
61
60
  const payload = {
@@ -9,8 +9,9 @@
9
9
  * · **登记簿只由配置中心下发**:settings-schema 的本地读取集不收 `projects` 域 ⇒ 没有中心腿在应用配置的部署上没有登记簿 —— 两口 501
10
10
  * `capability.unavailable`,能力位 `capabilities.projects`(布尔)读同一只事实(`capability-facts.ts` 的 `projectRegistry`)答 `false`;
11
11
  * 有登记簿时答 `true`。本面不开写动词(写到哪里由另一张设计定;写面到货时另立一位,本位不改义)。
12
- * · **可见性 fail-closed**:身份判在登记簿在场判**之前**(否则「这台有没有登记簿」先于 401 泄出去);fleet 调用方(列表面 `list.read` 读档(`listFilterOf`))看全部;
13
- * 带验过主体的调用方只看 `registeredBy` 恰是自己的登记;看不见的与不存在的同码同句(404 `not_found.project`,不给存在性预言机)。
12
+ * · **可见性 fail-closed**:身份判在登记簿在场判**之前**(否则「这台有没有登记簿」先于 401 泄出去);判与按 id 取只有一只(`project-registry.ts`:
13
+ * fleet 调用方(列表面 `list.read` 读档(`listFilterOf`))看全部,带验过主体的调用方只看 `registeredBy` 恰是自己的登记 —— 项目上下文继承与登记簿默认读层种子同读它);
14
+ * 看不见的与不存在的同码同句(404 `not_found.project`,不给存在性预言机)。
14
15
  *
15
16
  * 归档:`archivedAt` 在场 = 已归档。列表缺省不列,`?archived=true` 只列已归档的,`?archived=false` 与缺省同;单项读不论归档与否都答(会话行引用它)。
16
17
  */
@@ -48,6 +49,7 @@ export declare const PROJECT_ROW_DISPOSITIONS: {
48
49
  readonly registeredBy: "forward";
49
50
  readonly registeredAt: "forward";
50
51
  readonly archivedAt: "forward";
52
+ readonly contentAttestedAt: "forward";
51
53
  };
52
54
  /** 项目行的键全集(处置表的键 = wire 上可能出现的每一个键;自铸登记表 `trace/self-minted-wire.ts` 的 `projectRowKey` 按它 `satisfies`)。 */
53
55
  export type ProjectRowKey = keyof typeof PROJECT_ROW_DISPOSITIONS;