@sema-agent/server 7.150.0 → 7.151.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/MIGRATION.md +185 -0
  2. package/USAGE.md +53 -25
  3. package/deploy/sema-up/README.md +7 -1
  4. package/deploy/sema-up/chart/Chart.yaml +1 -1
  5. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  6. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  7. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  8. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  9. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  10. package/deploy/sema-up/chart/values.yaml +8 -1
  11. package/deploy/sema-up/cluster-up.sh +1 -0
  12. package/deploy/sema-up/kube-up.sh +1 -1
  13. package/deploy/sema-up/lib/flagshape.sh +1 -1
  14. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  16. package/dist/adoption/import.js +3 -3
  17. package/dist/approval-ask-machine.d.ts +1 -1
  18. package/dist/approval-card.d.ts +2 -2
  19. package/dist/approval-gate-currency.d.ts +1 -1
  20. package/dist/auth-bridge.d.ts +20 -0
  21. package/dist/auth-bridge.js +9 -0
  22. package/dist/background-session-reap.d.ts +1 -1
  23. package/dist/bake-runner/main.d.ts +4 -2
  24. package/dist/bind-host.d.ts +2 -3
  25. package/dist/bind-host.js +2 -4
  26. package/dist/boot/budget-tracing.js +1 -1
  27. package/dist/boot/engine-lease.d.ts +5 -0
  28. package/dist/boot/engine-lease.js +1 -0
  29. package/dist/boot/execution-env.d.ts +8 -14
  30. package/dist/boot/execution-env.js +54 -17
  31. package/dist/boot/execution-lane.js +32 -5
  32. package/dist/boot/late-binds.d.ts +8 -4
  33. package/dist/boot/late-binds.js +7 -1
  34. package/dist/boot/memory-consolidation.d.ts +3 -2
  35. package/dist/boot/memory-consolidation.js +6 -6
  36. package/dist/boot/reapers.d.ts +5 -0
  37. package/dist/boot/reapers.js +12 -1
  38. package/dist/boot/resolve-spec.d.ts +3 -3
  39. package/dist/boot/resolve-spec.js +31 -22
  40. package/dist/boot/runner-deps.d.ts +9 -2
  41. package/dist/boot/runner-deps.js +3 -3
  42. package/dist/boot/session-age-out.d.ts +36 -0
  43. package/dist/boot/session-age-out.js +101 -0
  44. package/dist/boot/session-faces.d.ts +5 -14
  45. package/dist/boot/session-faces.js +9 -5
  46. package/dist/boot/stage-01-config.js +2 -0
  47. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  48. package/dist/boot/stage-05-execution-env.js +2 -2
  49. package/dist/boot/stage-06-runners.d.ts +7 -4
  50. package/dist/boot/stage-06-runners.js +15 -6
  51. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  52. package/dist/boot/stage-07-capability-layer.js +2 -1
  53. package/dist/boot/stage-08-reapers.d.ts +7 -4
  54. package/dist/boot/stage-08-reapers.js +4 -2
  55. package/dist/boot/stage-09-leader.d.ts +11 -5
  56. package/dist/boot/stage-09-leader.js +12 -3
  57. package/dist/boot/stage-10-http-server.d.ts +11 -5
  58. package/dist/boot/stage-10-http-server.js +3 -6
  59. package/dist/boot/web-admin.js +3 -1
  60. package/dist/boot/workflow-orchestration.d.ts +7 -2
  61. package/dist/boot/workflow-orchestration.js +24 -7
  62. package/dist/bounded-rotation.d.ts +29 -0
  63. package/dist/bounded-rotation.js +24 -0
  64. package/dist/capability-facts.d.ts +22 -13
  65. package/dist/capability-facts.js +28 -18
  66. package/dist/center-credential.d.ts +25 -6
  67. package/dist/center-credential.js +25 -5
  68. package/dist/config-catalog.d.ts +26 -7
  69. package/dist/config-catalog.js +14 -11
  70. package/dist/config-invariants.d.ts +2 -1
  71. package/dist/config-invariants.js +4 -4
  72. package/dist/config-types.d.ts +10 -4
  73. package/dist/config.d.ts +51 -2
  74. package/dist/config.js +35 -24
  75. package/dist/deployment-shape.d.ts +9 -1
  76. package/dist/deployment-shape.js +2 -1
  77. package/dist/device-protocol.d.ts +5 -4
  78. package/dist/device-protocol.js +1 -1
  79. package/dist/device-ws-hub.js +3 -2
  80. package/dist/device-ws-protocol.d.ts +63 -10
  81. package/dist/device-ws-protocol.js +56 -25
  82. package/dist/engine-identity.d.ts +19 -7
  83. package/dist/engine-identity.js +10 -2
  84. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  85. package/dist/execution-env-refusal.d.ts +23 -0
  86. package/dist/execution-env-refusal.js +5 -0
  87. package/dist/execution-lane-caps.d.ts +3 -1
  88. package/dist/field-conflict.d.ts +1 -1
  89. package/dist/file-history-capture.d.ts +11 -4
  90. package/dist/file-history-capture.js +9 -6
  91. package/dist/file-history-disclosure.d.ts +7 -5
  92. package/dist/file-history-disclosure.js +7 -5
  93. package/dist/fleet/drain-entry.d.ts +4 -0
  94. package/dist/hooks/hook-runner.js +2 -2
  95. package/dist/host-lsp-manager.d.ts +2 -2
  96. package/dist/http/admission.js +17 -2
  97. package/dist/http/approval-sweeps.js +5 -5
  98. package/dist/http/checkpoint-ctx.d.ts +2 -0
  99. package/dist/http/checkpoint-ctx.js +1 -0
  100. package/dist/http/dispatch.d.ts +2 -1
  101. package/dist/http/dispatch.js +34 -27
  102. package/dist/http/durable-run-leg.js +16 -16
  103. package/dist/http/health-self-report.d.ts +9 -1
  104. package/dist/http/health-self-report.js +2 -0
  105. package/dist/http/owner-access.d.ts +31 -11
  106. package/dist/http/owner-access.js +37 -6
  107. package/dist/http/resume-ctx-read.js +25 -3
  108. package/dist/http/resume-legs.d.ts +2 -1
  109. package/dist/http/resume-legs.js +259 -79
  110. package/dist/http/route-ctx.d.ts +18 -8
  111. package/dist/http/route-table.d.ts +1 -1
  112. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  113. package/dist/http/routes/agents-roster.js +2 -3
  114. package/dist/http/routes/approvals-assistant.js +4 -3
  115. package/dist/http/routes/background.d.ts +3 -3
  116. package/dist/http/routes/capabilities.js +8 -5
  117. package/dist/http/routes/fleet.js +10 -8
  118. package/dist/http/routes/projects.d.ts +3 -2
  119. package/dist/http/routes/projects.js +4 -5
  120. package/dist/http/routes/runs.js +102 -36
  121. package/dist/http/routes/session-sync.d.ts +4 -3
  122. package/dist/http/routes/session-sync.js +172 -77
  123. package/dist/http/routes/sessions-list.js +13 -7
  124. package/dist/http/routes/sessions.js +10 -6
  125. package/dist/http/routes/tasks.js +30 -16
  126. package/dist/http/routes/trace-usage.js +2 -2
  127. package/dist/http/server.d.ts +21 -27
  128. package/dist/http/server.js +2 -2
  129. package/dist/http/submit-ctx.js +5 -4
  130. package/dist/http/wire-types.d.ts +14 -4
  131. package/dist/identity-source.d.ts +20 -3
  132. package/dist/identity-source.js +14 -0
  133. package/dist/index.d.ts +4 -0
  134. package/dist/lane-home-probe.d.ts +3 -7
  135. package/dist/lane-home-probe.js +0 -1
  136. package/dist/leader/leader.d.ts +2 -1
  137. package/dist/leg-facts.d.ts +13 -5
  138. package/dist/leg-facts.js +2 -1
  139. package/dist/memory-scope.d.ts +5 -4
  140. package/dist/memory-scope.js +4 -4
  141. package/dist/memory-sync-client.d.ts +30 -2
  142. package/dist/memory-sync-client.js +16 -9
  143. package/dist/observability/err-text.d.ts +7 -0
  144. package/dist/observability/err-text.js +5 -0
  145. package/dist/observability/fail-open.d.ts +7 -3
  146. package/dist/observability/fail-open.js +7 -3
  147. package/dist/observability/metrics.js +1 -0
  148. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  149. package/dist/orchestration/workflow-notify-journal.js +12 -1
  150. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  151. package/dist/orchestration/workflow-park-decision.js +49 -10
  152. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  153. package/dist/orchestration/workflow-park-holder.js +98 -0
  154. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  155. package/dist/orchestration/workflow-record-fence.js +42 -0
  156. package/dist/owner-faces.d.ts +1 -1
  157. package/dist/parked-decide.d.ts +104 -53
  158. package/dist/parked-decide.js +153 -117
  159. package/dist/peer-directory.d.ts +2 -2
  160. package/dist/peer-inbound-face.d.ts +2 -6
  161. package/dist/peer-inbound-face.js +0 -3
  162. package/dist/permission-mode-admission.d.ts +41 -5
  163. package/dist/permission-mode-admission.js +29 -3
  164. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  165. package/dist/plugins/adoption-log-sql.js +7 -1
  166. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  167. package/dist/plugins/approval-ask-store-file.js +8 -0
  168. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  169. package/dist/plugins/approval-ask-store-memory.js +28 -9
  170. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  171. package/dist/plugins/approval-ask-store-sql.js +34 -5
  172. package/dist/plugins/approval-exemption-store.js +3 -0
  173. package/dist/plugins/approval-nonce-store.js +2 -0
  174. package/dist/plugins/breaker-state-sql.js +2 -0
  175. package/dist/plugins/caching-session-store.d.ts +9 -15
  176. package/dist/plugins/caching-session-store.js +6 -0
  177. package/dist/plugins/device-store-sql.js +6 -0
  178. package/dist/plugins/error-origin.d.ts +18 -0
  179. package/dist/plugins/error-origin.js +10 -0
  180. package/dist/plugins/execution-placement-sql.js +6 -6
  181. package/dist/plugins/image-bake-store-sql.js +6 -0
  182. package/dist/plugins/image-index-sql.js +4 -0
  183. package/dist/plugins/landed-attendants.d.ts +212 -0
  184. package/dist/plugins/landed-attendants.js +161 -0
  185. package/dist/plugins/leader-run-store-sql.js +4 -0
  186. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  187. package/dist/plugins/local-session-live-reference.js +39 -0
  188. package/dist/plugins/local-session-store.d.ts +71 -33
  189. package/dist/plugins/local-session-store.js +129 -27
  190. package/dist/plugins/memory-engine-pg.js +4 -0
  191. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  192. package/dist/plugins/memory-engine-tidb.js +4 -0
  193. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  194. package/dist/plugins/memory-sync-store-pg.js +5 -0
  195. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  196. package/dist/plugins/one-time-migrations.d.ts +57 -63
  197. package/dist/plugins/one-time-migrations.js +162 -90
  198. package/dist/plugins/org-delivery-quota-store.js +4 -1
  199. package/dist/plugins/outcome-ledger-sql.js +2 -0
  200. package/dist/plugins/permission-rule-store-sql.js +11 -4
  201. package/dist/plugins/pg-cost-quota.js +4 -0
  202. package/dist/plugins/pg-pool.js +24 -1
  203. package/dist/plugins/pg-rate-limiter.js +2 -0
  204. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  205. package/dist/plugins/posix-shell-fs.js +4 -1
  206. package/dist/plugins/remote-env-adb.d.ts +19 -15
  207. package/dist/plugins/remote-env-adb.js +41 -15
  208. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  209. package/dist/plugins/remote-env-connect-seat.js +72 -0
  210. package/dist/plugins/remote-env-device.d.ts +22 -5
  211. package/dist/plugins/remote-env-device.js +106 -8
  212. package/dist/plugins/remote-env-e2b.d.ts +15 -6
  213. package/dist/plugins/remote-env-e2b.js +42 -32
  214. package/dist/plugins/remote-env-file-error.js +6 -2
  215. package/dist/plugins/remote-env-host.d.ts +17 -0
  216. package/dist/plugins/remote-env-host.js +30 -38
  217. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  218. package/dist/plugins/remote-env-k8s.js +53 -30
  219. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  220. package/dist/plugins/remote-env-local-docker.js +34 -41
  221. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  222. package/dist/plugins/remote-env-ssh.js +60 -59
  223. package/dist/plugins/remote-shell.d.ts +98 -1
  224. package/dist/plugins/remote-shell.js +218 -0
  225. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  226. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  227. package/dist/plugins/retention-lane-store-sql.js +4 -0
  228. package/dist/plugins/retention-sql.d.ts +20 -2
  229. package/dist/plugins/retention-sql.js +11 -0
  230. package/dist/plugins/run-store-sql.d.ts +21 -2
  231. package/dist/plugins/run-store-sql.js +31 -7
  232. package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
  233. package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
  234. package/dist/plugins/schema-consistency.d.ts +4 -2
  235. package/dist/plugins/schema-consistency.js +19 -2
  236. package/dist/plugins/send-file-ledger.js +3 -0
  237. package/dist/plugins/serving-requirement.d.ts +26 -7
  238. package/dist/plugins/serving-requirement.js +11 -4
  239. package/dist/plugins/session-birth.d.ts +6 -2
  240. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  241. package/dist/plugins/session-ext-table.d.ts +14 -1
  242. package/dist/plugins/session-ext-table.js +5 -1
  243. package/dist/plugins/session-row-sql.d.ts +49 -2
  244. package/dist/plugins/session-row-sql.js +56 -13
  245. package/dist/plugins/session-store-sql.d.ts +34 -18
  246. package/dist/plugins/session-store-sql.js +98 -17
  247. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  248. package/dist/plugins/shared-memory-store-sql.js +6 -2
  249. package/dist/plugins/sql-driver.d.ts +2 -1
  250. package/dist/plugins/sql-driver.js +18 -3
  251. package/dist/plugins/sql-errors.d.ts +11 -6
  252. package/dist/plugins/sql-errors.js +5 -6
  253. package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
  254. package/dist/plugins/stop-then-start-sentence.js +14 -10
  255. package/dist/plugins/stop-then-start.d.ts +109 -0
  256. package/dist/plugins/stop-then-start.js +104 -0
  257. package/dist/plugins/store-backend.d.ts +40 -13
  258. package/dist/plugins/store-backend.js +169 -27
  259. package/dist/plugins/store-boundary.d.ts +57 -0
  260. package/dist/plugins/store-boundary.js +139 -0
  261. package/dist/plugins/store-contracts.d.ts +17 -0
  262. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  263. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  264. package/dist/plugins/store-fault.d.ts +26 -7
  265. package/dist/plugins/store-fault.js +18 -2
  266. package/dist/plugins/task-attachment-store.js +9 -0
  267. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  268. package/dist/plugins/task-list-store-sql.js +10 -8
  269. package/dist/plugins/tidb-cost-quota.js +4 -0
  270. package/dist/plugins/tidb-pool.js +2 -1
  271. package/dist/plugins/tidb-rate-limiter.js +4 -0
  272. package/dist/plugins/user-input-ledger-sql.js +4 -0
  273. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  274. package/dist/plugins/workflow-run-store-sql.js +64 -4
  275. package/dist/plugins/workspace-fill.d.ts +4 -7
  276. package/dist/plugins/workspace-fill.js +2 -1
  277. package/dist/plugins/write-behind-counter.js +5 -0
  278. package/dist/project-context.d.ts +0 -2
  279. package/dist/project-context.js +4 -8
  280. package/dist/project-registry.d.ts +46 -0
  281. package/dist/project-registry.js +44 -0
  282. package/dist/request-key-closure.js +1 -1
  283. package/dist/request-value-closure.d.ts +4 -0
  284. package/dist/request-value-closure.js +10 -0
  285. package/dist/run-acceptance.d.ts +3 -2
  286. package/dist/run-acceptance.js +4 -6
  287. package/dist/run-local.js +1 -0
  288. package/dist/runs.d.ts +37 -8
  289. package/dist/runs.js +53 -12
  290. package/dist/runtime-governance.d.ts +5 -4
  291. package/dist/security.d.ts +30 -32
  292. package/dist/security.js +41 -7
  293. package/dist/server-secret-env.d.ts +12 -10
  294. package/dist/server-secret-env.js +24 -15
  295. package/dist/session-bindings.d.ts +82 -0
  296. package/dist/session-bindings.js +18 -0
  297. package/dist/session-children-retire.d.ts +2 -2
  298. package/dist/session-children-retire.js +2 -6
  299. package/dist/session-deletion.d.ts +16 -1
  300. package/dist/session-error-wire.d.ts +3 -3
  301. package/dist/session-error-wire.js +3 -3
  302. package/dist/session-incarnation.d.ts +10 -0
  303. package/dist/session-incarnation.js +10 -1
  304. package/dist/session-kind.d.ts +57 -0
  305. package/dist/session-kind.js +22 -0
  306. package/dist/session-row.d.ts +21 -1
  307. package/dist/session-row.js +7 -1
  308. package/dist/session-sync-kernel.d.ts +24 -14
  309. package/dist/session-sync-kernel.js +3 -6
  310. package/dist/session-sync.d.ts +4 -98
  311. package/dist/session-sync.js +1 -71
  312. package/dist/session-titler.d.ts +10 -3
  313. package/dist/session-titler.js +19 -6
  314. package/dist/ssh-host-key.d.ts +5 -0
  315. package/dist/ssh-host-key.js +3 -0
  316. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  317. package/dist/stores-sql/file-history-store-sql.js +108 -70
  318. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  319. package/dist/stores-sql/pg-session-storage.js +37 -13
  320. package/dist/stores-sql/retention-store-sql.d.ts +1 -9
  321. package/dist/stores-sql/retention-store-sql.js +2 -10
  322. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  323. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  324. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  325. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  326. package/dist/stores-sql/tidb-session-store.js +37 -13
  327. package/dist/submission-exit.d.ts +3 -2
  328. package/dist/submission-exit.js +9 -1
  329. package/dist/task-cwd.d.ts +2 -2
  330. package/dist/task-settings.d.ts +6 -5
  331. package/dist/terminal.d.ts +33 -2
  332. package/dist/terminal.js +139 -9
  333. package/dist/tool-approval.d.ts +140 -6
  334. package/dist/tool-approval.js +165 -72
  335. package/dist/trace/self-minted-wire.d.ts +290 -27
  336. package/dist/trace/self-minted-wire.js +101 -13
  337. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +78 -27
  338. package/package.json +2 -2
  339. package/wire-changes/server@7.151.0.json +762 -0
  340. package/dist/http/session-inherit-env.d.ts +0 -36
  341. package/dist/http/session-inherit-env.js +0 -6
