@sema-agent/server 7.147.0 → 7.148.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 (725) hide show
  1. package/MIGRATION.md +1039 -24
  2. package/README.md +20 -7
  3. package/README.zh-CN.md +14 -8
  4. package/USAGE.md +380 -163
  5. package/deploy/sema-up/README.md +16 -5
  6. package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
  7. package/deploy/sema-up/chart/templates/_helpers.tpl +20 -4
  8. package/deploy/sema-up/chart/values.yaml +3 -2
  9. package/deploy/sema-up/cluster-up.sh +74 -176
  10. package/deploy/sema-up/kube-up.sh +29 -49
  11. package/deploy/sema-up/lib/chart-run.sh +23 -0
  12. package/deploy/sema-up/lib/dataroot.sh +3 -3
  13. package/deploy/sema-up/lib/health.sh +62 -13
  14. package/deploy/sema-up/lib/helm-values-cluster.py +18 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +35 -0
  16. package/deploy/sema-up/lib/regcred.py +8 -0
  17. package/deploy/sema-up/lib/remote/helm-install.sh +3 -0
  18. package/deploy/sema-up/lib/remote/image-import.sh +6 -0
  19. package/deploy/sema-up/lib/remote/machine-precheck.sh +11 -0
  20. package/deploy/sema-up/lib/remote/region-probe.sh +3 -0
  21. package/deploy/sema-up/lib/remote/stack-ready.sh +26 -0
  22. package/deploy/sema-up/lib/remote/vxlan-guard.sh +8 -0
  23. package/deploy/sema-up/lib/render-stack.py +17 -0
  24. package/deploy/sema-up/lib/shell-text.sh +87 -0
  25. package/deploy/sema-up/lib/usage-flags.txt +10 -0
  26. package/deploy/sema-up/lib/usage-head.txt +1 -0
  27. package/deploy/sema-up/lib/usage-tail.txt +13 -0
  28. package/deploy/sema-up/preflight.sh +10 -8
  29. package/deploy/sema-up/sema-up.sh +14 -39
  30. package/deploy/sema-up/smoke.sh +7 -6
  31. package/deploy/sema-up/stack/compose.dataroot.yaml +3 -0
  32. package/deploy/sema-up/stack/compose.yaml +13 -1
  33. package/deploy/sema-up/stack/sema-stack-cluster.yaml +21 -0
  34. package/dist/adoption/plan.d.ts +24 -0
  35. package/dist/adoption/plan.js +53 -1
  36. package/dist/adoption/runner.d.ts +10 -1
  37. package/dist/adoption/runner.js +36 -16
  38. package/dist/adoption/wire.d.ts +3 -3
  39. package/dist/approval-card.d.ts +28 -30
  40. package/dist/approval-gate-currency.js +3 -2
  41. package/dist/approval-reconciler.d.ts +4 -13
  42. package/dist/approval-reconciler.js +2 -2
  43. package/dist/approval.d.ts +13 -11
  44. package/dist/approval.js +3 -3
  45. package/dist/audit.d.ts +10 -3
  46. package/dist/audit.js +15 -7
  47. package/dist/auth-bridge.d.ts +0 -14
  48. package/dist/auth-bridge.js +0 -7
  49. package/dist/auto-mode-face.d.ts +10 -7
  50. package/dist/auto-mode-face.js +7 -4
  51. package/dist/background-agent-name.d.ts +19 -1
  52. package/dist/background-agent-name.js +12 -2
  53. package/dist/background-session-reap.d.ts +1 -1
  54. package/dist/bake-runner/main.js +9 -6
  55. package/dist/bench/s1/arms.js +6 -5
  56. package/dist/bench/s1/live-deps.js +5 -2
  57. package/dist/bench/s1/run-firm.js +6 -5
  58. package/dist/bind-host.d.ts +25 -0
  59. package/dist/bind-host.js +25 -0
  60. package/dist/boot/adoption.d.ts +3 -0
  61. package/dist/boot/adoption.js +1 -0
  62. package/dist/boot/deployment-mods.d.ts +1 -1
  63. package/dist/boot/execution-env.d.ts +17 -7
  64. package/dist/boot/execution-env.js +37 -31
  65. package/dist/boot/exit-boundary.d.ts +2 -2
  66. package/dist/boot/exit-boundary.js +6 -5
  67. package/dist/boot/fatal-exit.d.ts +3 -5
  68. package/dist/boot/fatal-exit.js +2 -2
  69. package/dist/boot/leader.d.ts +15 -0
  70. package/dist/boot/leader.js +17 -15
  71. package/dist/boot/memory-consolidation.d.ts +37 -29
  72. package/dist/boot/memory-consolidation.js +11 -5
  73. package/dist/boot/org-memory.js +1 -1
  74. package/dist/boot/parked-revive-gate.js +2 -2
  75. package/dist/boot/reapers.d.ts +4 -3
  76. package/dist/boot/reapers.js +19 -16
  77. package/dist/boot/resolve-spec.d.ts +5 -3
  78. package/dist/boot/resolve-spec.js +55 -67
  79. package/dist/boot/retention-lane.d.ts +4 -4
  80. package/dist/boot/retention-lane.js +2 -2
  81. package/dist/boot/runner-deps.d.ts +28 -7
  82. package/dist/boot/runner-deps.js +11 -4
  83. package/dist/boot/runtime-caps.d.ts +2 -2
  84. package/dist/boot/runtime-caps.js +16 -2
  85. package/dist/boot/session-faces.d.ts +16 -7
  86. package/dist/boot/session-faces.js +114 -94
  87. package/dist/boot/shutdown.d.ts +5 -4
  88. package/dist/boot/shutdown.js +6 -4
  89. package/dist/boot/stage-01-config.js +9 -1
  90. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  91. package/dist/boot/stage-02-web-admin-pull.js +6 -1
  92. package/dist/boot/stage-03-store-backend.d.ts +3 -0
  93. package/dist/boot/stage-03-store-backend.js +4 -3
  94. package/dist/boot/stage-04-stores.d.ts +2 -0
  95. package/dist/boot/stage-04-stores.js +2 -2
  96. package/dist/boot/stage-05-execution-env.d.ts +7 -3
  97. package/dist/boot/stage-05-execution-env.js +2 -2
  98. package/dist/boot/stage-06-runners.d.ts +10 -12
  99. package/dist/boot/stage-06-runners.js +23 -15
  100. package/dist/boot/stage-07-capability-layer.d.ts +11 -8
  101. package/dist/boot/stage-07-capability-layer.js +5 -3
  102. package/dist/boot/stage-08-reapers.d.ts +11 -8
  103. package/dist/boot/stage-08-reapers.js +3 -3
  104. package/dist/boot/stage-09-leader.d.ts +12 -15
  105. package/dist/boot/stage-09-leader.js +12 -4
  106. package/dist/boot/stage-10-http-server.d.ts +12 -15
  107. package/dist/boot/stage-10-http-server.js +7 -4
  108. package/dist/boot/store-evidence.d.ts +20 -0
  109. package/dist/boot/store-evidence.js +13 -0
  110. package/dist/boot/stores.d.ts +3 -0
  111. package/dist/boot/stores.js +21 -10
  112. package/dist/boot/task-list-lane.d.ts +4 -4
  113. package/dist/boot/web-admin.d.ts +4 -2
  114. package/dist/boot/web-admin.js +55 -35
  115. package/dist/boot/webfetch-summarize-lane.d.ts +1 -1
  116. package/dist/boot-reclaim.d.ts +3 -1
  117. package/dist/boot-reclaim.js +1 -1
  118. package/dist/brain.d.ts +7 -18
  119. package/dist/brain.js +5 -17
  120. package/dist/budget.js +6 -6
  121. package/dist/capabilities/center-plugins.d.ts +7 -1
  122. package/dist/capabilities/center-plugins.js +32 -10
  123. package/dist/capabilities/center-wiring.js +1 -1
  124. package/dist/capabilities/composite-members.d.ts +2 -2
  125. package/dist/capabilities/composite-members.js +2 -2
  126. package/dist/capabilities/repo-tools.d.ts +2 -0
  127. package/dist/capabilities/repo-tools.js +14 -12
  128. package/dist/capabilities/scenarios.d.ts +6 -15
  129. package/dist/capabilities/scenarios.js +11 -16
  130. package/dist/capabilities/skills.d.ts +1 -1
  131. package/dist/capabilities/tool-defer.d.ts +1 -1
  132. package/dist/capability-facts.d.ts +38 -11
  133. package/dist/capability-facts.js +47 -8
  134. package/dist/card-void.d.ts +4 -4
  135. package/dist/card-void.js +1 -1
  136. package/dist/center-credential-renewer.d.ts +6 -2
  137. package/dist/center-credential-renewer.js +7 -3
  138. package/dist/config-catalog.d.ts +16 -1
  139. package/dist/config-catalog.js +62 -56
  140. package/dist/config-dir-trust.d.ts +37 -4
  141. package/dist/config-dir-trust.js +88 -44
  142. package/dist/config-invariants.d.ts +42 -3
  143. package/dist/config-invariants.js +69 -5
  144. package/dist/config-lkg.d.ts +23 -1
  145. package/dist/config-lkg.js +17 -3
  146. package/dist/config-provider.d.ts +9 -9
  147. package/dist/config-provider.js +25 -110
  148. package/dist/config-pull-failure.d.ts +50 -0
  149. package/dist/config-pull-failure.js +48 -0
  150. package/dist/config-types.d.ts +26 -17
  151. package/dist/config.d.ts +8 -16
  152. package/dist/config.js +113 -47
  153. package/dist/delegated-session-owner.d.ts +1 -1
  154. package/dist/deleted-session-ids.d.ts +3 -2
  155. package/dist/deployment-governance.d.ts +3 -3
  156. package/dist/deployment-shape.d.ts +30 -4
  157. package/dist/deployment-shape.js +7 -0
  158. package/dist/egress-redirect.d.ts +25 -7
  159. package/dist/egress-redirect.js +20 -2
  160. package/dist/elicitation.d.ts +6 -5
  161. package/dist/elicitation.js +23 -22
  162. package/dist/engine-identity.d.ts +28 -0
  163. package/dist/engine-identity.js +10 -0
  164. package/dist/entry-problems.d.ts +5 -7
  165. package/dist/entry-problems.js +1 -1
  166. package/dist/env-facts.js +2 -1
  167. package/dist/env-witness.d.ts +7 -0
  168. package/dist/env-witness.js +16 -0
  169. package/dist/execution-lane-caps.d.ts +5 -18
  170. package/dist/execution-lane-caps.js +0 -22
  171. package/dist/execution-placement.d.ts +58 -18
  172. package/dist/execution-placement.js +41 -2
  173. package/dist/field-conflict.d.ts +7 -11
  174. package/dist/field-conflict.js +3 -3
  175. package/dist/file-history-capture.d.ts +3 -3
  176. package/dist/file-history-disclosure.js +1 -0
  177. package/dist/fleet/fleet-bus.d.ts +21 -3
  178. package/dist/fleet/fleet-bus.js +35 -25
  179. package/dist/fleet/fleet-reconciler.js +2 -2
  180. package/dist/fleet/serving-lease.js +3 -3
  181. package/dist/fleet-client.js +3 -3
  182. package/dist/fleet-lease.d.ts +0 -1
  183. package/dist/fleet-lease.js +4 -5
  184. package/dist/history-anchor.d.ts +23 -3
  185. package/dist/history-anchor.js +24 -4
  186. package/dist/hitl-delivery.d.ts +90 -0
  187. package/dist/hitl-delivery.js +98 -0
  188. package/dist/hooks/classic-stations.d.ts +8 -11
  189. package/dist/hooks/classic-stations.js +0 -7
  190. package/dist/hooks/hook-llm.d.ts +5 -1
  191. package/dist/hooks/hook-llm.js +24 -15
  192. package/dist/hooks/hook-runner.d.ts +67 -57
  193. package/dist/hooks/hook-runner.js +260 -186
  194. package/dist/host-lsp-manager.d.ts +22 -8
  195. package/dist/host-lsp-manager.js +4 -1
  196. package/dist/http/active-run-conflict.d.ts +2 -43
  197. package/dist/http/active-run-conflict.js +3 -7
  198. package/dist/http/admission.d.ts +4 -18
  199. package/dist/http/admission.js +75 -78
  200. package/dist/http/approval-sweeps.d.ts +3 -3
  201. package/dist/http/approval-sweeps.js +54 -30
  202. package/dist/http/caller-trust.d.ts +8 -10
  203. package/dist/http/caller-trust.js +1 -2
  204. package/dist/http/claim-heartbeat.d.ts +49 -0
  205. package/dist/http/claim-heartbeat.js +46 -0
  206. package/dist/http/claimed-run.d.ts +4 -3
  207. package/dist/http/dispatch.d.ts +8 -1
  208. package/dist/http/dispatch.js +76 -30
  209. package/dist/http/durable-run-leg.d.ts +3 -3
  210. package/dist/http/durable-run-leg.js +17 -12
  211. package/dist/http/execution-context.d.ts +17 -43
  212. package/dist/http/execution-context.js +7 -5
  213. package/dist/http/health-reader.d.ts +36 -0
  214. package/dist/http/health-reader.js +21 -0
  215. package/dist/http/health-self-report.d.ts +9 -9
  216. package/dist/http/health-self-report.js +4 -4
  217. package/dist/http/idempotency.d.ts +9 -5
  218. package/dist/http/idempotency.js +4 -4
  219. package/dist/http/memory-compliance-failure-reply.d.ts +15 -16
  220. package/dist/http/memory-compliance-failure-reply.js +4 -2
  221. package/dist/http/memory-face-fault-reply.d.ts +67 -0
  222. package/dist/http/memory-face-fault-reply.js +71 -0
  223. package/dist/http/memory-store-refusal-reply.d.ts +1 -1
  224. package/dist/http/memory-store-refusal-reply.js +3 -0
  225. package/dist/http/owner-access.d.ts +391 -67
  226. package/dist/http/owner-access.js +371 -35
  227. package/dist/http/principal-gate.d.ts +24 -81
  228. package/dist/http/principal-gate.js +24 -68
  229. package/dist/http/refusal-body.d.ts +35 -2
  230. package/dist/http/refusal-body.js +34 -0
  231. package/dist/http/request-guards.d.ts +9 -13
  232. package/dist/http/request-guards.js +34 -68
  233. package/dist/http/resume-composition.d.ts +37 -0
  234. package/dist/http/resume-composition.js +18 -0
  235. package/dist/http/resume-ctx-read.d.ts +35 -12
  236. package/dist/http/resume-ctx-read.js +25 -6
  237. package/dist/http/resume-legs.d.ts +21 -18
  238. package/dist/http/resume-legs.js +189 -129
  239. package/dist/http/retired-skill-manifest.d.ts +1 -1
  240. package/dist/http/route-ctx.d.ts +25 -32
  241. package/dist/http/routes/a2a-serve.d.ts +43 -5
  242. package/dist/http/routes/a2a-serve.js +58 -37
  243. package/dist/http/routes/admin-config-refresh.js +2 -2
  244. package/dist/http/routes/admin-drain.js +2 -2
  245. package/dist/http/routes/admin-memory-optout.js +4 -3
  246. package/dist/http/routes/adoption.d.ts +3 -0
  247. package/dist/http/routes/adoption.js +17 -10
  248. package/dist/http/routes/agents-roster.js +13 -7
  249. package/dist/http/routes/approvals-assistant.js +70 -65
  250. package/dist/http/routes/attachments.js +2 -2
  251. package/dist/http/routes/background.d.ts +3 -3
  252. package/dist/http/routes/background.js +9 -17
  253. package/dist/http/routes/capabilities.js +15 -18
  254. package/dist/http/routes/config-catalog.js +2 -2
  255. package/dist/http/routes/devices.d.ts +3 -3
  256. package/dist/http/routes/devices.js +4 -4
  257. package/dist/http/routes/diagnostics.d.ts +27 -3
  258. package/dist/http/routes/diagnostics.js +27 -21
  259. package/dist/http/routes/engine.js +2 -2
  260. package/dist/http/routes/fleet.js +5 -3
  261. package/dist/http/routes/images.js +10 -6
  262. package/dist/http/routes/leader.d.ts +7 -2
  263. package/dist/http/routes/leader.js +12 -3
  264. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  265. package/dist/http/routes/mcp-reconnect.js +7 -15
  266. package/dist/http/routes/memory-bundle.js +4 -7
  267. package/dist/http/routes/memory-compliance.js +4 -4
  268. package/dist/http/routes/memory-consolidation.js +6 -9
  269. package/dist/http/routes/memory-origin.d.ts +2 -0
  270. package/dist/http/routes/memory-origin.js +7 -8
  271. package/dist/http/routes/memory-policy.js +17 -12
  272. package/dist/http/routes/notify-wake.js +10 -19
  273. package/dist/http/routes/observability.js +3 -3
  274. package/dist/http/routes/principal-inbox.d.ts +1 -1
  275. package/dist/http/routes/principal-inbox.js +2 -2
  276. package/dist/http/routes/projects.d.ts +1 -1
  277. package/dist/http/routes/projects.js +3 -2
  278. package/dist/http/routes/retention-ops.js +6 -9
  279. package/dist/http/routes/rules.js +20 -5
  280. package/dist/http/routes/run-memory-capture.d.ts +2 -2
  281. package/dist/http/routes/run-memory-capture.js +6 -12
  282. package/dist/http/routes/run-permission-mode.d.ts +2 -2
  283. package/dist/http/routes/run-permission-mode.js +10 -17
  284. package/dist/http/routes/runs.js +146 -231
  285. package/dist/http/routes/session-memory-sync.d.ts +2 -2
  286. package/dist/http/routes/session-memory-sync.js +7 -13
  287. package/dist/http/routes/session-sync.d.ts +4 -2
  288. package/dist/http/routes/session-sync.js +21 -20
  289. package/dist/http/routes/sessions-list.d.ts +3 -3
  290. package/dist/http/routes/sessions-list.js +9 -9
  291. package/dist/http/routes/sessions.js +87 -124
  292. package/dist/http/routes/shared-memory.js +6 -6
  293. package/dist/http/routes/side-query.js +2 -2
  294. package/dist/http/routes/tasks.js +136 -120
  295. package/dist/http/routes/trace-usage.d.ts +0 -12
  296. package/dist/http/routes/trace-usage.js +40 -46
  297. package/dist/http/routes/workflows.d.ts +39 -4
  298. package/dist/http/routes/workflows.js +42 -14
  299. package/dist/http/run-concurrency-cap.d.ts +20 -12
  300. package/dist/http/run-concurrency-cap.js +39 -26
  301. package/dist/http/run-read-face.d.ts +3 -5
  302. package/dist/http/run-read-face.js +8 -13
  303. package/dist/http/send.d.ts +12 -3
  304. package/dist/http/send.js +42 -6
  305. package/dist/http/server.d.ts +39 -40
  306. package/dist/http/server.js +36 -11
  307. package/dist/http/sse-log.d.ts +17 -10
  308. package/dist/http/sse-log.js +7 -7
  309. package/dist/http/stored-body-replay.d.ts +12 -0
  310. package/dist/http/stored-body-replay.js +2 -2
  311. package/dist/http/submit-ctx.d.ts +16 -8
  312. package/dist/http/submit-ctx.js +6 -2
  313. package/dist/http/submit-replay.d.ts +19 -6
  314. package/dist/http/submit-replay.js +18 -6
  315. package/dist/http/sync-submit-body.d.ts +3 -4
  316. package/dist/http/sync-submit-body.js +4 -5
  317. package/dist/http/wire-types.d.ts +4 -3
  318. package/dist/identity-source.d.ts +36 -5
  319. package/dist/identity-source.js +27 -0
  320. package/dist/index.d.ts +1 -0
  321. package/dist/index.js +1 -0
  322. package/dist/key-resolver.d.ts +32 -0
  323. package/dist/key-resolver.js +23 -9
  324. package/dist/leader/diffup.js +2 -1
  325. package/dist/leader/endpoint.d.ts +26 -5
  326. package/dist/leader/endpoint.js +154 -14
  327. package/dist/leader/fanout.d.ts +3 -0
  328. package/dist/leader/fanout.js +78 -63
  329. package/dist/leader/leader.d.ts +16 -0
  330. package/dist/leader/leader.js +43 -3
  331. package/dist/leader/merge.d.ts +9 -1
  332. package/dist/leader/merge.js +16 -1
  333. package/dist/leader/repair-wire.js +1 -1
  334. package/dist/leader/wire.d.ts +36 -3
  335. package/dist/leader/wire.js +59 -18
  336. package/dist/lsp-evict.d.ts +6 -4
  337. package/dist/lsp-evict.js +2 -3
  338. package/dist/memory-operator-faces.d.ts +5 -4
  339. package/dist/memory-operator-faces.js +1 -1
  340. package/dist/memory-scope.d.ts +29 -2
  341. package/dist/memory-scope.js +64 -15
  342. package/dist/memory-store-refusal.d.ts +5 -2
  343. package/dist/memory-sync-client.d.ts +3 -2
  344. package/dist/memory-sync-client.js +6 -3
  345. package/dist/model-compat.d.ts +17 -8
  346. package/dist/model-compat.js +6 -2
  347. package/dist/model-context-window.d.ts +18 -0
  348. package/dist/model-context-window.js +2 -0
  349. package/dist/model-entry-headers.d.ts +46 -4
  350. package/dist/model-entry-headers.js +2 -2
  351. package/dist/model-entry-refusal.d.ts +35 -16
  352. package/dist/model-entry-refusal.js +40 -27
  353. package/dist/model-plane-face.d.ts +19 -11
  354. package/dist/model-plane-face.js +9 -1
  355. package/dist/model-plane-probe.d.ts +2 -0
  356. package/dist/model-plane-probe.js +17 -0
  357. package/dist/model-provider.d.ts +3 -3
  358. package/dist/model-route-endpoint.d.ts +9 -5
  359. package/dist/model-route-endpoint.js +29 -7
  360. package/dist/model-select.d.ts +16 -0
  361. package/dist/model-select.js +4 -0
  362. package/dist/mountinfo.d.ts +37 -0
  363. package/dist/mountinfo.js +47 -0
  364. package/dist/namespaced-rule-name.d.ts +23 -14
  365. package/dist/namespaced-rule-name.js +8 -11
  366. package/dist/net-address.d.ts +1 -1
  367. package/dist/observability/corrupt-read-seat.d.ts +4 -4
  368. package/dist/observability/corrupt-read-seat.js +5 -3
  369. package/dist/observability/fail-open.d.ts +58 -38
  370. package/dist/observability/fail-open.js +60 -38
  371. package/dist/observability/logger.d.ts +22 -1
  372. package/dist/observability/logger.js +89 -12
  373. package/dist/observability/metrics.js +3 -4
  374. package/dist/observability/otel-exporter.js +2 -1
  375. package/dist/observability/principal-context.d.ts +14 -7
  376. package/dist/observability/principal-context.js +8 -3
  377. package/dist/observability/run-terminal.d.ts +7 -1
  378. package/dist/observability/run-terminal.js +5 -2
  379. package/dist/orchestration/hardened-vm-runner.d.ts +1 -0
  380. package/dist/orchestration/hardened-vm-runner.js +11 -5
  381. package/dist/orchestration/hardened-vm-worker-runner.d.ts +0 -14
  382. package/dist/orchestration/hardened-vm-worker-runner.js +5 -0
  383. package/dist/orchestration/hardened-vm-worker.js +2 -1
  384. package/dist/orchestration/workflow-completion-inbox.d.ts +3 -3
  385. package/dist/orchestration/workflow-completion-inbox.js +3 -2
  386. package/dist/org-delivery-gate.d.ts +5 -4
  387. package/dist/org-delivery-gate.js +7 -6
  388. package/dist/outbound-dispatcher.d.ts +1 -1
  389. package/dist/outbound-dispatcher.js +6 -12
  390. package/dist/owner-brands.d.ts +81 -0
  391. package/dist/owner-brands.js +42 -0
  392. package/dist/owner-faces.d.ts +531 -0
  393. package/dist/owner-faces.js +126 -0
  394. package/dist/parked-decide.d.ts +67 -5
  395. package/dist/parked-decide.js +127 -5
  396. package/dist/parked-revive-surface.d.ts +14 -4
  397. package/dist/parked-revive-surface.js +5 -4
  398. package/dist/peer-directory.d.ts +6 -8
  399. package/dist/peer-directory.js +3 -2
  400. package/dist/permission-rule-vocab.d.ts +53 -8
  401. package/dist/permission-rule-vocab.js +30 -2
  402. package/dist/plugins/adoption-log-sql.d.ts +0 -22
  403. package/dist/plugins/adoption-log-sql.js +5 -3
  404. package/dist/plugins/approval-ask-retired-delete-by-task-m50.d.ts +7 -0
  405. package/dist/plugins/approval-ask-retired-delete-by-task-m50.js +17 -0
  406. package/dist/plugins/approval-ask-store-file.d.ts +18 -7
  407. package/dist/plugins/approval-ask-store-file.js +37 -14
  408. package/dist/plugins/approval-ask-store-memory.d.ts +12 -4
  409. package/dist/plugins/approval-ask-store-memory.js +24 -10
  410. package/dist/plugins/approval-ask-store-sql.d.ts +39 -20
  411. package/dist/plugins/approval-ask-store-sql.js +41 -10
  412. package/dist/plugins/approval-exemption-skill-m46.d.ts +20 -0
  413. package/dist/plugins/approval-exemption-skill-m46.js +25 -0
  414. package/dist/plugins/approval-exemption-store.d.ts +6 -1
  415. package/dist/plugins/approval-exemption-store.js +14 -0
  416. package/dist/plugins/approval-nonce-store.d.ts +39 -12
  417. package/dist/plugins/approval-nonce-store.js +72 -23
  418. package/dist/plugins/blob-backend.d.ts +2 -0
  419. package/dist/plugins/blob-backend.js +9 -6
  420. package/dist/plugins/caching-session-store.d.ts +13 -1
  421. package/dist/plugins/caching-session-store.js +43 -4
  422. package/dist/plugins/checkpoint-index-columns.d.ts +32 -5
  423. package/dist/plugins/checkpoint-index-columns.js +36 -1
  424. package/dist/plugins/checkpoint-store-face.d.ts +83 -10
  425. package/dist/plugins/checkpoint-store-face.js +18 -1
  426. package/dist/plugins/device-store-sql.js +1 -0
  427. package/dist/plugins/ensure-index.d.ts +13 -1
  428. package/dist/plugins/ensure-index.js +154 -21
  429. package/dist/plugins/ensure-schema-lock-policy.d.ts +0 -15
  430. package/dist/plugins/ensure-schema-lock-policy.js +3 -2
  431. package/dist/plugins/file-run-store.d.ts +63 -23
  432. package/dist/plugins/file-run-store.js +138 -83
  433. package/dist/plugins/host-platform.d.ts +24 -3
  434. package/dist/plugins/host-platform.js +15 -1
  435. package/dist/plugins/image-bake-store-sql.js +2 -0
  436. package/dist/plugins/imported-layer-root-retirement.d.ts +2 -2
  437. package/dist/plugins/k8s-pod-reaper.d.ts +1 -3
  438. package/dist/plugins/k8s-pod-reaper.js +0 -1
  439. package/dist/plugins/leader-run-store-sql.d.ts +22 -0
  440. package/dist/plugins/leader-run-store-sql.js +34 -4
  441. package/dist/plugins/local-checkpoint-store.d.ts +58 -23
  442. package/dist/plugins/local-checkpoint-store.js +195 -76
  443. package/dist/plugins/local-data-dir-modes-m39.js +2 -1
  444. package/dist/plugins/local-docker-capacity.d.ts +93 -0
  445. package/dist/plugins/local-docker-capacity.js +194 -0
  446. package/dist/plugins/local-docker-reaper.d.ts +92 -0
  447. package/dist/plugins/local-docker-reaper.js +102 -0
  448. package/dist/plugins/local-engine-high-water.d.ts +4 -2
  449. package/dist/plugins/local-engine-high-water.js +4 -1
  450. package/dist/plugins/local-session-store.d.ts +358 -125
  451. package/dist/plugins/local-session-store.js +824 -251
  452. package/dist/plugins/local-session-window.d.ts +3 -2
  453. package/dist/plugins/local-session-window.js +3 -2
  454. package/dist/plugins/local-sidecar-quarantine.js +3 -2
  455. package/dist/plugins/local-task-attachment-store.d.ts +18 -1
  456. package/dist/plugins/local-task-attachment-store.js +22 -1
  457. package/dist/plugins/memory-embedder.js +9 -7
  458. package/dist/plugins/memory-engine-pg.d.ts +3 -2
  459. package/dist/plugins/memory-engine-pg.js +14 -5
  460. package/dist/plugins/memory-engine-sql-apply.d.ts +8 -4
  461. package/dist/plugins/memory-engine-sql-apply.js +6 -8
  462. package/dist/plugins/memory-engine-tidb.d.ts +4 -2
  463. package/dist/plugins/memory-engine-tidb.js +11 -2
  464. package/dist/plugins/memory-optout-grant-store-sql.d.ts +1 -1
  465. package/dist/plugins/memory-optout-grant-store-sql.js +3 -3
  466. package/dist/plugins/memory-run-store.d.ts +39 -27
  467. package/dist/plugins/memory-run-store.js +72 -70
  468. package/dist/plugins/one-time-migration-marker.d.ts +10 -0
  469. package/dist/plugins/one-time-migration-marker.js +7 -0
  470. package/dist/plugins/one-time-migrations.d.ts +186 -45
  471. package/dist/plugins/one-time-migrations.js +442 -119
  472. package/dist/plugins/org-delivery-quota-store.js +2 -1
  473. package/dist/plugins/permission-rule-store-file.d.ts +3 -3
  474. package/dist/plugins/permission-rule-store-sql.d.ts +4 -63
  475. package/dist/plugins/permission-rule-store-sql.js +6 -86
  476. package/dist/plugins/pg-pool.d.ts +1 -31
  477. package/dist/plugins/pg-pool.js +16 -7
  478. package/dist/plugins/remote-env-e2b.d.ts +7 -25
  479. package/dist/plugins/remote-env-e2b.js +34 -25
  480. package/dist/plugins/remote-env-host.d.ts +2 -9
  481. package/dist/plugins/remote-env-host.js +34 -22
  482. package/dist/plugins/remote-env-k8s.d.ts +40 -45
  483. package/dist/plugins/remote-env-k8s.js +107 -58
  484. package/dist/plugins/remote-env-local-docker.d.ts +148 -14
  485. package/dist/plugins/remote-env-local-docker.js +367 -72
  486. package/dist/plugins/remote-scratchpad.js +4 -0
  487. package/dist/plugins/retention-deployment.d.ts +49 -17
  488. package/dist/plugins/retention-deployment.js +39 -8
  489. package/dist/plugins/run-preview-m45.d.ts +11 -0
  490. package/dist/plugins/run-preview-m45.js +19 -0
  491. package/dist/plugins/run-store-sql.d.ts +56 -68
  492. package/dist/plugins/run-store-sql.js +127 -116
  493. package/dist/plugins/s3-answer.d.ts +2 -1
  494. package/dist/plugins/sandbox-reaper.d.ts +26 -0
  495. package/dist/plugins/sandbox-reaper.js +2 -0
  496. package/dist/plugins/scenario-prefix-switch-m42.d.ts +54 -0
  497. package/dist/plugins/scenario-prefix-switch-m42.js +55 -0
  498. package/dist/plugins/scheduler-support.d.ts +16 -1
  499. package/dist/plugins/scheduler-support.js +22 -2
  500. package/dist/plugins/schema-consistency.d.ts +42 -9
  501. package/dist/plugins/schema-consistency.js +212 -11
  502. package/dist/plugins/schema-drift-sentence.d.ts +4 -1
  503. package/dist/plugins/schema-drift-sentence.js +4 -4
  504. package/dist/plugins/schema-ensure-legs.d.ts +9 -0
  505. package/dist/plugins/schema-ensure-legs.js +1 -1
  506. package/dist/plugins/schema-indexes.js +3 -0
  507. package/dist/plugins/schema-live-columns.d.ts +14 -5
  508. package/dist/plugins/schema-live-columns.js +10 -10
  509. package/dist/plugins/send-user-file.js +2 -1
  510. package/dist/plugins/session-birth.d.ts +37 -0
  511. package/dist/plugins/session-birth.js +38 -0
  512. package/dist/plugins/session-epoch-anchor.d.ts +40 -12
  513. package/dist/plugins/session-epoch-anchor.js +33 -11
  514. package/dist/plugins/session-ext-table.d.ts +27 -3
  515. package/dist/plugins/session-ext-table.js +19 -6
  516. package/dist/plugins/session-fork.d.ts +15 -1
  517. package/dist/plugins/session-fork.js +3 -0
  518. package/dist/plugins/session-ownership.d.ts +1 -1
  519. package/dist/plugins/session-placement.d.ts +22 -16
  520. package/dist/plugins/session-placement.js +15 -12
  521. package/dist/plugins/session-row-sql.d.ts +12 -0
  522. package/dist/plugins/session-row-sql.js +3 -3
  523. package/dist/plugins/session-run-rollup.d.ts +29 -0
  524. package/dist/plugins/session-run-rollup.js +40 -0
  525. package/dist/plugins/session-store-sql.d.ts +38 -12
  526. package/dist/plugins/session-store-sql.js +130 -30
  527. package/dist/plugins/session-withdraw-sql.d.ts +36 -0
  528. package/dist/plugins/session-withdraw-sql.js +42 -0
  529. package/dist/plugins/shared-memory-store-sql.d.ts +0 -69
  530. package/dist/plugins/shared-memory-store-sql.js +2 -1
  531. package/dist/plugins/shell-sentinel-owner-m48.d.ts +20 -0
  532. package/dist/plugins/shell-sentinel-owner-m48.js +3 -0
  533. package/dist/plugins/snapshot-bucket-presence.d.ts +2 -1
  534. package/dist/plugins/sql-driver.d.ts +1 -1
  535. package/dist/plugins/sql-driver.js +2 -1
  536. package/dist/plugins/sql-errors.d.ts +32 -5
  537. package/dist/plugins/sql-errors.js +55 -7
  538. package/dist/plugins/sql-json-column.d.ts +8 -7
  539. package/dist/plugins/sql-json-column.js +10 -6
  540. package/dist/plugins/store-backend.d.ts +84 -15
  541. package/dist/plugins/store-backend.js +186 -55
  542. package/dist/plugins/store-contracts.d.ts +90 -30
  543. package/dist/plugins/store-contracts.js +22 -1
  544. package/dist/plugins/store-fault.d.ts +28 -2
  545. package/dist/plugins/store-fault.js +20 -2
  546. package/dist/plugins/task-attachment-store.d.ts +15 -3
  547. package/dist/plugins/task-attachment-store.js +22 -9
  548. package/dist/plugins/tidb-pool.js +23 -8
  549. package/dist/plugins/web-search.js +5 -3
  550. package/dist/plugins/workflow-run-store-sql.d.ts +6 -1
  551. package/dist/plugins/workflow-run-store-sql.js +11 -5
  552. package/dist/principal-jwt.d.ts +4 -4
  553. package/dist/principal-jwt.js +20 -5
  554. package/dist/principal-shape.d.ts +41 -0
  555. package/dist/principal-shape.js +19 -0
  556. package/dist/question.d.ts +13 -23
  557. package/dist/question.js +21 -39
  558. package/dist/request-declaration-refusal.d.ts +35 -12
  559. package/dist/request-declaration-refusal.js +21 -9
  560. package/dist/request-form.d.ts +58 -0
  561. package/dist/request-form.js +72 -0
  562. package/dist/request-image-urls.d.ts +8 -2
  563. package/dist/request-image-urls.js +2 -1
  564. package/dist/request-images.d.ts +20 -0
  565. package/dist/request-images.js +59 -0
  566. package/dist/request-key-closure.d.ts +6 -7
  567. package/dist/request-key-closure.js +15 -2
  568. package/dist/resource-suspend.d.ts +7 -16
  569. package/dist/resource-suspend.js +1 -1
  570. package/dist/retired-name-host-notice.d.ts +21 -0
  571. package/dist/retired-name-host-notice.js +12 -0
  572. package/dist/rule-entry-list.d.ts +2 -2
  573. package/dist/rule-entry-list.js +3 -4
  574. package/dist/rule-issue-reading.d.ts +58 -0
  575. package/dist/rule-issue-reading.js +14 -0
  576. package/dist/rules-consent.d.ts +5 -3
  577. package/dist/rules-consent.js +1 -0
  578. package/dist/run-acceptance.d.ts +3 -1
  579. package/dist/run-acceptance.js +3 -0
  580. package/dist/run-local.d.ts +14 -6
  581. package/dist/run-local.js +92 -80
  582. package/dist/run-stale-default.d.ts +7 -0
  583. package/dist/run-stale-default.js +2 -0
  584. package/dist/runs.d.ts +26 -15
  585. package/dist/runs.js +39 -27
  586. package/dist/runtime-caps-resolver.d.ts +21 -6
  587. package/dist/runtime-caps-resolver.js +17 -4
  588. package/dist/runtime-governance.d.ts +2 -2
  589. package/dist/runtime-governance.js +5 -3
  590. package/dist/sealed-key-layout.d.ts +12 -5
  591. package/dist/sealed-key-layout.js +5 -0
  592. package/dist/sealed-key.d.ts +12 -2
  593. package/dist/sealed-key.js +115 -27
  594. package/dist/security.d.ts +128 -158
  595. package/dist/security.js +163 -59
  596. package/dist/sema-config-dir.d.ts +20 -0
  597. package/dist/sema-config-dir.js +25 -0
  598. package/dist/server-secret-env.d.ts +21 -5
  599. package/dist/server-secret-env.js +14 -4
  600. package/dist/session-children-retire.d.ts +7 -5
  601. package/dist/session-children-retire.js +7 -2
  602. package/dist/session-deletion.d.ts +88 -0
  603. package/dist/session-deletion.js +8 -0
  604. package/dist/session-erase.d.ts +145 -0
  605. package/dist/session-erase.js +115 -0
  606. package/dist/session-error-wire.d.ts +5 -5
  607. package/dist/session-error-wire.js +1 -1
  608. package/dist/session-incarnation.d.ts +52 -5
  609. package/dist/session-incarnation.js +19 -2
  610. package/dist/session-policy-wire.d.ts +6 -3
  611. package/dist/session-policy-wire.js +11 -1
  612. package/dist/session-resident-background.d.ts +0 -71
  613. package/dist/session-resident-background.js +4 -3
  614. package/dist/session-row.d.ts +2 -1
  615. package/dist/session-rules-seat.d.ts +12 -0
  616. package/dist/session-rules-seat.js +19 -0
  617. package/dist/session-titler.d.ts +7 -15
  618. package/dist/session-titler.js +1 -1
  619. package/dist/spec-fields.d.ts +57 -3
  620. package/dist/spec-fields.js +72 -51
  621. package/dist/store-posture.d.ts +136 -20
  622. package/dist/store-posture.js +188 -3
  623. package/dist/stored-request-hooks-m20.js +2 -2
  624. package/dist/stores-sql/background-agent-store-sql.d.ts +11 -2
  625. package/dist/stores-sql/background-agent-store-sql.js +73 -20
  626. package/dist/stores-sql/checkpoint-store-sql.d.ts +33 -28
  627. package/dist/stores-sql/checkpoint-store-sql.js +75 -44
  628. package/dist/stores-sql/mailbox-store-sql.d.ts +7 -4
  629. package/dist/stores-sql/mailbox-store-sql.js +31 -32
  630. package/dist/stores-sql/pg-session-storage.d.ts +7 -5
  631. package/dist/stores-sql/pg-session-storage.js +54 -46
  632. package/dist/stores-sql/retention-store-sql.d.ts +87 -19
  633. package/dist/stores-sql/retention-store-sql.js +92 -27
  634. package/dist/stores-sql/session-policy-store-sql.d.ts +32 -10
  635. package/dist/stores-sql/session-policy-store-sql.js +44 -36
  636. package/dist/stores-sql/session-write-hooks.d.ts +12 -6
  637. package/dist/stores-sql/tidb-session-storage.d.ts +4 -4
  638. package/dist/stores-sql/tidb-session-storage.js +13 -8
  639. package/dist/stores-sql/tidb-session-store.d.ts +36 -17
  640. package/dist/stores-sql/tidb-session-store.js +69 -39
  641. package/dist/stores-sql/windowed-session-storage.d.ts +5 -0
  642. package/dist/stores-sql/windowed-session-storage.js +9 -0
  643. package/dist/submission-exit.d.ts +50 -0
  644. package/dist/submission-exit.js +108 -0
  645. package/dist/task-a2a.d.ts +1 -1
  646. package/dist/task-a2a.js +3 -3
  647. package/dist/task-cwd.d.ts +20 -0
  648. package/dist/task-cwd.js +8 -0
  649. package/dist/task-mcp.d.ts +1 -1
  650. package/dist/task-mcp.js +3 -3
  651. package/dist/task-settings.d.ts +14 -10
  652. package/dist/task-settings.js +18 -7
  653. package/dist/terminal.d.ts +25 -43
  654. package/dist/terminal.js +31 -11
  655. package/dist/tool-approval.d.ts +131 -129
  656. package/dist/tool-approval.js +189 -193
  657. package/dist/trace/core-keyset-guard.d.ts +13 -6
  658. package/dist/trace/core-vocab-wire.d.ts +95 -0
  659. package/dist/trace/core-vocab-wire.js +15 -0
  660. package/dist/trace/exit-seat.d.ts +30 -4
  661. package/dist/trace/exit-seat.js +40 -36
  662. package/dist/trace/extension-call-face.d.ts +3 -2
  663. package/dist/trace/extension-call-face.js +3 -1
  664. package/dist/trace/ledger-events.d.ts +4 -7
  665. package/dist/trace/ledger-sink.d.ts +1 -30
  666. package/dist/trace/ledger-sink.js +0 -11
  667. package/dist/trace/model-segment.d.ts +5 -5
  668. package/dist/trace/model-segment.js +5 -5
  669. package/dist/trace/project.d.ts +55 -42
  670. package/dist/trace/project.js +52 -19
  671. package/dist/trace/redact.d.ts +123 -27
  672. package/dist/trace/redact.js +880 -260
  673. package/dist/trace/self-minted-wire.d.ts +487 -19
  674. package/dist/trace/self-minted-wire.js +172 -23
  675. package/dist/trace/wire-projection-faces.d.ts +5 -6
  676. package/dist/trace/wire-projection-faces.js +2 -2
  677. package/dist/upstream-body.d.ts +23 -0
  678. package/dist/upstream-body.js +16 -0
  679. package/dist/url-refusal.d.ts +3 -3
  680. package/dist/url-refusal.js +11 -4
  681. package/dist/user-authored-text.d.ts +1 -1
  682. package/dist/user-input-ledger.d.ts +7 -8
  683. package/dist/user-input-ledger.js +1 -1
  684. package/dist/web-admin-client/apply-effective.d.ts +6 -3
  685. package/dist/web-admin-client/apply-effective.js +13 -16
  686. package/dist/web-admin-client/apply-ledger.d.ts +16 -7
  687. package/dist/web-admin-client/apply-ledger.js +5 -2
  688. package/dist/web-admin-client/center-request.d.ts +2 -2
  689. package/dist/web-admin-client/center-request.js +15 -15
  690. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  691. package/dist/web-admin-client/effective-keys.js +1 -1
  692. package/dist/web-admin-client/entry-metadata.d.ts +8 -0
  693. package/dist/web-admin-client/entry-metadata.js +13 -0
  694. package/dist/web-admin-client/http-client.d.ts +1 -1
  695. package/dist/web-admin-client/http-client.js +23 -4
  696. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  697. package/dist/web-admin-client/mcp-revocation.js +2 -1
  698. package/dist/web-admin-client/read-warnings.d.ts +1 -0
  699. package/dist/web-admin-client/read-warnings.js +1 -0
  700. package/dist/web-admin-client/restart-signal.js +8 -4
  701. package/dist/web-admin-client/skills-mcp.d.ts +2 -2
  702. package/dist/web-admin-client/types.d.ts +1 -2
  703. package/dist/workspace-space.d.ts +3 -2
  704. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +4 -4
  705. package/package.json +6 -3
  706. package/scripts/drain-check-local.mjs +118 -147
  707. package/scripts/drain-check.mysql.sql +22 -2
  708. package/scripts/drain-check.pg.sql +22 -2
  709. package/wire-changes/server@7.148.0.json +1517 -0
  710. package/dist/http/memory-control-plane-corrupt-reply.d.ts +0 -25
  711. package/dist/http/memory-control-plane-corrupt-reply.js +0 -19
  712. package/dist/http/memory-layer-reply.d.ts +0 -30
  713. package/dist/http/memory-layer-reply.js +0 -24
  714. package/dist/lsp/e2b-bridge.d.ts +0 -57
  715. package/dist/lsp/e2b-bridge.js +0 -139
  716. package/dist/lsp/e2b-manager.d.ts +0 -93
  717. package/dist/lsp/e2b-manager.js +0 -178
  718. package/dist/lsp/lsp-frames.d.ts +0 -14
  719. package/dist/lsp/lsp-frames.js +0 -25
  720. package/dist/lsp/manager.d.ts +0 -129
  721. package/dist/lsp/manager.js +0 -127
  722. package/dist/lsp/types.d.ts +0 -12
  723. package/dist/lsp/types.js +0 -2
  724. package/dist/lsp/ws-transport.d.ts +0 -40
  725. package/dist/lsp/ws-transport.js +0 -210
