@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
@@ -14,8 +14,8 @@ import { readWritableSessionPermissionRules } from "../../session-policy-wire.js
14
14
  import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
15
15
  import { gatedPerson, gatedSubject, sendPrincipalRefusal } from "../principal-gate.js";
16
16
  import { personOf } from "../../owner-brands.js";
17
- import { headReadOf, leafOfAdmittedHead, sessionFaceOfHead } from "../../session-incarnation.js";
18
- import { admitSessionById, admitSessionRow, admittedAsFleet, callerEntry, callerOf, deliverVerdict, enter, judgeSessionRow, protocolEntry, readOwnerCell, refuse, seesRun, sessionRowPresent } from "../owner-access.js";
17
+ import { leafOfAdmittedHead, sessionFaceOfHead } from "../../session-incarnation.js";
18
+ import { admitSessionById, admitSessionForDeletion, admitSessionRow, admitSessionView, admittedAsFleet, callerEntry, callerOf, deliverVerdict, enter, judgeSessionById, protocolEntry, readOwnerCell, readVisibleLatestRun, refuse, sessionOccupantUnchanged } from "../owner-access.js";
19
19
  import { assertNever } from "../route-ctx.js";
20
20
  import * as facts from "../../capability-facts.js";
21
21
  import { rosterAgentId } from "./agents-roster.js";