@@ -8,7 +8,7 @@ import { FileWorkflowJournalStore } from "@sema-agent/core";
8
8
  import { fileSessionCaptureRecordStore } from "@sema-agent/core";
9
9
  import { TiDBOutcomeLedger, PgOutcomeLedger } from "./outcome-ledger-sql.js";
10
10
  import { FileOutcomeSink } from "./file-outcome-sink.js";
11
- import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, TiDBWorkflowAgentSessionIndex, SqlWorkflowParkDecisionStore, PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore, PgWorkflowAgentSessionIndex } from "./workflow-run-store-sql.js";
11
+ import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, TiDBWorkflowAgentSessionIndex, SqlWorkflowParkDecisionStore, SqlWorkflowRunStore, PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore, PgWorkflowAgentSessionIndex } from "./workflow-run-store-sql.js";
12
12
  import { FileRunStore } from "./file-run-store.js";
13
13
  import { LocalWorkflowParkDecisionStore } from "../orchestration/workflow-park-decision.js";
14
14
  import { StoreBootRefusalError } from "./store-contracts.js";
@@ -25,6 +25,7 @@ import { SKILL_EXEMPTION_CUTOFF_ID } from "./one-time-migration-marker.js";
25
25
  import { LocalTaskAttachmentStore } from "./local-task-attachment-store.js";