@@ -3,18 +3,20 @@ import { heldAskOf, liveHostSource, readDecider, retiredDecisionKeyFacts, POLICY
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  import { uuidv7, classifyAsk, foldArbitrationRow, policyCannotAnswer, screenAskClassMembers, MAX_RULE_TEXT_CHARS, READ_ROOT_CANDIDATE_DIR_MAX, parseRuleText, pathConfinableWriteToolNames } from "@sema-agent/core";
5
5
  import { precheckCardRuleText } from "./rules-consent.js";
6
- import { cardTakesWholeToolConsent } from "./permission-rule-vocab.js";
6
+ import { CARD_RULE_FORM_OF_MATCH, cardRuleFormOf } from "./permission-rule-vocab.js";
7
7
  import { redactDeep, redactSecrets, redactSecretsWithArms } from "./trace/redact.js";
8
8
  import { seatText } from "./trace/exit-seat.js";
9
9
  import { hasBidiControls } from "./text-bidi.js";
10
10
  import { approvalPayloadFingerprint } from "./plugins/approval-payload-fingerprint.js";
11
11
  import { createLogger } from "./observability/logger.js";
12
12
  import { errorKindOf } from "./observability/err-text.js";
13
+ import { createHitlOpenRace, deliverHitlNotice } from "./hitl-delivery.js";
13
14
  import { recordFailOpen } from "./observability/fail-open.js";
14
15
  import { ownerOfCheckpointScope } from "./security.js";
16
+ import { keyAdmits, ownerCellOf, recoveredSubject } from "./owner-faces.js";
15
17
  import { deriveAskId, deriveAskScopedBatchId, deriveBatchId, MAX_DECISION_NOTE_CHARS, noteLandedOnRow, noteRecordedReceipt, readBoundInputHash } from "./approval-ask-machine.js";
16
18
  import { askDemandsAPerson, storedPersonDemandRecord, currentParkArm, MAX_RULE_OFFERS, buildApprovalCard, buildApprovalCardEnvelope, adoptStoredLiveFacts, buildApprovalRequestFrame, buildReplayFrame, buildRevokeFrame, readDenialLimitFallback, readProbeCause, readProbeReason, readReadRootCandidate, readStoredCardEnvelope, readRuleEvidence, readAllowRuleShadowed, readRuleOffersAbsence, readRuleOffersAbsenceSeat, readParkRowTrueSeat, readAskClassPair, readAskReasons, readClosedWordSeat, buildApprovalCompleteFrame, readRuleOfferList, } from "./approval-card.js";
17
- import { askOwnerAdmits, askRowCarriesOwner, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth } from "./plugins/approval-ask-store-sql.js";
19
+ import { askRowCarriesOwner, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth } from "./plugins/approval-ask-store-sql.js";
18
20
  import { APPROVAL_ENDING_CAUSES, SETTLE_OUTCOME, askRowEndingCause, askRowParkTrigger } from "./approval-deny-reasons.js";
19
21
  import { settleByPolicy } from "./approval-policy-settlement.js";
20
22
  import { governanceAskMarksFor, runWithGovernanceAskScope } from "./governance-ask-marks.js";
@@ -46,8 +48,10 @@ const PARKING_RETRY_AFTER_MS = 250;
46
48
  export function approvalDecidePath(sessionId) {
47
49
  return `/v1/approvals/${encodeURIComponent(sessionId)}/decide`;
48
50
  }
49
- function parkSessionOf(row) {
50
- return row.sourceSessionId === row.sessionId && row.sessionId !== row.taskId ? row.sessionId : undefined;
51
+ export function parkSessionOf(row) {
52
+ if (row.state === "PARKED")
53
+ return row.sourceSessionId;
54
+ return row.sourceSessionId !== row.taskId ? row.sourceSessionId : undefined;
51
55
  }
52
56
  function ruleMaterialCarriesCredentialShape(command) {
53
57
  return redactSecretsWithArms(command, { observe: false }).arms.has("full");
@@ -227,7 +231,13 @@ function rowOrUnknown(read) {
227
231
  return read.kind === "row" ? read.row : null;
228
232
  }
229
233
  function askRowVisibleTo(row, principal) {
230
- return row !== null && askOwnerAdmits(row.owner, principal);
234
+ return row !== null && askOwnerAdmitsAnswer(row.owner, principal);
235
+ }
236
+ function askOwnerAdmitsAnswer(owner, principal) {
237
+ return keyAdmits("ask.answer", { subject: recoveredSubject(principal), operator: false }, ownerCellOf(owner));
238
+ }
239
+ function receiptAnswersNow(redeemedGeneration, openGenerationNow) {
240
+ return redeemedGeneration === undefined || openGenerationNow === undefined || openGenerationNow <= redeemedGeneration;
231
241
  }
232
242
  function waitingLegsReached(entry, othersReached) {
233
243
  return (entry.adopted === true ? 0 : 1) + othersReached;
@@ -257,8 +267,10 @@ function livePendingRowOf(e) {
257
267
  ...(e.adopted === true ? { consumerState: ASK_DECISION_CONSUMER_ABSENT } : {}),
258
268
  };
259
269
  }
270
+ const _legFamiliesAreFrameFamilies = true;
271
+ void _legFamiliesAreFrameFamilies;
260
272
  function canPresentWithoutDurableRow(c) {
261
- return c.emitCard === undefined;
273
+ return c.family === "tool_approval";
262
274
  }
263
275
  export const PERSIST_RULE_TEXT_ERROR = `persistRule.rule must be a non-empty string of at most ${MAX_RULE_TEXT_CHARS} characters`;
264
276
  export const PERSIST_RULE_EDITED_FLAG_ERROR = "persistRule.edited must be a boolean when present";
@@ -435,49 +447,6 @@ export function declaredApprovalFrameFamilies(settings) {
435
447
  const raw = Reflect.get(settings, "approvalFrameFamilies");
436
448
  return new Set(Array.isArray(raw) ? raw.filter((w) => APPROVAL_FRAME_FAMILIES.includes(w)) : []);
437
449
  }
438
- export function createApprovalCardEmitter(sinks) {
439
- const present = [sinks.appendDurable, sinks.writeLive].filter((w) => w !== undefined);
440
- const attempt = (write, frame) => (async () => {
441
- try {
442
- await write(frame);
443
- return true;
444
- }
445
- catch (err) {
446
- defaultLogger.warn("approval_card_sink_write_failed", { frame: frame.type, approvalId: frame.approvalId, errKind: errorKindOf(err) });
447
- return false;
448
- }
449
- })();
450
- const opened = new Map();
451
- return async (frame, registration) => {
452
- if (frame.type === "approval_request") {
453
- const results = present.map((write) => attempt(write, frame));
454
- opened.set(registration, results);
455
- const accepted = await new Promise((resolve) => {
456
- let pending = results.length;
457
- if (pending === 0)
458
- resolve(false);
459
- for (const r of results) {
460
- void r.then((ok) => {
461
- if (ok)
462
- resolve(true);
463
- else if (--pending === 0)
464
- resolve(false);
465
- });
466
- }
467
- });
468
- if (!accepted) {
469
- opened.delete(registration);
470
- throw new Error("approval card undeliverable — no sink accepted the frame (live stream closed and/or the durable append failed)");
471
- }
472
- return;
473
- }
474
- const results = opened.get(registration);
475
- opened.delete(registration);
476
- if (results === undefined)
477
- return;
478
- await Promise.all(present.map((write, i) => results[i].then((ok) => (ok ? attempt(write, frame) : false))));
479
- };
480
- }
481
450
  export function resolveApprovalLeg(input) {
482
451
  const active = input.streamApprovalOn;
483
452
  const tightDeadline = active && input.legWalltimeMs !== undefined && input.legWalltimeMs - input.windowMarginMs <= 0;
@@ -767,14 +736,14 @@ export class ToolApprovalCoordinator {
767
736
  }
768
737
  });
769
738
  }
770
- static ruleOfferDerivedFactsAgree(offer) {
739
+ static ruleOfferDerivedFactsAgree(offer, cardTool) {
771
740
  const derive = (rule) => {
772
741
  const p = parseRuleText(rule, "allow");
773
742
  return "rule" in p ? p.rule : undefined;
774
743
  };
775
744
  if (offer.kind === "single") {
776
745
  const d = derive(offer.rule);
777
- return d !== undefined && d.rule === offer.rule && d.match === offer.match && d.command === offer.command && ToolApprovalCoordinator.singleOfferToolAgrees(d.match, d.tool);
746
+ return d !== undefined && d.rule === offer.rule && d.match === offer.match && d.command === offer.command && ToolApprovalCoordinator.singleOfferBelongsOnCard(d.match, d.tool, cardTool);
778
747
  }
779
748
  return offer.rules.every((m) => {
780
749
  const d = derive(m.rule);
@@ -790,40 +759,21 @@ export class ToolApprovalCoordinator {
790
759
  }
791
760
  });
792
761
  }
793
- static singleOfferToolAgrees(match, tool) {
794
- switch (match) {
795
- case "exact":
796
- case "prefix":
797
- case "wildcard":
798
- case "pattern":
799
- return tool === "Bash";
800
- case "tool":
801
- return cardTakesWholeToolConsent(tool);
802
- case "subpath":
803
- case "path":
804
- case "name":
805
- case "name_prefix":
806
- case "host":
807
- case "subdomain":
808
- return false;
809
- default: {
810
- const unknown = match;
811
- void unknown;
812
- return false;
813
- }
814
- }
762
+ static singleOfferBelongsOnCard(match, ruleTool, cardTool) {
763
+ const form = CARD_RULE_FORM_OF_MATCH[match];
764
+ return ruleTool === cardTool && form !== undefined && form === cardRuleFormOf(cardTool);
815
765
  }
816
- static boundRuleOfferTexts(offers) {
766
+ static boundRuleOfferTexts(offers, cardTool) {
817
767
  const over = (s) => s.length > MAX_RULE_TEXT_CHARS;
818
768
  const clipSegment = (s) => (over(s) ? s.slice(0, MAX_RULE_TEXT_CHARS) : s);
819
769
  const out = [];
820
770
  for (const { offer } of readRuleOfferList(offers)) {
821
771
  if (ToolApprovalCoordinator.ruleOfferTextsOverSize(offer))
822
772
  return undefined;
823
- if (!ToolApprovalCoordinator.ruleOfferDerivedFactsAgree(offer)) {
773
+ if (!ToolApprovalCoordinator.ruleOfferDerivedFactsAgree(offer, cardTool)) {
824
774
  defaultLogger.warn("rule_offer_dropped_derived_facts_disagree", {
825
775
  kind: offer.kind,
826
- note: "an offer's kind/match/command/directory seats do not agree with what the shared validator derives from its rule text — dropped whole so the card never shows one grant while redeeming another (core/dist skew or forged material?)",
776
+ note: "an offer's kind/match/command/directory seats do not agree with what the shared validator derives from its rule text, or it is not this card's tool / card form — dropped whole so the card never shows one grant while redeeming another (core/dist skew or forged material?)",
827
777
  });
828
778
  continue;
829
779
  }
@@ -860,11 +810,9 @@ export class ToolApprovalCoordinator {
860
810
  return out;
861
811
  }
862
812
  static cardBindingOf(args, offers) {
863
- const isWholeTool = (o) => o.kind === "single" && o.match === "tool";
864
- if (offers.length > 0 && offers.every(isWholeTool))
865
- return "";
866
- if (offers.some(isWholeTool))
867
- return undefined;
813
+ const valueOffers = offers.filter((o) => o.kind === "single" && CARD_RULE_FORM_OF_MATCH[o.match] !== "command");
814
+ if (valueOffers.length > 0)
815
+ return valueOffers.length === 1 && offers.length === 1 ? valueOffers[0].command : undefined;
868
816
  if (args === null || typeof args !== "object" || Array.isArray(args))
869
817
  return undefined;
870
818
  const command = args.command;
@@ -881,7 +829,7 @@ export class ToolApprovalCoordinator {
881
829
  if (!Array.isArray(rawOffers) || rawOffers.length === 0)
882
830
  return undefined;
883
831
  const capped = rawOffers.length > MAX_RULE_OFFERS ? rawOffers.slice(0, MAX_RULE_OFFERS) : rawOffers;
884
- const offers = ToolApprovalCoordinator.boundRuleOfferTexts(capped);
832
+ const offers = ToolApprovalCoordinator.boundRuleOfferTexts(capped, req.toolName);
885
833
  if (offers === undefined)
886
834
  return undefined;
887
835
  const command = ToolApprovalCoordinator.cardBindingOf(req.args, offers);
@@ -1224,15 +1172,9 @@ export class ToolApprovalCoordinator {
1224
1172
  emitRevokeTo(ctxs, frame) {
1225
1173
  if (frame.askIds.length === 0)
1226
1174
  return;
1227
- for (const c of ctxs) {
1228
- if (!c.emitRevoke)
1229
- continue;
1230
- try {
1231
- void Promise.resolve(c.emitRevoke(frame)).catch(() => undefined);
1232
- }
1233
- catch {
1234
- }
1235
- }
1175
+ for (const c of ctxs)
1176
+ if (c.family === "approval_request")
1177
+ void deliverHitlNotice(c.transport, frame);
1236
1178
  }
1237
1179
  emitRevoke(frame, target) {
1238
1180
  const targets = new Set();
@@ -1583,6 +1525,7 @@ export class ToolApprovalCoordinator {
1583
1525
  const allowedP = new Promise((resolve) => { resolveAllowed = resolve; });
1584
1526
  let lastOutcome = SETTLE_OUTCOME.EXPIRED;
1585
1527
  let lastCause;
1528
+ let completeFrame;
1586
1529
  const abortListeners = [];
1587
1530
  let selfEntry;
1588
1531
  let hostSettled;
@@ -1646,8 +1589,10 @@ export class ToolApprovalCoordinator {
1646
1589
  }
1647
1590
  lastOutcome = outcome;
1648
1591
  lastCause = verdict.by === "system" ? verdict.cause : undefined;
1649
- if (lastLiveRegistration && askId !== undefined) {
1650
- this.notifyPresentedCardWatchers(askId, buildApprovalCompleteFrame({ askId, taskId: origin.taskId, approvalId: wireApprovalId, outcome, ...(lastCause !== undefined ? { cause: lastCause } : {}), parked: parkRouted, nowMs: Date.now() }));
1592
+ if (askId !== undefined) {
1593
+ completeFrame = buildApprovalCompleteFrame({ askId, taskId: origin.taskId, approvalId: wireApprovalId, outcome, ...(lastCause !== undefined ? { cause: lastCause } : {}), parked: parkRouted, nowMs: Date.now() });
1594
+ if (lastLiveRegistration)
1595
+ this.notifyPresentedCardWatchers(askId, completeFrame);
1651
1596
  }
1652
1597
  releaseAdmission();
1653
1598
  if (selfEntry)
@@ -1952,6 +1897,7 @@ export class ToolApprovalCoordinator {
1952
1897
  forceParkNow,
1953
1898
  settleParkRoute: (cause) => settleParkRouteIfUnsettled(undefined, cause),
1954
1899
  owner: origin.owner,
1900
+ ownerReadSeq: this.rowReadSeq,
1955
1901
  ...(primary ? { ctxTaskId: primary.taskId, originCtx: primary } : {}),
1956
1902
  ...(reachability === "unreached" ? { suspended: true } : {}),
1957
1903
  ...(child ? { originTaskId: req.sourceSessionId } : primary ? { targetCtxs: new Set(aliveCtxs), onTargetGone } : {}),
@@ -2014,38 +1960,24 @@ export class ToolApprovalCoordinator {
2014
1960
  frame.serverNowMs = serverNowMs;
2015
1961
  frame.expiresInMs = Math.max(0, persistedExpiresAtMs - serverNowMs);
2016
1962
  }
2017
- const emitOne = async (c) => {
2018
- let family;
2019
- let send;
2020
- if (c.emitCard !== undefined) {
2021
- if (cardFrame === undefined) {
2022
- defaultLogger.warn("approval card leg cannot present this ask: it has no confirmed durable identity (no approval_request frame is minted without one)", {
2023
- taskId: origin.taskId,
2024
- approvalId: wireApprovalId,
2025
- toolName: req.toolName,
2026
- });
2027
- return { delivered: false };
2028
- }
2029
- family = "approval_request";
2030
- send = () => c.emitCard(cardFrame, id);
2031
- }
2032
- else {
2033
- family = "tool_approval";
2034
- send = () => c.emit(frame);
2035
- }
2036
- try {
2037
- await send();
2038
- return { delivered: true };
2039
- }
2040
- catch (err) {
2041
- defaultLogger.warn("approval_card_delivery_failed", { taskId: origin.taskId, approvalId: wireApprovalId, family, errKind: errorKindOf(err) });
2042
- return { delivered: false };
2043
- }
2044
- };
2045
- const openByCtx = new Map(aliveCtxs.map((c) => [c, emitOne(c)]));
1963
+ const cardCtxs = aliveCtxs.filter((c) => c.family === "approval_request");
1964
+ const legacyCtxs = aliveCtxs.filter((c) => c.family === "tool_approval");
1965
+ if (cardFrame === undefined && cardCtxs.length > 0) {
1966
+ defaultLogger.warn("approval card leg cannot present this ask: it has no confirmed durable identity (no approval_request frame is minted without one)", {
1967
+ taskId: origin.taskId,
1968
+ approvalId: wireApprovalId,
1969
+ toolName: req.toolName,
1970
+ });
1971
+ }
1972
+ const cardRace = cardFrame !== undefined && cardCtxs.length > 0
1973
+ ? createHitlOpenRace({ targets: cardCtxs.map((c) => ({ transport: c.transport, frame: cardFrame })), settled: allowedP })
1974
+ : undefined;
1975
+ const legacyRace = legacyCtxs.length > 0 ? createHitlOpenRace({ targets: legacyCtxs.map((c) => ({ transport: c.transport, frame })), settled: allowedP }) : undefined;
1976
+ if (cardRace !== undefined && cardFrame !== undefined)
1977
+ cardCtxs.forEach((c, i) => this.notePresentedCardRegistration(cardFrame.askId, c.transport, cardRace.acceptedLive(i)));
2046
1978
  const emitAllP = (async () => {
2047
- const results = await Promise.all(openByCtx.values());
2048
- const anySucceeded = reachability === "unreached" || this.hasOtherSuspendedOwner(askId, selfEntry) || results.some((r) => r.delivered);
1979
+ const landings = await Promise.all([cardRace?.landing, legacyRace?.landing]);
1980
+ const anySucceeded = reachability === "unreached" || this.hasOtherSuspendedOwner(askId, selfEntry) || landings.includes("delivered");
2049
1981
  emitSettled = true;
2050
1982
  if (!anySucceeded && !done) {
2051
1983
  if (this.askStore && askId !== undefined && batchId !== undefined) {
@@ -2086,35 +2018,15 @@ export class ToolApprovalCoordinator {
2086
2018
  })();
2087
2019
  await Promise.race([emitAllP, allowedP]);
2088
2020
  const settled = await allowedP;
2089
- for (const c of aliveCtxs) {
2090
- void openByCtx
2091
- .get(c)
2092
- .then(({ delivered }) => {
2093
- if (!delivered)
2094
- return undefined;
2095
- if (c.emitCard !== undefined) {
2096
- if (cardFrame === undefined)
2097
- return undefined;
2098
- return c.emitCard(buildApprovalCompleteFrame({
2099
- askId: cardFrame.askId,
2100
- taskId: cardFrame.taskId,
2101
- approvalId: wireApprovalId,
2102
- outcome: lastOutcome,
2103
- ...(lastCause !== undefined ? { cause: lastCause } : {}),
2104
- parked: parkRouted,
2105
- nowMs: Date.now(),
2106
- }), id);
2107
- }
2108
- return c.emit({
2109
- type: "tool_approval_complete",
2110
- approvalId: wireApprovalId,
2111
- outcome: lastOutcome,
2112
- ...(lastCause !== undefined ? { cause: lastCause } : {}),
2113
- ...(parkRouted ? { parked: true } : {}),
2114
- });
2115
- })
2116
- .catch(() => undefined);
2117
- }
2021
+ if (cardRace !== undefined && completeFrame !== undefined)
2022
+ cardRace.close(completeFrame);
2023
+ legacyRace?.close({
2024
+ type: "tool_approval_complete",
2025
+ approvalId: wireApprovalId,
2026
+ outcome: lastOutcome,
2027
+ ...(lastCause !== undefined ? { cause: lastCause } : {}),
2028
+ ...(parkRouted ? { parked: true } : {}),
2029
+ });
2118
2030
  if (emitFailed)
2119
2031
  return this.unattendedOutcome({ arm: "emit_failed", taskId: origin.taskId, ...(origin.owner !== null ? { owner: origin.owner } : {}), toolName: req.toolName, reachability });
2120
2032
  if (windowRouteUnavailable)
@@ -2133,7 +2045,7 @@ export class ToolApprovalCoordinator {
2133
2045
  const entry = this.liveEntryFor(id);
2134
2046
  if (entry?.adopted === true)
2135
2047
  return this.respondByRow(entry, id, principal, parsed, httpReq);
2136
- if (entry !== undefined && askOwnerAdmits(entry.owner, principal))
2048
+ if (entry !== undefined && askOwnerAdmitsAnswer(entry.owner, principal))
2137
2049
  return this.answerRegistration(entry, entry.owner, id, principal, parsed, httpReq);
2138
2050
  if (entry !== undefined && this.registrationHasRow(entry))
2139
2051
  return this.respondByRow(entry, id, principal, parsed, httpReq);
@@ -2145,10 +2057,13 @@ export class ToolApprovalCoordinator {
2145
2057
  async respondByRow(entry, id, principal, parsed, httpReq) {
2146
2058
  const store = this.askStore;
2147
2059
  if (!store)
2148
- return this.notPending();
2060
+ return this.askNotVisible();
2061
+ const readSeq = this.nextRowReadSeq();
2149
2062
  const row = rowOrUnknown(await this.askRowFor(store, id, "getAsk(respond-by-row)"));
2063
+ if (row?.state === "STREAM_PENDING")
2064
+ this.followRowOwner(row.askId, row.owner, readSeq);
2150
2065
  if (!askRowVisibleTo(row, principal))
2151
- return this.notPending(NOT_PENDING_UNKNOWN_CAUSE);
2066
+ return this.askNotVisible();
2152
2067
  if (row.state !== "STREAM_PENDING")
2153
2068
  return this.dispatchRowTruth(row, id, parsed, httpReq, principal);
2154
2069
  return this.answerRegistration(entry, row.owner, id, principal, parsed, httpReq);
@@ -2240,31 +2155,37 @@ export class ToolApprovalCoordinator {
2240
2155
  }),
2241
2156
  };
2242
2157
  }
2158
+ askNotVisible() {
2159
+ return { status: 404, body: refusalBody({ errorCode: "not_found.ask", message: "no such approval ask (never existed, no longer kept, or not yours)" }) };
2160
+ }
2243
2161
  readApproval(id, principal) {
2244
2162
  const entry = this.liveEntryFor(id);
2245
2163
  if (entry !== undefined && this.registrationHasRow(entry))
2246
2164
  return this.readByRow(entry, id, principal);
2247
- if (entry !== undefined && askOwnerAdmits(entry.owner, principal)) {
2165
+ if (entry !== undefined && askOwnerAdmitsAnswer(entry.owner, principal)) {
2248
2166
  const body = { state: "pending", ...livePendingRowOf(entry) };
2249
2167
  return { status: 200, body };
2250
2168
  }
2251
2169
  const store = this.askStore;
2252
2170
  if (!store)
2253
- return this.notPending();
2171
+ return this.askNotVisible();
2254
2172
  return this.readAskRowState(store, id, principal);
2255
2173
  }
2256
2174
  async readByRow(entry, id, principal) {
2257
2175
  const store = this.askStore;
2258
2176
  if (!store)
2259
- return this.notPending();
2177
+ return this.askNotVisible();
2178
+ const readSeq = this.nextRowReadSeq();
2260
2179
  const read = await this.askRowFor(store, id, "getAsk(read-by-row)");
2261
2180
  if (read.kind === "unreadable") {
2262
- if (entry.adopted === true || !askOwnerAdmits(entry.owner, principal))
2263
- return this.notPending(NOT_PENDING_UNKNOWN_CAUSE);
2181
+ if (entry.adopted === true || !askOwnerAdmitsAnswer(entry.owner, principal))
2182
+ return this.askNotVisible();
2264
2183
  const body = { state: "pending", ...livePendingRowOf(entry) };
2265
2184
  return { status: 200, body };
2266
2185
  }
2267
2186
  const row = rowOrUnknown(read);
2187
+ if (row?.state === "STREAM_PENDING")
2188
+ this.followRowOwner(row.askId, row.owner, readSeq);
2268
2189
  if (askRowVisibleTo(row, principal) && row.state === "STREAM_PENDING") {
2269
2190
  const body = { state: "pending", ...livePendingRowOf(entry) };
2270
2191
  return { status: 200, body };
@@ -2277,18 +2198,22 @@ export class ToolApprovalCoordinator {
2277
2198
  async readParkedGate(row) {
2278
2199
  const gate = this.parkedGate;
2279
2200
  if (gate === undefined || row.gateToken === null)
2280
- return { kind: "open" };
2201
+ return undefined;
2281
2202
  try {
2282
2203
  return await this.withStoreDeadline(gate({ gateToken: row.gateToken, gateBoundCallId: row.gateBoundCallId }), "readParkedGate", DURABLE_CONVERGE_READ_TIMEOUT_MS);
2283
2204
  }
2284
2205
  catch (err) {
2285
2206
  this.noteStoreError(err, "readParkedGate");
2286
- return { kind: "open" };
2207
+ return undefined;
2287
2208
  }
2288
2209
  }
2210
+ async openGateGeneration(row) {
2211
+ const gate = await this.readParkedGate(row);
2212
+ return gate?.kind === "open" ? gate.generation : undefined;
2213
+ }
2289
2214
  async readStateOfRow(row, principal) {
2290
2215
  if (!askRowVisibleTo(row, principal))
2291
- return this.notPending(NOT_PENDING_UNKNOWN_CAUSE);
2216
+ return this.askNotVisible();
2292
2217
  const projection = buildAskRowReadProjection(row, Date.now());
2293
2218
  let body;
2294
2219
  switch (row.state) {
@@ -2301,13 +2226,13 @@ export class ToolApprovalCoordinator {
2301
2226
  }
2302
2227
  case "PARKING":
2303
2228
  case "PARKED": {
2304
- const gate = row.state === "PARKED" ? await this.readParkedGate(row) : { kind: "open" };
2229
+ const gate = row.state === "PARKED" ? await this.readParkedGate(row) : undefined;
2230
+ if (gate === undefined || gate.kind === "open") {
2231
+ const parkSession = parkSessionOf(row);
2232
+ body = { state: "parked", ...projection, ...(parkSession !== undefined ? { decidePath: approvalDecidePath(parkSession) } : {}), ...(gate?.reopened !== undefined ? { reopened: gate.reopened } : {}) };
2233
+ break;
2234
+ }
2305
2235
  switch (gate.kind) {
2306
- case "open": {
2307
- const parkSession = parkSessionOf(row);
2308
- body = { state: "parked", ...projection, ...(parkSession !== undefined ? { decidePath: approvalDecidePath(parkSession) } : {}), ...(gate.reopened !== undefined ? { reopened: gate.reopened } : {}) };
2309
- break;
2310
- }
2311
2236
  case "decided":
2312
2237
  body = { state: "decided", ...projection, decision: gate.decision, decidedAtMs: gate.decidedAtMs, ...(gate.decisionNote !== undefined ? { decisionNote: gate.decisionNote } : {}) };
2313
2238
  break;
@@ -2350,11 +2275,11 @@ export class ToolApprovalCoordinator {
2350
2275
  respondLate(id, principal, parsed, httpReq) {
2351
2276
  const store = this.askStore;
2352
2277
  if (!store)
2353
- return this.notPending();
2278
+ return this.askNotVisible();
2354
2279
  return this.dispatchLateByRow(store, id, parsed, httpReq, principal);
2355
2280
  }
2356
- watchPresentedCards(askIds, deliver) {
2357
- const watcher = { deliver, askIds: new Set() };
2281
+ watchPresentedCards(askIds, deliver, connection) {
2282
+ const watcher = { deliver, connection, askIds: new Set(), registrationsOnConnection: new Map() };
2358
2283
  for (const askId of askIds) {
2359
2284
  if (!this.pendingByAskId.has(askId))
2360
2285
  continue;
@@ -2370,13 +2295,26 @@ export class ToolApprovalCoordinator {
2370
2295
  for (const askId of watcher.askIds)
2371
2296
  this.dropPresentedCardWatcher(askId, watcher);
2372
2297
  watcher.askIds.clear();
2298
+ watcher.registrationsOnConnection.clear();
2373
2299
  };
2374
2300
  }
2301
+ notePresentedCardRegistration(askId, transport, acceptedLive) {
2302
+ for (const watcher of this.presentedCardWatchers.get(askId) ?? []) {
2303
+ if (watcher.connection() !== transport)
2304
+ continue;
2305
+ const opens = watcher.registrationsOnConnection.get(askId);
2306
+ if (opens === undefined)
2307
+ watcher.registrationsOnConnection.set(askId, [acceptedLive]);
2308
+ else
2309
+ opens.push(acceptedLive);
2310
+ }
2311
+ }
2375
2312
  dropPresentedCardWatcher(askId, watcher) {
2376
2313
  const set = this.presentedCardWatchers.get(askId);
2377
2314
  if (set === undefined)
2378
2315
  return;
2379
2316
  set.delete(watcher);
2317
+ watcher.registrationsOnConnection.delete(askId);
2380
2318
  if (set.size === 0)
2381
2319
  this.presentedCardWatchers.delete(askId);
2382
2320
  }
@@ -2387,12 +2325,20 @@ export class ToolApprovalCoordinator {
2387
2325
  this.presentedCardWatchers.delete(askId);
2388
2326
  for (const watcher of set) {
2389
2327
  watcher.askIds.delete(askId);
2390
- try {
2391
- watcher.deliver(frame);
2392
- }
2393
- catch (err) {
2394
- defaultLogger.warn("presented-card completion notice could not be written to its connection", { askId, error: err instanceof Error ? err.message : String(err) });
2395
- }
2328
+ const opens = watcher.registrationsOnConnection.get(askId) ?? [];
2329
+ watcher.registrationsOnConnection.delete(askId);
2330
+ const write = () => {
2331
+ try {
2332
+ watcher.deliver(frame);
2333
+ }
2334
+ catch (err) {
2335
+ defaultLogger.warn("presented-card completion notice could not be written to its connection", { askId, error: err instanceof Error ? err.message : String(err) });
2336
+ }
2337
+ };
2338
+ if (opens.length === 0)
2339
+ write();
2340
+ else
2341
+ void Promise.all(opens).then((accepted) => (accepted.includes(true) ? undefined : write()));
2396
2342
  }
2397
2343
  }
2398
2344
  liveEntryFor(id) {
@@ -2418,10 +2364,7 @@ export class ToolApprovalCoordinator {
2418
2364
  }
2419
2365
  async dispatchRowTruth(row, id, parsed, httpReq, principal) {
2420
2366
  if (!askRowVisibleTo(row, principal))
2421
- return this.notPending(NOT_PENDING_UNKNOWN_CAUSE);
2422
- const receipt = this.lookupParkRedemption(row.askId);
2423
- if (receipt?.redeemed !== undefined)
2424
- return this.replayRedeemReceipt(id, receipt, row, receipt.redeemed, parsed);
2367
+ return this.askNotVisible();
2425
2368
  switch (row.state) {
2426
2369
  case "DECIDED":
2427
2370
  return this.replayDecidedAsk(id, row, parsed);
@@ -2494,14 +2437,17 @@ export class ToolApprovalCoordinator {
2494
2437
  defaultLogger.error("tool approval parked row carries no gate token — nothing to redeem", { askId: row.askId });
2495
2438
  return this.notPending();
2496
2439
  }
2440
+ const openGenerationNow = this.lookupParkRedemption(row.askId) !== undefined ? await this.openGateGeneration(row) : undefined;
2497
2441
  const prior = this.lookupParkRedemption(row.askId);
2498
- if (prior?.redeemed !== undefined)
2442
+ if (prior?.redeemed !== undefined && receiptAnswersNow(prior.redeemed.gateGeneration, openGenerationNow))
2499
2443
  return this.replayRedeemReceipt(id, prior, row, prior.redeemed, parsed);
2500
2444
  if (prior?.inflight !== undefined) {
2501
2445
  const shared = await prior.inflight;
2502
2446
  if (shared.status < 200 || shared.status >= 300)
2503
2447
  return shared;
2504
- return this.replayRedeemReceipt(id, prior, row, { decision: shared.decision, body: shared.body, ...(shared.rule?.terminal === true ? { rule: shared.rule.body } : {}) }, parsed);
2448
+ if (!receiptAnswersNow(shared.gateGeneration, openGenerationNow))
2449
+ return this.redeemParkedAsk(id, row, parsed, httpReq, principal);
2450
+ return this.replayRedeemReceipt(id, prior, row, { decision: shared.decision, body: shared.body, gateGeneration: shared.gateGeneration, ...(shared.rule?.terminal === true ? { rule: shared.rule.body } : {}) }, parsed);
2505
2451
  }
2506
2452
  const admission = this.parkRedemptionAdmission(row.owner);
2507
2453
  if (admission !== undefined)
@@ -2550,7 +2496,7 @@ export class ToolApprovalCoordinator {
2550
2496
  }
2551
2497
  const rule = out.rule;
2552
2498
  if (this.retainParkRedemption(row.askId, memo))
2553
- memo.redeemed = { decision, body: out.body, ...(rule?.terminal === true ? { rule: rule.body } : {}) };
2499
+ memo.redeemed = { decision, body: out.body, gateGeneration: out.gateGeneration, ...(rule?.terminal === true ? { rule: rule.body } : {}) };
2554
2500
  return {
2555
2501
  status: out.status,
2556
2502
  body: {
@@ -2779,17 +2725,33 @@ export class ToolApprovalCoordinator {
2779
2725
  this.noteStoreError(err, "decideAsk");
2780
2726
  ruleEligibility.eligible = false;
2781
2727
  try {
2728
+ const confirmSeq = this.nextRowReadSeq();
2782
2729
  const row = await this.withStoreDeadline(askStore.getAsk(askId), "getAsk(decideAsk-confirm)", DURABLE_CONVERGE_READ_TIMEOUT_MS);
2783
- if (row !== null && !askRowCarriesOwner(row, owner))
2730
+ if (row?.state === "STREAM_PENDING")
2731
+ this.followRowOwner(askId, row.owner, confirmSeq);
2732
+ if (row === null || !askRowCarriesOwner(row, owner))
2784
2733
  return { lost: true, row: null };
2785
- if (row?.state === "DECIDED" && row.decision === (parsed.value === "deny" ? "deny" : "approve")) {
2734
+ if (row.state === "DECIDED" && row.decision === (parsed.value === "deny" ? "deny" : "approve")) {
2786
2735
  winnerRow = row;
2787
2736
  ambiguousConfirmedRow = row;
2788
2737
  noteLanded = noteLandedOnRow(parsed.note, row.decisionNote);
2789
2738
  }
2739
+ else if (row.state !== "STREAM_PENDING") {
2740
+ return { lost: true, row };
2741
+ }
2790
2742
  }
2791
2743
  catch (confirmErr) {
2792
2744
  this.noteStoreError(confirmErr, "getAsk(decideAsk-confirm)");
2745
+ return {
2746
+ lost: false,
2747
+ result: {
2748
+ status: 500,
2749
+ body: refusalBody({
2750
+ errorCode: "internal.error",
2751
+ message: "the approval store failed while recording this answer and could not be read back, so whether the answer was recorded is unknown — retry: a retry returns the recorded answer if it was recorded, or records it if it was not",
2752
+ }),
2753
+ },
2754
+ };
2793
2755
  }
2794
2756
  }
2795
2757
  const wantAllowed = parsed.value !== "deny";
@@ -2939,6 +2901,7 @@ export class ToolApprovalCoordinator {
2939
2901
  forceParkNow: release,
2940
2902
  settleParkRoute: (cause) => leave({ outcome: SETTLE_OUTCOME.EXPIRED, cause, parked: this.unattendedRoutesToPark }),
2941
2903
  owner: row.owner,
2904
+ ownerReadSeq: this.rowReadSeq,
2942
2905
  executionLane: row.executionLane,
2943
2906
  ...(row.sessionId !== row.taskId ? { sessionId: row.sessionId } : {}),
2944
2907
  ...(card.fromSubagent === true ? { originTaskId: row.sourceSessionId } : {}),
@@ -2972,10 +2935,42 @@ export class ToolApprovalCoordinator {
2972
2935
  for (const watcher of watchers)
2973
2936
  watcher.askIds.delete(askId);
2974
2937
  }
2975
- followAdoptedOwner(askId, owner) {
2976
- for (const e of this.pendingByAskId.get(askId) ?? [])
2977
- if (e.adopted === true)
2978
- e.owner = owner;
2938
+ followRowOwner(askId, owner, readSeq) {
2939
+ for (const e of this.pendingByAskId.get(askId) ?? []) {
2940
+ if (e.ownerReadSeq >= readSeq)
2941
+ continue;
2942
+ e.owner = owner;
2943
+ e.ownerReadSeq = readSeq;
2944
+ }
2945
+ }
2946
+ rowReadSeq = 0;
2947
+ nextRowReadSeq() {
2948
+ this.rowReadSeq += 1;
2949
+ return this.rowReadSeq;
2950
+ }
2951
+ async followRowOwners() {
2952
+ const store = this.askStore;
2953
+ const out = { read: 0, followed: 0, unreadable: 0 };
2954
+ if (!store)
2955
+ return out;
2956
+ for (const askId of [...this.pendingByAskId.keys()]) {
2957
+ out.read += 1;
2958
+ const readSeq = this.nextRowReadSeq();
2959
+ let row;
2960
+ try {
2961
+ row = await this.withStoreDeadline(store.getAsk(askId), "getAsk(follow-row-owners)", DURABLE_CONVERGE_READ_TIMEOUT_MS);
2962
+ }
2963
+ catch (err) {
2964
+ this.noteStoreError(err, "getAsk(follow-row-owners)");
2965
+ out.unreadable += 1;
2966
+ continue;
2967
+ }
2968
+ if (row?.state !== "STREAM_PENDING")
2969
+ continue;
2970
+ this.followRowOwner(askId, row.owner, readSeq);
2971
+ out.followed += 1;
2972
+ }
2973
+ return out;
2979
2974
  }
2980
2975
  waitingRegistrationCount(askId) {
2981
2976
  let n = 0;
@@ -3051,6 +3046,7 @@ export class ToolApprovalCoordinator {
3051
3046
  else
3052
3047
  this.adoptedPollOffset = adoptedStart + ++polledAdopted;
3053
3048
  let row;
3049
+ const readSeq = this.nextRowReadSeq();
3054
3050
  try {
3055
3051
  row = await this.withStoreDeadline(store.getAsk(askId), "getAsk(poll-suspended)", DURABLE_CONVERGE_READ_TIMEOUT_MS);
3056
3052
  }
@@ -3063,7 +3059,7 @@ export class ToolApprovalCoordinator {
3063
3059
  continue;
3064
3060
  }
3065
3061
  if (row.state === "STREAM_PENDING") {
3066
- this.followAdoptedOwner(askId, row.owner);
3062
+ this.followRowOwner(askId, row.owner, readSeq);
3067
3063
  continue;
3068
3064
  }
3069
3065
  if (this.editedDecisionInFlight(askId))