@sema-agent/server 7.145.0 → 7.147.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 (526) hide show
  1. package/MIGRATION.md +876 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +374 -99
  5. package/deploy/facts/CHANGES.json +25 -0
  6. package/deploy/facts/README.md +57 -0
  7. package/deploy/facts/lanes.json +61 -0
  8. package/deploy/facts/lanes.schema.json +57 -0
  9. package/deploy/facts/sandbox-rbac.json +113 -0
  10. package/deploy/facts/sandbox-rbac.schema.json +74 -0
  11. package/deploy/facts/sealed-key.json +9 -0
  12. package/deploy/facts/sealed-key.schema.json +52 -0
  13. package/deploy/sema-up/README.md +2 -2
  14. package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
  15. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
  16. package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
  17. package/deploy/sema-up/chart/templates/server.yaml +9 -4
  18. package/deploy/sema-up/chart/values.yaml +8 -1
  19. package/deploy/sema-up/cluster-up.sh +2 -1
  20. package/deploy/sema-up/lib/flagshape.sh +4 -0
  21. package/deploy/sema-up/lib/lanes.json +2 -5
  22. package/deploy/sema-up/sema-up.sh +12 -9
  23. package/deploy/sema-up/stack/compose.yaml +5 -4
  24. package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
  25. package/dist/adoption/import-limits.d.ts +6 -0
  26. package/dist/adoption/import-limits.js +7 -0
  27. package/dist/adoption/import.d.ts +62 -0
  28. package/dist/adoption/import.js +107 -0
  29. package/dist/adoption/wire.d.ts +52 -0
  30. package/dist/adoption/wire.js +9 -0
  31. package/dist/approval-ask-machine.d.ts +2 -2
  32. package/dist/approval-card.d.ts +7 -16
  33. package/dist/approval-card.js +0 -4
  34. package/dist/approval-gate-currency.d.ts +1 -1
  35. package/dist/approval-gate-currency.js +1 -1
  36. package/dist/approval-reconciler.d.ts +1 -1
  37. package/dist/approval.d.ts +3 -3
  38. package/dist/audit.js +2 -2
  39. package/dist/bench/s1/live-deps.js +3 -1
  40. package/dist/boot/crash-last.js +2 -1
  41. package/dist/boot/deployment-mods.d.ts +11 -1
  42. package/dist/boot/deployment-mods.js +15 -2
  43. package/dist/boot/device-lane.js +7 -5
  44. package/dist/boot/engine-lease.d.ts +195 -22
  45. package/dist/boot/engine-lease.js +146 -20
  46. package/dist/boot/execution-env.d.ts +5 -0
  47. package/dist/boot/execution-env.js +57 -33
  48. package/dist/boot/execution-lane.d.ts +37 -9
  49. package/dist/boot/execution-lane.js +74 -20
  50. package/dist/boot/exit-boundary.d.ts +50 -0
  51. package/dist/boot/exit-boundary.js +32 -0
  52. package/dist/boot/exit-last.d.ts +20 -4
  53. package/dist/boot/exit-last.js +23 -5
  54. package/dist/boot/governance-seams.d.ts +2 -2
  55. package/dist/boot/governance-seams.js +1 -0
  56. package/dist/boot/leader.js +1 -1
  57. package/dist/boot/memory-boundary.d.ts +11 -11
  58. package/dist/boot/memory-boundary.js +3 -3
  59. package/dist/boot/memory-consolidation.d.ts +42 -41
  60. package/dist/boot/memory-consolidation.js +26 -28
  61. package/dist/boot/org-memory.js +3 -2
  62. package/dist/boot/parked-revive-gate.d.ts +1 -1
  63. package/dist/boot/parked-revive-gate.js +1 -1
  64. package/dist/boot/reapers.d.ts +12 -4
  65. package/dist/boot/reapers.js +40 -16
  66. package/dist/boot/resolve-spec.d.ts +2 -0
  67. package/dist/boot/resolve-spec.js +126 -123
  68. package/dist/boot/retention-lane.d.ts +4 -42
  69. package/dist/boot/runner-deps.js +1 -1
  70. package/dist/boot/session-faces.d.ts +1 -0
  71. package/dist/boot/session-faces.js +11 -3
  72. package/dist/boot/shutdown.js +27 -9
  73. package/dist/boot/stage-01-config.d.ts +1 -1
  74. package/dist/boot/stage-01-config.js +7 -3
  75. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
  76. package/dist/boot/stage-02-web-admin-pull.js +10 -8
  77. package/dist/boot/stage-03-store-backend.d.ts +2 -1
  78. package/dist/boot/stage-03-store-backend.js +2 -2
  79. package/dist/boot/stage-04-stores.d.ts +2 -1
  80. package/dist/boot/stage-05-execution-env.d.ts +4 -1
  81. package/dist/boot/stage-05-execution-env.js +6 -6
  82. package/dist/boot/stage-06-runners.d.ts +5 -2
  83. package/dist/boot/stage-06-runners.js +12 -13
  84. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  85. package/dist/boot/stage-07-capability-layer.js +7 -7
  86. package/dist/boot/stage-08-reapers.d.ts +5 -2
  87. package/dist/boot/stage-08-reapers.js +3 -3
  88. package/dist/boot/stage-09-leader.d.ts +6 -2
  89. package/dist/boot/stage-10-http-server.d.ts +6 -2
  90. package/dist/boot/stage-10-http-server.js +5 -3
  91. package/dist/boot/stores.d.ts +10 -0
  92. package/dist/boot/stores.js +53 -26
  93. package/dist/boot/web-admin.js +3 -3
  94. package/dist/boot/workflow-orchestration.d.ts +1 -1
  95. package/dist/boot/workflow-orchestration.js +2 -1
  96. package/dist/capabilities/center-plugins.d.ts +2 -0
  97. package/dist/capabilities/center-plugins.js +6 -2
  98. package/dist/capabilities/composite-members.d.ts +4 -1
  99. package/dist/capabilities/composite-members.js +4 -1
  100. package/dist/capabilities/execution-lane.d.ts +7 -7
  101. package/dist/capabilities/execution-lane.js +2 -2
  102. package/dist/capabilities/hands-lane.d.ts +1 -1
  103. package/dist/capabilities/scenarios.d.ts +34 -20
  104. package/dist/capabilities/scenarios.js +13 -9
  105. package/dist/capabilities/settings-contract.d.ts +29 -0
  106. package/dist/capabilities/settings-contract.js +14 -0
  107. package/dist/capabilities/skills.d.ts +5 -5
  108. package/dist/capability-facts.d.ts +56 -1
  109. package/dist/capability-facts.js +59 -8
  110. package/dist/center-credential-renewer.js +3 -2
  111. package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
  112. package/dist/config-catalog.js +19 -9
  113. package/dist/config-invariants.d.ts +18 -3
  114. package/dist/config-invariants.js +36 -19
  115. package/dist/config-lkg.d.ts +1 -1
  116. package/dist/config-lkg.js +5 -6
  117. package/dist/config-provider.d.ts +2 -2
  118. package/dist/config-provider.js +2 -0
  119. package/dist/config-types.d.ts +228 -185
  120. package/dist/config.d.ts +74 -6
  121. package/dist/config.js +146 -64
  122. package/dist/degenerate-instrument.js +1 -1
  123. package/dist/deleted-session-ids.d.ts +19 -0
  124. package/dist/deleted-session-ids.js +26 -0
  125. package/dist/deploy-facts.d.ts +155 -0
  126. package/dist/deploy-facts.js +95 -0
  127. package/dist/deployment-shape.d.ts +21 -12
  128. package/dist/deployment-shape.js +24 -6
  129. package/dist/device-ws-hub.d.ts +48 -3
  130. package/dist/device-ws-hub.js +48 -2
  131. package/dist/env-facts.d.ts +7 -5
  132. package/dist/env-facts.js +10 -6
  133. package/dist/error-code-family.d.ts +35 -0
  134. package/dist/error-code-family.js +26 -0
  135. package/dist/execution-config-root.d.ts +5 -5
  136. package/dist/execution-config-root.js +5 -5
  137. package/dist/execution-env-purpose.d.ts +14 -0
  138. package/dist/execution-env-purpose.js +29 -0
  139. package/dist/execution-lane-caps.d.ts +49 -86
  140. package/dist/execution-lane-caps.js +52 -62
  141. package/dist/execution-placement.d.ts +18 -2
  142. package/dist/execution-placement.js +19 -0
  143. package/dist/file-history-disclosure.d.ts +2 -2
  144. package/dist/fleet/drain-entry.d.ts +46 -3
  145. package/dist/fleet/drain-entry.js +6 -0
  146. package/dist/fleet/fleet-bus.d.ts +2 -1
  147. package/dist/fleet/serving-lease.js +3 -4
  148. package/dist/history-anchor.d.ts +22 -0
  149. package/dist/history-anchor.js +14 -0
  150. package/dist/hooks/branch-transcript.d.ts +1 -1
  151. package/dist/hooks/branch-transcript.js +1 -0
  152. package/dist/hooks/classic-stations.d.ts +25 -8
  153. package/dist/hooks/classic-stations.js +29 -3
  154. package/dist/hooks/command-spawn.d.ts +1 -4
  155. package/dist/hooks/command-spawn.js +0 -11
  156. package/dist/hooks/hook-runner.d.ts +85 -24
  157. package/dist/hooks/hook-runner.js +326 -109
  158. package/dist/hooks/hook-source.d.ts +14 -2
  159. package/dist/hooks/hook-source.js +8 -0
  160. package/dist/http/active-run-conflict.d.ts +1 -1
  161. package/dist/http/active-run-conflict.js +1 -1
  162. package/dist/http/admission.js +11 -1
  163. package/dist/http/approval-sweeps.d.ts +2 -5
  164. package/dist/http/approval-sweeps.js +3 -2
  165. package/dist/http/checkpoint-ctx.d.ts +76 -71
  166. package/dist/http/checkpoint-ctx.js +40 -40
  167. package/dist/http/claim-latency.d.ts +10 -0
  168. package/dist/http/claim-latency.js +12 -0
  169. package/dist/http/dispatch.js +19 -3
  170. package/dist/http/durable-run-leg.d.ts +5 -0
  171. package/dist/http/durable-run-leg.js +3 -1
  172. package/dist/http/execution-context.d.ts +7 -1
  173. package/dist/http/execution-context.js +13 -0
  174. package/dist/http/health-self-report.d.ts +6 -2
  175. package/dist/http/health-self-report.js +3 -2
  176. package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
  177. package/dist/http/memory-compliance-failure-reply.js +5 -15
  178. package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
  179. package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
  180. package/dist/http/memory-store-refusal-reply.d.ts +3 -3
  181. package/dist/http/memory-store-refusal-reply.js +3 -0
  182. package/dist/http/owner-access.d.ts +11 -0
  183. package/dist/http/owner-access.js +7 -4
  184. package/dist/http/principal-gate.d.ts +28 -16
  185. package/dist/http/principal-gate.js +10 -19
  186. package/dist/http/request-guards.d.ts +2 -2
  187. package/dist/http/request-guards.js +5 -5
  188. package/dist/http/resume-legs.d.ts +29 -10
  189. package/dist/http/resume-legs.js +94 -56
  190. package/dist/http/rewind-files-reply.d.ts +34 -0
  191. package/dist/http/rewind-files-reply.js +36 -0
  192. package/dist/http/route-ctx.d.ts +43 -26
  193. package/dist/http/route-table.js +4 -0
  194. package/dist/http/routes/adoption.d.ts +11 -0
  195. package/dist/http/routes/adoption.js +80 -6
  196. package/dist/http/routes/agents-roster.js +1 -0
  197. package/dist/http/routes/approvals-assistant.js +7 -26
  198. package/dist/http/routes/background.js +1 -0
  199. package/dist/http/routes/capabilities.js +12 -3
  200. package/dist/http/routes/devices.js +1 -1
  201. package/dist/http/routes/diagnostics.d.ts +9 -14
  202. package/dist/http/routes/diagnostics.js +10 -20
  203. package/dist/http/routes/engine.d.ts +31 -0
  204. package/dist/http/routes/engine.js +81 -0
  205. package/dist/http/routes/memory-bundle.js +3 -0
  206. package/dist/http/routes/memory-consolidation.js +3 -5
  207. package/dist/http/routes/memory-origin.d.ts +2 -2
  208. package/dist/http/routes/memory-origin.js +2 -4
  209. package/dist/http/routes/memory-policy.js +5 -1
  210. package/dist/http/routes/notify-wake.js +2 -1
  211. package/dist/http/routes/observability.js +3 -6
  212. package/dist/http/routes/projects.d.ts +70 -0
  213. package/dist/http/routes/projects.js +86 -0
  214. package/dist/http/routes/rules.js +30 -2
  215. package/dist/http/routes/runs.js +15 -11
  216. package/dist/http/routes/session-sync.js +39 -35
  217. package/dist/http/routes/sessions-list.d.ts +1 -1
  218. package/dist/http/routes/sessions.d.ts +7 -1
  219. package/dist/http/routes/sessions.js +108 -2
  220. package/dist/http/routes/tasks.js +32 -8
  221. package/dist/http/routes/trace-usage.js +1 -1
  222. package/dist/http/run-concurrency-cap.d.ts +86 -0
  223. package/dist/http/run-concurrency-cap.js +54 -0
  224. package/dist/http/server.d.ts +31 -14
  225. package/dist/http/server.js +29 -3
  226. package/dist/http/stored-body-replay.d.ts +12 -7
  227. package/dist/http/stored-body-replay.js +28 -5
  228. package/dist/http/wire-types.d.ts +27 -13
  229. package/dist/index.d.ts +2 -2
  230. package/dist/index.js +1 -1
  231. package/dist/instruction-source-notice.d.ts +1 -1
  232. package/dist/json-body-limit.d.ts +8 -0
  233. package/dist/json-body-limit.js +2 -0
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/local-data-root.d.ts +2 -2
  236. package/dist/memory-embedder-reembed.d.ts +38 -0
  237. package/dist/memory-embedder-reembed.js +20 -0
  238. package/dist/memory-incident-sink.d.ts +0 -28
  239. package/dist/memory-incident-sink.js +5 -0
  240. package/dist/memory-operator-faces.d.ts +9 -4
  241. package/dist/memory-scope-stores.d.ts +9 -7
  242. package/dist/memory-scope-stores.js +3 -14
  243. package/dist/memory-scope.d.ts +38 -2
  244. package/dist/memory-scope.js +33 -2
  245. package/dist/memory-store-refusal.d.ts +17 -4
  246. package/dist/memory-store-refusal.js +1 -1
  247. package/dist/memory-sync-client.d.ts +2 -0
  248. package/dist/memory-sync-client.js +13 -11
  249. package/dist/memory-sync.js +1 -1
  250. package/dist/model-compat.d.ts +35 -21
  251. package/dist/model-compat.js +49 -21
  252. package/dist/model-entry-refusal.d.ts +11 -1
  253. package/dist/model-entry-refusal.js +7 -0
  254. package/dist/namespaced-rule-name.d.ts +18 -1
  255. package/dist/namespaced-rule-name.js +12 -0
  256. package/dist/net-address.d.ts +53 -0
  257. package/dist/net-address.js +111 -0
  258. package/dist/observability/fail-open.d.ts +29 -17
  259. package/dist/observability/fail-open.js +29 -17
  260. package/dist/observability/metrics.d.ts +2 -0
  261. package/dist/observability/metrics.js +2 -0
  262. package/dist/observability/secret-env-scrub.d.ts +30 -4
  263. package/dist/observability/secret-env-scrub.js +15 -3
  264. package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
  265. package/dist/orchestration/workflow-agent-session-index.js +1 -6
  266. package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
  267. package/dist/orchestration/workflow-completion-inbox.js +63 -45
  268. package/dist/orchestration/workflow-notify-journal.js +2 -3
  269. package/dist/org-delivery-gate.js +1 -1
  270. package/dist/org-memory-admission.d.ts +5 -2
  271. package/dist/org-memory-admission.js +25 -10
  272. package/dist/parked-decide.d.ts +33 -26
  273. package/dist/parked-decide.js +36 -44
  274. package/dist/peer-directory.d.ts +6 -12
  275. package/dist/peer-directory.js +5 -1
  276. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  277. package/dist/plugins/approval-ask-store-file.js +37 -4
  278. package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
  279. package/dist/plugins/approval-ask-store-memory.js +11 -2
  280. package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
  281. package/dist/plugins/approval-ask-store-sql.js +3 -1
  282. package/dist/plugins/blob-backend.d.ts +38 -195
  283. package/dist/plugins/blob-backend.js +33 -229
  284. package/dist/plugins/caching-session-store.d.ts +12 -5
  285. package/dist/plugins/caching-session-store.js +3 -0
  286. package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
  287. package/dist/plugins/checkpoint-index-columns.js +3 -2
  288. package/dist/plugins/checkpoint-store-face.d.ts +426 -0
  289. package/dist/plugins/checkpoint-store-face.js +152 -0
  290. package/dist/plugins/device-store-sql.d.ts +2 -2
  291. package/dist/plugins/device-store-sql.js +5 -10
  292. package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
  293. package/dist/plugins/execution-lane-rename-m40.js +10 -0
  294. package/dist/plugins/execution-placement-sql.d.ts +63 -88
  295. package/dist/plugins/execution-placement-sql.js +94 -54
  296. package/dist/plugins/file-run-store.d.ts +26 -18
  297. package/dist/plugins/file-run-store.js +64 -75
  298. package/dist/plugins/fork-routing-session-store.d.ts +6 -2
  299. package/dist/plugins/fork-routing-session-store.js +2 -2
  300. package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
  301. package/dist/plugins/imported-layer-root-retirement.js +4 -8
  302. package/dist/plugins/inbox-payload-column.d.ts +14 -0
  303. package/dist/plugins/inbox-payload-column.js +13 -0
  304. package/dist/plugins/local-checkpoint-store.d.ts +7 -2
  305. package/dist/plugins/local-checkpoint-store.js +13 -8
  306. package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
  307. package/dist/plugins/local-data-dir-modes-m39.js +182 -0
  308. package/dist/plugins/local-engine-high-water.d.ts +11 -0
  309. package/dist/plugins/local-engine-high-water.js +59 -0
  310. package/dist/plugins/local-session-store.d.ts +119 -30
  311. package/dist/plugins/local-session-store.js +156 -53
  312. package/dist/plugins/local-task-attachment-store.d.ts +2 -0
  313. package/dist/plugins/local-task-attachment-store.js +10 -11
  314. package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
  315. package/dist/plugins/memory-embedder-fingerprint.js +52 -12
  316. package/dist/plugins/memory-embedder.d.ts +1 -1
  317. package/dist/plugins/memory-embedder.js +2 -2
  318. package/dist/plugins/memory-engine-pg.d.ts +30 -6
  319. package/dist/plugins/memory-engine-pg.js +96 -214
  320. package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
  321. package/dist/plugins/memory-engine-sql-apply.js +358 -0
  322. package/dist/plugins/memory-engine-tidb.d.ts +38 -9
  323. package/dist/plugins/memory-engine-tidb.js +99 -230
  324. package/dist/plugins/memory-key-guards.d.ts +1 -1
  325. package/dist/plugins/memory-origin-law.d.ts +3 -3
  326. package/dist/plugins/one-time-migrations.d.ts +169 -83
  327. package/dist/plugins/one-time-migrations.js +295 -235
  328. package/dist/plugins/owner-only-file-mode.d.ts +29 -0
  329. package/dist/plugins/owner-only-file-mode.js +141 -0
  330. package/dist/plugins/permission-rule-store-file.d.ts +17 -3
  331. package/dist/plugins/permission-rule-store-file.js +20 -1
  332. package/dist/plugins/pg-pool.d.ts +2 -1
  333. package/dist/plugins/pg-pool.js +12 -5
  334. package/dist/plugins/release-version.d.ts +20 -0
  335. package/dist/plugins/release-version.js +28 -0
  336. package/dist/plugins/remote-env-adb.d.ts +20 -4
  337. package/dist/plugins/remote-env-adb.js +39 -11
  338. package/dist/plugins/remote-env-e2b.d.ts +12 -3
  339. package/dist/plugins/remote-env-e2b.js +6 -4
  340. package/dist/plugins/remote-env-host.d.ts +9 -1
  341. package/dist/plugins/remote-env-host.js +6 -5
  342. package/dist/plugins/remote-env-k8s.d.ts +5 -2
  343. package/dist/plugins/remote-env-k8s.js +15 -4
  344. package/dist/plugins/remote-env-local-docker.d.ts +4 -1
  345. package/dist/plugins/remote-env-local-docker.js +3 -3
  346. package/dist/plugins/remote-env-ssh.d.ts +8 -2
  347. package/dist/plugins/remote-env-ssh.js +26 -24
  348. package/dist/plugins/remote-shell.d.ts +59 -30
  349. package/dist/plugins/remote-shell.js +175 -62
  350. package/dist/plugins/retention-declaration.d.ts +37 -0
  351. package/dist/plugins/retention-declaration.js +9 -0
  352. package/dist/plugins/retention-deployment.d.ts +126 -0
  353. package/dist/plugins/retention-deployment.js +88 -0
  354. package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
  355. package/dist/plugins/retention-lane-store-sql.js +103 -1
  356. package/dist/plugins/retention-sql.d.ts +29 -0
  357. package/dist/plugins/retention-sql.js +8 -0
  358. package/dist/plugins/run-store-sql.js +2 -2
  359. package/dist/plugins/schema-consistency.d.ts +0 -6
  360. package/dist/plugins/schema-consistency.js +1 -2
  361. package/dist/plugins/schema-ensure-legs.d.ts +1 -1
  362. package/dist/plugins/schema-ensure-legs.js +13 -3
  363. package/dist/plugins/session-ext-table.d.ts +74 -0
  364. package/dist/plugins/session-ext-table.js +121 -0
  365. package/dist/plugins/session-fork.d.ts +31 -9
  366. package/dist/plugins/session-fork.js +3 -2
  367. package/dist/plugins/session-placement.d.ts +4 -2
  368. package/dist/plugins/session-row-sql.d.ts +8 -7
  369. package/dist/plugins/session-row-sql.js +15 -7
  370. package/dist/plugins/session-store-sql.d.ts +131 -0
  371. package/dist/plugins/session-store-sql.js +298 -0
  372. package/dist/plugins/session-workspace-cell.d.ts +2 -2
  373. package/dist/plugins/session-workspace-cell.js +2 -2
  374. package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
  375. package/dist/plugins/shared-memory-store-sql.js +13 -13
  376. package/dist/plugins/snapshot-bucket-presence.js +1 -1
  377. package/dist/plugins/sql-driver.d.ts +23 -7
  378. package/dist/plugins/sql-driver.js +41 -8
  379. package/dist/plugins/sql-errors.d.ts +5 -2
  380. package/dist/plugins/sql-errors.js +4 -0
  381. package/dist/plugins/sql-json-column.d.ts +5 -1
  382. package/dist/plugins/store-backend.d.ts +46 -16
  383. package/dist/plugins/store-backend.js +192 -69
  384. package/dist/plugins/store-contracts.d.ts +10 -13
  385. package/dist/plugins/store-contracts.js +1 -9
  386. package/dist/plugins/store-sweep.d.ts +63 -0
  387. package/dist/plugins/store-sweep.js +48 -0
  388. package/dist/plugins/task-attachment-store.d.ts +6 -8
  389. package/dist/plugins/task-attachment-store.js +15 -10
  390. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  391. package/dist/plugins/text-column-capacity.d.ts +21 -0
  392. package/dist/plugins/text-column-capacity.js +5 -0
  393. package/dist/plugins/tidb-pool.d.ts +3 -2
  394. package/dist/plugins/tidb-pool.js +20 -32
  395. package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
  396. package/dist/prompt-screen.d.ts +6 -9
  397. package/dist/prompt-screen.js +2 -5
  398. package/dist/read-face-posture.d.ts +6 -6
  399. package/dist/read-face-posture.js +2 -2
  400. package/dist/request-value-closure.d.ts +5 -5
  401. package/dist/request-value-closure.js +1 -1
  402. package/dist/rules-consent.d.ts +48 -27
  403. package/dist/rules-consent.js +147 -23
  404. package/dist/run-cancel-context.d.ts +4 -1
  405. package/dist/run-cancel-context.js +2 -1
  406. package/dist/run-local.js +17 -13
  407. package/dist/runs.d.ts +48 -30
  408. package/dist/runs.js +27 -17
  409. package/dist/runtime-caps-resolver.d.ts +15 -8
  410. package/dist/runtime-caps-resolver.js +14 -10
  411. package/dist/sandbox-egress-policy.js +6 -11
  412. package/dist/sandbox-rbac-rules.d.ts +88 -0
  413. package/dist/sandbox-rbac-rules.js +80 -0
  414. package/dist/sealed-key-layout.d.ts +16 -0
  415. package/dist/sealed-key-layout.js +3 -0
  416. package/dist/sealed-key.js +8 -6
  417. package/dist/security.d.ts +43 -9
  418. package/dist/security.js +9 -2
  419. package/dist/sema-config-dir.js +2 -2
  420. package/dist/server-secret-env.d.ts +2 -0
  421. package/dist/service-version.d.ts +2 -1
  422. package/dist/service-version.js +2 -2
  423. package/dist/session-error-wire.d.ts +1 -1
  424. package/dist/session-incarnation.d.ts +8 -5
  425. package/dist/session-notify-door.d.ts +5 -3
  426. package/dist/session-resident-background.d.ts +110 -0
  427. package/dist/session-resident-background.js +88 -0
  428. package/dist/session-row.d.ts +1 -1
  429. package/dist/session-sync-kernel.d.ts +53 -14
  430. package/dist/session-sync-kernel.js +70 -1
  431. package/dist/session-sync.d.ts +5 -3
  432. package/dist/session-workspace.d.ts +12 -2
  433. package/dist/session-workspace.js +6 -0
  434. package/dist/sighup-idle.d.ts +9 -7
  435. package/dist/sighup-idle.js +4 -5
  436. package/dist/spec-fields.d.ts +16 -0
  437. package/dist/spec-fields.js +7 -0
  438. package/dist/store-posture.d.ts +2 -1
  439. package/dist/stored-request-env-credentials-m38.d.ts +3 -0
  440. package/dist/stored-request-env-credentials-m38.js +8 -0
  441. package/dist/stored-request-hooks-m20.d.ts +3 -2
  442. package/dist/stored-request-hooks-m20.js +19 -14
  443. package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
  444. package/dist/stores-sql/blob-index-sql.d.ts +148 -0
  445. package/dist/stores-sql/blob-index-sql.js +154 -0
  446. package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
  447. package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
  448. package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
  449. package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
  450. package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
  451. package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
  452. package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
  453. package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
  454. package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
  455. package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
  456. package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
  457. package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
  458. package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
  459. package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
  460. package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
  461. package/dist/stores-sql/session-write-hooks.d.ts +59 -0
  462. package/dist/stores-sql/session-write-hooks.js +2 -0
  463. package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
  464. package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
  465. package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
  466. package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
  467. package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
  468. package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
  469. package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
  470. package/dist/stores-sql/windowed-session-storage.js +61 -0
  471. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
  472. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
  473. package/dist/task-a2a.d.ts +7 -1
  474. package/dist/task-a2a.js +15 -14
  475. package/dist/task-cwd.d.ts +11 -3
  476. package/dist/task-cwd.js +17 -1
  477. package/dist/task-mcp.d.ts +10 -2
  478. package/dist/task-mcp.js +13 -16
  479. package/dist/task-settings.d.ts +68 -8
  480. package/dist/task-settings.js +63 -6
  481. package/dist/tool-approval.d.ts +23 -10
  482. package/dist/tool-approval.js +10 -6
  483. package/dist/trace/core-keyset-guard.d.ts +17 -10
  484. package/dist/trace/engine-notice-wire.d.ts +1 -1
  485. package/dist/trace/engine-notice-wire.js +4 -0
  486. package/dist/trace/exit-seat.d.ts +29 -1
  487. package/dist/trace/exit-seat.js +4 -0
  488. package/dist/trace/project.d.ts +33 -16
  489. package/dist/trace/project.js +21 -9
  490. package/dist/trace/redact.d.ts +13 -2
  491. package/dist/trace/redact.js +347 -78
  492. package/dist/trace/self-minted-wire.d.ts +587 -16
  493. package/dist/trace/self-minted-wire.js +215 -9
  494. package/dist/trace/sema-provenance.d.ts +45 -41
  495. package/dist/trace/sema-provenance.js +81 -10
  496. package/dist/trace/task-notification-facets.d.ts +70 -2
  497. package/dist/trace/task-notification-facets.js +71 -1
  498. package/dist/trace/wire-projection-faces.d.ts +39 -3
  499. package/dist/trace/wire-projection-faces.js +27 -2
  500. package/dist/unread-request-members.d.ts +66 -0
  501. package/dist/unread-request-members.js +41 -0
  502. package/dist/usage-analytics.d.ts +4 -0
  503. package/dist/user-input-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/apply-effective.js +22 -26
  505. package/dist/web-admin-client/candidate-gate.d.ts +35 -3
  506. package/dist/web-admin-client/candidate-gate.js +53 -5
  507. package/dist/web-admin-client/center-request.d.ts +4 -1
  508. package/dist/web-admin-client/center-request.js +2 -1
  509. package/dist/web-admin-client/effective-keys.js +0 -1
  510. package/dist/web-admin-client/facade.d.ts +1 -1
  511. package/dist/web-admin-client/http-client.d.ts +1 -0
  512. package/dist/web-admin-client/http-client.js +17 -9
  513. package/dist/web-admin-client/restart-signal.js +5 -2
  514. package/dist/web-admin-client/skills-mcp.d.ts +20 -6
  515. package/dist/web-admin-client/skills-mcp.js +26 -21
  516. package/dist/web-admin-client/types.d.ts +34 -49
  517. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
  518. package/package.json +22 -13
  519. package/scripts/drain-check-local.mjs +8 -55
  520. package/scripts/drain-check.mysql.sql +3 -40
  521. package/scripts/drain-check.pg.sql +3 -40
  522. package/skills/update-config.md +1 -1
  523. package/wire-changes/server@7.146.0.json +3221 -0
  524. package/wire-changes/server@7.147.0.json +813 -0
  525. package/dist/approval-batch-census.d.ts +0 -27
  526. package/dist/approval-batch-census.js +0 -27
