@sema-agent/server 7.147.0 → 7.148.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (725) hide show
  1. package/MIGRATION.md +1039 -24
  2. package/README.md +20 -7
  3. package/README.zh-CN.md +14 -8
  4. package/USAGE.md +380 -163
  5. package/deploy/sema-up/README.md +16 -5
  6. package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
  7. package/deploy/sema-up/chart/templates/_helpers.tpl +20 -4
  8. package/deploy/sema-up/chart/values.yaml +3 -2
  9. package/deploy/sema-up/cluster-up.sh +74 -176
  10. package/deploy/sema-up/kube-up.sh +29 -49
  11. package/deploy/sema-up/lib/chart-run.sh +23 -0
  12. package/deploy/sema-up/lib/dataroot.sh +3 -3
  13. package/deploy/sema-up/lib/health.sh +62 -13
  14. package/deploy/sema-up/lib/helm-values-cluster.py +18 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +35 -0
  16. package/deploy/sema-up/lib/regcred.py +8 -0
  17. package/deploy/sema-up/lib/remote/helm-install.sh +3 -0
  18. package/deploy/sema-up/lib/remote/image-import.sh +6 -0
  19. package/deploy/sema-up/lib/remote/machine-precheck.sh +11 -0
  20. package/deploy/sema-up/lib/remote/region-probe.sh +3 -0
  21. package/deploy/sema-up/lib/remote/stack-ready.sh +26 -0
  22. package/deploy/sema-up/lib/remote/vxlan-guard.sh +8 -0
  23. package/deploy/sema-up/lib/render-stack.py +17 -0
  24. package/deploy/sema-up/lib/shell-text.sh +87 -0
  25. package/deploy/sema-up/lib/usage-flags.txt +10 -0
  26. package/deploy/sema-up/lib/usage-head.txt +1 -0
  27. package/deploy/sema-up/lib/usage-tail.txt +13 -0
  28. package/deploy/sema-up/preflight.sh +10 -8
  29. package/deploy/sema-up/sema-up.sh +14 -39
  30. package/deploy/sema-up/smoke.sh +7 -6
  31. package/deploy/sema-up/stack/compose.dataroot.yaml +3 -0
  32. package/deploy/sema-up/stack/compose.yaml +13 -1
  33. package/deploy/sema-up/stack/sema-stack-cluster.yaml +21 -0
  34. package/dist/adoption/plan.d.ts +24 -0
  35. package/dist/adoption/plan.js +53 -1
  36. package/dist/adoption/runner.d.ts +10 -1
  37. package/dist/adoption/runner.js +36 -16
  38. package/dist/adoption/wire.d.ts +3 -3
  39. package/dist/approval-card.d.ts +28 -30
  40. package/dist/approval-gate-currency.js +3 -2
  41. package/dist/approval-reconciler.d.ts +4 -13
  42. package/dist/approval-reconciler.js +2 -2
  43. package/dist/approval.d.ts +13 -11
  44. package/dist/approval.js +3 -3
  45. package/dist/audit.d.ts +10 -3
  46. package/dist/audit.js +15 -7
  47. package/dist/auth-bridge.d.ts +0 -14
  48. package/dist/auth-bridge.js +0 -7
  49. package/dist/auto-mode-face.d.ts +10 -7
  50. package/dist/auto-mode-face.js +7 -4
  51. package/dist/background-agent-name.d.ts +19 -1
  52. package/dist/background-agent-name.js +12 -2
  53. package/dist/background-session-reap.d.ts +1 -1
  54. package/dist/bake-runner/main.js +9 -6
  55. package/dist/bench/s1/arms.js +6 -5
  56. package/dist/bench/s1/live-deps.js +5 -2
  57. package/dist/bench/s1/run-firm.js +6 -5
  58. package/dist/bind-host.d.ts +25 -0
  59. package/dist/bind-host.js +25 -0
  60. package/dist/boot/adoption.d.ts +3 -0
  61. package/dist/boot/adoption.js +1 -0
  62. package/dist/boot/deployment-mods.d.ts +1 -1
  63. package/dist/boot/execution-env.d.ts +17 -7
  64. package/dist/boot/execution-env.js +37 -31
  65. package/dist/boot/exit-boundary.d.ts +2 -2
  66. package/dist/boot/exit-boundary.js +6 -5
  67. package/dist/boot/fatal-exit.d.ts +3 -5
  68. package/dist/boot/fatal-exit.js +2 -2
  69. package/dist/boot/leader.d.ts +15 -0
  70. package/dist/boot/leader.js +17 -15
  71. package/dist/boot/memory-consolidation.d.ts +37 -29
  72. package/dist/boot/memory-consolidation.js +11 -5
  73. package/dist/boot/org-memory.js +1 -1
  74. package/dist/boot/parked-revive-gate.js +2 -2
  75. package/dist/boot/reapers.d.ts +4 -3
  76. package/dist/boot/reapers.js +19 -16
  77. package/dist/boot/resolve-spec.d.ts +5 -3
  78. package/dist/boot/resolve-spec.js +55 -67
  79. package/dist/boot/retention-lane.d.ts +4 -4
  80. package/dist/boot/retention-lane.js +2 -2
  81. package/dist/boot/runner-deps.d.ts +28 -7
  82. package/dist/boot/runner-deps.js +11 -4
  83. package/dist/boot/runtime-caps.d.ts +2 -2
  84. package/dist/boot/runtime-caps.js +16 -2
  85. package/dist/boot/session-faces.d.ts +16 -7
  86. package/dist/boot/session-faces.js +114 -94
  87. package/dist/boot/shutdown.d.ts +5 -4
  88. package/dist/boot/shutdown.js +6 -4
  89. package/dist/boot/stage-01-config.js +9 -1
  90. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  91. package/dist/boot/stage-02-web-admin-pull.js +6 -1
  92. package/dist/boot/stage-03-store-backend.d.ts +3 -0
  93. package/dist/boot/stage-03-store-backend.js +4 -3
  94. package/dist/boot/stage-04-stores.d.ts +2 -0
  95. package/dist/boot/stage-04-stores.js +2 -2
  96. package/dist/boot/stage-05-execution-env.d.ts +7 -3
  97. package/dist/boot/stage-05-execution-env.js +2 -2
  98. package/dist/boot/stage-06-runners.d.ts +10 -12
  99. package/dist/boot/stage-06-runners.js +23 -15
  100. package/dist/boot/stage-07-capability-layer.d.ts +11 -8
  101. package/dist/boot/stage-07-capability-layer.js +5 -3
  102. package/dist/boot/stage-08-reapers.d.ts +11 -8
  103. package/dist/boot/stage-08-reapers.js +3 -3
  104. package/dist/boot/stage-09-leader.d.ts +12 -15
  105. package/dist/boot/stage-09-leader.js +12 -4
  106. package/dist/boot/stage-10-http-server.d.ts +12 -15
  107. package/dist/boot/stage-10-http-server.js +7 -4
  108. package/dist/boot/store-evidence.d.ts +20 -0
  109. package/dist/boot/store-evidence.js +13 -0
  110. package/dist/boot/stores.d.ts +3 -0
  111. package/dist/boot/stores.js +21 -10
  112. package/dist/boot/task-list-lane.d.ts +4 -4
  113. package/dist/boot/web-admin.d.ts +4 -2
  114. package/dist/boot/web-admin.js +55 -35
  115. package/dist/boot/webfetch-summarize-lane.d.ts +1 -1
  116. package/dist/boot-reclaim.d.ts +3 -1
  117. package/dist/boot-reclaim.js +1 -1
  118. package/dist/brain.d.ts +7 -18
  119. package/dist/brain.js +5 -17
  120. package/dist/budget.js +6 -6
  121. package/dist/capabilities/center-plugins.d.ts +7 -1
  122. package/dist/capabilities/center-plugins.js +32 -10
  123. package/dist/capabilities/center-wiring.js +1 -1
  124. package/dist/capabilities/composite-members.d.ts +2 -2
  125. package/dist/capabilities/composite-members.js +2 -2
  126. package/dist/capabilities/repo-tools.d.ts +2 -0
  127. package/dist/capabilities/repo-tools.js +14 -12
  128. package/dist/capabilities/scenarios.d.ts +6 -15
  129. package/dist/capabilities/scenarios.js +11 -16
  130. package/dist/capabilities/skills.d.ts +1 -1
  131. package/dist/capabilities/tool-defer.d.ts +1 -1
  132. package/dist/capability-facts.d.ts +38 -11
  133. package/dist/capability-facts.js +47 -8
  134. package/dist/card-void.d.ts +4 -4
  135. package/dist/card-void.js +1 -1
  136. package/dist/center-credential-renewer.d.ts +6 -2
  137. package/dist/center-credential-renewer.js +7 -3
  138. package/dist/config-catalog.d.ts +16 -1
  139. package/dist/config-catalog.js +62 -56
  140. package/dist/config-dir-trust.d.ts +37 -4
  141. package/dist/config-dir-trust.js +88 -44
  142. package/dist/config-invariants.d.ts +42 -3
  143. package/dist/config-invariants.js +69 -5
  144. package/dist/config-lkg.d.ts +23 -1
  145. package/dist/config-lkg.js +17 -3
  146. package/dist/config-provider.d.ts +9 -9
  147. package/dist/config-provider.js +25 -110
  148. package/dist/config-pull-failure.d.ts +50 -0
  149. package/dist/config-pull-failure.js +48 -0
  150. package/dist/config-types.d.ts +26 -17
  151. package/dist/config.d.ts +8 -16
  152. package/dist/config.js +113 -47
  153. package/dist/delegated-session-owner.d.ts +1 -1
  154. package/dist/deleted-session-ids.d.ts +3 -2
  155. package/dist/deployment-governance.d.ts +3 -3
  156. package/dist/deployment-shape.d.ts +30 -4
  157. package/dist/deployment-shape.js +7 -0
  158. package/dist/egress-redirect.d.ts +25 -7
  159. package/dist/egress-redirect.js +20 -2
  160. package/dist/elicitation.d.ts +6 -5
  161. package/dist/elicitation.js +23 -22
  162. package/dist/engine-identity.d.ts +28 -0
  163. package/dist/engine-identity.js +10 -0
  164. package/dist/entry-problems.d.ts +5 -7
  165. package/dist/entry-problems.js +1 -1
  166. package/dist/env-facts.js +2 -1
  167. package/dist/env-witness.d.ts +7 -0
  168. package/dist/env-witness.js +16 -0
  169. package/dist/execution-lane-caps.d.ts +5 -18
  170. package/dist/execution-lane-caps.js +0 -22
  171. package/dist/execution-placement.d.ts +58 -18
  172. package/dist/execution-placement.js +41 -2
  173. package/dist/field-conflict.d.ts +7 -11
  174. package/dist/field-conflict.js +3 -3
  175. package/dist/file-history-capture.d.ts +3 -3
  176. package/dist/file-history-disclosure.js +1 -0
  177. package/dist/fleet/fleet-bus.d.ts +21 -3
  178. package/dist/fleet/fleet-bus.js +35 -25
  179. package/dist/fleet/fleet-reconciler.js +2 -2
  180. package/dist/fleet/serving-lease.js +3 -3
  181. package/dist/fleet-client.js +3 -3
  182. package/dist/fleet-lease.d.ts +0 -1
  183. package/dist/fleet-lease.js +4 -5
  184. package/dist/history-anchor.d.ts +23 -3
  185. package/dist/history-anchor.js +24 -4
  186. package/dist/hitl-delivery.d.ts +90 -0
  187. package/dist/hitl-delivery.js +98 -0
  188. package/dist/hooks/classic-stations.d.ts +8 -11
  189. package/dist/hooks/classic-stations.js +0 -7
  190. package/dist/hooks/hook-llm.d.ts +5 -1
  191. package/dist/hooks/hook-llm.js +24 -15
  192. package/dist/hooks/hook-runner.d.ts +67 -57
  193. package/dist/hooks/hook-runner.js +260 -186
  194. package/dist/host-lsp-manager.d.ts +22 -8
  195. package/dist/host-lsp-manager.js +4 -1
  196. package/dist/http/active-run-conflict.d.ts +2 -43
  197. package/dist/http/active-run-conflict.js +3 -7
  198. package/dist/http/admission.d.ts +4 -18
  199. package/dist/http/admission.js +75 -78
  200. package/dist/http/approval-sweeps.d.ts +3 -3
  201. package/dist/http/approval-sweeps.js +54 -30
  202. package/dist/http/caller-trust.d.ts +8 -10
  203. package/dist/http/caller-trust.js +1 -2
  204. package/dist/http/claim-heartbeat.d.ts +49 -0
  205. package/dist/http/claim-heartbeat.js +46 -0
  206. package/dist/http/claimed-run.d.ts +4 -3
  207. package/dist/http/dispatch.d.ts +8 -1
  208. package/dist/http/dispatch.js +76 -30
  209. package/dist/http/durable-run-leg.d.ts +3 -3
  210. package/dist/http/durable-run-leg.js +17 -12
  211. package/dist/http/execution-context.d.ts +17 -43
  212. package/dist/http/execution-context.js +7 -5
  213. package/dist/http/health-reader.d.ts +36 -0
  214. package/dist/http/health-reader.js +21 -0
  215. package/dist/http/health-self-report.d.ts +9 -9
  216. package/dist/http/health-self-report.js +4 -4
  217. package/dist/http/idempotency.d.ts +9 -5
  218. package/dist/http/idempotency.js +4 -4
  219. package/dist/http/memory-compliance-failure-reply.d.ts +15 -16
  220. package/dist/http/memory-compliance-failure-reply.js +4 -2
  221. package/dist/http/memory-face-fault-reply.d.ts +67 -0
  222. package/dist/http/memory-face-fault-reply.js +71 -0
  223. package/dist/http/memory-store-refusal-reply.d.ts +1 -1
  224. package/dist/http/memory-store-refusal-reply.js +3 -0
  225. package/dist/http/owner-access.d.ts +391 -67
  226. package/dist/http/owner-access.js +371 -35
  227. package/dist/http/principal-gate.d.ts +24 -81
  228. package/dist/http/principal-gate.js +24 -68
  229. package/dist/http/refusal-body.d.ts +35 -2
  230. package/dist/http/refusal-body.js +34 -0
  231. package/dist/http/request-guards.d.ts +9 -13
  232. package/dist/http/request-guards.js +34 -68
  233. package/dist/http/resume-composition.d.ts +37 -0
  234. package/dist/http/resume-composition.js +18 -0
  235. package/dist/http/resume-ctx-read.d.ts +35 -12
  236. package/dist/http/resume-ctx-read.js +25 -6
  237. package/dist/http/resume-legs.d.ts +21 -18
  238. package/dist/http/resume-legs.js +189 -129
  239. package/dist/http/retired-skill-manifest.d.ts +1 -1
  240. package/dist/http/route-ctx.d.ts +25 -32
  241. package/dist/http/routes/a2a-serve.d.ts +43 -5
  242. package/dist/http/routes/a2a-serve.js +58 -37
  243. package/dist/http/routes/admin-config-refresh.js +2 -2
  244. package/dist/http/routes/admin-drain.js +2 -2
  245. package/dist/http/routes/admin-memory-optout.js +4 -3
  246. package/dist/http/routes/adoption.d.ts +3 -0
  247. package/dist/http/routes/adoption.js +17 -10
  248. package/dist/http/routes/agents-roster.js +13 -7
  249. package/dist/http/routes/approvals-assistant.js +70 -65
  250. package/dist/http/routes/attachments.js +2 -2
  251. package/dist/http/routes/background.d.ts +3 -3
  252. package/dist/http/routes/background.js +9 -17
  253. package/dist/http/routes/capabilities.js +15 -18
  254. package/dist/http/routes/config-catalog.js +2 -2
  255. package/dist/http/routes/devices.d.ts +3 -3
  256. package/dist/http/routes/devices.js +4 -4
  257. package/dist/http/routes/diagnostics.d.ts +27 -3
  258. package/dist/http/routes/diagnostics.js +27 -21
  259. package/dist/http/routes/engine.js +2 -2
  260. package/dist/http/routes/fleet.js +5 -3
  261. package/dist/http/routes/images.js +10 -6
  262. package/dist/http/routes/leader.d.ts +7 -2
  263. package/dist/http/routes/leader.js +12 -3
  264. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  265. package/dist/http/routes/mcp-reconnect.js +7 -15
  266. package/dist/http/routes/memory-bundle.js +4 -7
  267. package/dist/http/routes/memory-compliance.js +4 -4
  268. package/dist/http/routes/memory-consolidation.js +6 -9
  269. package/dist/http/routes/memory-origin.d.ts +2 -0
  270. package/dist/http/routes/memory-origin.js +7 -8
  271. package/dist/http/routes/memory-policy.js +17 -12
  272. package/dist/http/routes/notify-wake.js +10 -19
  273. package/dist/http/routes/observability.js +3 -3
  274. package/dist/http/routes/principal-inbox.d.ts +1 -1
  275. package/dist/http/routes/principal-inbox.js +2 -2
  276. package/dist/http/routes/projects.d.ts +1 -1
  277. package/dist/http/routes/projects.js +3 -2
  278. package/dist/http/routes/retention-ops.js +6 -9
  279. package/dist/http/routes/rules.js +20 -5
  280. package/dist/http/routes/run-memory-capture.d.ts +2 -2
  281. package/dist/http/routes/run-memory-capture.js +6 -12
  282. package/dist/http/routes/run-permission-mode.d.ts +2 -2
  283. package/dist/http/routes/run-permission-mode.js +10 -17
  284. package/dist/http/routes/runs.js +146 -231
  285. package/dist/http/routes/session-memory-sync.d.ts +2 -2
  286. package/dist/http/routes/session-memory-sync.js +7 -13
  287. package/dist/http/routes/session-sync.d.ts +4 -2
  288. package/dist/http/routes/session-sync.js +21 -20
  289. package/dist/http/routes/sessions-list.d.ts +3 -3
  290. package/dist/http/routes/sessions-list.js +9 -9
  291. package/dist/http/routes/sessions.js +87 -124
  292. package/dist/http/routes/shared-memory.js +6 -6
  293. package/dist/http/routes/side-query.js +2 -2
  294. package/dist/http/routes/tasks.js +136 -120
  295. package/dist/http/routes/trace-usage.d.ts +0 -12
  296. package/dist/http/routes/trace-usage.js +40 -46
  297. package/dist/http/routes/workflows.d.ts +39 -4
  298. package/dist/http/routes/workflows.js +42 -14
  299. package/dist/http/run-concurrency-cap.d.ts +20 -12
  300. package/dist/http/run-concurrency-cap.js +39 -26
  301. package/dist/http/run-read-face.d.ts +3 -5
  302. package/dist/http/run-read-face.js +8 -13
  303. package/dist/http/send.d.ts +12 -3
  304. package/dist/http/send.js +42 -6
  305. package/dist/http/server.d.ts +39 -40
  306. package/dist/http/server.js +36 -11
  307. package/dist/http/sse-log.d.ts +17 -10
  308. package/dist/http/sse-log.js +7 -7
  309. package/dist/http/stored-body-replay.d.ts +12 -0
  310. package/dist/http/stored-body-replay.js +2 -2
  311. package/dist/http/submit-ctx.d.ts +16 -8
  312. package/dist/http/submit-ctx.js +6 -2
  313. package/dist/http/submit-replay.d.ts +19 -6
  314. package/dist/http/submit-replay.js +18 -6
  315. package/dist/http/sync-submit-body.d.ts +3 -4
  316. package/dist/http/sync-submit-body.js +4 -5
  317. package/dist/http/wire-types.d.ts +4 -3
  318. package/dist/identity-source.d.ts +36 -5
  319. package/dist/identity-source.js +27 -0
  320. package/dist/index.d.ts +1 -0
  321. package/dist/index.js +1 -0
  322. package/dist/key-resolver.d.ts +32 -0
  323. package/dist/key-resolver.js +23 -9
  324. package/dist/leader/diffup.js +2 -1
  325. package/dist/leader/endpoint.d.ts +26 -5
  326. package/dist/leader/endpoint.js +154 -14
  327. package/dist/leader/fanout.d.ts +3 -0
  328. package/dist/leader/fanout.js +78 -63
  329. package/dist/leader/leader.d.ts +16 -0
  330. package/dist/leader/leader.js +43 -3
  331. package/dist/leader/merge.d.ts +9 -1
  332. package/dist/leader/merge.js +16 -1
  333. package/dist/leader/repair-wire.js +1 -1
  334. package/dist/leader/wire.d.ts +36 -3
  335. package/dist/leader/wire.js +59 -18
  336. package/dist/lsp-evict.d.ts +6 -4
  337. package/dist/lsp-evict.js +2 -3
  338. package/dist/memory-operator-faces.d.ts +5 -4
  339. package/dist/memory-operator-faces.js +1 -1
  340. package/dist/memory-scope.d.ts +29 -2
  341. package/dist/memory-scope.js +64 -15
  342. package/dist/memory-store-refusal.d.ts +5 -2
  343. package/dist/memory-sync-client.d.ts +3 -2
  344. package/dist/memory-sync-client.js +6 -3
  345. package/dist/model-compat.d.ts +17 -8
  346. package/dist/model-compat.js +6 -2
  347. package/dist/model-context-window.d.ts +18 -0
  348. package/dist/model-context-window.js +2 -0
  349. package/dist/model-entry-headers.d.ts +46 -4
  350. package/dist/model-entry-headers.js +2 -2
  351. package/dist/model-entry-refusal.d.ts +35 -16
  352. package/dist/model-entry-refusal.js +40 -27
  353. package/dist/model-plane-face.d.ts +19 -11
  354. package/dist/model-plane-face.js +9 -1
  355. package/dist/model-plane-probe.d.ts +2 -0
  356. package/dist/model-plane-probe.js +17 -0
  357. package/dist/model-provider.d.ts +3 -3
  358. package/dist/model-route-endpoint.d.ts +9 -5
  359. package/dist/model-route-endpoint.js +29 -7
  360. package/dist/model-select.d.ts +16 -0
  361. package/dist/model-select.js +4 -0
  362. package/dist/mountinfo.d.ts +37 -0
  363. package/dist/mountinfo.js +47 -0
  364. package/dist/namespaced-rule-name.d.ts +23 -14
  365. package/dist/namespaced-rule-name.js +8 -11
  366. package/dist/net-address.d.ts +1 -1
  367. package/dist/observability/corrupt-read-seat.d.ts +4 -4
  368. package/dist/observability/corrupt-read-seat.js +5 -3
  369. package/dist/observability/fail-open.d.ts +58 -38
  370. package/dist/observability/fail-open.js +60 -38
  371. package/dist/observability/logger.d.ts +22 -1
  372. package/dist/observability/logger.js +89 -12
  373. package/dist/observability/metrics.js +3 -4
  374. package/dist/observability/otel-exporter.js +2 -1
  375. package/dist/observability/principal-context.d.ts +14 -7
  376. package/dist/observability/principal-context.js +8 -3
  377. package/dist/observability/run-terminal.d.ts +7 -1
  378. package/dist/observability/run-terminal.js +5 -2
  379. package/dist/orchestration/hardened-vm-runner.d.ts +1 -0
  380. package/dist/orchestration/hardened-vm-runner.js +11 -5
  381. package/dist/orchestration/hardened-vm-worker-runner.d.ts +0 -14
  382. package/dist/orchestration/hardened-vm-worker-runner.js +5 -0
  383. package/dist/orchestration/hardened-vm-worker.js +2 -1
  384. package/dist/orchestration/workflow-completion-inbox.d.ts +3 -3
  385. package/dist/orchestration/workflow-completion-inbox.js +3 -2
  386. package/dist/org-delivery-gate.d.ts +5 -4
  387. package/dist/org-delivery-gate.js +7 -6
  388. package/dist/outbound-dispatcher.d.ts +1 -1
  389. package/dist/outbound-dispatcher.js +6 -12
  390. package/dist/owner-brands.d.ts +81 -0
  391. package/dist/owner-brands.js +42 -0
  392. package/dist/owner-faces.d.ts +531 -0
  393. package/dist/owner-faces.js +126 -0
  394. package/dist/parked-decide.d.ts +67 -5
  395. package/dist/parked-decide.js +127 -5
  396. package/dist/parked-revive-surface.d.ts +14 -4
  397. package/dist/parked-revive-surface.js +5 -4
  398. package/dist/peer-directory.d.ts +6 -8
  399. package/dist/peer-directory.js +3 -2
  400. package/dist/permission-rule-vocab.d.ts +53 -8
  401. package/dist/permission-rule-vocab.js +30 -2
  402. package/dist/plugins/adoption-log-sql.d.ts +0 -22
  403. package/dist/plugins/adoption-log-sql.js +5 -3
  404. package/dist/plugins/approval-ask-retired-delete-by-task-m50.d.ts +7 -0
  405. package/dist/plugins/approval-ask-retired-delete-by-task-m50.js +17 -0
  406. package/dist/plugins/approval-ask-store-file.d.ts +18 -7
  407. package/dist/plugins/approval-ask-store-file.js +37 -14
  408. package/dist/plugins/approval-ask-store-memory.d.ts +12 -4
  409. package/dist/plugins/approval-ask-store-memory.js +24 -10
  410. package/dist/plugins/approval-ask-store-sql.d.ts +39 -20
  411. package/dist/plugins/approval-ask-store-sql.js +41 -10
  412. package/dist/plugins/approval-exemption-skill-m46.d.ts +20 -0
  413. package/dist/plugins/approval-exemption-skill-m46.js +25 -0
  414. package/dist/plugins/approval-exemption-store.d.ts +6 -1
  415. package/dist/plugins/approval-exemption-store.js +14 -0
  416. package/dist/plugins/approval-nonce-store.d.ts +39 -12
  417. package/dist/plugins/approval-nonce-store.js +72 -23
  418. package/dist/plugins/blob-backend.d.ts +2 -0
  419. package/dist/plugins/blob-backend.js +9 -6
  420. package/dist/plugins/caching-session-store.d.ts +13 -1
  421. package/dist/plugins/caching-session-store.js +43 -4
  422. package/dist/plugins/checkpoint-index-columns.d.ts +32 -5
  423. package/dist/plugins/checkpoint-index-columns.js +36 -1
  424. package/dist/plugins/checkpoint-store-face.d.ts +83 -10
  425. package/dist/plugins/checkpoint-store-face.js +18 -1
  426. package/dist/plugins/device-store-sql.js +1 -0
  427. package/dist/plugins/ensure-index.d.ts +13 -1
  428. package/dist/plugins/ensure-index.js +154 -21
  429. package/dist/plugins/ensure-schema-lock-policy.d.ts +0 -15
  430. package/dist/plugins/ensure-schema-lock-policy.js +3 -2
  431. package/dist/plugins/file-run-store.d.ts +63 -23
  432. package/dist/plugins/file-run-store.js +138 -83
  433. package/dist/plugins/host-platform.d.ts +24 -3
  434. package/dist/plugins/host-platform.js +15 -1
  435. package/dist/plugins/image-bake-store-sql.js +2 -0
  436. package/dist/plugins/imported-layer-root-retirement.d.ts +2 -2
  437. package/dist/plugins/k8s-pod-reaper.d.ts +1 -3
  438. package/dist/plugins/k8s-pod-reaper.js +0 -1
  439. package/dist/plugins/leader-run-store-sql.d.ts +22 -0
  440. package/dist/plugins/leader-run-store-sql.js +34 -4
  441. package/dist/plugins/local-checkpoint-store.d.ts +58 -23
  442. package/dist/plugins/local-checkpoint-store.js +195 -76
  443. package/dist/plugins/local-data-dir-modes-m39.js +2 -1
  444. package/dist/plugins/local-docker-capacity.d.ts +93 -0
  445. package/dist/plugins/local-docker-capacity.js +194 -0
  446. package/dist/plugins/local-docker-reaper.d.ts +92 -0
  447. package/dist/plugins/local-docker-reaper.js +102 -0
  448. package/dist/plugins/local-engine-high-water.d.ts +4 -2
  449. package/dist/plugins/local-engine-high-water.js +4 -1
  450. package/dist/plugins/local-session-store.d.ts +358 -125
  451. package/dist/plugins/local-session-store.js +824 -251
  452. package/dist/plugins/local-session-window.d.ts +3 -2
  453. package/dist/plugins/local-session-window.js +3 -2
  454. package/dist/plugins/local-sidecar-quarantine.js +3 -2
  455. package/dist/plugins/local-task-attachment-store.d.ts +18 -1
  456. package/dist/plugins/local-task-attachment-store.js +22 -1
  457. package/dist/plugins/memory-embedder.js +9 -7
  458. package/dist/plugins/memory-engine-pg.d.ts +3 -2
  459. package/dist/plugins/memory-engine-pg.js +14 -5
  460. package/dist/plugins/memory-engine-sql-apply.d.ts +8 -4
  461. package/dist/plugins/memory-engine-sql-apply.js +6 -8
  462. package/dist/plugins/memory-engine-tidb.d.ts +4 -2
  463. package/dist/plugins/memory-engine-tidb.js +11 -2
  464. package/dist/plugins/memory-optout-grant-store-sql.d.ts +1 -1
  465. package/dist/plugins/memory-optout-grant-store-sql.js +3 -3
  466. package/dist/plugins/memory-run-store.d.ts +39 -27
  467. package/dist/plugins/memory-run-store.js +72 -70
  468. package/dist/plugins/one-time-migration-marker.d.ts +10 -0
  469. package/dist/plugins/one-time-migration-marker.js +7 -0
  470. package/dist/plugins/one-time-migrations.d.ts +186 -45
  471. package/dist/plugins/one-time-migrations.js +442 -119
  472. package/dist/plugins/org-delivery-quota-store.js +2 -1
  473. package/dist/plugins/permission-rule-store-file.d.ts +3 -3
  474. package/dist/plugins/permission-rule-store-sql.d.ts +4 -63
  475. package/dist/plugins/permission-rule-store-sql.js +6 -86
  476. package/dist/plugins/pg-pool.d.ts +1 -31
  477. package/dist/plugins/pg-pool.js +16 -7
  478. package/dist/plugins/remote-env-e2b.d.ts +7 -25
  479. package/dist/plugins/remote-env-e2b.js +34 -25
  480. package/dist/plugins/remote-env-host.d.ts +2 -9
  481. package/dist/plugins/remote-env-host.js +34 -22
  482. package/dist/plugins/remote-env-k8s.d.ts +40 -45
  483. package/dist/plugins/remote-env-k8s.js +107 -58
  484. package/dist/plugins/remote-env-local-docker.d.ts +148 -14
  485. package/dist/plugins/remote-env-local-docker.js +367 -72
  486. package/dist/plugins/remote-scratchpad.js +4 -0
  487. package/dist/plugins/retention-deployment.d.ts +49 -17
  488. package/dist/plugins/retention-deployment.js +39 -8
  489. package/dist/plugins/run-preview-m45.d.ts +11 -0
  490. package/dist/plugins/run-preview-m45.js +19 -0
  491. package/dist/plugins/run-store-sql.d.ts +56 -68
  492. package/dist/plugins/run-store-sql.js +127 -116
  493. package/dist/plugins/s3-answer.d.ts +2 -1
  494. package/dist/plugins/sandbox-reaper.d.ts +26 -0
  495. package/dist/plugins/sandbox-reaper.js +2 -0
  496. package/dist/plugins/scenario-prefix-switch-m42.d.ts +54 -0
  497. package/dist/plugins/scenario-prefix-switch-m42.js +55 -0
  498. package/dist/plugins/scheduler-support.d.ts +16 -1
  499. package/dist/plugins/scheduler-support.js +22 -2
  500. package/dist/plugins/schema-consistency.d.ts +42 -9
  501. package/dist/plugins/schema-consistency.js +212 -11
  502. package/dist/plugins/schema-drift-sentence.d.ts +4 -1
  503. package/dist/plugins/schema-drift-sentence.js +4 -4
  504. package/dist/plugins/schema-ensure-legs.d.ts +9 -0
  505. package/dist/plugins/schema-ensure-legs.js +1 -1
  506. package/dist/plugins/schema-indexes.js +3 -0
  507. package/dist/plugins/schema-live-columns.d.ts +14 -5
  508. package/dist/plugins/schema-live-columns.js +10 -10
  509. package/dist/plugins/send-user-file.js +2 -1
  510. package/dist/plugins/session-birth.d.ts +37 -0
  511. package/dist/plugins/session-birth.js +38 -0
  512. package/dist/plugins/session-epoch-anchor.d.ts +40 -12
  513. package/dist/plugins/session-epoch-anchor.js +33 -11
  514. package/dist/plugins/session-ext-table.d.ts +27 -3
  515. package/dist/plugins/session-ext-table.js +19 -6
  516. package/dist/plugins/session-fork.d.ts +15 -1
  517. package/dist/plugins/session-fork.js +3 -0
  518. package/dist/plugins/session-ownership.d.ts +1 -1
  519. package/dist/plugins/session-placement.d.ts +22 -16
  520. package/dist/plugins/session-placement.js +15 -12
  521. package/dist/plugins/session-row-sql.d.ts +12 -0
  522. package/dist/plugins/session-row-sql.js +3 -3
  523. package/dist/plugins/session-run-rollup.d.ts +29 -0
  524. package/dist/plugins/session-run-rollup.js +40 -0
  525. package/dist/plugins/session-store-sql.d.ts +38 -12
  526. package/dist/plugins/session-store-sql.js +130 -30
  527. package/dist/plugins/session-withdraw-sql.d.ts +36 -0
  528. package/dist/plugins/session-withdraw-sql.js +42 -0
  529. package/dist/plugins/shared-memory-store-sql.d.ts +0 -69
  530. package/dist/plugins/shared-memory-store-sql.js +2 -1
  531. package/dist/plugins/shell-sentinel-owner-m48.d.ts +20 -0
  532. package/dist/plugins/shell-sentinel-owner-m48.js +3 -0
  533. package/dist/plugins/snapshot-bucket-presence.d.ts +2 -1
  534. package/dist/plugins/sql-driver.d.ts +1 -1
  535. package/dist/plugins/sql-driver.js +2 -1
  536. package/dist/plugins/sql-errors.d.ts +32 -5
  537. package/dist/plugins/sql-errors.js +55 -7
  538. package/dist/plugins/sql-json-column.d.ts +8 -7
  539. package/dist/plugins/sql-json-column.js +10 -6
  540. package/dist/plugins/store-backend.d.ts +84 -15
  541. package/dist/plugins/store-backend.js +186 -55
  542. package/dist/plugins/store-contracts.d.ts +90 -30
  543. package/dist/plugins/store-contracts.js +22 -1
  544. package/dist/plugins/store-fault.d.ts +28 -2
  545. package/dist/plugins/store-fault.js +20 -2
  546. package/dist/plugins/task-attachment-store.d.ts +15 -3
  547. package/dist/plugins/task-attachment-store.js +22 -9
  548. package/dist/plugins/tidb-pool.js +23 -8
  549. package/dist/plugins/web-search.js +5 -3
  550. package/dist/plugins/workflow-run-store-sql.d.ts +6 -1
  551. package/dist/plugins/workflow-run-store-sql.js +11 -5
  552. package/dist/principal-jwt.d.ts +4 -4
  553. package/dist/principal-jwt.js +20 -5
  554. package/dist/principal-shape.d.ts +41 -0
  555. package/dist/principal-shape.js +19 -0
  556. package/dist/question.d.ts +13 -23
  557. package/dist/question.js +21 -39
  558. package/dist/request-declaration-refusal.d.ts +35 -12
  559. package/dist/request-declaration-refusal.js +21 -9
  560. package/dist/request-form.d.ts +58 -0
  561. package/dist/request-form.js +72 -0
  562. package/dist/request-image-urls.d.ts +8 -2
  563. package/dist/request-image-urls.js +2 -1
  564. package/dist/request-images.d.ts +20 -0
  565. package/dist/request-images.js +59 -0
  566. package/dist/request-key-closure.d.ts +6 -7
  567. package/dist/request-key-closure.js +15 -2
  568. package/dist/resource-suspend.d.ts +7 -16
  569. package/dist/resource-suspend.js +1 -1
  570. package/dist/retired-name-host-notice.d.ts +21 -0
  571. package/dist/retired-name-host-notice.js +12 -0
  572. package/dist/rule-entry-list.d.ts +2 -2
  573. package/dist/rule-entry-list.js +3 -4
  574. package/dist/rule-issue-reading.d.ts +58 -0
  575. package/dist/rule-issue-reading.js +14 -0
  576. package/dist/rules-consent.d.ts +5 -3
  577. package/dist/rules-consent.js +1 -0
  578. package/dist/run-acceptance.d.ts +3 -1
  579. package/dist/run-acceptance.js +3 -0
  580. package/dist/run-local.d.ts +14 -6
  581. package/dist/run-local.js +92 -80
  582. package/dist/run-stale-default.d.ts +7 -0
  583. package/dist/run-stale-default.js +2 -0
  584. package/dist/runs.d.ts +26 -15
  585. package/dist/runs.js +39 -27
  586. package/dist/runtime-caps-resolver.d.ts +21 -6
  587. package/dist/runtime-caps-resolver.js +17 -4
  588. package/dist/runtime-governance.d.ts +2 -2
  589. package/dist/runtime-governance.js +5 -3
  590. package/dist/sealed-key-layout.d.ts +12 -5
  591. package/dist/sealed-key-layout.js +5 -0
  592. package/dist/sealed-key.d.ts +12 -2
  593. package/dist/sealed-key.js +115 -27
  594. package/dist/security.d.ts +128 -158
  595. package/dist/security.js +163 -59
  596. package/dist/sema-config-dir.d.ts +20 -0
  597. package/dist/sema-config-dir.js +25 -0
  598. package/dist/server-secret-env.d.ts +21 -5
  599. package/dist/server-secret-env.js +14 -4
  600. package/dist/session-children-retire.d.ts +7 -5
  601. package/dist/session-children-retire.js +7 -2
  602. package/dist/session-deletion.d.ts +88 -0
  603. package/dist/session-deletion.js +8 -0
  604. package/dist/session-erase.d.ts +145 -0
  605. package/dist/session-erase.js +115 -0
  606. package/dist/session-error-wire.d.ts +5 -5
  607. package/dist/session-error-wire.js +1 -1
  608. package/dist/session-incarnation.d.ts +52 -5
  609. package/dist/session-incarnation.js +19 -2
  610. package/dist/session-policy-wire.d.ts +6 -3
  611. package/dist/session-policy-wire.js +11 -1
  612. package/dist/session-resident-background.d.ts +0 -71
  613. package/dist/session-resident-background.js +4 -3
  614. package/dist/session-row.d.ts +2 -1
  615. package/dist/session-rules-seat.d.ts +12 -0
  616. package/dist/session-rules-seat.js +19 -0
  617. package/dist/session-titler.d.ts +7 -15
  618. package/dist/session-titler.js +1 -1
  619. package/dist/spec-fields.d.ts +57 -3
  620. package/dist/spec-fields.js +72 -51
  621. package/dist/store-posture.d.ts +136 -20
  622. package/dist/store-posture.js +188 -3
  623. package/dist/stored-request-hooks-m20.js +2 -2
  624. package/dist/stores-sql/background-agent-store-sql.d.ts +11 -2
  625. package/dist/stores-sql/background-agent-store-sql.js +73 -20
  626. package/dist/stores-sql/checkpoint-store-sql.d.ts +33 -28
  627. package/dist/stores-sql/checkpoint-store-sql.js +75 -44
  628. package/dist/stores-sql/mailbox-store-sql.d.ts +7 -4
  629. package/dist/stores-sql/mailbox-store-sql.js +31 -32
  630. package/dist/stores-sql/pg-session-storage.d.ts +7 -5
  631. package/dist/stores-sql/pg-session-storage.js +54 -46
  632. package/dist/stores-sql/retention-store-sql.d.ts +87 -19
  633. package/dist/stores-sql/retention-store-sql.js +92 -27
  634. package/dist/stores-sql/session-policy-store-sql.d.ts +32 -10
  635. package/dist/stores-sql/session-policy-store-sql.js +44 -36
  636. package/dist/stores-sql/session-write-hooks.d.ts +12 -6
  637. package/dist/stores-sql/tidb-session-storage.d.ts +4 -4
  638. package/dist/stores-sql/tidb-session-storage.js +13 -8
  639. package/dist/stores-sql/tidb-session-store.d.ts +36 -17
  640. package/dist/stores-sql/tidb-session-store.js +69 -39
  641. package/dist/stores-sql/windowed-session-storage.d.ts +5 -0
  642. package/dist/stores-sql/windowed-session-storage.js +9 -0
  643. package/dist/submission-exit.d.ts +50 -0
  644. package/dist/submission-exit.js +108 -0
  645. package/dist/task-a2a.d.ts +1 -1
  646. package/dist/task-a2a.js +3 -3
  647. package/dist/task-cwd.d.ts +20 -0
  648. package/dist/task-cwd.js +8 -0
  649. package/dist/task-mcp.d.ts +1 -1
  650. package/dist/task-mcp.js +3 -3
  651. package/dist/task-settings.d.ts +14 -10
  652. package/dist/task-settings.js +18 -7
  653. package/dist/terminal.d.ts +25 -43
  654. package/dist/terminal.js +31 -11
  655. package/dist/tool-approval.d.ts +131 -129
  656. package/dist/tool-approval.js +189 -193
  657. package/dist/trace/core-keyset-guard.d.ts +13 -6
  658. package/dist/trace/core-vocab-wire.d.ts +95 -0
  659. package/dist/trace/core-vocab-wire.js +15 -0
  660. package/dist/trace/exit-seat.d.ts +30 -4
  661. package/dist/trace/exit-seat.js +40 -36
  662. package/dist/trace/extension-call-face.d.ts +3 -2
  663. package/dist/trace/extension-call-face.js +3 -1
  664. package/dist/trace/ledger-events.d.ts +4 -7
  665. package/dist/trace/ledger-sink.d.ts +1 -30
  666. package/dist/trace/ledger-sink.js +0 -11
  667. package/dist/trace/model-segment.d.ts +5 -5
  668. package/dist/trace/model-segment.js +5 -5
  669. package/dist/trace/project.d.ts +55 -42
  670. package/dist/trace/project.js +52 -19
  671. package/dist/trace/redact.d.ts +123 -27
  672. package/dist/trace/redact.js +880 -260
  673. package/dist/trace/self-minted-wire.d.ts +487 -19
  674. package/dist/trace/self-minted-wire.js +172 -23
  675. package/dist/trace/wire-projection-faces.d.ts +5 -6
  676. package/dist/trace/wire-projection-faces.js +2 -2
  677. package/dist/upstream-body.d.ts +23 -0
  678. package/dist/upstream-body.js +16 -0
  679. package/dist/url-refusal.d.ts +3 -3
  680. package/dist/url-refusal.js +11 -4
  681. package/dist/user-authored-text.d.ts +1 -1
  682. package/dist/user-input-ledger.d.ts +7 -8
  683. package/dist/user-input-ledger.js +1 -1
  684. package/dist/web-admin-client/apply-effective.d.ts +6 -3
  685. package/dist/web-admin-client/apply-effective.js +13 -16
  686. package/dist/web-admin-client/apply-ledger.d.ts +16 -7
  687. package/dist/web-admin-client/apply-ledger.js +5 -2
  688. package/dist/web-admin-client/center-request.d.ts +2 -2
  689. package/dist/web-admin-client/center-request.js +15 -15
  690. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  691. package/dist/web-admin-client/effective-keys.js +1 -1
  692. package/dist/web-admin-client/entry-metadata.d.ts +8 -0
  693. package/dist/web-admin-client/entry-metadata.js +13 -0
  694. package/dist/web-admin-client/http-client.d.ts +1 -1
  695. package/dist/web-admin-client/http-client.js +23 -4
  696. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  697. package/dist/web-admin-client/mcp-revocation.js +2 -1
  698. package/dist/web-admin-client/read-warnings.d.ts +1 -0
  699. package/dist/web-admin-client/read-warnings.js +1 -0
  700. package/dist/web-admin-client/restart-signal.js +8 -4
  701. package/dist/web-admin-client/skills-mcp.d.ts +2 -2
  702. package/dist/web-admin-client/types.d.ts +1 -2
  703. package/dist/workspace-space.d.ts +3 -2
  704. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +4 -4
  705. package/package.json +6 -3
  706. package/scripts/drain-check-local.mjs +118 -147
  707. package/scripts/drain-check.mysql.sql +22 -2
  708. package/scripts/drain-check.pg.sql +22 -2
  709. package/wire-changes/server@7.148.0.json +1517 -0
  710. package/dist/http/memory-control-plane-corrupt-reply.d.ts +0 -25
  711. package/dist/http/memory-control-plane-corrupt-reply.js +0 -19
  712. package/dist/http/memory-layer-reply.d.ts +0 -30
  713. package/dist/http/memory-layer-reply.js +0 -24
  714. package/dist/lsp/e2b-bridge.d.ts +0 -57
  715. package/dist/lsp/e2b-bridge.js +0 -139
  716. package/dist/lsp/e2b-manager.d.ts +0 -93
  717. package/dist/lsp/e2b-manager.js +0 -178
  718. package/dist/lsp/lsp-frames.d.ts +0 -14
  719. package/dist/lsp/lsp-frames.js +0 -25
  720. package/dist/lsp/manager.d.ts +0 -129
  721. package/dist/lsp/manager.js +0 -127
  722. package/dist/lsp/types.d.ts +0 -12
  723. package/dist/lsp/types.js +0 -2
  724. package/dist/lsp/ws-transport.d.ts +0 -40
  725. package/dist/lsp/ws-transport.js +0 -210