26
26
  import { assertRetiredSchemaAbsentOnPool } from "./schema-consistency.js";
27
27
  import { LocalSessionStore, createLocalSessionRepo } from "./local-session-store.js";
28
+ import { createLocalWorkflowRunsSeat } from "./local-session-live-reference.js";
28
29
  import { localStoreDeclarationOf } from "../local-store-declaration.js";
29
30
  import { SESSION_PLACEMENTS } from "./session-placement.js";
30
31
  import { LocalCheckpointStore, dropLocalCheckpointCtxStrict } from "./local-checkpoint-store.js";
@@ -40,10 +41,11 @@ import { TiDBSendFileLedger, PgSendFileLedger, FileSendFileLedger } from "./send
40
41
  import { FileUserInputLedgerStore } from "./user-input-ledger-file.js";
41
42
  import { TiDBUserInputLedgerStore, PgUserInputLedgerStore } from "./user-input-ledger-sql.js";
42
43
  import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
43
- import { TiDBSessionPolicyStore, PgSessionPolicyStore } from "../stores-sql/session-policy-store-sql.js";
44
- import { countClientWriteOn } from "./session-withdraw-sql.js";
45
- import { TiDBWorkflowJournalStore, PgWorkflowJournalStore } from "../stores-sql/workflow-journal-store-sql.js";
46
- import { TiDBFileHistoryStore, PgFileHistoryStore, FILE_HISTORY_BLOB_KEY_PREFIX } from "../stores-sql/file-history-store-sql.js";
44
+ import { TiDBSessionPolicyStore, PgSessionPolicyStore, SqlSessionPolicyStore } from "../stores-sql/session-policy-store-sql.js";
45
+ import { SQL_SESSION_ROOT_SEAT } from "./session-row-sql.js";
46
+ import { TiDBWorkflowJournalStore, PgWorkflowJournalStore, SqlWorkflowJournalStore } from "../stores-sql/workflow-journal-store-sql.js";
47
+ import { TiDBFileHistoryStore, PgFileHistoryStore, FILE_HISTORY_BLOB_KEY_PREFIX, SqlFileHistoryStore } from "../stores-sql/file-history-store-sql.js";
48
+ import { createLocalLandedAttendantSeat, createSqlLandedAttendantSeat } from "./landed-attendants.js";
47
49
  import { SqlBlobIndex } from "../stores-sql/blob-index-sql.js";
48
50
  import { MinioBlobBackend } from "./blob-backend.js";
49
51
  import { buildDisplaySafeUrl } from "../trace/redact.js";
@@ -51,8 +53,8 @@ import { fileMemoryControlDirFor, memoryEngineRootFor } from "../memory-scope.js
51
53
  import { createTidbPool, ensureSchema as ensureTidbSchema } from "./tidb-pool.js";
52
54
  import { createPgPool, ensurePgSchema, pgPoolOptions } from "./pg-pool.js";
53
55
  import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
54
- import { TiDBCheckpointStore, PgCheckpointStore } from "../stores-sql/checkpoint-store-sql.js";
55
- import { TiDBToolResultStore, PgToolResultStore } from "../stores-sql/tool-result-store-sql.js";
56
+ import { TiDBCheckpointStore, PgCheckpointStore, SqlCheckpointStore } from "../stores-sql/checkpoint-store-sql.js";
57
+ import { TiDBToolResultStore, PgToolResultStore, SqlToolResultStore } from "../stores-sql/tool-result-store-sql.js";
56
58
  import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
57
59
  import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
58
60
  import { TiDBLeaderRunStore, PgLeaderRunStore } from "./leader-run-store-sql.js";
@@ -62,8 +64,8 @@ import { TiDBCostQuota } from "./tidb-cost-quota.js";
62
64
  import { PgCostQuota } from "./pg-cost-quota.js";
63
65
  import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
64
66
  import { PgRateLimiter } from "./pg-rate-limiter.js";
65
- import { TiDBSessionStore } from "../stores-sql/tidb-session-store.js";
66
- import { PgSessionStore } from "../stores-sql/pg-session-storage.js";
67
+ import { TiDBSessionStore, TiDBStagingHandle } from "../stores-sql/tidb-session-store.js";
68
+ import { PgSessionStore, PgSessionStorage, PgStagingHandle } from "../stores-sql/pg-session-storage.js";
67
69
  import { SqlSessionStore } from "./session-store-sql.js";
68
70
  import { TiDBSharedMemoryStore, PgSharedMemoryStore } from "./shared-memory-store-sql.js";
69
71
  import { TiDBAdoptionLogStore, PgAdoptionLogStore } from "./adoption-log-sql.js";
@@ -83,6 +85,13 @@ import { admitLocalDataRoot, holdLocalDataRootAdmission } from "./local-data-roo
83
85
  import { mysqlDriver, pgDriver } from "./sql-driver.js";
84
86
  import { localDataRootHoldsData, storeDegradedReasonFor } from "../store-posture.js";
85
87
  import { openWithinWait } from "./store-open-wait.js";
88
+ import { sealStoreClass, sealStoreObject } from "./store-boundary.js";
89
+ import { WindowedSessionStorage } from "../stores-sql/windowed-session-storage.js";
90
+ import { PgBackgroundAgentStore, TiDBBackgroundAgentStore } from "../stores-sql/background-agent-store-sql.js";
91
+ import { PgMailboxStore, TiDBMailboxStore } from "../stores-sql/mailbox-store-sql.js";
92
+ import { PgRosterStore, TiDBRosterStore } from "../stores-sql/roster-store-sql.js";
93
+ import { TiDBSessionStorage } from "../stores-sql/tidb-session-storage.js";
94
+ import { PgUsageWindowStore, TiDBUsageWindowStore } from "../stores-sql/usage-window-store-sql.js";
86
95
  export function createRunStallWiring(config, observers) {
87
96
  const count = observers?.runStallVerdicts;
88
97
  return { windowMs: () => config.runStaleSec * 1000, onVerdicts: (landed) => count?.(landed) };
@@ -151,7 +160,7 @@ export function createSqlRetentionExecutor(db, opts) {
151
160
  const hooks = createSqlRetentionCallHooks(db, opts, input);
152
161
  return { store: new SqlRetentionStore(db, { ...storeOpts, transactionHooks: hooks.hooks }), hooks, call: { domain: input.domain, cutoffMs: input.cutoffMs } };
153
162
  };
154
- return {
163
+ return sealStoreObject({
155
164
  retention: reads.retention,
156
165
  listRetentionDomains: () => reads.listRetentionDomains(),
157
166
  previewRetention: (input) => reads.previewRetention(input),
@@ -171,7 +180,7 @@ export function createSqlRetentionExecutor(db, opts) {
171
180
  const one = forCall(input);
172
181
  return one.store.deleteOrphanToolResults(one.call);
173
182
  },
174
- };
183
+ }, "sql-retention-executor", { listRetentionDomains: "exit", previewRetention: "exit", expireCheckpoints: "exit", deleteExpiredSessions: "exit", deleteOrphanToolResults: "exit" });
175
184
  }