@@ -1,72 +1,8 @@
1
- import { mysqlDriver, pgDriver } from "./sql-driver.js";
2
- import { TASK_LIST_ITEM_TABLE, TASK_LIST_META_TABLE, taskListKeyFor } from "./task-list-store-sql.js";
3
- import { USER_INPUT_ACCEPTANCE_TABLE } from "./user-input-ledger-sql.js";
4
- import { ensureIndexes } from "./ensure-index.js";
5
1
  import { incarnationFromCell } from "../session-incarnation.js";
6
- import { lockRootAndReadClaim, rowsOnSqlExec } from "./execution-placement-sql.js";
7
- export const MANAGED_RETENTION = "managed";
8
- export const UNMANAGED_RETENTION = "none";
9
- export function retentionSweepRuns(sweep) {
10
- return sweep.intervalSec > 0;
11
- }
12
- export function sqlStoreRetention(sweep) {
13
- return retentionSweepRuns(sweep) ? MANAGED_RETENTION : UNMANAGED_RETENTION;
14
- }
15
- export const RETENTION_AUDIT_TABLE = "retention_audit";
16
- export const RETENTION_HOLD_TABLE = "retention_hold";
17
- export const RETENTION_LEASE_TABLE = "retention_lease";
2
+ import { MANAGED_RETENTION } from "../plugins/retention-declaration.js";
3
+ import { retentionDomainWhere, retentionIdSet } from "../plugins/retention-sql.js";
18
4
  export const RETENTION_TOMBSTONE_TABLE = "retention_tombstone";
