@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
@@ -72,7 +72,8 @@ export declare function sendReadyz(res: ServerResponse, v: ReadinessVerdict): vo
72
72
  export declare const BILLABLE_KINDS: readonly ["submit", "hitl-answer", "resume"];
73
73
  export type BillableKind = (typeof BILLABLE_KINDS)[number];
74
74
  /**
75
- * 计费面的拒因(**数组序 = 优先序**):就绪原因({@link READINESS_REASONS})∪ `lease_expired`(服务租约过期且中心不可达满 `T_max`)。
75
+ * 计费面的拒因(**数组序 = 优先序**):就绪原因({@link READINESS_REASONS})∪ `lease_expired`(服务租约过期且中心不可达满 `T_max` —— 含从起步起一直没听到
76
+ * 中心的成员:推定在围栏内,钟从本进程起点)。
76
77
  * `lease_expired` 刻意不是就绪原因:它不翻 `/readyz`(中心不可达不是本实例的病,摘它出路由只会把取消 / HITL / 读面一起摘掉)。
77
78
  */
78
79
  export declare const ADMISSION_REFUSALS: readonly ["draining", "model_roster_pending", "lease_expired"];
@@ -80,7 +81,8 @@ export type AdmissionRefusal = (typeof ADMISSION_REFUSALS)[number];
80
81
  /**
81
82
  * 计费面请求的**唯一**准入判(dispatch 的计费门、a2a `message/send`、PARKED 赎回席同调):按 {@link ADMISSION_REFUSALS} 序找第一条
82
83
  * 成立且按 {@link ADMISSION_TABLE} 拒这一种的拒因;没有 ⇒ `undefined`(放行)。入参是**判决**而不是 deps:就绪判由调用点经唯一谓词
83
- * {@link readinessOf} 现读(模块边界上那一只 —— 谓词单源钉注入它,任何读点自己读 `drainState` 都会当场红),租约读数取 `deps.servingLease`。
84
+ * {@link readinessOf} 现读(模块边界上那一只 —— 谓词单源钉注入它,任何读点自己读 `drainState` 都会当场红),租约读数经唯一读者
85
+ * `fleet/engine-signal.ts` 的 `memberLeaseOf`(只有 fleet 成员有租约;成员没有任何中心读数之前是推定的 `expired`,同一臂)。
84
86
  */
85
87
  export declare function admissionRefusalOf(verdict: ReadinessVerdict, lease: ServingLeaseView | undefined, kind: BillableKind): BillableRefusal | undefined;
