@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
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * SIGHUP(壳窗口关闭打到整个进程组)≠「没人在用这只引擎」:共享引擎形态(同 config 多壳会话,引擎按
5
5
  * T11 防孤儿拍骑在首壳进程组里)下 peer 会话还活着——无条件 drain 会把 peer mid-turn 斩掉(499)且窗内
6
- * 新提交 503。这里改为:SIGHUP 不翻 draining(peer 零感知),armed 一只空闲窗——`inflight()`(bg/resume
7
- * legs + live streams)连续 idleGraceMs 为 0 才 shutdown,任何在飞 leg 重置窗口。真孤儿(最后一窗关掉)
6
+ * 新提交 503。这里改为:SIGHUP 不翻 draining(peer 零感知),armed 一只空闲窗——工作谓词连续 idleGraceMs
7
+ * 为假才 shutdown,任何工作重置窗口(谓词的在飞格读阻断集 `drainState.blockingInflight` = `http + leader + backgroundAgents`;会话驻留的后台 shell / monitor
8
+ * 在 `/health.inflight` 总数里、不阻断)。真孤儿(最后一窗关掉)
8
9
  * 有界自灭=T11 保留;第二个 SIGHUP 升级 escalate(既有 drain 路径,操作员硬梯子)。
9
10
  *
10
11
  * 诚实边界:idle-but-live 的 peer(两 turn 之间静默超过窗口)会碰到引擎已退→壳 dead-respawn 1-2s 自愈
@@ -12,13 +13,14 @@
12
13
  * [ref]:附着(打开着的 SSE 流)是判据的第二格 `attached` —— 只读订阅自此不进 inflight(排空不该等一个看着的壳),而一个只挂着订阅流的
13
14
  * peer 壳(cli 附着形:`GET /v1/approvals/stream` 常开)仍然是「有人在用」,靠这一格不被当成孤儿。修前这一形是订阅流被算进 inflight
14
15
  * 时顺带挡住的;拆开之后两件事各有一格,规则不变:inflight = 0 ∧ attached = 0 ∧ 活性静默满窗才关。
16
+ * [ref]([ref] v3 §9.4):「有没有工作」不再由本文件自己拼 —— 它读附着租约的**同一只**工作谓词(`boot/engine-lease.ts` 的 `laneWork`,
17
+ * 读者词 `"sighup"`),装配层经 {@link SighupIdleDeps.work} 递进来。于是附着租约的车道表在这里同样成立:交接车道(壳已把引擎交给后台)那一格
18
+ * 对 SIGHUP 读作「有工作」—— 终端关闭不会按另一套谓词把只剩后台 shell 在跑的引擎拆掉,寿命只归租约腿;别的车道读到的仍是附着 ∨ 在飞。
15
19
  */
16
20
  export interface SighupIdleDeps {
17
- /** This replica's in-flight legs (drainState.inflight). */
18
- inflight: () => number;
19
- /** [ref]:打开着的 SSE 流条数(drainState.attachedStreams,附着租约同一只 getter)。> 0 ⇒ 有壳挂着,同 inflight 一样重置窗口。
20
- * 缺席 ⇒ 视为 0(单测 / 嵌入形)。 */
21
- attached?: () => number;
21
+ /** 此刻有没有工作 —— 附着租约的工作谓词(`laneWork(车道, 采样, "sighup")`:附着 > 0 ∨ 阻断集在飞 > 0,交接车道恒真)。真 ⇒ 重置窗口。
22
+ * 本文件不自拼判据([ref] 的附着格与在飞格都在那只谓词里)。 */
23
+ work: () => boolean;
22
24
  /** MONOTONIC-clock ms of the last non-probe HTTP request (drainState.lastActivityAt). Covers what inflight
23
25
  * can't: admitted-but-not-yet-registered requests (auth/prepare/claim phases) and sub-tick short requests —
24
26
  * and keeps an idle-but-live peer (still listing/browsing) alive. Absent ⇒ inflight-only semantics.
@@ -21,17 +21,16 @@ export function createSighupIdleHandler(deps) {
21
21
  return;
22
22
  }
23
23
  armedAt = now();
24
- const inflight = deps.inflight();
25
- const attached = deps.attached?.() ?? 0;
26
- idleSince = inflight === 0 && attached === 0 ? now() : null;
27
- deps.log("sighup_idle_watch_armed", { inflight, attached, idleGraceMs: deps.idleGraceMs });
24
+ const work = deps.work();
25
+ idleSince = work ? null : now();
26
+ deps.log("sighup_idle_watch_armed", { work, idleGraceMs: deps.idleGraceMs });
28
27
  watch = setInterval(() => {
29
28
  if (deps.isStopped()) {
30
29
  clearInterval(watch);
31
30
  watch = undefined;
32
31
  return;
33
32
  }
34
- if (deps.inflight() > 0 || (deps.attached?.() ?? 0) > 0) {
33
+ if (deps.work()) {
35
34
  idleSince = null;
36
35
  return;
37
36
  }
@@ -206,6 +206,22 @@ export declare function promptLeanSpecFragment(body: {
206
206
  }): {
207
207
  promptLean?: boolean;
208
208
  };
209
+ /** 请求面能写进 `TaskSpec.compaction` 的成员(其余成员是运维轴,有意不在 wire 上)。型取自引擎本体:引擎改名 / 删这两位 ⇒ 本仓编译红。 */
210
+ export type RequestCompaction = Pick<NonNullable<TaskSpec["compaction"]>, "clampTolerance" | "autoCompact">;
211
+ /**
212
+ * `TaskSpec.compaction` 的座位片段 —— 调用方拥有的**两个成员**的唯一映射(一个事实一个座位、一只读法,不分两处各铸半个对象):
213
+ * · `clampTolerance` ← 顶层 `body.compaction.clampTolerance`([ref] 的配套旋钮):`[0,1]` 闭区间的有限数才收,其余丢;
214
+ * · `autoCompact` ← `settings.autoCompactEnabled`(CC 同名 settings 键,CC 只拿它闸**引擎自起**的压缩):布尔**逐字**(`false` 是「关」,有意义,不当作「没说」)。
215
+ * 引擎座 `autoCompact` 管引擎自起的三条道(窗阈值那一遍、prompt-too-long 恢复那一遍、任务尾摘要);调用方要的那一遍(`POST /v1/runs/:id/compact` → `TaskStream.compact()`)
216
+ * 归另一只座 `manualCompact`,本仓不写它 ⇒ 它取部署席 / 引擎缺省(开)—— 「只关自动」不连带关手动 `/compact`。
217
+ * `compaction` 里别的成员(`manualCompact` / `withinTask` / `reserveTokens` / `keepRecentTokens` / `instructions` / `attachWorkingFiles` / `staleToolResultOffload`)是运维轴,有意不开。
218
+ * 两成员都缺席 ⇒ **整键不写**(与改前字节同;座的缺省属主是引擎与它的部署席,本仓不复刻);只有一个成员在场 ⇒ `compaction` 里只有它。
219
+ * 每个成员只在**自己的入口**被判一次:`clampTolerance` 直接来自体(resume 重放不过 HTTP 400 门),在这里判;`autoCompact` 来自解析层,类型 `boolean | undefined` 就是合同 ——
220
+ * 它的判官只有 `task-settings.ts` 的 `autoCompactEnabledOk`(受理门与宽容解析层同问它),这里不再判第二遍。
221
+ */
222
+ export declare function compactionSpecFragment(clampTolerance: unknown, autoCompact: boolean | undefined): {
223
+ compaction?: RequestCompaction;
224
+ };
209
225
  /** [ref]②(core 5.14.0 `TaskSpec.toolMaterializeStrategy`):deferred 工具激活后的 schema 供给策略。
210
226
  * 与 {@link promptLeanFromBody} 同姿势的**防御性归一**——提交面的 fail-loud 400 在 HTTP 门,这里
211
227
  * 只负责 resume 重放存量 body 时把不认识的值静默 DROP(回落 core 的 env/缺省链),而不是把它带上 spec。 */
@@ -325,6 +325,13 @@ export function promptLeanSpecFragment(body) {
325
325
  const lean = promptLeanFromBody(body.promptLean);
326
326
  return lean !== undefined ? { promptLean: lean } : {};
327
327
  }
328
+ export function compactionSpecFragment(clampTolerance, autoCompact) {
329
+ const seat = {
330
+ ...(typeof clampTolerance === "number" && Number.isFinite(clampTolerance) && clampTolerance >= 0 && clampTolerance <= 1 ? { clampTolerance } : {}),
331
+ ...(autoCompact !== undefined ? { autoCompact } : {}),
332
+ };
333
+ return Object.keys(seat).length > 0 ? { compaction: seat } : {};
334
+ }
328
335
  export function toolMaterializeStrategyFromBody(raw) {
329
336
  return raw === "static" || raw === "swap" ? raw : undefined;
330
337
  }
@@ -19,7 +19,8 @@ import type { SqlEngineFacts } from "./plugins/sql-driver.js";
19
19
  import { type SqlEngineCapability } from "./sql-engine-posture.js";
20
20
  /**
21
21
  * 降级词闭集(**按后端族**,不按失败发生在哪一步):
22
- * · `local_unwritable` —— **缺省推导**的 local 文件店构造期失败(mkdir / 数据根锁 / 权限 / 只读挂载 / 磁盘满)。
22
+ * · `local_unwritable` —— **缺省推导**的 local 文件店在**空 / 不存在**的数据根上构造期失败(mkdir / 权限 / 只读挂载 / 磁盘满)。
23
+ * 数据根上已有东西时开不了(含另一实例持锁)是拒启,不是降级(判据见 `openStoreBackendWithFallback`)。
23
24
  *
24
25
  * 🔴 SQL 族**没有**降级词:配了 DSN 的库当下打不开 ⇒ 窗内重试、到窗拒启(`plugins/store-open-wait.ts` / `openStoreBackendWithFallback`),
25
26
  * 从来不退成内存 —— 修前这里有第二个词 `db_unreachable`(`SESSION_BACKEND=auto` 下 SQL 族打不开 ⇒ 内存 + 本位置位),那是 [ref] P 类的静默 fail-open,随降级臂一并退役。
@@ -0,0 +1,3 @@
1
+ /** M38 的窗在 `today`(UTC 日历日 YYYY-MM-DD)开着没有:开 ⇒ 续跑重放腿剥键照续;关 ⇒ 同一只判据拒。登记行不在 ⇒ 响亮抛(这只读者活过了它的登记行,该随那一行一起删)。 */
2
+ export declare function storedEnvCredentialsDropM38(today: string): boolean;
3
+ //# sourceMappingURL=stored-request-env-credentials-m38.d.ts.map
@@ -0,0 +1,8 @@
1
+ import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
2
+ export function storedEnvCredentialsDropM38(today) {
3
+ const window = ONE_TIME_MIGRATIONS.find((w) => w.id === "M38");
4
+ if (window === undefined)
5
+ throw new Error("stored-request-env-credentials-m38: the one-time migration registry has no M38 row (the replay-leg settings.env credential drop window) — the drop arm outlived its registry row; delete it with that row");
6
+ return migrationWindowOpen(window, today);
7
+ }
8
+ //# sourceMappingURL=stored-request-env-credentials-m38.js.map
@@ -9,10 +9,11 @@ export type StoredHooksRereadM20 = (raw: unknown) => StoredHooksRereadM20Result
9
9
  /** 读者(= `parseHooksConfig`);作形参只为让「读者交回什么拒因」可被替身喂(默认值就是生产读者)。 */
10
10
  export type HooksReader = (raw: unknown) => ParseHooksConfigResult;
11
11
  /**
12
- * 重读一份存体 hooks:读者拒因全部属于两形 ⇒ 剥掉被点名的块里按类型确属未知的键、再问读者,**剥到读者受理为止**,过了就交回产物 + 被剥坐标;否则 `undefined`(原臂:整份不采纳)。
12
+ * 重读一份存体 hooks:读者拒因全部属于两形 ⇒ 剥掉被点名的块里该剥的键(全部未知键 + 被点名的不透明列)、再问读者,**剥到读者受理为止**,过了就交回产物 + 被剥坐标;否则 `undefined`(原臂:整份不采纳)。
13
13
  * 调用方只在读者**已经拒过**这份原值之后才来问;读者一开始就受理的值不进这里(进来也返回 `undefined`:没有可迁移的东西)。
14
14
  *
15
- * 终止:循环体以一次读开头(最后一次剥键之后必有一次读);继续下一轮的条件是本轮真从文档里剥掉了至少一个对象键,文档只减不增 ⇒ 必停;同一块只会被点名一次 ⇒ 轮数 ≤ 被点名的块数 + `__proto__` 键数。
15
+ * 终止:循环体以一次读开头(最后一次剥键之后必有一次读);继续下一轮的条件是本轮真从文档里剥掉了至少一个对象键,文档只减不增 ⇒ 必停;
16
+ * 同一块至多被点名 1 + 它的不透明列数次 ⇒ 轮数 ≤ Σ 被点名的块(1 + 不透明列数)+ `__proto__` 键数。
16
17
  */
17
18
  export declare function rereadStoredHooksM20(raw: unknown, read?: HooksReader): StoredHooksRereadM20Result | undefined;
18
19
  /**
@@ -1,13 +1,6 @@
1
- import { HOOK_ENTRY_TYPES } from "@sema-agent/settings-schema/hooks";
1
+ import { HOOK_ENTRY_FIELDS, HOOK_ENTRY_TYPES } from "@sema-agent/settings-schema/hooks";
2
2
  import { hooksCoordinate, parseHooksConfig } from "./hooks/hook-runner.js";
3
3
  import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
4
- const ENTRY_FIELD_NAMES = {
5
- command: { type: true, if: true, timeout: true, statusMessage: true, once: true, command: true, shell: true, async: true, asyncRewake: true },
6
- prompt: { type: true, if: true, timeout: true, statusMessage: true, once: true, prompt: true, model: true },
7
- agent: { type: true, if: true, timeout: true, statusMessage: true, once: true, prompt: true, model: true },
8
- http: { type: true, if: true, timeout: true, statusMessage: true, once: true, url: true, headers: true, allowedEnvVars: true },
9
- mcp_tool: { type: true, if: true, timeout: true, statusMessage: true, once: true, server: true, tool: true, input: true },
10
- };
11
4
  const MATCHER_FIELD_NAMES = { matcher: true, hooks: true };
12
5
  function isRecord(v) {
13
6
  return v !== null && typeof v === "object" && !Array.isArray(v);
@@ -27,13 +20,24 @@ function nodeAt(node, path) {
27
20
  }
28
21
  return cur;
29
22
  }
30
- function contractFieldsOf(code, block) {
23
+ const OPAQUE_KIND = "any";
24
+ function standingOf(code, block) {
31
25
  if (!isRecord(block))
32
26
  return undefined;
33
27
  if (code === "guard-matcher-invalid")
34
- return MATCHER_FIELD_NAMES;
28
+ return (key) => (Object.hasOwn(MATCHER_FIELD_NAMES, key) ? "read" : "unknown");
35
29
  const type = Object.hasOwn(block, "type") ? block.type : undefined;
36
- return isEntryType(type) ? ENTRY_FIELD_NAMES[type] : undefined;
30
+ if (!isEntryType(type))
31
+ return undefined;
32
+ const row = HOOK_ENTRY_FIELDS[type];
33
+ return (key) => {
34
+ if (key === "type")
35
+ return "read";
36
+ const kind = Object.hasOwn(row, key) ? row[key] : undefined;
37
+ if (kind === undefined)
38
+ return "unknown";
39
+ return (kind.endsWith("?") ? kind.slice(0, -1) : kind) === OPAQUE_KIND ? "opaque" : "read";
40
+ };
37
41
  }
38
42
  function stripTargetsOf(piece, doc) {
39
43
  const [root, ...rel] = piece.path;
@@ -43,11 +47,12 @@ function stripTargetsOf(piece, doc) {
43
47
  return [rel];
44
48
  if ((piece.code === "guard-entry-invalid" || piece.code === "guard-matcher-invalid") && typeof piece.field === "string") {
45
49
  const block = nodeAt(doc, rel);
46
- const known = contractFieldsOf(piece.code, block);
47
- if (known === undefined || !isRecord(block) || Object.hasOwn(known, piece.field) || !Object.hasOwn(block, piece.field))
50
+ const standing = standingOf(piece.code, block);
51
+ const named = piece.field;
52
+ if (standing === undefined || !isRecord(block) || !Object.hasOwn(block, named) || standing(named) === "read")
48
53
  return undefined;
49
54
  return Object.keys(block)
50
- .filter((key) => !Object.hasOwn(known, key))
55
+ .filter((key) => key === named || standing(key) === "unknown")
51
56
  .map((key) => [...rel, key]);
52
57
  }
53
58
  return undefined;
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import { type SealedCheckpointCtx } from "./http/checkpoint-ctx.js";
25
25
  import { type OneTimeMigrationWindow } from "./plugins/one-time-migrations.js";
26
- import type { CheckpointCtxRowsRewriter } from "./plugins/checkpoint-store-sql.js";
26
+ import type { CheckpointCtxRowsRewriter } from "./plugins/checkpoint-store-face.js";
27
27
  /** M30 一次起服的读数(起服 info 行逐键打出;测试按它断言)。`window: "closed"` ⇒ 一行都没读(其余全 0)。`rowsLongFormKept` = 改写成 `promptLean: false` 的行。 */
28
28
  export interface PromptProfileRetireM30Report {
29
29
  readonly window: "open" | "closed";
@@ -0,0 +1,148 @@
1
+ /**
2
+ * The SQL blob INDEX of a content-addressed blob domain — one row per blob `(blob_hash, byte_len, bytes, created_at)` in the
3
+ * domain's own table ([ref] D1: the file-history domain's `file_history_blob`; the retired snapshot epoch's `snapshot_blob`). The
4
+ * rows are the INDEX OWNER's (the store), never the byte port's: whether a blob is there, which blobs are orphans, the created_at
5
+ * grace window, the per-blob cap on SQL-kept bytes and the content-address check of a port read all live here. The byte port
6
+ * ({@link BlobBackend}, `plugins/blob-backend.ts`) only moves bytes: `put` / `get` / `delete` under a key.
7
+ *
8
+ * Where the bytes go — one option, the shape of the engine package's `fileHistory.blobs`:
9
+ * - no byte port (the DEFAULT): the bytes ride the index row itself (the `bytes` column), so a deployment without object storage
10
+ * keeps every blob in SQL, capped per blob ({@link sqlBlobCapOf}, judged on the connection that writes);
11
+ * - a byte port (object storage): the port stores the bytes under the blob's hash and the index row keeps `bytes` NULL. The port
12
+ * write lands BEFORE the index row, so an index row never claims bytes the port does not hold (an object with no row is
13
+ * unreachable and harmless); a port read is checked against its hash here ({@link readAtAddress}) — a mismatch reads as absent.
14
+ *
15
+ * Deletion stays ASYNCHRONOUS (clay 2026-06-26): a purge deletes only the referencing rows, so a blob becomes an orphan; the periodic
16
+ * {@link SqlBlobIndex.sweep} removes the grace-passed index rows FIRST and then asks the port to delete exactly those keys. A port
17
+ * delete that fails surfaces (the sweep rejects — the reaper's throttled guard is the loud channel) and leaves an object with no row.
18
+ *
19
+ * The SQL statements below are the ones the retired `SqlBlobBackend` / indexed `MinioBlobBackend` sent, verbatim — this module only
20
+ * gathers them under their owner.
21
+ */
22
+ import type { Pool as MysqlPool } from "mysql2/promise";
23
+ import type { Pool as PgPool } from "pg";
24
+ import { type BlobBackend } from "../plugins/blob-backend.js";
25
+ import { type SqlEngineFacts, type SqlEngineReading, type SqlWallSource, type SqlWallsReading, type SqlDialect } from "../plugins/sql-driver.js";
26
+ import { type Logger } from "../observability/logger.js";
27
+ /**
28
+ * 文本协议的 blob 膨胀律 —— mysql2 `query()` 把 Buffer 参数写成 `X'<hex>'`,一字节两个字符,所以承载一个 blob 的语句至少是它的 2 倍。
29
+ * 包墙折成「能装下多大的 blob」只用这一只常量,推导里不手写 `/ 2`。
30
+ */
31
+ export declare const SQL_TEXT_PROTOCOL_BLOB_INFLATION = 2;
32
+ /**
33
+ * 包墙下能装多大的 blob:语句里的载荷量({@link packetWallStatementBytes})再按 {@link SQL_TEXT_PROTOCOL_BLOB_INFLATION} 折半。
34
+ * blob 以十六进制字面进语句、有 2× —— 膨胀律是 blob 腿自己的,余量不是。
35
+ */
36
+ export declare function packetWallBlobCap(maxPacketBytes: number): number;
37
+ /**
38
+ * SQL 快照 blob 的**缺省**帽(运维没设 `SNAPSHOT_BLOB_SQL_MAX_BYTES` 时)的唯一推导 —— 入参是判官 `sqlWallsOf` 给的墙(不读事实、不判缺席、不看方言),**两堵墙取最小**:
39
+ * 行墙腿(`SqlEngineFacts.maxRowBytes`,TiDB:{@link rowWallPayloadBytes} 的 `blob` = 行墙 − blob 行的余量 1 KiB —— 按这一行的真实形算,不借 JSON 提交体行的 64 KiB)
40
+ * 与包墙腿(`SqlEngineFacts.maxPacketBytes`,InnoDB 与 TiDB 都有:{@link packetWallBlobCap} = ⌊(包墙 − 1 KiB 语句余量) ÷ 2⌋)。余量只在 `sql-driver.ts` 定义一次
41
+ * (墙 × 行的形各一只),提交体受理口(`http/request-guards.ts` `refuseSubmitBody`)读同一张表的 `json` 那一只,不各抄。
42
+ * 墙的 `null` 只表示「这堵墙不存在」;两堵都不存在(PG —— 扩展协议无这两堵墙 —— 或没有 SQL 后端)⇒ `undefined` 不设帽。
43
+ * 「事实本身缺席」不是这里的入参:店的写前判读的是借出连接自己的事实(恒已建立,见 {@link SqlConnectionReading}),缺席的读法只在提交受理口读池级读口时出现(判官 `sqlWallsOf` 给墙)。
44
+ * 显式旋钮是运维的策略帽,在本推导之上(见 {@link sqlBlobCapBytes})。
45
+ *
46
+ * 两堵墙的真库读数(clay 拍 a+c,2026-07-27;k3s8 tidb-test v7.5.1 默认配置探针):7 MiB / 31 MiB = `entry too large`(行墙,默认 6291456)、
47
+ * 32 MiB = `max_allowed_packet`(包墙,64 MiB ÷ ~2× 文本协议膨胀)。帽=诚实拒绝:超限 blob 在 query 之前 typed 拒(消费面 HTTP 413 / capture warn
48
+ * 拿到可行动信息);帽与墙之间只差这一行自己的几百字节(blob 行余量),帽之下的 blob 在缺省配置下落得进。D-1 附件战役同墙教训:`task-attachment-store.ts` 头注。
49
+ */
50
+ export declare function sqlBlobDefaultCapBytes(walls: SqlWallsReading): number | undefined;
51
+ /**
52
+ * 一个 SQL 快照 blob 的帽 + 它**从哪来**。`operator` = 运维显式设的 `SNAPSHOT_BLOB_SQL_MAX_BYTES`(策略帽);`reported` / `assumed` = 缺省推导里**定下这个帽的那条腿**的墙数字出处
53
+ * ({@link SqlWallSource}:库自己报的 / 读失败或事实缺席而退的文档缺省)。机读位同 413 拒体的 `wallSource` 词,旋钮形多一个 `operator`。
54
+ */
55
+ export interface SqlBlobCapReading {
56
+ readonly capBytes: number;
57
+ readonly source: "operator" | SqlWallSource;
58
+ }
59
+ /**
60
+ * 缺省帽的推导(唯一一处,{@link sqlBlobDefaultCapBytes} 是它的字节投影):两条腿各带自己那堵墙的出处,取最小的那条;两条一样小取行墙腿。两堵墙都不存在 ⇒ `undefined`。
61
+ */
62
+ export declare function sqlBlobDefaultCapOf(walls: SqlWallsReading): SqlBlobCapReading | undefined;
63
+ /**
64
+ * 一条**借出连接**的引擎读口:方言(装配事实)+ 它自己那次初始化回读的事实。与 {@link SqlEngineReading} 的差别只有一处 —— `facts` 恒在:连接是借出时才有的,
65
+ * 借出即已初始化({@link connectJudged} 交给判决的就是借出连接的 `sqlConnectionFacts`),所以「事实缺席」在这条读法上**不可表示**(编译期拒,不是运行期一个没人走的分支)。
66
+ * 事实缺席(池上还没建立过、或最近一次初始化被拒)只出现在读**池级**读口的地方 —— 提交受理口 —— 那一格的墙由判官 `sqlWallsOf` 给,不经过帽的推导。
67
+ */
68
+ export interface SqlConnectionReading {
69
+ readonly dialect: SqlEngineReading["dialect"];
70
+ readonly facts: SqlEngineFacts;
71
+ }
72
+ /**
73
+ * 一个 SQL 快照 blob 此刻的帽 —— **显式旋钮 ?? 判官给的墙走缺省推导**的唯一一只函数。唯一读者 = 店的写前判({@link SqlBlobIndex.put} 的 SQL 存字节臂),传的读口({@link SqlConnectionReading})是
74
+ * **将要执行写入的那条连接**的(方言 + 它自己那次初始化回读的事实,墙经与提交受理口同一只判官 `sqlWallsOf`):包墙是连接的会话值,所以判决只在写入的那条连接上做,
75
+ * HTTP 面不替店另算一份帽。
76
+ */
77
+ export declare function sqlBlobCapOf(explicitCapBytes: number | undefined, connection: SqlConnectionReading): SqlBlobCapReading | undefined;
78
+ /** {@link sqlBlobCapOf} 的字节投影(同一个推导,不另读)。 */
79
+ export declare function sqlBlobCapBytes(explicitCapBytes: number | undefined, connection: SqlConnectionReading): number | undefined;
80
+ /**
81
+ * 这一拒是不是**那条连接的包墙**定的:帽是缺省推导出的(不是运维旋钮)、那条连接有包墙、且包墙腿的折算恰是这个帽(包墙腿是最矮的一腿,或与行墙腿并列)。
82
+ * 只有这种拒才值得问「这条连接过时了吗」({@link connectJudged}) —— 旋钮的拒、行墙的拒与连接新旧无关。`walls` = 判出这个帽的那一份墙({@link sqlWallsOf})。
83
+ */
84
+ export declare function capBoundByPacketWall(cap: SqlBlobCapReading, walls: SqlWallsReading): boolean;
85
+ /**
86
+ * 一次 blob 超帽的拒句 —— **唯一的组句器**(店的 typed {@link BlobTooLargeError} 调它;`PUT /sync/blobs` 的 413 原样转出它的句子):句子按帽的出处({@link SqlBlobCapReading.source})
87
+ * 分三形,不把假定说成库的上限、也不把运维的旋钮说成库的上限。
88
+ * · `operator` —— 帽是运维设的 `SNAPSHOT_BLOB_SQL_MAX_BYTES`;
89
+ * · `reported` —— 帽由库报的两堵墙推出(单行上限与包墙÷文本协议膨胀的较小者);
90
+ * · `assumed` —— 库的上限没读到(事实还没建立,或这一堵读失败),帽按受支持引擎里最保守的缺省墙推出,稍后重试或由运维设旋钮。
91
+ */
92
+ export declare function sqlBlobCapRefusalText(byteLen: number, cap: SqlBlobCapReading): string;
93
+ /** typed 判别错:blob 超过 SQL 店的承载帽。判别码供店侧结果映射/HTTP 面/日志使用——绝不能与
94
+ * transient 写失败混在一类(那类是可重试的 502;这类重试永远不会成功)。句子是 {@link sqlBlobCapRefusalText}(带帽的出处)。 */
95
+ export declare class BlobTooLargeError extends Error {
96
+ readonly cap: SqlBlobCapReading;
97
+ readonly code: "blob_too_large_for_sql";
98
+ constructor(byteLen: number, cap: SqlBlobCapReading);
99
+ }
100
+ /** The blob domain an index serves, and where its bytes go (see the file header). */
101
+ export interface SqlBlobIndexOptions {
102
+ /** The domain's index table (a code literal, never user input). */
103
+ readonly table: string;
104
+ /** The byte port; absent ⇒ the bytes ride the index rows (SQL). */
105
+ readonly bytes?: BlobBackend;
106
+ /** The operator's explicit per-blob cap for SQL-kept bytes (`SNAPSHOT_BLOB_SQL_MAX_BYTES`); absent ⇒ the derivation in
107
+ * {@link sqlBlobCapOf} over the walls of the connection each write borrows. Not read with a byte port. */
108
+ readonly maxBytes?: number;
109
+ /** Where a stale connection's replacement is logged ({@link connectJudged}). */
110
+ readonly log?: Pick<Logger, "warn">;
111
+ }
112
+ /**
113
+ * One blob domain's index, owned by its store: every read and write of the domain's blob rows, and the only caller of the byte port.
114
+ */
115
+ export declare class SqlBlobIndex {
116
+ private readonly dialect;
117
+ private readonly pool;
118
+ private readonly opts;
119
+ /** The write path's connection source: an SQL-kept `put` borrows ONE connection from it (through {@link connectJudged}), judges on that connection's walls, writes on it. */
120
+ private readonly db;
121
+ private readonly log;
122
+ constructor(dialect: SqlDialect, pool: MysqlPool | PgPool, opts: SqlBlobIndexOptions);
123
+ /** Store `bytes` under `hash` (idempotent; a repeat refreshes created_at even on a dedup hit, so a just-written or re-used blob is
124
+ * "touched = now" and grace-protected — the delete-in-use lease).
125
+ * · SQL-kept: an over-cap blob is REJECTED (typed {@link BlobTooLargeError}) BEFORE the driver sees the bytes. 🔴 The cap is judged
126
+ * ON THE CONNECTION THAT WRITES ([ref]): `max_allowed_packet` is a session value, so the write borrows one connection through
127
+ * {@link connectJudged}, which reads ITS walls, judges, and — when the refusal is that connection's packet wall and the server's
128
+ * global wall is higher — replaces the stale connection and judges once more; the INSERT runs on the connection that passed.
129
+ * · Port-kept: the port write first, then the bytes-NULL index row (an index row never claims bytes the port does not hold). A
130
+ * failed port write throws (a silent drop would read as `read_failed` on restore). */
131
+ put(hash: string, bytes: Uint8Array): Promise<void>;
132
+ /** The bytes for `hash`, or `undefined` when absent. SQL-kept: the row's bytes (a pool / query error PROPAGATES — a transient fault
133
+ * is loud, not a silent "missing blob"). Port-kept: the port's bytes, checked against `hash` ({@link readAtAddress}: a mismatch —
134
+ * corruption or a poisoned object — reads as absent, never as wrong bytes; a transient port fault throws). */
135
+ get(hash: string): Promise<Uint8Array | undefined>;
136
+ /** The subset of `hashes` with an index row — one `blob_hash IN (...)` SELECT, the same reading for both byte homes (a bytes-NULL
137
+ * row counts as present). No bytes are read. */
138
+ has(hashes: readonly string[]): Promise<Set<string>>;
139
+ /** Collect orphans: the caller (the store) computes the orphan SET from its own domain's references and hands it here. Removes the
140
+ * index rows past the grace window (`created_at < cutoff` — a just-written blob an in-flight write still needs is never deleted:
141
+ * delete-in-use is data loss, under-delete is harmless), then — with a byte port — deletes exactly those keys' bytes. Returns the
142
+ * number of blobs removed (the grace-passed subset). A port delete failure surfaces as a rejection after the rows are gone. */
143
+ sweep(orphans: readonly string[]): Promise<number>;
144
+ /** DELETE the index rows for `hashes` that have passed the grace window; returns the hashes ACTUALLY deleted. Best-effort: a DB
145
+ * error is swallowed (under-delete is harmless; the next sweep retries). */
146
+ private deleteRowsPastGrace;
147
+ }
148
+ //# sourceMappingURL=blob-index-sql.d.ts.map
@@ -0,0 +1,154 @@
1
+ import { readAtAddress } from "../plugins/blob-backend.js";
2
+ import { connectJudged, mysqlDriver, packetWallStatementBytes, pgDriver, rowWallPayloadBytes, sqlWallsOf } from "../plugins/sql-driver.js";
3
+ import { createLogger } from "../observability/logger.js";
4
+ const BLOB_GC_GRACE_MS = 3_600_000;
5
+ export const SQL_TEXT_PROTOCOL_BLOB_INFLATION = 2;
6
+ export function packetWallBlobCap(maxPacketBytes) {
7
+ return Math.floor(packetWallStatementBytes(maxPacketBytes) / SQL_TEXT_PROTOCOL_BLOB_INFLATION);
8
+ }
9
+ export function sqlBlobDefaultCapBytes(walls) {
10
+ return sqlBlobDefaultCapOf(walls)?.capBytes;
11
+ }
12
+ export function sqlBlobDefaultCapOf(walls) {
13
+ const legs = [];
14
+ if (walls.maxRowBytes !== null)
15
+ legs.push({ capBytes: rowWallPayloadBytes(walls.maxRowBytes, "blob"), source: walls.sources.maxRowBytes });
16
+ if (walls.maxPacketBytes !== null)
17
+ legs.push({ capBytes: packetWallBlobCap(walls.maxPacketBytes), source: walls.sources.maxPacketBytes });
18
+ return legs.reduce((best, leg) => (best === undefined || leg.capBytes < best.capBytes ? leg : best), undefined);
19
+ }
20
+ export function sqlBlobCapOf(explicitCapBytes, connection) {
21
+ return explicitCapBytes !== undefined ? { capBytes: explicitCapBytes, source: "operator" } : sqlBlobDefaultCapOf(sqlWallsOf(connection));
22
+ }
23
+ export function sqlBlobCapBytes(explicitCapBytes, connection) {
24
+ return sqlBlobCapOf(explicitCapBytes, connection)?.capBytes;
25
+ }
26
+ export function capBoundByPacketWall(cap, walls) {
27
+ return cap.source !== "operator" && walls.maxPacketBytes !== null && packetWallBlobCap(walls.maxPacketBytes) === cap.capBytes;
28
+ }
29
+ export function sqlBlobCapRefusalText(byteLen, cap) {
30
+ const objectStorage = "configure MinIO object storage (MINIO_ENDPOINT/MINIO_ACCESS_KEY/MINIO_SECRET_KEY) for large snapshot blobs";
31
+ const head = `blob of ${byteLen} bytes exceeds this deployment's SQL snapshot-blob cap (${cap.capBytes} bytes — `;
32
+ switch (cap.source) {
33
+ case "operator":
34
+ return `${head}set by the operator's SNAPSHOT_BLOB_SQL_MAX_BYTES) — ${objectStorage}, or raise SNAPSHOT_BLOB_SQL_MAX_BYTES if the database allows larger writes`;
35
+ case "reported":
36
+ return `${head}the smaller of the database's single-row limit (TiDB txn-entry-size-limit, 6MiB by default) and about half its max_allowed_packet (the text protocol doubles a blob inside the statement)) — ${objectStorage}, or raise SNAPSHOT_BLOB_SQL_MAX_BYTES if your deployment lifted those limits`;
37
+ case "assumed":
38
+ return `${head}the database's limits were not read — engine facts not read yet, or a limit could not be read — so the smallest documented default wall applies) — retry shortly, ${objectStorage}, or set SNAPSHOT_BLOB_SQL_MAX_BYTES to the limit your deployment actually has`;
39
+ default: {
40
+ const unhandled = cap.source;
41
+ throw new Error(`blob cap refusal without a sentence: ${String(unhandled)}`);
42
+ }
43
+ }
44
+ }
45
+ export class BlobTooLargeError extends Error {
46
+ cap;
47
+ code = "blob_too_large_for_sql";
48
+ constructor(byteLen, cap) {
49
+ super(sqlBlobCapRefusalText(byteLen, cap));
50
+ this.cap = cap;
51
+ this.name = "BlobTooLargeError";
52
+ }
53
+ }
54
+ export class SqlBlobIndex {
55
+ dialect;
56
+ pool;
57
+ opts;
58
+ db;
59
+ log;
60
+ constructor(dialect, pool, opts) {
61
+ this.dialect = dialect;
62
+ this.pool = pool;
63
+ this.opts = opts;
64
+ this.db = dialect === "mysql" ? mysqlDriver(pool) : pgDriver(pool);
65
+ this.log = opts.log ?? createLogger();
66
+ }
67
+ async put(hash, bytes) {
68
+ const port = this.opts.bytes;
69
+ if (port !== undefined) {
70
+ await port.put(hash, bytes);
71
+ if (this.dialect === "mysql") {
72
+ await this.pool.query(`INSERT INTO ${this.opts.table} (blob_hash, byte_len, bytes, created_at) VALUES (?,?,NULL,?) ON DUPLICATE KEY UPDATE created_at = VALUES(created_at)`, [hash, bytes.byteLength, new Date()]);
73
+ }
74
+ else {
75
+ await this.pool.query(`INSERT INTO ${this.opts.table} (blob_hash, byte_len, bytes, created_at) VALUES ($1,$2,NULL,$3) ON CONFLICT (blob_hash) DO UPDATE SET created_at = EXCLUDED.created_at`, [hash, bytes.byteLength, new Date()]);
76
+ }
77
+ return;
78
+ }
79
+ const judged = await connectJudged(this.db, (facts) => {
80
+ const connection = { dialect: this.dialect, facts };
81
+ const cap = sqlBlobCapOf(this.opts.maxBytes, connection);
82
+ if (cap === undefined || bytes.byteLength <= cap.capBytes)
83
+ return undefined;
84
+ return { cap, packetBound: capBoundByPacketWall(cap, sqlWallsOf(connection)) };
85
+ }, (refusal) => refusal.packetBound, this.log);
86
+ if (judged.refusal !== undefined)
87
+ throw new BlobTooLargeError(bytes.byteLength, judged.refusal.cap);
88
+ try {
89
+ await judged.conn.query(this.dialect === "mysql"
90
+ ? `INSERT INTO ${this.opts.table} (blob_hash, byte_len, bytes, created_at) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE created_at = VALUES(created_at)`
91
+ : `INSERT INTO ${this.opts.table} (blob_hash, byte_len, bytes, created_at) VALUES ($1,$2,$3,$4) ON CONFLICT (blob_hash) DO UPDATE SET created_at = EXCLUDED.created_at`, [hash, bytes.byteLength, Buffer.from(bytes), new Date()]);
92
+ }
93
+ finally {
94
+ judged.conn.release();
95
+ }
96
+ }
97
+ async get(hash) {
98
+ const port = this.opts.bytes;
99
+ if (port !== undefined)
100
+ return readAtAddress(port, hash);
101
+ if (this.dialect === "mysql") {
102
+ const [rows] = await this.pool.query(`SELECT bytes FROM ${this.opts.table} WHERE blob_hash = ?`, [hash]);
103
+ return rows[0]?.bytes != null ? new Uint8Array(rows[0].bytes) : undefined;
104
+ }
105
+ const b = await this.pool.query(`SELECT bytes FROM ${this.opts.table} WHERE blob_hash = $1`, [hash]);
106
+ return b.rows[0]?.bytes != null ? new Uint8Array(b.rows[0].bytes) : undefined;
107
+ }
108
+ async has(hashes) {
109
+ if (hashes.length === 0)
110
+ return new Set();
111
+ const distinct = [...new Set(hashes)];
112
+ if (this.dialect === "mysql") {
113
+ const ph = distinct.map(() => "?").join(",");
114
+ const [rows] = await this.pool.query(`SELECT blob_hash FROM ${this.opts.table} WHERE blob_hash IN (${ph})`, distinct);
115
+ return new Set(rows.map((r) => String(r.blob_hash)));
116
+ }
117
+ const ph = distinct.map((_, i) => `$${i + 1}`).join(",");
118
+ const r = await this.pool.query(`SELECT blob_hash FROM ${this.opts.table} WHERE blob_hash IN (${ph})`, distinct);
119
+ return new Set(r.rows.map((row) => row.blob_hash));
120
+ }
121
+ async sweep(orphans) {
122
+ const removed = await this.deleteRowsPastGrace(orphans);
123
+ const port = this.opts.bytes;
124
+ if (port !== undefined && removed.length > 0)
125
+ await port.delete(removed);
126
+ return removed.length;
127
+ }
128
+ async deleteRowsPastGrace(hashes) {
129
+ if (hashes.length === 0)
130
+ return [];
131
+ const distinct = [...new Set(hashes)];
132
+ const cutoff = new Date(Date.now() - BLOB_GC_GRACE_MS);
133
+ if (this.dialect === "mysql") {
134
+ const ph = distinct.map(() => "?").join(",");
135
+ const grace = await this.pool
136
+ .query(`SELECT blob_hash FROM ${this.opts.table} WHERE created_at < ? AND blob_hash IN (${ph})`, [cutoff, ...distinct])
137
+ .then(([rows]) => rows.map((r) => String(r.blob_hash)))
138
+ .catch(() => []);
139
+ if (grace.length === 0)
140
+ return [];
141
+ const gph = grace.map(() => "?").join(",");
142
+ await this.pool
143
+ .query(`DELETE FROM ${this.opts.table} WHERE created_at < ? AND blob_hash IN (${gph})`, [cutoff, ...grace])
144
+ .catch(() => undefined);
145
+ return grace;
146
+ }
147
+ const ph = distinct.map((_, i) => `$${i + 2}`).join(",");
148
+ const r = await this.pool
149
+ .query(`DELETE FROM ${this.opts.table} WHERE created_at < $1 AND blob_hash IN (${ph}) RETURNING blob_hash`, [cutoff, ...distinct])
150
+ .catch(() => undefined);
151
+ return (r?.rows ?? []).map((row) => row.blob_hash);
152
+ }
153
+ }
154
+ //# sourceMappingURL=blob-index-sql.js.map