@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
@@ -2,7 +2,7 @@ import { homedir } from "node:os";
2
2
  import { createCorruptReadSeat, createDurableAbsenceSeat } from "../observability/corrupt-read-seat.js";
3
3
  import { createLogger } from "../observability/logger.js";
4
4
  import { join } from "node:path";
5
- import { existsSync } from "node:fs";
5
+ import { existsSync, readdirSync } from "node:fs";
6
6
  import { AdoptionError, FileStorageBackend } from "@sema-agent/core";
7
7
  import { FileWorkflowJournalStore } from "@sema-agent/core";
8
8
  import { fileSessionCaptureRecordStore } from "@sema-agent/core";
@@ -33,16 +33,17 @@ import { FileUserInputLedgerStore } from "./user-input-ledger-file.js";
33
33
  import { TiDBUserInputLedgerStore, PgUserInputLedgerStore } from "./user-input-ledger-sql.js";
34
34
  import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
35
35
  import { TiDBSessionPolicyStore, PgSessionPolicyStore } from "../stores-sql/session-policy-store-sql.js";
36
- import { TiDBWorkflowJournalStore, PgWorkflowJournalStore } from "./workflow-journal-store-sql.js";
37
- import { TiDBFileHistoryStore, PgFileHistoryStore, FILE_HISTORY_BLOB_TABLE, FILE_HISTORY_BLOB_KEY_PREFIX } from "./file-history-store-sql.js";
38
- import { MinioBlobBackend, SqlBlobBackend } from "./blob-backend.js";
36
+ import { TiDBWorkflowJournalStore, PgWorkflowJournalStore } from "../stores-sql/workflow-journal-store-sql.js";
37
+ import { TiDBFileHistoryStore, PgFileHistoryStore, FILE_HISTORY_BLOB_KEY_PREFIX } from "../stores-sql/file-history-store-sql.js";
38
+ import { SqlBlobIndex } from "../stores-sql/blob-index-sql.js";
39
+ import { MinioBlobBackend } from "./blob-backend.js";
39
40
  import { buildDisplaySafeUrl } from "../trace/redact.js";
40
- import { fileMemoryControlDirFor } from "../memory-scope.js";
41
+ import { fileMemoryControlDirFor, memoryEngineRootFor } from "../memory-scope.js";
41
42
  import { createTidbPool, ensureSchema as ensureTidbSchema } from "./tidb-pool.js";
42
43
  import { createPgPool, ensurePgSchema, pgPoolOptions } from "./pg-pool.js";
43
44
  import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
44
- import { TiDBCheckpointStore, PgCheckpointStore } from "./checkpoint-store-sql.js";
45
- import { TiDBToolResultStore, PgToolResultStore } from "./tool-result-store-sql.js";
45
+ import { TiDBCheckpointStore, PgCheckpointStore } from "../stores-sql/checkpoint-store-sql.js";
46
+ import { TiDBToolResultStore, PgToolResultStore } from "../stores-sql/tool-result-store-sql.js";
46
47
  import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
47
48
  import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
48
49
  import { TiDBLeaderRunStore, PgLeaderRunStore } from "./leader-run-store-sql.js";
@@ -52,45 +53,62 @@ import { TiDBCostQuota } from "./tidb-cost-quota.js";
52
53
  import { PgCostQuota } from "./pg-cost-quota.js";
53
54
  import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
54
55
  import { PgRateLimiter } from "./pg-rate-limiter.js";
55
- import { TiDBSessionStore } from "./tidb-session-store.js";
56
- import { PgSessionStore } from "./pg-session-storage.js";
56
+ import { TiDBSessionStore } from "../stores-sql/tidb-session-store.js";
57
+ import { PgSessionStore } from "../stores-sql/pg-session-storage.js";
58
+ import { SqlSessionStore } from "./session-store-sql.js";
57
59
  import { TiDBSharedMemoryStore, PgSharedMemoryStore } from "./shared-memory-store-sql.js";
58
60
  import { TiDBAdoptionLogStore, PgAdoptionLogStore } from "./adoption-log-sql.js";
59
- import { TiDBRetentionStore, PgRetentionStore, sqlStoreRetention } from "./retention-store-sql.js";
61
+ import { SqlRetentionStore } from "../stores-sql/retention-store-sql.js";
62
+ import { sqlStoreRetention } from "./retention-declaration.js";
63
+ import { createRetentionDeploymentHooks } from "./retention-deployment.js";
64
+ import { createSqlSessionWriteHooks } from "./session-store-sql.js";
60
65
  import { TiDBRetentionLaneStore, PgRetentionLaneStore } from "./retention-lane-store-sql.js";
61
66
  import { createSqlPermissionRuleStores } from "./permission-rule-store-sql.js";
62
- import { FILE_PERMISSION_RULE_DIR, createFilePermissionRuleStores } from "./permission-rule-store-file.js";
67
+ import { FILE_PERMISSION_RULE_DIR, createFilePermissionRuleStores, fileRuleBucketOwners, isFileBucketDamaged } from "./permission-rule-store-file.js";
63
68
  import { retireImportedLayerRootAllows } from "./imported-layer-root-retirement.js";
69
+ import { buildDataDirLayout, tightenLocalDataDirModes } from "./local-data-dir-modes-m39.js";
70
+ import { holdEngineHighWater } from "./local-engine-high-water.js";
71
+ import { serviceVersion } from "../service-version.js";
64
72
  import { mysqlDriver, pgDriver } from "./sql-driver.js";
65
73
  import { storeDegradedReasonFor } from "../store-posture.js";
66
74
  import { openWithinWait } from "./store-open-wait.js";
67
- function historyBlobBackend(config, dialect, pool) {
75
+ export function workflowJournalOf(config, backend) {
76
+ return config.selfOrchestrationEnabled && backend ? backend.workflowJournal() : undefined;
77
+ }
78
+ function fileHistoryOptions(config) {
68
79
  const s = config.snapshotBlobStore;
69
- if (!s)
70
- return new SqlBlobBackend(dialect, pool, config.snapshotBlobSqlMaxBytes, FILE_HISTORY_BLOB_TABLE, createLogger(config.logLevel));
71
- return new MinioBlobBackend({
72
- endpoint: s.endpoint,
73
- bucket: s.bucket,
74
- accessKey: s.accessKey,
75
- secretKey: s.secretKey,
76
- ...(s.region ? { region: s.region } : {}),
77
- keyPrefix: `${s.keyPrefix ?? ""}${FILE_HISTORY_BLOB_KEY_PREFIX}`,
78
- ...(s.presignTtlSec ? { presignTtlSec: s.presignTtlSec } : {}),
79
- }, { dialect, pool, table: FILE_HISTORY_BLOB_TABLE });
80
+ const placement = s
81
+ ? {
82
+ blobs: new MinioBlobBackend({
83
+ endpoint: s.endpoint,
84
+ bucket: s.bucket,
85
+ accessKey: s.accessKey,
86
+ secretKey: s.secretKey,
87
+ ...(s.region ? { region: s.region } : {}),
88
+ keyPrefix: `${s.keyPrefix ?? ""}${FILE_HISTORY_BLOB_KEY_PREFIX}`,
89
+ ...(s.presignTtlSec ? { presignTtlSec: s.presignTtlSec } : {}),
90
+ }),
91
+ }
92
+ : {
93
+ ...(config.snapshotBlobSqlMaxBytes !== undefined ? { blobSqlMaxBytes: config.snapshotBlobSqlMaxBytes } : {}),
94
+ log: createLogger(config.logLevel),
95
+ };
96
+ return { ...config.fileHistory, ...placement };
80
97
  }
81
- function legacyBlobBackend(config, dialect, pool) {
98
+ function legacyBlobIndex(config, dialect, pool) {
82
99
  const s = config.snapshotBlobStore;
83
- if (!s)
84
- return new SqlBlobBackend(dialect, pool, config.snapshotBlobSqlMaxBytes, undefined, createLogger(config.logLevel));
85
- return new MinioBlobBackend({
86
- endpoint: s.endpoint,
87
- bucket: s.bucket,
88
- accessKey: s.accessKey,
89
- secretKey: s.secretKey,
90
- ...(s.region ? { region: s.region } : {}),
91
- ...(s.keyPrefix ? { keyPrefix: s.keyPrefix } : {}),
92
- ...(s.presignTtlSec ? { presignTtlSec: s.presignTtlSec } : {}),
93
- }, { dialect, pool });
100
+ const bytes = s
101
+ ? new MinioBlobBackend({
102
+ endpoint: s.endpoint,
103
+ bucket: s.bucket,
104
+ accessKey: s.accessKey,
105
+ secretKey: s.secretKey,
106
+ ...(s.region ? { region: s.region } : {}),
107
+ ...(s.keyPrefix ? { keyPrefix: s.keyPrefix } : {}),
108
+ ...(s.presignTtlSec ? { presignTtlSec: s.presignTtlSec } : {}),
109
+ })
110
+ : undefined;
111
+ return new SqlBlobIndex(dialect, pool, { table: "snapshot_blob", ...(bytes !== undefined ? { bytes } : {}), log: createLogger(config.logLevel) });
94
112
  }
95
113
  async function legacySweepImpl(config, dialect, pool) {
96
114
  const sql = "SELECT blob_hash FROM snapshot_blob";
@@ -105,7 +123,38 @@ async function legacySweepImpl(config, dialect, pool) {
105
123
  }
106
124
  if (orphans.length === 0)
107
125
  return 0;
108
- return legacyBlobBackend(config, dialect, pool).deleteBlobs(orphans);
126
+ return legacyBlobIndex(config, dialect, pool).sweep(orphans);
127
+ }
128
+ export function createSqlRetentionCallHooks(db, opts, input) {
129
+ const deployment = createRetentionDeploymentHooks(db.dialect, opts, input);
130
+ return { hooks: { retention: deployment.hooks.retention, session: createSqlSessionWriteHooks(db) }, endedSpaces: deployment.endedSpaces };
131
+ }
132
+ export function createSqlRetentionExecutor(db, opts) {
133
+ const logged = opts.logger !== undefined ? { logger: opts.logger } : {};
134
+ const reads = new SqlRetentionStore(db, logged);
135
+ const forCall = (input) => {
136
+ const hooks = createSqlRetentionCallHooks(db, opts, input);
137
+ return { store: new SqlRetentionStore(db, { ...logged, transactionHooks: hooks.hooks }), hooks, call: { domain: input.domain, cutoffMs: input.cutoffMs } };
138
+ };
139
+ return {
140
+ retention: reads.retention,
141
+ listRetentionDomains: () => reads.listRetentionDomains(),
142
+ previewRetention: (input) => reads.previewRetention(input),
143
+ expireCheckpoints: async (input) => {
144
+ const one = forCall(input);
145
+ return one.store.expireCheckpoints(one.call);
146
+ },
147
+ deleteExpiredSessions: async (input) => {
148
+ const one = forCall(input);
149
+ const receipt = await one.store.deleteExpiredSessions(one.call);
150
+ const endedSpaces = one.hooks.endedSpaces();
151
+ return endedSpaces.length > 0 ? { ...receipt, endedSpaces } : receipt;
152
+ },
153
+ deleteOrphanToolResults: async (input) => {
154
+ const one = forCall(input);
155
+ return one.store.deleteOrphanToolResults(one.call);
156
+ },
157
+ };
109
158
  }
110
159
  export function assertCloudSnapshotBlobPosture(kind, config) {
111
160
  if (kind === "local" || config.snapshotBlobStore || config.snapshotBlobAllowSql)
@@ -138,12 +187,12 @@ class TiDBBackend {
138
187
  sendFileLedger() { return new TiDBSendFileLedger(this.pool); }
139
188
  userInputLedger() { return new TiDBUserInputLedgerStore(this.pool); }
140
189
  sessionPolicy(logger) { return new TiDBSessionPolicyStore(this.pool, logger); }
141
- fileHistory() { return new TiDBFileHistoryStore(this.pool, historyBlobBackend(this.config, "mysql", this.pool), this.config.fileHistory); }
190
+ fileHistory() { return new TiDBFileHistoryStore(this.pool, fileHistoryOptions(this.config)); }
142
191
  memoryOptOutGrant() { return new TiDBMemoryOptOutGrantStore(this.pool); }
143
192
  sessionCaptureRecords() { return () => (this.captureRecordsInst ??= new TiDBSessionCaptureRecordStore(this.pool)); }
144
193
  captureRecordsInst;
145
194
  legacySnapshotBlobSweep() { return legacySweepImpl(this.config, "mysql", this.pool); }
146
- runOneTimeMigrations() { return runSqlOneTimeMigrations("mysql", this.pool, { lanes: deployedExecutionLanes(this.config) }); }
195
+ runOneTimeMigrations() { return runSqlOneTimeMigrations("mysql", this.pool, { lanes: deployedExecutionLanes(this.config), liveRunWindowMs: this.config.runStaleSec * 1000 }); }
147
196
  workflowJournal() { return new TiDBWorkflowJournalStore(this.pool); }
148
197
  outcomeSink() { return new TiDBOutcomeLedger(this.pool); }
149
198
  workflowRun(onWarn) { return new TiDBWorkflowRunStore(this.pool, onWarn); }
@@ -160,12 +209,12 @@ class TiDBBackend {
160
209
  imageBake() { return new TiDBImageBake(this.pool); }
161
210
  leaderRun() { return new TiDBLeaderRunStore(this.pool); }
162
211
  device() { return new TiDBDeviceStore(this.pool); }
163
- retention(opts) { return new TiDBRetentionStore(this.pool, opts); }
212
+ retention(opts) { return createSqlRetentionExecutor(mysqlDriver(this.pool), opts); }
164
213
  retentionLane() { return new TiDBRetentionLaneStore(this.pool); }
165
214
  breaker(onWriteFail) { return new TiDBBreakerState(this.pool, onWriteFail); }
166
215
  costQuota(limitMicroUsd, windowMs, onDegraded) { return new TiDBCostQuota(this.pool, limitMicroUsd, windowMs, undefined, onDegraded, this.config.dbQueryTimeoutMs); }
167
216
  rateLimiter(limit, onDegraded) { return new TiDBRateLimiter(this.pool, limit, undefined, undefined, onDegraded, this.config.dbQueryTimeoutMs); }
168
- session() { return new TiDBSessionStore(this.pool, { retention: sqlStoreRetention(this.config.retentionSweep) }); }
217
+ session() { return new SqlSessionStore(mysqlDriver(this.pool), (hooks) => new TiDBSessionStore(this.pool, { retention: sqlStoreRetention(this.config.retentionSweep), hooks })); }
169
218
  adoptionLog() { return new TiDBAdoptionLogStore(this.pool); }
170
219
  mysqlPool() { return this.pool; }
171
220
  pgPool() { return undefined; }
@@ -192,12 +241,12 @@ class PgBackend {
192
241
  sendFileLedger() { return new PgSendFileLedger(this.pool); }
193
242
  userInputLedger() { return new PgUserInputLedgerStore(this.pool); }
194
243
  sessionPolicy(logger) { return new PgSessionPolicyStore(this.pool, logger); }
195
- fileHistory() { return new PgFileHistoryStore(this.pool, historyBlobBackend(this.config, "pg", this.pool), this.config.fileHistory); }
244
+ fileHistory() { return new PgFileHistoryStore(this.pool, fileHistoryOptions(this.config)); }
196
245
  memoryOptOutGrant() { return new PgMemoryOptOutGrantStore(this.pool); }
197
246
  sessionCaptureRecords() { return () => (this.captureRecordsInst ??= new PgSessionCaptureRecordStore(this.pool)); }
198
247
  captureRecordsInst;
199
248
  legacySnapshotBlobSweep() { return legacySweepImpl(this.config, "pg", this.pool); }
200
- runOneTimeMigrations() { return runSqlOneTimeMigrations("pg", this.pool, { lanes: deployedExecutionLanes(this.config) }); }
249
+ runOneTimeMigrations() { return runSqlOneTimeMigrations("pg", this.pool, { lanes: deployedExecutionLanes(this.config), liveRunWindowMs: this.config.runStaleSec * 1000 }); }
201
250
  workflowJournal() { return new PgWorkflowJournalStore(this.pool); }
202
251
  outcomeSink() { return new PgOutcomeLedger(this.pool); }
203
252
  workflowRun(onWarn) { return new PgWorkflowRunStore(this.pool, onWarn); }
@@ -214,12 +263,12 @@ class PgBackend {
214
263
  imageBake() { return new PgImageBake(this.pool); }
215
264
  leaderRun() { return new PgLeaderRunStore(this.pool); }
216
265
  device() { return new PgDeviceStore(this.pool); }
217
- retention(opts) { return new PgRetentionStore(this.pool, opts); }
266
+ retention(opts) { return createSqlRetentionExecutor(pgDriver(this.pool), opts); }
218
267
  retentionLane() { return new PgRetentionLaneStore(this.pool); }
219
268
  breaker(onWriteFail) { return new PgBreakerState(this.pool, onWriteFail); }
220
269
  costQuota(limitMicroUsd, windowMs, onDegraded) { return new PgCostQuota(this.pool, limitMicroUsd, windowMs, undefined, onDegraded, this.config.dbQueryTimeoutMs); }
221
270
  rateLimiter(limit, onDegraded) { return new PgRateLimiter(this.pool, limit, undefined, undefined, onDegraded, this.config.dbQueryTimeoutMs); }
222
- session() { return new PgSessionStore(this.pool, { retention: sqlStoreRetention(this.config.retentionSweep) }); }
271
+ session() { return new SqlSessionStore(pgDriver(this.pool), (hooks) => new PgSessionStore(this.pool, { retention: sqlStoreRetention(this.config.retentionSweep), hooks })); }
223
272
  adoptionLog() { return new PgAdoptionLogStore(this.pool); }
224
273
  mysqlPool() { return undefined; }
225
274
  pgPool() { return this.pool; }
@@ -247,26 +296,16 @@ class LocalBackend {
247
296
  discloseWarn;
248
297
  parkDecisionLedgerRoot;
249
298
  executionLanes;
250
- constructor(root, config, onWarn, onError) {
299
+ dataDirLayout;
300
+ constructor(fileBackend, config, discloseWarn, onWarn, onError) {
251
301
  this.executionLanes = deployedExecutionLanes(config);
252
302
  this.onWarn = onWarn;
253
- this.discloseWarn = onWarn ?? ((msg, meta) => console.warn(msg, meta));
303
+ this.discloseWarn = discloseWarn;
254
304
  this.onError = onError;
255
- try {
256
- this.fileBackend = acquireLocalBackendWithWait(() => new FileStorageBackend({
257
- root,
258
- ...(config.fileHistory !== undefined ? { fileHistory: config.fileHistory } : {}),
259
- onCorruptRead: createDurableAbsenceSeat((msg, fields) => this.discloseWarn(msg, fields), root, "file-history = a rewind boundary or scope read as missing"),
260
- }), config.storeLockWaitMs, (fields) => this.onWarn?.("store_dir_lock_wait", { ...fields }));
261
- }
262
- catch (e) {
263
- if (e instanceof AdoptionError)
264
- throw e;
265
- const tail = buildStoreOpenRefusalTail(e, "http");
266
- throw new Error(`DB_BACKEND=local cannot open data dir ${root}: ${e instanceof Error ? e.message : String(e)}` +
267
- (tail === undefined ? "" : ` ${tail}`));
268
- }
305
+ this.fileBackend = fileBackend;
306
+ const root = localBackendRootOf(config);
269
307
  const corruptReadWarn = (msg, fields) => this.discloseWarn(msg, fields);
308
+ this.dataDirLayout = buildDataDirLayout({ configuredRoot: root, physicalRoot: this.fileBackend.root, memoryEngineRoot: memoryEngineRootFor(config, root) });
270
309
  this.runStore = new FileRunStore(this.fileBackend.root, {
271
310
  error: (msg, fields) => void (this.onError ?? this.onWarn)?.(msg, fields),
272
311
  strictHydrate: config.runStoreStrictHydrate,
@@ -294,24 +333,32 @@ class LocalBackend {
294
333
  : (plane) => fileSessionCaptureRecordStore(plane?.controlDir ?? ownControlDir);
295
334
  }
296
335
  async ensureSchema() {
336
+ this.executionLaneWordsRenamed += await this.sessionStore.renameRetiredExecutionLaneWordM40();
297
337
  await this.sessionStore.assertStrictSidecarsReadable();
298
338
  await this.sessionStore.settleArchiveSnapshots();
299
339
  }
340
+ executionLaneWordsRenamed = 0;
300
341
  async runOneTimeMigrations() {
301
- const holderDeathCodeRowsBackfilled = this.runStore.migrateLegacyHolderDeathCodes();
342
+ tightenLocalDataDirModes(this.dataDirLayout, {
343
+ tightened: (msg, meta) => this.onWarn?.(msg, meta),
344
+ refused: (msg, meta) => this.discloseWarn(msg, meta),
345
+ });
302
346
  const archives = await this.sessionStore.migrateLocalArchives();
303
347
  const placements = await backfillLocalExecutionPlacements(this.runStore.sessionIdsWithRuns(), this.sessionStore.executionPlacementBackfill, { lanes: this.executionLanes });
304
- const importedLayerRoot = { importedLayerRootAllowsRetired: [], importedLayerRootBucketsSkipped: [] };
348
+ const importedLayerRoot = { importedLayerRootAllowsRetired: [], importedLayerRootBucketsSkipped: [], importedLayerRootBucketsUnnamed: 0 };
305
349
  if (existsSync(join(this.fileBackend.root, FILE_PERMISSION_RULE_DIR))) {
306
350
  const rules = this.permissionRule();
307
- await retireImportedLayerRootAllows({ candidateOwners: () => rules.approvals.importRecordOwners(), durable: rules.durable, isWholeBucketRefusal: () => false, isVanishedBucket: () => false }, importedLayerRoot);
351
+ await retireImportedLayerRootAllows({ candidateOwners: () => fileRuleBucketOwners(rules), durable: rules.durable, isWholeBucketRefusal: isFileBucketDamaged, isVanishedBucket: () => false }, importedLayerRoot);
308
352
  }
353
+ const executionLaneWordsRenamed = this.executionLaneWordsRenamed + this.approvalAskStore.renameRetiredExecutionLaneWordM40();
354
+ this.executionLaneWordsRenamed = 0;
355
+ const askExecutionLanesBackfilled = backfillLocalAskExecutionLanes(this.approvalAskStore, { lanes: this.executionLanes });
309
356
  return {
310
357
  ...NO_SQL_MIGRATIONS,
311
- holderDeathCodeRowsBackfilled,
312
358
  executionPlacementsBackfilled: placements.backfilled,
313
359
  executionPlacementSessionsUnreadable: placements.unreadable,
314
- askExecutionLanesBackfilled: backfillLocalAskExecutionLanes(this.approvalAskStore, { lanes: this.executionLanes }),
360
+ askExecutionLanesBackfilled,
361
+ executionLaneWordsRenamed,
315
362
  askJournalRecordsUpgraded: this.approvalAskStore.upgradeJournalEnvelope(),
316
363
  localArchiveRowFactsBackfilled: archives.rowFactsBackfilled,
317
364
  localArchivesAnonymized: archives.anonymized,
@@ -395,9 +442,75 @@ class LocalBackend {
395
442
  export function counterStoreLabel(store, kind) {
396
443
  return store ? `shared(${kind ?? "unknown"})` : "in-process";
397
444
  }
445
+ function openLocalBackend(config, onWarn, onError) {
446
+ const root = localBackendRootOf(config);
447
+ const discloseWarn = onWarn ?? ((msg, meta) => console.warn(msg, meta));
448
+ let fileBackend;
449
+ try {
450
+ fileBackend = acquireLocalBackendWithWait(() => new FileStorageBackend({
451
+ root,
452
+ ...(config.fileHistory !== undefined ? { fileHistory: config.fileHistory } : {}),
453
+ onCorruptRead: createDurableAbsenceSeat(discloseWarn, root, "file-history = a rewind boundary or scope read as missing"),
454
+ }), config.storeLockWaitMs, (fields) => onWarn?.("store_dir_lock_wait", { ...fields }));
455
+ }
456
+ catch (e) {
457
+ if (e instanceof AdoptionError)
458
+ throw e;
459
+ const tail = buildStoreOpenRefusalTail(e, "http");
460
+ throw new Error(`DB_BACKEND=local cannot open data dir ${root}: ${e instanceof Error ? e.message : String(e)}` +
461
+ (tail === undefined ? "" : ` ${tail}`));
462
+ }
463
+ try {
464
+ holdEngineHighWater(fileBackend.root, serviceVersion());
465
+ }
466
+ catch (refusal) {
467
+ return new RefusedLocalBackend(fileBackend, refusal instanceof Error ? refusal : new Error(String(refusal)));
468
+ }
469
+ return new LocalBackend(fileBackend, config, discloseWarn, onWarn, onError);
470
+ }
471
+ class RefusedLocalBackend {
472
+ fileBackend;
473
+ refusal;
474
+ kind = "local";
475
+ constructor(fileBackend, refusal) {
476
+ this.fileBackend = fileBackend;
477
+ this.refusal = refusal;
478
+ }
479
+ refused() {
480
+ throw this.refusal;
481
+ }
482
+ async ensureSchema() {
483
+ return this.refused();
484
+ }
485
+ async runOneTimeMigrations() {
486
+ return this.refused();
487
+ }
488
+ async close() {
489
+ await this.fileBackend.dispose();
490
+ }
491
+ run() { return this.refused(); }
492
+ resumeAnchor() { return this.refused(); }
493
+ approvalExemption() { return this.refused(); }
494
+ approvalNonce() { return this.refused(); }
495
+ orgDeliveryQuota() { return this.refused(); }
496
+ approvalAsk() { return this.refused(); }
497
+ permissionRule() { return this.refused(); }
498
+ sendFileLedger() { return this.refused(); }
499
+ userInputLedger() { return this.refused(); }
500
+ sessionPolicy() { return this.refused(); }
501
+ fileHistory() { return this.refused(); }
502
+ memoryOptOutGrant() { return this.refused(); }
503
+ sessionCaptureRecords() { return this.refused(); }
504
+ workflowJournal() { return this.refused(); }
505
+ outcomeSink() { return this.refused(); }
506
+ checkpointReadView() { return this.refused(); }
507
+ session() { return this.refused(); }
508
+ mysqlPool() { return undefined; }
509
+ pgPool() { return undefined; }
510
+ }
398
511
  export function createStoreBackend(config, onWarn, onError) {
399
512
  if (config.dbBackend === "local")
400
- return new LocalBackend(config.localDataRoot ?? join(homedir(), ".ai-agent"), config, onWarn, onError);
513
+ return openLocalBackend(config, onWarn, onError);
401
514
  if (config.dbBackend === "pg") {
402
515
  if (!config.pg)
403
516
  return undefined;
@@ -418,9 +531,21 @@ function withRetiredSchemaProbe(inner, target, executionPlacementSwitch) {
418
531
  };
419
532
  return guarded;
420
533
  }
534
+ function localBackendRootOf(config) {
535
+ return config.localDataRoot ?? join(homedir(), ".ai-agent");
536
+ }
537
+ function localDataRootHoldsData(root) {
538
+ try {
539
+ return readdirSync(root).length > 0;
540
+ }
541
+ catch (e) {
542
+ const code = e.code;
543
+ return code !== "ENOENT" && code !== "ENOTDIR";
544
+ }
545
+ }
421
546
  export async function openStoreBackendWithFallback(config, logger) {
422
547
  const sqlEngine = config.dbBackend === "mysql" || config.dbBackend === "pg" ? config.dbBackend : undefined;
423
- const mayFallback = config.dbBackend === "local" && !config.dbBackendExplicit;
548
+ const mayFallback = config.dbBackend === "local" && !config.dbBackendExplicit && !localDataRootHoldsData(localBackendRootOf(config));
424
549
  let backend;
425
550
  let inFlight;
426
551
  try {
@@ -447,8 +572,6 @@ export async function openStoreBackendWithFallback(config, logger) {
447
572
  }
448
573
  catch (err) {
449
574
  void inFlight?.close().catch(() => undefined);
450
- if (err instanceof AdoptionError)
451
- throw err;
452
575
  if (err instanceof StoreBootRefusalError)
453
576
  throw err;
454
577
  if (!mayFallback) {
@@ -37,13 +37,19 @@ import type { SessionUnreadable } from "../session-error-wire.js";
37
37
  * F1 [high] 实测:`DB_BACKEND` 未设时坏账本 ⇒ `{backend: undefined, degraded: true}`,不是拒启)。
38
38
  * 收法:**一个基类,一条重抛**。新 File 店的拒启只要 `extends StoreBootRefusalError` 就自动落在正确的
39
39
  * 一侧;忘了继承是**可见**的(它是一个必须显式选择的父类),而忘了往 if 链里加一行是不可见的。
40
- * (core 的 `AdoptionError` 不在本仓,改不了它的继承链 ⇒ 降级臂保留它那一条 `instanceof`,共两条。)
40
+ * (core 的 `AdoptionError` 不在本族:它的标记住在数据根里,而降级臂只对**空 / 不存在**的数据根开(`openStoreBackendWithFallback` 的数据根判据),
41
+ * 它到不了降级那一步 ⇒ 降级臂不为它单开一条。local 形上本族同样先被那条判据兜住;族规仍在,管的是拒句的属主与 SQL 族。)
41
42
  *
42
43
  * 族的含义是「**确定的拒启表态**」,不限 File 店:SQL `ensureSchema()` 里库带着已退役 schema 的拒启(`RetiredSchemaPresentError`)也属此族。三处读它,读法一致 ——
43
44
  * 降级臂不吞(穿过 `mayFallback`)、SQL 开库的等待窗不重试它(`store-open-wait.ts`:再等也等不来另一个答案)、「库打不开」的拒句不改写它(它自己的拒句才是真话)。
44
45
  */
45
46
  export declare class StoreBootRefusalError extends Error {
46
47
  }
48
+ /**
49
+ * 起服对账一族的拒启码(机读;附录 A / 拒启码表的登记名)。含义 = 「本构建读不出 / 建不出的持久形,开始服务之前判」:SQL 列册对账与退役 schema 两道(`schema-consistency.ts`)、
50
+ * 会话部署格旁表建不出(`session-ext-table.ts`)、local 数据根的严格边档对账(`local-session-store.ts`)。码住在族基类旁边:读它的几只模块彼此不必互相 import。
51
+ */
52
+ export declare const SCHEMA_MISMATCH_ERROR_CODE = "config.schema_mismatch";
47
53
  /**
48
54
  * 取消便签里的**大脑相位**快照 —— core `BrainStatus` 帧经 `brainStatusEventData` 投影后的五键子集。
49
55
  *
@@ -168,20 +174,10 @@ export declare const RUN_HOLDER_DEATH_CODES: {
168
174
  readonly orphaned: "run.orphaned";
169
175
  };
170
176
  export type RunHolderDeathCode = (typeof RUN_HOLDER_DEATH_CODES)[keyof typeof RUN_HOLDER_DEATH_CODES];
171
- /**
172
- * 一次性迁移 **M6** 的判据(窗、删法与删后谁接住:窗口见 `plugins/one-time-migrations.ts` 登记表):7.116.0 之前写下的死亡判决行只有句子、码列为空 ——
173
- * 该行应有的码。两处用:local 腿的起服写回(`FileRunStore.migrateLegacyHolderDeathCodes`)与 SQL 两孪生行映射里的**读侧半场**(滚动升级窗里旧副本
174
- * 还会写这种行,起服写回覆盖不到;本函数随 M6 一起删)。只认两句落款的原字节(接管臂括注形按前缀认);码列已有值 / 非 `failed` / 别的句子 ⇒ 原样。
175
- */
176
- export declare function readLegacyHolderDeathCode(row: {
177
- readonly status: string;
178
- readonly error: string | null;
179
- readonly errorCode: string | null;
180
- }): string | null;
181
177
  /**
182
178
  * run 行上是不是一份**持有者死亡判决**:`failed`,且行上的码是 {@link RUN_HOLDER_DEATH_CODES} 之一。判决只说「持有它的那个进程死在这条腿收场之前」,
183
179
  * 不说是谁 —— 持有者是谁读行上的 `instanceId`(判决不改它)。读者 = 用户输入受理账本的收敛判词(`src/user-input-ledger.ts` `judgeOpen`)。
184
- * 旧行(只有句子)由一次性迁移 M6 补上码(起服写回 + SQL 滚动窗的读侧半场,{@link readLegacyHolderDeathCode}),所以这里不再按句子判。
180
+ * 只认码、不按句子判:7.116.0 起两只死亡判决的写者恒同写码;只有句子、码列为空的行(更早的写者铸的)不是死亡判决(随包 MIGRATION 写了)。
185
181
  * 正常失败(别的码 / 无码)/ park 过期收割(`approval.expired`:腿 park 过)都**不是**死亡判决。
186
182
  */
187
183
  export declare function isHolderDeathVerdict(run: Pick<RunRecord, "status" | "errorCode">): boolean;
@@ -555,7 +551,8 @@ export interface SessionRunRollupSource {
555
551
  }
556
552
  /**
557
553
  * 会话**此刻的 run 认领**(单活槽)的窄读面 —— run 店的 `getActiveTaskId`,同一个问题在 SQL 孪生里是写事务内对 `task_active` 的锁定读。
558
- * local 会话店的执行席在 `markMirror` 的写锁内读它,判序与 SQL 孪生同(行不在 / 住客不同 / writer / mirror 先判,认领只拦「absent → mirror」这一笔写)。
554
+ * local 会话店在写锁内读它:执行席的 `markMirror`(判序与 SQL 孪生同:行不在 / 住客不同 / writer / mirror 先判,认领只拦「absent → mirror」这一笔写),
555
+ * 与导入三写口(整段 `importEntries` / `replaceEntries` / 暂存提交;判官 `judgeImportWrite` 与 SQL 事务内钩的 `import` 臂同一只:先认领后本处写者)。
559
556
  */
560
557
  export interface SessionRunClaimSource {
561
558
  getActiveTaskId(sessionId: string): Promise<string | undefined>;
@@ -1,5 +1,6 @@
1
1
  export class StoreBootRefusalError extends Error {
2
2
  }
3
+ export const SCHEMA_MISMATCH_ERROR_CODE = "config.schema_mismatch";
3
4
  export const ABORT_CAUSES = ["client_disconnected", "ask_park_grace_exhausted", "cancel_verb"];
4
5
  export const RUN_STALLED_ERROR = "run stalled (instance lost?)";
5
6
  export const RUN_ORPHANED_ERROR = "run orphaned by engine restart";
@@ -8,15 +9,6 @@ export function buildRunOrphanedError(heldBy) {
8
9
  }
9
10
  export const RUN_HOLDER_DEATH_CODES = { stalled: "run.stalled", orphaned: "run.orphaned" };
10
11
  const RUN_HOLDER_DEATH_CODE_WORDS = new Set(Object.values(RUN_HOLDER_DEATH_CODES));
11
- export function readLegacyHolderDeathCode(row) {
12
- if (row.errorCode !== null || row.status !== "failed" || row.error === null)
13
- return row.errorCode;
14
- if (row.error === RUN_STALLED_ERROR)
15
- return RUN_HOLDER_DEATH_CODES.stalled;
16
- if (row.error === RUN_ORPHANED_ERROR || row.error.startsWith(`${RUN_ORPHANED_ERROR} (`))
17
- return RUN_HOLDER_DEATH_CODES.orphaned;
18
- return null;
19
- }
20
12
  export function isHolderDeathVerdict(run) {
21
13
  return run.status === "failed" && run.errorCode !== null && RUN_HOLDER_DEATH_CODE_WORDS.has(run.errorCode);
22
14
  }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * 后端级按龄清扫动词 —— 一个后端的按龄清扫只有一只动词 `sweep({ nowMs })`,答每条腿删了几行。
3
+ *
4
+ * ## 律(一条)
5
+ * 维护 tick 只调这一只动词,不逐店探「有没有某个按龄删的方法」;每条腿的界只有一种读法({@link buildStoreSweepBounds}:部署旋钮 → 引擎的词 `maxAgeMs`,
6
+ * 即工具结果店 `ToolResultStore.reap(now, { maxAgeMs })`、名册 `RosterGcOptions.maxAgeMs` 的那个词;journal 店的按龄删同收 `maxAgeMs`),**每次清扫现读** —— `TOOL_RESULT_TTL_SEC` 是热键,
7
+ * 改了下一拍就按新值删;没给界的腿,或本后端那只座没有按龄删的面,一行不删、答 0。
8
+ * 形照引擎 SQL 后端包的同名动词(`SqlStorageBackend.sweep` / `SqlSweepLeg` / `SqlSweepReceipt`):腿名逐字用它的词。
9
+ *
10
+ * ## 射程(如实)
11
+ * 今天的三条腿:`tool-results-aged`(工具结果店的契约成员 `reap`)、`roster-aged`(名册 SQL 孪生的按龄删;File / 内存名册没有这一面 ⇒ 0)与
12
+ * `workflow-journal-expired`(journal SQL 孪生的按龄删 `reapExpired`,见 {@link createJournalSweepLeg};只在开了 self-orchestration 且有后端时有这只店,
13
+ * core 的 File journal 店没有这一面 ⇒ 0)。引擎包的腿闭集另有 `file-history-orphan-blobs`,随它的座搬进 `src/stores-sql/` 时并进来;信箱的 `reap` 是按收件箱
14
+ * 作用域的契约成员,引擎包的清扫腿里没有它,本动词也不收。实现仍是各座自己的方法;目录搬进引擎包之后,SQL 后端的这只动词就是包的 `sweep`。
15
+ *
16
+ * ## 失败
17
+ * 腿互不牵连:一条腿抛(同步抛或拒)不拦别的腿。全腿成功 ⇒ 答回执;有腿失败 ⇒ 以 {@link StoreSweepError} 拒,带上成功腿的计数与失败腿的原因,
18
+ * 调用方按腿各自上报。
19
+ */
20
+ import type { ServiceConfig } from "../config.js";
21
+ /** 本后端跑的清扫腿(闭集;词与引擎 SQL 后端包的 `SqlSweepLeg` 同字)。 */
22
+ export declare const STORE_SWEEP_LEGS: readonly ["roster-aged", "tool-results-aged", "workflow-journal-expired"];
23
+ export type StoreSweepLeg = (typeof STORE_SWEEP_LEGS)[number];
24
+ /** 一次清扫每条腿删了几行。 */
25
+ export type StoreSweepReceipt = Readonly<Record<StoreSweepLeg, number>>;
26
+ /** 一条腿的界(部署陈述;词 = 引擎的 `maxAgeMs`)。 */
27
+ export interface StoreSweepBound {
28
+ readonly maxAgeMs: number;
29
+ }
30
+ /** 各腿的界(缺一条 = 那条腿不删)。 */
31
+ export type StoreSweepBounds = Readonly<Partial<Record<StoreSweepLeg, StoreSweepBound>>>;
32
+ /**
33
+ * 部署旋钮 → 各腿的界:本仓唯一的读法。`TOOL_RESULT_TTL_SEC`(秒,> 0,热键)→ `tool-results-aged`;`ROSTER_RETENTION_MS`(毫秒,下限 1 分钟)→ `roster-aged`;
34
+ * `WORKFLOW_JOURNAL_RETENTION_MS`(毫秒,下限 1 分钟)→ `workflow-journal-expired`。
35
+ * 组合点把它包成读法函数交给 {@link createStoreSweep},每次清扫现读一次 —— 交起服那一刻的值会让热发布的新界不生效。
36
+ */
37
+ export declare function buildStoreSweepBounds(config: Pick<ServiceConfig, "toolResultTtlSec" | "rosterRetentionMs" | "workflowJournalRetentionMs">): StoreSweepBounds;
38
+ /** 一条腿的实现:删掉存了超过 `bound.maxAgeMs` 的行,答删了几行。 */
39
+ export type StoreSweepLegRun = (nowMs: number, bound: StoreSweepBound) => Promise<number> | number;
40
+ /**
41
+ * journal 店的按龄删 → `workflow-journal-expired` 腿:截止线 = 动词交来的 `nowMs` − 动词交来的 `maxAgeMs`(界每次清扫现读,腿不自存)。
42
+ * 店没有这一面(core 的 File / 内存 journal 店)或没有店(self-orchestration 关 / 无后端)⇒ 无腿,动词答 0。
43
+ */
44
+ export declare function createJournalSweepLeg(store: {
45
+ reapExpired?(now: number, maxAgeMs: number): Promise<number>;
46
+ } | undefined): StoreSweepLegRun | undefined;
47
+ export interface StoreSweep {
48
+ sweep(input: {
49
+ readonly nowMs: number;
50
+ }): Promise<StoreSweepReceipt>;
51
+ }
52
+ /** 有腿失败的那次清扫:`receipt` 里失败腿记 0,`failed` 按腿带原因。 */
53
+ export declare class StoreSweepError extends Error {
54
+ readonly receipt: StoreSweepReceipt;
55
+ readonly failed: ReadonlyMap<StoreSweepLeg, unknown>;
56
+ constructor(receipt: StoreSweepReceipt, failed: ReadonlyMap<StoreSweepLeg, unknown>);
57
+ }
58
+ export declare function createStoreSweep(spec: {
59
+ readonly legs: Readonly<Partial<Record<StoreSweepLeg, StoreSweepLegRun>>>;
60
+ /** 界的读法:每次清扫调一次(只收函数 —— 起服那一刻的界对象交不进来)。 */
61
+ readonly bounds: () => StoreSweepBounds;
62
+ }): StoreSweep;
63
+ //# sourceMappingURL=store-sweep.d.ts.map
@@ -0,0 +1,48 @@
1
+ export const STORE_SWEEP_LEGS = ["roster-aged", "tool-results-aged", "workflow-journal-expired"];
2
+ export function buildStoreSweepBounds(config) {
3
+ return {
4
+ "roster-aged": { maxAgeMs: config.rosterRetentionMs },
5
+ "tool-results-aged": { maxAgeMs: config.toolResultTtlSec * 1000 },
6
+ "workflow-journal-expired": { maxAgeMs: config.workflowJournalRetentionMs },
7
+ };
8
+ }
9
+ export function createJournalSweepLeg(store) {
10
+ const reap = store?.reapExpired?.bind(store);
11
+ return reap === undefined ? undefined : (nowMs, { maxAgeMs }) => reap(nowMs, maxAgeMs);
12
+ }
13
+ export class StoreSweepError extends Error {
14
+ receipt;
15
+ failed;
16
+ constructor(receipt, failed) {
17
+ super(`store sweep: leg(s) ${[...failed.keys()].join(", ")} failed`);
18
+ this.receipt = receipt;
19
+ this.failed = failed;
20
+ this.name = "StoreSweepError";
21
+ }
22
+ }
23
+ export function createStoreSweep(spec) {
24
+ const runLeg = async (leg, nowMs, bounds) => {
25
+ const run = spec.legs[leg];
26
+ const bound = bounds[leg];
27
+ if (run === undefined || bound === undefined)
28
+ return { leg, removed: 0 };
29
+ try {
30
+ return { leg, removed: await run(nowMs, bound) };
31
+ }
32
+ catch (error) {
33
+ return { leg, error };
34
+ }
35
+ };
36
+ return {
37
+ async sweep({ nowMs }) {
38
+ const bounds = spec.bounds();
39
+ const settled = await Promise.all(STORE_SWEEP_LEGS.map((leg) => runLeg(leg, nowMs, bounds)));
40
+ const receipt = Object.fromEntries(settled.map((s) => [s.leg, "removed" in s ? s.removed : 0]));
41
+ const failed = new Map(settled.flatMap((s) => ("error" in s ? [[s.leg, s.error]] : [])));
42
+ if (failed.size > 0)
43
+ throw new StoreSweepError(receipt, failed);
44
+ return receipt;
45
+ },
46
+ };
47
+ }
48
+ //# sourceMappingURL=store-sweep.js.map
@@ -2,7 +2,7 @@
2
2
  * TaskAttachmentStore —— D-1 通用文件上传的**独立附件 store**(clay 拍 2026-07-27:不复用 fileSnapshot
3
3
  * 的 content-addressed blob 面,新建)。TiDB/PG 双方言 + local 文件店(local-task-attachment-store.ts)。
4
4
  *
5
- * 为什么独立而不是骑 SqlBlobBackend/snapshot_blob:那套的引用追踪=「本域 manifest 里没有的即 orphan」,
5
+ * 为什么独立而不是骑快照 blob 的索引(snapshot_blob):那套的引用追踪=「本域 manifest 里没有的即 orphan」,
6
6
  * 附件不在任何一域的 manifest 里 ⇒ 会被孤儿扫在 1h grace 后误收。生命周期也不同:
7
7
  * snapshot blob 跟 session 的工作树;**附件跟 task/session 的绑定**(上传先行、提交时绑定、E21 随会话
8
8
  * 级联删、未绑定的按 TTL 收割)。
@@ -11,8 +11,8 @@
11
11
  * - `owner` = auth principal ?? "default"(单库 tenant 轴;无 principal 部署全 default = 单用户语义)。
12
12
  * 读/删门在 SQL WHERE 完成(filter-before-reduce,roster 语义条 1 同姿)——他人行连结果集都不进。
13
13
  * - **字节本体在对象存储(clay 裁 2026-07-27:云形态对象存储必配,「现在就接」)**:SQL 只存 meta
14
- * (索引/owner 门/生命周期),bytes 走 {@link AttachmentBytesStore}(生产=既有 MinioBlobBackend,
15
- * 读侧内建 sha 校验)。对象键=**sha256**(同内容天然去重;跨 owner 共享对象 ⇒ 对象删除必须过
14
+ * (索引/owner 门/生命周期),bytes 走 {@link AttachmentBytesStore}(字节口 {@link BlobBackend} —— 生产 = 对象存储
15
+ * MinioBlobBackend;读侧的 sha 校验是本店作为索引属主的事:{@link readAtAddress})。对象键=**sha256**(同内容天然去重;跨 owner 共享对象 ⇒ 对象删除必须过
16
16
  * 零引用检查)+ **附件专属 keyPrefix**(与快照 blob 命名空间隔离——同 sha 不同生命周期,混用会互删)。
17
17
  * 删除次序:meta 先(E21 purge 永不被 MinIO 网络抖动卡死,blob-backend 异步删裁定同旨),对象删
18
18
  * =零引用检查后 best-effort(失败只 log:无 meta 的对象经 API 不可达;彻底清收敛作 follow-up 记账)。
@@ -32,6 +32,7 @@ import type { Pool } from "mysql2/promise";
32
32
  import type { PgQueryFn } from "./pg-query.js";
33
33
  import type { Pool as PgPool } from "pg";
34
34
  import { type IndexSpec } from "./ensure-index.js";
35
+ import { type BlobBackend } from "./blob-backend.js";
35
36
  /**
36
37
  * 一条附件 meta 的**形属主**(整仓唯一那份键集)。
37
38
  *
@@ -79,12 +80,9 @@ export interface TaskAttachmentStore {
79
80
  sweepOrphanObjects?(graceMs: number, nowMs?: number): Promise<number>;
80
81
  }
81
82
  export declare const TASK_ATTACHMENT_TABLE = "task_attachment";
82
- /** 字节面 seam —— MinioBlobBackend 的结构子集(hash 键控;读侧 sha 校验在实现内)。`listObjects` 可选
83
+ /** 字节面 = 字节口 {@link BlobBackend}(sha256 键控;读侧 sha 校验在本店,{@link readAtAddress})+ 对象存储的两只可选读面。`listObjects` 可选
83
84
  * (D-1 孤儿对象 GC 的列举面;测试桩/无列举后端缺席=sweep 诚实 0,不装作扫过)。 */
84
- export interface AttachmentBytesStore {
85
- putBlob(hash: string, bytes: Uint8Array): Promise<void>;
86
- getBlob(hash: string): Promise<Uint8Array | undefined>;
87
- deleteBlobs(hashes: string[]): Promise<number>;
85
+ export interface AttachmentBytesStore extends BlobBackend {
88
86
  listObjects?(): AsyncGenerator<{
89
87
  hash: string;
90
88
  lastModifiedMs: number;