86
88
  /** 计费提交门的拒绝(首条 reason 定码)。`retryAfterSec` 由发送形(`sendBillableRefusal`)镜像成头;交回
@@ -1,12 +1,49 @@
1
1
  import { openCheckpointCtx } from "./checkpoint-ctx.js";
2
2
  import { storeFaultClassOf } from "../plugins/store-fault.js";
3
3
  import { refusalBody } from "./refusal-body.js";
4
+ import { frozenProjectContextOf } from "../project-context.js";
5
+ import { frozenMemorySeedOf } from "../project-registry.js";
4
6
  export async function readResumeCtx(load, opening) {
5
7
  const read = await readStoredCtx(load);
6
8
  if (read.kind !== "ok")
7
9
  return read;
8
10
  const opened = openCheckpointCtx(read.ctx, opening.opener, opening.sessionId);
9
- return opened.kind === "ok" ? { kind: "ok", ctx: opened.ctx } : { kind: "unsealable", field: opened.field, reason: opened.reason };
11
+ if (opened.kind !== "ok")
12
+ return { kind: "unsealable", field: opened.field, reason: opened.reason };
13
+ const where = (key) => ({ kind: "corrupt", where: `checkpoint ctx for session ${JSON.stringify(opening.sessionId)}: ${key}` });
14
+ const { memorySeed: _storedSeed, projectContext: _storedContext, ...rest } = opened.ctx;
15
+ const seed = frozenMemorySeedOf(opened.ctx.memorySeed);
16
+ const frozen = frozenProjectContextOf(opened.ctx.projectContext);
17
+ let seedPart;
18
+ switch (seed.kind) {
19
+ case "absent":
20
+ seedPart = {};
21
+ break;
22
+ case "none":
23
+ seedPart = { memorySeed: null };
24
+ break;
25
+ case "malformed":
26
+ return where("memorySeed");
27
+ case "ok":
28
+ seedPart = { memorySeed: seed.seed };
29
+ break;
30
+ default: {
31
+ const unhandled = seed;
32
+ throw new Error(`resume-ctx-read: unplaced frozen memory seed reading ${JSON.stringify(unhandled)}`);
33
+ }
34
+ }
35
+ switch (frozen.kind) {
36
+ case "absent":
37
+ return { kind: "ok", ctx: { ...rest, ...seedPart } };
38
+ case "malformed":
39
+ return where("projectContext");
40
+ case "ok":
41
+ return { kind: "ok", ctx: { ...rest, ...seedPart, projectContext: frozen.context } };
42
+ default: {
43
+ const unhandled = frozen;
44
+ throw new Error(`resume-ctx-read: unplaced frozen project context reading ${JSON.stringify(unhandled)}`);
45
+ }
46
+ }
10
47
  }
11
48
  async function readStoredCtx(load) {
12
49
  let stored;
@@ -129,7 +129,7 @@ export declare function createResumeLegs(ctx: {
129
129
  }) => void) => Promise<ResumeLegOutcome>;
130
130
  decisionRowAdmits: (cs: CheckpointStoreFull, token: CheckpointToken, who: KeyCaller | undefined, bodyScope: string | undefined) => Promise<boolean>;
131
131
  resumePreempted: (sessionId: string, req: IncomingMessage | undefined, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
132
- startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
132
+ startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage | undefined, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
133
133
  resumeWake: (sessionId: string, message: PendingSteerInput | undefined, caller: Subject | undefined, req: IncomingMessage | undefined, acceptEarly?: boolean, workflowDecision?: WorkflowDecisionDelivery, ownerLeaseAdmittedFor?: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
134
134
  preparePlanReview: (sessionId: string, log?: {
135
135
  taskId?: string;
@@ -146,6 +146,7 @@ export declare function createResumeLegs(ctx: {
146
146
  }>;
147
147
  drivePlanReview: (prepared: PreparedPlanReview, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, acceptEarly?: boolean, permissionModeAfter?: PlanApprovePermissionModeAfter) => Promise<ResumeLegOutcome>;
148
148
  sessionNotifyDoor: import("../session-notify-door.js").SessionNotifyDoor;
149
+ handOverRunEndedDecisions: (runId: string) => Promise<void>;
149
150
  };
150
151
  export {};
151
152
  //# sourceMappingURL=resume-legs.d.ts.map
@@ -1,21 +1,23 @@
1
1
  import { redactErrorMessage, redactHead } from "../observability/run-terminal.js";
2
2
  import { createHash } from "node:crypto";
3
3
  import { uuidv7, resumeWithVerification, resumeCascade, CheckpointError, judgeCheckpointRow, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
4
- import { decideParkedAgent, deliverToHoldingRun, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
4
+ import { answerOfHolderFence, answerOfHolderRedeem, decideParkedAgent, deliverableEntryOf, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, holderFenceFaultAnswer, planWorkflowParkedDecide, redeemHere, runChannelEnded, workflowParkGuidance } from "../parked-decide.js";
5
5
  import { parkDecisionFingerprint } from "../orchestration/workflow-park-decision.js";
6
- import { headReadOf } from "../session-incarnation.js";
6
+ import { heldParksOf, readRunParks } from "../orchestration/workflow-agent-session-index.js";
7
+ import { isAdoptionQuiescing, trackMaintenanceLeg } from "../adoption/quiesce.js";
8
+ import { runFactsOf, sealRouteDeps, sessionFactsReadOf, sessionOccupantReadOf } from "./owner-access.js";
7
9
  import { createSessionWorkspaceRecorder, sessionWorkspaceStoreOf } from "../session-workspace.js";
8
10
  const DELIVERY_NOT_RECORDED = "workflow park decide: this delivery no longer holds the host session (its claim was released) — the decision was not recorded and this delivery was not started";
9
11
  import { HttpError, checkpointPartsOf, decodeCheckpointScope, scopeCellOf, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
10
12
  import { keyAdmits } from "../owner-faces.js";
11
13
  import { personOf } from "../owner-brands.js";
12
14
  import { recoveredSubject } from "../owner-faces.js";
13
- import { beatRunHeartbeat, graftParkToolCallId, heldParkOf, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort, voidHeldParkCard } from "../runs.js";
15
+ import { beatRunHeartbeat, createRunAnchorWriter, graftParkToolCallId, heldParkOf, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort, voidHeldParkCard } from "../runs.js";
14
16
  import { commitParkRow } from "../park-row-commit.js";
15
17
  import { atHostBoundary, failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane, outwardThrownMessage } from "../terminal.js";
16
18
  import { voidVerifierPauseCard } from "../verifier-pause-card.js";
17
19
  import { buildCancelledLedgerRow, CANCELLED_CODE, CARD_SETTLED_BY_CANCEL_MESSAGE, createRunAbort, mintCancelledResult, withCardSettledByCancelMessage } from "../run-cancel-context.js";
18
- import { isTerminalRunStatus, runProvenElsewhere } from "../plugins/store-contracts.js";
20
+ import { createLegCtxClaim, isTerminalRunStatus } from "../plugins/store-contracts.js";
19
21
  import { readTurnActivityMs, recordTurnActivity } from "../turn-activity.js";
20
22
  import { recordResumeResourceWindow } from "../resource-window.js";
21
23
  import { emitPendingWorkflowCompletions, taskNotificationInboxEntry, taskNotificationStreamKeyOf, NotifiedKeys } from "../orchestration/workflow-completion-inbox.js";
@@ -60,21 +62,28 @@ import { buildActiveRunConflict, resumeEntryForGate } from "./active-run-conflic
60
62
  import { refusalAfterLostClaim } from "./claim-heartbeat.js";
61
63
  import { CONTINUATION_CLAIM_FACE, ClaimFaultAnswer, commitExecutionContext, faultedAnswerOf, isRootSessionGoneError, resolveBeforeClaim, rootSessionAbsentAnswer, stampSpecRoot, withdrawClaim } from "./execution-context.js";
62
64
  import { timeClaim } from "./claim-latency.js";
63
- import { commitSessionInheritEnv } from "./session-inherit-env.js";
65
+ import { commitLegBindings } from "../session-bindings.js";
64
66
  import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
65
67
  import { deploymentListAsks } from "../approval.js";
66
68
  import { isParkLedgerEventType } from "../trace/ledger-events.js";
67
69
  import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnreadableAnswer, resumeCtxUnsealableAnswer, resumeStoreFailureOf } from "./resume-ctx-read.js";
68
70
  import { objectiveWithheldIn } from "./submit-ctx.js";
69
- import { buildCheckpointVersionKeys, resumeAssemblyRefusalAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
71
+ import { buildCheckpointVersionKeys, resumeAssemblyRefusalAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields } from "./checkpoint-ctx.js";
70
72
  import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
71
73
  import { storedBodyReplayRefusal } from "./stored-body-replay.js";
72
74
  import { restateResumeCtx } from "./resume-restatement.js";
75
+ import { stampReplayEntryMode } from "../permission-mode-admission.js";
73
76
  import { httpErrorRefusal } from "./send.js";
74
77
  import { createRunAcceptance } from "../run-acceptance.js";
75
78
  import { createSubmissionSeat } from "../submission-exit.js";
76
79
  import { fieldConflictFacts } from "../field-conflict.js";
77
80
  import { createSessionNotifyDoor } from "../session-notify-door.js";
81
+ const HANDOFF_RETRY_CODES = new Set(["conflict.session_active_run", "not_found.parked_checkpoint", "conflict.claim_lost"]);
82
+ function handoffResultOf(refusal, refusedWhy) {
83
+ const errorCode = "errorCode" in refusal.body ? refusal.body.errorCode : undefined;
84
+ const code = typeof errorCode === "string" ? errorCode : `status_${refusal.status}`;
85
+ return refusal.status >= 500 || HANDOFF_RETRY_CODES.has(code) ? { kind: "retry", why: code } : { kind: "refused", why: refusedWhy ?? code };
86
+ }
78
87
  function compositionUnlinkedAnswer() {
79
88
  return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context does not match this card — the run is a cascade but the card records no ladder rung, so the ladder cannot be continued" }) };
80
89
  }
@@ -302,6 +311,13 @@ export function decidedActionOf(binding) {
302
311
  export function createResumeLegs(ctx) {
303
312
  const { deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode, prepareSpec, finalizeTaskResult, ownerCostQuotaDenied, ownerFleetLeaseDenied, usageWindowDenialFor } = ctx;
304
313
  const ctxOpening = (sessionId) => ({ sessionId, opener: deps.checkpointCtxSealing });
314
+ const replayCtxOf = (stored, restatement) => {
315
+ const restated = restateResumeCtx(stored, restatement);
316
+ if (restated.unattendedLeg === true)
317
+ return restated;
318
+ const body = stampReplayEntryMode(restated.body, deps.config);
319
+ return body === restated.body ? restated : { ...restated, body };
320
+ };
305
321
  const resumeFleetScope = (req, auth) => req ? (gatedSubject(req, deps.config) ?? "default") : (auth.subject ?? "default");
306
322
  function createRememberIntent(sessionId, remember) {
307
323
  let pending;
@@ -569,73 +585,56 @@ export function createResumeLegs(ctx) {
569
585
  if (!plan.ok)
570
586
  return plan.deny;
571
587
  const fingerprint = parkDecisionFingerprint(plan.outcome, restatement);
572
- const live = await deliverToHoldingRun(origin, { token, outcome: plan.outcome, decision: parkedReq.decision, fingerprint, restated: restatement !== undefined });
573
- if (live.kind === "answered")
574
- return live.answer;
575
588
  const decisions = deps.workflowParkDecisions;
576
- const runStore = deps.runStore;
577
- if (decisions === undefined || runStore === undefined) {
589
+ if (decisions === undefined || deps.runStore === undefined) {
578
590
  return { status: 501, body: refusalBody({ errorCode: "capability.run_store_required", message: "delivering this decision requires a durable run store (DB_BACKEND=mysql|pg|local)" }) };
579
591
  }
580
- const liveReceiptOf = async (held) => {
581
- if (held === null || held.fingerprint !== fingerprint)
582
- return undefined;
583
- const run = await runStore.getRun(held.deliveredTaskId);
584
- return run != null && !isTerminalRunStatus(run.status) ? acceptedResumingReceipt(held.deliveredTaskId, held.hostSessionId, NO_SETTLEMENT_EVIDENCE) : undefined;
585
- };
586
- const replay = await liveReceiptOf(await decisions.get(token));
587
- if (replay !== undefined)
588
- return replay;
589
- let recordFailure;
590
- const answerOfRecordFailure = async (failed) => {
591
- if (failed.kind === "faulted")
592
- return faultedAnswerOf(failed.err, CONTINUATION_CLAIM_FACE.faulted);
592
+ if (origin.run.status === "running") {
593
+ let verdict;
593
594
  try {
594
- return await refusalAfterLostClaim(deps, runStore, plan.hostSessionId, failed.deliveredTaskId);
595
+ verdict = await decisions.recordForRunningHolder({ token, runId: plan.runId, hostSessionId: plan.hostSessionId, outcome: plan.outcome, fingerprint, deliveredTaskId: plan.runId, acceptedAtMs: Date.now() }, { restated: restatement !== undefined });
595
596
  }
596
- catch (e) {
597
- return faultedAnswerOf(e, CONTINUATION_CLAIM_FACE.faulted);
597
+ catch (err) {
598
+ return faultedAnswerOf(err, () => holderFenceFaultAnswer(plan.runId));
598
599
  }
599
- };
600
- const delivery = {
601
- carried: [{ runId: plan.runId, token, outcome: plan.outcome }],
602
- commitBeforeLaunch: async (deliveredTaskId) => {
603
- let recorded;
604
- try {
605
- recorded = await decisions.record({ token, runId: plan.runId, hostSessionId: plan.hostSessionId, outcome: plan.outcome, fingerprint, deliveredTaskId, acceptedAtMs: Date.now() });
606
- }
607
- catch (err) {
608
- recordFailure = { kind: "faulted", err };
609
- throw err;
610
- }
611
- if (!recorded) {
612
- recordFailure = { kind: "not_recorded", deliveredTaskId };
613
- throw new Error(DELIVERY_NOT_RECORDED);
600
+ switch (verdict) {
601
+ case "not_running":
602
+ break;
603
+ case "not_held":
604
+ case "restated":
605
+ case "other_decision":
606
+ return answerOfHolderFence(verdict, plan.runId);
607
+ case "stands":
608
+ return answerOfHolderRedeem(await redeemHere(plan.runId, origin.run.scope, { token, outcome: plan.outcome }), plan.runId, parkedReq.decision);
609
+ default: {
610
+ const unhandled = verdict;
611
+ throw new Error(`unhandled workflow holder fence verdict: ${String(unhandled)}`);
614
612
  }
615
- },
616
- };
617
- const hostToken = await cs
618
- .findPendingTokenBySession(plan.hostSessionId, undefined, { gateKinds: TERMINAL_PARK_GATE_KINDS, pick: "oldest" })
619
- .catch(() => undefined);
620
- const admittedPayer = decodeCheckpointScope(cp.scope);
621
- let out;
622
- try {
623
- out = hostToken
624
- ? await resumeWake(plan.hostSessionId, plan.message, decider?.subject, req, acceptEarly, delivery, admittedPayer, restatement)
625
- : await startFreshHostTurn(plan.hostSessionId, plan.message.text, admittedPayer, req, delivery, plan.runId, restatement);
613
+ }
626
614
  }
627
- catch (err) {
628
- const failed = recordFailure;
629
- if (failed === undefined)
630
- throw err;
631
- return await answerOfRecordFailure(failed);
615
+ const laned = await deliverViaResumeLane({
616
+ hostSessionId: plan.hostSessionId,
617
+ runId: plan.runId,
618
+ runScope: origin.run.scope,
619
+ token,
620
+ outcome: plan.outcome,
621
+ fingerprint,
622
+ message: plan.message,
623
+ ...(restatement !== undefined ? { restatement } : {}),
624
+ initiator: { kind: "decide", req, caller: decider?.subject, ...(acceptEarly === true ? { acceptEarly: true } : {}), admittedPayer: decodeCheckpointScope(cp.scope) },
625
+ });
626
+ switch (laned.kind) {
627
+ case "launched":
628
+ case "replayed":
629
+ case "refused":
630
+ return laned.out;
631
+ case "record_failed":
632
+ return await answerOfRecordFailure(laned.failure, plan.hostSessionId);
633
+ default: {
634
+ const unhandled = laned;
635
+ throw new Error(`unhandled resume lane delivery: ${JSON.stringify(unhandled)}`);
636
+ }
632
637
  }
633
- const failed = recordFailure;
634
- if (failed !== undefined)
635
- return await answerOfRecordFailure(failed);
636
- if (acceptedTaskIdOf(out) === undefined)
637
- return (await liveReceiptOf(await decisions.get(token))) ?? out;
638
- return out;
639
638
  }
640
639
  }
641
640
  const runCtx = await ctxPromise;
@@ -644,7 +643,7 @@ export function createResumeLegs(ctx) {
644
643
  if (runCtx === undefined || runCtx.ctx === null)
645
644
  return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
646
645
  const { runSessionId, ctx: storedCtx } = runCtx;
647
- const ctx = restateResumeCtx(storedCtx, restatement);
646
+ const ctx = replayCtxOf(storedCtx, restatement);
648
647
  const auth = { sessionId: runSessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
649
648
  const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
650
649
  if (!resolved.ok)
@@ -690,6 +689,8 @@ export function createResumeLegs(ctx) {
690
689
  leg: "resume",
691
690
  onNotice: (n) => engineNotices.push(n),
692
691
  ...(ctx.unattendedLeg === true ? { unattendedLeg: true } : {}),
692
+ ...(ctx.projectContext !== undefined ? { projectContext: ctx.projectContext } : {}),
693
+ ...(ctx.memorySeed !== undefined ? { memorySeed: ctx.memorySeed } : {}),
693
694
  lease,
694
695
  execution,
695
696
  });
@@ -762,10 +763,10 @@ export function createResumeLegs(ctx) {
762
763
  };
763
764
  const commitResumeCtx = () => Promise.resolve().then(async () => {
764
765
  const sealed = sealCheckpointCtx({ ...resumeCtx.ctx, writerVersion: serviceVersion() }, deps.checkpointCtxSealing, resumeCtx.sessionId);
765
- const claim = claimedRow && taskId !== undefined && deps.runStore !== undefined ? { fence: deps.runStore, taskId, legHolds: (run) => !runProvenElsewhere(run, deps.instanceId) } : undefined;
766
+ const claim = heldLeg !== undefined && taskId !== undefined && deps.runStore !== undefined ? createLegCtxClaim(deps.runStore, taskId, heldLeg) : undefined;
766
767
  const landed = await deps.checkpointStore.putCtx(resumeCtx.sessionId, sealed, claim);
767
768
  if (landed === "claim_released")
768
- resumeCtxNotPersisted("claim_released: this run no longer holds the session claim (settled or reaped before the write-back landed) — nothing written");
769
+ resumeCtxNotPersisted("claim_released: this leg no longer holds the run (settled, reaped, or claimed again by a later leg before the write-back landed) — nothing written");
769
770
  }).catch((e) => resumeCtxNotPersisted(errorText(e)));
770
771
  const legKey = createHash("sha256").update(String(token)).digest("hex");
771
772
  const streamApprovalOn = resolveStreamApprovalGate({
@@ -978,7 +979,7 @@ export function createResumeLegs(ctx) {
978
979
  ...heldDecisions,
979
980
  ...(workflowDecision !== undefined && taskId !== undefined ? { afterCheckpointResolve: () => workflowDecision.commitBeforeLaunch(taskId) } : {}),
980
981
  };
981
- commitSessionInheritEnv(deps, sessionId, resumeCtx.ctx.body);
982
+ commitLegBindings(deps, undefined, sessionId, args.legFacts?.sessionBindings);
982
983
  if (args.onResumeCommitted)
983
984
  await args.onResumeCommitted();
984
985
  let unregisterEngineNotice;
@@ -1035,7 +1036,7 @@ export function createResumeLegs(ctx) {
1035
1036
  const verifyTailContentMode = resumeTaskConfig.forwardSubagentEvents === true ? "on" : "progress_only";
1036
1037
  const verifyInternals = {
1037
1038
  ...launchInternals,
1038
- ...compositionLegRoot(args.legFacts?.registeredCwd),
1039
+ ...compositionLegRoot(args.legFacts?.sessionBindings.cwd),
1039
1040
  ...(taskId ? { onActivity: () => recordTurnActivity(taskId) } : {}),
1040
1041
  onForwardEvent: (e) => {
1041
1042
  fleetPub?.onForwardEvent(e);
@@ -1147,15 +1148,18 @@ export function createResumeLegs(ctx) {
1147
1148
  const append = (type, data) => (rs && taskId ? serialAppend(type, data) : Promise.resolve());
1148
1149
  cancelLedgerAppend = append;
1149
1150
  await openEngineNoticePort(append);
1150
- const anchorOwner = subject ?? null;
1151
- const headOf = headReadOf(deps.sessionStorage);
1152
- const captureTurnAnchor = deps.resumeAnchorStore && headOf
1153
- ? async (eventId) => { const leaf = (await headOf(sessionId))?.leafId; if (leaf)
1154
- await deps.resumeAnchorStore.put(sessionId, eventId, leaf, anchorOwner); }
1155
- : undefined;
1156
- const captureUserMessageAnchor = deps.resumeAnchorStore && taskId && freshRunClaimed
1157
- ? async (entryId) => { await deps.resumeAnchorStore.put(sessionId, taskId, entryId, anchorOwner); }
1158
- : undefined;
1151
+ const sessionFactsOf = sessionFactsReadOf(deps.sessionStorage);
1152
+ const anchors = createRunAnchorWriter({
1153
+ seat: deps.backend?.landedAttendants(),
1154
+ sessionId,
1155
+ owner: subject ?? null,
1156
+ promptKey: taskId && freshRunClaimed ? taskId : undefined,
1157
+ witness: args.legFacts?.sessionWitness,
1158
+ occupantOf: sessionOccupantReadOf(deps.sessionStorage),
1159
+ leafOf: sessionFactsOf === undefined ? undefined : async (id) => (await sessionFactsOf(id))?.leafId,
1160
+ });
1161
+ const captureTurnAnchor = anchors.turn;
1162
+ const captureUserMessageAnchor = anchors.prompt;
1159
1163
  const anchor = new TurnAnchorCapture(captureTurnAnchor, "resume", captureUserMessageAnchor);
1160
1164
  const flush = async () => {
1161
1165
  if (reasoning) {
@@ -1416,9 +1420,12 @@ export function createResumeLegs(ctx) {
1416
1420
  const withElicitation = () => deps.elicitation && taskId
1417
1421
  ? deps.elicitation.runWithContext({ taskId, owner: subject ?? null, transport: hitlTransport, abortSignal: cancelCtrl.signal }, withApproval)
1418
1422
  : withApproval();
1423
+ const withQuestion = () => deps.question && taskId
1424
+ ? deps.question.runWithContext({ taskId, owner: subject ?? null, transport: hitlTransport, abortSignal: cancelCtrl.signal }, withElicitation)
1425
+ : withElicitation();
1419
1426
  return await (deps.sendUserFile && taskId
1420
- ? deps.sendUserFile.runWithContext({ taskId, emit: async (frame) => { const { type, ...rest } = frame; await append(type, rest); } }, withElicitation)
1421
- : withElicitation());
1427
+ ? deps.sendUserFile.runWithContext({ taskId, emit: async (frame) => { const { type, ...rest } = frame; await append(type, rest); } }, withQuestion)
1428
+ : withQuestion());
1422
1429
  })));
1423
1430
  }
1424
1431
  catch (e) {
@@ -1619,7 +1626,7 @@ export function createResumeLegs(ctx) {
1619
1626
  return resumeCtxUnreadableAnswer();
1620
1627
  if (ctxRead.kind === "absent")
1621
1628
  return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
1622
- const ctx = restateResumeCtx(ctxRead.ctx, restatement);
1629
+ const ctx = replayCtxOf(ctxRead.ctx, restatement);
1623
1630
  const auth = { sessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
1624
1631
  const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
1625
1632
  if (!resolved.ok)
@@ -1664,7 +1671,7 @@ export function createResumeLegs(ctx) {
1664
1671
  }),
1665
1672
  };
1666
1673
  }
1667
- const ctx = restateResumeCtx(storedCtx, restatement);
1674
+ const ctx = replayCtxOf(storedCtx, restatement);
1668
1675
  const windowDenial = await usageWindowDenialFor(subject === undefined ? undefined : personOf(recoveredSubject(subject)));
1669
1676
  if (windowDenial)
1670
1677
  return { status: windowDenial.status, body: windowDenial.body };
@@ -1753,7 +1760,7 @@ export function createResumeLegs(ctx) {
1753
1760
  return resumeCtxUnreadableAnswer();
1754
1761
  if (ctxRead.kind === "absent")
1755
1762
  return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
1756
- const ctx = restateResumeCtx(ctxRead.ctx, restatement);
1763
+ const ctx = replayCtxOf(ctxRead.ctx, restatement);
1757
1764
  const auth = { sessionId: cp.sessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
1758
1765
  const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
1759
1766
  if (!resolved.ok)
@@ -1780,7 +1787,7 @@ export function createResumeLegs(ctx) {
1780
1787
  ...(workflowDecision !== undefined ? { workflowDecision } : {}),
1781
1788
  ...(engineNotices.length > 0 ? { engineNotices } : {}),
1782
1789
  ...(acceptEarly === true ? { acceptEarly: true } : {}),
1783
- ...(req !== undefined ? { callerInitiated: true } : {}),
1790
+ ...(req !== undefined || workflowDecision !== undefined ? { callerInitiated: true } : {}),
1784
1791
  ...(ownerLeaseAdmittedFor !== undefined && auth.subject === ownerLeaseAdmittedFor ? { ownerLeaseAdmitted: true } : {}),
1785
1792
  });
1786
1793
  }
@@ -1788,6 +1795,183 @@ export function createResumeLegs(ctx) {
1788
1795
  resolved.peerLease.release();
1789
1796
  }
1790
1797
  }
1798
+ async function answerOfRecordFailure(failed, hostSessionId) {
1799
+ if (failed.kind === "faulted")
1800
+ return faultedAnswerOf(failed.err, CONTINUATION_CLAIM_FACE.faulted);
1801
+ const runStore = deps.runStore;
1802
+ if (runStore === undefined)
1803
+ throw new Error("workflow park decide: a decision row failed to land without a run store — the claim fence it was written under is the run store");
1804
+ try {
1805
+ return await refusalAfterLostClaim(deps, runStore, hostSessionId, failed.deliveredTaskId);
1806
+ }
1807
+ catch (e) {
1808
+ return faultedAnswerOf(e, CONTINUATION_CLAIM_FACE.faulted);
1809
+ }
1810
+ }
1811
+ async function deliverViaResumeLane(d) {
1812
+ const decisions = deps.workflowParkDecisions;
1813
+ const runStore = deps.runStore;
1814
+ const cs = deps.checkpointStore;
1815
+ if (decisions === undefined || runStore === undefined || cs === undefined) {
1816
+ return { kind: "refused", out: { status: 501, body: refusalBody({ errorCode: "capability.run_store_required", message: "delivering this decision requires a durable run store (DB_BACKEND=mysql|pg|local)" }) } };
1817
+ }
1818
+ const liveReceiptOf = async (held) => {
1819
+ if (held === null || held.fingerprint !== d.fingerprint)
1820
+ return undefined;
1821
+ const run = await runFactsOf(runStore, held.deliveredTaskId);
1822
+ return run != null && !isTerminalRunStatus(run.status) ? acceptedResumingReceipt(held.deliveredTaskId, held.hostSessionId, NO_SETTLEMENT_EVIDENCE) : undefined;
1823
+ };
1824
+ const replay = await liveReceiptOf(await decisions.get(d.token));
1825
+ if (replay !== undefined)
1826
+ return { kind: "replayed", out: replay };
1827
+ await runChannelEnded(d.runId, d.runScope);
1828
+ const condition = d.initiator.kind === "run_ended" ? { expect: d.fingerprint } : undefined;
1829
+ let recordFailure;
1830
+ const delivery = {
1831
+ carried: [{ runId: d.runId, token: d.token, outcome: d.outcome }],
1832
+ commitBeforeLaunch: async (deliveredTaskId) => {
1833
+ let recorded;
1834
+ try {
1835
+ recorded = await decisions.record({ token: d.token, runId: d.runId, hostSessionId: d.hostSessionId, outcome: d.outcome, fingerprint: d.fingerprint, deliveredTaskId, acceptedAtMs: Date.now() }, condition);
1836
+ }
1837
+ catch (err) {
1838
+ recordFailure = { kind: "faulted", err };
1839
+ throw err;
1840
+ }
1841
+ if (!recorded) {
1842
+ recordFailure = { kind: "not_recorded", deliveredTaskId };
1843
+ throw new Error(DELIVERY_NOT_RECORDED);
1844
+ }
1845
+ },
1846
+ };
1847
+ const hostToken = await cs.findPendingTokenBySession(d.hostSessionId, undefined, { gateKinds: TERMINAL_PARK_GATE_KINDS, pick: "oldest" }).catch(() => undefined);
1848
+ const req = d.initiator.kind === "decide" ? d.initiator.req : undefined;
1849
+ const acceptEarly = d.initiator.kind === "decide" ? d.initiator.acceptEarly : undefined;
1850
+ let out;
1851
+ try {
1852
+ out = hostToken
1853
+ ? await resumeWake(d.hostSessionId, d.message, d.initiator.caller, req, acceptEarly, delivery, d.initiator.admittedPayer, d.restatement)
1854
+ : await startFreshHostTurn(d.hostSessionId, d.message.text, d.initiator.admittedPayer, req, delivery, d.runId, d.restatement);
1855
+ }
1856
+ catch (err) {
1857
+ const failed = recordFailure;
1858
+ if (failed === undefined)
1859
+ throw err;
1860
+ return { kind: "record_failed", failure: failed };
1861
+ }
1862
+ const failed = recordFailure;
1863
+ if (failed !== undefined)
1864
+ return { kind: "record_failed", failure: failed };
1865
+ if (acceptedTaskIdOf(out) === undefined) {
1866
+ const raced = await liveReceiptOf(await decisions.get(d.token));
1867
+ return raced !== undefined ? { kind: "replayed", out: raced } : { kind: "refused", out };
1868
+ }
1869
+ return { kind: "launched", out };
1870
+ }
1871
+ async function handOverRunEndedDecisions(runId) {
1872
+ if (isAdoptionQuiescing())
1873
+ throw new Error(`workflow run ${runId}: an adoption arc is running in this process — the decision handoff yields and is retried on the next recovery sweep`);
1874
+ const handing = handOverHeldRows(runId);
1875
+ trackMaintenanceLeg(handing);
1876
+ await handing;
1877
+ }
1878
+ async function handOverHeldRows(runId) {
1879
+ const decisions = deps.workflowParkDecisions;
1880
+ const records = deps.workflowRunStore;
1881
+ const cs = deps.checkpointStore;
1882
+ const index = deps.workflowAgentSessionIndex;
1883
+ if (decisions === undefined || records === undefined || cs === undefined || index === undefined)
1884
+ return;
1885
+ const run = await records.get(runId);
1886
+ if (run === null)
1887
+ return;
1888
+ const parks = readRunParks(run);
1889
+ if (parks === undefined) {
1890
+ deps.logger?.warn?.("workflow_park_handoff_refused", { runId, why: "parks_unreadable" });
1891
+ return;
1892
+ }
1893
+ const held = heldParksOf(runId, parks);
1894
+ if (run.status === "running") {
1895
+ for (const park of held) {
1896
+ if ((await decisions.get(park.token)) !== null) {
1897
+ throw new Error(`workflow run ${runId}: its completion arrived while its record still reads running (the terminal record write did not land) and it holds an accepted decision — leaving the completion pending until recovery ends the record`);
1898
+ }
1899
+ }
1900
+ return;
1901
+ }
1902
+ for (const park of held) {
1903
+ const row = await decisions.get(park.token);
1904
+ if (row === null)
1905
+ continue;
1906
+ const deliverable = await deliverableEntryOf({ checkpointStore: cs, workflowAgentSessionIndex: index, workflowRunStore: records }, row);
1907
+ if (deliverable.kind === "unreadable")
1908
+ throw new Error(`workflow run ${runId}: the card or the holder of a recorded decision could not be read — leaving the completion pending for the next recovery sweep`);
1909
+ if (deliverable.kind === "not_deliverable" || deliverable.entry.runId !== runId)
1910
+ continue;
1911
+ const result = await handOverOne(runId, run.scope, deliverable, row);
1912
+ deps.metrics?.inc("workflow_park_handoff_total", { result: result.kind });
1913
+ switch (result.kind) {
1914
+ case "delivered":
1915
+ continue;
1916
+ case "retry":
1917
+ throw new Error(`workflow run ${runId}: the decision handoff must be retried (${result.why}) — leaving the completion pending for the next recovery sweep`);
1918
+ case "refused":
1919
+ deps.logger?.warn?.("workflow_park_handoff_refused", { runId, why: result.why });
1920
+ continue;
1921
+ default: {
1922
+ const unhandled = result;
1923
+ throw new Error(`unhandled workflow park handoff result: ${JSON.stringify(unhandled)}`);
1924
+ }
1925
+ }
1926
+ }
1927
+ }
1928
+ async function handOverOne(runId, runScope, parkEntry, row) {
1929
+ const cs = deps.checkpointStore;
1930
+ const hostSessionId = parkEntry.origin.run.originatingSessionId;
1931
+ if (hostSessionId === undefined || hostSessionId === "")
1932
+ return { kind: "refused", why: "host_unknown" };
1933
+ const ownerScope = parkEntry.card.scope;
1934
+ const hostToken = await cs.findPendingTokenBySession(hostSessionId, undefined, { gateKinds: TERMINAL_PARK_GATE_KINDS, pick: "oldest" });
1935
+ if (hostToken) {
1936
+ const hostCard = await cs.get(hostToken);
1937
+ if (hostCard !== null && hostCard.scope !== ownerScope)
1938
+ return { kind: "refused", why: "owner_mismatch" };
1939
+ }
1940
+ const parts = checkpointPartsOf(ownerScope);
1941
+ const quota = ownerCostQuotaDenied(parts?.person);
1942
+ if (quota !== undefined)
1943
+ return handoffResultOf(quota, "payer_cost_quota");
1944
+ const lease = await ownerFleetLeaseDenied(parts?.person);
1945
+ if (lease !== undefined)
1946
+ return handoffResultOf(lease, "payer_fleet_lease");
1947
+ const laned = await deliverViaResumeLane({
1948
+ hostSessionId,
1949
+ runId,
1950
+ runScope,
1951
+ token: row.token,
1952
+ outcome: row.outcome,
1953
+ fingerprint: row.fingerprint,
1954
+ message: workflowParkGuidance(runId, parkEntry.origin.park.callKey, row.outcome.decision === "allow" ? "approve" : "deny"),
1955
+ initiator: { kind: "run_ended", caller: parts?.subject, admittedPayer: decodeCheckpointScope(ownerScope) },
1956
+ });
1957
+ switch (laned.kind) {
1958
+ case "launched":
1959
+ case "replayed":
1960
+ return { kind: "delivered" };
1961
+ case "refused":
1962
+ return handoffResultOf(laned.out);
1963
+ case "record_failed": {
1964
+ if (laned.failure.kind === "faulted")
1965
+ return { kind: "retry", why: "store_fault" };
1966
+ const now = await deps.workflowParkDecisions.get(row.token);
1967
+ return now?.fingerprint === row.fingerprint ? { kind: "retry", why: "claim_lost" } : { kind: "refused", why: "superseded" };
1968
+ }
1969
+ default: {
1970
+ const unhandled = laned;
1971
+ throw new Error(`unhandled resume lane delivery: ${JSON.stringify(unhandled)}`);
1972
+ }
1973
+ }
1974
+ }
1791
1975
  async function preparePlanReview(sessionId, log, decider, sighting, restatement) {
1792
1976
  const cs = deps.checkpointStore;
1793
1977
  const refuse = (answer) => ({ ok: false, answer });
@@ -1861,7 +2045,7 @@ export function createResumeLegs(ctx) {
1861
2045
  return refuse(resumeCtxUnreadableAnswer());
1862
2046
  if (ctxRead.kind === "absent")
1863
2047
  return refuse({ status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) });
1864
- const ctx = restateResumeCtx(ctxRead.ctx, restatement);
2048
+ const ctx = replayCtxOf(ctxRead.ctx, restatement);
1865
2049
  const replay = storedBodyReplayRefusal(ctx, deps.config);
1866
2050
  if (replay !== undefined)
1867
2051
  return refuse(refuseStoredBodyReplay(sessionId, replay));
@@ -1877,7 +2061,7 @@ export function createResumeLegs(ctx) {
1877
2061
  throw new Error("drivePlanReview: permissionModeAfter was passed for a task whose stored permission mode is not \"plan\" — the caller must refuse this before any state changes (see the plan_review route's pre-nonce gate)");
1878
2062
  }
1879
2063
  const approvedMode = planReviewDecisionExitsPlan(decision) && effMode === "plan" ? (permissionModeAfter ?? "default") : undefined;
1880
- const rebuildCtx = approvedMode === undefined ? ctx : withPermissionModeRewritten(ctx, { ...ctx.body, permissionMode: approvedMode });
2064
+ const rebuildCtx = approvedMode === undefined ? ctx : { ...ctx, body: { ...ctx.body, permissionMode: approvedMode } };
1881
2065
  const resolved = await resolveResumeSpecOrBlocked(rebuildCtx, req, auth);
1882
2066
  if (!resolved.ok)
1883
2067
  return resolved.answer;
@@ -1907,15 +2091,15 @@ export function createResumeLegs(ctx) {
1907
2091
  activeTaskIdOf: async (sessionId) => deps.runStore?.getActiveTaskId?.(sessionId),
1908
2092
  liveRuns: steerableRuns,
1909
2093
  inbox: deps.workflowCompletionInbox,
1910
- headOf: headReadOf(deps.sessionStorage),
2094
+ sessionStorage: deps.sessionStorage,
1911
2095
  });
1912
2096
  const routeCtxBase = {
1913
- deps,
2097
+ deps: sealRouteDeps(deps),
1914
2098
  registry: { idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters },
1915
2099
  helpers: { readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode },
1916
2100
  local: { images: createImagesLocal(deps), sessions: createSessionsLocal(), sessionSync: createSessionSyncLocal(), capabilities: createCapabilitiesLocal() },
1917
2101
  legs: { prepareSpec, finalizeTaskResult, resumeCheckpoint, driveResumeIntoRunLog, resumePreempted, resumeWake, preparePlanReview, drivePlanReview, sessionNotify: sessionNotifyDoor },
1918
2102
  };
1919
- return { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg, decisionRowAdmits, resumePreempted, startFreshHostTurn, resumeWake, preparePlanReview, drivePlanReview, sessionNotifyDoor };
2103
+ return { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg, decisionRowAdmits, resumePreempted, startFreshHostTurn, resumeWake, preparePlanReview, drivePlanReview, sessionNotifyDoor, handOverRunEndedDecisions };
1920
2104
  }
1921
2105
  //# sourceMappingURL=resume-legs.js.map