@@ -67,11 +67,9 @@ async function readLastLegMcp(deps, sessionId, entry) {
67
67
  const runStore = deps.runStore;
68
68
  if (!runStore || sessionId === null)
69
69
  return undefined;
70
- const latest = await runStore.latestRunForSession(sessionId);
70
+ const latest = await readVisibleLatestRun(entry, runStore, sessionId);
71
71
  if (latest === undefined)
72
72
  return undefined;
73
- if (!seesRun(entry, latest.owner))
74
- return undefined;
75
73
  const events = await runStore.getEvents(latest.taskId, 0);
76
74
  for (let i = events.length - 1; i >= 0; i--) {
77
75
  const ev = events[i];
@@ -87,26 +85,7 @@ async function readLastLegMcp(deps, sessionId, entry) {
87
85
  export async function handleSessions(req, res, match, ctx) {
88
86
  const { deps } = ctx;
89
87
  const { readJson, safeDecode } = ctx.helpers;
90
- const readOwnedSessionView = async (entry, sessionAudit, sessionId, readOpts) => {
91
- const headOf = headReadOf(deps.sessionStorage);
92
- if (headOf !== undefined) {
93
- const head = await readOwnerCell(entry, sessionId, () => headOf(sessionId));
94
- if ((await admitSessionRow(entry, res, deps.sessionStorage, sessionId, head)) === undefined)
95
- return undefined;
96
- }
97
- let audit;
98
- try {
99
- audit = await sessionAudit(sessionId, readOpts);
100
- }
101
- catch (e) {
102
- if (headOf !== undefined)
103
- throw e;
104
- throw new Error(`session view read failed before ownership could be established: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
105
- }
106
- if ((await admitSessionRow(entry, res, deps.sessionStorage, sessionId, audit)) === undefined)
107
- return undefined;
108
- return audit;
109
- };
88
+ const readOwnedSessionView = (entry, sessionAudit, sessionId, readOpts) => admitSessionView(entry, res, deps.sessionStorage, sessionAudit, sessionId, readOpts);
110
89
  const sse = ctx.local.sessions;
111
90
  const { mcpStatusCache, a2aStatusCache } = ctx.local.sessions;
112
91
  {
@@ -262,8 +241,8 @@ export async function handleSessions(req, res, match, ctx) {
262
241
  }
263
242
  {
264
243
  if (match.decl.id === "session-head") {
265
- const headOf = headReadOf(deps.sessionStorage);
266
- if (!headOf) {
244
+ const headFact = facts.sessionOwnership(deps);
245
+ if (!headFact.available) {
267
246
  sendError(res, 501, "capability.session_store_required", "session head probe requires a durable session store (DB_BACKEND=mysql|pg|local)");
268
247
  return;
269
248
  }
@@ -273,8 +252,7 @@ export async function handleSessions(req, res, match, ctx) {
273
252
  return;
274
253
  }
275
254
  const headEntry = callerEntry(req, deps, match.decl.id);
276
- const headRead = await readOwnerCell(headEntry, headSession, () => headOf(headSession));
277
- const admittedHead = await admitSessionRow(headEntry, res, deps.sessionStorage, headSession, headRead);
255
+ const admittedHead = await admitSessionById(headEntry, res, headFact.sessionStorage, headSession);
278
256
  if (admittedHead === undefined)
279
257
  return;
280
258
  const leafId = leafOfAdmittedHead(admittedHead.row);
@@ -317,8 +295,6 @@ export async function handleSessions(req, res, match, ctx) {
317
295
  return;
318
296
  }
319
297
  const evEntry = callerEntry(req, deps, match.decl.id);
320
- const readHead = (id) => readOwnerCell(evEntry, id, () => evFact.sessionStorage.headOf(id));
321
- const readOwner = async (id) => (await readHead(id))?.owner;
322
298
  const watch = evFact.watch;
323
299
  const evSession = safeDecode(match.params.sessionId);
324
300
  if (evSession === null) {
@@ -354,7 +330,7 @@ export async function handleSessions(req, res, match, ctx) {
354
330
  return;
355
331
  }
356
332
  sse.sseOwnerLookups++;
357
- const admissionP = readHead(evSession).then(async (head) => (!sessionRowPresent(head) ? undefined : { head, verdict: await judgeSessionRow(evEntry, evFact.sessionStorage, evSession, head) }));
333
+ const admissionP = judgeSessionById(evEntry, evFact.sessionStorage, evSession);
358
334
  void admissionP.catch(() => undefined).then(() => { sse.sseOwnerLookups--; });
359
335
  let stallTimer;
360
336
  let admission;
@@ -381,12 +357,13 @@ export async function handleSessions(req, res, match, ctx) {
381
357
  refuse(evEntry, res, "missing");
382
358
  return;
383
359
  }
384
- if (deliverVerdict(evEntry, res, admission.verdict) === undefined) {
360
+ const evAdmitted = deliverVerdict(evEntry, res, admission);
361
+ if (evAdmitted === undefined) {
385
362
  cleanup();
386
363
  return;
387
364
  }
388
- leafOfAdmittedHead(admission.head);
389
- const owner = admission.head.owner;
365
+ leafOfAdmittedHead(evAdmitted.row);
366
+ const owner = evAdmitted.row.owner;
390
367
  const q = new URLSearchParams(match.search);
391
368
  const lastLeafId = q.get("lastLeafId");
392
369
  let first = true;
@@ -485,9 +462,9 @@ export async function handleSessions(req, res, match, ctx) {
485
462
  }
486
463
  ownerCheckPending = true;
487
464
  ownerCheckStartedAt = Date.now();
488
- void readOwner(evSession).then((o) => {
465
+ void sessionOccupantUnchanged(evEntry, evFact.sessionStorage, evSession, evAdmitted.row).then((same) => {
489
466
  ownerCheckPending = false;
490
- if (!closed && o !== owner)
467
+ if (!closed && !same)
491
468
  onEnd();
492
469
  }).catch(() => { ownerCheckPending = false; });
493
470
  }, hbMs);
@@ -615,7 +592,7 @@ export async function handleSessions(req, res, match, ctx) {
615
592
  sendJson(res, 200, {
616
593
  sessionId,
617
594
  autoConsolidationArmed: deps.memoryAutoConsolidationArmed,
618
- ...(deps.memorySyncLeg !== undefined ? { memorySync: { parked: deps.memorySyncLeg.parked().map((p) => ({ scope: p.scope, wayOut: p.wayOut })) } } : {}),
595
+ ...(deps.memorySyncLeg !== undefined ? { memorySync: { parked: deps.memorySyncLeg.parked() } } : {}),
619
596
  ...(s.captureOptedOut !== undefined ? { captureOptedOut: s.captureOptedOut } : {}),
620
597
  ...(s.committedCount !== undefined ? { committedCount: s.committedCount } : {}),
621
598
  ...(s.foldedCount !== undefined ? { foldedCount: s.foldedCount } : {}),
@@ -706,14 +683,11 @@ export async function handleSessions(req, res, match, ctx) {
706
683
  const store = rowFact.sessionStorage;
707
684
  const sessionId = match.params.sessionId;
708
685
  const patchEntry = callerEntry(req, deps, match.decl.id);
709
- const head = await store.headOf(sessionId);
710
- if (head === undefined) {
711
- refuse(patchEntry, res, "missing");
686
+ const patchAdmitted = await admitSessionById(patchEntry, res, store, sessionId);
687
+ if (patchAdmitted === undefined)
712
688
  return;
713
- }
689
+ const head = patchAdmitted.row;
714
690
  const face = sessionFaceOfHead(sessionId, head);
715
- if ((await admitSessionRow(patchEntry, res, store, sessionId, face)) === undefined)
716
- return;
717
691
  leafOfAdmittedHead(head);
718
692
  const read = readSessionRowPatch(await readJson(req));
719
693
  if ("problem" in read) {
@@ -903,7 +877,7 @@ export async function handleSessions(req, res, match, ctx) {
903
877
  sendError(res, 400, "request.id_invalid", "invalid session id (must be a canonical uuid)");
904
878
  return;
905
879
  }
906
- const deleteAdmitted = await admitSessionById(deleteEntry, res, deleteFact.gateStore, sessionId);
880
+ const deleteAdmitted = await admitSessionForDeletion(deleteEntry, res, deleteFact.sessionStorage, sessionId);
907
881
  if (deleteAdmitted === undefined)
908
882
  return;
909
883
  const owner = deleteAdmitted.row.owner;
@@ -931,7 +905,7 @@ export async function handleSessions(req, res, match, ctx) {
931
905
  sendError(res, 501, "capability.session_store_required", "session policy requires a session-store backend");
932
906
  return;
933
907
  }
934
- const store = policyFact.policyStore;
908
+ const store = policyFact.backend.sessionPolicy();
935
909
  const policyEntry = enter(req, res, deps, match.decl.id);
936
910
  if (policyEntry === undefined)
937
911
  return;
@@ -973,8 +947,12 @@ export async function handleSessions(req, res, match, ctx) {
973
947
  }
974
948
  const rules = read.rules;
975
949
  try {
976
- const stored = await store.putRules(sessionId, target, rules, { ...(typeof body.expectedRev === "number" ? { expectedRev: body.expectedRev } : {}), operator });
977
- sendJson(res, 200, { rules: stored });
950
+ const stored = await policyFact.backend.landedAttendants().putPolicy(sessionId, sessionFaceOfHead(sessionId, policyAdmitted.row), target, rules, { ...(typeof body.expectedRev === "number" ? { expectedRev: body.expectedRev } : {}), operator });
951
+ if (!stored.landed) {
952
+ refuse(policyEntry, res, "missing");
953
+ return;
954
+ }
955
+ sendJson(res, 200, { rules: stored.value });
978
956
  }
979
957
  catch (e) {
980
958
  if (sendSessionPolicyError(res, e))
@@ -1,7 +1,7 @@
1
1
  import { redactErrorMessage, redactHead, redactTerminalResult } from "../../observability/run-terminal.js";
2
2
  import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
3
3
  import { heldFor } from "../../peer-seat.js";
4
- import { beatRunHeartbeat, graftParkToolCallId, heldParkOf, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, settleResumeAnchor, TurnAnchorCapture, HEARTBEAT_MS } from "../../runs.js";
4
+ import { beatRunHeartbeat, createRunAnchorWriter, graftParkToolCallId, heldParkOf, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, settleResumeAnchor, TurnAnchorCapture, HEARTBEAT_MS } from "../../runs.js";
5
5
  import { commitParkRow } from "../../park-row-commit.js";
6
6
  import { atHostBoundary, failureCodeOf, sealResultForExit, outwardPlane } from "../../terminal.js";
7
7
  import { voidVerifierPauseCard } from "../../verifier-pause-card.js";
@@ -21,7 +21,8 @@ import { writeLiveFrame, writeLiveHeartbeat } from "../live-frame.js";
21
21
  import { contextUsageEventData, turnEndEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestFaceEventData, toolRosterDeltaEventData, toolProgressEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat, identityFields } from "../../trace/project.js";
22
22
  import { cascadeConfig, fillRunPreviewOnDelivery, runMeta } from "../run-meta.js";
23
23
  import { idemCallerOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
24
- import { isReplayedOutcome, replayedOutcome, replayOfExistingRun } from "../submit-replay.js";
24
+ import { answerReplay, isReplayedOutcome, replayedOutcome, replayOfExistingRun } from "../submit-replay.js";
25
+ import { readReplayHit, runFactsOf, sessionOccupantReadOf } from "../owner-access.js";
25
26
  import { httpErrorCode, sendJson, sseHeaders } from "../send.js";
26
27
  import { collectSsePreamble } from "../sse-log.js";
27
28
  import { buildApprovalPreamble } from "../../approval-card.js";
@@ -32,7 +33,7 @@ import { SUBMISSION_CLAIM_FACE, commitExecutionContext, faultedAnswerOf } from "
32
33
  import { rootSessionAbsentAnswer } from "../execution-context.js";
33
34
  import { recheckClaimBeforeLaunch, startClaimHeartbeat } from "../claim-heartbeat.js";
34
35
  import { timeClaim } from "../claim-latency.js";
35
- import { commitSessionInheritEnv } from "../session-inherit-env.js";
36
+ import { commitLegBindings } from "../../session-bindings.js";
36
37
  import { headerStr, gatedPerson, gatedSubject, explicitOperatorOk, runIdentityOf } from "../principal-gate.js";
37
38
  import { recoveredSubject } from "../../owner-faces.js";
38
39
  import { recordFailOpen } from "../../observability/fail-open.js";
@@ -109,12 +110,12 @@ export async function handleTasks(req, res, match, ctx) {
109
110
  const idem = rawIdem ? submissionIdemOf(rawIdem, idemCallerOf(req, ctx), keyedBody) : undefined;
110
111
  const inflightKey = idem ? inflightKeyOf(idem, "sync") : undefined;
111
112
  const cached = inflightKey ? idemCache.peek(inflightKey) : undefined;
112
- const keyedRow = idem && !cached && deps.runStore ? await deps.runStore.getRunByIdem(idem.key) : undefined;
113
- if (keyedRow && deps.runStore) {
114
- const replay = await replayOfExistingRun(keyedRow, { subject: submitter, idem }, "sync", deps, deps.runStore);
115
- if (liveStream && replay.status === 200) {
116
- sseHeaders(res, { "x-task-id": keyedRow.taskId });
117
- writeMetaFrame(res, keyedRow.taskId, keyedRow.sessionId);
113
+ const keyedHit = idem && !cached && deps.runStore ? await readReplayHit(submitter, deps.config, deps.runStore, { idemKey: idem.key }, undefined) : undefined;
114
+ if (keyedHit && deps.runStore) {
115
+ const replay = await answerReplay(keyedHit, { subject: submitter, idem }, "sync", deps.runStore);
116
+ if (liveStream && replay.status === 200 && keyedHit.kind === "visible") {
117
+ sseHeaders(res, { "x-task-id": keyedHit.row.taskId });
118
+ writeMetaFrame(res, keyedHit.row.taskId, keyedHit.row.sessionId);
118
119
  writeLiveFrame(res, doneFrameOfOutcome(replay));
119
120
  res.end();
120
121
  }
@@ -294,13 +295,20 @@ export async function handleTasks(req, res, match, ctx) {
294
295
  const promptCommit = createPromptCommitReader();
295
296
  let anchorPut = false;
296
297
  const putRewindAnchor = async () => {
297
- const store = deps.resumeAnchorStore;
298
- const key = durableTaskId;
299
298
  const entryId = userMsgEntryId;
300
- if (anchorPut || !entryId || !key || !store)
299
+ const write = createRunAnchorWriter({
300
+ seat: deps.backend?.landedAttendants(),
301
+ sessionId: prepared.spec.sessionId,
302
+ owner: principal ?? null,
303
+ promptKey: durableTaskId,
304
+ witness: prepared.legFacts?.sessionWitness,
305
+ occupantOf: sessionOccupantReadOf(deps.sessionStorage),
306
+ leafOf: undefined,
307
+ }).prompt;
308
+ if (anchorPut || !entryId || write === undefined)
301
309
  return;
302
310
  anchorPut = true;
303
- await settleResumeAnchor(() => store.put(prepared.spec.sessionId, key, entryId, principal ?? null), { leg: "stream", kind: "prompt" });
311
+ await settleResumeAnchor((held) => write(entryId, held), { leg: "stream", kind: "prompt" });
304
312
  };
305
313
  try {
306
314
  if (deps.runStore) {
@@ -357,7 +365,7 @@ export async function handleTasks(req, res, match, ctx) {
357
365
  writeTerminalFrame(doneFrameOfOutcome(claimFault));
358
366
  return claimFault;
359
367
  }
360
- commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
368
+ commitLegBindings(deps, prepared.seat, prepared.spec.sessionId, prepared.legFacts?.sessionBindings);
361
369
  markChildrenStoppedByUserOnAbort(ac.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.subject);
362
370
  let ledgerSink;
363
371
  let ledgerTerminal = false;
@@ -530,7 +538,7 @@ export async function handleTasks(req, res, match, ctx) {
530
538
  await deps.userInputLedger?.observeLegEvent(liveStream, ev);
531
539
  await prepared.acceptance.observe(ev);
532
540
  if (ev.type === "done")
533
- prepared.acceptance.settle(ev.result);
541
+ await prepared.acceptance.settle(ev.result);
534
542
  await liveWorkspace.observe(ev);
535
543
  if (ledgerSink)
536
544
  await manifestSeat?.drain(ledgerSink.append);
@@ -800,7 +808,7 @@ export async function handleTasks(req, res, match, ctx) {
800
808
  evict();
801
809
  if (!runRowSettled && durableTaskId && deps.runStore) {
802
810
  try {
803
- const row = await deps.runStore.getRun(durableTaskId);
811
+ const row = await runFactsOf(deps.runStore, durableTaskId);
804
812
  if (row?.status === "running") {
805
813
  const pending = await deps.checkpointStore?.findPendingTokenBySession(prepared.spec.sessionId, undefined, { axis: "run" });
806
814
  const backstopCause = ac.cause();
@@ -938,7 +946,7 @@ export async function handleTasks(req, res, match, ctx) {
938
946
  catch (e) {
939
947
  return faultedAnswerOf(e, SUBMISSION_CLAIM_FACE.faulted);
940
948
  }
941
- commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
949
+ commitLegBindings(deps, prepared.seat, prepared.spec.sessionId, prepared.legFacts?.sessionBindings);
942
950
  const syncCancelCtrl = createRunAbort(principal ?? null);
943
951
  markChildrenStoppedByUserOnAbort(syncCancelCtrl.signal, durableTaskId ?? prepared.spec.sessionId, prepared.auth?.subject);
944
952
  if (durableTaskId && deps.runStore) {
@@ -974,15 +982,22 @@ export async function handleTasks(req, res, match, ctx) {
974
982
  counters.uncountedBillableInflight++;
975
983
  try {
976
984
  const heldDecisions = await heldWorkflowParkDecisions(deps, prepared.spec.sessionId);
977
- const compositionInternals = { ...heldDecisions, ...compositionLegRoot(prepared.legFacts?.registeredCwd) };
985
+ const compositionInternals = { ...heldDecisions, ...compositionLegRoot(prepared.legFacts?.sessionBindings.cwd) };
978
986
  const verifyLeg = (v) => runWithVerification(prepared.runner, specWithSignal, v, compositionInternals);
979
987
  const cascadeLeg = () => runCascade(prepared.runner, specWithSignal, cascadeConfig(deps.config.cascadeLadder, prepared.spec.limits?.maxCostUsd), compositionInternals);
980
988
  const plainLeg = async () => {
981
989
  const stream = prepared.runner.runTaskStream(specWithSignal, undefined, heldDecisions);
982
990
  const syncWorkspace = createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), prepared.legFacts?.sessionWitness);
983
- const anchorKey = durableTaskId;
984
- const anchorStore = deps.resumeAnchorStore;
985
- const anchor = new TurnAnchorCapture(undefined, "sync", anchorStore && anchorKey ? async (entryId) => { await anchorStore.put(prepared.spec.sessionId, anchorKey, entryId, principal ?? null); } : undefined);
991
+ const anchorWriter = createRunAnchorWriter({
992
+ seat: deps.backend?.landedAttendants(),
993
+ sessionId: prepared.spec.sessionId,
994
+ owner: principal ?? null,
995
+ promptKey: durableTaskId,
996
+ witness: prepared.legFacts?.sessionWitness,
997
+ occupantOf: sessionOccupantReadOf(deps.sessionStorage),
998
+ leafOf: undefined,
999
+ });
1000
+ const anchor = new TurnAnchorCapture(undefined, "sync", anchorWriter.prompt);
986
1001
  for await (const ev of stream) {
987
1002
  observeSyncLegEvent(ev);
988
1003
  switch (ev.type) {
@@ -1039,18 +1054,18 @@ export async function handleTasks(req, res, match, ctx) {
1039
1054
  const syncPlane = outwardPlane(result.terminal);
1040
1055
  const syncHeld = heldParkOf(result);
1041
1056
  if (syncHeld !== undefined && deps.checkpointStore && deps.runStore && durableTaskId) {
1057
+ await prepared.acceptance.settle(result);
1042
1058
  const parked = await commitParkRow({
1043
1059
  runStore: deps.runStore, taskId: durableTaskId, word: syncHeld.word, result: exitResult, card: { token: syncHeld.token, sessionId: prepared.spec.sessionId }, cards: deps.checkpointStore, leg: "sync",
1044
1060
  legId: heldLegOf(durableLegId, durableTaskId), staleWindowMs: deps.config.runStaleSec * 1000,
1045
1061
  });
1046
- prepared.acceptance.settle(result);
1047
1062
  if (parked.kind === "ended")
1048
1063
  return { status: 200, body: withSyncSubmitKeys(parked.row !== undefined ? syncSubmitBodyOfRow(parked.row) : { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "failed" }) };
1049
1064
  return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: syncHeld.word })) };
1050
1065
  }
1066
+ await prepared.acceptance.settle(result);
1051
1067
  if (durableTaskId && deps.runStore)
1052
1068
  await deps.runStore.setTerminal(durableTaskId, syncPlane.status, exitResult, syncPlane.errorMessage ?? null);
1053
- prepared.acceptance.settle(result);
1054
1069
  finalizeTaskResult(result, principal, prepared.spec.objective);
1055
1070
  noteRunOutcome(result);
1056
1071
  return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult)) };
@@ -9,7 +9,7 @@ import { bindSseLifecycle } from "../sse-lifecycle.js";
9
9
  import { sendJson, sendError, sseHeaders, SSE_MAX_STREAM_MS, SSE_HEARTBEAT_IDLE_MS } from "../send.js";
10
10
  import { filterFingerprint } from "../cursor-fingerprint.js";
11
11
  import { sendUnauthorized } from "../principal-gate.js";
12
- import { admitRunById, enter, entryIsFleet, readVisibleRun, routeListFilter, runRowAt } from "../owner-access.js";
12
+ import { admitRunById, enter, entryIsFleet, listVisibleRuns, readVisibleRun, routeListFilter, listOwnerOf, toolResultRefOwned } from "../owner-access.js";
13
13
  import { listFilterOf } from "../../owner-faces.js";
14
14
  import { assertNever } from "../route-ctx.js";
15
15
  import * as facts from "../../capability-facts.js";
@@ -42,7 +42,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
42
42
  const traceEntry = enter(req, res, deps, match.decl.id);
43
43
  if (traceEntry === undefined)
44
44
  return;
45
- const gateOwner = listFilterOf(traceEntry.face, traceEntry.caller).gateOwner;
45
+ const traceFilter = listFilterOf(traceEntry.face, traceEntry.caller);
46
46
  const runs = facts.durableRuns(deps);
47
47
  if (!runs.available) {
48
48
  sendError(res, 501, "capability.run_store_required", "trace API requires a durable run store (DB_BACKEND=mysql|pg|local)");
@@ -61,20 +61,20 @@ export async function handleTraceUsage(req, res, match, ctx) {
61
61
  }
62
62
  switch (match.decl.id) {
63
63
  case "task-trace-list":
64
- await handleTaskList(res, runStore, query, gateOwner);
64
+ await handleTaskList(res, runStore, query, traceFilter);
65
65
  return;
66
66
  case "task-trace-turns":
67
67
  await handleTaskTurns(res, runStore, admittedRun, query);
68
68
  return;
69
69
  case "task-trace-stream":
70
- await streamTaskTrace(req, res, runStore, admittedRun, match.search);
70
+ await streamTaskTrace(req, res, runStore, traceEntry, admittedRun, match.search);
71
71
  return;
72
72
  case "task-trace-artifacts":
73
73
  await handleTaskArtifacts(res, runStore, admittedRun);
74
74
  return;
75
75
  case "task-tool-result": {
76
76
  const ownedRun = admittedRun;
77
- const readRun = ownedRun !== undefined ? async () => ownedRun : () => readVisibleRun(traceEntry, runStore, taskId);
77
+ const readRun = ownedRun !== undefined ? async () => ownedRun : async () => (await readVisibleRun(traceEntry, runStore, taskId))?.row;
78
78
  await handleToolResult(res, deps.toolResultStore, taskId, readRun, safeDecode(match.params.ref), query);
79
79
  return;
80
80
  }
@@ -161,11 +161,12 @@ function decodeCursor(s, expectF) {
161
161
  return undefined;
162
162
  }
163
163
  }
164
- async function handleTaskList(res, runStore, query, forceOwner) {
164
+ async function handleTaskList(res, runStore, query, filter) {
165
165
  const status = query.get("status") ?? undefined;
166
166
  const jobId = query.get("jobId") ?? undefined;
167
167
  const source = query.get("source") ?? undefined;
168
- const owner = forceOwner != null ? forceOwner : (query.get("owner") ?? undefined);
168
+ const namedOwner = query.get("owner") ?? undefined;
169
+ const owner = listOwnerOf(filter, namedOwner);
169
170
  const limit = Math.min(100, Math.max(1, Number(query.get("limit") ?? 50) || 50));
170
171
  const f = filterFingerprint([status, jobId, source, owner]);
171
172
  const cursor = decodeCursor(query.get("cursor"), f);
@@ -173,7 +174,7 @@ async function handleTaskList(res, runStore, query, forceOwner) {
173
174
  sendError(res, 400, "request.cursor_filter_mismatch", "cursor was issued under a different filter (status/jobId/source/owner) — restart from the first page without a cursor");
174
175
  return;
175
176
  }
176
- const rows = await runStore.listRuns({ ...(status ? { status } : {}), ...(jobId ? { jobId } : {}), ...(source ? { source } : {}), ...(owner ? { owner } : {}), ...(cursor ? { cursor } : {}), limit: limit + 1 });
177
+ const rows = await listVisibleRuns(runStore, filter, namedOwner, { ...(status ? { status } : {}), ...(jobId ? { jobId } : {}), ...(source ? { source } : {}), ...(cursor ? { cursor } : {}), limit: limit + 1 });
177
178
  const hasMore = rows.length > limit;
178
179
  const page = hasMore ? rows.slice(0, limit) : rows;
179
180
  const tasks = page.map((r) => taskSummary(r));
@@ -216,8 +217,7 @@ async function handleToolResult(res, store, taskId, readRun, ref, query) {
216
217
  const run = await readRun();
217
218
  if (!run)
218
219
  return notFound();
219
- const owner = store?.ownerOf ? await store.ownerOf(ref) : undefined;
220
- const ownedByThisCaller = owner !== undefined && owner.sessionId === run.sessionId && (owner.taskId === undefined || owner.taskId === taskId);
220
+ const ownedByThisCaller = await toolResultRefOwned(store, ref, run);
221
221
  if (!ownedByThisCaller)
222
222
  return notFound();
223
223
  if (!store)
@@ -240,7 +240,7 @@ async function handleTaskTurns(res, runStore, run, query) {
240
240
  const nextCursor = eligible.length > limit && oldest ? String(oldest.seq) : undefined;
241
241
  sendJson(res, 200, { turns, ...(nextCursor ? { nextCursor } : {}), retainedFrom });
242
242
  }
243
- async function streamTaskTrace(req, res, runStore, admitted, search) {
243
+ async function streamTaskTrace(req, res, runStore, entry, admitted, search) {
244
244
  const taskId = admitted.taskId;
245
245
  const lastId = Number(req.headers["last-event-id"] ?? new URLSearchParams(search).get("from") ?? 0);
246
246
  let from = Number.isFinite(lastId) ? lastId : 0;
@@ -264,11 +264,11 @@ async function streamTaskTrace(req, res, runStore, admitted, search) {
264
264
  }
265
265
  };
266
266
  while (!closed) {
267
- const [events, raw] = await Promise.all([runStore.getEvents(taskId, from), runStore.getRun(taskId)]);
267
+ const [events, reread] = await Promise.all([runStore.getEvents(taskId, from), readVisibleRun(entry, runStore, taskId)]);
268
268
  write(events);
269
- if (!raw)
269
+ if (!reread)
270
270
  break;
271
- const run = await runRowAt("task-trace-stream", runStore, raw);
271
+ const run = reread.row;
272
272
  if (run.status !== "running") {
273
273
  write(await runStore.getEvents(taskId, from));
274
274
  if (!deliveredTerminal && isHolderDeathVerdict(run))
@@ -2,6 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import { type WorkflowRun } from "@sema-agent/core";
3
3
  import { type Admit } from "../../trace/projection-table.js";
4
4
  import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js";
5
+ /** SVC-5 的 steer 路——`handle()` 里位置在 tasks/runs 之后(鉴权门之后),故是**独立**的域入口。 */
5
6
  /** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
6
7
  * = 「本域已应答」;走到函数尾才是「没匹配上」。跨域的东西一律在首行解构出来。 */
7
8
  export declare function handleWorkflows(req: IncomingMessage, res: ServerResponse, match: RouteMatch<WorkflowsRouteId>, ctx: RouteCtx): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { persistedPlaneOf } from "../../terminal.js";
2
2
  import { z } from "zod";
3
- import { getWorkflowRun, subscribeWorkflow, deriveAgentDisplayStatus, callKeyOrdinal, runParkedOf, JOURNAL_INCOMPATIBLE_ERROR_CODE, WorkflowJournalIncompatibleError } from "@sema-agent/core";
3
+ import { subscribeWorkflow, deriveAgentDisplayStatus, callKeyOrdinal, runParkedOf, JOURNAL_INCOMPATIBLE_ERROR_CODE, WorkflowJournalIncompatibleError } from "@sema-agent/core";
4
4
  import { redactSteerIn, STEER_IN_MAX_CHARS, STEER_IN_MAX_REQUEST_CHARS } from "../../orchestration/workflow-agent-steer.js";
5
5
  import { journalEntryOfCell, journalEntryPayload, journalRowPayloadOf } from "../../plugins/workflow-journal-payload.js";
6
6
  import { redactSecrets } from "../../trace/redact.js";
@@ -10,30 +10,18 @@ import { projectByTable } from "../../trace/projection-table.js";
10
10
  const JOURNAL_PROJECTION_MEMO_CAP = 1024;
11
11
  const journalProjectionMemo = new Map();
12
12
  import { sendJson, sendError, sseHeaders } from "../send.js";
13
- import { gatedSubject, explicitOperatorOk, sendPrincipalRefusal } from "../principal-gate.js";
13
+ import { explicitOperatorOk } from "../principal-gate.js";
14
14
  import { partsOf } from "../../owner-brands.js";
15
- import { taskSpecIdentityOf } from "../../engine-identity.js";
16
15
  import { assertNever } from "../route-ctx.js";
17
- import { callerOf, sessionAsserted } from "../owner-access.js";
16
+ import { admitWorkflowRun, enter, judgeWorkflowRun, listVisibleWorkflows, refuse } from "../owner-access.js";
18
17
  import * as facts from "../../capability-facts.js";
19
18
  import { steerBodyKeyIssue } from "../../request-key-closure.js";
20
- function sendWorkflowAbsent(res) {
21
- sendError(res, 404, "not_found.workflow", "workflow not found");
22
- }
23
- const WORKFLOW_SESSION_ASSERTION = {
24
- "workflow-detail": { phase: "accept", label: "workflow.detail" },
25
- "workflow-journal": { phase: "accept", label: "workflow.journal" },
26
- "workflow-stream": { phase: "accept", label: "workflow.stream" },
27
- "workflow-agent-steer": { phase: "accept", label: "workflow.agent-steer" },
28
- };
29
19
  export async function handleWorkflows(req, res, match, ctx) {
30
20
  const { deps } = ctx;
31
21
  {
32
- const subject = gatedSubject(req, deps.config);
33
- if (deps.config.requirePrincipal && !subject) {
34
- sendPrincipalRefusal(res, req, deps.config);
22
+ const wfEntry = enter(req, res, deps, match.decl.id);
23
+ if (wfEntry === undefined)
35
24
  return;
36
- }
37
25
  let journalStore;
38
26
  if (match.decl.id === "workflow-journal") {
39
27
  const journalFace = facts.workflowsJournal(deps);
@@ -49,7 +37,6 @@ export async function handleWorkflows(req, res, match, ctx) {
49
37
  return;
50
38
  }
51
39
  const runStore = runs.store;
52
- const scope = taskSpecIdentityOf(subject === undefined ? undefined : partsOf(subject)).principal ?? "default";
53
40
  const wfId = match.params.runId;
54
41
  const isStream = match.decl.id === "workflow-stream";
55
42
  if (match.decl.id === "workflows-list") {
@@ -57,7 +44,7 @@ export async function handleWorkflows(req, res, match, ctx) {
57
44
  const statusFilter = q.get("status");
58
45
  const limit = Math.min(100, Math.max(1, Number(q.get("limit") ?? 50) || 50));
59
46
  const sessionFilter = q.get("session");
60
- const sessionRuns = await runStore.listByScope(scope, {
47
+ const sessionRuns = await listVisibleWorkflows(wfEntry, runStore, {
61
48
  ...(statusFilter ? { status: statusFilter } : {}),
62
49
  limit,
63
50
  ...(sessionFilter !== null ? { session: sessionFilter } : {}),
@@ -71,15 +58,11 @@ export async function handleWorkflows(req, res, match, ctx) {
71
58
  sendJson(res, 200, { workflows: redacted });
72
59
  return;
73
60
  }
74
- const run = await getWorkflowRun(runStore, wfId, scope);
75
- if (!run || run.scope !== scope) {
76
- sendWorkflowAbsent(res);
77
- return;
78
- }
79
- if (!sessionAsserted(WORKFLOW_SESSION_ASSERTION[match.decl.id], req, run.originatingSessionId, callerOf(req, deps).operator)) {
80
- sendWorkflowAbsent(res);
61
+ const wfAdmitted = await admitWorkflowRun(wfEntry, res, runStore, wfId);
62
+ if (wfAdmitted === undefined)
81
63
  return;
82
- }
64
+ const run = wfAdmitted.row;
65
+ const scope = run.scope;
83
66
  if (match.decl.id === "workflow-journal") {
84
67
  if (journalStore === undefined)
85
68
  throw new Error("workflow-journal reached without the workflowsJournal journal witness");
@@ -182,12 +165,11 @@ export async function handleWorkflowAgentSteer(req, res, match, ctx) {
182
165
  sendWorkflowsUnavailable(res, runs.why);
183
166
  return;
184
167
  }
185
- const subject = gatedSubject(req, deps.config);
186
- const principal = subject === undefined ? undefined : partsOf(subject).person;
187
- if (deps.config.requirePrincipal && principal === undefined) {
188
- sendPrincipalRefusal(res, req, deps.config);
168
+ const steerEntry = enter(req, res, deps, match.decl.id);
169
+ if (steerEntry === undefined)
189
170
  return;
190
- }
171
+ const subject = steerEntry.caller.subject;
172
+ const principal = subject === undefined ? undefined : partsOf(subject).person;
191
173
  const wfRunId = safeDecode(match.params.runId);
192
174
  const label = safeDecode(match.params.label);
193
175
  if (wfRunId === null || label === null) {
@@ -211,14 +193,14 @@ export async function handleWorkflowAgentSteer(req, res, match, ctx) {
211
193
  return;
212
194
  }
213
195
  const trusted = explicitOperatorOk(principal, deps.config);
214
- const ownerScope = taskSpecIdentityOf(subject === undefined ? undefined : partsOf(subject)).principal ?? "default";
215
- const wfRun = await getWorkflowRun(runs.store, wfRunId, ownerScope);
216
- if (!trusted && !wfRun) {
217
- sendWorkflowAbsent(res);
196
+ const wfVerdict = await judgeWorkflowRun(steerEntry, runs.store, wfRunId);
197
+ if (wfVerdict === "session_mismatch") {
198
+ refuse(steerEntry, res, "session_mismatch");
218
199
  return;
219
200
  }
220
- if (wfRun && !sessionAsserted(WORKFLOW_SESSION_ASSERTION["workflow-agent-steer"], req, wfRun.originatingSessionId, callerOf(req, deps).operator)) {
221
- sendWorkflowAbsent(res);
201
+ const wfRun = typeof wfVerdict === "object" ? wfVerdict.row : undefined;
202
+ if (!trusted && wfRun === undefined) {
203
+ refuse(steerEntry, res, wfVerdict === "missing" ? "missing" : "not_visible");
222
204
  return;
223
205
  }
224
206
  const sendNotRunningWf = (error) => sendError(res, 409, "steering.not_running", error);