19
- export const TIDB_RETENTION_STATEMENTS = [
20
- `CREATE TABLE IF NOT EXISTS ${RETENTION_AUDIT_TABLE} (
21
- id BIGINT NOT NULL AUTO_INCREMENT,
22
- domain VARCHAR(190) NOT NULL,
23
- -- action:闭集词表见 RetentionAuditAction。前三词 = 破坏性行(本店写),其余 = lane/路由写。
24
- action VARCHAR(32) NOT NULL,
25
- -- mode:判定时点的灰度档(audit-only | enforce)——「按哪档跑的」必须与计数同行,否则事后无法解释
26
- -- 一行 deleted=0 是"没有候选"还是"当时是 audit-only"。
27
- mode VARCHAR(16) NOT NULL,
28
- -- policy_days:判定时点的策略值(按哪版策略删的)。策略是部署 env,会被改;计数离开它就没有意义。
29
- policy_days INT NOT NULL,
30
- -- fencing_token:本轮 sweep lease 的 fencing token(§3;**破坏性行必填**,非破坏行可空)。丢租后
31
- -- 在飞的旧轮仍可能提交一条审计行,靠这一位判别新旧轮。
32
- fencing_token BIGINT NULL,
33
- -- 三数字 = RetentionReceipt(audit_only 行 = previewRetention 的三候选数)。
34
- deleted INT NOT NULL DEFAULT 0,
35
- skipped INT NOT NULL DEFAULT 0,
36
- tombstones INT NOT NULL DEFAULT 0,
37
- executed_at_ms BIGINT NOT NULL,
38
- error TEXT NULL,
39
- PRIMARY KEY (id),
40
- KEY idx_retention_audit_domain (domain, id),
41
- KEY idx_retention_audit_executed (executed_at_ms)
42
- ) COLLATE utf8mb4_bin`,
43
- `CREATE TABLE IF NOT EXISTS ${RETENTION_HOLD_TABLE} (
44
- domain VARCHAR(190) NOT NULL,
45
- -- held:**1 = 冻结中,0 = 只是一把锁**。
46
- -- 🔴 为什么冻结不能用「行在/行不在」表达(codex 对抗复审 R1-[high],验真后改的**承重**形):
47
- -- 设计稿 §5 声称「PUT hold 的 commit 一旦完成,其后任何删除事务都必然看见它,串行化由行锁给出」——
48
- -- 而 SELECT … FOR UPDATE **锁不住一条不存在的行**(TiDB 无 gap lock;PG 的 READ COMMITTED 同样
49
- -- 不锁缺席行)。presence 形下两边都读到「没有 hold」是完全可能的,于是 operator 拿到成功回执之后
50
- -- 数据仍被删 —— 那正是 F2 要消灭的那件事,只是换了个位置复发。
51
- -- ⇒ 行**恒存在**(破坏性事务首步幂等建一条 held=0 的哨兵),冻结与否写在这一列上。
52
- -- 于是 hold 的放置(同一 PK 的 upsert)与三只破坏性事务抢的是**同一把行锁**,串行化由引擎给出:
53
- -- PUT 提交完成 ⇒ 其后每一个破坏性事务的首读必见 held=1。放置/解除都必须走这一列(车2 交接件)。
54
- held TINYINT(1) NOT NULL DEFAULT 0,
55
- placed_by VARCHAR(190) NULL,
56
- placed_at_ms BIGINT NULL,
57
- note TEXT NULL,
58
- PRIMARY KEY (domain)
59
- ) COLLATE utf8mb4_bin`,
60
- `CREATE TABLE IF NOT EXISTS ${RETENTION_LEASE_TABLE} (
61
- -- singleton:恒 'x' 的单行键(全局唯一一只 sweep 租约)。用定值列而不是 id=1,是为了让"这张表只能有
62
- -- 一行"写在**主键**上而不是写在注释里。
63
- singleton CHAR(1) NOT NULL DEFAULT 'x',
64
- holder VARCHAR(190) NOT NULL,
65
- -- fencing_token:每次**抢租**(而非续租)自增;随本轮全部审计行走,旧轮的写因此可判别。
66
- fencing_token BIGINT NOT NULL DEFAULT 0,
67
- expires_at_ms BIGINT NOT NULL,
68
- PRIMARY KEY (singleton)
69
- ) COLLATE utf8mb4_bin`,
5
+ export const TIDB_RETENTION_TOMBSTONE_STATEMENTS = [
70
6
  `CREATE TABLE IF NOT EXISTS ${RETENTION_TOMBSTONE_TABLE} (
71
7
  domain VARCHAR(190) NOT NULL,
72
8
  -- kind:闭集(session | tool_result),见 RetentionTombstoneKind。
@@ -88,37 +24,7 @@ export const TIDB_RETENTION_STATEMENTS = [
88
24
  KEY idx_retention_tombstone_key (kind, row_key)
89
25
  ) COLLATE utf8mb4_bin`,
90
26
  ];
91
- export const PG_RETENTION_SCHEMA = [
92
- `CREATE TABLE IF NOT EXISTS ${RETENTION_AUDIT_TABLE} (
93
- id BIGSERIAL,
94
- domain VARCHAR(190) COLLATE "C" NOT NULL,
95
- action VARCHAR(32) COLLATE "C" NOT NULL,
96
- mode VARCHAR(16) COLLATE "C" NOT NULL,
97
- policy_days INT NOT NULL,
98
- fencing_token BIGINT NULL,
99
- deleted INT NOT NULL DEFAULT 0,
100
- skipped INT NOT NULL DEFAULT 0,
101
- tombstones INT NOT NULL DEFAULT 0,
102
- executed_at_ms BIGINT NOT NULL,
103
- error TEXT COLLATE "C" NULL,
104
- PRIMARY KEY (id)
105
- )`,
106
- `CREATE TABLE IF NOT EXISTS ${RETENTION_HOLD_TABLE} (
107
- domain VARCHAR(190) COLLATE "C" NOT NULL,
108
- -- held:1 = 冻结中,0 = 只是那把域级互斥行锁的哨兵。完整判据(为什么 presence 形不成立)见 MySQL 孪生。
109
- held SMALLINT NOT NULL DEFAULT 0,
110
- placed_by VARCHAR(190) COLLATE "C" NULL,
111
- placed_at_ms BIGINT NULL,
112
- note TEXT COLLATE "C" NULL,
113
- PRIMARY KEY (domain)
114
- )`,
115
- `CREATE TABLE IF NOT EXISTS ${RETENTION_LEASE_TABLE} (
116
- singleton CHAR(1) COLLATE "C" NOT NULL DEFAULT 'x',
117
- holder VARCHAR(190) COLLATE "C" NOT NULL,
118
- fencing_token BIGINT NOT NULL DEFAULT 0,
119
- expires_at_ms BIGINT NOT NULL,
120
- PRIMARY KEY (singleton)
121
- )`,
27
+ export const PG_RETENTION_TOMBSTONE_SCHEMA = [
122
28
  `CREATE TABLE IF NOT EXISTS ${RETENTION_TOMBSTONE_TABLE} (
123
29
  domain VARCHAR(190) COLLATE "C" NOT NULL,
124
30
  kind VARCHAR(32) COLLATE "C" NOT NULL,
@@ -128,16 +34,9 @@ export const PG_RETENTION_SCHEMA = [
128
34
  PRIMARY KEY (domain, kind, row_key)
129
35
  )`,
130
36
  ];
131
- export const RETENTION_INDEXES = [
132
- { table: `${RETENTION_AUDIT_TABLE}`, name: "idx_retention_audit_domain", columns: ["domain", "id"] },
133
- { table: `${RETENTION_AUDIT_TABLE}`, name: "idx_retention_audit_executed", columns: ["executed_at_ms"] },
37
+ export const RETENTION_TOMBSTONE_INDEXES = [
134
38
  { table: `${RETENTION_TOMBSTONE_TABLE}`, name: "idx_retention_tombstone_key", columns: ["kind", "row_key"] },
135
39
  ];
136
- export async function ensurePgRetentionSchema(query) {
137
- for (const stmt of PG_RETENTION_SCHEMA)
138
- await query(stmt);
139
- await ensureIndexes(query, "pg", RETENTION_INDEXES);
140
- }
141
40
  class RetentionAborted extends Error {
142
41
  why;
143
42
  constructor(why) {
@@ -151,7 +50,7 @@ export class SqlRetentionStore {
151
50
  db;
152
51
  opts;
153
52
  retention = MANAGED_RETENTION;
154
- constructor(db, opts) {
53
+ constructor(db, opts = {}) {
155
54
  this.db = db;
156
55
  this.opts = opts;
157
56
  }
@@ -159,14 +58,10 @@ export class SqlRetentionStore {
159
58
  return this.db.dialect === "mysql" ? mysql : pg;
160
59
  }
161
60
  domainWhere(col, domain, pgIndex) {
162
- return domain === ""
163
- ? { sql: this.q(`(${col} IS NULL OR ${col} = ?)`, `(${col} IS NULL OR ${col} = $${pgIndex})`), params: [""] }
164
- : { sql: this.q(`${col} = ?`, `${col} = $${pgIndex}`), params: [domain] };
61
+ return retentionDomainWhere(this.db.dialect, col, domain, pgIndex);
165
62
  }
166
63
  idSet(col, ids, pgIndex) {
167
- return this.db.dialect === "mysql"
168
- ? { sql: `${col} IN (${ids.map(() => "?").join(",")})`, params: [...ids] }
169
- : { sql: `${col} = ANY($${pgIndex}::text[])`, params: [ids] };
64
+ return retentionIdSet(this.db.dialect, col, ids, pgIndex);
170
65
  }
171
66
  async tx(fn) {
172
67
  const conn = await this.db.connect();
@@ -189,22 +84,42 @@ export class SqlRetentionStore {
189
84
  conn.release();
190
85
  }
191
86
  }
192
- requireAudit(input, action) {
193
- if (!input.audit) {
194
- throw new Error(`retention: refusing a destructive call (${action}) with no audit context — every destructive retention ` +
195
- `transaction must persist its {mode, policyDays, fencingToken} alongside the deletion (DESIGN-270 §6 F5). ` +
196
- `Pass \`audit\` from the sweep lane's current round.`);
87
+ statementFace(conn) {
88
+ return { query: (sql, params) => conn.query(sql, params) };
89
+ }
90
+ async heldBy(face, call) {
91
+ const holdLock = this.opts.transactionHooks?.retention?.holdLock;
92
+ if (holdLock === undefined)
93
+ return false;
94
+ const answer = await holdLock(face, call);
95
+ switch (answer) {
96
+ case "proceed":
97
+ return false;
98
+ case "held":
99
+ return true;
100
+ default: {
101
+ const unknown = answer;
102
+ throw new Error(`retention: holdLock answered ${JSON.stringify(unknown)} for ${call.op} in domain ${JSON.stringify(call.domain)} — the closed answer set is "proceed" | "held"; rolling back.`);
103
+ }
197
104
  }
198
- return input.audit;
199
105
  }
200
- async holdInForce(conn, domain) {
201
- const key = domain;
202
- await conn.query(this.q(`INSERT INTO ${RETENTION_HOLD_TABLE} (domain, held, placed_by, placed_at_ms, note) VALUES (?,0,NULL,NULL,NULL) ON DUPLICATE KEY UPDATE domain = domain`, `INSERT INTO ${RETENTION_HOLD_TABLE} (domain, held, placed_by, placed_at_ms, note) VALUES ($1,0,NULL,NULL,NULL) ON CONFLICT (domain) DO NOTHING`), [key]);
203
- const { rows } = await conn.query(this.q(`SELECT held FROM ${RETENTION_HOLD_TABLE} WHERE domain = ? FOR UPDATE`, `SELECT held FROM ${RETENTION_HOLD_TABLE} WHERE domain = $1 FOR UPDATE`), [key]);
204
- return Number(rows[0]?.held ?? 0) === 1;
106
+ async admittedBy(face, rootSessionId) {
107
+ const beforeCommit = this.opts.transactionHooks?.session?.beforeCommit;
108
+ if (beforeCommit === undefined)
109
+ return true;
110
+ const answer = await beforeCommit(face, { op: "retention-delete", rootSessionId });
111
+ if (answer === "proceed")
112
+ return true;
113
+ if (typeof answer === "object" && answer !== null && answer.refuse instanceof Error)
114
+ return false;
115
+ throw new Error(`retention: session.beforeCommit answered ${JSON.stringify(answer)} for root ${JSON.stringify(rootSessionId)} — the closed answer set is "proceed" | { refuse }; rolling back.`);
116
+ }
117
+ async referencedBy(face, candidates) {
118
+ const liveReferences = this.opts.transactionHooks?.retention?.liveReferences;
119
+ return liveReferences === undefined || candidates.length === 0 ? new Set() : liveReferences(face, candidates);
205
120
  }
206
- async writeAuditRow(conn, row) {
207
- await conn.query(this.q(`INSERT INTO ${RETENTION_AUDIT_TABLE} (domain, action, mode, policy_days, fencing_token, deleted, skipped, tombstones, executed_at_ms) VALUES (?,?,?,?,?,?,?,?,?)`, `INSERT INTO ${RETENTION_AUDIT_TABLE} (domain, action, mode, policy_days, fencing_token, deleted, skipped, tombstones, executed_at_ms) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)`), [row.domain, row.action, row.audit.mode, row.audit.policyDays, row.audit.fencingToken, row.deleted, row.skipped, row.tombstones, Date.now()]);
121
+ async auditedBy(face, call, receipt) {
122
+ await this.opts.transactionHooks?.retention?.audit?.(face, call, receipt);
208
123
  }
209
124
  async writeTombstones(conn, domain, kind, keys) {
210
125
  if (keys.length === 0)
@@ -236,11 +151,12 @@ export class SqlRetentionStore {
236
151
  return { checkpoints, sessions, toolResults };
237
152
  }
238
153
  async expireCheckpoints(input) {
239
- const audit = this.requireAudit(input, "expired_checkpoints");
154
+ const call = { domain: input.domain, op: "expireCheckpoints" };
240
155
  let skippedOnAbort = 0;
241
156
  try {
242
157
  return await this.tx(async (conn) => {
243
- if (await this.holdInForce(conn, input.domain)) {
158
+ const face = this.statementFace(conn);
159
+ if (await this.heldBy(face, call)) {
244
160
  skippedOnAbort = (await this.expiryCandidates(conn, input)).length + (await this.countPinnedExpiryCandidates(conn, input));
245
161
  throw new RetentionAborted("hold_in_force");
246
162
  }
@@ -256,8 +172,9 @@ export class SqlRetentionStore {
256
172
  `AND NOT EXISTS (SELECT 1 FROM task_active ta WHERE ta.session_id = checkpoint.session_id)`), [Date.now(), ...w.params, ...set.params]);
257
173
  expired = res.affected;
258
174
  }
259
- await this.writeAuditRow(conn, { domain: input.domain, action: "expired_checkpoints", audit, deleted: expired, skipped: pinned, tombstones: 0 });
260
- return { domain: input.domain, deleted: expired, skipped: pinned, tombstones: 0 };
175
+ const receipt = { domain: input.domain, deleted: expired, skipped: pinned, tombstones: 0 };
176
+ await this.auditedBy(face, call, receipt);
177
+ return receipt;
261
178
  });
262
179
  }
263
180
  catch (err) {
@@ -329,32 +246,35 @@ export class SqlRetentionStore {
329
246
  return rows.map((r) => String(r.ref));
330
247
  }
331
248
  async deleteExpiredSessions(input) {
332
- const audit = this.requireAudit(input, "deleted_sessions");
249
+ const call = { domain: input.domain, op: "deleteExpiredSessions" };
333
250
  let skippedOnAbort = 0;
334
251
  try {
335
252
  return await this.tx(async (conn) => {
336
- if (await this.holdInForce(conn, input.domain)) {
253
+ const face = this.statementFace(conn);
254
+ if (await this.heldBy(face, call)) {
337
255
  skippedOnAbort = (await this.sessionCandidates(conn, input)).length + (await this.countProtectedSessions(conn, input));
338
256
  throw new RetentionAborted("hold_in_force");
339
257
  }
340
258
  const candidates = await this.sessionCandidates(conn, input, true);
341
- const rowsOn = rowsOnSqlExec(conn);
342
- const doomed = [];
259
+ const admitted = [];
343
260
  for (const c of candidates)
344
- if ((await lockRootAndReadClaim(rowsOn, this.db.dialect, c.id)).activeTaskId === null)
345
- doomed.push(c);
346
- const skipped = await this.countProtectedSessions(conn, input);
261
+ if (await this.admittedBy(face, c.id))
262
+ admitted.push(c);
263
+ const referenced = await this.referencedBy(face, admitted.map((c) => c.id));
264
+ const doomed = admitted.filter((c) => !referenced.has(c.id));
265
+ const skipped = (await this.countProtectedSessions(conn, input)) + (candidates.length - doomed.length);
347
266
  skippedOnAbort = doomed.length + skipped;
348
267
  let deleted = 0;
349
268
  let tombstones = 0;
350
269
  const ids = doomed.map((d) => d.id);
351
270
  if (ids.length > 0) {
271
+ await this.opts.transactionHooks?.retention?.beforeDelete?.(face, doomed.map((d) => ({ sessionId: d.id, incarnation: d.incarnation })));
352
272
  deleted = await this.purgeSessionTrees(conn, input.domain, ids);
353
273
  tombstones = await this.writeTombstones(conn, input.domain, "session", ids);
354
274
  }
355
- await this.writeAuditRow(conn, { domain: input.domain, action: "deleted_sessions", audit, deleted, skipped, tombstones });
356
- const endedSpaces = doomed.flatMap((d) => (d.incarnation === undefined ? [] : [{ sessionId: d.id, spaceKey: d.incarnation }]));
357
- return { domain: input.domain, deleted, skipped, tombstones, ...(endedSpaces.length > 0 ? { endedSpaces } : {}) };
275
+ const receipt = { domain: input.domain, deleted, skipped, tombstones };
276
+ await this.auditedBy(face, call, receipt);
277
+ return receipt;
358
278
  });
359
279
  }
360
280
  catch (err) {
@@ -365,28 +285,11 @@ export class SqlRetentionStore {
365
285
  }
366
286
  async purgeSessionTrees(conn, domain, ids) {
367
287
  const set = (col, pgIndex) => this.idSet(col, ids, pgIndex);
368
- {
369
- const s = set("tr.session_id", 1);
370
- await conn.query(this.q(`DELETE te FROM task_event te JOIN task_run tr ON te.task_id = tr.task_id WHERE ${s.sql}`, `DELETE FROM task_event te USING task_run tr WHERE te.task_id = tr.task_id AND ${s.sql}`), [...s.params]);
371
- }
372
- {
373
- const s = set("tr.session_id", 1);
374
- await conn.query(this.q(`DELETE ta FROM task_active ta JOIN task_run tr ON ta.task_id = tr.task_id WHERE ${s.sql}`, `DELETE FROM task_active ta USING task_run tr WHERE ta.task_id = tr.task_id AND ${s.sql}`), [...s.params]);
375
- }
376
- {
377
- const s = set("session_id", 1);
378
- await conn.query(`DELETE FROM task_run WHERE ${s.sql}`, [...s.params]);
379
- }
380
288
  {
381
289
  const s = set("checkpoint.session_id", 1);
382
290
  const w = this.domainWhere("sm.owner", domain, 2);
383
291
  await conn.query(`DELETE FROM checkpoint WHERE ${s.sql} AND EXISTS (SELECT 1 FROM session_meta sm WHERE sm.session_id = checkpoint.session_id AND ${w.sql})`, [...s.params, ...w.params]);
384
292
  }
385
- {
386
- const s = set("checkpoint_ctx.session_id", 1);
387
- const w = this.domainWhere("sm.owner", domain, 2);
388
- await conn.query(`DELETE FROM checkpoint_ctx WHERE ${s.sql} AND EXISTS (SELECT 1 FROM session_meta sm WHERE sm.session_id = checkpoint_ctx.session_id AND ${w.sql})`, [...s.params, ...w.params]);
389
- }
390
293
  {
391
294
  const s = set("owner_session_id", 1);
392
295
  await conn.query(`DELETE FROM tool_result WHERE ${s.sql}`, s.params);
@@ -396,12 +299,8 @@ export class SqlRetentionStore {
396
299
  await conn.query(`SELECT scope FROM file_history_scope WHERE ${s.sql} ORDER BY scope FOR UPDATE`, s.params);
397
300
  }
398
301
  for (const [table, col] of [
399
- ["resume_anchor", "session_id"],
400
- ["approval_exemption", "session_id"],
401
302
  ["session_policy", "session_id"],
402
303
  ["session_policy_rev_mark", "session_id"],
403
- ...(this.opts.taskAttachmentTable ? [["task_attachment", "session_id"]] : []),
404
- [USER_INPUT_ACCEPTANCE_TABLE, "session_id"],
405
304
  ["file_history_tracked", "scope"],
406
305
  ["file_history_version", "scope"],
407
306
  ["file_history_boundary", "scope"],
@@ -412,21 +311,6 @@ export class SqlRetentionStore {
412
311
  const s = set(col, 1);
413
312
  await conn.query(`DELETE FROM ${table} WHERE ${s.sql}`, s.params);
414
313
  }
415
- if (this.opts.taskListTables) {
416
- const listKeys = ids.map((id) => taskListKeyFor(id)).sort();
417
- {
418
- const s = this.idSet("list_key", listKeys, 1);
419
- await conn.query(`SELECT list_key FROM ${TASK_LIST_META_TABLE} WHERE ${s.sql} ORDER BY list_key FOR UPDATE`, s.params);
420
- }
421
- for (const table of [TASK_LIST_ITEM_TABLE, TASK_LIST_META_TABLE]) {
422
- const s = this.idSet("list_key", listKeys, 1);
423
- await conn.query(`DELETE FROM ${table} WHERE ${s.sql}`, s.params);
424
- }
425
- }
426
- {
427
- const s = set("session_id", 1);
428
- await conn.query(`DELETE FROM workflow_completion_inbox WHERE ${s.sql}`, s.params);
429
- }
430
314
  const s = set("session_id", 1);
431
315
  const w = this.domainWhere("owner", domain, 2);
432
316
  const metaRes = await conn.query(`DELETE FROM session_meta WHERE ${s.sql} AND ${w.sql}`, [...s.params, ...w.params]);
@@ -440,11 +324,12 @@ export class SqlRetentionStore {
440
324
  return metaRes.affected;
441
325
  }
442
326
  async deleteOrphanToolResults(input) {
443
- const audit = this.requireAudit(input, "deleted_tool_results");
327
+ const call = { domain: input.domain, op: "deleteOrphanToolResults" };
444
328
  let skippedOnAbort = 0;
445
329
  try {
446
330
  return await this.tx(async (conn) => {
447
- if (await this.holdInForce(conn, input.domain)) {
331
+ const face = this.statementFace(conn);
332
+ if (await this.heldBy(face, call)) {
448
333
  skippedOnAbort = (await this.orphanToolResultCandidates(conn, input)).length + (await this.countLiveReachableToolResults(conn, input));
449
334
  throw new RetentionAborted("hold_in_force");
450
335
  }
@@ -458,8 +343,9 @@ export class SqlRetentionStore {
458
343
  deleted = res.affected;
459
344
  tombstones = await this.writeTombstones(conn, input.domain, "tool_result", refs);
460
345
  }
461
- await this.writeAuditRow(conn, { domain: input.domain, action: "deleted_tool_results", audit, deleted, skipped: reachable, tombstones });
462
- return { domain: input.domain, deleted, skipped: reachable, tombstones };
346
+ const receipt = { domain: input.domain, deleted, skipped: reachable, tombstones };
347
+ await this.auditedBy(face, call, receipt);
348
+ return receipt;
463
349
  });
464
350
  }
465
351
  catch (err) {
@@ -474,14 +360,4 @@ export class SqlRetentionStore {
474
360
  return Number(rows[0]?.n ?? 0);
475
361
  }
476
362
  }
477
- export class TiDBRetentionStore extends SqlRetentionStore {
478
- constructor(pool, opts) {
479
- super(mysqlDriver(pool), opts);
480
- }
481
- }
482
- export class PgRetentionStore extends SqlRetentionStore {
483
- constructor(pool, opts) {
484
- super(pgDriver(pool), opts);
485
- }
486
- }
487
363
  //# sourceMappingURL=retention-store-sql.js.map
@@ -22,8 +22,8 @@
22
22
  */
23
23
  import type { Pool } from "mysql2/promise";
24
24
  import { type RosterStore, type RosterEntry, type RosterAccess } from "@sema-agent/core";
25
- import type { PgQueryFn } from "./pg-query.js";
26
- import { type IndexSpec } from "./ensure-index.js";
25
+ import type { PgQueryFn } from "../plugins/pg-query.js";
26
+ import { type IndexSpec } from "../plugins/ensure-index.js";
27
27
  export declare const ROSTER_TABLE = "agent_roster";
28
28
  export declare function ensureTiDBRosterSchema(pool: Pool): Promise<void>;
29
29
  /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgRosterSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
@@ -1,5 +1,5 @@
1
1
  import { normalizeAgentName } from "@sema-agent/core";
2
- import { ensureIndexes } from "./ensure-index.js";
2
+ import { ensureIndexes } from "../plugins/ensure-index.js";
3
3
  export const ROSTER_TABLE = "agent_roster";
4
4
  function rowToEntry(r) {
5
5
  return {
@@ -28,7 +28,7 @@
28
28
  * `isJsonColumnBodyProblem`,不另写一份。
29
29
  */
30
30
  import { type SessionTreeEntry } from "@sema-agent/core";
31
- import { type JsonColumnReader } from "./sql-json-column.js";
31
+ import { type JsonColumnReader } from "../plugins/sql-json-column.js";
32
32
  /**
33
33
  * 形读者:core 自己声明的 `SessionTreeEntryBase` 里那两把**不可省**的串键。
34
34
  *
@@ -1,5 +1,5 @@
1
1
  import { SessionError } from "@sema-agent/core";
2
- import { decodeJsonColumn, isJsonColumnBodyProblem } from "./sql-json-column.js";
2
+ import { decodeJsonColumn, isJsonColumnBodyProblem } from "../plugins/sql-json-column.js";
3
3
  export const readSessionEventPayload = (body) => {
4
4
  if (typeof body !== "object" || body === null || Array.isArray(body))
5
5
  return { problem: "expected a JSON object (a SessionTreeEntry)" };
@@ -106,7 +106,7 @@ export declare class SqlSessionPolicyStore implements SessionPolicyStore {
106
106
  * order. This is the SAME lock order putRules uses (policy row → mark row), which is the whole point: the
107
107
  * obvious shape (`INSERT … SELECT` the marks, then DELETE) locks the MARK first and takes only a SHARED lock
108
108
  * on the policy rows it reads, i.e. a reversed order PLUS an S→X upgrade — the textbook deadlock this repo
109
- * 已经吃过两次(retention-store-sql.ts ④a/④b 的 [ref] 案:一边持 boundary 等哨兵,一边持哨兵等 boundary)。
109
+ * 已经吃过两次(留存会话树删除的 file-history 哨兵腿与任务清单腿的 [ref] 案:一边持 boundary 等哨兵,一边持哨兵等 boundary)。
110
110
  * ② the marks (their revs come from ①'s already-locked rows) — `GREATEST` merge, so a mark only ever RISES and
111
111
  * repeated erases never walk the line back.
112
112
  * ③ the DELETE — scoped to ①'s POLICY_KEY SET, never re-scanned by `session_id`. 🔴 This is the whole of
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 会话店的**事务内钩**(部署在店的写事务里参与的唯一一扇门)—— 店写的是引擎座表(`session_meta` / `session_event`),部署记在会话上的格与认领住部署自己的表;
3
+ * 跨两边的「同一事务」只经这里:店锁住根 `session_meta` 行之后、写之前,把**本事务的语句面**交给部署,部署读自己的认领、写自己的格,答放行或拒。
4
+ *
5
+ * ## 形 = 引擎 SQL 店包的钩表(`@sema-agent/core-stores-sql` 的 `SqlTransactionHooks.session.beforeCommit`)
6
+ * {@link SessionWriteHooks.beforeCommit} 与包里那一只同名、同调用时刻(根行锁住之后、写之前)、同语句面(本事务连接的 `query`)、同写闭集
7
+ * (`import` / `delete` / `retention-delete`)。本仓还不依赖那只包 ⇒ 型在这里声明;店随包搬家时改从包根取型。与包的形只差一处,是向引擎的请托:
8
+ * 拒的载荷 —— 包里是一句话(`{ refuse: string }`),这里是部署的具名错误(`{ refuse: Error }`):导入 / 删除的调用方按错误的型答各自的 wire 码
9
+ * (409 `session_active` / `conflict.session_writer`),一句话答不出。
10
+ *
11
+ * ## 同事务两句,不是同一句 UPDATE
12
+ * 认领(`task_active`)与部署格住的表都不是根行所在的表 ⇒ 一句 UPDATE 里拿不到「锁住根行 + 当前读别的表」:PG 读已提交下子查询读的是语句快照、
13
+ * 不对别的表的行加锁,也不在 EvalPlanQual 里复判它们。所以是**两句**:店先 `FOR UPDATE` 锁根行(删除 / 重登记 / 改属主都要先拿这把锁),
14
+ * 再在**同一连接**上交出语句面,部署用新语句锁定读(PG 新快照、TiDB 当前读)。钩里的写随店的事务提交或回滚(店拒、或任何一步抛,一起撤)。
15
+ *
16
+ * ## 键控 fork(服务扩展,包里没有)
17
+ * 调用方给目标 id 与键的 fork(`forkTo`)是本服务的扩展:键是部署格,在建目标行的同一事务里由 {@link SessionWriteHooks.keyedFork} 记下;撞上已在的目标时
18
+ * 读它的属主与键。包随店搬家时这一组是向引擎的请托(带目标 id 与键的 fork,或钩表多一组)。
19
+ */
20
+ /** 店交给钩的语句面:本事务自己的连接(与包的 `SqlStatementFace` 同形:`query` 答行 + 受影响行数)。 */
21
+ export interface SessionTxStatements {
22
+ query(sql: string, params?: unknown[]): Promise<{
23
+ readonly rows: ReadonlyArray<Readonly<Record<string, unknown>>>;
24
+ readonly affected: number;
25
+ }>;
26
+ }
27
+ /**
28
+ * 改动会话树根的写(闭集,与包同一组词):
29
+ * · `import` —— 导入写口(整段新建、整段换装、暂存提交)落定这一行:根行已被本事务锁住 / 占下;
30
+ * · `delete` —— 属主删除:根行已被本事务锁住;
31
+ * · `retention-delete` —— 留存删除一棵会话树的根(留存座的事务;根行已锁)。
32
+ */
33
+ export interface SessionWrite {
34
+ readonly op: "import" | "delete" | "retention-delete";
35
+ readonly rootSessionId: string;
36
+ }
37
+ /** 钩的答案:放行,或拒(店回滚、一个字节不写、原样抛这只错)。 */
38
+ export type SessionWriteVerdict = "proceed" | {
39
+ readonly refuse: Error;
40
+ };
41
+ /** 键控 fork 撞上已在的目标时,那一行的属主与 fork 键(一次读;`undefined` = 行不在)。 */
42
+ export interface ForkTargetReading {
43
+ readonly owner: string | null;
44
+ readonly forkKey: string | null;
45
+ }
46
+ /** 部署交给会话店的钩表(组合座装配)。 */
47
+ export interface SessionWriteHooks {
48
+ /** 根行锁住之后、写之前调(同一事务、同一连接)。 */
49
+ beforeCommit(txn: SessionTxStatements, write: SessionWrite): Promise<SessionWriteVerdict>;
50
+ /** 键控 fork(服务扩展):`record` 在建目标行的同一事务里记下键(目标行是本事务刚插下的);`targetOf` = 撞上已在的目标时那一行的属主与键。 */
51
+ readonly keyedFork: {
52
+ record(txn: SessionTxStatements, fork: {
53
+ readonly rootSessionId: string;
54
+ readonly forkKey: string;
55
+ }): Promise<void>;
56
+ targetOf(sessionId: string): Promise<ForkTargetReading | undefined>;
57
+ };
58
+ }
59
+ //# sourceMappingURL=session-write-hooks.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-write-hooks.js.map
@@ -1,11 +1,12 @@
1
- import { BaseSessionStorage, type SessionMetadata, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
1
+ import { type SessionMetadata, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
2
2
  import type { Pool } from "mysql2/promise";
3
+ import { WindowedSessionStorage } from "./windowed-session-storage.js";
3
4
  export declare const SESSION_EVENT_LATEST_BY_TYPE_SQL: {
4
5
  readonly floor: `SELECT /*+ USE_INDEX(session_event, idx_session_event_type) */ ${string} FROM session_event WHERE session_id = ? AND type = 'compaction' ORDER BY seq DESC LIMIT 1`;
5
6
  readonly epochAnchor: `SELECT /*+ USE_INDEX(session_event, idx_session_event_type) */ seq, ${string} FROM session_event WHERE session_id = ? AND seq < ? AND type IN ('prompt_epoch','compaction') ORDER BY seq DESC LIMIT 100`;
6
7
  };
7
8
  /**
8
- * TiDB-backed {@link BaseSessionStorage} — the durable L1 event log for one session.
9
+ * TiDB-backed session storage — the durable L1 event log for one session (the window view and its reads: {@link WindowedSessionStorage}).
9
10
  *
10
11
  * - `appendEntry` / `setLeafId` persist under an **atomic compare-and-set on `leaf_id`** (core's F2
11
12
  * optimistic-lock seam): the conditional UPDATE's only predicate is `leaf_id <=> ?`, so a write lands
@@ -14,11 +15,11 @@ export declare const SESSION_EVENT_LATEST_BY_TYPE_SQL: {
14
15
  * `isSessionConflict`), with the `(session_id, seq)` primary key as the backstop for a racing writer
15
16
  * that grabbed the same seq. ([ref] 件2 更正:`leaf_seq` **不是**判据 —— 它是无条件的 `SET leaf_seq =
16
17
  * leaf_seq + 1` 计数器,在同一事务内重读出来给事件铸 `seq`,从不进 WHERE。)
17
- * - The in-memory base tree is the wake-time snapshot; every write is also mirrored into it so the
18
- * live harness keeps reading a consistent view. Wake is **bounded** to `[floor .. leaf]` (F3,
18
+ * - The window (core's in-memory storage, composed) is the wake-time snapshot; every write lands here first and is then
19
+ * recorded into it so the live harness keeps reading a consistent view. Wake is **bounded** to `[floor .. leaf]` (F3,
19
20
  * core 1.6.0 branch-floor seam); older history is covered by the last compaction's summary.
20
21
  */
21
- export declare class TiDBSessionStorage extends BaseSessionStorage {
22
+ export declare class TiDBSessionStorage extends WindowedSessionStorage {
22
23
  private readonly pool;
23
24
  private readonly sessionId;
24
25
  private readonly floorSeq;
@@ -43,21 +44,19 @@ export declare class TiDBSessionStorage extends BaseSessionStorage {
43
44
  * helper trims a FULL-loaded path in memory, whereas we compute the floor seq first and only `SELECT
44
45
  * seq >= floorSeq` — so the head never leaves cold storage. Our sessions are LINEAR (no fork), so
45
46
  * seq-order == root→leaf path-order and our `seq >= floorSeq` tail is byte-identical to
46
- * `boundedTail(path).tail`; the resulting floored `BaseSessionStorage.buildContext()` matches a
47
+ * `boundedTail(path).tail`; the resulting floored window's `buildContext()` matches a
47
48
  * full-tree wake (core's `session-floor.test.ts`). If branching is ever added, switch to `boundedTail`.
48
49
  */
49
50
  static wake(pool: Pool, sessionId: string): Promise<TiDBSessionStorage | null>;
50
51
  /** The bounded-window floor = last compaction's firstKeptEntryId (and its seq). */
51
52
  private static computeFloor;
52
- /** Sub-floor lookups (e.g. a label target) aren't in the loaded tail — fall back to the durable log. */
53
- getEntry(id: string): Promise<SessionTreeEntry | undefined>;
54
- appendEntry(entry: SessionTreeEntry, opts?: SessionWriteOptions): Promise<void>;
55
- setLeafId(leafId: string | null, opts?: SessionWriteOptions): Promise<void>;
53
+ /** Sub-floor lookups (e.g. a label target) aren't in the loaded tail — read the durable log. */
54
+ protected readBelowFloor(id: string): Promise<SessionTreeEntry | undefined>;
56
55
  /**
57
56
  * Atomically: CAS the meta leaf (+bump leaf_seq), then append the event at the new seq.
58
57
  * The `(session_id, seq)` primary key is the backstop — a racing writer that grabbed the same
59
58
  * seq makes our INSERT fail with a duplicate-key, which we translate to a conflict too.
60
59
  */
61
- private persist;
60
+ protected persist(entry: SessionTreeEntry, opts?: SessionWriteOptions): Promise<void>;
62
61
  }
63
62
  //# sourceMappingURL=tidb-session-storage.d.ts.map
@@ -1,24 +1,25 @@
1
1
  import { emitLeafAdvance } from "../session-leaf-bus.js";
2
- import { BaseSessionStorage, SessionError, leafIdAfterEntry, } from "@sema-agent/core";
3
- import { toIso } from "./sql-row-helpers.js";
4
- import { isMysqlDupKeyError } from "./sql-errors.js";
5
- import { PLACEMENT_SELECT_COLUMNS, placementFromRow } from "./session-placement.js";
2
+ import { SessionError, leafIdAfterEntry, } from "@sema-agent/core";
3
+ import { toIso } from "../plugins/sql-row-helpers.js";
4
+ import { isMysqlDupKeyError } from "../plugins/sql-errors.js";
5
+ import { PLACEMENT_SELECT_COLUMNS, placementFromRow } from "../plugins/session-placement.js";
6
6
  import { decodeSessionEventPayload } from "./session-event-payload.js";
7
- import { scanEpochAnchor } from "./session-epoch-anchor.js";
8
- import { jsonColumnText } from "./sql-json-column.js";
7
+ import { scanEpochAnchor } from "../plugins/session-epoch-anchor.js";
8
+ import { jsonColumnText } from "../plugins/sql-json-column.js";
9
9
  import { incarnationFromCell } from "../session-incarnation.js";
10
+ import { WindowedSessionStorage } from "./windowed-session-storage.js";
10
11
  const SESSION_EVENT_BY_TYPE_HINT = "/*+ USE_INDEX(session_event, idx_session_event_type) */";
11
12
  export const SESSION_EVENT_LATEST_BY_TYPE_SQL = {
12
13
  floor: `SELECT ${SESSION_EVENT_BY_TYPE_HINT} ${jsonColumnText("mysql", "payload")} FROM session_event WHERE session_id = ? AND type = 'compaction' ORDER BY seq DESC LIMIT 1`,
13
14
  epochAnchor: `SELECT ${SESSION_EVENT_BY_TYPE_HINT} seq, ${jsonColumnText("mysql", "payload")} FROM session_event WHERE session_id = ? AND seq < ? AND type IN ('prompt_epoch','compaction') ORDER BY seq DESC LIMIT 100`,
14
15
  };
15
16
  const isDupKey = isMysqlDupKeyError;
16
- export class TiDBSessionStorage extends BaseSessionStorage {
17
+ export class TiDBSessionStorage extends WindowedSessionStorage {
17
18
  pool;
18
19
  sessionId;
19
20
  floorSeq;
20
21
  constructor(pool, sessionId, metadata, entries, leafId, floorEntryId = null, floorSeq = 0) {
21
- super(metadata, entries, leafId, { floorEntryId });
22
+ super(metadata, entries, leafId, floorEntryId);
22
23
  this.pool = pool;
23
24
  this.sessionId = sessionId;
24
25
  this.floorSeq = floorSeq;
@@ -54,24 +55,12 @@ export class TiDBSessionStorage extends BaseSessionStorage {
54
55
  return { floorEntryId: null, floorSeq: 0 };
55
56
  return { floorEntryId: fk, floorSeq: Number(seqRows[0].seq) };
56
57
  }
57
- async getEntry(id) {
58
- const inMem = await super.getEntry(id);
59
- if (inMem)
60
- return inMem;
58
+ async readBelowFloor(id) {
61
59
  const [rows] = await this.pool.query(`SELECT ${jsonColumnText("mysql", "payload")} FROM session_event WHERE session_id = ? AND entry_id = ?`, [this.sessionId, id]);
62
60
  if (rows[0] === undefined)
63
61
  return undefined;
64
62
  return decodeSessionEventPayload(rows[0].payload, this.sessionId, id);
65
63
  }
66
- async appendEntry(entry, opts) {
67
- await this.persist(entry, opts);
68
- this.recordEntry(entry);
69
- }
70
- async setLeafId(leafId, opts) {
71
- const leafEntry = this.createLeafEntry(leafId);
72
- await this.persist(leafEntry, opts);
73
- this.recordEntry(leafEntry);
74
- }
75
64
  async persist(entry, opts) {
76
65
  const newLeaf = leafIdAfterEntry(entry);
77
66
  const conditional = opts !== undefined && opts.expectedLeafId !== undefined;