@@ -2,7 +2,7 @@ import { type SessionPolicyStore, type SessionPermissionRules, type StoredSessio
2
2
  import type { Pool as MySqlPool } from "mysql2/promise";
3
3
  import type { Pool as PgPool } from "pg";
4
4
  import { type JsonColumnShape } from "../plugins/sql-json-column.js";
5
- import { type SqlDriver } from "../plugins/sql-driver.js";
5
+ import { type SqlDialect, type SqlDriver, type SqlTxConn } from "../plugins/sql-driver.js";
6
6
  /** `session_policy.policy_key` 的**唯一铸造点**(core 复合键的 sha256)。
7
7
  *
8
8
  * 🔴 导出而不是让收编腿再抄一份(clay 宪法「schema 单一属主禁复制」):[ref] form b 的身份重绑要
@@ -44,16 +44,38 @@ export type StoredSessionRulesBody = SessionPermissionRules & Pick<StoredSession
44
44
  * + 恰好解一次 `decodeJsonColumn` + 折码 `foldJsonColumn`);本店只留「形判据是哪一只」与「坏体折成哪个码」。
45
45
  */
46
46
  export declare function readSessionRulesBody(body: unknown): JsonColumnShape<StoredSessionRulesBody>;
47
- /** 本店唯一的日志口:抹除封键那一臂([ref])的点名。缺席 ⇒ 退回 `console.warn`(不静默)。
48
- * 结构型,与服务日志口的 `warn` 逐位同形:本目录对服务的观测模块零依赖(目录的可搬性),服务的日志口照样直接交进来。 */
47
+ /** 封键的 warn 事件名(提交后每次抹除至多一条,点名会话与被封的键)。 */
48
+ export declare const SEALED_EVENT = "session_policy_erase_sealed_keys";
49
+ /** 一把被封的键:单向哈希的键 + 那一行读不出的两个计数的原文(取证用;不带 principal 明文、不带规则体)。 */
50
+ export type SealedEraseKey = {
51
+ readonly policyKey: string;
52
+ readonly rev: string;
53
+ readonly gen: string;
54
+ };
55
+ /** 本店的日志口:抹除封键那一臂([ref])的点名。**必填**:组合座(`store-backend.ts`)交服务的日志口,没有自己的就交日志出口接缝的
56
+ * 缺省 logger —— 本目录不碰 stdio(目录的可搬性;进程 stdout / stderr 只有接缝一个出口,`test/log-exit-single-source-gate.test.ts`)。
57
+ * 结构型,与服务日志口的 `warn` 逐位同形,服务的日志口照样直接交进来。注入的这只抛 ⇒ 同一行落接缝的缺省 logger(见 `discloseSealed`)。 */
49
58
  export type SessionPolicyStoreLogger = {
50
59
  warn(msg: string, fields?: Record<string, unknown>): void;
51
60
  };
61
+ /**
62
+ * 一次客户端写的计数(部署的格:会话规则是客户端可见的会话态,提交出口撤回一只刚铸的会话之前读这只计数)。组合座交入;店只在锁住根行、根行在、
63
+ * 所有拒判之后、规则落行之前,同一事务、同一连接调它一次 —— 计数住部署的旁表,店目录不认识那张表。
64
+ */
65
+ export type SessionClientWriteCounter = (conn: SqlTxConn, dialect: SqlDriver["dialect"], sessionId: string) => Promise<void>;
66
+ /**
67
+ * 按会话抹除规则行的**唯一语句源**(店的 `deleteBySession` 在自己的事务里调;会话删除执行体 `retention-store-sql.ts` 在会话树事务里对一批会话调 ——
68
+ * 同一组语句,`session_policy_rev_mark` 的高水位律只写这一处,core 契约 `session_policy.rev_survives_delete`)。调用方持事务。
69
+ * 步序:锁这批会话的规则行(`policy_key` 升序,与 `putRules` 同向)→ 每把键写记号(rev 高水位 + 下一代 `gen`;读不出计数的行写封键)→ 删规则行。
70
+ * 返回封键(调用方负责响亮披露)。没有规则行 ⇒ 零写。
71
+ */
72
+ export declare function eraseSessionPolicyRowsOn(conn: Pick<SqlTxConn, "query">, dialect: SqlDialect, sessionIds: readonly string[]): Promise<readonly SealedEraseKey[]>;
52
73
  /** Dual-dialect durable SessionPolicyStore. See the file header for the dialect-delta ledger. */
53
74
  export declare class SqlSessionPolicyStore implements SessionPolicyStore {
54
75
  private readonly db;
55
- private readonly logger?;
56
- constructor(db: SqlDriver, logger?: SessionPolicyStoreLogger | undefined);
76
+ private readonly countClientWrite;
77
+ private readonly logger;
78
+ constructor(db: SqlDriver, countClientWrite: SessionClientWriteCounter, logger: SessionPolicyStoreLogger);
57
79
  /** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
58
80
  private q;
59
81
  /** 判据属主 = `sql-errors.ts`([ref] P1-①;本站点旧形已是并集形,收编后语义不变)。 */
@@ -143,9 +165,9 @@ export declare class SqlSessionPolicyStore implements SessionPolicyStore {
143
165
  * (驱动错误;那只记号本来就读不回,`putRules` 同样拒)—— 抹除不读记号,这一形不在本判词射程内。 */
144
166
  deleteBySession(sessionId: string): Promise<void>;
145
167
  /**
146
- * [ref] 封键的响亮面:一次抹除至多一条 warn。日志座**抛** ⇒ 退回 `console.warn` 带原句 —— 走到这里删除已经提交,
147
- * 一次日志故障不许把它报成失败(E21 会因此 500、overwrite-dst 会因此中止;codex 7.105.0 修复验证轮 [medium] 同形)。
148
- * 缺日志座(直接 `new` 本店的工具 / 测试)⇒ `console.warn`,不静默。
168
+ * [ref] 封键的响亮面:一次抹除至多一条 warn。走到这里删除已经提交,一次日志故障不许把它报成失败(E21 会因此 500、
169
+ * overwrite-dst 会因此中止;codex 7.105.0 修复验证轮 [medium] 同形)⇒ 日志座抛不往外抛;**也不吞披露**:同一行落日志出口接缝的
170
+ * 缺省 logger(与数据根权限收紧的披露座同一条律:披露不许因日志座坏而消失)—— 运维面对一把读写都拒的封键,要靠这一行知道为什么。
149
171
  */
150
172
  private discloseSealed;
151
173
  /**
@@ -161,10 +183,10 @@ export declare class SqlSessionPolicyStore implements SessionPolicyStore {
161
183
  }
162
184
  /** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
163
185
  export declare class TiDBSessionPolicyStore extends SqlSessionPolicyStore {
164
- constructor(pool: MySqlPool, logger?: SessionPolicyStoreLogger);
186
+ constructor(pool: MySqlPool, countClientWrite: SessionClientWriteCounter, logger: SessionPolicyStoreLogger);
165
187
  }
166
188
  /** PostgreSQL binding — historical class name + ctor shape preserved. */
167
189
  export declare class PgSessionPolicyStore extends SqlSessionPolicyStore {
168
- constructor(pool: PgPool, logger?: SessionPolicyStoreLogger);
190
+ constructor(pool: PgPool, countClientWrite: SessionClientWriteCounter, logger: SessionPolicyStoreLogger);
169
191
  }
170
192
  //# sourceMappingURL=session-policy-store-sql.d.ts.map
@@ -5,6 +5,7 @@ import { decodeJsonColumn, isJsonColumnBodyProblem, jsonColumnText } from "../pl
5
5
  import { pgHasUnstorable } from "../plugins/pg-safe-json.js";
6
6
  import { mysqlDriver, pgDriver } from "../plugins/sql-driver.js";
7
7
  import { isDupKeyError, retryOnDeadlock } from "../plugins/sql-errors.js";
8
+ import { createLogger } from "../observability/logger.js";
8
9
  export const policyKeyFor = (sessionId, principal) => createHash("sha256").update(JSON.stringify([sessionId, principal ?? null])).digest("hex");
9
10
  const policyKey = policyKeyFor;
10
11
  const RULES = SESSION_RULES_COLUMN.name;
@@ -50,16 +51,47 @@ function readRowCounters(r, where) {
50
51
  return { rev, gen };
51
52
  }
52
53
  const SEALED_MARK_REV = Number.MAX_SAFE_INTEGER;
53
- const SEALED_EVENT = "session_policy_erase_sealed_keys";
54
+ export const SEALED_EVENT = "session_policy_erase_sealed_keys";
54
55
  const NO_SEALED_KEYS = [];
55
56
  function sealedKeyError(sessionId, what) {
56
57
  return new SessionPolicyError("corrupt", `session rules for session ${JSON.stringify(sessionId)}: ${what} is sealed — an erase removed a row whose counters were unreadable (session_policy_rev_mark.rev = ${SEALED_MARK_REV}), so its rule state is unknown; refusing rather than serve it as "no rules" until an operator unseals it (USAGE §9.11)`);
57
58
  }
59
+ export async function eraseSessionPolicyRowsOn(conn, dialect, sessionIds) {
60
+ if (sessionIds.length === 0)
61
+ return NO_SEALED_KEYS;
62
+ const q = (mysql, pg) => (dialect === "mysql" ? mysql : pg);
63
+ const idHoles = sessionIds.map((_, i) => (dialect === "mysql" ? "?" : `$${i + 1}`)).join(",");
64
+ const { rows } = await conn.query(`SELECT policy_key, session_id, rev, gen FROM session_policy WHERE session_id IN (${idHoles}) ORDER BY policy_key FOR UPDATE`, [...sessionIds]);
65
+ if (rows.length === 0)
66
+ return NO_SEALED_KEYS;
67
+ const now = new Date();
68
+ const keys = rows.map((r) => String(r.policy_key));
69
+ const params = [];
70
+ const sealedKeys = [];
71
+ const tuples = rows.map((r) => {
72
+ const sessionId = String(r.session_id);
73
+ const counters = readRowCounters(r, `for session ${JSON.stringify(sessionId)} (erase)`);
74
+ const readable = !("problem" in counters) && isStoredCounter(counters.gen + 1, 0);
75
+ if (!readable)
76
+ sealedKeys.push({ policyKey: String(r.policy_key), rev: String(r.rev), gen: String(r.gen) });
77
+ params.push(String(r.policy_key), sessionId, readable ? counters.rev : SEALED_MARK_REV, readable ? counters.gen + 1 : 0, now);
78
+ const base = params.length - 5;
79
+ return dialect === "mysql" ? "(?,?,?,?,?)" : `($${base + 1},$${base + 2},$${base + 3},$${base + 4},$${base + 5})`;
80
+ });
81
+ await conn.query(q(`INSERT INTO session_policy_rev_mark (policy_key, session_id, rev, gen, erased_at) VALUES ${tuples.join(",")}` +
82
+ " ON DUPLICATE KEY UPDATE rev = GREATEST(session_policy_rev_mark.rev, VALUES(rev)), gen = GREATEST(session_policy_rev_mark.gen + 1, VALUES(gen)), erased_at = VALUES(erased_at)", `INSERT INTO session_policy_rev_mark (policy_key, session_id, rev, gen, erased_at) VALUES ${tuples.join(",")}` +
83
+ " ON CONFLICT (policy_key) DO UPDATE SET rev = GREATEST(session_policy_rev_mark.rev, EXCLUDED.rev), gen = GREATEST(session_policy_rev_mark.gen + 1, EXCLUDED.gen), erased_at = EXCLUDED.erased_at"), params);
84
+ const holes = keys.map((_, i) => (dialect === "mysql" ? "?" : `$${i + 1}`)).join(",");
85
+ await conn.query(`DELETE FROM session_policy WHERE policy_key IN (${holes})`, keys);
86
+ return sealedKeys;
87
+ }
58
88
  export class SqlSessionPolicyStore {
59
89
  db;
90
+ countClientWrite;
60
91
  logger;
61
- constructor(db, logger) {
92
+ constructor(db, countClientWrite, logger) {
62
93
  this.db = db;
94
+ this.countClientWrite = countClientWrite;
63
95
  this.logger = logger;
64
96
  }
65
97
  q(mysql, pg) {
@@ -94,6 +126,7 @@ export class SqlSessionPolicyStore {
94
126
  async putRules(sessionId, principal, rules, opts) {
95
127
  const key = policyKey(sessionId, principal);
96
128
  return this.retrying(() => this.tx(async (conn) => {
129
+ const root = await conn.query(this.q("SELECT session_id FROM session_meta WHERE session_id = ? FOR UPDATE", "SELECT session_id FROM session_meta WHERE session_id = $1 FOR UPDATE"), [sessionId]);
97
130
  const { rows } = await conn.query(this.q(`SELECT ${jsonColumnText("mysql", RULES)}, rev, gen FROM session_policy WHERE policy_key = ? FOR UPDATE`, `SELECT ${jsonColumnText("pg", RULES)}, rev, gen FROM session_policy WHERE policy_key = $1 FOR UPDATE`), [key]);
98
131
  const prior = rows[0] ? rowToStored(rows[0], `for session ${JSON.stringify(sessionId)} (pre-write snapshot)`) : undefined;
99
132
  const priorRev = prior?.rev ?? 0;
@@ -115,6 +148,8 @@ export class SqlSessionPolicyStore {
115
148
  if (!isStoredCounter(nextRev, 1) || !isStoredCounter(nextGen, 0)) {
116
149
  throw new SessionPolicyError("corrupt", `session rules for session ${JSON.stringify(sessionId)}: the next stamp (rev ${nextRev}, gen ${nextGen}) would leave the safe-integer range this store reads back — refusing before writing a row nothing could read`);
117
150
  }
151
+ if (root.rows.length > 0)
152
+ await this.countClientWrite(conn, this.db.dialect, sessionId);
118
153
  const json = JSON.stringify(clean);
119
154
  const now = new Date();
120
155
  if (prior) {
@@ -132,30 +167,7 @@ export class SqlSessionPolicyStore {
132
167
  return retryOnDeadlock(this.db.dialect, attempt, (e) => this.isDupKey(e));
133
168
  }
134
169
  async deleteBySession(sessionId) {
135
- const sealed = await this.retrying(() => this.tx(async (conn) => {
136
- const { rows } = await conn.query(this.q("SELECT policy_key, rev, gen FROM session_policy WHERE session_id = ? ORDER BY policy_key FOR UPDATE", "SELECT policy_key, rev, gen FROM session_policy WHERE session_id = $1 ORDER BY policy_key FOR UPDATE"), [sessionId]);
137
- if (rows.length === 0)
138
- return NO_SEALED_KEYS;
139
- const now = new Date();
140
- const keys = rows.map((r) => String(r.policy_key));
141
- const params = [];
142
- const sealedKeys = [];
143
- const tuples = rows.map((r) => {
144
- const counters = readRowCounters(r, `for session ${JSON.stringify(sessionId)} (erase)`);
145
- const readable = !("problem" in counters) && isStoredCounter(counters.gen + 1, 0);
146
- if (!readable)
147
- sealedKeys.push({ policyKey: String(r.policy_key), rev: String(r.rev), gen: String(r.gen) });
148
- params.push(String(r.policy_key), sessionId, readable ? counters.rev : SEALED_MARK_REV, readable ? counters.gen + 1 : 0, now);
149
- const base = params.length - 5;
150
- return this.db.dialect === "mysql" ? "(?,?,?,?,?)" : `($${base + 1},$${base + 2},$${base + 3},$${base + 4},$${base + 5})`;
151
- });
152
- await conn.query(this.q(`INSERT INTO session_policy_rev_mark (policy_key, session_id, rev, gen, erased_at) VALUES ${tuples.join(",")}` +
153
- " ON DUPLICATE KEY UPDATE rev = GREATEST(session_policy_rev_mark.rev, VALUES(rev)), gen = GREATEST(session_policy_rev_mark.gen + 1, VALUES(gen)), erased_at = VALUES(erased_at)", `INSERT INTO session_policy_rev_mark (policy_key, session_id, rev, gen, erased_at) VALUES ${tuples.join(",")}` +
154
- " ON CONFLICT (policy_key) DO UPDATE SET rev = GREATEST(session_policy_rev_mark.rev, EXCLUDED.rev), gen = GREATEST(session_policy_rev_mark.gen + 1, EXCLUDED.gen), erased_at = EXCLUDED.erased_at"), params);
155
- const holes = keys.map((_, i) => (this.db.dialect === "mysql" ? "?" : `$${i + 1}`)).join(",");
156
- await conn.query(`DELETE FROM session_policy WHERE policy_key IN (${holes})`, keys);
157
- return sealedKeys;
158
- }));
170
+ const sealed = await this.retrying(() => this.tx((conn) => eraseSessionPolicyRowsOn(conn, this.db.dialect, [sessionId])));
159
171
  if (sealed.length > 0)
160
172
  this.discloseSealed(sessionId, sealed);
161
173
  }
@@ -165,15 +177,11 @@ export class SqlSessionPolicyStore {
165
177
  keys,
166
178
  note: "these rows' counters were unreadable, so the erase could not end their lineage: each key now carries a sealed rev mark and answers every read and write with SessionPolicyError corrupt until an operator unseals its session_policy_rev_mark row in place (USAGE §9.11)",
167
179
  };
168
- if (this.logger === undefined) {
169
- console.warn(`[session-policy] ${SEALED_EVENT}`, fields);
170
- return;
171
- }
172
180
  try {
173
181
  this.logger.warn(SEALED_EVENT, fields);
174
182
  }
175
- catch (err) {
176
- console.warn(`[session-policy] ${SEALED_EVENT} — the injected logger threw (${err instanceof Error ? err.message : String(err)})`, fields);
183
+ catch {
184
+ createLogger().warn(SEALED_EVENT, fields);
177
185
  }
178
186
  }
179
187
  async tx(fn) {
@@ -198,13 +206,13 @@ export class SqlSessionPolicyStore {
198
206
  }
199
207
  }
200
208
  export class TiDBSessionPolicyStore extends SqlSessionPolicyStore {
201
- constructor(pool, logger) {
202
- super(mysqlDriver(pool), logger);
209
+ constructor(pool, countClientWrite, logger) {
210
+ super(mysqlDriver(pool), countClientWrite, logger);
203
211
  }
204
212
  }
205
213
  export class PgSessionPolicyStore extends SqlSessionPolicyStore {
206
- constructor(pool, logger) {
207
- super(pgDriver(pool), logger);
214
+ constructor(pool, countClientWrite, logger) {
215
+ super(pgDriver(pool), countClientWrite, logger);
208
216
  }
209
217
  }
210
218
  //# sourceMappingURL=session-policy-store-sql.js.map
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * ## 形 = 引擎 SQL 店包的钩表(`@sema-agent/core-stores-sql` 的 `SqlTransactionHooks.session.beforeCommit`)
6
6
  * {@link SessionWriteHooks.beforeCommit} 与包里那一只同名、同调用时刻(根行锁住之后、写之前)、同语句面(本事务连接的 `query`)、同写闭集
7
- * (`import` / `delete` / `retention-delete`)。本仓还不依赖那只包 ⇒ 型在这里声明;店随包搬家时改从包根取型。与包的形只差一处,是向引擎的请托:
7
+ * (`import` / `delete` / `retention-delete`;本服务另加 `erase`)。本仓还不依赖那只包 ⇒ 型在这里声明;店随包搬家时改从包根取型。与包的形只差一处,是向引擎的请托:
8
8
  * 拒的载荷 —— 包里是一句话(`{ refuse: string }`),这里是部署的具名错误(`{ refuse: Error }`):导入 / 删除的调用方按错误的型答各自的 wire 码
9
9
  * (409 `session_active` / `conflict.session_writer`),一句话答不出。
10
10
  *
@@ -25,15 +25,21 @@ export interface SessionTxStatements {
25
25
  }>;
26
26
  }
27
27
  /**
28
- * 改动会话树根的写(闭集,与包同一组词):
28
+ * 改动会话树根的写(闭集;前三个词与包同一组,`erase` 是本服务的扩展 —— 向引擎的请托同上):
29
29
  * · `import` —— 导入写口(整段新建、整段换装、暂存提交)落定这一行:根行已被本事务锁住 / 占下;
30
- * · `delete` —— 属主删除:根行已被本事务锁住;
31
- * · `retention-delete` —— 留存删除一棵会话树的根(留存座的事务;根行已锁)。
30
+ * · `delete` —— 不经删除协调器的删一行(提交出口的条件撤回):根行已被本事务锁住;
31
+ * · `retention-delete` —— 留存删除一棵会话树的根(留存座的事务;根行已锁);
32
+ * · `erase` —— 删净一只在删会话(执行器 `stores-sql/retention-store-sql.ts` 的 `eraseSession`,删除协调器的执行体):这一行必须处于 `token` 那一次删除的在删态
33
+ * (会话三态 活 → 在删 → 没了,围栏在 `plugins/session-store-sql.ts` 的删除面);根行已被本事务锁住。
32
34
  */
33
- export interface SessionWrite {
35
+ export type SessionWrite = {
34
36
  readonly op: "import" | "delete" | "retention-delete";
35
37
  readonly rootSessionId: string;
36
- }
38
+ } | {
39
+ readonly op: "erase";
40
+ readonly rootSessionId: string;
41
+ readonly token: string;
42
+ };
37
43
  /** 钩的答案:放行,或拒(店回滚、一个字节不写、原样抛这只错)。 */
38
44
  export type SessionWriteVerdict = "proceed" | {
39
45
  readonly refuse: Error;
@@ -3,7 +3,6 @@ import type { Pool } from "mysql2/promise";
3
3
  import { WindowedSessionStorage } from "./windowed-session-storage.js";
4
4
  export declare const SESSION_EVENT_LATEST_BY_TYPE_SQL: {
5
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`;
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`;
7
6
  };
8
7
  /**
9
8
  * TiDB-backed session storage — the durable L1 event log for one session (the window view and its reads: {@link WindowedSessionStorage}).
@@ -25,12 +24,13 @@ export declare class TiDBSessionStorage extends WindowedSessionStorage {
25
24
  private readonly floorSeq;
26
25
  constructor(pool: Pool, sessionId: string, metadata: SessionMetadata, entries: SessionTreeEntry[], leafId: string | null, floorEntryId?: string | null, floorSeq?: number);
27
26
  /**
28
- * [ref] S3 [ref] pull seam — `SessionStorage.getEpochAnchor?()`: the nearest prompt-epoch carrier BELOW the
27
+ * [ref] S3 [ref] pull seam — `SessionStorage.getEpochAnchor?()`: the nearest prompt-epoch carrier on the branch BELOW the
29
28
  * bounded-wake floor, AS STORED (engine 7.52.0: `Promise<unknown>`; the engine reads the record, a retired shape
30
29
  * included). The engine's `Session.getPromptEpoch()` asks for it only when the in-window branch walk finds no carrier
31
30
  * (a rewind/resumeAt cut inside the kept tail; compactions without a restatement). The one reading of every windowed
32
- * storage (both SQL twins, the local leg's view window) is {@link scanEpochAnchor}; this backend supplies its page query
33
- * (keyset-paged to exhaustion) and decodes its own rows.
31
+ * storage (both SQL twins, the local leg's view window) is {@link scanEpochAnchor} — it walks the floor entry's parent
32
+ * chain, not the row order; this backend supplies the twins' page ({@link epochAnchorPageSql}, keyset-paged to
33
+ * exhaustion) and decodes its own carrier rows.
34
34
  */
35
35
  getEpochAnchor(): Promise<unknown>;
36
36
  /**
@@ -4,14 +4,13 @@ import { toIso } from "../plugins/sql-row-helpers.js";
4
4
  import { isMysqlDupKeyError } from "../plugins/sql-errors.js";
5
5
  import { PLACEMENT_SELECT_COLUMNS, placementFromRow } from "../plugins/session-placement.js";
6
6
  import { decodeSessionEventPayload } from "./session-event-payload.js";
7
- import { scanEpochAnchor } from "../plugins/session-epoch-anchor.js";
7
+ import { epochAnchorPageSql, epochFloorOf, scanEpochAnchor, sqlEpochAnchorRowOf } from "../plugins/session-epoch-anchor.js";
8
8
  import { jsonColumnText } from "../plugins/sql-json-column.js";
9
- import { incarnationFromCell } from "../session-incarnation.js";
9
+ import { forkLineageOfRow, incarnationFromCell } from "../session-incarnation.js";
10
10
  import { WindowedSessionStorage } from "./windowed-session-storage.js";
11
11
  const SESSION_EVENT_BY_TYPE_HINT = "/*+ USE_INDEX(session_event, idx_session_event_type) */";
12
12
  export const SESSION_EVENT_LATEST_BY_TYPE_SQL = {
13
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`,
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`,
15
14
  };
16
15
  const isDupKey = isMysqlDupKeyError;
17
16
  export class TiDBSessionStorage extends WindowedSessionStorage {
@@ -25,13 +24,13 @@ export class TiDBSessionStorage extends WindowedSessionStorage {
25
24
  this.floorSeq = floorSeq;
26
25
  }
27
26
  async getEpochAnchor() {
28
- return scanEpochAnchor(this.floorSeq, async (beforeSeq) => {
29
- const [rows] = await this.pool.query(SESSION_EVENT_LATEST_BY_TYPE_SQL.epochAnchor, [this.sessionId, beforeSeq]);
30
- return rows.map((r) => ({ seq: r.seq, payload: r.payload }));
27
+ return scanEpochAnchor(epochFloorOf(this.floorSeq, await this.windowFloorEntry()), async (beforeSeq) => {
28
+ const [rows] = await this.pool.query(epochAnchorPageSql("mysql"), [this.sessionId, beforeSeq]);
29
+ return rows.map(sqlEpochAnchorRowOf);
31
30
  }, (row) => decodeSessionEventPayload(row.payload, this.sessionId, row.seq));
32
31
  }
33
32
  static async wake(pool, sessionId) {
34
- const [metaRows] = await pool.query(`SELECT created_at, leaf_id, leaf_seq, incarnation, ${PLACEMENT_SELECT_COLUMNS} FROM session_meta WHERE session_id = ?`, [sessionId]);
33
+ const [metaRows] = await pool.query(`SELECT created_at, leaf_id, leaf_seq, incarnation, ${PLACEMENT_SELECT_COLUMNS}, forked_from, forked_from_incarnation FROM session_meta WHERE session_id = ?`, [sessionId]);
35
34
  const meta = metaRows[0];
36
35
  if (!meta)
37
36
  return null;
@@ -39,7 +38,13 @@ export class TiDBSessionStorage extends WindowedSessionStorage {
39
38
  const [eventRows] = await pool.query(`SELECT seq, ${jsonColumnText("mysql", "payload")} FROM session_event WHERE session_id = ? AND seq >= ? ORDER BY seq ASC`, [sessionId, floorSeq]);
40
39
  const entries = eventRows.map((r) => decodeSessionEventPayload(r.payload, sessionId, r.seq));
41
40
  const placement = placementFromRow(meta);
42
- const metadata = { id: sessionId, createdAt: toIso(meta.created_at), incarnation: incarnationFromCell(sessionId, meta.incarnation), ...(placement !== undefined ? { placement } : {}) };
41
+ const metadata = {
42
+ id: sessionId,
43
+ createdAt: toIso(meta.created_at),
44
+ incarnation: incarnationFromCell(sessionId, meta.incarnation),
45
+ ...(placement !== undefined ? { placement } : {}),
46
+ ...forkLineageOfRow(sessionId, meta.forked_from, meta.forked_from_incarnation),
47
+ };
43
48
  return new TiDBSessionStorage(pool, sessionId, metadata, entries, meta.leaf_id ?? null, floorEntryId, floorSeq);
44
49
  }
45
50
  static async computeFloor(pool, sessionId) {
@@ -13,10 +13,36 @@
13
13
  import { type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
14
14
  import type { Pool } from "mysql2/promise";
15
15
  import type { RetentionDeclaration } from "@sema-agent/core";
16
- import type { SessionWriteHooks } from "./session-write-hooks.js";
16
+ import { type RegisterReceipt, type WithdrawJudgeVerdict, type WithdrawOutcome } from "../session-incarnation.js";
17
+ import type { SessionTxStatements, SessionWriteHooks } from "./session-write-hooks.js";
17
18
  import { type PlacementAcquireOpts } from "../plugins/session-placement.js";
18
19
  import { type StagingHandle } from "../session-sync-kernel.js";
19
20
  import { type ForkPlacement, type ForkTarget, type ForkToOutcome } from "../plugins/session-fork.js";
21
+ /**
22
+ * **条件撤回的店那一半**(两方言一形;TiDB 孪生与 PG 孪生 `pg-session-storage.ts` 同调;撤回的规则在 `plugins/session-birth.ts` 头注)。
23
+ * 店拿根行、化身、内容、认领;部署交入的条件({@link SessionDeleteCondition})带可撤条目型名单与部署判据(启用标记、客户端写计数、别的 run、本次 run 的部署行),
24
+ * 判据跑在**同一事务、同一连接**的语句面上。每一读都是锁定读(`FOR UPDATE`):TiDB 悲观事务里普通 SELECT 读的是事务开始时的快照,
25
+ * 等根锁期间别人提交的写(导入的内容、计数 +1、新 run 行)它看不到 —— 锁定读是当前读;PG 读已提交下每一句新快照,同一形照写。
26
+ */
27
+ export interface SessionDeleteCondition {
28
+ /** 候选那一位(这一笔 INSERT 铸下的属主 + 化身)。 */
29
+ readonly expect: {
30
+ readonly owner: string | null;
31
+ readonly incarnation: string;
32
+ };
33
+ /** 可撤集合 A 组的条目型(部署交入;名单的唯一属主在部署,店只拿它做锁定读的 `NOT IN`)。 */
34
+ readonly withdrawableEntryTypes: readonly string[];
35
+ /** 部署判据(同一语句面;放行时已在同一事务里删掉本次 run 的部署行)。 */
36
+ readonly judge: (tx: SessionTxStatements) => Promise<WithdrawJudgeVerdict>;
37
+ }
38
+ /** 两孪生的方言词(店只用它挑占位符形)。 */
39
+ type WithdrawDialect = "mysql" | "pg";
40
+ /**
41
+ * 店的那一半(调用方已开事务、持着这只连接;答 `withdrawn` ⇒ 调用方提交,否则回滚):
42
+ * 锁根行 → 不在 ⇒ `absent`;属主 / 化身不是候选 ⇒ `incarnation` → 锁定读一条可撤集合之外的会话条目 ⇒ `content` → 部署钩 `delete` 臂(认领在 ⇒ 拒)⇒ `claim`
43
+ * → 部署判据 → 删会话条目 + 按化身删根行(旁表随外键级联)。
44
+ */
45
+ export declare function withdrawSessionOn(tx: SessionTxStatements, dialect: WithdrawDialect, hooks: SessionWriteHooks, sessionId: string, cond: SessionDeleteCondition): Promise<WithdrawOutcome>;
20
46
  export declare class TiDBSessionStore implements SessionStore {
21
47
  private readonly pool;
22
48
  /** 托管留存声明 = 装配交给它的词(后端按扫车道开不开给;不给 ⇒ `"none"`)。读法逐字见
@@ -45,6 +71,13 @@ export declare class TiDBSessionStore implements SessionStore {
45
71
  private load;
46
72
  /** Idempotently create a session_meta row with an owner (core `SessionStore.register`). Existing owner is never overwritten. */
47
73
  register(sessionId: string, owner: string | null): Promise<void>;
74
+ /**
75
+ * 出生回执面(`plugins/session-birth.ts`):与 {@link register} 同一笔 INSERT;候选化身 = 这一次 INSERT 入参里铸的那一只(不复读)。
76
+ * 已在的行上 INSERT 是 no-op 臂 ⇒ 行上的化身不是候选 ⇒ 撤回在锁内比对时判「留」—— 出生事实只在那里判,这里不分新旧行。
77
+ */
78
+ registerWithReceipt(sessionId: string, owner: string | null): Promise<RegisterReceipt>;
79
+ /** 条件删除(`plugins/session-birth.ts` 的撤回;本连接开事务 → 店与部署两半同一语句面 → 撤回才提交,否则回滚)。 */
80
+ deleteSessionIf(sessionId: string, cond: SessionDeleteCondition): Promise<WithdrawOutcome>;
48
81
  /**
49
82
  * acquire 的建行(唯一一处):普通会话 ⇒ 无主(按 id 首建的既有读法);placed 会话 ⇒ 属主 = `placement.owner` 原样,与元组同一条 INSERT 落库
50
83
  * (core 7.62.0 [ref] 盒义务 7:委派树的属主是引擎判的,店只记、不判、不推断;唯一读法 `placedSessionOwnerOf`,值不是主体名也不是 null ⇒ 响亮拒、不留行。PG 孪生同调)。
@@ -101,7 +134,7 @@ export declare class TiDBSessionStore implements SessionStore {
101
134
  */
102
135
  forget(sessionId: string): void;
103
136
  /** 真删除一只 placed 会话的两张表(条件删门在 `placement_kind IS NOT NULL`;事务内 meta 先删=提交点,
104
- * 与 {@link deleteSession} 同序)。任何 I/O 失败上浮成 `SessionError("storage")`,绝不吞。 */
137
+ * 会话删除执行体同序:行先删 = 提交点)。任何 I/O 失败上浮成 `SessionError("storage")`,绝不吞。 */
105
138
  private deletePlacedSession;
106
139
  /**
107
140
  * E17 — fork a session: copy its WHOLE durable history to a NEW uuidv7 session owned by `owner`, mirroring
@@ -233,22 +266,8 @@ export declare class TiDBSessionStore implements SessionStore {
233
266
  * stream is never reaped while another abandoned one is. Returns the affected row count. Driven by main.ts's reaper.
234
267
  */
235
268
  sweepStagingSessions(): Promise<number>;
236
- /**
237
- * E21 — purge a session's CONVERSATION HISTORY (session_meta + session_event). Idempotent: a missing
238
- * session is a no-op (returns false). The service's OWN run-ledger / checkpoint / tool-result rows are
239
- * purged separately by the route's `purgeSession` coordinator — this method owns only the session
240
- * abstraction's tables (the `SessionRepo.delete` half).
241
- *
242
- * `owner` is the single-DB-fleet null-safe SQL owner guard on `session_meta.owner` (defense-in-depth — the
243
- * route already owner-gates; `<=>` so a legacy null-owner session matches owner=null). session_event carries
244
- * no owner column, so its purge is GATED on the owner-matched meta delete: if the meta DELETE matched 0 rows
245
- * (wrong owner / already gone) we skip the event delete — so a wrong-owner caller can never strand-delete
246
- * another tenant's events. Meta is deleted FIRST (mirrors core BUG-2: once it's gone, wake is `null`
247
- * regardless of leftover events; if a crash interleaves, orphan events with NO meta are invisible, never a
248
- * half-session), and the event purge only runs after that owner-matched commit point.
249
- */
250
- deleteSession(sessionId: string, owner: string | null): Promise<boolean>;
251
269
  get size(): number;
252
270
  dispose(): void;
253
271
  }
272
+ export {};
254
273
  //# sourceMappingURL=tidb-session-store.d.ts.map
@@ -5,11 +5,11 @@ import { jsonColumnText } from "../plugins/sql-json-column.js";
5
5
  import { MANAGED_RETENTION, UNMANAGED_RETENTION } from "../plugins/retention-declaration.js";
6
6
  import { headFromRow, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
7
7
  import { contentForkRelation, fastForwardSharedContentDiverged } from "../session-sync-content.js";
8
- import { placementCapabilityOf, LIST_PLACED_BATCH, PLACEMENT_SELECT_COLUMNS, placedRowFromRow, placementFromRow, placementInsertValues, SESSION_DURABILITY, SESSION_PLACEMENTS, } from "../plugins/session-placement.js";
8
+ import { placementCapabilityOf, LIST_PLACED_BATCH, PLACEMENT_SELECT_COLUMNS, placedRowFromRow, placementFromRow, placementInsertCells, SESSION_DURABILITY, SESSION_PLACEMENTS, } from "../plugins/session-placement.js";
9
9
  import { classifySyncRelationshipByIds, SyncConflictError, StagedCommitOwnerChangedError, stagingIdFor, STAGING_ID_MARKER, STAGING_GC_GRACE_MS, } from "../session-sync-kernel.js";
10
10
  import { assertFirstOwnerWritable, forkOwnerOf, isSessionOwnerValue, placedSessionOwnerOf } from "../plugins/session-ownership.js";
11
- import { selectForkRows } from "@sema-agent/core";
12
- import { FORK_LOG_ROW_SHAPE, ForkTargetUnsettledError, classifyForkTarget, forkByFreshId, forkPointOf } from "../plugins/session-fork.js";
11
+ import { forkRowCells, selectForkRows } from "@sema-agent/core";
12
+ import { FORK_LOG_ROW_SHAPE, ForkTargetUnsettledError, classifyForkTarget, forkByFreshId, forkPointOf, sameSourceGeneration } from "../plugins/session-fork.js";
13
13
  import { isMysqlDupKeyError } from "../plugins/sql-errors.js";
14
14
  const statementsOn = (conn) => ({
15
15
  async query(sql, params) {
@@ -17,6 +17,34 @@ const statementsOn = (conn) => ({
17
17
  return Array.isArray(res) ? { rows: res, affected: 0 } : { rows: [], affected: res.affectedRows };
18
18
  },
19
19
  });
20
+ function withdrawPlaceholders(dialect, from, count) {
21
+ return Array.from({ length: count }, (_, i) => (dialect === "pg" ? `$${from + i}` : "?"));
22
+ }
23
+ const keptAs = (word) => ({ withdrawn: false, kept: word });
24
+ export async function withdrawSessionOn(tx, dialect, hooks, sessionId, cond) {
25
+ const [p1] = withdrawPlaceholders(dialect, 1, 1);
26
+ const root = (await tx.query(`SELECT owner, incarnation FROM session_meta WHERE session_id = ${p1} FOR UPDATE`, [sessionId])).rows[0];
27
+ if (root === undefined)
28
+ return keptAs("absent");
29
+ const owner = root.owner === null || root.owner === undefined ? null : String(root.owner);
30
+ if (String(root.incarnation ?? "") !== cond.expect.incarnation || owner !== cond.expect.owner)
31
+ return keptAs("incarnation");
32
+ const types = withdrawPlaceholders(dialect, 2, cond.withdrawableEntryTypes.length);
33
+ const content = await tx.query(`SELECT type FROM session_event WHERE session_id = ${p1} AND type NOT IN (${types.join(", ")}) LIMIT 1 FOR UPDATE`, [sessionId, ...cond.withdrawableEntryTypes]);
34
+ if (content.rows.length > 0)
35
+ return keptAs("content");
36
+ if ((await hooks.beforeCommit(tx, { op: "delete", rootSessionId: sessionId })) !== "proceed")
37
+ return keptAs("claim");
38
+ const judged = await cond.judge(tx);
39
+ if (judged !== "proceed")
40
+ return keptAs(judged.keep);
41
+ await tx.query(`DELETE FROM session_event WHERE session_id = ${p1}`, [sessionId]);
42
+ const [q1, q2] = withdrawPlaceholders(dialect, 1, 2);
43
+ const gone = await tx.query(`DELETE FROM session_meta WHERE session_id = ${q1} AND incarnation = ${q2}`, [sessionId, cond.expect.incarnation]);
44
+ if (gone.affected !== 1)
45
+ throw new Error(`withdraw of session ${sessionId}: the root row this transaction holds locked matched ${gone.affected} rows on delete — engine/driver anomaly, refusing to commit`);
46
+ return { withdrawn: true };
47
+ }
20
48
  class HookRefusal {
21
49
  refuse;
22
50
  constructor(refuse) {
@@ -74,21 +102,45 @@ export class TiDBSessionStore {
74
102
  return { session: new StoredSession(storage), sessionId };
75
103
  }
76
104
  async register(sessionId, owner) {
105
+ await this.registerWithReceipt(sessionId, owner);
106
+ }
107
+ async registerWithReceipt(sessionId, owner) {
77
108
  if (!isSessionOwnerValue(owner)) {
78
109
  if ((await this.headOf(sessionId)) !== undefined)
79
- return;
110
+ return {};
80
111
  assertFirstOwnerWritable(sessionId, owner);
81
112
  }
82
- await this.insertMeta(sessionId, owner, undefined);
113
+ const incarnation = mintSessionIncarnation();
114
+ await this.insertMeta(sessionId, owner, undefined, incarnation);
115
+ return { minted: { sessionId, owner, incarnation } };
116
+ }
117
+ async deleteSessionIf(sessionId, cond) {
118
+ const conn = await this.pool.getConnection();
119
+ try {
120
+ await conn.beginTransaction();
121
+ const outcome = await withdrawSessionOn(statementsOn(conn), "mysql", this.hooks, sessionId, cond);
122
+ if (outcome.withdrawn)
123
+ await conn.commit();
124
+ else
125
+ await conn.rollback();
126
+ return outcome;
127
+ }
128
+ catch (err) {
129
+ await conn.rollback().catch(() => undefined);
130
+ throw err;
131
+ }
132
+ finally {
133
+ conn.release();
134
+ }
83
135
  }
84
136
  async createOnAcquire(sessionId, placement) {
85
137
  await this.insertMeta(sessionId, placement === undefined ? null : placedSessionOwnerOf(sessionId, placement), placement);
86
138
  }
87
- async insertMeta(sessionId, owner, placement) {
139
+ async insertMeta(sessionId, owner, placement, incarnation = mintSessionIncarnation()) {
88
140
  const now = new Date();
89
- await this.pool.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, " +
90
- "placement_kind, placement_scope, placement_parent_session_id, placement_root_session_id, placement_handle, placed_at) " +
91
- "VALUES (?,?,?,?,NULL,0,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE leaf_seq = leaf_seq", [sessionId, owner, now, now, mintSessionIncarnation(), ...placementInsertValues(placement, now)]);
141
+ const placed = placementInsertCells(placement, now);
142
+ await this.pool.query(`INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, ${placed.columns}) ` +
143
+ "VALUES (?,?,?,?,NULL,0,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE leaf_seq = leaf_seq", [sessionId, owner, now, now, incarnation, ...placed.values]);
92
144
  }
93
145
  async placementOf(sessionId) {
94
146
  const [rows] = await this.pool.query(`SELECT ${PLACEMENT_SELECT_COLUMNS} FROM session_meta WHERE session_id = ?`, [sessionId]);
@@ -168,7 +220,8 @@ export class TiDBSessionStore {
168
220
  throw new ForkTargetUnsettledError(target.id);
169
221
  }
170
222
  async forkToOnce(sourceId, owner, target) {
171
- const [metaRows] = await this.pool.query("SELECT leaf_id, owner FROM session_meta WHERE session_id = ?", [sourceId]);
223
+ const sourceRow = "SELECT leaf_id, owner, incarnation FROM session_meta WHERE session_id = ?";
224
+ const [metaRows] = await this.pool.query(sourceRow, [sourceId]);
172
225
  if (!metaRows[0])
173
226
  return null;
174
227
  const leafId = metaRows[0].leaf_id ?? null;
@@ -177,16 +230,20 @@ export class TiDBSessionStore {
177
230
  if (storage === null)
178
231
  return null;
179
232
  const point = await forkPointOf(storage);
233
+ const cells = forkRowCells(await storage.getMetadata());
180
234
  const [allRows] = await this.pool.query(`SELECT entry_id, parent_id, type, ${jsonColumnText("mysql", "payload")}, ts FROM session_event WHERE session_id = ? ORDER BY seq ASC`, [sourceId]);
235
+ const [afterRows] = await this.pool.query(sourceRow, [sourceId]);
236
+ if (!sameSourceGeneration(cells.forkedFromIncarnation, metaRows[0].incarnation, afterRows[0]?.incarnation))
237
+ return null;
181
238
  const { rows: eventRows, leafId: forkLeafId } = selectForkRows(allRows, leafId, point, FORK_LOG_ROW_SHAPE);
182
239
  const now = new Date();
183
240
  const conn = await this.pool.getConnection();
184
241
  let collided = false;
185
242
  try {
186
243
  await conn.beginTransaction();
244
+ const placed = placementInsertCells(target.placement, now);
187
245
  try {
188
- await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, " +
189
- "placement_kind, placement_scope, placement_parent_session_id, placement_root_session_id, placement_handle, placed_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", [target.id, forkOwner, now, now, forkLeafId, eventRows.length, mintSessionIncarnation(), ...placementInsertValues(target.placement, now)]);
246
+ await conn.query(`INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation, ${placed.columns}, forked_from, forked_from_incarnation) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`, [target.id, forkOwner, now, now, forkLeafId, eventRows.length, mintSessionIncarnation(), ...placed.values, cells.forkedFrom, cells.forkedFromIncarnation ?? null]);
190
247
  }
191
248
  catch (err) {
192
249
  if (!isMysqlDupKeyError(err))
@@ -362,33 +419,6 @@ export class TiDBSessionStore {
362
419
  }
363
420
  return removed;
364
421
  }
365
- async deleteSession(sessionId, owner) {
366
- const conn = await this.pool.getConnection();
367
- try {
368
- await conn.beginTransaction();
369
- const [locked] = await conn.query("SELECT session_id FROM session_meta WHERE session_id = ? FOR UPDATE", [sessionId]);
370
- if (locked.length > 0)
371
- settleHookVerdict(await this.hooks.beforeCommit(statementsOn(conn), { op: "delete", rootSessionId: sessionId }));
372
- const [metaRes] = await conn.query("DELETE FROM session_meta WHERE session_id = ? AND owner <=> ?", [sessionId, owner]);
373
- if (metaRes.affectedRows > 0)
374
- await conn.query("DELETE FROM session_event WHERE session_id = ?", [sessionId]);
375
- await conn.commit();
376
- return metaRes.affectedRows > 0;
377
- }
378
- catch (err) {
379
- try {
380
- await conn.rollback();
381
- }
382
- catch {
383
- }
384
- if (err instanceof HookRefusal)
385
- throw err.refuse;
386
- throw err;
387
- }
388
- finally {
389
- conn.release();
390
- }
391
- }
392
422
  get size() {
393
423
  return this.pending.size;
394
424
  }
@@ -45,6 +45,11 @@ export declare abstract class WindowedSessionStorage implements SessionStorage {
45
45
  getReplayLoss(): ReturnType<InMemorySessionStorage["getReplayLoss"]>;
46
46
  /** 窗口此刻的日志标记(同步读;引擎存储的读法)。 */
47
47
  logMarkNow(): SessionLogMark;
48
+ /**
49
+ * 窗口的地板那一条(窗口里就有,不另读库)—— 地板之下的 epoch 锚从它的父起沿分支走(`plugins/session-epoch-anchor.ts` 的 `epochFloorOf`)。
50
+ * 没有地板(整条日志都在窗口里)⇒ `undefined`;地板 id 指向窗口里没有的条目 ⇒ 坏会话(响亮)。
51
+ */
52
+ protected windowFloorEntry(): Promise<SessionTreeEntry | undefined>;
48
53
  /** 窗口里没有的 id(地板之下)回落到库。 */
49
54
  getEntry(id: string): Promise<SessionTreeEntry | undefined>;
50
55
  appendEntry(entry: SessionTreeEntry, opts?: SessionWriteOptions): Promise<void>;
@@ -39,6 +39,15 @@ export class WindowedSessionStorage {
39
39
  logMarkNow() {
40
40
  return this.view.logMarkNow();
41
41
  }
42
+ async windowFloorEntry() {
43
+ const floorId = this.view.getFloorId();
44
+ if (floorId === null)
45
+ return undefined;
46
+ const floor = await this.view.getEntry(floorId);
47
+ if (floor === undefined)
48
+ throw new SessionError("corrupt_session", `Entry ${floorId} not found — the window's floor names an entry the window does not hold`);
49
+ return floor;
50
+ }
42
51
  async getEntry(id) {
43
52
  return (await this.view.getEntry(id)) ?? (await this.readBelowFloor(id));
44
53
  }