@sema-agent/server 7.150.0 → 7.152.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (514) hide show
  1. package/MIGRATION.md +451 -0
  2. package/README.md +15 -3
  3. package/README.zh-CN.md +10 -2
  4. package/USAGE.md +144 -87
  5. package/deploy/sema-up/README.md +11 -4
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  9. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  10. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  11. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  12. package/deploy/sema-up/chart/values.yaml +8 -1
  13. package/deploy/sema-up/cluster-up.sh +7 -6
  14. package/deploy/sema-up/kube-up.sh +6 -6
  15. package/deploy/sema-up/lib/flagshape.sh +36 -8
  16. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  17. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  18. package/deploy/sema-up/machines.example.yaml +3 -1
  19. package/deploy/sema-up/sema-up.sh +22 -16
  20. package/dist/adoption/import.js +3 -3
  21. package/dist/approval-ask-audit-store.d.ts +1 -1
  22. package/dist/approval-ask-machine.d.ts +4 -10
  23. package/dist/approval-ask-retention.d.ts +1 -1
  24. package/dist/approval-card.d.ts +12 -14
  25. package/dist/approval-gate-currency.d.ts +9 -9
  26. package/dist/approval-gate-currency.js +3 -4
  27. package/dist/approval-hmac.d.ts +17 -1
  28. package/dist/approval-hmac.js +7 -1
  29. package/dist/approval-queue-kind.d.ts +1 -1
  30. package/dist/approval.d.ts +2 -2
  31. package/dist/approval.js +2 -2
  32. package/dist/auth-bridge.d.ts +20 -0
  33. package/dist/auth-bridge.js +9 -0
  34. package/dist/background-session-reap.d.ts +1 -1
  35. package/dist/bake-runner/main.d.ts +4 -2
  36. package/dist/bind-host.d.ts +3 -6
  37. package/dist/bind-host.js +4 -7
  38. package/dist/boot/budget-tracing.js +1 -1
  39. package/dist/boot/coordinators.d.ts +1 -1
  40. package/dist/boot/coordinators.js +9 -10
  41. package/dist/boot/device-lane.js +2 -0
  42. package/dist/boot/engine-lease.d.ts +5 -0
  43. package/dist/boot/engine-lease.js +1 -0
  44. package/dist/boot/execution-env.d.ts +9 -14
  45. package/dist/boot/execution-env.js +85 -22
  46. package/dist/boot/execution-lane.js +32 -5
  47. package/dist/boot/late-binds.d.ts +8 -4
  48. package/dist/boot/late-binds.js +7 -1
  49. package/dist/boot/leader.d.ts +31 -30
  50. package/dist/boot/leader.js +38 -28
  51. package/dist/boot/leg-path-adjudication.d.ts +40 -0
  52. package/dist/boot/leg-path-adjudication.js +18 -0
  53. package/dist/boot/memory-consolidation.d.ts +3 -2
  54. package/dist/boot/memory-consolidation.js +6 -6
  55. package/dist/boot/parked-revive-gate.js +3 -15
  56. package/dist/boot/reapers.d.ts +6 -1
  57. package/dist/boot/reapers.js +13 -2
  58. package/dist/boot/resolve-spec.d.ts +3 -3
  59. package/dist/boot/resolve-spec.js +43 -48
  60. package/dist/boot/runner-deps.d.ts +46 -35
  61. package/dist/boot/runner-deps.js +94 -91
  62. package/dist/boot/session-age-out.d.ts +36 -0
  63. package/dist/boot/session-age-out.js +101 -0
  64. package/dist/boot/session-faces.d.ts +5 -14
  65. package/dist/boot/session-faces.js +9 -5
  66. package/dist/boot/shutdown.d.ts +6 -0
  67. package/dist/boot/shutdown.js +10 -4
  68. package/dist/boot/stage-01-config.js +2 -0
  69. package/dist/boot/stage-02-web-admin-pull.js +4 -5
  70. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  71. package/dist/boot/stage-05-execution-env.js +3 -2
  72. package/dist/boot/stage-06-runners.d.ts +9 -4
  73. package/dist/boot/stage-06-runners.js +24 -9
  74. package/dist/boot/stage-07-capability-layer.d.ts +8 -4
  75. package/dist/boot/stage-07-capability-layer.js +3 -2
  76. package/dist/boot/stage-08-reapers.d.ts +8 -4
  77. package/dist/boot/stage-08-reapers.js +4 -2
  78. package/dist/boot/stage-09-leader.d.ts +12 -5
  79. package/dist/boot/stage-09-leader.js +14 -5
  80. package/dist/boot/stage-10-http-server.d.ts +19 -5
  81. package/dist/boot/stage-10-http-server.js +14 -21
  82. package/dist/boot/stores.js +7 -4
  83. package/dist/boot/web-admin.js +5 -8
  84. package/dist/boot/workflow-orchestration.d.ts +7 -2
  85. package/dist/boot/workflow-orchestration.js +24 -7
  86. package/dist/bounded-rotation.d.ts +29 -0
  87. package/dist/bounded-rotation.js +24 -0
  88. package/dist/capabilities/approvals-push.d.ts +3 -3
  89. package/dist/capabilities/scenarios.d.ts +28 -13
  90. package/dist/capabilities/scenarios.js +2 -2
  91. package/dist/capability-facts.d.ts +43 -32
  92. package/dist/capability-facts.js +45 -51
  93. package/dist/card-rule-offers.d.ts +32 -0
  94. package/dist/card-rule-offers.js +130 -0
  95. package/dist/center-credential.d.ts +25 -6
  96. package/dist/center-credential.js +25 -5
  97. package/dist/config-catalog.d.ts +26 -7
  98. package/dist/config-catalog.js +26 -22
  99. package/dist/config-dir-trust.js +4 -2
  100. package/dist/config-invariants.d.ts +20 -8
  101. package/dist/config-invariants.js +55 -12
  102. package/dist/config-lkg.d.ts +5 -19
  103. package/dist/config-lkg.js +8 -62
  104. package/dist/config-provider.d.ts +1 -1
  105. package/dist/config-root-migration.d.ts +2 -2
  106. package/dist/config-types.d.ts +38 -42
  107. package/dist/config.d.ts +58 -7
  108. package/dist/config.js +90 -40
  109. package/dist/control-socket.d.ts +51 -0
  110. package/dist/control-socket.js +115 -0
  111. package/dist/deployment-governance.d.ts +2 -1
  112. package/dist/deployment-shape.d.ts +9 -1
  113. package/dist/deployment-shape.js +2 -1
  114. package/dist/device-protocol.d.ts +5 -4
  115. package/dist/device-protocol.js +1 -1
  116. package/dist/device-ws-hub.d.ts +7 -0
  117. package/dist/device-ws-hub.js +10 -3
  118. package/dist/device-ws-protocol.d.ts +63 -10
  119. package/dist/device-ws-protocol.js +56 -25
  120. package/dist/elicitation.js +2 -2
  121. package/dist/engine-identity.d.ts +19 -7
  122. package/dist/engine-identity.js +10 -2
  123. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  124. package/dist/entry-problems.d.ts +40 -3
  125. package/dist/entry-problems.js +3 -1
  126. package/dist/execution-env-refusal.d.ts +29 -0
  127. package/dist/execution-env-refusal.js +8 -0
  128. package/dist/execution-lane-caps.d.ts +3 -1
  129. package/dist/field-conflict.d.ts +1 -1
  130. package/dist/file-history-capture.d.ts +11 -4
  131. package/dist/file-history-capture.js +9 -6
  132. package/dist/file-history-disclosure.d.ts +7 -5
  133. package/dist/file-history-disclosure.js +7 -5
  134. package/dist/fleet/drain-entry.d.ts +4 -0
  135. package/dist/fleet/engine-signal.d.ts +12 -29
  136. package/dist/fleet/engine-signal.js +1 -7
  137. package/dist/fleet-client.js +2 -5
  138. package/dist/gate-settlement.d.ts +1 -8
  139. package/dist/gate-settlement.js +0 -4
  140. package/dist/history-anchor.js +1 -1
  141. package/dist/hitl-delivery.d.ts +2 -3
  142. package/dist/hitl-delivery.js +0 -2
  143. package/dist/hooks/hook-llm.js +4 -2
  144. package/dist/hooks/hook-runner.d.ts +3 -2
  145. package/dist/hooks/hook-runner.js +18 -3
  146. package/dist/host-decision.d.ts +11 -11
  147. package/dist/host-lsp-manager.d.ts +2 -2
  148. package/dist/http/active-run-conflict.d.ts +35 -2
  149. package/dist/http/active-run-conflict.js +48 -19
  150. package/dist/http/admission.js +17 -2
  151. package/dist/http/approval-sweeps.d.ts +1 -1
  152. package/dist/http/approval-sweeps.js +10 -7
  153. package/dist/http/checkpoint-ctx.d.ts +4 -0
  154. package/dist/http/checkpoint-ctx.js +2 -0
  155. package/dist/http/dispatch.d.ts +8 -3
  156. package/dist/http/dispatch.js +59 -32
  157. package/dist/http/durable-run-leg.js +16 -17
  158. package/dist/http/health-reader.d.ts +16 -9
  159. package/dist/http/health-reader.js +2 -1
  160. package/dist/http/health-self-report.d.ts +9 -1
  161. package/dist/http/health-self-report.js +3 -1
  162. package/dist/http/owner-access.d.ts +33 -14
  163. package/dist/http/owner-access.js +40 -10
  164. package/dist/http/principal-gate.d.ts +49 -21
  165. package/dist/http/principal-gate.js +61 -11
  166. package/dist/http/request-channel.d.ts +23 -0
  167. package/dist/http/request-channel.js +9 -0
  168. package/dist/http/request-guards.js +17 -2
  169. package/dist/http/resume-ctx-read.js +42 -3
  170. package/dist/http/resume-legs.d.ts +4 -3
  171. package/dist/http/resume-legs.js +367 -117
  172. package/dist/http/route-ctx.d.ts +91 -15
  173. package/dist/http/route-ctx.js +17 -0
  174. package/dist/http/route-table.d.ts +5 -1
  175. package/dist/http/route-table.js +4 -0
  176. package/dist/http/routes/admin-config-refresh.js +3 -3
  177. package/dist/http/routes/admin-drain.d.ts +3 -0
  178. package/dist/http/routes/admin-drain.js +7 -7
  179. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  180. package/dist/http/routes/admin-memory-optout.js +3 -3
  181. package/dist/http/routes/adoption.js +3 -5
  182. package/dist/http/routes/agents-roster.js +2 -3
  183. package/dist/http/routes/approvals-assistant.d.ts +2 -1
  184. package/dist/http/routes/approvals-assistant.js +99 -51
  185. package/dist/http/routes/background.d.ts +3 -3
  186. package/dist/http/routes/capabilities.d.ts +4 -0
  187. package/dist/http/routes/capabilities.js +38 -10
  188. package/dist/http/routes/config-catalog.js +2 -2
  189. package/dist/http/routes/devices.js +1 -1
  190. package/dist/http/routes/diagnostics.d.ts +3 -3
  191. package/dist/http/routes/diagnostics.js +19 -7
  192. package/dist/http/routes/fleet.js +10 -8
  193. package/dist/http/routes/images.js +10 -10
  194. package/dist/http/routes/memory-bundle.js +3 -3
  195. package/dist/http/routes/memory-compliance.js +3 -3
  196. package/dist/http/routes/memory-consolidation.js +2 -2
  197. package/dist/http/routes/memory-origin.js +3 -3
  198. package/dist/http/routes/memory-policy.js +2 -2
  199. package/dist/http/routes/observability.js +3 -3
  200. package/dist/http/routes/projects.d.ts +3 -2
  201. package/dist/http/routes/projects.js +4 -5
  202. package/dist/http/routes/retention-ops.js +3 -3
  203. package/dist/http/routes/rules.js +5 -5
  204. package/dist/http/routes/run-permission-mode.d.ts +2 -1
  205. package/dist/http/routes/run-permission-mode.js +2 -2
  206. package/dist/http/routes/runs.d.ts +4 -9
  207. package/dist/http/routes/runs.js +171 -65
  208. package/dist/http/routes/session-sync.d.ts +22 -9
  209. package/dist/http/routes/session-sync.js +204 -107
  210. package/dist/http/routes/sessions-list.js +13 -7
  211. package/dist/http/routes/sessions.js +30 -15
  212. package/dist/http/routes/tasks.js +46 -41
  213. package/dist/http/routes/trace-usage.js +2 -2
  214. package/dist/http/routes/workflows.js +1 -1
  215. package/dist/http/server.d.ts +30 -30
  216. package/dist/http/server.js +16 -4
  217. package/dist/http/submit-ctx.d.ts +1 -1
  218. package/dist/http/submit-ctx.js +7 -4
  219. package/dist/http/wire-types.d.ts +14 -4
  220. package/dist/human-facing-args.d.ts +33 -0
  221. package/dist/human-facing-args.js +33 -0
  222. package/dist/identity-source.d.ts +20 -3
  223. package/dist/identity-source.js +14 -0
  224. package/dist/index.d.ts +5 -1
  225. package/dist/k8s-api-credentials.d.ts +29 -0
  226. package/dist/k8s-api-credentials.js +25 -0
  227. package/dist/lane-home-probe.d.ts +3 -7
  228. package/dist/lane-home-probe.js +2 -2
  229. package/dist/leader/diffup.d.ts +19 -0
  230. package/dist/leader/diffup.js +7 -0
  231. package/dist/leader/leader.d.ts +116 -11
  232. package/dist/leader/leader.js +69 -5
  233. package/dist/leader/repair-wire.js +2 -2
  234. package/dist/leader/run-entry.d.ts +2 -1
  235. package/dist/leader/run-entry.js +1 -1
  236. package/dist/leader/wire.d.ts +42 -132
  237. package/dist/leader/wire.js +81 -67
  238. package/dist/leg-facts.d.ts +13 -5
  239. package/dist/leg-facts.js +2 -1
  240. package/dist/memory-scope.d.ts +23 -11
  241. package/dist/memory-scope.js +18 -6
  242. package/dist/memory-sync-client.d.ts +30 -2
  243. package/dist/memory-sync-client.js +16 -9
  244. package/dist/model-entry-headers.d.ts +9 -10
  245. package/dist/model-entry-headers.js +0 -4
  246. package/dist/model-entry-refusal.d.ts +7 -4
  247. package/dist/model-entry-refusal.js +11 -5
  248. package/dist/model-plane-face.d.ts +1 -1
  249. package/dist/model-plane-face.js +3 -1
  250. package/dist/model-route-endpoint.d.ts +13 -7
  251. package/dist/model-route-endpoint.js +14 -11
  252. package/dist/model-select.d.ts +22 -0
  253. package/dist/model-select.js +9 -0
  254. package/dist/model-unreachable-notice.d.ts +11 -0
  255. package/dist/model-unreachable-notice.js +4 -4
  256. package/dist/object-store-buckets.d.ts +640 -6
  257. package/dist/object-store-buckets.js +166 -0
  258. package/dist/observability/err-text.d.ts +7 -0
  259. package/dist/observability/err-text.js +5 -0
  260. package/dist/observability/fail-open.d.ts +25 -17
  261. package/dist/observability/fail-open.js +25 -17
  262. package/dist/observability/logger.js +3 -1
  263. package/dist/observability/metrics.js +1 -0
  264. package/dist/operator-roster.d.ts +68 -0
  265. package/dist/operator-roster.js +32 -0
  266. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  267. package/dist/orchestration/workflow-notify-journal.js +12 -1
  268. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  269. package/dist/orchestration/workflow-park-decision.js +49 -10
  270. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  271. package/dist/orchestration/workflow-park-holder.js +98 -0
  272. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  273. package/dist/orchestration/workflow-record-fence.js +42 -0
  274. package/dist/outbound-dispatcher.d.ts +71 -8
  275. package/dist/outbound-dispatcher.js +48 -7
  276. package/dist/owner-faces.d.ts +2 -2
  277. package/dist/parked-decide.d.ts +106 -55
  278. package/dist/parked-decide.js +153 -117
  279. package/dist/peer-directory.d.ts +2 -2
  280. package/dist/peer-inbound-face.d.ts +2 -6
  281. package/dist/peer-inbound-face.js +0 -3
  282. package/dist/permission-mode-admission.d.ts +74 -5
  283. package/dist/permission-mode-admission.js +56 -3
  284. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  285. package/dist/plugins/adoption-log-sql.js +7 -1
  286. package/dist/plugins/approval-ask-store-file.d.ts +14 -2
  287. package/dist/plugins/approval-ask-store-file.js +11 -0
  288. package/dist/plugins/approval-ask-store-memory.d.ts +10 -1
  289. package/dist/plugins/approval-ask-store-memory.js +35 -10
  290. package/dist/plugins/approval-ask-store-sql.d.ts +69 -4
  291. package/dist/plugins/approval-ask-store-sql.js +45 -5
  292. package/dist/plugins/approval-exemption-store.js +3 -0
  293. package/dist/plugins/approval-nonce-store.js +2 -0
  294. package/dist/plugins/blob-backend.d.ts +83 -7
  295. package/dist/plugins/blob-backend.js +57 -6
  296. package/dist/plugins/breaker-state-sql.js +2 -0
  297. package/dist/plugins/caching-session-store.d.ts +9 -15
  298. package/dist/plugins/caching-session-store.js +6 -0
  299. package/dist/plugins/checkpoint-index-columns.d.ts +20 -16
  300. package/dist/plugins/checkpoint-index-columns.js +3 -6
  301. package/dist/plugins/checkpoint-store-face.d.ts +119 -61
  302. package/dist/plugins/checkpoint-store-face.js +134 -55
  303. package/dist/plugins/device-store-sql.js +6 -0
  304. package/dist/plugins/error-origin.d.ts +18 -0
  305. package/dist/plugins/error-origin.js +10 -0
  306. package/dist/plugins/execution-placement-sql.js +6 -6
  307. package/dist/plugins/image-bake-store-sql.js +6 -0
  308. package/dist/plugins/image-index-sql.js +4 -0
  309. package/dist/plugins/landed-attendants.d.ts +212 -0
  310. package/dist/plugins/landed-attendants.js +161 -0
  311. package/dist/plugins/leader-run-store-sql.js +4 -0
  312. package/dist/plugins/local-checkpoint-store.d.ts +13 -3
  313. package/dist/plugins/local-checkpoint-store.js +38 -49
  314. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  315. package/dist/plugins/local-session-live-reference.js +39 -0
  316. package/dist/plugins/local-session-store.d.ts +71 -33
  317. package/dist/plugins/local-session-store.js +129 -27
  318. package/dist/plugins/memory-engine-pg.js +4 -0
  319. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  320. package/dist/plugins/memory-engine-tidb.js +4 -0
  321. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  322. package/dist/plugins/memory-sync-store-pg.js +5 -0
  323. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  324. package/dist/plugins/one-time-migrations.d.ts +104 -80
  325. package/dist/plugins/one-time-migrations.js +226 -132
  326. package/dist/plugins/org-delivery-quota-store.js +4 -1
  327. package/dist/plugins/outcome-ledger-sql.js +2 -0
  328. package/dist/plugins/permission-rule-store-sql.js +11 -4
  329. package/dist/plugins/pg-cost-quota.js +4 -0
  330. package/dist/plugins/pg-pool.js +35 -10
  331. package/dist/plugins/pg-rate-limiter.js +2 -0
  332. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  333. package/dist/plugins/posix-shell-fs.js +4 -1
  334. package/dist/plugins/remote-env-adb.d.ts +19 -15
  335. package/dist/plugins/remote-env-adb.js +41 -15
  336. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  337. package/dist/plugins/remote-env-connect-seat.js +72 -0
  338. package/dist/plugins/remote-env-device.d.ts +22 -5
  339. package/dist/plugins/remote-env-device.js +106 -8
  340. package/dist/plugins/remote-env-e2b.d.ts +15 -6
  341. package/dist/plugins/remote-env-e2b.js +42 -32
  342. package/dist/plugins/remote-env-file-error.js +6 -2
  343. package/dist/plugins/remote-env-host.d.ts +46 -10
  344. package/dist/plugins/remote-env-host.js +124 -52
  345. package/dist/plugins/remote-env-k8s.d.ts +109 -41
  346. package/dist/plugins/remote-env-k8s.js +160 -54
  347. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  348. package/dist/plugins/remote-env-local-docker.js +34 -41
  349. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  350. package/dist/plugins/remote-env-ssh.js +60 -59
  351. package/dist/plugins/remote-shell.d.ts +98 -1
  352. package/dist/plugins/remote-shell.js +218 -0
  353. package/dist/plugins/replica-registration.d.ts +1 -1
  354. package/dist/plugins/replica-registration.js +1 -1
  355. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  356. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  357. package/dist/plugins/retention-lane-store-sql.js +4 -0
  358. package/dist/plugins/retention-sql.d.ts +20 -2
  359. package/dist/plugins/retention-sql.js +11 -0
  360. package/dist/plugins/run-store-sql.d.ts +21 -2
  361. package/dist/plugins/run-store-sql.js +31 -7
  362. package/dist/plugins/s3-presign.d.ts +23 -0
  363. package/dist/plugins/s3-presign.js +37 -3
  364. package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
  365. package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
  366. package/dist/plugins/scheduler-support.d.ts +2 -2
  367. package/dist/plugins/scheduler-support.js +0 -3
  368. package/dist/plugins/schema-consistency.d.ts +4 -2
  369. package/dist/plugins/schema-consistency.js +19 -2
  370. package/dist/plugins/schema-indexes.js +2 -0
  371. package/dist/plugins/send-file-ledger.d.ts +2 -2
  372. package/dist/plugins/send-file-ledger.js +5 -2
  373. package/dist/plugins/send-user-file.d.ts +3 -4
  374. package/dist/plugins/send-user-file.js +56 -52
  375. package/dist/plugins/serving-requirement.d.ts +26 -7
  376. package/dist/plugins/serving-requirement.js +11 -4
  377. package/dist/plugins/session-birth.d.ts +6 -2
  378. package/dist/plugins/session-blob-claim-token.d.ts +15 -0
  379. package/dist/plugins/session-blob-claim-token.js +20 -0
  380. package/dist/plugins/session-blob-namespace.d.ts +46 -0
  381. package/dist/plugins/session-blob-namespace.js +116 -0
  382. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  383. package/dist/plugins/session-ext-table.d.ts +14 -1
  384. package/dist/plugins/session-ext-table.js +5 -1
  385. package/dist/plugins/session-row-sql.d.ts +49 -2
  386. package/dist/plugins/session-row-sql.js +56 -13
  387. package/dist/plugins/session-store-sql.d.ts +34 -18
  388. package/dist/plugins/session-store-sql.js +98 -17
  389. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  390. package/dist/plugins/shared-memory-store-sql.js +6 -2
  391. package/dist/plugins/snapshot-bucket-presence.d.ts +25 -2
  392. package/dist/plugins/snapshot-bucket-presence.js +8 -2
  393. package/dist/plugins/sql-driver.d.ts +2 -1
  394. package/dist/plugins/sql-driver.js +18 -3
  395. package/dist/plugins/sql-errors.d.ts +11 -6
  396. package/dist/plugins/sql-errors.js +5 -6
  397. package/dist/plugins/sql-json-column.d.ts +1 -1
  398. package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
  399. package/dist/plugins/stop-then-start-sentence.js +14 -10
  400. package/dist/plugins/stop-then-start.d.ts +109 -0
  401. package/dist/plugins/stop-then-start.js +104 -0
  402. package/dist/plugins/store-backend.d.ts +84 -15
  403. package/dist/plugins/store-backend.js +236 -72
  404. package/dist/plugins/store-boundary.d.ts +57 -0
  405. package/dist/plugins/store-boundary.js +139 -0
  406. package/dist/plugins/store-contracts.d.ts +17 -0
  407. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  408. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  409. package/dist/plugins/store-fault.d.ts +26 -7
  410. package/dist/plugins/store-fault.js +18 -2
  411. package/dist/plugins/task-attachment-store.d.ts +2 -1
  412. package/dist/plugins/task-attachment-store.js +14 -1
  413. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  414. package/dist/plugins/task-list-store-sql.js +10 -8
  415. package/dist/plugins/tidb-cost-quota.js +4 -0
  416. package/dist/plugins/tidb-pool.js +21 -25
  417. package/dist/plugins/tidb-rate-limiter.js +4 -0
  418. package/dist/plugins/user-input-ledger-sql.js +4 -0
  419. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  420. package/dist/plugins/workflow-run-store-sql.js +64 -4
  421. package/dist/plugins/workspace-custody.d.ts +4 -3
  422. package/dist/plugins/workspace-fill.d.ts +4 -7
  423. package/dist/plugins/workspace-fill.js +2 -1
  424. package/dist/plugins/write-behind-counter.js +5 -0
  425. package/dist/project-context.d.ts +0 -2
  426. package/dist/project-context.js +4 -8
  427. package/dist/project-registry.d.ts +46 -0
  428. package/dist/project-registry.js +44 -0
  429. package/dist/question.d.ts +2 -1
  430. package/dist/question.js +5 -13
  431. package/dist/request-form.d.ts +6 -1
  432. package/dist/request-form.js +4 -1
  433. package/dist/request-key-closure.js +1 -1
  434. package/dist/request-value-closure.d.ts +4 -0
  435. package/dist/request-value-closure.js +10 -0
  436. package/dist/rule-issue-reading.d.ts +1 -1
  437. package/dist/rules-consent.d.ts +1 -1
  438. package/dist/run-acceptance.d.ts +3 -2
  439. package/dist/run-acceptance.js +4 -6
  440. package/dist/run-local.js +9 -9
  441. package/dist/runs.d.ts +54 -16
  442. package/dist/runs.js +67 -13
  443. package/dist/runtime-governance.d.ts +5 -4
  444. package/dist/security.d.ts +30 -32
  445. package/dist/security.js +41 -7
  446. package/dist/sema-config-dir.d.ts +2 -1
  447. package/dist/server-secret-env.d.ts +12 -10
  448. package/dist/server-secret-env.js +24 -15
  449. package/dist/session-bindings.d.ts +82 -0
  450. package/dist/session-bindings.js +18 -0
  451. package/dist/session-children-retire.d.ts +2 -2
  452. package/dist/session-children-retire.js +2 -6
  453. package/dist/session-deletion.d.ts +16 -1
  454. package/dist/session-error-wire.d.ts +3 -3
  455. package/dist/session-error-wire.js +3 -3
  456. package/dist/session-incarnation.d.ts +10 -0
  457. package/dist/session-incarnation.js +10 -1
  458. package/dist/session-kind.d.ts +57 -0
  459. package/dist/session-kind.js +22 -0
  460. package/dist/session-row.d.ts +21 -1
  461. package/dist/session-row.js +7 -1
  462. package/dist/session-sync-kernel.d.ts +24 -14
  463. package/dist/session-sync-kernel.js +3 -6
  464. package/dist/session-sync.d.ts +25 -103
  465. package/dist/session-sync.js +14 -76
  466. package/dist/session-titler.d.ts +10 -3
  467. package/dist/session-titler.js +19 -6
  468. package/dist/ssh-host-key.d.ts +5 -0
  469. package/dist/ssh-host-key.js +3 -0
  470. package/dist/stores-sql/blob-index-sql.d.ts +30 -9
  471. package/dist/stores-sql/blob-index-sql.js +40 -21
  472. package/dist/stores-sql/checkpoint-store-sql.d.ts +54 -27
  473. package/dist/stores-sql/checkpoint-store-sql.js +70 -146
  474. package/dist/stores-sql/file-history-store-sql.d.ts +113 -15
  475. package/dist/stores-sql/file-history-store-sql.js +205 -95
  476. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  477. package/dist/stores-sql/pg-session-storage.js +37 -13
  478. package/dist/stores-sql/retention-store-sql.d.ts +1 -9
  479. package/dist/stores-sql/retention-store-sql.js +5 -19
  480. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  481. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  482. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  483. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  484. package/dist/stores-sql/tidb-session-store.js +37 -13
  485. package/dist/submission-exit.d.ts +3 -2
  486. package/dist/submission-exit.js +9 -1
  487. package/dist/task-cwd.d.ts +2 -2
  488. package/dist/task-settings.d.ts +7 -5
  489. package/dist/task-settings.js +3 -3
  490. package/dist/terminal.d.ts +33 -2
  491. package/dist/terminal.js +139 -9
  492. package/dist/tool-approval.d.ts +465 -507
  493. package/dist/tool-approval.js +606 -1222
  494. package/dist/trace/core-keyset-guard.d.ts +1 -1
  495. package/dist/trace/ledger-events.d.ts +3 -3
  496. package/dist/trace/project.d.ts +2 -3
  497. package/dist/trace/redact.js +3 -2
  498. package/dist/trace/self-minted-wire.d.ts +571 -178
  499. package/dist/trace/self-minted-wire.js +189 -56
  500. package/dist/web-admin-client/apply-effective.js +2 -2
  501. package/dist/web-admin-client/read-warnings.d.ts +2 -2
  502. package/dist/web-admin-client/read-warnings.js +1 -1
  503. package/dist/web-admin-client/types.d.ts +1 -1
  504. package/dist/workspace-space.d.ts +10 -4
  505. package/dist/workspace-space.js +4 -1
  506. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +79 -28
  507. package/package.json +7 -3
  508. package/scripts/embed-minimal.mjs +3 -3
  509. package/wire-changes/server@7.151.0.json +762 -0
  510. package/wire-changes/server@7.152.0.json +900 -0
  511. package/dist/config-d-migration.d.ts +0 -37
  512. package/dist/config-d-migration.js +0 -60
  513. package/dist/http/session-inherit-env.d.ts +0 -36
  514. package/dist/http/session-inherit-env.js +0 -6