176
185
  async function afterSessionErase(db, opts, sessions) {
177
186
  if (!opts.completionInbox || sessions.length === 0)
@@ -180,7 +189,7 @@ async function afterSessionErase(db, opts, sessions) {
180
189
  }
181
190
  export function createSqlSessionEraser(db, opts) {
182
191
  const storeOpts = { ...(opts.mailboxTables ? { sessionBoxScope: sessionTenantScope } : {}), ...(opts.logger !== undefined ? { logger: opts.logger } : {}) };
183
- return {
192
+ return sealStoreObject({
184
193
  async erase(input) {
185
194
  const rows = createSessionRowsHook(db.dialect, opts, input.owner ?? "");
186
195
  const store = new SqlRetentionStore(db, { ...storeOpts, transactionHooks: { retention: { beforeDelete: rows.beforeDelete }, session: createSqlSessionWriteHooks(db) } });
@@ -201,7 +210,7 @@ export function createSqlSessionEraser(db, opts) {
201
210
  }
202
211
  }
203
212
  },
204
- };
213
+ }, "sql-session-eraser", { erase: "exit" });
205
214
  }
206
215
  export function assertCloudSnapshotBlobPosture(kind, config) {
207
216
  if (kind === "local" || config.snapshotBlobStore || config.snapshotBlobAllowSql)
@@ -226,21 +235,42 @@ const SQL_BLOB_POSTURE_FACTS = {
226
235
  export function buildSqlOneTimeMigrationInput(config) {
227
236
  return { lanes: deployedExecutionLanes(config), liveRunWindowMs: config.runStaleSec * 1000, identityBoundary: DEPLOYMENT_SHAPE_PREDICATES.identityBoundary.holds(config) };
228
237
  }
238
+ function decisionStoreBoundOnce(held, records, make) {
239
+ if (held === undefined)
240
+ return make();
241
+ if (held.records !== records)
242
+ throw new Error("store backend: the workflow park decision store is already bound to another workflow record store — a backend keeps one decision store, fenced by the one record store every workflow record write goes through");
243
+ return held;
244
+ }
245
+ function sqlRecordFenceOf(records) {
246
+ if (records instanceof SqlWorkflowRunStore)
247
+ return records;
248
+ throw new Error("SQL store backend: the workflow park decision store's record fence must be this backend's SQL workflow record store (workflowRun()) — a decision row is written in the same transaction that locks the run's record row");
249
+ }
250
+ function policyStoreLoggerOf(onWarn) {
251
+ return onWarn !== undefined ? { warn: (msg, fields) => onWarn(msg, fields) } : createLogger();
252
+ }
253
+ export function sqlLandedAttendantsOf(db, history, policy) {
254
+ return createSqlLandedAttendantSeat(db, { history, policy });
255
+ }
229
256
  class TiDBBackend {
230
257
  pool;
231
258
  config;
232
259
  observers;
260
+ onWarn;
233
261
  kind = "mysql";
234
- constructor(pool, config, observers) {
262
+ constructor(pool, config, observers, onWarn) {
235
263
  this.pool = pool;
236
264
  this.config = config;
237
265
  this.observers = observers;
266
+ this.onWarn = onWarn;
238
267
  }
239
268
  ensureSchema() { return ensureTidbSchema(this.pool); }
240
269
  close() { return this.pool.end(); }
241
270
  run() { return (this.runStoreInst ??= new TiDBRunStore(this.pool, createRunStallWiring(this.config, this.observers))); }
242
271
  runStoreInst;
243
- resumeAnchor() { return new TiDBResumeAnchorStore(this.pool); }
272
+ resumeAnchor() { return (this.resumeAnchorInst ??= new TiDBResumeAnchorStore(this.pool)); }
273
+ resumeAnchorInst;
244
274
  approvalExemption() { return new TiDBApprovalExemptionStore(this.pool); }
245
275
  approvalNonce() { return new TiDBApprovalNonceStore(this.pool); }
246
276
  orgDeliveryQuota() { return new TiDBOrgDeliveryQuotaStore(this.pool); }
@@ -248,8 +278,12 @@ class TiDBBackend {
248
278
  permissionRule() { return createSqlPermissionRuleStores(mysqlDriver(this.pool)); }
249
279
  sendFileLedger() { return new TiDBSendFileLedger(this.pool); }
250
280
  userInputLedger() { return new TiDBUserInputLedgerStore(this.pool); }
251
- sessionPolicy(logger) { return new TiDBSessionPolicyStore(this.pool, countClientWriteOn, logger ?? createLogger()); }
252
- fileHistory() { return new TiDBFileHistoryStore(this.pool, fileHistoryOptions(this.config)); }
281
+ sessionPolicy() { return (this.sessionPolicyInst ??= new TiDBSessionPolicyStore(this.pool, SQL_SESSION_ROOT_SEAT, policyStoreLoggerOf(this.onWarn))); }
282
+ sessionPolicyInst;
283
+ fileHistory() { return (this.fileHistoryInst ??= new TiDBFileHistoryStore(this.pool, fileHistoryOptions(this.config))); }
284
+ fileHistoryInst;
285
+ landedAttendants() { return (this.landedAttendantsInst ??= sqlLandedAttendantsOf(mysqlDriver(this.pool), this.fileHistory(), this.sessionPolicy())); }
286
+ landedAttendantsInst;
253
287
  memoryOptOutGrant() { return new TiDBMemoryOptOutGrantStore(this.pool); }
254
288
  sessionCaptureRecords() { return () => (this.captureRecordsInst ??= new TiDBSessionCaptureRecordStore(this.pool)); }
255
289
  captureRecordsInst;
@@ -261,7 +295,7 @@ class TiDBBackend {
261
295
  completionInbox(onWarn) { return new TiDBWorkflowCompletionInbox(this.pool, onWarn); }
262
296
  notifyJournal() { return new TiDBWorkflowNotifyJournalStore(this.pool); }
263
297
  workflowAgentSessionIndex() { return new TiDBWorkflowAgentSessionIndex(this.pool); }
264
- workflowParkDecisions() { return (this.parkDecisionsInst ??= new SqlWorkflowParkDecisionStore(this.run())); }
298
+ workflowParkDecisions(records) { return (this.parkDecisionsInst = decisionStoreBoundOnce(this.parkDecisionsInst, records, () => new SqlWorkflowParkDecisionStore(this.run(), sqlRecordFenceOf(records)))); }
265
299
  parkDecisionsInst;
266
300
  sharedMemoryStore(authorizer) { return new TiDBSharedMemoryStore(this.pool, authorizer); }
267
301
  checkpoint(logger) { return new TiDBCheckpointStore(this.pool, logger, { retention: sqlStoreRetention(this.config.retentionSweep) }); }
@@ -283,21 +317,33 @@ class TiDBBackend {
283
317
  pgPool() { return undefined; }
284
318
  async dbNowMs() { const [rows] = await this.pool.query("SELECT ROUND(UNIX_TIMESTAMP(NOW(3))*1000) AS ms"); return Number(rows[0]?.ms); }
285
319
  }
320
+ sealStoreClass(TiDBBackend, "tidb-backend", {
321
+ ensureSchema: "boot", close: "boot", run: "exit", resumeAnchor: "exit", approvalExemption: "exit", approvalNonce: "exit", orgDeliveryQuota: "exit",
322
+ approvalAsk: "exit", permissionRule: "exit", sendFileLedger: "exit", userInputLedger: "exit", sessionPolicy: "exit", fileHistory: "exit",
323
+ memoryOptOutGrant: "exit", sessionCaptureRecords: "exit", legacySnapshotBlobSweep: "exit", runOneTimeMigrations: "boot", workflowJournal: "exit",
324
+ outcomeSink: "exit", workflowRun: "exit", completionInbox: "exit", notifyJournal: "exit", workflowAgentSessionIndex: "exit", workflowParkDecisions: "exit",
325
+ sharedMemoryStore: "exit", checkpoint: "exit", checkpointReadView: "exit", toolResult: "exit", imageIndex: "exit", imageBake: "exit", leaderRun: "exit",
326
+ device: "exit", retention: "exit", sessionEraser: "exit", retentionLane: "exit", breaker: "exit", costQuota: "exit", rateLimiter: "exit", session: "exit",
327
+ adoptionLog: "exit", mysqlPool: "boot", pgPool: "boot", dbNowMs: "exit", landedAttendants: "exit",
328
+ });
286
329
  class PgBackend {
287
330
  pool;
288
331
  config;
289
332
  observers;
333
+ onWarn;
290
334
  kind = "pg";
291
- constructor(pool, config, observers) {
335
+ constructor(pool, config, observers, onWarn) {
292
336
  this.pool = pool;
293
337
  this.config = config;
294
338
  this.observers = observers;
339
+ this.onWarn = onWarn;
295
340
  }
296
341
  ensureSchema() { return ensurePgSchema(this.pool); }
297
342
  close() { return this.pool.end(); }
298
343
  run() { return (this.runStoreInst ??= new PgRunStore(this.pool, createRunStallWiring(this.config, this.observers))); }
299
344
  runStoreInst;
300
- resumeAnchor() { return new PgResumeAnchorStore(this.pool); }
345
+ resumeAnchor() { return (this.resumeAnchorInst ??= new PgResumeAnchorStore(this.pool)); }
346
+ resumeAnchorInst;
301
347
  approvalExemption() { return new PgApprovalExemptionStore(this.pool); }
302
348
  approvalNonce() { return new PgApprovalNonceStore(this.pool); }
303
349
  orgDeliveryQuota() { return new PgOrgDeliveryQuotaStore(this.pool); }
@@ -305,8 +351,12 @@ class PgBackend {
305
351
  permissionRule() { return createSqlPermissionRuleStores(pgDriver(this.pool)); }
306
352
  sendFileLedger() { return new PgSendFileLedger(this.pool); }
307
353
  userInputLedger() { return new PgUserInputLedgerStore(this.pool); }
308
- sessionPolicy(logger) { return new PgSessionPolicyStore(this.pool, countClientWriteOn, logger ?? createLogger()); }
309
- fileHistory() { return new PgFileHistoryStore(this.pool, fileHistoryOptions(this.config)); }
354
+ sessionPolicy() { return (this.sessionPolicyInst ??= new PgSessionPolicyStore(this.pool, SQL_SESSION_ROOT_SEAT, policyStoreLoggerOf(this.onWarn))); }
355
+ sessionPolicyInst;
356
+ fileHistory() { return (this.fileHistoryInst ??= new PgFileHistoryStore(this.pool, fileHistoryOptions(this.config))); }
357
+ fileHistoryInst;
358
+ landedAttendants() { return (this.landedAttendantsInst ??= sqlLandedAttendantsOf(pgDriver(this.pool), this.fileHistory(), this.sessionPolicy())); }
359
+ landedAttendantsInst;
310
360
  memoryOptOutGrant() { return new PgMemoryOptOutGrantStore(this.pool); }
311
361
  sessionCaptureRecords() { return () => (this.captureRecordsInst ??= new PgSessionCaptureRecordStore(this.pool)); }
312
362
  captureRecordsInst;
@@ -318,7 +368,7 @@ class PgBackend {
318
368
  completionInbox(onWarn) { return new PgWorkflowCompletionInbox(this.pool, onWarn); }
319
369
  notifyJournal() { return new PgWorkflowNotifyJournalStore(this.pool); }
320
370
  workflowAgentSessionIndex() { return new PgWorkflowAgentSessionIndex(this.pool); }
321
- workflowParkDecisions() { return (this.parkDecisionsInst ??= new SqlWorkflowParkDecisionStore(this.run())); }
371
+ workflowParkDecisions(records) { return (this.parkDecisionsInst = decisionStoreBoundOnce(this.parkDecisionsInst, records, () => new SqlWorkflowParkDecisionStore(this.run(), sqlRecordFenceOf(records)))); }
322
372
  parkDecisionsInst;
323
373
  sharedMemoryStore(authorizer) { return new PgSharedMemoryStore(this.pool, authorizer); }
324
374
  checkpoint(logger) { return new PgCheckpointStore(this.pool, logger, { retention: sqlStoreRetention(this.config.retentionSweep) }); }
@@ -340,6 +390,15 @@ class PgBackend {
340
390
  pgPool() { return this.pool; }
341
391
  async dbNowMs() { const res = await this.pool.query("SELECT ROUND(EXTRACT(EPOCH FROM now())*1000) AS ms"); return Number(res.rows[0]?.ms); }
342
392
  }
393
+ sealStoreClass(PgBackend, "pg-backend", {
394
+ ensureSchema: "boot", close: "boot", run: "exit", resumeAnchor: "exit", approvalExemption: "exit", approvalNonce: "exit", orgDeliveryQuota: "exit",
395
+ approvalAsk: "exit", permissionRule: "exit", sendFileLedger: "exit", userInputLedger: "exit", sessionPolicy: "exit", fileHistory: "exit",
396
+ memoryOptOutGrant: "exit", sessionCaptureRecords: "exit", legacySnapshotBlobSweep: "exit", runOneTimeMigrations: "boot", workflowJournal: "exit",
397
+ outcomeSink: "exit", workflowRun: "exit", completionInbox: "exit", notifyJournal: "exit", workflowAgentSessionIndex: "exit", workflowParkDecisions: "exit",
398
+ sharedMemoryStore: "exit", checkpoint: "exit", checkpointReadView: "exit", toolResult: "exit", imageIndex: "exit", imageBake: "exit", leaderRun: "exit",
399
+ device: "exit", retention: "exit", sessionEraser: "exit", retentionLane: "exit", breaker: "exit", costQuota: "exit", rateLimiter: "exit", session: "exit",
400
+ adoptionLog: "exit", mysqlPool: "boot", pgPool: "boot", dbNowMs: "exit", landedAttendants: "exit",
401
+ });
343
402
  export function localSessionRowsOf(backend) {
344
403
  return backend instanceof LocalBackend ? backend.session() : undefined;
345
404
  }
@@ -364,6 +423,7 @@ class LocalBackend {
364
423
  fileBackend;
365
424
  runStore;
366
425
  sessionStore;
426
+ workflowRunsSeat = createLocalWorkflowRunsSeat();
367
427
  resumeAnchorStore;
368
428
  approvalExemptionStore;
369
429
  approvalNonceStore;
@@ -399,11 +459,17 @@ class LocalBackend {
399
459
  stall: createRunStallWiring(config, observers),
400
460
  });
401
461
  const physicalRoot = this.fileBackend.root;
462
+ const checkpoints = this.fileBackend.checkpointStore;
463
+ const listCheckpoints = checkpoints.listBySession;
464
+ const ageOut = listCheckpoints !== undefined
465
+ ? { liveReferences: { checkpoints: { listBySession: (q) => listCheckpoints.call(checkpoints, q) }, agents: this.fileBackend.backgroundAgentStore, workflows: this.workflowRunsSeat } }
466
+ : {};
402
467
  this.sessionStore = new LocalSessionStore(createLocalSessionRepo(physicalRoot), this.runStore, physicalRoot, {
403
468
  log: createLogger(config.logLevel),
404
469
  durability: this.storeDeclaration.durability,
405
470
  placements: SESSION_PLACEMENTS,
406
471
  withdrawCheckpointCtx: (sessionId) => dropLocalCheckpointCtxStrict(physicalRoot, sessionId),
472
+ ...ageOut,
407
473
  });
408
474
  this.parkDecisionLedgerRoot = config.workflowRunStoreBackend === "memory" ? undefined : join(this.fileBackend.root, "workflows");
409
475
  this.resumeAnchorStore = new FileResumeAnchorStore(this.fileBackend.root);
@@ -518,8 +584,10 @@ class LocalBackend {
518
584
  await this.fileBackend.dispose();
519
585
  }
520
586
  run() { return this.runStore; }
521
- workflowParkDecisions() {
522
- return (this.parkDecisionsInst ??= new LocalWorkflowParkDecisionStore(this.runStore, this.parkDecisionLedgerRoot));
587
+ workflowParkDecisions(records) {
588
+ if (records instanceof SqlWorkflowRunStore)
589
+ throw new Error("local store backend: the workflow park decision store's record fence must be the in-process record fence (FencedWorkflowRecordStore), not a SQL record store — the local backend keeps its decisions in this process");
590
+ return (this.parkDecisionsInst = decisionStoreBoundOnce(this.parkDecisionsInst, records, () => new LocalWorkflowParkDecisionStore(this.runStore, records, this.parkDecisionLedgerRoot)));
523
591
  }
524
592
  parkDecisionsInst;
525
593
  resumeAnchor() { return this.resumeAnchorStore; }
@@ -565,12 +633,15 @@ class LocalBackend {
565
633
  localStoreDeclaration() { return this.storeDeclaration; }
566
634
  fileUsageWindowStore() { return this.fileBackend.usageWindowStore; }
567
635
  fileHistory() { return this.fileBackend.fileHistoryStore; }
636
+ landedAttendants() { return (this.landedAttendantsInst ??= createLocalLandedAttendantSeat({ sessions: this.sessionStore, history: this.fileBackend.fileHistoryStore, policy: this.fileBackend.sessionPolicyStore, anchors: this.resumeAnchorStore })); }
637
+ landedAttendantsInst;
568
638
  memoryOptOutGrant() { return undefined; }
569
639
  sessionCaptureRecords() { return this.captureRecordsSource; }
570
640
  captureRecordsSource;
571
641
  workflowJournal() { return this.workflowJournalStore; }
572
642
  outcomeSink() { return this.outcomeSinkInst; }
573
643
  session() { return this.sessionStore; }
644
+ bindWorkflowRunReader(reader) { this.workflowRunsSeat.bind(reader); }
574
645
  toolResult() { return this.fileBackend.toolResultStore; }
575
646
  engineFileStores() {
576
647
  const fb = this.fileBackend;
@@ -649,6 +720,7 @@ class RefusedLocalBackend {
649
720
  userInputLedger() { return this.refused(); }
650
721
  sessionPolicy() { return this.refused(); }
651
722
  fileHistory() { return this.refused(); }
723
+ landedAttendants() { return this.refused(); }
652
724
  memoryOptOutGrant() { return this.refused(); }
653
725
  sessionCaptureRecords() { return this.refused(); }
654
726
  workflowJournal() { return this.refused(); }
@@ -659,6 +731,7 @@ class RefusedLocalBackend {
659
731
  toolResult() { return this.refused(); }
660
732
  fileUsageWindowStore() { return this.refused(); }
661
733
  localStoreDeclaration() { return this.refused(); }
734
+ bindWorkflowRunReader() { this.refused(); }
662
735
  mysqlPool() { return undefined; }
663
736
  pgPool() { return undefined; }
664
737
  }
@@ -669,12 +742,12 @@ export function createStoreBackend(config, onWarn, onError, observers) {
669
742
  if (!config.pg)
670
743
  return undefined;
671
744
  const pool = createPgPool(pgPoolOptions(config.pg, config.dbQueryTimeoutMs), onWarn);
672
- return withRetiredSchemaProbe(new PgBackend(pool, config, observers), { dialect: "pg", pool }, { lanes: deployedExecutionLanes(config) });
745
+ return withRetiredSchemaProbe(new PgBackend(pool, config, observers, onWarn), { dialect: "pg", pool }, { lanes: deployedExecutionLanes(config) });
673
746
  }
674
747
  if (!config.tidb)
675
748
  return undefined;
676
749
  const pool = createTidbPool(config);
677
- return withRetiredSchemaProbe(new TiDBBackend(pool, config, observers), { dialect: "mysql", pool }, { lanes: deployedExecutionLanes(config) });
750
+ return withRetiredSchemaProbe(new TiDBBackend(pool, config, observers, onWarn), { dialect: "mysql", pool }, { lanes: deployedExecutionLanes(config) });
678
751
  }
679
752
  function openAdmittedLocalBackend(config, admission, sinks) {
680
753
  let admitted = admission;
@@ -770,4 +843,73 @@ export function buildSqlStoreOpenRefusal(engine, endpoint, waitedMs, err) {
770
843
  next +
771
844
  `or run explicitly in memory with DB_BACKEND=memory (and remove the ${coords} coordinates).`);
772
845
  }
846
+ sealStoreClass(WindowedSessionStorage, "windowed-session-storage", {
847
+ getMetadata: "exit", getLeafId: "exit", createEntryId: "exit", findEntries: "exit", getLabel: "exit", getPathToRoot: "exit", getEntries: "exit",
848
+ getFloorId: "exit", getReplayLoss: "exit", logMarkNow: "exit", getEntry: "exit", appendEntry: "exit", setLeafId: "exit",
849
+ });
850
+ sealStoreClass(TiDBBackgroundAgentStore, "tidb-background-agent-store", {
851
+ put: "exit", get: "exit", update: "exit", updateIf: "exit", listBySession: "exit", listByScope: "exit", delete: "exit", reap: "exit", listScopes: "exit",
852
+ });
853
+ sealStoreClass(PgBackgroundAgentStore, "pg-background-agent-store", {
854
+ put: "exit", get: "exit", update: "exit", updateIf: "exit", listBySession: "exit", listByScope: "exit", delete: "exit", reap: "exit", listScopes: "exit",
855
+ });
856
+ sealStoreClass(SqlBlobIndex, "sql-blob-index", { put: "exit", get: "exit", has: "exit", sweep: "exit" });
857
+ sealStoreClass(SqlCheckpointStore, "sql-checkpoint-store", {
858
+ put: "exit", get: "exit", listBySession: "exit", resolve: "exit", reopen: "exit", recordExecutionOutcome: "exit", setPendingSteer: "exit", expire: "exit",
859
+ reap: "exit", reapExpired: "exit", listExpiredApprovalGates: "exit", listPending: "exit", listByScope: "exit", listPendingSessionIds: "exit",
860
+ findPendingTokenBySession: "exit", findCheckpointCandidatesForAsk: "exit", findDecidedApprovalsForBinding: "exit", peekScopeByToken: "exit",
861
+ peekPendingScope: "exit", hostSessionOfCard: "exit", putCtx: "exit", getCtx: "exit", rewriteCtxWhileClaimed: "exit", rewriteCtxRows: "exit", reapCtx: "exit",
862
+ deleteBySession: "exit",
863
+ });
864
+ sealStoreClass(SqlFileHistoryStore, "sql-file-history-store", {
865
+ trackEdit: "exit", annulTrack: "exit", snapshot: "exit", restore: "exit", canRestore: "exit", reap: "exit", deleteBySession: "exit", sweepOrphanBlobs: "exit",
866
+ adoptScope: "exit", exportHistory: "exit", importHistory: "exit", importFailureOf: "exit", prepareImport: "exit",
867
+ lockScopeOn: "in-store", publishImportOn: "in-store", deleteScopeOn: "in-store",
868
+ });
869
+ sealStoreClass(TiDBMailboxStore, "tidb-mailbox-store", {
870
+ append: "exit", claimLease: "exit", ack: "exit", moveDecision: "exit", releaseLease: "exit", peekCount: "exit", drop: "exit", reap: "exit",
871
+ retireRecipient: "exit", listRetiredRecipients: "exit",
872
+ });
873
+ sealStoreClass(PgMailboxStore, "pg-mailbox-store", {
874
+ append: "exit", claimLease: "exit", ack: "exit", moveDecision: "exit", releaseLease: "exit", peekCount: "exit", drop: "exit", reap: "exit",
875
+ retireRecipient: "exit", listRetiredRecipients: "exit",
876
+ });
877
+ sealStoreClass(PgSessionStorage, "pg-session-storage", {
878
+ getMetadata: "exit", getLeafId: "exit", createEntryId: "exit", findEntries: "exit", getLabel: "exit", getPathToRoot: "exit", getEntries: "exit",
879
+ getFloorId: "exit", getReplayLoss: "exit", logMarkNow: "exit", getEntry: "exit", appendEntry: "exit", setLeafId: "exit", getEpochAnchor: "exit",
880
+ });
881
+ sealStoreObject(PgSessionStorage, "pg-session-storage-static", { wake: "exit" });
882
+ sealStoreClass(PgSessionStore, "pg-session-store", {
883
+ acquire: "exit", register: "exit", registerWithReceipt: "exit", deleteSessionIf: "exit", placementOf: "exit", listPlaced: "exit", headOf: "exit",
884
+ touch: "exit", release: "exit", forget: "exit", fork: "exit", forkTo: "exit", exportEntries: "exit", listEntryIds: "exit", exportEntriesStream: "exit",
885
+ importEntries: "exit", replaceEntries: "exit", beginImportStaging: "exit", readStagedEntries: "exit", sweepStagingSessions: "exit", dispose: "exit",
886
+ });
887
+ sealStoreClass(PgStagingHandle, "pg-staging-handle", { appendBatch: "exit", commit: "exit", abort: "exit" });
888
+ sealStoreClass(SqlRetentionStore, "sql-retention-store", {
889
+ listRetentionDomains: "exit", previewRetention: "exit", expireCheckpoints: "exit", deleteExpiredSessions: "exit", eraseSession: "exit",
890
+ deleteOrphanToolResults: "exit",
891
+ });
892
+ sealStoreClass(TiDBRosterStore, "tidb-roster-store", { record: "exit", resolve: "exit", list: "exit", releaseAgent: "exit", reapOlderThan: "exit" });
893
+ sealStoreClass(PgRosterStore, "pg-roster-store", { record: "exit", resolve: "exit", list: "exit", releaseAgent: "exit", reapOlderThan: "exit" });
894
+ sealStoreClass(SqlSessionPolicyStore, "sql-session-policy-store", {
895
+ getRules: "exit", listBySession: "exit", putRules: "exit", deleteBySession: "exit", discloseErased: "exit", isDupKeyError: "exit",
896
+ putRulesOn: "in-store", eraseOn: "in-store",
897
+ });
898
+ sealStoreClass(TiDBSessionStorage, "tidb-session-storage", {
899
+ getMetadata: "exit", getLeafId: "exit", createEntryId: "exit", findEntries: "exit", getLabel: "exit", getPathToRoot: "exit", getEntries: "exit",
900
+ getFloorId: "exit", getReplayLoss: "exit", logMarkNow: "exit", getEntry: "exit", appendEntry: "exit", setLeafId: "exit", getEpochAnchor: "exit",
901
+ });
902
+ sealStoreObject(TiDBSessionStorage, "tidb-session-storage-static", { wake: "exit" });
903
+ sealStoreClass(TiDBSessionStore, "tidb-session-store", {
904
+ acquire: "exit", register: "exit", registerWithReceipt: "exit", deleteSessionIf: "exit", placementOf: "exit", listPlaced: "exit", headOf: "exit",
905
+ touch: "exit", release: "exit", forget: "exit", fork: "exit", forkTo: "exit", exportEntries: "exit", listEntryIds: "exit", exportEntriesStream: "exit",
906
+ importEntries: "exit", replaceEntries: "exit", beginImportStaging: "exit", readStagedEntries: "exit", sweepStagingSessions: "exit", dispose: "exit",
907
+ });
908
+ sealStoreClass(TiDBStagingHandle, "tidb-staging-handle", { appendBatch: "exit", commit: "exit", abort: "exit" });
909
+ sealStoreClass(SqlToolResultStore, "sql-tool-result-store", { put: "exit", ownerOf: "exit", get: "exit", reap: "exit", deleteBySession: "exit" });
910
+ sealStoreClass(TiDBUsageWindowStore, "tidb-usage-window-store", { charge: "exit", read: "exit" });
911
+ sealStoreClass(PgUsageWindowStore, "pg-usage-window-store", { charge: "exit", read: "exit" });
912
+ sealStoreClass(SqlWorkflowJournalStore, "sql-workflow-journal-store", {
913
+ append: "exit", load: "exit", locator: "exit", loadPage: "exit", resumeClaim: "exit", releaseResumeClaim: "exit", reapExpired: "exit",
914
+ });
773
915
  //# sourceMappingURL=store-backend.js.map
@@ -0,0 +1,57 @@
1
+ import type { SqlExec } from "./sql-driver.js";
2
+ /** T 的公开成员里**一切可调用**的键(含可选成员、同步或 Promise 联合返回;`keyof` 天然不含 private / protected;getter 不是可调用成员)。 */
3
+ export type CallableKeysOf<T> = {
4
+ [K in keyof T]-?: NonNullable<T[K]> extends (...a: never[]) => unknown ? K : never;
5
+ }[keyof T];
6
+ /** 出口表的闭集三词(见文件头注)。 */
7
+ export type StoreExitWord = "exit" | "boot" | "in-store";
8
+ /** 成员的首参是不是调用方借来的语句面(`SqlExec` 形:事务连接 / 它的 `query` 面)—— `in-store` 只许给这一形。首参可缺省 / 是别的型 ⇒ 不是。 */
9
+ type LendsStatementFace<F> = F extends (first: infer P, ...rest: never[]) => unknown ? ([P] extends [SqlExec] ? true : false) : false;
10
+ /** 一只店的出口表:每个公开可调用成员的去处(闭集三词,见文件头注;借语句面的成员 `exit | in-store`,其余 `exit | boot`)。 */
11
+ export type StoreExitPlan<T> = Readonly<{
12
+ [K in CallableKeysOf<T>]: LendsStatementFace<NonNullable<T[K]>> extends true ? "exit" | "in-store" : "exit" | "boot";
13
+ }>;
14
+ /**
15
+ * `boot` 一词只许这些名字(闭集):只在起服阶段被调、它们的错进起服拒句(要库的原码 / 原句,`databaseAnswerCodesOf` 一类读者),或交出给起服装配的原始池。
16
+ * · `ensureSchema` / `runOneTimeMigrations`:起服建表与一次性迁移(stage-01..04);
17
+ * · `close`:停机时关池(错进停机日志);
18
+ * · `mysqlPool` / `pgPool`:后端交给起服装配的原始池 —— 装配拿它铸的店各自封口(记忆引擎、会话审计、任务清单车道)。
19
+ */
20
+ export declare const BOOT_METHOD_NAMES: ReadonlySet<string>;
21
+ /** 封过的成员带的标记(值 = 它的 `site`):门读它判「这一只封过」;继承成员靠它断言基类先封。 */
22
+ export declare const SEALED_STORE_MEMBER: unique symbol;
23
+ /** 一次封口的登记(门读):店词、形(类 / 对象)、名字、出口表。对象形按店词只登记第一次(工厂每次调用都铸新对象,登记不随调用次数增长)。 */
24
+ export interface StoreSealRecord {
25
+ readonly store: string;
26
+ readonly kind: "class" | "object";
27
+ readonly name: string;
28
+ readonly plan: Readonly<Record<string | symbol, StoreExitWord>>;
29
+ }
30
+ /** 本进程已登记的封口(门读;不可写)。 */
31
+ export declare function storeSealRecords(): readonly StoreSealRecord[];
32
+ /**
33
+ * 封一只店类:`plan` 里每个 `exit` 成员 —— 本类原型上**自有**的 ⇒ 包一层;继承来的 ⇒ 断言继承到的那一只已封(否则加载即抛:先封基类)。
34
+ * 封口行住在店类的定义旁边;`src/stores-sql/**` 的店类例外 —— 那个目录要能原样搬进 core 包(对本仓其余部分零依赖,`test/dependency-direction-gate.test.ts` R8),
35
+ * 店边界是本服务的事(运维日志座、对外句词表),所以它们的封口住在组合座 `plugins/store-backend.ts`(装配它们的那一处)。
36
+ * 形参读类的 `prototype`(不读构造签名):受保护 / 抽象构造器的店基类同样能封;出口表按原型的实例形 `P` 穷尽。
37
+ * 异步生成器方法照封(调用交回的生成器对象由封口同封,迭代中途的错同样过边界);同步生成器方法拒封(加载即抛:它的错在调用返回之后才发生,封口接不住)。
38
+ */
39
+ export declare function sealStoreClass<P extends object>(ctor: {
40
+ readonly prototype: P;
41
+ readonly name: string;
42
+ }, store: string, plan: StoreExitPlan<P>): void;
43
+ /**
44
+ * 封一只对象(工厂产物 / 读器 / 事务对象 / 店类的静态面):原地包 `plan` 里每个 `exit` 的自有可调用属性,交回**同一引用**。
45
+ * 运行期另断言「对象自有的可调用属性 ⊆ 表的键」(普通对象;工厂的对象先 `satisfies` 接口保住具体类型;多出一个 ⇒ 封口时就抛)。表里的可选成员对象上可以没有。
46
+ * 类的静态面(构造器)同样经这一只封;它的穷尽只靠编译期的表(TS 私有的静态成员运行期看不出私有)。
47
+ */
48
+ export declare function sealStoreObject<T extends object>(obj: T, store: string, plan: StoreExitPlan<T>): T;
49
+ /**
50
+ * 封一只**导出的自由函数**出店口(它自己借连接、拨库,调用方是店外的装配 / 读面 —— 不是哪只已封店方法的体):交回同签名的包过的函数,
51
+ * 同步抛与拒绝都过边界。`site` 是 `<店>.<动词>` 的字面词。
52
+ */
53
+ export declare function sealStoreFunction<A extends unknown[], R>(fn: (...a: A) => R, site: string): (...a: A) => R;
54
+ /** 惰性异步可迭代的封口:迭代中途(取下一项 / 提前结束)的错同样过边界。交回一只新的可迭代(原可迭代只被它读;生成器的 `return` 值原样交回)。 */
55
+ export declare function sealStoreIterable<E>(it: AsyncIterable<E>, site: string): AsyncGenerator<E, unknown, undefined>;
56
+ export {};
57
+ //# sourceMappingURL=store-boundary.d.ts.map
@@ -0,0 +1,139 @@
1
+ import { storeBoundaryFault } from "../terminal.js";
2
+ export const BOOT_METHOD_NAMES = new Set(["ensureSchema", "runOneTimeMigrations", "close", "mysqlPool", "pgPool"]);
3
+ export const SEALED_STORE_MEMBER = Symbol("sema.sealedStoreMember");
4
+ const SEALS = new Map();
5
+ export function storeSealRecords() {
6
+ return [...SEALS.values()];
7
+ }
8
+ const STORE_WORD = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
9
+ export function sealStoreClass(ctor, store, plan) {
10
+ assertStoreWord(store);
11
+ const proto = ctor.prototype;
12
+ if (SEALS.has(`class:${store}`))
13
+ throw new Error(`store-boundary: store word ${store} is already sealed — every sealed producer has its own word`);
14
+ for (const key of Reflect.ownKeys(plan)) {
15
+ const word = plan[key];
16
+ assertWord(store, key, word);
17
+ if (word !== "exit")
18
+ continue;
19
+ const own = Object.getOwnPropertyDescriptor(proto, key);
20
+ if (own !== undefined) {
21
+ if (typeof own.value !== "function")
22
+ throw new Error(`store-boundary: ${store}.${String(key)} is not a method on ${ctor.name}.prototype (an accessor or a field cannot be sealed in place)`);
23
+ assertNotGenerator(store, key, own.value);
24
+ Object.defineProperty(proto, key, { ...own, value: sealedMember(own.value, `${store}.${String(key)}`) });
25
+ continue;
26
+ }
27
+ const inherited = proto[key];
28
+ if (typeof inherited !== "function")
29
+ throw new Error(`store-boundary: ${store}.${String(key)} is not a method reachable from ${ctor.name}.prototype`);
30
+ if (inherited[SEALED_STORE_MEMBER] === undefined) {
31
+ throw new Error(`store-boundary: ${store}.${String(key)} is inherited by ${ctor.name} from an unsealed base — seal the base class first`);
32
+ }
33
+ }
34
+ SEALS.set(`class:${store}`, { store, kind: "class", name: ctor.name, plan: Object.freeze({ ...plan }) });
35
+ }
36
+ export function sealStoreObject(obj, store, plan) {
37
+ assertStoreWord(store);
38
+ const planKeys = new Set(Reflect.ownKeys(plan));
39
+ if (typeof obj !== "function") {
40
+ for (const key of Reflect.ownKeys(obj)) {
41
+ const d = Object.getOwnPropertyDescriptor(obj, key);
42
+ if (d !== undefined && typeof d.value === "function" && !planKeys.has(key)) {
43
+ throw new Error(`store-boundary: ${store} has a callable member ${String(key)} that its exit plan does not list`);
44
+ }
45
+ }
46
+ }
47
+ for (const key of planKeys) {
48
+ const word = plan[key];
49
+ assertWord(store, key, word);
50
+ if (word !== "exit")
51
+ continue;
52
+ const d = Object.getOwnPropertyDescriptor(obj, key);
53
+ if (d === undefined)
54
+ continue;
55
+ if (typeof d.value !== "function")
56
+ throw new Error(`store-boundary: ${store}.${String(key)} is not a callable own property`);
57
+ if (d.value[SEALED_STORE_MEMBER] !== undefined)
58
+ continue;
59
+ assertNotGenerator(store, key, d.value);
60
+ if (d.writable !== true && d.configurable !== true)
61
+ throw new Error(`store-boundary: ${store}.${String(key)} is frozen and cannot be sealed`);
62
+ Object.defineProperty(obj, key, { ...d, value: sealedMember(d.value, `${store}.${String(key)}`) });
63
+ }
64
+ if (!SEALS.has(`object:${store}`))
65
+ SEALS.set(`object:${store}`, { store, kind: "object", name: store, plan: Object.freeze({ ...plan }) });
66
+ return obj;
67
+ }
68
+ export function sealStoreFunction(fn, site) {
69
+ if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*\.[A-Za-z][A-Za-z0-9]*$/.test(site))
70
+ throw new Error(`store-boundary: site ${JSON.stringify(site)} is not <store word>.<verb>`);
71
+ return sealedMember(fn, site);
72
+ }
73
+ export async function* sealStoreIterable(it, site) {
74
+ try {
75
+ return yield* it;
76
+ }
77
+ catch (err) {
78
+ throw storeBoundaryFault(err, site);
79
+ }
80
+ }
81
+ function sealedMember(fn, site) {
82
+ const sealed = function (...args) {
83
+ try {
84
+ const out = fn.apply(this, args);
85
+ const then = thenOf(out);
86
+ if (then === undefined)
87
+ return sealedYield(out, site);
88
+ return Reflect.apply(then, out, [
89
+ (value) => sealedYield(value, site),
90
+ (err) => {
91
+ throw storeBoundaryFault(err, site);
92
+ },
93
+ ]);
94
+ }
95
+ catch (err) {
96
+ throw storeBoundaryFault(err, site);
97
+ }
98
+ };
99
+ Object.defineProperty(sealed, "name", { value: fn.name, configurable: true });
100
+ Object.defineProperty(sealed, "length", { value: fn.length, configurable: true });
101
+ Object.defineProperty(sealed, SEALED_STORE_MEMBER, { value: site });
102
+ return sealed;
103
+ }
104
+ function thenOf(v) {
105
+ if (v === null || (typeof v !== "object" && typeof v !== "function"))
106
+ return undefined;
107
+ const then = Reflect.get(v, "then");
108
+ return typeof then === "function" ? then : undefined;
109
+ }
110
+ function sealedYield(value, site) {
111
+ let tag;
112
+ try {
113
+ tag = Object.prototype.toString.call(value);
114
+ }
115
+ catch (err) {
116
+ throw storeBoundaryFault(err, site);
117
+ }
118
+ return tag === "[object AsyncGenerator]" ? sealStoreIterable(value, site) : value;
119
+ }
120
+ function assertStoreWord(store) {
121
+ if (!STORE_WORD.test(store))
122
+ throw new Error(`store-boundary: store word ${JSON.stringify(store)} is not a lowercase dashed word`);
123
+ }
124
+ function assertWord(store, key, word) {
125
+ if (word === "exit" || word === "in-store")
126
+ return;
127
+ if (word === "boot") {
128
+ if (typeof key === "string" && BOOT_METHOD_NAMES.has(key))
129
+ return;
130
+ throw new Error(`store-boundary: ${store}.${String(key)} is marked boot but is not a boot lifecycle name (${[...BOOT_METHOD_NAMES].join(" / ")})`);
131
+ }
132
+ throw new Error(`store-boundary: ${store}.${String(key)} has exit word ${JSON.stringify(word)} (expected exit | boot | in-store)`);
133
+ }
134
+ function assertNotGenerator(store, key, fn) {
135
+ if (fn.constructor?.name === "GeneratorFunction") {
136
+ throw new Error(`store-boundary: ${store}.${String(key)} is a synchronous generator method — its failures happen after the call returns, where the seal cannot see them`);
137
+ }
138
+ }
139
+ //# sourceMappingURL=store-boundary.js.map
@@ -21,6 +21,7 @@
21
21
  import type { PeerSessionTempo, TaskResult, TaskStatus } from "@sema-agent/core";
22
22
  import type { RunIdentity } from "../identity-source.js";
23
23
  import type { SessionUnreadable } from "../session-error-wire.js";
24
+ import type { SessionKind } from "../session-kind.js";
24
25
  import type { ReadDenyFloorSummary } from "../read-deny-floor-notice.js";
25
26
  /**
26
27
  * **File 店族的 boot 期拒启基类**([ref];把 `RunStoreStrictHydrateError` 的那条论证升成一条族规)。
@@ -616,6 +617,22 @@ export interface SessionSummary {
616
617
  /** fork 谱系:建这一行的那次 fork 的源会话 id(core `SessionMetadata.forkedFrom` 原词)—— present-iff 这一行是 fork 建的、且建于谱系落地之后(更早的 fork 不回填:源已不可知)。
617
618
  * 三店从行上读(谱系的唯一读法 `session-incarnation.ts` 的 `forkLineageOfRow`);来源住客(`forkedFromIncarnation`)不上列表行。wire 半场见 `security.ts SessionListItem.forkedFrom`(同名同义)。 */
618
619
  forkedFrom?: string;
620
+ /** 会话种类(律 `session-kind.ts`):present-iff 这只会话由一次带 `sessionKind` 的提交建下;顶层行缺席(恒不铸 null)。三店从行上读(唯一解码 `sessionKindFromCell`)。
621
+ * wire 半场见 `security.ts SessionListItem.sessionKind`(同名同义)。 */
622
+ sessionKind?: SessionKind;
623
+ }
624
+ /** 列表面的查询形(`listSessions` / `listSessionRows` 同一形;三只会话店与路由同读)。`sessionKind` = 视图(律 `session-kind.ts`:缺席 = 缺省视图,只列无种类的会话)。 */
625
+ export interface SessionListQuery {
626
+ owner?: string;
627
+ /** [ref] 窄互认第二臂的第三条件(SQL 孪生里是 `owner IS NULL` 谓词;local 店是同义的 `owner === null` 放行)。 */
628
+ includeUnowned?: boolean;
629
+ cursor?: {
630
+ lastActivityAt: string;
631
+ sessionId: string;
632
+ };
633
+ limit: number;
634
+ q?: string;
635
+ sessionKind?: SessionKind;
619
636
  }
620
637
  /**
621
638
  * run 账里「每会话的 run 投影」的五位([ref] 四位 + [ref] 预览位)—— 会话列表行上出自 run 行的那一半: