@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
@@ -1,21 +1,23 @@
1
1
  import { FileSessionRepo, type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionPlacementRecord, type SessionStore, type SessionRepo, type SessionMetadata, type SessionTreeEntry, type StoreDurability } from "@sema-agent/core";
2
2
  import { type PlacementAcquireOpts } from "./session-placement.js";
3
3
  import { z } from "zod";
4
- import { StoreBootRefusalError, type SessionRootRows, type SessionRunClaimSource, type SessionRunRollupSource, type SessionSummary } from "./store-contracts.js";
5
- import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowAnswer, type SessionRowPatch, type SessionRowWriteOutcome } from "../session-row.js";
4
+ import { StoreBootRefusalError, type SessionRootRows, type SessionRunClaimSource, type SessionRunRollupSource, type SessionListQuery, type SessionSummary } from "./store-contracts.js";
5
+ import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowAnswer, type SessionRowPatch, type SessionRowWriteOutcome, type LandedOutcome } from "../session-row.js";
6
6
  import { type SqlJsonColumnProblem } from "./sql-json-column.js";
7
7
  import { type LocalArchiveKeptStamped, type LocalArchiveUnreadable } from "./one-time-migrations.js";
8
8
  import { type ReleaseTriple } from "./release-version.js";
9
9
  import { type Logger } from "../observability/logger.js";
10
10
  import type { SessionOccupant } from "../session-erase.js";
11
11
  import { type RegisterReceipt, type SessionBirth, type SessionFace, type WithdrawOutcome } from "../session-incarnation.js";
12
+ import { type LocalSessionLiveReferenceReaders } from "./local-session-live-reference.js";
13
+ import { type IdleSession, type IdleSessionCursor, type SessionKind, type SessionKindReading } from "../session-kind.js";
12
14
  import type { SessionDeletionFace } from "../session-deletion.js";
13
15
  import { type ExecutionLane } from "../execution-lane-caps.js";
14
16
  import { type ExecutionPlacementSeat, type LocalPlacementBackfillSeat } from "../execution-placement.js";
15
17
  import { type ForkPlacement, type ForkTarget, type ForkToOutcome } from "./session-fork.js";
16
18
  import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
17
19
  import type { SessionWorkspace } from "../session-workspace.js";
18
- import { type StagedCommitOptions, type StagingHandle, type SyncRelation } from "../session-sync-kernel.js";
20
+ import { type EntriesStreamOptions, type StagedCommitOptions, type StagingHandle, type SyncRelation } from "../session-sync-kernel.js";
19
21
  /**
20
22
  * 本店执行格的形(会话元数据那一格的 `execution` 位;规则在 `src/execution-placement.ts`):`writer(L)` | `mirror`;缺 = absent。
21
23
  * local 车道没有 device 表 ⇒ 不设任何设备位(writer 只带车道)。`forking` 不是存下的值,是「fork 创建的格({@link isForkCreatedCell})而存档不在」的读法。
@@ -59,6 +61,11 @@ interface SessionMetaCellObject {
59
61
  * 撤回对它一律答「留」(`upgrade_pending`)。不需要一次性升级:撤回的候选只可能是本版登记新铸的格(化身比对,`session-birth.ts`),缺这一位的格永远不是候选。
60
62
  */
61
63
  readonly clientWrites?: number;
64
+ /**
65
+ * 会话种类(律 `src/session-kind.ts`;SQL 孪生 `session_ext.session_kind`):只由登记新行那一笔写下(带种类的提交建的会话),此后无写口;缺 = 顶层对话。
66
+ * 半建形(登记写下了格、建存档那一步失败)之后同 id 的缺档新建臂随属主一起带过它(两位都是登记那一笔写下的出生事实)。
67
+ */
68
+ readonly sessionKind?: SessionKind;
62
69
  }
63
70
  /**
64
71
  * 会话元数据边档(`session-incarnations.json`)的一格 —— SQL 孪生 `session_meta` 行在本店的对位(同一行 ⇒ 同一格、同一次落盘):属主 / 化身 / 执行放置 / `fork_key` /
@@ -93,6 +100,9 @@ export declare const SESSION_META_CELL_OBJECT: z.ZodObject<{
93
100
  dropping: z.ZodOptional<z.ZodLiteral<true>>;
94
101
  deleting: z.ZodOptional<z.ZodString>;
95
102
  clientWrites: z.ZodOptional<z.ZodNumber>;
103
+ sessionKind: z.ZodOptional<z.ZodEnum<{
104
+ sidechain: "sidechain";
105
+ }>>;
96
106
  }, z.core.$strict>;
97
107
  /**
98
108
  * 数据根对账里一只文件的读数(拒句的逐文件一段;{@link LocalDataRootSchemaMismatchError.findings}):严格边档清册里的一只边档,或引擎版本高水位 marker
@@ -328,6 +338,14 @@ export interface SessionRunWithdrawSource {
328
338
  export interface LocalSessionWithdrawDeclaration {
329
339
  readonly withdrawCheckpointCtx?: (sessionId: string) => void;
330
340
  }
341
+ /**
342
+ * 本店的老化装配(装配方给;会话种类的律在 `src/session-kind.ts`):活引用判除认领之外的三只读口(检查点 / 后台子代 / workflow 晚绑座,`local-session-live-reference.ts`;
343
+ * 认领那一腿读本店自己的 run 店)。**显式声明才有老化**:缺这一格 ⇒ 本店不交老化候选面 ⇒ 这台部署记不了种类(能力位 `sessionKinds` 为空、带键提交 400)——
344
+ * 不按「没说 = 没有引用」放行一条删用户数据的腿;每一腿逐只声明(`"none"` = 这台部署确实没有那只店)。
345
+ */
346
+ export interface LocalSessionAgeOutDeclaration {
347
+ readonly liveReferences?: Omit<LocalSessionLiveReferenceReaders, "claim">;
348
+ }
331
349
  export declare class LocalSessionStore implements SessionStore, SessionRootRows {
332
350
  private readonly repo;
333
351
  private readonly runs;
@@ -436,6 +454,13 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
436
454
  private archiveSnapshotsSettled;
437
455
  /** 撤回时本会话续跑输入的严格删法({@link LocalSessionWithdrawDeclaration};缺 = 没有可删的)。 */
438
456
  private readonly withdrawCheckpointCtx;
457
+ /** 活引用判({@link LocalSessionAgeOutDeclaration};缺 = 本店不老化 —— 老化围栏对带条件的删除一律答「不删」)。 */
458
+ private readonly liveReferenceOf;
459
+ /** 老化候选面(`OwnerAwareSessionStore.listIdleOfKind`;只在声明了老化装配时交 —— {@link LocalSessionAgeOutDeclaration})。 */
460
+ readonly listIdleOfKind?: (kind: SessionKind, idleBefore: Date, page: {
461
+ readonly after?: IdleSessionCursor;
462
+ readonly limit: number;
463
+ }) => Promise<IdleSession[]>;
439
464
  /** @param repo the core SessionRepo this store projects into the §0.5 SessionStore shape.
440
465
  * @param runs the run store whose per-session projection is the ONLY source of a row's `runCount` / `lastStatus` / `lastRunId` /
441
466
  * `lastTaskRunId` (LocalBackend passes its `FileRunStore`). Required — a run-less local session store does not exist.
@@ -447,7 +472,7 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
447
472
  * @param opts.durability / opts.placements the deployment's declaration ({@link LocalSessionStoreDeclaration}; see the two fields). */
448
473
  constructor(repo: HeadReadingSessionRepo & Partial<PlacementRecordingRepo>, runs: SessionRunRollupSource & SessionRunClaimSource, dataDir?: string, opts?: {
449
474
  log?: Pick<Logger, "info" | "warn">;
450
- } & LocalSessionStoreDeclaration & LocalSessionWithdrawDeclaration);
475
+ } & LocalSessionStoreDeclaration & LocalSessionWithdrawDeclaration & LocalSessionAgeOutDeclaration);
451
476
  /**
452
477
  * 🔴 一次性迁移 **M40 的 local 会话腿**(窗口见 `plugins/one-time-migrations.ts` 登记表 M40 行;唯一调用点 `LocalBackend.ensureSchema()` 的**第一步**,
453
478
  * 先于任何读会话元数据的店步骤 —— 严格读的执行位只认本版车道词;数据根准入的那一读在内存里先套同一只内核 {@link renameRetiredExecutionLaneWordsInCellsM40},零写):会话元数据边档里 `execution` 位记成退役词的
@@ -616,11 +641,13 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
616
641
  * 别的读者一律读作不在(读者律);门对别的属主答「不在」的同一句,所以不可探测。SQL 孪生同交这一口(座的原始头读)。
617
642
  */
618
643
  deletionHeadOf(sessionId: string): Promise<SessionHead | undefined>;
644
+ /** 按 id 的种类读(`session-kind.ts` 的 `SessionKindFace`):行事实那一格(属主与化身的唯一读口 {@link metaOf} 的同一次观察)上的住客与种类。不在 ⇒ `undefined`。 */
645
+ sessionKindOf(sessionId: string): Promise<SessionKindReading | undefined>;
619
646
  /**
620
647
  * 引擎仓存档的头(core `SessionRepo.headOf`:日志首记录与尾,不重放)—— 本店按 id 读存档头的**唯一**一处。存档头在本店只有三种读法:叶子(读内容的人要的那一格)、
621
648
  * 行代号(暂存提交落点 / 一次性迁移 M33 的 `expect.row`、迁移判「有没有、读不读得出」)与带戳判({@link assertArchiveAnonymous};读的是存档的**形** —— 头上有没有属主戳 —— 不是属主事实);
622
649
  * 属主 / 化身 / 建档时刻 / 谱系作为行事实从不从这里读(规则一,行事实只住边档);例外只有窗内无格存档长第一格的那一读({@link firstCellIncarnationHeld},M47 在树时;
623
- * M47 的起服扫经列表面的行集读同一只令牌)。
650
+ * M47 的起服扫经列表面的行集读同一只令牌);会话老化的候选面也经它问「存档在不在」(行集没交它的时刻时,{@link idleOfKind})。
624
651
  */
625
652
  private archiveHeadOf;
626
653
  /**
@@ -641,7 +668,7 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
641
668
  * failure keeps the in-memory title (degrades to re-title after restart). Runs under this session's write lock — the
642
669
  * user's conditional write ({@link writeSessionRowCells}) judges its row tag and writes under the same lock, so the two
643
670
  * writers of the title cell never interleave between a judgement and its write (the SQL twins get this from the row lock). */
644
- setTitleIfNull(sessionId: string, title: string): Promise<boolean>;
671
+ setTitleIfNull(sessionId: string, title: string, landed: SessionFace): Promise<boolean>;
645
672
  /**
646
673
  * 会话行格写原语 —— 用户标题 / 置顶的**唯一**写口(SQL 孪生 `writeSessionRowCells` 的 local 对位;规则与判序:`src/session-row.ts` 头注「写原语」)。
647
674
  * **整段在这只会话的写锁里**({@link withSessionWriteLock}):读出锁住的那一行(会话元数据那一格的属主 + 化身 + 执行位、列表面上有它、两只边档的格)→
@@ -811,7 +838,7 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
811
838
  * 出生回执面(`session-birth.ts`):与 {@link register} 同一笔写。**只有新建会话那一臂**(存档不在 ∧ 这一笔真写下了新格)交回候选 —— 化身是这一笔里铸的那一只,
812
839
  * 不复读;已记下属主(并发登记里后到的那一只)/ 只补化身 ⇒ 不交候选。新格同一笔写下客户端写计数 `0`(版本位,见 {@link SessionMetaCellObject.clientWrites})。
813
840
  */
814
- registerWithReceipt(sessionId: string, owner: string | null): Promise<RegisterReceipt>;
841
+ registerWithReceipt(sessionId: string, owner: string | null, kind?: SessionKind): Promise<RegisterReceipt>;
815
842
  touch(sessionId: string): Promise<void>;
816
843
  /**
817
844
  * 普通会话:durable 史留在 repo,只丢 in-flight 那一格(义务 3,与 SQL 孪生同)。
@@ -847,34 +874,17 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
847
874
  * Keyset matches the contract: STRICTLY older than the cursor, ties broken by id DESC; `limit` is honored after
848
875
  * the in-memory sort. Cheap (a local single-user store holds few sessions).
849
876
  */
850
- listSessions(opts: {
851
- owner?: string;
852
- /** [ref] 窄互认第二臂的第三条件(SQL 孪生里是 `owner IS NULL` 谓词;此处是同义的 `owner === null` 放行)。 */
853
- includeUnowned?: boolean;
854
- cursor?: {
855
- lastActivityAt: string;
856
- sessionId: string;
857
- };
858
- limit: number;
859
- q?: string;
860
- }): Promise<SessionSummary[]>;
877
+ listSessions(opts: SessionListQuery): Promise<SessionSummary[]>;
861
878
  /** {@link listSessions} 带每行的住客(属主 + 化身那一格,与行同一刻读)—— `OwnerAwareSessionStore.listSessionRows`;化身不进行本身。 */
862
- listSessionRows(opts: {
863
- owner?: string;
864
- includeUnowned?: boolean;
865
- cursor?: {
866
- lastActivityAt: string;
867
- sessionId: string;
868
- };
869
- limit: number;
870
- q?: string;
871
- }): Promise<Array<SessionRowAnswer<SessionSummary>>>;
879
+ listSessionRows(opts: SessionListQuery): Promise<Array<SessionRowAnswer<SessionSummary>>>;
872
880
  /** 列表行要读的边档一次装齐(lastActivity / 标题 / 置顶 / 会话元数据);各自记忆化,只有第一次真读盘。 */
873
881
  private loadRowSidecars;
874
882
  /** 列表行上的属主:那一格的属主(没有格 / 属主从没被记下 ⇒ null —— 与 `headOf(id)?.owner` 同答;列表不补铸缺的格,`headOf` 在第一次读时补)。 */
875
883
  private ownerCellOf;
876
884
  /** 一只会话的列表行 —— {@link listSessions} 与 {@link sessionSummaryOf} 的**同一只**合成(字段来源逐位见 listSessions 的头注)。调用方先 {@link loadRowSidecars}。 */
877
885
  private summaryOf;
886
+ /** 列表行的 `sessionKind` 键:那一格的种类(没有那一格 / 顶层 ⇒ 键缺席)。 */
887
+ private listedKindOf;
878
888
  /** 列表行的 `forkedFrom` 键:那一格的谱系经三店唯一的读法 `forkLineageOfRow`(没有那一格 / 不是 fork ⇒ 键缺席;住客令牌不上列表行)。 */
879
889
  private listedLineageOf;
880
890
  /** 列表行的 `rowTag` 键(规则 `session-row.ts`):化身出自会话元数据那一格(与写原语锁住的那一行同读),属主与两格由调用方交 —— 就是这一行交出去的那两位(同一刻读);没有那一格 ⇒ 键缺席。 */
@@ -939,10 +949,7 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
939
949
  * resume is always same-backend), so the local 0-based-index base needn't match the durable backends' `seq` column
940
950
  * base. Resolves to null (NOT an empty iterable) for an unknown session — mirrors {@link exportEntries}.
941
951
  * `opts.batchSize` is accepted for API parity but has no effect locally (the whole log is already in hand). */
942
- exportEntriesStream(sessionId: string, opts?: {
943
- afterSeq?: number;
944
- batchSize?: number;
945
- }): Promise<AsyncIterable<SessionTreeEntry> | null>;
952
+ exportEntriesStream(sessionId: string, opts: EntriesStreamOptions): Promise<AsyncIterable<SessionTreeEntry> | null>;
946
953
  /**
947
954
  * 2c session-sync — IMPORT a verbatim entry log into a **new** session `sessionId`(`owner` = 鉴权过的导入者)。按接口句(`importEntries` 只建新会话;改写既有会话走
948
955
  * {@link replaceEntries} / 暂存提交),SQL 孪生同判(占行不成 ⇒ 拒):id 上已有行(或格缺而存档在)⇒ `conflict`,一个字节不写;新行的属主 = 导入者、铸一只化身、
@@ -1044,7 +1051,7 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
1044
1051
  assertArchiveAnonymous(sessionId: string): Promise<void>;
1045
1052
  /**
1046
1053
  * {@link LocalStagingHandle.commit} 的整段 —— **一次持锁**(这只会话的写锁,{@link withSessionWriteLock}):属主 CAS(此刻的属主格 = 这次导入的门判过的那一格,
1047
- * 否则抛 {@link StagedCommitOwnerChangedError},一个字节不写;在判目的端日志之前判,SQL 孪生同序)→ 分区判 → 提交时重新分类(目的端此刻的日志 vs staged)→
1054
+ * 否则抛 {@link StagedCommitOccupantChangedError},一个字节不写;在判目的端日志之前判,SQL 孪生同序)→ 分区判 → 提交时重新分类(目的端此刻的日志 vs staged)→
1048
1055
  * 这一提交要换日志(不是「id 与内容都相同」那一支)⇒ 带戳存档判({@link assertArchiveAnonymous};只有 local 店有带戳存档,SQL 孪生没有这一步)→
1049
1056
  * 拒未经同意的 fork / stale / 载荷分叉(带戳判在它们之前:带戳存档上日志换不了,同步冲突与载荷分叉的出路 —— 带同意重来 —— 无从谈起)→ 准入({@link admitImportHeld}:读认领 → 本处写者 / fork 中间态 → 拒;fork 中间态的拒也在这一处,不再在提交入口另判一遍)→ 换装(导入写序 ①②③,落点 `judged` = 上面这一判;化身与 fork 键按换装律沿用)或 identical 且内容相同时日志不动、
1050
1057
  * 行照样落(② 那一格:重戳属主 + mirror)→ 两支同记新近(推送即活动)→ **在同一次持锁里**
@@ -1073,6 +1080,21 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
1073
1080
  private deletingTokenOf;
1074
1081
  /** 删除面(会话三态的围栏 / 复核 / 收尾输入;律在 `src/session-deletion.ts`)。 */
1075
1082
  readonly sessionDeletion: SessionDeletionFace;
1083
+ /**
1084
+ * 老化候选面的体({@link listIdleOfKind};律 `src/session-kind.ts`):会话元数据格里种类为 `kind` 的行(活格与在删格 —— 在删的照交,交给围栏接管;标记格不交:
1085
+ * 店内删序正在收它)× 时钟锚({@link ageAnchorOf}:新近标记 / 存档的最后写时刻 / 建档时刻里最晚的那一个)早于视界 × 当下无活引用。最老先出、keyset 续页(序的唯一判 `idleSessionAfter`)。
1086
+ * 先按格判(同步、零 I/O:新近标记与建档时刻都早于视界是必要条件);过了的格有一只才读一遍 repo 行集取存档时刻(`lastActiveAt`);行集里没有它的格(半建 / 存档读不出被行集跳过)
1087
+ * 再经存档头读口探一次:存档在而时刻读不到 ⇒ 不交(说不准就护住)。
1088
+ */
1089
+ private idleOfKind;
1090
+ /**
1091
+ * 老化的时钟锚(epoch ms;候选面与围栏同读):新近标记(本进程的 touch / 边档)· 存档的最后写时刻(`archived`:repo 行的 `lastActiveAt` = 日志 mtime,持久 —— 边档读不出、
1092
+ * 最后几次 touch 没落盘时它仍在)· 行上的建档时刻,**取最晚的那一个**。新近标记的持久是尽力的(边档撕裂 ⇒ 空表、去抖窗内崩 ⇒ 丢最后几笔),删用户数据的判不单读它。
1093
+ * 一个读得出的时刻都没有 ⇒ `+∞`(永不闲置)。调用方先 {@link loadRowSidecars}。
1094
+ */
1095
+ private ageAnchorOf;
1096
+ /** 新近标记此刻是否仍早于视界(没有标记 = 本进程没见过它的活动 ⇒ 仍早于)。同步读 —— 围栏在令牌落盘那一节里读它,与 touch 不交错。 */
1097
+ private unTouchedSince;
1076
1098
  /** 一只在删格上的属主(遗留行围栏时没有记下属主 ⇒ 读作无主,与删除门的读法同)。 */
1077
1099
  private deletionOwnerOf;
1078
1100
  /**
@@ -1083,6 +1105,13 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
1083
1105
  * 写令牌 `required`(文件 + 目录 fsync):落不了 ⇒ 抛,什么都没删(围栏没立)。遗留行铸一格(化身新铸、只带令牌;回执的化身 `undefined` —— 它的住客从没被记下,没有空间)。
1084
1106
  */
1085
1107
  private fenceDeletionHeld;
1108
+ /**
1109
+ * 老化条件的锁内判(`session-deletion.ts` 的 `SessionAgeOutExpectation`;调用方持这只会话的写锁):活格 ∧ 住客仍是候选那一位 ∧ 种类仍是它 ∧ 时钟锚仍早于视界 ∧ 当下无活引用
1110
+ * (本店的活引用判;没有老化装配 ⇒ 一律不成立)。遗留行(没有格)没有种类 ⇒ 不成立。
1111
+ * 时钟锚在这里读新近标记与建档时刻({@link ageAnchorOf},存档时刻不重读 —— 候选面读过它;本进程独占数据根,之后存档的每一次写都随一次 touch:run 收场、导入、同步推送);
1112
+ * 新近标记在令牌落盘那一节里还要再读一次({@link fenceDeletionHeld})。
1113
+ */
1114
+ private ageOutHoldsHeld;
1086
1115
  /**
1087
1116
  * 客户端写计数 +1(锁内一形,调用方持这只会话的写锁):活格 ⇒ `clientWrites` = 原值(缺 ⇒ 0)+ 1,**落盘必须成功**(`required`;落不了 ⇒ 抛,调用方的写不发生);
1088
1117
  * 没有活格(行不在 / 遗留行)⇒ 不计(没有可撤的候选)。
@@ -1095,6 +1124,15 @@ export declare class LocalSessionStore implements SessionStore, SessionRootRows
1095
1124
  * `write` 不得回到本店上锁的公开口(锁不可重入);`count` 只在这一节里有效(节外调用 ⇒ 抛)。
1096
1125
  */
1097
1126
  withClientWrite<T>(sessionId: string, write: (count: () => Promise<void>) => Promise<T>): Promise<T>;
1127
+ /**
1128
+ * **落定段**的 local 实现(SQL 孪生 `plugins/session-row-sql.ts` 的 `withLandedRow`;律在 `plugins/landed-attendants.ts` 头注):这只会话的写锁一节 —— 节首收尾待删(既有)→
1129
+ * 读出锁住的那一行(与行格写原语同一读 {@link lockedRowOf})→ 同一只判官 `judgeLandedRow`(行在 ∧ 非在删 ∧ 属主与化身整对同)→ 是 ⇒ `body(count)` 在同一节里跑完 ⇒
1130
+ * `{ landed: true, value }`;不是 ⇒ `{ landed: false }`,`body` 一个字节都不跑。与 {@link withClientWrite} 是**同一把锁、同一只计数口**(两只入口一只实现:
1131
+ * 后者不判住客);与删净段 `deleteSession` 同锁 ⇒ 删除与落定写互不穿插。`body` 不得回到本店上锁的公开口(锁不可重入),只调各附随店的动词(锁序 会话 → 店)。
1132
+ */
1133
+ withLanded<T>(sessionId: string, landed: SessionFace, body: (count: () => Promise<void>) => Promise<T>): Promise<LandedOutcome<T>>;
1134
+ /** 持锁的一节里交出那只客户端写计数口(节外调用 ⇒ 抛)。 */
1135
+ private countedSectionHeld;
1098
1136
  /**
1099
1137
  * 条件撤回面(`session-birth.ts` 头注的判序;SQL 孪生的一只事务 = 本店这只会话的写锁一节):
1100
1138
  * 节首收掉了这只 id 的待删 / 行不在 ⇒ `absent`;遗留行、化身或属主不是候选 ⇒ `incarnation`;没有计数版本位 ⇒ `upgrade_pending`;存档里有可撤集合之外的条目 ⇒ `content`;
@@ -15,7 +15,7 @@ import { z } from "zod";
15
15
  import { contentForkRelation, fastForwardSharedContentDiverged, identicalIdsAlsoIdenticalContent } from "../session-sync-content.js";
16
16
  import { SCHEMA_MISMATCH_ERROR_CODE, StoreBootRefusalError } from "./store-contracts.js";
17
17
  import { entryTypeWithdrawable } from "./session-birth.js";
18
- import { judgeSessionRowWrite, sessionRowTagKey, settleSessionRowWrite, } from "../session-row.js";
18
+ import { judgeLandedRow, judgeSessionRowWrite, sessionRowTagKey, settleSessionRowWrite, } from "../session-row.js";
19
19
  import { quarantineUnreadableSidecar } from "./local-sidecar-quarantine.js";
20
20
  import { createZodColumnReader, decodeJsonColumn, isJsonColumnBodyProblem, isJsonObject, readJsonObjectColumn, readStringRecordColumn, SqlJsonColumnError } from "./sql-json-column.js";
21
21
  import { RENAMED_EXECUTION_LANE_M40, RETIRED_EXECUTION_LANE_WORD_M40 } from "./execution-lane-rename-m40.js";
@@ -26,13 +26,15 @@ import { recordFailOpen } from "../observability/fail-open.js";
26
26
  import { createLogger, writeLogText } from "../observability/logger.js";
27
27
  import { UNMANAGED_RETENTION } from "./retention-declaration.js";
28
28
  import { UnreadableLeaf, carriedRowCells, forkLineageOfRow, headFromRow, incarnationFromCell, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
29
+ import { createLocalSessionLiveReference } from "./local-session-live-reference.js";
30
+ import { SESSION_KINDS, idleSessionAfter, sessionKindListed } from "../session-kind.js";
29
31
  import { isExecutionLane } from "../execution-lane-caps.js";
30
- import { SessionForkInProgressError, WRITABLE, assertPlaceableLane, judgeSessionWrite, settledMirrorOutcome, settledPlaceOutcome, SessionDeletingError, } from "../execution-placement.js";
32
+ import { SessionForkInProgressError, WRITABLE, assertPlaceableLane, judgeSessionWrite, sameOccupant, settledMirrorOutcome, settledPlaceOutcome, SessionDeletingError, } from "../execution-placement.js";
31
33
  import { classifyForkTarget, forkByFreshId } from "./session-fork.js";
32
34
  import { decodeInstructionSource, encodeInstructionSource, sameInstructionSourceBaseline } from "../instruction-source-notice.js";
33
35
  import { decodeSessionWorkspaceCell, encodeSessionWorkspaceCell } from "./session-workspace-cell.js";
34
36
  import { createCorruptReadFailOpenSeat } from "../observability/corrupt-read-seat.js";
35
- import { classifySyncRelationshipByIds, ownerCellIs, SyncConflictError, StagedCommitOwnerChangedError, stagingIdFor, } from "../session-sync-kernel.js";
37
+ import { classifySyncRelationshipByIds, SyncConflictError, StagedCommitOccupantChangedError, stagingIdFor, } from "../session-sync-kernel.js";
36
38
  const ownerEq = (a, b) => (a ?? null) === (b ?? null);
37
39
  const isNotFound = (e) => e instanceof SessionError && e.code === "not_found";
38
40
  function archiveFaultWord(code) {
@@ -76,8 +78,8 @@ const readPinnedSidecar = createZodColumnReader(z.record(z.string(), z.literal(t
76
78
  const MIRROR_CELL = { role: "mirror" };
77
79
  function readSessionMetaCell(cell) {
78
80
  return typeof cell === "string"
79
- ? { incarnation: cell, owner: undefined, execution: undefined, forkKey: undefined, createdAt: undefined, forkedFrom: undefined, forkedFromIncarnation: undefined, dropping: false, deleting: undefined, clientWrites: undefined }
80
- : { incarnation: cell.incarnation, owner: cell.owner, execution: cell.execution, forkKey: cell.forkKey, createdAt: cell.createdAt, forkedFrom: cell.forkedFrom, forkedFromIncarnation: cell.forkedFromIncarnation, dropping: cell.dropping === true, deleting: cell.deleting, clientWrites: cell.clientWrites };
81
+ ? { incarnation: cell, owner: undefined, execution: undefined, forkKey: undefined, createdAt: undefined, forkedFrom: undefined, forkedFromIncarnation: undefined, dropping: false, deleting: undefined, clientWrites: undefined, sessionKind: undefined }
82
+ : { incarnation: cell.incarnation, owner: cell.owner, execution: cell.execution, forkKey: cell.forkKey, createdAt: cell.createdAt, forkedFrom: cell.forkedFrom, forkedFromIncarnation: cell.forkedFromIncarnation, dropping: cell.dropping === true, deleting: cell.deleting, clientWrites: cell.clientWrites, sessionKind: cell.sessionKind };
81
83
  }
82
84
  function shellSentinelCellIdsM48(cells) {
83
85
  const ids = [];
@@ -168,6 +170,7 @@ export const SESSION_META_CELL_OBJECT = z
168
170
  dropping: z.literal(true).optional(),
169
171
  deleting: z.string().min(1).optional(),
170
172
  clientWrites: z.number().int().nonnegative().optional(),
173
+ sessionKind: z.enum(SESSION_KINDS).optional(),
171
174
  })
172
175
  .strict();
173
176
  const SESSION_META_SIDECAR = z.record(z.string(), z.union([z.string(), SESSION_META_CELL_OBJECT]));
@@ -719,11 +722,19 @@ export class LocalSessionStore {
719
722
  dataRoot;
720
723
  archiveSnapshotsSettled = 0;
721
724
  withdrawCheckpointCtx;
725
+ liveReferenceOf;
726
+ listIdleOfKind;
722
727
  constructor(repo, runs, dataDir, opts) {
723
728
  this.repo = repo;
724
729
  this.runs = runs;
725
730
  this.sidecarPath = dataDir ? join(dataDir, "session-last-activity.json") : undefined;
726
731
  this.withdrawCheckpointCtx = opts?.withdrawCheckpointCtx;
732
+ const liveReferences = opts?.liveReferences;
733
+ if (liveReferences !== undefined) {
734
+ const live = createLocalSessionLiveReference({ ...liveReferences, claim: (id) => runs.getActiveTaskId(id) });
735
+ this.liveReferenceOf = live;
736
+ this.listIdleOfKind = (kind, idleBefore, page) => this.idleOfKind(kind, idleBefore, page, live);
737
+ }
727
738
  this.log = opts?.log ?? createLogger();
728
739
  const repoPlacementOf = repo.placementOf;
729
740
  const repoListPlaced = repo.listPlaced;
@@ -1078,6 +1089,10 @@ export class LocalSessionStore {
1078
1089
  return headFromRow(sessionId, cell.meta.owner ?? null, cell.meta.incarnation, null);
1079
1090
  return this.headOf(sessionId);
1080
1091
  }
1092
+ async sessionKindOf(sessionId) {
1093
+ const meta = await this.metaOf(sessionId);
1094
+ return meta === undefined ? undefined : { incarnation: incarnationFromCell(sessionId, meta.incarnation, "absent"), kind: meta.sessionKind };
1095
+ }
1081
1096
  archiveHeadOf(sessionId) {
1082
1097
  return this.repo.headOf(sessionId);
1083
1098
  }
@@ -1095,10 +1110,8 @@ export class LocalSessionStore {
1095
1110
  await this.titles.ensureLoaded();
1096
1111
  return this.titles.state.entries.has(sessionId) ? "titled" : "untitled";
1097
1112
  }
1098
- async setTitleIfNull(sessionId, title) {
1099
- return this.withSessionWriteLock(sessionId, async () => {
1100
- if (!(await this.rowPresentHeld(sessionId)))
1101
- return false;
1113
+ async setTitleIfNull(sessionId, title, landed) {
1114
+ const out = await this.withLanded(sessionId, landed, async () => {
1102
1115
  await this.titles.ensureLoaded();
1103
1116
  const entries = this.titles.state.entries;
1104
1117
  if (entries.has(sessionId))
@@ -1107,6 +1120,7 @@ export class LocalSessionStore {
1107
1120
  await this.titles.persist();
1108
1121
  return true;
1109
1122
  });
1123
+ return out.landed && out.value;
1110
1124
  }
1111
1125
  async writeSessionRowCells(sessionId, cells, how) {
1112
1126
  return this.withSessionWriteLock(sessionId, async () => {
@@ -1140,7 +1154,7 @@ export class LocalSessionStore {
1140
1154
  const meta = this.liveCellOf(sessionId);
1141
1155
  if (meta === undefined || (await this.rowHeaderOf(sessionId)) === undefined)
1142
1156
  return undefined;
1143
- return { owner: meta.owner ?? null, incarnation: incarnationFromCell(sessionId, meta.incarnation, "absent"), placed: false, mirror: meta.execution?.role === "mirror", cells: this.rowCellsOf(sessionId) };
1157
+ return { owner: meta.owner ?? null, incarnation: incarnationFromCell(sessionId, meta.incarnation, "absent"), placed: false, deleting: false, mirror: meta.execution?.role === "mirror", cells: this.rowCellsOf(sessionId) };
1144
1158
  }
1145
1159
  rowCellsOf(sessionId) {
1146
1160
  return { title: this.titles.state.entries.get(sessionId) ?? null, pinned: this.pinned.state.entries.get(sessionId) === true };
@@ -1394,7 +1408,10 @@ export class LocalSessionStore {
1394
1408
  if (placement !== undefined)
1395
1409
  return this.createPlacedHeld(sessionId, placement, opts ?? {});
1396
1410
  const session = await this.repo.create({ id: sessionId });
1397
- await this.writeMeta(sessionId, (before) => ({ incarnation: mintSessionIncarnation(), owner: before !== undefined && ownerRecorded(before) ? (readSessionMetaCell(before).owner ?? null) : null, createdAt: rowBornNow() }));
1411
+ await this.writeMeta(sessionId, (before) => {
1412
+ const born = before !== undefined && ownerRecorded(before) ? readSessionMetaCell(before) : undefined;
1413
+ return { incarnation: mintSessionIncarnation(), owner: born?.owner ?? null, createdAt: rowBornNow(), ...(born?.sessionKind !== undefined ? { sessionKind: born.sessionKind } : {}) };
1414
+ });
1398
1415
  return this.handOut(sessionId, session);
1399
1416
  });
1400
1417
  }
@@ -1456,7 +1473,7 @@ export class LocalSessionStore {
1456
1473
  async register(sessionId, owner) {
1457
1474
  await this.registerWithReceipt(sessionId, owner);
1458
1475
  }
1459
- async registerWithReceipt(sessionId, owner) {
1476
+ async registerWithReceipt(sessionId, owner, kind) {
1460
1477
  return this.withSessionWriteLock(sessionId, async () => {
1461
1478
  await this.meta.ensureLoaded();
1462
1479
  if (this.cellStateOf(sessionId).state === "deleting")
@@ -1473,7 +1490,7 @@ export class LocalSessionStore {
1473
1490
  if (ownerRecorded(before))
1474
1491
  return undefined;
1475
1492
  if (!existed)
1476
- return { incarnation: born, owner, createdAt: rowBornNow(), clientWrites: 0 };
1493
+ return { incarnation: born, owner, createdAt: rowBornNow(), clientWrites: 0, ...(kind !== undefined ? { sessionKind: kind } : {}) };
1477
1494
  return before === undefined ? { incarnation: first ?? cellChangedUnderLock(sessionId) } : undefined;
1478
1495
  });
1479
1496
  if (!existed && wrote)
@@ -1484,6 +1501,7 @@ export class LocalSessionStore {
1484
1501
  async touch(sessionId) {
1485
1502
  this.lastActivity.set(sessionId, new Date().toISOString());
1486
1503
  this.scheduleFlush();
1504
+ await this.repo.touch?.(sessionId);
1487
1505
  }
1488
1506
  async release(sessionId) {
1489
1507
  this.pending.delete(sessionId);
@@ -1516,6 +1534,8 @@ export class LocalSessionStore {
1516
1534
  if (opts.owner !== undefined && owner !== opts.owner && !(opts.includeUnowned === true && owner === null))
1517
1535
  continue;
1518
1536
  const meta = this.liveCellOf(row.sessionId);
1537
+ if (!sessionKindListed(meta?.sessionKind, opts.sessionKind))
1538
+ continue;
1519
1539
  const incarnation = meta === undefined ? undefined : incarnationFromCell(row.sessionId, meta.incarnation, "absent");
1520
1540
  all.push({ row: this.summaryOf(row, rollups), occupant: { owner, incarnation } });
1521
1541
  }
@@ -1555,8 +1575,13 @@ export class LocalSessionStore {
1555
1575
  ...rowTag,
1556
1576
  ...("unreadable" in listed ? { unreadable: sessionUnreadableOf(listed.unreadable) } : {}),
1557
1577
  ...this.listedLineageOf(sessionId),
1578
+ ...this.listedKindOf(sessionId),
1558
1579
  };
1559
1580
  }
1581
+ listedKindOf(sessionId) {
1582
+ const kind = this.liveCellOf(sessionId)?.sessionKind;
1583
+ return kind !== undefined ? { sessionKind: kind } : {};
1584
+ }
1560
1585
  listedLineageOf(sessionId) {
1561
1586
  const lineage = forkLineageOfRow(sessionId, this.liveCellOf(sessionId)?.forkedFrom, undefined);
1562
1587
  return lineage.forkedFrom !== undefined ? { forkedFrom: lineage.forkedFrom } : {};
@@ -1679,9 +1704,11 @@ export class LocalSessionStore {
1679
1704
  const entries = await this.exportEntries(sessionId);
1680
1705
  if (entries === null)
1681
1706
  return null;
1682
- const afterSeq = opts?.afterSeq ?? -1;
1707
+ const afterSeq = opts.afterSeq ?? -1;
1683
1708
  const slice = entries.slice(afterSeq + 1);
1684
1709
  async function* gen() {
1710
+ if (slice.length > 0)
1711
+ await opts.recheck();
1685
1712
  for (const e of slice)
1686
1713
  yield e;
1687
1714
  }
@@ -1808,8 +1835,9 @@ export class LocalSessionStore {
1808
1835
  async commitStagedImport(sessionId, owner, staged, opts) {
1809
1836
  return this.withImportLock(sessionId, owner, async (importer) => {
1810
1837
  const current = await this.metaHeld(sessionId);
1811
- if (!ownerCellIs(opts.expectedOwner, current === undefined ? undefined : (current.owner ?? null)))
1812
- throw new StagedCommitOwnerChangedError(sessionId);
1838
+ const held = current === undefined ? undefined : { owner: current.owner ?? null, incarnation: incarnationFromCell(sessionId, current.incarnation, "absent") };
1839
+ if (opts.expectedOccupant === undefined ? held !== undefined : held === undefined || !sameOccupant(opts.expectedOccupant, held))
1840
+ throw new StagedCommitOccupantChangedError(sessionId);
1813
1841
  await this.assertNotPlacedHeld(sessionId);
1814
1842
  const dstEntries = await this.exportEntries(sessionId);
1815
1843
  const rel = classifySyncRelationshipByIds(staged.map((e) => e.id), dstEntries === null ? null : dstEntries.map((e) => e.id));
@@ -1873,6 +1901,52 @@ export class LocalSessionStore {
1873
1901
  return this.deletingIds().map((sessionId) => ({ sessionId, owner: this.deletionOwnerOf(sessionId), token: this.deletingTokenOf(sessionId) }));
1874
1902
  },
1875
1903
  };
1904
+ async idleOfKind(kind, idleBefore, page, live) {
1905
+ await this.loadRowSidecars();
1906
+ const maybe = [];
1907
+ for (const sessionId of [...this.liveCellIds(), ...this.deletingIds()]) {
1908
+ const cell = this.cellStateOf(sessionId);
1909
+ if (cell.state === "none" || cell.state === "dropping" || cell.meta.sessionKind !== kind)
1910
+ continue;
1911
+ if (this.ageAnchorOf(sessionId, cell.meta, undefined) < idleBefore.getTime())
1912
+ maybe.push({ sessionId, meta: cell.meta });
1913
+ }
1914
+ if (maybe.length === 0)
1915
+ return [];
1916
+ const recorded = new Map((await this.repo.list()).map((r) => [r.id, r.lastActiveAt]));
1917
+ const seen = [];
1918
+ for (const { sessionId, meta } of maybe) {
1919
+ let archived = recorded.get(sessionId);
1920
+ if (!recorded.has(sessionId) && (await this.archiveHeadOf(sessionId).catch(() => "unreadable")) !== undefined)
1921
+ continue;
1922
+ if (archived !== undefined && !Number.isFinite(archived))
1923
+ archived = undefined;
1924
+ const anchor = this.ageAnchorOf(sessionId, meta, archived);
1925
+ if (!(anchor < idleBefore.getTime()))
1926
+ continue;
1927
+ seen.push({ sessionId, owner: meta.owner ?? null, incarnation: incarnationFromCell(sessionId, meta.incarnation, "absent"), lastActivityAt: new Date(anchor).toISOString() });
1928
+ }
1929
+ seen.sort((a, b) => (a.lastActivityAt !== b.lastActivityAt ? (a.lastActivityAt < b.lastActivityAt ? -1 : 1) : a.sessionId < b.sessionId ? -1 : 1));
1930
+ const out = [];
1931
+ for (const row of seen) {
1932
+ if (out.length >= page.limit)
1933
+ break;
1934
+ if (!idleSessionAfter(row, page.after))
1935
+ continue;
1936
+ if (await live(row.sessionId, row.owner))
1937
+ continue;
1938
+ out.push(row);
1939
+ }
1940
+ return out;
1941
+ }
1942
+ ageAnchorOf(sessionId, meta, archived) {
1943
+ const marks = [Date.parse(this.lastActivity.get(sessionId) ?? ""), archived ?? Number.NaN, Date.parse(rowCreatedAtOf(sessionId, meta))].filter((t) => Number.isFinite(t));
1944
+ return marks.length === 0 ? Number.POSITIVE_INFINITY : Math.max(...marks);
1945
+ }
1946
+ unTouchedSince(sessionId, idleBefore) {
1947
+ const touched = this.lastActivity.get(sessionId);
1948
+ return touched === undefined || Date.parse(touched) < idleBefore.getTime();
1949
+ }
1876
1950
  deletionOwnerOf(sessionId) {
1877
1951
  const cell = this.cellStateOf(sessionId);
1878
1952
  return cell.state === "none" ? null : (cell.meta.owner ?? null);
@@ -1903,23 +1977,42 @@ export class LocalSessionStore {
1903
1977
  return { inProgress: true };
1904
1978
  }
1905
1979
  else {
1980
+ if (opts.ageOut !== undefined && !(await this.ageOutHoldsHeld(sessionId, current, opts.ageOut)))
1981
+ return undefined;
1906
1982
  const verdict = await judgeSessionWrite({ op: "delete", rootSessionId: sessionId }, { claim: () => this.runs.getActiveTaskId(sessionId), cell: async () => ({ role: "absent" }), deleting: async () => this.deletingTokenOf(sessionId) });
1907
1983
  if (verdict !== "proceed")
1908
1984
  throw verdict.refuse;
1909
1985
  }
1910
1986
  const token = uuidv7();
1911
1987
  let incarnation;
1988
+ let touchedMeanwhile = false;
1912
1989
  const committed = await this.meta.commit((draft) => {
1990
+ if (opts.ageOut !== undefined && state.state !== "deleting" && !this.unTouchedSince(sessionId, opts.ageOut.idleBefore)) {
1991
+ touchedMeanwhile = true;
1992
+ return false;
1993
+ }
1913
1994
  const before = draft.get(sessionId);
1914
1995
  const base = before === undefined ? { incarnation: mintSessionIncarnation() } : cellObjectOf(before);
1915
1996
  incarnation = before === undefined ? undefined : base.incarnation;
1916
1997
  draft.set(sessionId, { ...base, deleting: token });
1917
1998
  return true;
1918
1999
  }, "required");
2000
+ if (touchedMeanwhile)
2001
+ return undefined;
1919
2002
  if (!committed)
1920
2003
  throw new SessionError("storage", `LocalSessionStore: the deletion fence of session ${sessionId} could not be made durable — nothing of the session was removed; retry the delete`);
1921
2004
  return { token, incarnation };
1922
2005
  }
2006
+ async ageOutHoldsHeld(sessionId, current, ageOut) {
2007
+ if (current === undefined || this.liveReferenceOf === undefined)
2008
+ return false;
2009
+ if (incarnationFromCell(sessionId, current.incarnation, "absent") !== ageOut.incarnation || current.sessionKind !== ageOut.kind)
2010
+ return false;
2011
+ await this.loadRowSidecars();
2012
+ if (!(this.ageAnchorOf(sessionId, current, undefined) < ageOut.idleBefore.getTime()))
2013
+ return false;
2014
+ return !(await this.liveReferenceOf(sessionId, current.owner ?? null));
2015
+ }
1923
2016
  async bumpClientWritesHeld(sessionId) {
1924
2017
  await this.meta.ensureLoaded();
1925
2018
  if (this.cellStateOf(sessionId).state === "deleting")
@@ -1940,20 +2033,29 @@ export class LocalSessionStore {
1940
2033
  throw new SessionError("storage", `LocalSessionStore: the client-write count of session ${sessionId} could not be made durable — the write was not made; retry it`);
1941
2034
  }
1942
2035
  async withClientWrite(sessionId, write) {
2036
+ return this.withSessionWriteLock(sessionId, () => this.countedSectionHeld(sessionId, write));
2037
+ }
2038
+ async withLanded(sessionId, landed, body) {
1943
2039
  return this.withSessionWriteLock(sessionId, async () => {
1944
- let open = true;
1945
- try {
1946
- return await write(async () => {
1947
- if (!open)
1948
- throw new Error(`LocalSessionStore.withClientWrite: session ${sessionId}'s client-write count was taken after its lock section ended`);
1949
- await this.bumpClientWritesHeld(sessionId);
1950
- });
1951
- }
1952
- finally {
1953
- open = false;
1954
- }
2040
+ await this.loadRowSidecars();
2041
+ if (!judgeLandedRow(sessionId, landed, await this.lockedRowOf(sessionId)))
2042
+ return { landed: false };
2043
+ return { landed: true, value: await this.countedSectionHeld(sessionId, body) };
1955
2044
  });
1956
2045
  }
2046
+ async countedSectionHeld(sessionId, body) {
2047
+ let open = true;
2048
+ try {
2049
+ return await body(async () => {
2050
+ if (!open)
2051
+ throw new Error(`LocalSessionStore: session ${sessionId}'s client-write count was taken after its lock section ended`);
2052
+ await this.bumpClientWritesHeld(sessionId);
2053
+ });
2054
+ }
2055
+ finally {
2056
+ open = false;
2057
+ }
2058
+ }
1957
2059
  async withdrawBirth(birth, ownTaskId) {
1958
2060
  const runs = this.runs;
1959
2061
  return this.withSessionWriteLock(birth.sessionId, async (dropped) => {
@@ -9,6 +9,7 @@ import { assertMemoryScopeWidth } from "./memory-key-guards.js";
9
9
  import { exposureBandOf, exposureCarriage, originMarkedSqlPredicate, distilledCarriage } from "./memory-origin-law.js";
10
10
  import { applySqlPatches, } from "./memory-engine-sql-apply.js";
11
11
  import { ensureIndexes } from "./ensure-index.js";
12
+ import { sealStoreClass } from "./store-boundary.js";
12
13
  export const PG_MEMORY_ENGINE_TABLES = {
13
14
  entry: "agent_memory_engine_entry",
14
15
  cursor: "agent_memory_engine_cursor",
@@ -301,4 +302,7 @@ export class PgMemoryEngineBackend {
301
302
  ON CONFLICT (scope) DO UPDATE SET cursor = $2`, [scope, cursor]);
302
303
  }
303
304
  }
305
+ sealStoreClass(PgMemoryEngineBackend, "pg-memory-engine-backend", {
306
+ listHeaders: "exit", getByIds: "exit", search: "exit", applyPatches: "exit", getConsolidationCursor: "exit", setConsolidationCursor: "exit",
307
+ });
304
308
  //# sourceMappingURL=memory-engine-pg.js.map
@@ -1,6 +1,8 @@
1
1
  import { LandingsNeedAdmission, admittingLandings, computeEntryRev, requireLandingsAdmitted, } from "@sema-agent/core";
2
2
  import { memoryEntryKeyWidthRefusal } from "./memory-key-guards.js";
3
3
  import { pgHasUnstorable } from "./pg-safe-json.js";
4
+ import { storeBoundaryFault } from "../terminal.js";
5
+ import { markErrorOrigin } from "./error-origin.js";
4
6
  import { ambiguousOriginRefusal, createBatchCommittedBaseline, distilledWhitewashRefusal, originWhitewashRefusal, rememberBatchCommitted, unknownPatchOpRefusal, } from "./memory-origin-law.js";
5
7
  const FIRST_SUFFIX_STEP = 2;
6
8
  const candidateAt = (slug, n) => (n === FIRST_SUFFIX_STEP ? slug : `${slug}-${n - 1}`);
@@ -317,7 +319,8 @@ export async function applySqlPatches(patches, opts, leg) {
317
319
  throw err;
318
320
  if (issued)
319
321
  mayHaveWritten = true;
320
- report.conflicts.push({ op: patch.op, id: patch.id, reason: `io error: ${err instanceof Error ? err.message : String(err)}` });
322
+ const seen = storeBoundaryFault(err, "memory-engine.applyPatches");
323
+ report.conflicts.push({ op: patch.op, id: patch.id, reason: `io error: ${seen instanceof Error ? seen.message : String(seen)}` });
321
324
  return [];
322
325
  }
323
326
  };
@@ -345,7 +348,7 @@ export async function applySqlPatches(patches, opts, leg) {
345
348
  await admittingLandings(admit, attempt);
346
349
  }
347
350
  catch (err) {
348
- throw err instanceof CallerThrow ? err.thrown : err;
351
+ throw err instanceof CallerThrow ? markErrorOrigin(err.thrown, "caller") : err;
349
352
  }
350
353
  finally {
351
354
  if (leg.appendHistory && history.length > 0)
@@ -9,6 +9,7 @@ import { applySqlPatches, } from "./memory-engine-sql-apply.js";
9
9
  import { isMysqlDupKeyError } from "./sql-errors.js";
10
10
  import { ensureIndexes } from "./ensure-index.js";
11
11
  import { MEMORY_ENGINE_INDEXES, PG_MEMORY_ENGINE_TABLES } from "./memory-engine-pg.js";
12
+ import { sealStoreClass } from "./store-boundary.js";
12
13
  export const TIDB_MEMORY_ENGINE_TABLES = {
13
14
  entry: "agent_memory_engine_entry",
14
15
  cursor: "agent_memory_engine_cursor",
@@ -265,4 +266,7 @@ export class TiDBMemoryEngineBackend {
265
266
  await this.write(`INSERT INTO ${TIDB_MEMORY_ENGINE_TABLES.cursor} (scope, \`cursor\`) VALUES (?, ?) ON DUPLICATE KEY UPDATE \`cursor\` = VALUES(\`cursor\`)`, [scope, cursor]);
266
267
  }
267
268
  }
269
+ sealStoreClass(TiDBMemoryEngineBackend, "tidb-memory-engine-backend", {
270
+ listHeaders: "exit", getByIds: "exit", search: "exit", applyPatches: "exit", getConsolidationCursor: "exit", setConsolidationCursor: "exit",
271
+ });
268
272
  //# sourceMappingURL=memory-engine-tidb.js.map
@@ -1,5 +1,6 @@
1
1
  import { mysqlDriver, pgDriver } from "./sql-driver.js";
2
2
  import { PRINCIPAL_MAX_BYTES, RESERVED_PRINCIPALS, RESERVED_PRINCIPAL_PREFIXES } from "../principal-shape.js";
3
+ import { sealStoreClass } from "./store-boundary.js";
3
4
  export const MEMORY_OPTOUT_GRANT_TABLE = "memory_optout_grant";
4
5
  export const MEMORY_OPTOUT_DEFAULT_PRINCIPAL = "";
5
6
  export function buildMemoryOptOutVerdict(rows, principal) {
@@ -124,6 +125,9 @@ export class SqlMemoryOptOutGrantStore {
124
125
  return { principal, allow: input.allow, updatedAtMs: at, updatedBy: input.updatedBy, ...(note !== null ? { note } : {}) };
125
126
  }
126
127
  }
128
+ sealStoreClass(SqlMemoryOptOutGrantStore, "sql-memory-opt-out-grant-store", {
129
+ resolveAllow: "exit", list: "exit", putDefault: "exit", putOverride: "exit", deleteOverride: "exit",
130
+ });
127
131
  export class TiDBMemoryOptOutGrantStore extends SqlMemoryOptOutGrantStore {
128
132
  constructor(pool, now) {
129
133
  super(mysqlDriver(pool), "mysql", now);