@@ -15,9 +15,9 @@ import { defaultSubagentTailBus } from "../../fleet/subagent-tail-bus.js";
15
15
  import { idemCallerOf, idemKeyOf, inflightKeyOf, submissionIdemOf } from "../idempotency.js";
16
16
  import { streamSseLog } from "../sse-log.js";
17
17
  import { bindSseLifecycle } from "../sse-lifecycle.js";
18
- import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSeat, storedCardDemandsAPerson } from "../../approval-card.js";
19
- import { heldAskOf, liveHostSource, readDecider, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
20
- import { ASK_DECISION_CONSUMER_ABSENT, approvalPreambleReplays, outcomeOfDecidedRow, parkSessionOf, presentedApprovalFrameFamily, resolveStreamApprovalGate } from "../../tool-approval.js";
18
+ import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSeat } from "../../approval-card.js";
19
+ import { heldAskOf, readDecider, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
20
+ import { ASK_DECISION_CONSUMER_ABSENT, ASK_NOT_FOUND_UNDER_TASK, approvalPreambleReplays, decidedRowFacts, outcomeOfDecidedRow, parkSessionOf, presentedApprovalFrameFamily, readPersistRuleSlot, readReadRootGrantSlot, resolveStreamApprovalGate, READ_ROOT_GRANT_LIVE_ONLY, READ_ROOT_GRANT_NOT_ACCEPTED } from "../../tool-approval.js";
21
21
  import { MAX_DECISION_NOTE_CHARS, noteLandedOnRow, noteRecordedReceipt } from "../../approval-ask-machine.js";
22
22
  import { askRowEndingCause } from "../../approval-deny-reasons.js";
23
23
  import { normalizeRunEventType, screenedStoredEventData } from "../../trace/project.js";
@@ -28,13 +28,14 @@ import { INJECTION_TIERS } from "../../trace/injection-tier.js";
28
28
  import { headerStr, gatedSubject, explicitOperatorOk, sendPrincipalRefusal, runIdentityOf } from "../principal-gate.js";
29
29
  import { ActorAssertionWire } from "@sema-agent/settings-schema";
30
30
  import * as facts from "../../capability-facts.js";
31
- import { assertNever } from "../route-ctx.js";
31
+ import { assertNever, readRememberSlot } from "../route-ctx.js";
32
32
  import { readRunFace } from "../run-read-face.js";
33
33
  import { replayOfExistingRun, replayOfKey } from "../submit-replay.js";
34
34
  import { mintAndDriveDurableRun } from "../durable-run-leg.js";
35
35
  import { SUBMISSION_CLAIM_FACE } from "../execution-context.js";
36
36
  import { admitRunById, admitRunByIdem, enter, readVisibleRun, sessionFactsReadOf } from "../owner-access.js";
37
37
  import { keyAdmission, ownerCellOf, recoveredSubject } from "../../owner-faces.js";
38
+ import { engineScopeOfOwner } from "../../engine-identity.js";
38
39
  import { personOf } from "../../owner-brands.js";
39
40
  import { withSubject } from "../../observability/principal-context.js";
40
41
  import { readResumeCtx, resumeCtxUnreadableAnswer } from "../resume-ctx-read.js";
@@ -48,7 +49,13 @@ const STEER_PRIORITY_UNION = STEER_PRIORITY_WORDS.join(" | ");
48
49
  const STEER_PRIORITY_CHOICES = STEER_PRIORITY_WORDS.length <= 2 ? STEER_PRIORITY_WORDS.join(" or ") : `${STEER_PRIORITY_WORDS.slice(0, -1).join(", ")}, or ${STEER_PRIORITY_WORDS[STEER_PRIORITY_WORDS.length - 1]}`;
49
50
  const ASK_PARKING_RETRY_AFTER_SEC = 2;
50
51
  const ASK_ACTOR_LABEL_MAX = 256;
52
+ const ASK_LEDGER_DISABLED = "the durable stream-approval ask ledger is not enabled on this worker (needs a store backend (DB_BACKEND) and DURABLE_APPROVAL)";
51
53
  const AskDecisionActorSchema = ActorAssertionWire.strip();
54
+ function mirrorRetryAfter(res, body) {
55
+ const retryAfterSec = body !== null && typeof body === "object" ? body.retryAfterSec : undefined;
56
+ if (typeof retryAfterSec === "number" && Number.isFinite(retryAfterSec) && retryAfterSec >= 0)
57
+ res.setHeader("retry-after", String(Math.ceil(retryAfterSec)));
58
+ }
52
59
  const AskDecisionBodySchema = z
53
60
  .object({
54
61
  decision: z.enum(["approve", "deny"]),
@@ -63,6 +70,9 @@ const AskDecisionBodySchema = z
63
70
  actor: z.object({ label: z.string().max(ASK_ACTOR_LABEL_MAX) }).strict().optional(),
64
71
  decidedBy: z.unknown().optional(),
65
72
  decidedVia: z.unknown().optional(),
73
+ remember: z.unknown().optional(),
74
+ persistRule: z.unknown().optional(),
75
+ readRootGrant: z.unknown().optional(),
66
76
  })
67
77
  .strict();
68
78
  const ASK_DECISION_CONFIRM_TIMEOUT_MS = 2_000;
@@ -110,18 +120,19 @@ async function streamRunEvents(req, res, deps, runStore, entry, taskId) {
110
120
  preamble: async (signal) => {
111
121
  const gate = resolveStreamApprovalGate({
112
122
  toolApprovalEnabled: Boolean(deps.toolApproval),
113
- streamApprovalEnabled: deps.config.streamApproval?.enabled === true,
114
123
  backend: deps.backend,
115
124
  checkpointStore: deps.checkpointStore,
116
125
  });
117
126
  if (!gate.active)
118
127
  return [];
119
- if (!approvalPreambleReplays({
120
- streamApprovalOn: gate.active,
121
- windowMs: deps.config.streamApproval?.windowMs,
122
- windowMarginMs: deps.config.streamAskWindowMarginMs,
123
- declaredFamilies: new Set([presentedApprovalFrameFamily(gate.active)]),
124
- })) {
128
+ const presented = presentedApprovalFrameFamily(gate.active);
129
+ if (presented === undefined ||
130
+ !approvalPreambleReplays({
131
+ streamApprovalOn: gate.active,
132
+ windowMs: deps.config.streamApproval?.windowMs,
133
+ windowMarginMs: deps.config.streamAskWindowMarginMs,
134
+ declaredFamilies: new Set([presented]),
135
+ })) {
125
136
  return [];
126
137
  }
127
138
  const store = gate.askStore;
@@ -885,7 +896,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
885
896
  if (!gated)
886
897
  return;
887
898
  const { run } = gated;
888
- const out = await subagentTaskOutput(target, { owner: runId, scope: run.owner ?? "default", ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
899
+ const out = await subagentTaskOutput(target, { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
889
900
  const details = out.details;
890
901
  if (details?.error === "not_found" || details?.type !== "background_agent") {
891
902
  if (!sendHandleMiss(res, run, deps.instanceId))
@@ -914,7 +925,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
914
925
  return;
915
926
  const { run } = gatedTail;
916
927
  const it = defaultSubagentTailBus.subscribe(target);
917
- const probe = await subagentTaskOutput(target, { owner: runId, scope: run.owner ?? "default", ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
928
+ const probe = await subagentTaskOutput(target, { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
918
929
  const probeDetails = probe.details;
919
930
  if (probeDetails?.error === "not_found" || probeDetails?.type !== "background_agent") {
920
931
  void it.return?.();
@@ -982,7 +993,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
982
993
  return;
983
994
  const { run } = gatedB;
984
995
  const q = new URLSearchParams(match.search);
985
- const access = { owner: runId, scope: run.owner ?? "default", ...(run.sessionId ? { sessionId: run.sessionId } : {}) };
996
+ const access = { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) };
986
997
  if (q.get("filter") !== null) {
987
998
  sendError(res, 400, "request.param_unsupported", "filter is not accepted on the wire — fetch the output and filter client-side (note: the wire serves the clipped projection)");
988
999
  return;
@@ -1168,12 +1179,12 @@ export async function handleRunVerbs(req, res, match, ctx) {
1168
1179
  sendJson(res, status, respBody);
1169
1180
  return;
1170
1181
  }
1171
- if (match.decl.id === "tool-approval-respond" || match.decl.id === "tool-approval-read") {
1182
+ if (match.decl.id === "task-ask-read") {
1172
1183
  if (rateLimited(req, res))
1173
1184
  return;
1174
- const approvalFact = facts.toolApproval(deps);
1175
- if (!approvalFact.available) {
1176
- sendError(res, 501, "feature.tool_approval_disabled", "live tool-approval HITL is not enabled on this worker (TOOL_APPROVAL_ENABLED)");
1185
+ const streamFact = facts.streamApproval(deps);
1186
+ if (!streamFact.available) {
1187
+ sendError(res, 501, "feature.approval_ask_disabled", ASK_LEDGER_DISABLED);
1177
1188
  return;
1178
1189
  }
1179
1190
  const principal = gatedSubject(req, deps.config);
@@ -1181,18 +1192,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
1181
1192
  sendPrincipalRefusal(res, req, deps.config);
1182
1193
  return;
1183
1194
  }
1184
- const id = match.params.id;
1185
- if (match.decl.id === "tool-approval-read") {
1186
- const { status, body: respBody } = await approvalFact.coordinator.readApproval(id, principal);
1187
- sendJson(res, status, respBody);
1188
- return;
1189
- }
1190
- const body = await readJson(req);
1191
- const { status, body: respBody } = await approvalFact.coordinator.respond(id, principal, body, req, { readRootGrantAccepted: facts.readRootGrant(deps).available });
1192
- const retryAfterSec = respBody.retryAfterSec;
1193
- if (typeof retryAfterSec === "number" && Number.isFinite(retryAfterSec) && retryAfterSec >= 0) {
1194
- res.setHeader("retry-after", String(Math.ceil(retryAfterSec)));
1195
- }
1195
+ const { status, body: respBody } = await streamFact.coordinator.readAsk(match.params.taskId, match.params.askId, principal);
1196
1196
  sendJson(res, status, respBody);
1197
1197
  return;
1198
1198
  }
@@ -1201,10 +1201,11 @@ export async function handleRunVerbs(req, res, match, ctx) {
1201
1201
  return;
1202
1202
  const streamFact = facts.streamApproval(deps);
1203
1203
  if (!streamFact.available) {
1204
- sendError(res, 501, "feature.approval_ask_disabled", "the durable stream-approval ask ledger is not enabled on this worker (needs STREAM_APPROVAL_ENABLED plus a DURABLE store backend — the local backend keeps asks in memory and would lose accepted decisions on restart)");
1204
+ sendError(res, 501, "feature.approval_ask_disabled", ASK_LEDGER_DISABLED);
1205
1205
  return;
1206
1206
  }
1207
1207
  const askStore = streamFact.askStore;
1208
+ const coordinator = streamFact.coordinator;
1208
1209
  const principal = gatedSubject(req, deps.config);
1209
1210
  if (deps.config.requirePrincipal && principal === undefined) {
1210
1211
  sendPrincipalRefusal(res, req, deps.config);
@@ -1218,7 +1219,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
1218
1219
  sendError(res, 400, "request.body_shape", retired.error, retired.extra);
1219
1220
  return;
1220
1221
  }
1221
- sendError(res, 400, "request.body_shape", "invalid ask decision body — expected decision=approve|deny plus optional updatedInput / note / idempotencyKey / actor.label / decidedBy / decidedVia");
1222
+ sendError(res, 400, "request.body_shape", "invalid ask decision body — expected decision=approve|deny plus optional updatedInput / note / idempotencyKey / actor.label / decidedBy / decidedVia / remember / persistRule / readRootGrant");
1222
1223
  return;
1223
1224
  }
1224
1225
  const body = parsedBody.data;
@@ -1238,16 +1239,39 @@ export async function handleRunVerbs(req, res, match, ctx) {
1238
1239
  }
1239
1240
  }
1240
1241
  const decider = decidedByReading.decider;
1242
+ const rememberSlot = readRememberSlot(body.remember, body.decision);
1243
+ if (rememberSlot.kind === "refused") {
1244
+ sendError(res, 400, rememberSlot.refusal.errorCode, rememberSlot.refusal.message, rememberSlot.refusal.facts);
1245
+ return;
1246
+ }
1247
+ const remember = rememberSlot.kind === "session" ? "session" : undefined;
1248
+ const ruleSlot = readPersistRuleSlot(body.persistRule, body.decision === "approve" ? "allow" : "deny");
1249
+ if (!ruleSlot.ok) {
1250
+ sendError(res, 400, "request.body_shape", ruleSlot.error);
1251
+ return;
1252
+ }
1253
+ const persistRule = ruleSlot.slot;
1254
+ const grantSlot = readReadRootGrantSlot(body.readRootGrant, body.decision === "approve" && remember === undefined);
1255
+ if (!grantSlot.ok) {
1256
+ sendError(res, 400, "request.body_shape", grantSlot.error);
1257
+ return;
1258
+ }
1259
+ if (grantSlot.grant !== undefined && !facts.readRootGrant(deps).available) {
1260
+ sendError(res, 400, "request.body_shape", READ_ROOT_GRANT_NOT_ACCEPTED);
1261
+ return;
1262
+ }
1263
+ const readRootGrant = grantSlot.grant;
1241
1264
  const hasUpdatedInput = typeof rawBody === "object" && rawBody !== null && "updatedInput" in rawBody;
1242
1265
  const taskId = match.params.taskId;
1243
1266
  const askId = match.params.askId;
1244
- const askNotFound = () => sendError(res, 404, "not_found.ask", "no such approval ask under this task (never existed, belongs to another task, or is not yours)");
1267
+ const askNotFound = () => sendError(res, 404, "not_found.ask", ASK_NOT_FOUND_UNDER_TASK);
1245
1268
  const row0 = await askStore.getAsk(askId);
1246
1269
  if (!row0 || row0.taskId !== taskId) {
1247
1270
  askNotFound();
1248
1271
  return;
1249
1272
  }
1250
- const askAdmission = keyAdmission("ask.decide", { subject: principal, operator: explicitOperatorOk(principal === undefined ? undefined : personOf(principal), deps.config) }, ownerCellOf(row0.owner));
1273
+ const callerIsOperator = explicitOperatorOk(principal === undefined ? undefined : personOf(principal), deps.config, "operate");
1274
+ const askAdmission = keyAdmission("ask.decide", { subject: principal, operator: callerIsOperator }, ownerCellOf(row0.owner));
1251
1275
  if (askAdmission === undefined) {
1252
1276
  askNotFound();
1253
1277
  return;
@@ -1259,7 +1283,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
1259
1283
  via: askAdmission === "row" ? "owner" : "operator",
1260
1284
  };
1261
1285
  const decidedRowIsAuthoritative = (row) => {
1262
- if (row.state !== "DECIDED" || row.decision !== "approve" && row.decision !== "deny" || row.provisional || row.decidedAtMs === null) {
1286
+ if (decidedRowFacts(row) === undefined) {
1263
1287
  deps.logger?.error?.("ask_decision_row_not_authoritative", {
1264
1288
  taskId,
1265
1289
  askId,
@@ -1290,8 +1314,8 @@ export async function handleRunVerbs(req, res, match, ctx) {
1290
1314
  const replayDecided = (row) => {
1291
1315
  const storedActor = projectDecisionActor(row.decisionActor);
1292
1316
  sendJson(res, 200, {
1293
- askId: row.askId,
1294
- taskId: row.taskId,
1317
+ askId,
1318
+ taskId,
1295
1319
  decision: row.decision,
1296
1320
  decidedAtMs: row.decidedAtMs,
1297
1321
  ...(storedActor ? { actor: storedActor } : {}),
@@ -1299,7 +1323,83 @@ export async function handleRunVerbs(req, res, match, ctx) {
1299
1323
  ...noteReceipt(row),
1300
1324
  });
1301
1325
  };
1302
- const sendTerminal = (row) => {
1326
+ const heldLeg = coordinator.holdLiveLeg(askId);
1327
+ const policyMayNotApprove = (row) => body.decision === "approve" && policyCannotAnswer(heldAskOf(coordinator.askDemandsAPerson(row, heldLeg)), decider.decidedBy);
1328
+ const refusePolicyApprove = () => sendError(res, 400, "request.field_conflict", POLICY_CANNOT_ALLOW_PERSON_ASK, fieldConflictFacts("policy_person_ask", ["decidedBy", "decision"]));
1329
+ const conflictWithFirst = (row) => {
1330
+ const first = projectDecisionActor(row.decisionActor);
1331
+ sendError(res, 409, "conflict.ask_decided", "this ask was already decided — the first decision stands and is echoed here", {
1332
+ decision: row.decision,
1333
+ decidedAtMs: row.decidedAtMs,
1334
+ ...(first ? { actor: first } : {}),
1335
+ ...decisionNoteEcho(row),
1336
+ });
1337
+ };
1338
+ const answerParked = async (row) => {
1339
+ const answer = await coordinator.decideParkedAsk(askStore, row, {
1340
+ write: { decision: body.decision, decider, ...(body.note !== undefined ? { note: body.note } : {}), actor, ...(body.idempotencyKey !== undefined ? { idempotencyKey: body.idempotencyKey } : {}) },
1341
+ ...(body.decision === "approve" && hasUpdatedInput ? { updatedInput: body.updatedInput } : {}),
1342
+ ...(remember !== undefined ? { remember } : {}),
1343
+ ...(persistRule !== undefined ? { persistRule } : {}),
1344
+ ...(principal !== undefined ? { principal } : {}),
1345
+ operator: callerIsOperator,
1346
+ policyMayNotApprove: policyMayNotApprove(row),
1347
+ httpReq: req,
1348
+ }, body.idempotencyKey);
1349
+ switch (answer.kind) {
1350
+ case "standing": {
1351
+ const first = { decision: answer.decision, decidedAtMs: answer.decidedAtMs, decisionActor: answer.actor ?? null, decisionNote: answer.decisionNote ?? null };
1352
+ if (answer.byThisRequest)
1353
+ replayDecided(first);
1354
+ else
1355
+ conflictWithFirst(first);
1356
+ return;
1357
+ }
1358
+ case "refused":
1359
+ if (answer.status === 404) {
1360
+ askNotFound();
1361
+ return;
1362
+ }
1363
+ mirrorRetryAfter(res, answer.body);
1364
+ sendJson(res, answer.status, answer.body);
1365
+ return;
1366
+ case "gone":
1367
+ askNotFound();
1368
+ return;
1369
+ case "policy_refused":
1370
+ refusePolicyApprove();
1371
+ return;
1372
+ case "gate_only":
1373
+ sendError(res, 410, "gone.ask_parked", "the in-stream window closed and this ask was parked onto the durable approval gate — decide it through that gate for the session echoed here", {
1374
+ sessionId: parkSessionOf(row),
1375
+ gateBoundCallId: row.gateBoundCallId,
1376
+ gateBoundInputHash: row.gateBoundInputHash,
1377
+ });
1378
+ return;
1379
+ case "accepted": {
1380
+ const recorded = answer.recorded ?? { decisionNote: null };
1381
+ sendJson(res, 200, {
1382
+ ...answer.body,
1383
+ askId,
1384
+ taskId,
1385
+ decision: body.decision,
1386
+ decidedAtMs: answer.recorded?.decidedAtMs ?? Date.now(),
1387
+ actor,
1388
+ accepted: "parked_redeemed",
1389
+ ...decisionNoteEcho(recorded),
1390
+ ...noteReceipt(recorded),
1391
+ ...(answer.rememberApplied !== undefined ? { rememberApplied: answer.rememberApplied } : {}),
1392
+ ...(answer.rule ?? {}),
1393
+ });
1394
+ return;
1395
+ }
1396
+ default: {
1397
+ const unhandled = answer;
1398
+ throw new Error(`unhandled parked ask answer: ${JSON.stringify(unhandled)}`);
1399
+ }
1400
+ }
1401
+ };
1402
+ const sendTerminal = async (row) => {
1303
1403
  switch (row.state) {
1304
1404
  case "DECIDED": {
1305
1405
  if (!syncLiveFromDecidedRow(row))
@@ -1308,21 +1408,15 @@ export async function handleRunVerbs(req, res, match, ctx) {
1308
1408
  replayDecided(row);
1309
1409
  return;
1310
1410
  }
1311
- const first = projectDecisionActor(row.decisionActor);
1312
- sendError(res, 409, "conflict.ask_decided", "this ask was already decided — the first decision stands and is echoed here", {
1313
- decision: row.decision,
1314
- decidedAtMs: row.decidedAtMs,
1315
- ...(first ? { actor: first } : {}),
1316
- ...decisionNoteEcho(row),
1317
- });
1411
+ conflictWithFirst(row);
1318
1412
  return;
1319
1413
  }
1320
1414
  case "PARKED":
1321
- sendError(res, 410, "gone.ask_parked", "the in-stream window closed and this ask was parked onto the durable approval gate — decide it through that gate for the session echoed here", {
1322
- sessionId: parkSessionOf(row),
1323
- gateBoundCallId: row.gateBoundCallId,
1324
- gateBoundInputHash: row.gateBoundInputHash,
1325
- });
1415
+ if (readRootGrant !== undefined) {
1416
+ sendError(res, 400, "request.body_shape", READ_ROOT_GRANT_LIVE_ONLY);
1417
+ return;
1418
+ }
1419
+ await answerParked(row);
1326
1420
  return;
1327
1421
  case "DENIED":
1328
1422
  case "VOID": {
@@ -1367,23 +1461,28 @@ export async function handleRunVerbs(req, res, match, ctx) {
1367
1461
  }
1368
1462
  }
1369
1463
  if (row0.state !== "STREAM_PENDING") {
1370
- sendTerminal(row0);
1464
+ await sendTerminal(row0);
1371
1465
  return;
1372
1466
  }
1373
- if (body.decision === "approve" && policyCannotAnswer(heldAskOf(storedCardDemandsAPerson(row0.cardJson)), decider.decidedBy)) {
1374
- sendError(res, 400, "request.field_conflict", POLICY_CANNOT_ALLOW_PERSON_ASK, fieldConflictFacts("policy_person_ask", ["decidedBy", "decision"]));
1467
+ if (policyMayNotApprove(row0)) {
1468
+ refusePolicyApprove();
1469
+ return;
1470
+ }
1471
+ const ruleTextRefusal = persistRule !== undefined ? coordinator.precheckEditedRuleOfAskRow(row0, row0.owner, persistRule, hasUpdatedInput) : undefined;
1472
+ if (ruleTextRefusal !== undefined) {
1473
+ sendError(res, 400, "request.body_shape", ruleTextRefusal.message, ruleTextRefusal.ruleRejectCode !== undefined ? { ruleRejectCode: ruleTextRefusal.ruleRejectCode } : undefined);
1375
1474
  return;
1376
1475
  }
1377
1476
  let outcome;
1378
- const releaseEditMark = body.decision === "approve" && hasUpdatedInput ? deps.toolApproval?.markEditedDecisionInFlight(askId) : undefined;
1477
+ const releaseEditMark = body.decision === "approve" && (hasUpdatedInput || readRootGrant !== undefined) ? deps.toolApproval?.markEditedDecisionInFlight(askId) : undefined;
1379
1478
  try {
1380
- outcome = await askStore.decideAsk(askId, row0.batchId, row0.owner, {
1479
+ outcome = await coordinator.writeAskDecision(askStore, askId, { kind: "live", batchId: row0.batchId }, row0.owner, {
1381
1480
  decision: body.decision,
1382
- decisionActor: actor,
1383
- decisionNote: body.note ?? null,
1384
- idempotencyKey: body.idempotencyKey ?? null,
1385
- ...liveHostSource(decider),
1386
- ...(body.decision === "approve" && hasUpdatedInput ? { updatedInput: body.updatedInput } : {}),
1481
+ decider,
1482
+ actor,
1483
+ ...(body.note !== undefined ? { note: body.note } : {}),
1484
+ ...(body.idempotencyKey !== undefined ? { idempotencyKey: body.idempotencyKey } : {}),
1485
+ ...(hasUpdatedInput ? { updatedInput: body.updatedInput } : {}),
1387
1486
  });
1388
1487
  }
1389
1488
  catch (err) {
@@ -1407,7 +1506,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
1407
1506
  confirmed.decision === body.decision &&
1408
1507
  confirmed.idempotencyKey === body.idempotencyKey &&
1409
1508
  !confirmed.provisional) {
1410
- const settledNow = deps.toolApproval.notifyExternalDecision(askId, outcomeOfDecidedRow(confirmed)).settled;
1509
+ const settledNow = deps.toolApproval.notifyExternalDecision(askId, outcomeOfDecidedRow(confirmed), readRootGrant).settled;
1411
1510
  deps.logger?.warn?.("ask_decision_edit_settled_after_ambiguous_commit", { taskId, askId, settled: settledNow });
1412
1511
  }
1413
1512
  }
@@ -1443,7 +1542,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
1443
1542
  askNotFound();
1444
1543
  return;
1445
1544
  }
1446
- sendTerminal(outcome.row);
1545
+ await sendTerminal(outcome.row);
1447
1546
  return;
1448
1547
  }
1449
1548
  if (!decidedRowIsAuthoritative(outcome.row))
@@ -1454,7 +1553,13 @@ export async function handleRunVerbs(req, res, match, ctx) {
1454
1553
  sendError(res, 500, "internal.error", "the ask row was rewritten between commit and read-back — the decision that stands is not the one this request submitted; re-read the ask before acting on it");
1455
1554
  return;
1456
1555
  }
1457
- const settled = deps.toolApproval?.notifyExternalDecision(outcome.row.askId, outcomeOfDecidedRow(outcome.row)).settled ?? 0;
1556
+ const live = await coordinator.settleLiveDecision(outcome.row, heldLeg, row0.owner, principal, {
1557
+ ...(remember !== undefined ? { remember } : {}),
1558
+ ...(readRootGrant !== undefined ? { readRootGrant } : {}),
1559
+ ...(persistRule !== undefined ? { persistRule } : {}),
1560
+ inputWasEdited: hasUpdatedInput,
1561
+ });
1562
+ const settled = live.settled;
1458
1563
  const forwarded = outcome.row.decision === "approve" && outcome.row.updatedInput !== undefined && settled > 0;
1459
1564
  sendJson(res, 200, {
1460
1565
  askId: outcome.row.askId,
@@ -1466,6 +1571,8 @@ export async function handleRunVerbs(req, res, match, ctx) {
1466
1571
  ...(settled === 0 ? { consumerState: ASK_DECISION_CONSUMER_ABSENT } : {}),
1467
1572
  ...decisionNoteEcho(outcome.row),
1468
1573
  ...noteReceipt(outcome.row),
1574
+ ...(live.rememberApplied !== undefined ? { rememberApplied: live.rememberApplied } : {}),
1575
+ ...(live.rule ?? {}),
1469
1576
  });
1470
1577
  return;
1471
1578
  }
@@ -1554,8 +1661,7 @@ export const RUN_VERBS_ROUTES = [
1554
1661
  { id: "run-task-stop", pattern: /^\/v1\/runs\/(?<runId>[^/]+)\/tasks\/(?<tid>[^/]+)\/stop$/, label: "/v1/runs/:id/tasks/:tid/*", methods: ["POST"] },
1555
1662
  { id: "elicitation-respond", pattern: /^\/v1\/elicitations\/(?<id>[^/]+)\/respond$/, label: "/v1/elicitations/:id/respond", methods: ["POST"] },
1556
1663
  { id: "question-respond", pattern: /^\/v1\/questions\/(?<id>[^/]+)\/respond$/, label: "/v1/questions/:id/respond", methods: ["POST"] },
1557
- { id: "tool-approval-respond", pattern: /^\/v1\/tool-approvals\/(?<id>[^/]+)\/respond$/, label: "/v1/tool-approvals/:id/respond", methods: ["POST"] },
1558
- { id: "tool-approval-read", pattern: /^\/v1\/tool-approvals\/(?<id>[^/]+)$/, label: "/v1/tool-approvals/:id", methods: ["GET"] },
1559
1664
  { id: "task-ask-decision", pattern: /^\/v1\/tasks\/(?<taskId>[^/]+)\/asks\/(?<askId>[^/]+)\/decision$/, label: "/v1/tasks/:id/asks/:askId/decision", methods: ["POST"] },
1665
+ { id: "task-ask-read", pattern: /^\/v1\/tasks\/(?<taskId>[^/]+)\/asks\/(?<askId>[^/]+)$/, label: "/v1/tasks/:id/asks/:askId", methods: ["GET"] },
1560
1666
  ];
1561
1667
  //# sourceMappingURL=runs.js.map
@@ -9,10 +9,14 @@
9
9
  */
10
10
  import type { IncomingMessage, ServerResponse } from "node:http";
11
11
  import { type SessionRulesRecord, type FileHistoryExport } from "@sema-agent/core";
12
+ import { type VisibleBlobs } from "../../session-sync.js";
12
13
  import { type ImportAnchor, type StagingHandle } from "../../session-sync-kernel.js";
14
+ import { type ListFilter } from "../../owner-faces.js";
13
15
  import type { DurableOwnerKey } from "../../owner-brands.js";
16
+ import type { SyncLanding } from "../../plugins/store-backend.js";
14
17
  import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js";
15
18
  import { type SessionRowPatch } from "../../session-row.js";
19
+ import { type SessionFace } from "../../session-incarnation.js";
16
20
  export type PendingStaging = {
17
21
  handle: StagingHandle;
18
22
  realSessionId: string;
@@ -33,20 +37,29 @@ export type PendingStaging = {
33
37
  /** The principal that opened this staging, kept as the handle's owner key (`null` = a fleet caller opened it) — a different caller may not drive it
34
38
  * (404, no oracle; compared through `owner-faces.ts` `sameKey` only). */
35
39
  openedBy: DurableOwnerKey | null;
36
- /** The owner cell the gate judged when it opened this staging (head-read reading `headOf(id)?.owner`: `undefined` = no such session) — the commit lands only on
37
- * this same cell (`StagedCommitOptions.expectedOwner`, `session-sync-kernel.ts`); `owner` above (the re-stamped importing principal) is derived from it for a fleet caller. */
38
- expectedOwner: string | null | undefined;
40
+ /** The live occupant the gate judged when it opened this staging (owner ∧ incarnation, the head read: `undefined` = no live session) — the commit lands only on
41
+ * this same occupant (`StagedCommitOptions.expectedOccupant`, `session-sync-kernel.ts`); `owner` above (the re-stamped importing principal) is derived from its owner for a fleet caller. */
42
+ expectedOccupant: SessionFace | undefined;
39
43
  /** 开这张暂存时占下的导入租约的键({@link importLeaseKey});续期与放掉都按它,不再从会话 id 重算。 */
40
44
  leaseKey: string;
45
+ /** 第一阶段那一次可见性读的答案(落点 = 开暂存时门判的那一格):提交臂的文件历史重放只经它的取值口取字节 —— 许可集在第一阶段定,覆盖写的擦除不改它。 */
46
+ visible: VisibleBlobs;
41
47
  };
42
48
  /**
43
- * 导入租约的键 = 这次导入**落在哪一格属主上**(与提交的属主 CAS 同一格)+ 会话 id。一条读法:
44
- * · id 被占着(活行 ∪ 在删行 —— 「被占着」的唯一读法,门读的 `occupant`)⇒ 落点是住客的属主格(`null` = 无主):所有碰得到这一行的调用方(属主、fleet、存量无主互认)共一把 —— 同一份会话上第二份在飞导入,谁发起的都 409;
45
- * · id 空闲 ⇒ 还没有谁的会话,落点是这位调用方自己将成的属主(`importingPrincipal`):各占各的,先提交者得(提交的属主 CAS 要求那一格仍空着,输的那一份
46
- * 在提交前复判被拒)。一个主体的在飞导入既不挡、也不透给另一个主体 —— 租约键不含主体时,空闲 id 上任一主体都能占位,并从 409 读到「此 id 此刻有人在导」。
47
- * 键的主体只来自门读的 `occupant` 与 `importingPrincipal`(两者都派生自属主存取器的 `listFilterOf` 与门读的会话面,不另读调用方),且占租约在 `pushGateOk` 之后。
49
+ * 这次推送 / 拉取**落在哪一格**(落点)的唯一读法 —— 导入租约的键、blob 授予(`PUT …/sync/blobs/:hash`)、blob 可见性(第一阶段预检 · 重放取值 · `GET …/sync/history/blobs/:hash`)同读它:
50
+ * · id 被占着(活行 ∪ 在删行 —— 「被占着」的唯一读法,门读的 `occupant`)⇒ 落点是住客的属主格(`null` = 无主):所有碰得到这一行的调用方(属主、fleet、存量无主互认)落在同一格;
51
+ * · id 空闲 ⇒ 还没有谁的会话,落点是这位调用方自己将成的属主(fleet ⇒ 无主格;主体 ⇒ 主体):各落各的,先提交者得(提交的属主 CAS 要求那一格仍空着)。
52
+ * `occupied` 随落点走:只有被占着的 id,它的历史图才是 blob 的来历(空闲 id 上残留的图不是任何一位调用方持有过字节的证明)。
53
+ * 落点的主体只来自门读的 `occupant` 与 `listFilterOf` 的派生,不另读调用方;拉取口只在活行上放行(`pullGateOk`),那时 `occupant` 就是活行。
48
54
  */
49
- export declare function importLeaseKey(landingOwner: string | null, sessionId: string): string;
55
+ export declare function landingOf(gate: {
56
+ readonly occupant: SessionFace | undefined;
57
+ }, scope: ListFilter, sessionId: string): SyncLanding;
58
+ /**
59
+ * 导入租约的键 = 这次导入的落点({@link landingOf}):落点属主格 + 会话 id。同一份会话上第二份在飞导入,谁发起的都 409(同一格);空闲 id 上一个主体的在飞导入既不挡、也不透给
60
+ * 另一个主体 —— 租约键不含落点属主格时,空闲 id 上任一主体都能占位,并从 409 读到「此 id 此刻有人在导」。占租约在 `pushGateOk` 之后。
61
+ */
62
+ export declare function importLeaseKey(landing: SyncLanding): string;
50
63
  /** 一把导入租约:最后活动时刻 + 持有它的暂存 + 它守的会话 id(清扫与运维日志用,不从键里反解)。 */
51
64
  export type ImportLease = {
52
65
  at: number;