hippo-memory 1.71.0 → 2.0.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 (625) hide show
  1. package/README.md +7 -5
  2. package/dist/agent-memories/apply.d.ts +0 -11
  3. package/dist/agent-memories/apply.js +11 -26
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/copilot.d.ts +1 -3
  7. package/dist/agent-memories/copilot.js +1 -17
  8. package/dist/agent-memories/project-folds.d.ts +10 -0
  9. package/dist/agent-memories/project-folds.js +34 -0
  10. package/dist/agent-memories/sync.js +8 -6
  11. package/dist/api/assemble.js +3 -2
  12. package/dist/api/audit.d.ts +30 -2
  13. package/dist/api/audit.js +48 -7
  14. package/dist/api/auth.d.ts +11 -9
  15. package/dist/api/auth.js +39 -40
  16. package/dist/api/auto-sleep.d.ts +5 -2
  17. package/dist/api/auto-sleep.js +7 -3
  18. package/dist/api/availability.js +2 -3
  19. package/dist/api/cards.d.ts +42 -0
  20. package/dist/api/cards.js +52 -0
  21. package/dist/api/conflicts.d.ts +28 -0
  22. package/dist/api/conflicts.js +61 -0
  23. package/dist/api/context-auto.js +4 -2
  24. package/dist/api/context-render.js +4 -3
  25. package/dist/api/context-select.js +15 -29
  26. package/dist/api/context.js +29 -18
  27. package/dist/api/continuity.d.ts +47 -0
  28. package/dist/api/continuity.js +66 -0
  29. package/dist/api/dormant.js +4 -2
  30. package/dist/api/drill-down.js +3 -2
  31. package/dist/api/embeddings.d.ts +17 -0
  32. package/dist/api/embeddings.js +28 -0
  33. package/dist/api/error-reply.d.ts +8 -0
  34. package/dist/api/error-reply.js +21 -0
  35. package/dist/api/forget.d.ts +7 -3
  36. package/dist/api/forget.js +24 -14
  37. package/dist/api/goals.d.ts +1 -1
  38. package/dist/api/goals.js +5 -9
  39. package/dist/api/graph.js +2 -1
  40. package/dist/api/index.d.ts +4 -2
  41. package/dist/api/index.js +4 -2
  42. package/dist/api/instruction-detect.js +5 -1
  43. package/dist/api/learn.d.ts +5 -1
  44. package/dist/api/learn.js +71 -44
  45. package/dist/api/ledger-db.d.ts +2 -6
  46. package/dist/api/ledger-db.js +4 -36
  47. package/dist/api/memories.d.ts +21 -1
  48. package/dist/api/memories.js +51 -1
  49. package/dist/api/objects.d.ts +1 -1
  50. package/dist/api/objects.js +2 -1
  51. package/dist/api/outcome.d.ts +5 -5
  52. package/dist/api/outcome.js +17 -16
  53. package/dist/api/pilot-arm.d.ts +1 -11
  54. package/dist/api/pilot-arm.js +5 -45
  55. package/dist/api/predictions.d.ts +3 -1
  56. package/dist/api/predictions.js +8 -1
  57. package/dist/api/projects.d.ts +21 -0
  58. package/dist/api/projects.js +24 -0
  59. package/dist/api/promote.d.ts +3 -3
  60. package/dist/api/promote.js +26 -28
  61. package/dist/api/prompt-hook.d.ts +17 -2
  62. package/dist/api/prompt-hook.js +45 -4
  63. package/dist/api/quarantine.js +2 -1
  64. package/dist/api/recall-cli.d.ts +3 -0
  65. package/dist/api/recall-cli.js +13 -4
  66. package/dist/api/recall-core.js +10 -5
  67. package/dist/api/recall-pipeline.js +23 -24
  68. package/dist/api/recall-request.js +1 -1
  69. package/dist/api/recall-types.d.ts +3 -1
  70. package/dist/api/recall.d.ts +0 -3
  71. package/dist/api/recall.js +51 -73
  72. package/dist/api/remember-local.d.ts +5 -2
  73. package/dist/api/remember-local.js +15 -7
  74. package/dist/api/remember.d.ts +7 -3
  75. package/dist/api/remember.js +19 -16
  76. package/dist/api/session-end.d.ts +46 -0
  77. package/dist/api/session-end.js +131 -0
  78. package/dist/api/sleep-run.d.ts +1 -1
  79. package/dist/api/sleep-run.js +16 -11
  80. package/dist/api/sleep.js +4 -3
  81. package/dist/api/status.d.ts +24 -0
  82. package/dist/api/status.js +40 -0
  83. package/dist/api/store-init.d.ts +4 -0
  84. package/dist/api/store-init.js +9 -0
  85. package/dist/api/tokens.js +2 -2
  86. package/dist/api/types.d.ts +3 -7
  87. package/dist/api/types.js +6 -1
  88. package/dist/capture/caller-session.d.ts +0 -3
  89. package/dist/capture/caller-session.js +1 -12
  90. package/dist/capture/capture-error.d.ts +2 -2
  91. package/dist/capture/capture-error.js +23 -18
  92. package/dist/capture/codex-patch.js +3 -1
  93. package/dist/capture/command.js +36 -95
  94. package/dist/capture/compact.js +10 -5
  95. package/dist/capture/compaction-items-caller.js +11 -20
  96. package/dist/capture/compaction-record.d.ts +7 -93
  97. package/dist/capture/compaction-record.js +29 -426
  98. package/dist/capture/compaction-spool.d.ts +7 -7
  99. package/dist/capture/compaction-spool.js +60 -51
  100. package/dist/capture/copilot-transcript.d.ts +2 -1
  101. package/dist/capture/copilot-transcript.js +2 -1
  102. package/dist/capture/extract.d.ts +5 -2
  103. package/dist/capture/extract.js +4 -3
  104. package/dist/capture/failure-caller.d.ts +1 -1
  105. package/dist/capture/failure-caller.js +21 -16
  106. package/dist/capture/failure-reading.d.ts +2 -1
  107. package/dist/capture/failure-reading.js +7 -9
  108. package/dist/capture/pre-compact-caller.js +5 -4
  109. package/dist/capture/session-digest.js +4 -3
  110. package/dist/capture/session-end-caller.js +3 -2
  111. package/dist/capture/session-worker.js +22 -10
  112. package/dist/capture/transcript.d.ts +2 -1
  113. package/dist/capture/transcript.js +6 -3
  114. package/dist/capture/working-state.d.ts +4 -2
  115. package/dist/capture/working-state.js +4 -2
  116. package/dist/cli/audit-prune.d.ts +0 -25
  117. package/dist/cli/audit-prune.js +1 -27
  118. package/dist/cli/audit.js +20 -20
  119. package/dist/cli/auth.d.ts +1 -1
  120. package/dist/cli/auth.js +16 -17
  121. package/dist/cli/briefs.d.ts +1 -4
  122. package/dist/cli/briefs.js +37 -292
  123. package/dist/cli/card.js +41 -33
  124. package/dist/cli/client.d.ts +6 -2
  125. package/dist/cli/client.js +37 -21
  126. package/dist/cli/compact-resume-payload.js +1 -1
  127. package/dist/cli/context.d.ts +1 -1
  128. package/dist/cli/context.js +13 -13
  129. package/dist/cli/continuity.d.ts +1 -1
  130. package/dist/cli/continuity.js +36 -39
  131. package/dist/cli/curate.d.ts +2 -2
  132. package/dist/cli/curate.js +32 -36
  133. package/dist/cli/dag.d.ts +1 -1
  134. package/dist/cli/dag.js +23 -8
  135. package/dist/cli/decisions.d.ts +0 -2
  136. package/dist/cli/decisions.js +7 -285
  137. package/dist/cli/eval.d.ts +1 -1
  138. package/dist/cli/eval.js +12 -13
  139. package/dist/cli/explain.d.ts +1 -1
  140. package/dist/cli/explain.js +21 -25
  141. package/dist/cli/flag-values.js +16 -6
  142. package/dist/cli/flags.d.ts +0 -289
  143. package/dist/cli/flags.js +3 -138
  144. package/dist/cli/graph.d.ts +3 -0
  145. package/dist/cli/graph.js +83 -0
  146. package/dist/cli/hook-runtime.d.ts +6 -6
  147. package/dist/cli/hook-runtime.js +9 -36
  148. package/dist/cli/incidents.d.ts +3 -0
  149. package/dist/cli/incidents.js +112 -0
  150. package/dist/cli/init.d.ts +1 -1
  151. package/dist/cli/init.js +28 -19
  152. package/dist/cli/install-steps.d.ts +2 -1
  153. package/dist/cli/install-steps.js +11 -3
  154. package/dist/cli/last-sleep.js +1 -1
  155. package/dist/cli/maintenance.d.ts +3 -3
  156. package/dist/cli/maintenance.js +29 -30
  157. package/dist/cli/notes.d.ts +2 -0
  158. package/dist/cli/notes.js +41 -0
  159. package/dist/cli/object-verbs.d.ts +2 -2
  160. package/dist/cli/object-verbs.js +4 -4
  161. package/dist/cli/open-browser.d.ts +14 -0
  162. package/dist/cli/open-browser.js +26 -0
  163. package/dist/cli/playbooks.d.ts +3 -4
  164. package/dist/cli/playbooks.js +126 -290
  165. package/dist/cli/predictions.d.ts +3 -0
  166. package/dist/cli/predictions.js +174 -0
  167. package/dist/cli/print.js +2 -1
  168. package/dist/cli/projects.js +30 -22
  169. package/dist/cli/quality-repair-once.d.ts +1 -1
  170. package/dist/cli/quality-repair-once.js +6 -5
  171. package/dist/cli/recall.js +13 -7
  172. package/dist/cli/refine-llm.js +18 -17
  173. package/dist/cli/remember.js +17 -17
  174. package/dist/cli/scheduler.js +2 -1
  175. package/dist/cli/serve.js +11 -6
  176. package/dist/cli/session-hooks.d.ts +1 -5
  177. package/dist/cli/session-hooks.js +89 -168
  178. package/dist/cli/setup.d.ts +1 -1
  179. package/dist/cli/setup.js +17 -10
  180. package/dist/cli/shared.d.ts +2 -6
  181. package/dist/cli/shared.js +9 -29
  182. package/dist/cli/sleep-render.js +6 -3
  183. package/dist/cli/sleep.js +6 -37
  184. package/dist/cli/status.d.ts +3 -3
  185. package/dist/cli/status.js +32 -35
  186. package/dist/cli/transfer.d.ts +3 -3
  187. package/dist/cli/transfer.js +64 -43
  188. package/dist/cli/usage.d.ts +1 -80
  189. package/dist/cli/usage.js +2 -696
  190. package/dist/cli/verb-row.d.ts +34 -0
  191. package/dist/cli/verb-row.js +6 -0
  192. package/dist/cli/verbs/health.d.ts +27 -0
  193. package/dist/cli/verbs/health.js +234 -0
  194. package/dist/cli/verbs/memory.d.ts +16 -0
  195. package/dist/cli/verbs/memory.js +236 -0
  196. package/dist/cli/verbs/objects.d.ts +20 -0
  197. package/dist/cli/verbs/objects.js +257 -0
  198. package/dist/cli/verbs/sessions.d.ts +31 -0
  199. package/dist/cli/verbs/sessions.js +314 -0
  200. package/dist/cli/verbs.d.ts +81 -0
  201. package/dist/cli/verbs.js +7 -0
  202. package/dist/cli/versioned-verbs.d.ts +51 -0
  203. package/dist/cli/versioned-verbs.js +79 -0
  204. package/dist/cli.d.ts +1 -272
  205. package/dist/cli.js +24 -315
  206. package/dist/connectors/dlq.d.ts +39 -3
  207. package/dist/connectors/dlq.js +39 -4
  208. package/dist/connectors/github/backfill.js +12 -3
  209. package/dist/connectors/github/deletion.js +2 -1
  210. package/dist/connectors/github/dlq.js +31 -73
  211. package/dist/connectors/github/ingest.d.ts +2 -6
  212. package/dist/connectors/github/ingest.js +5 -29
  213. package/dist/connectors/github/tenant-routing.js +2 -1
  214. package/dist/connectors/github/webhook.d.ts +2 -1
  215. package/dist/connectors/github/webhook.js +35 -2
  216. package/dist/connectors/ingest.d.ts +10 -0
  217. package/dist/connectors/ingest.js +29 -0
  218. package/dist/connectors/slack/deletion.js +2 -1
  219. package/dist/connectors/slack/dlq.js +49 -71
  220. package/dist/connectors/slack/ingest.d.ts +2 -6
  221. package/dist/connectors/slack/ingest.js +4 -28
  222. package/dist/connectors/slack/tenant-routing.js +2 -1
  223. package/dist/connectors/slack/webhook.d.ts +2 -1
  224. package/dist/connectors/slack/webhook.js +2 -1
  225. package/dist/consolidate/conflicts.js +2 -2
  226. package/dist/consolidate/dag.js +29 -18
  227. package/dist/consolidate/dedupe.d.ts +7 -0
  228. package/dist/consolidate/dedupe.js +6 -4
  229. package/dist/consolidate/llm-passes.js +45 -19
  230. package/dist/consolidate/memory-value.js +3 -2
  231. package/dist/consolidate/merge.js +8 -8
  232. package/dist/consolidate/physics-pass.d.ts +6 -1
  233. package/dist/consolidate/physics-pass.js +26 -6
  234. package/dist/consolidate/replay.js +11 -4
  235. package/dist/consolidate/sleep.js +9 -6
  236. package/dist/consolidate/traces.js +5 -5
  237. package/dist/core/ablation.d.ts +10 -0
  238. package/dist/core/ablation.js +12 -0
  239. package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
  240. package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
  241. package/dist/core/ambient.d.ts +4 -0
  242. package/dist/core/ambient.js +39 -18
  243. package/dist/core/api-errors.d.ts +16 -0
  244. package/dist/core/api-errors.js +20 -0
  245. package/dist/core/card.js +3 -1
  246. package/dist/core/compaction-timing.d.ts +7 -0
  247. package/dist/core/compaction-timing.js +9 -0
  248. package/dist/core/config.d.ts +1 -1
  249. package/dist/core/config.js +22 -18
  250. package/dist/core/cosine.d.ts +3 -0
  251. package/dist/core/cosine.js +19 -0
  252. package/dist/{store → core}/markdown.d.ts +1 -1
  253. package/dist/{store → core}/markdown.js +4 -4
  254. package/dist/core/memory-audit.d.ts +17 -0
  255. package/dist/core/memory-audit.js +54 -0
  256. package/dist/core/memory.d.ts +14 -8
  257. package/dist/core/memory.js +35 -23
  258. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  259. package/dist/{consolidate → core}/merged-row.js +1 -1
  260. package/dist/core/physics.d.ts +3 -1
  261. package/dist/core/physics.js +23 -18
  262. package/dist/core/prediction.d.ts +3 -0
  263. package/dist/core/prediction.js +6 -0
  264. package/dist/core/project-identity.d.ts +3 -0
  265. package/dist/core/project-identity.js +12 -2
  266. package/dist/{store → core}/recall-scope.d.ts +1 -10
  267. package/dist/{store → core}/recall-scope.js +2 -19
  268. package/dist/core/search-types.d.ts +1 -1
  269. package/dist/dashboard/dashboard-actions.d.ts +2 -2
  270. package/dist/dashboard/dashboard-actions.js +5 -5
  271. package/dist/dashboard/dashboard-queries.js +2 -7
  272. package/dist/dashboard/dashboard-snapshot.js +1 -3
  273. package/dist/dashboard/dashboard.js +16 -5
  274. package/dist/db/busy.d.ts +2 -7
  275. package/dist/db/busy.js +21 -26
  276. package/dist/db/connect.d.ts +2 -2
  277. package/dist/db/connect.js +7 -7
  278. package/dist/db/index.d.ts +3 -3
  279. package/dist/db/index.js +3 -3
  280. package/dist/db/migrate.js +14 -7
  281. package/dist/db/migrations/index.d.ts +1 -1
  282. package/dist/db/migrations/index.js +3 -1
  283. package/dist/db/migrations/v11.js +1 -0
  284. package/dist/db/migrations/v14.js +1 -0
  285. package/dist/db/migrations/v55.d.ts +3 -0
  286. package/dist/db/migrations/v55.js +17 -0
  287. package/dist/db/open.d.ts +0 -2
  288. package/dist/db/open.js +6 -10
  289. package/dist/db/physics-state.d.ts +0 -4
  290. package/dist/db/physics-state.js +7 -33
  291. package/dist/db/request-stores.d.ts +1 -0
  292. package/dist/db/request-stores.js +2 -1
  293. package/dist/db/tables.d.ts +2 -0
  294. package/dist/db/tables.js +6 -2
  295. package/dist/db/vector-store.js +19 -5
  296. package/dist/db/wal-checkpointer.js +2 -1
  297. package/dist/doctor.d.ts +3 -0
  298. package/dist/doctor.js +18 -15
  299. package/dist/embeddings/local.d.ts +62 -0
  300. package/dist/embeddings/local.js +146 -0
  301. package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
  302. package/dist/{store/embeddings → embeddings}/provider.js +19 -25
  303. package/dist/embeddings/transformers.d.ts +26 -0
  304. package/dist/embeddings/transformers.js +89 -0
  305. package/dist/entry/session-text.d.ts +1 -1
  306. package/dist/entry/session-text.js +1 -1
  307. package/dist/entry/store-kit.d.ts +37 -0
  308. package/dist/entry/store-kit.js +25 -0
  309. package/dist/entry/testing.d.ts +6 -0
  310. package/dist/entry/testing.js +7 -0
  311. package/dist/eval/eval-suite.js +17 -11
  312. package/dist/eval/eval.js +1 -1
  313. package/dist/eval/judgment.js +12 -5
  314. package/dist/graph/extract.js +3 -3
  315. package/dist/graph/recall.js +1 -1
  316. package/dist/graph/view.js +13 -5
  317. package/dist/graph/write.d.ts +1 -1
  318. package/dist/graph/write.js +9 -9
  319. package/dist/hooks/codex-session.js +3 -2
  320. package/dist/hooks/codex-wrapper.js +2 -1
  321. package/dist/hooks/json-hooks.js +10 -4
  322. package/dist/hooks/opencode.js +8 -5
  323. package/dist/hooks/shared.d.ts +0 -6
  324. package/dist/hooks/shared.js +4 -15
  325. package/dist/importers/core.js +4 -4
  326. package/dist/importers/sources.js +5 -4
  327. package/dist/importers/vault.d.ts +1 -1
  328. package/dist/importers/vault.js +25 -23
  329. package/dist/index.d.ts +5 -4
  330. package/dist/index.js +4 -3
  331. package/dist/learn/autolearn.d.ts +15 -3
  332. package/dist/learn/autolearn.js +38 -16
  333. package/dist/learn/churn-git.js +13 -4
  334. package/dist/learn/extract.d.ts +3 -2
  335. package/dist/learn/extract.js +7 -5
  336. package/dist/learn/forward-claim-detector.js +4 -2
  337. package/dist/learn/invalidation.d.ts +2 -1
  338. package/dist/learn/invalidation.js +18 -9
  339. package/dist/mcp/admin-tools.d.ts +2 -2
  340. package/dist/mcp/admin-tools.js +27 -48
  341. package/dist/mcp/format.js +3 -2
  342. package/dist/mcp/framing.d.ts +1 -0
  343. package/dist/mcp/framing.js +1 -1
  344. package/dist/mcp/memory-tools.d.ts +1 -1
  345. package/dist/mcp/memory-tools.js +8 -9
  346. package/dist/mcp/protocol.d.ts +11 -7
  347. package/dist/mcp/protocol.js +25 -12
  348. package/dist/mcp/recall-tools.js +12 -9
  349. package/dist/mcp/request.js +22 -20
  350. package/dist/mcp/stdio.js +37 -16
  351. package/dist/mcp/tool-args.js +2 -1
  352. package/dist/mcp/tools.js +44 -21
  353. package/dist/objects/customer-notes.d.ts +2 -2
  354. package/dist/objects/decisions.d.ts +2 -2
  355. package/dist/objects/descriptor.d.ts +1 -1
  356. package/dist/objects/incidents.d.ts +2 -2
  357. package/dist/objects/lifecycle.d.ts +1 -1
  358. package/dist/objects/lifecycle.js +2 -1
  359. package/dist/objects/policies.d.ts +2 -2
  360. package/dist/objects/policies.js +2 -1
  361. package/dist/objects/processes.d.ts +2 -2
  362. package/dist/objects/project-briefs.d.ts +2 -2
  363. package/dist/objects/project-briefs.js +2 -3
  364. package/dist/objects/skills.d.ts +2 -2
  365. package/dist/postinstall.js +1 -1
  366. package/dist/rerankers/clef.js +3 -6
  367. package/dist/rerankers/cross-encoder.d.ts +31 -2
  368. package/dist/rerankers/cross-encoder.js +71 -98
  369. package/dist/rerankers/index.js +5 -4
  370. package/dist/rerankers/jev.js +2 -4
  371. package/dist/rerankers/outage-warning.d.ts +3 -1
  372. package/dist/rerankers/outage-warning.js +5 -3
  373. package/dist/search/bm25-search.js +1 -1
  374. package/dist/search/boosts.js +1 -1
  375. package/dist/search/embed-memories.d.ts +12 -0
  376. package/dist/search/embed-memories.js +389 -0
  377. package/dist/search/engine.d.ts +8 -0
  378. package/dist/search/engine.js +10 -0
  379. package/dist/search/goal-boost.d.ts +1 -1
  380. package/dist/search/goal-boost.js +6 -3
  381. package/dist/search/hybrid.d.ts +9 -2
  382. package/dist/search/hybrid.js +9 -4
  383. package/dist/search/physics-search.d.ts +6 -3
  384. package/dist/search/physics-search.js +22 -15
  385. package/dist/search/rerank.js +1 -1
  386. package/dist/search/vector.d.ts +8 -6
  387. package/dist/search/vector.js +14 -17
  388. package/dist/server/auth.d.ts +3 -1
  389. package/dist/server/auth.js +24 -15
  390. package/dist/server/boot.d.ts +2 -1
  391. package/dist/server/boot.js +34 -84
  392. package/dist/server/client-ip.d.ts +9 -6
  393. package/dist/server/client-ip.js +36 -17
  394. package/dist/server/deadline.d.ts +0 -2
  395. package/dist/server/deadline.js +1 -7
  396. package/dist/server/defaults.d.ts +1 -0
  397. package/dist/server/defaults.js +1 -0
  398. package/dist/server/mcp-http.js +16 -11
  399. package/dist/server/request.js +7 -2
  400. package/dist/server/route-checks.d.ts +7 -0
  401. package/dist/server/route-checks.js +42 -0
  402. package/dist/server/route-table.d.ts +9 -8
  403. package/dist/server/route-table.js +127 -133
  404. package/dist/server/routes/admin.d.ts +8 -8
  405. package/dist/server/routes/admin.js +13 -21
  406. package/dist/server/routes/customer-notes.d.ts +6 -6
  407. package/dist/server/routes/customer-notes.js +1 -2
  408. package/dist/server/routes/decisions.d.ts +6 -6
  409. package/dist/server/routes/decisions.js +2 -4
  410. package/dist/server/routes/incidents.d.ts +6 -6
  411. package/dist/server/routes/incidents.js +2 -5
  412. package/dist/server/routes/memories.d.ts +9 -9
  413. package/dist/server/routes/memories.js +19 -40
  414. package/dist/server/routes/object-routes.d.ts +6 -6
  415. package/dist/server/routes/object-routes.js +4 -7
  416. package/dist/server/routes/policies.d.ts +7 -7
  417. package/dist/server/routes/policies.js +2 -4
  418. package/dist/server/routes/predictions.d.ts +6 -6
  419. package/dist/server/routes/predictions.js +9 -13
  420. package/dist/server/routes/processes.d.ts +6 -6
  421. package/dist/server/routes/processes.js +1 -2
  422. package/dist/server/routes/project-briefs.d.ts +7 -7
  423. package/dist/server/routes/project-briefs.js +2 -4
  424. package/dist/server/routes/recall.d.ts +5 -5
  425. package/dist/server/routes/recall.js +6 -10
  426. package/dist/server/routes/skills.d.ts +7 -7
  427. package/dist/server/routes/skills.js +2 -4
  428. package/dist/server/server-detect.d.ts +7 -1
  429. package/dist/server/server-detect.js +36 -11
  430. package/dist/server/sleep-child.js +26 -7
  431. package/dist/server/sleep-offload.d.ts +11 -5
  432. package/dist/server/sleep-offload.js +17 -11
  433. package/dist/server/tls.d.ts +7 -2
  434. package/dist/server/tls.js +17 -5
  435. package/dist/server/types.d.ts +29 -12
  436. package/dist/server/validation.d.ts +1 -2
  437. package/dist/server/validation.js +6 -11
  438. package/dist/server.d.ts +4 -40
  439. package/dist/server.js +3 -29
  440. package/dist/sharing/global-store.d.ts +4 -5
  441. package/dist/sharing/global-store.js +8 -13
  442. package/dist/sharing/global-sync.js +38 -45
  443. package/dist/sharing/project-merge.d.ts +7 -14
  444. package/dist/sharing/project-merge.js +57 -121
  445. package/dist/sharing/search-both.js +10 -3
  446. package/dist/sharing/share.d.ts +2 -0
  447. package/dist/sharing/share.js +39 -38
  448. package/dist/store/ambient.js +7 -7
  449. package/dist/store/audit-event.d.ts +1 -1
  450. package/dist/store/audit.d.ts +0 -16
  451. package/dist/store/audit.js +4 -55
  452. package/dist/store/auth.d.ts +4 -2
  453. package/dist/store/auth.js +7 -3
  454. package/dist/store/candidates.d.ts +3 -2
  455. package/dist/store/candidates.js +59 -30
  456. package/dist/store/capture-write.d.ts +17 -0
  457. package/dist/store/capture-write.js +35 -0
  458. package/dist/store/cards.js +6 -5
  459. package/dist/store/compaction-caller.d.ts +18 -0
  460. package/dist/store/compaction-caller.js +29 -0
  461. package/dist/store/compactions-record.d.ts +115 -0
  462. package/dist/store/compactions-record.js +418 -0
  463. package/dist/store/compactions.js +6 -4
  464. package/dist/store/conflicts.d.ts +7 -1
  465. package/dist/store/conflicts.js +13 -9
  466. package/dist/store/connectors/dlq.d.ts +10 -0
  467. package/dist/store/connectors/dlq.js +33 -0
  468. package/dist/store/connectors/event-log.d.ts +13 -0
  469. package/dist/store/connectors/event-log.js +24 -0
  470. package/dist/store/connectors/github.d.ts +7 -9
  471. package/dist/store/connectors/github.js +35 -60
  472. package/dist/store/connectors/slack.d.ts +2 -11
  473. package/dist/store/connectors/slack.js +24 -57
  474. package/dist/store/dashboard-reads.js +8 -6
  475. package/dist/store/delete-and-batch.d.ts +6 -0
  476. package/dist/store/delete-and-batch.js +40 -6
  477. package/dist/store/delivery-recorder.d.ts +12 -5
  478. package/dist/store/delivery-recorder.js +13 -11
  479. package/dist/store/descendant-page.js +8 -4
  480. package/dist/store/dormant.d.ts +1 -1
  481. package/dist/store/dormant.js +10 -4
  482. package/dist/store/embeddings/index.d.ts +2 -12
  483. package/dist/store/embeddings/index.js +5 -374
  484. package/dist/store/entry-reads.d.ts +35 -4
  485. package/dist/store/entry-reads.js +86 -19
  486. package/dist/store/entry-row.js +9 -2
  487. package/dist/store/entry-writes.d.ts +15 -12
  488. package/dist/store/entry-writes.js +54 -22
  489. package/dist/store/failure-log-at.d.ts +8 -0
  490. package/dist/store/failure-log-at.js +16 -0
  491. package/dist/store/failure-log.d.ts +2 -2
  492. package/dist/store/failure-log.js +5 -3
  493. package/dist/{trust → store}/gated-write.d.ts +3 -1
  494. package/dist/{trust → store}/gated-write.js +7 -5
  495. package/dist/store/goals.js +22 -19
  496. package/dist/store/graph-reads.js +9 -6
  497. package/dist/store/graph-view-rows.js +2 -1
  498. package/dist/store/graph-writes.d.ts +6 -6
  499. package/dist/store/graph-writes.js +48 -71
  500. package/dist/store/half-life.js +2 -2
  501. package/dist/store/handoffs.d.ts +10 -4
  502. package/dist/store/handoffs.js +10 -9
  503. package/dist/store/index-and-stats.js +2 -2
  504. package/dist/store/index.d.ts +2 -2
  505. package/dist/store/index.js +1 -1
  506. package/dist/store/key-writes.js +1 -1
  507. package/dist/store/ledger-turn.d.ts +9 -0
  508. package/dist/store/ledger-turn.js +38 -0
  509. package/dist/store/mirrors.js +19 -10
  510. package/dist/store/open.d.ts +2 -5
  511. package/dist/store/open.js +42 -54
  512. package/dist/store/pilot-arm.d.ts +12 -0
  513. package/dist/store/pilot-arm.js +42 -0
  514. package/dist/store/port.d.ts +68 -6
  515. package/dist/store/port.js +8 -0
  516. package/dist/store/predictions.d.ts +1 -2
  517. package/dist/store/predictions.js +3 -6
  518. package/dist/store/project-tags.d.ts +62 -0
  519. package/dist/store/project-tags.js +67 -0
  520. package/dist/store/quality-repair.js +1 -1
  521. package/dist/store/quarantine.js +2 -1
  522. package/dist/store/recall-trace.d.ts +2 -0
  523. package/dist/store/recall-trace.js +20 -3
  524. package/dist/store/rejected-values.js +16 -10
  525. package/dist/store/rejection-probe.d.ts +4 -0
  526. package/dist/store/rejection-probe.js +19 -0
  527. package/dist/store/rejection.d.ts +0 -17
  528. package/dist/store/rejection.js +1 -21
  529. package/dist/store/rows.js +2 -2
  530. package/dist/store/rule-sql.d.ts +11 -0
  531. package/dist/store/rule-sql.js +31 -6
  532. package/dist/store/search-rows.d.ts +5 -5
  533. package/dist/store/search-rows.js +18 -16
  534. package/dist/store/sessions.js +4 -2
  535. package/dist/store/set-aside.d.ts +14 -0
  536. package/dist/store/set-aside.js +23 -0
  537. package/dist/store/sqlite/busy.d.ts +3 -0
  538. package/dist/store/sqlite/busy.js +8 -0
  539. package/dist/store/sqlite/connector-events-group.js +4 -7
  540. package/dist/store/sqlite/connector-writes-group.js +6 -4
  541. package/dist/store/sqlite/entry-writes-group.d.ts +3 -3
  542. package/dist/store/sqlite/entry-writes-group.js +3 -3
  543. package/dist/store/sqlite/error-codec.js +4 -3
  544. package/dist/store/sqlite/executor.js +10 -4
  545. package/dist/store/sqlite/graph-reads-group.js +1 -1
  546. package/dist/store/sqlite/held-connection.d.ts +11 -0
  547. package/dist/store/sqlite/held-connection.js +41 -0
  548. package/dist/store/sqlite/last-recall-group.d.ts +13 -0
  549. package/dist/store/sqlite/last-recall-group.js +57 -0
  550. package/dist/store/sqlite/local.d.ts +0 -17
  551. package/dist/store/sqlite/local.js +0 -31
  552. package/dist/store/sqlite/maintenance-groups.d.ts +6 -0
  553. package/dist/store/sqlite/maintenance-groups.js +60 -0
  554. package/dist/store/sqlite/object-rows.d.ts +1 -1
  555. package/dist/store/sqlite/objects-group.d.ts +1 -1
  556. package/dist/store/sqlite/objects-group.js +15 -7
  557. package/dist/store/sqlite/store.d.ts +1 -8
  558. package/dist/store/sqlite/store.js +13 -22
  559. package/dist/store/summaries.d.ts +10 -3
  560. package/dist/store/summaries.js +54 -11
  561. package/dist/store/token-ledger-rows.js +3 -2
  562. package/dist/store/token-ledger.d.ts +0 -7
  563. package/dist/store/token-ledger.js +0 -35
  564. package/dist/store/vector-index.js +8 -4
  565. package/dist/support-bundle.js +2 -3
  566. package/dist/trust/reject-flow.js +2 -2
  567. package/dist/util/agent-homes.d.ts +15 -0
  568. package/dist/util/agent-homes.js +34 -0
  569. package/dist/util/anthropic-messages.d.ts +6 -1
  570. package/dist/util/anthropic-messages.js +26 -7
  571. package/dist/util/atomic-write.d.ts +5 -2
  572. package/dist/util/atomic-write.js +12 -8
  573. package/dist/util/chunked.d.ts +3 -0
  574. package/dist/util/chunked.js +10 -0
  575. package/dist/util/ellipsize.d.ts +3 -0
  576. package/dist/util/ellipsize.js +5 -0
  577. package/dist/util/env.d.ts +12 -2
  578. package/dist/util/env.js +12 -2
  579. package/dist/util/format.d.ts +5 -0
  580. package/dist/util/format.js +10 -0
  581. package/dist/util/hook-payload.d.ts +8 -0
  582. package/dist/util/hook-payload.js +37 -0
  583. package/dist/util/http-retry.d.ts +6 -0
  584. package/dist/util/http-retry.js +43 -5
  585. package/dist/util/http-util.d.ts +0 -8
  586. package/dist/util/http-util.js +10 -21
  587. package/dist/util/limits.d.ts +7 -0
  588. package/dist/util/limits.js +14 -0
  589. package/dist/util/log.d.ts +4 -0
  590. package/dist/util/log.js +9 -0
  591. package/dist/util/request-scope.d.ts +9 -3
  592. package/dist/util/request-scope.js +18 -9
  593. package/dist/util/secret-detect.js +6 -1
  594. package/dist/util/spawn-argv.d.ts +9 -0
  595. package/dist/util/spawn-argv.js +57 -0
  596. package/dist/util/sql.d.ts +3 -0
  597. package/dist/util/sql.js +6 -0
  598. package/dist/util/sqlite-blocked.d.ts +2 -0
  599. package/dist/util/sqlite-blocked.js +5 -0
  600. package/dist/util/stream-tee.d.ts +3 -0
  601. package/dist/util/stream-tee.js +35 -0
  602. package/dist/util/time.d.ts +4 -0
  603. package/dist/util/time.js +4 -0
  604. package/dist/util/vector-codec.d.ts +4 -0
  605. package/dist/util/vector-codec.js +15 -0
  606. package/dist/util/version.d.ts +1 -1
  607. package/dist/util/version.js +1 -1
  608. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  609. package/extensions/openclaw-plugin/package.json +1 -1
  610. package/openclaw.plugin.json +1 -1
  611. package/package.json +4 -2
  612. package/dist/api/on-store.d.ts +0 -16
  613. package/dist/api/on-store.js +0 -38
  614. package/dist/store/embeddings/local.d.ts +0 -15
  615. package/dist/store/embeddings/local.js +0 -175
  616. /package/dist/{cli → api}/correction-latency.d.ts +0 -0
  617. /package/dist/{cli → api}/correction-latency.js +0 -0
  618. /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
  619. /package/dist/{cli → api}/provenance-coverage.js +0 -0
  620. /package/dist/{store → core}/object-types.d.ts +0 -0
  621. /package/dist/{store → core}/object-types.js +0 -0
  622. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  623. /package/dist/{capture → util}/compaction-items.js +0 -0
  624. /package/dist/{store → util}/yaml.d.ts +0 -0
  625. /package/dist/{store → util}/yaml.js +0 -0
@@ -0,0 +1,11 @@
1
+ /** What the server calls around its responses to keep its store connection. */
2
+ export interface StoreHolder {
3
+ hold: () => void;
4
+ afterResponse: () => void;
5
+ release: () => Promise<void>;
6
+ /** Runs one request, inside the fence that keeps hippo.db shut when the store is not it. */
7
+ runRequest: (run: () => Promise<void>) => Promise<void>;
8
+ }
9
+ /** Holds a connection to the hippo.db under `hippoRoot` once it exists, so serving never creates one. */
10
+ export declare function holdSqliteConnection(hippoRoot: string): StoreHolder;
11
+ //# sourceMappingURL=held-connection.d.ts.map
@@ -0,0 +1,41 @@
1
+ // A served hippo.db keeps one connection open for the life of the server, beside the worker that checkpoints its WAL.
2
+ import { existsSync } from 'node:fs';
3
+ import { closeHippoDb, getHippoDbPath, openHippoDb, outsideRequestStores, outsideSqliteOffLoop, SERVER_DB_WAIT_MS, } from '../../db/index.js';
4
+ import { startWalCheckpointer } from '../../db/wal-checkpointer.js';
5
+ import { errorMessage, log } from '../../util/log.js';
6
+ /** Holds a connection to the hippo.db under `hippoRoot` once it exists, so serving never creates one. */
7
+ export function holdSqliteConnection(hippoRoot) {
8
+ // Handlers open and close their own connections; while this one is held, none of those closes is SQLite's last,
9
+ // which checkpoints and deletes the WAL.
10
+ let heldDb;
11
+ let checkpointer;
12
+ let stopHolding = false;
13
+ const hold = () => {
14
+ if (heldDb || stopHolding || !existsSync(getHippoDbPath(hippoRoot)))
15
+ return;
16
+ try {
17
+ // The 'finish' listener can fire inside a request scope (closing this connection with the request) and inside a `loop: 'off'` block (refusing the open).
18
+ // The server's lock wait: this open runs on the event loop, where SQLite's 5 s default and the 30 s journal-mode retry would stall every request.
19
+ heldDb = outsideSqliteOffLoop(() => outsideRequestStores(() => openHippoDb(hippoRoot, { busyWaitMs: SERVER_DB_WAIT_MS })));
20
+ checkpointer = startWalCheckpointer(getHippoDbPath(hippoRoot));
21
+ }
22
+ catch (err) {
23
+ stopHolding = true;
24
+ log.warn(`serve: could not hold a store connection; requests still work, only slower: ${errorMessage(err)}`);
25
+ }
26
+ };
27
+ const afterResponse = () => {
28
+ hold();
29
+ checkpointer?.noteResponse();
30
+ };
31
+ const release = async () => {
32
+ stopHolding = true;
33
+ // The worker's connection closes first, so the held one is SQLite's last and its close checkpoints and deletes the WAL.
34
+ await checkpointer?.stop();
35
+ if (heldDb)
36
+ closeHippoDb(heldDb);
37
+ heldDb = undefined;
38
+ };
39
+ return { hold, afterResponse, release, runRequest: (run) => run() };
40
+ }
41
+ //# sourceMappingURL=held-connection.js.map
@@ -0,0 +1,13 @@
1
+ import type { LastRecall, RecallWrites, Sync } from '../port.js';
2
+ /** What a finished recall wrote after its audit rows: the trace's id, null when none was asked or its write failed, and the ids strengthened. */
3
+ interface RecallFinish {
4
+ readonly traceId: number | null;
5
+ readonly strengthened: ReadonlySet<string>;
6
+ }
7
+ /** sqliteStore's finishRecall, for the synchronous recall that cannot await the port. */
8
+ export declare function finishRecallAt(hippoRoot: string, writes: RecallWrites): RecallFinish;
9
+ export declare function sqliteLastRecall(hippoRoot: string): Sync<LastRecall>;
10
+ /** The group as a served store answers it: the call runs at once and resolves through a Promise, so a throw rejects as another store's would. */
11
+ export declare function servedLastRecall(sync: Sync<LastRecall>): LastRecall;
12
+ export {};
13
+ //# sourceMappingURL=last-recall-group.d.ts.map
@@ -0,0 +1,57 @@
1
+ // hippo.db's LastRecall group: the last recall sits in its meta table, and a traced outcome links on the outcome's own handle.
2
+ import { withWriteScope } from '../../db/index.js';
3
+ import { appendAuditEvent } from '../audit.js';
4
+ import { strengthenRetrieved, strengthenRetrievedInOwnTx } from '../entry-writes.js';
5
+ import { localGoalRecallRows, writeGoalRecallLog } from '../goals.js';
6
+ import { loadLastRecall, saveIndex } from '../index-and-stats.js';
7
+ import { onHandle } from '../open.js';
8
+ import { writeRecallTrace } from '../recall-trace.js';
9
+ import { applyOutcomeAt } from './entry-writes-group.js';
10
+ /** sqliteStore's finishRecall, for the synchronous recall that cannot await the port. */
11
+ export function finishRecallAt(hippoRoot, writes) {
12
+ return onHandle(hippoRoot, (db) => {
13
+ const traceAndStrengthen = () => ({
14
+ traceId: writes.trace ? writeRecallTrace(db, writes.trace) : null,
15
+ strengthened: writes.strengthen ? strengthenRetrievedInOwnTx(db, writes.strengthen.ids, writes.strengthen.opts) : new Set(),
16
+ });
17
+ // Alone, the fail-soft trace and strengthen keep their own scopes so a busy lock loses them, never the read.
18
+ if (writes.goalLog.length === 0 && writes.audit.length === 0)
19
+ return traceAndStrengthen();
20
+ // Inside this scope both run as savepoints, so one recall commits once and a failed trace or strengthen still unwinds alone.
21
+ return withWriteScope(db, 'finish_recall', () => {
22
+ writeGoalRecallLog(db, localGoalRecallRows(db, writes.goalLog));
23
+ for (const event of writes.audit)
24
+ appendAuditEvent(db, event);
25
+ return traceAndStrengthen();
26
+ });
27
+ });
28
+ }
29
+ export function sqliteLastRecall(hippoRoot) {
30
+ return {
31
+ applyTracedOutcome: (outcome, traceId) => applyOutcomeAt(hippoRoot, outcome, traceId),
32
+ applyOutcomeToLast(target, good) {
33
+ const { last_retrieval_ids: ids, last_trace_id: trace } = loadLastRecall(hippoRoot);
34
+ if (ids.length === 0)
35
+ return [];
36
+ return applyOutcomeAt(hippoRoot, { ...target, ids, good }, trace === null ? undefined : Number(trace));
37
+ },
38
+ finishRecall(writes, globalRoot) {
39
+ const { ids, opts } = writes.strengthen;
40
+ const { traceId, strengthened } = finishRecallAt(hippoRoot, writes);
41
+ if (globalRoot !== undefined)
42
+ strengthenRetrieved(globalRoot, ids.filter((id) => !strengthened.has(id)), opts);
43
+ // One write for both keys, so an outcome never pairs these ids with an older trace; a lost trace saves null.
44
+ saveIndex(hippoRoot, { last_retrieval_ids: [...ids], last_trace_id: traceId === null ? null : String(traceId) });
45
+ return traceId;
46
+ },
47
+ };
48
+ }
49
+ /** The group as a served store answers it: the call runs at once and resolves through a Promise, so a throw rejects as another store's would. */
50
+ export function servedLastRecall(sync) {
51
+ return {
52
+ applyTracedOutcome: async (outcome, traceId) => sync.applyTracedOutcome(outcome, traceId),
53
+ applyOutcomeToLast: async (target, good) => sync.applyOutcomeToLast(target, good),
54
+ finishRecall: async (writes, globalRoot) => sync.finishRecall(writes, globalRoot),
55
+ };
56
+ }
57
+ //# sourceMappingURL=last-recall-group.js.map
@@ -1,21 +1,4 @@
1
1
  import { type ScopeGrantChange } from '../key-writes.js';
2
- import type { EntryTarget, OutcomeWrite, RecallWrites } from '../port.js';
3
- /** A recall's writes when hippo.db keeps it as its last one: `strengthen.ids` are the ids it returned. */
4
- type LastRecallWrites = RecallWrites & Required<Pick<RecallWrites, 'strengthen'>>;
5
- /** The port's writes with a part that needs hippo.db's own handle or its meta table, which no other store has. */
6
- export interface SqliteLocal {
7
- /** entryWrites.applyOutcome, then a link from the recall trace to the ids applied, on the same handle after the commit. */
8
- applyOutcome(outcome: OutcomeWrite, traceId: number): string[];
9
- /** applyOutcome on the ids of the last recall, which hippo.db's meta table holds with that recall's trace; answers the ids applied. */
10
- applyOutcomeToLastRecall(target: EntryTarget, good: boolean): string[];
11
- /** finishRecall, then the ids this root lacks strengthened under `globalRoot`, then the ids and their trace saved as the last recall;
12
- * answers the trace id. A store of another kind keeps no last recall, so its stand-in is its own finishRecall, answering null. */
13
- finishLastRecall(writes: LastRecallWrites, globalRoot: string | undefined): number | null | Promise<number | null>;
14
- }
15
- export declare function sqliteLocal(hippoRoot: string): SqliteLocal;
16
- /** What a served store answers for each write that needs hippo.db's own handle: a refusal. */
17
- export declare const REFUSED_ON_A_STORE: Pick<SqliteLocal, 'applyOutcome'>;
18
2
  /** Off the port: only the local CLI changes grants, through synchronous published functions a store's Promise cannot answer. */
19
3
  export declare function changeScopeGrant(hippoRoot: string, change: ScopeGrantChange): void;
20
- export {};
21
4
  //# sourceMappingURL=local.d.ts.map
@@ -1,37 +1,6 @@
1
1
  // What only hippo.db does: operations no port method covers, so they never run on another store.
2
- import { strengthenRetrieved } from '../entry-writes.js';
3
- import { loadLastRecall, saveIndex } from '../index-and-stats.js';
4
2
  import { changeScopeGrantAt } from '../key-writes.js';
5
3
  import { onHandle } from '../open.js';
6
- import { applyOutcomeAt } from './entry-writes-group.js';
7
- import { finishRecallAt } from './store.js';
8
- export function sqliteLocal(hippoRoot) {
9
- return {
10
- applyOutcome: (outcome, traceId) => applyOutcomeAt(hippoRoot, outcome, traceId),
11
- // The ids and the trace come from one statement, so the outcome is linked to the recall that returned those ids.
12
- applyOutcomeToLastRecall(target, good) {
13
- const { last_retrieval_ids: ids, last_trace_id: trace } = loadLastRecall(hippoRoot);
14
- if (ids.length === 0)
15
- return [];
16
- return applyOutcomeAt(hippoRoot, { ...target, ids, good }, trace === null ? undefined : Number(trace));
17
- },
18
- finishLastRecall(writes, globalRoot) {
19
- const { ids, opts } = writes.strengthen;
20
- const { traceId, strengthened } = finishRecallAt(hippoRoot, writes);
21
- if (globalRoot !== undefined)
22
- strengthenRetrieved(globalRoot, ids.filter((id) => !strengthened.has(id)), opts);
23
- // One write for both keys, so an outcome never pairs these ids with an older trace; a lost trace saves null.
24
- saveIndex(hippoRoot, { last_retrieval_ids: [...ids], last_trace_id: traceId === null ? null : String(traceId) });
25
- return traceId;
26
- },
27
- };
28
- }
29
- /** What a served store answers for each write that needs hippo.db's own handle: a refusal. */
30
- export const REFUSED_ON_A_STORE = {
31
- applyOutcome() {
32
- throw new Error('an outcome links its recall trace on hippo.db only, never through a store');
33
- },
34
- };
35
4
  /** Off the port: only the local CLI changes grants, through synchronous published functions a store's Promise cannot answer. */
36
5
  export function changeScopeGrant(hippoRoot, change) {
37
6
  onHandle(hippoRoot, (db) => changeScopeGrantAt(db, change));
@@ -0,0 +1,6 @@
1
+ import type { AuditMaintenance, LessonWrites, Sync } from '../port.js';
2
+ export declare function sqliteAuditMaintenance(hippoRoot: string): Sync<AuditMaintenance>;
3
+ export declare function servedAuditMaintenance(sync: Sync<AuditMaintenance>): AuditMaintenance;
4
+ export declare function sqliteLessonWrites(hippoRoot: string): Sync<LessonWrites>;
5
+ export declare function servedLessonWrites(sync: Sync<LessonWrites>): LessonWrites;
6
+ //# sourceMappingURL=maintenance-groups.d.ts.map
@@ -0,0 +1,60 @@
1
+ // hippo.db's half of the AuditMaintenance and LessonWrites store groups: the quality audit, audit prune and git learn's batch.
2
+ import { pruneAuditRows } from '../audit.js';
3
+ import { loadTextsHoldingWords } from '../candidates.js';
4
+ import { deleteEntriesAutomatically, memoriesBackingObjects } from '../delete-and-batch.js';
5
+ import { loadAllEntries } from '../entry-reads.js';
6
+ import { writeEntriesSkippingRejected, writeEntriesTogether } from '../entry-writes.js';
7
+ import { updateStats } from '../index-and-stats.js';
8
+ import { repairAutomaticMemories, repairQualityOnce } from '../quality-repair.js';
9
+ import { touchableScopeSql } from '../rule-sql.js';
10
+ export function sqliteAuditMaintenance(hippoRoot) {
11
+ return {
12
+ tenantEntries: (tenantId) => loadAllEntries(hippoRoot, tenantId),
13
+ objectBackedIds: () => memoriesBackingObjects(hippoRoot),
14
+ deleteAutomatically: (removals, actor) => deleteEntriesAutomatically(hippoRoot, removals, actor),
15
+ pruneAuditRows: (prune) => pruneAuditRows(hippoRoot, prune),
16
+ repairQuality: (tenantId, apply) => repairAutomaticMemories(hippoRoot, { tenantId, apply }),
17
+ repairQualityOnce: (tenantId) => repairQualityOnce(hippoRoot, tenantId),
18
+ };
19
+ }
20
+ export function servedAuditMaintenance(sync) {
21
+ return {
22
+ tenantEntries: async (tenantId) => sync.tenantEntries(tenantId),
23
+ objectBackedIds: async () => sync.objectBackedIds(),
24
+ deleteAutomatically: async (removals, actor) => sync.deleteAutomatically(removals, actor),
25
+ pruneAuditRows: async (prune) => sync.pruneAuditRows(prune),
26
+ repairQuality: async (tenantId, apply) => sync.repairQuality(tenantId, apply),
27
+ repairQualityOnce: async (tenantId) => sync.repairQualityOnce(tenantId),
28
+ };
29
+ }
30
+ export function sqliteLessonWrites(hippoRoot) {
31
+ return {
32
+ tenantEntries: (tenantId) => loadAllEntries(hippoRoot, tenantId),
33
+ textsHoldingWords: (tenantId, words, ownScope) => loadTextsHoldingWords(hippoRoot, tenantId, words, undefined, touchableScopeSql('', ownScope)),
34
+ writeSkippingRejected(entries, actor) {
35
+ const written = [];
36
+ writeEntriesSkippingRejected(hippoRoot, (put) => {
37
+ for (const entry of entries)
38
+ if (put(entry))
39
+ written.push(entry.id);
40
+ }, actor);
41
+ return written;
42
+ },
43
+ writeTogether(entries) {
44
+ writeEntriesTogether(hippoRoot, entries);
45
+ },
46
+ bumpRemembered(count) {
47
+ updateStats(hippoRoot, { remembered: count });
48
+ },
49
+ };
50
+ }
51
+ export function servedLessonWrites(sync) {
52
+ return {
53
+ tenantEntries: async (tenantId) => sync.tenantEntries(tenantId),
54
+ textsHoldingWords: async (tenantId, words, ownScope) => sync.textsHoldingWords(tenantId, words, ownScope),
55
+ writeSkippingRejected: async (entries, actor) => sync.writeSkippingRejected(entries, actor),
56
+ writeTogether: async (entries) => sync.writeTogether(entries),
57
+ bumpRemembered: async (count) => sync.bumpRemembered(count),
58
+ };
59
+ }
60
+ //# sourceMappingURL=maintenance-groups.js.map
@@ -1,7 +1,7 @@
1
1
  import type { AuditOp } from '../audit.js';
2
2
  import type { JsonObject } from '../working-memory.js';
3
3
  import type { SourceObjectType } from '../graph-rows.js';
4
- import type { BriefStatus, DecisionStatus, IncidentStatus, NoteStatus, ObjectByKind, ObjectFields, ObjectKind, PolicyStatus, ProcessStatus, SavableKind, SkillStatus } from '../object-types.js';
4
+ import type { BriefStatus, DecisionStatus, IncidentStatus, NoteStatus, ObjectByKind, ObjectFields, ObjectKind, PolicyStatus, ProcessStatus, SavableKind, SkillStatus } from '../../core/object-types.js';
5
5
  interface HeadRow {
6
6
  id: number;
7
7
  memory_id: string | null;
@@ -1,4 +1,4 @@
1
- import type { BriefReceipt, Incident, ObjectByKind, ObjectKind, Policy, SavableKind, Skill } from '../object-types.js';
1
+ import type { BriefReceipt, Incident, ObjectByKind, ObjectKind, Policy, SavableKind, Skill } from '../../core/object-types.js';
2
2
  import { type IncidentOpen, type IncidentOpenRefusal, type IncidentResolve, type ObjectClose, type ObjectListQuery, type ObjectRefusal, type Objects, type ObjectSave, type PoliciesInForceQuery } from '../port.js';
3
3
  /** The group with each answer as its value; spelled out because `Sync<Objects>` would widen each method's kind to every kind. */
4
4
  export interface SyncObjects {
@@ -3,8 +3,9 @@ import { appendAuditEvent } from '../audit.js';
3
3
  import { getMeta, withWriteScopeOr } from '../../db/index.js';
4
4
  import { escapeLike } from '../../util/escape.js';
5
5
  import { keysetAfter } from '../../util/keyset.js';
6
+ import { chunked } from '../../util/chunked.js';
6
7
  import { calculateStrength, deriveHalfLife } from '../../core/memory.js';
7
- import { scopeAdmitSql } from '../recall-scope.js';
8
+ import { scopeAdmitSql } from '../rule-sql.js';
8
9
  import { stampOriginProject, upsertEntryRow } from '../entry-row.js';
9
10
  import { auditEntryWrite, writeEntryMirrors } from '../entry-writes.js';
10
11
  import { markGraphDirty } from '../graph-queue.js';
@@ -13,6 +14,7 @@ import { LEGACY_TYPED_HALF_LIFE, onHandle, openStore, TYPED_HALF_LIFE_META_KEY }
13
14
  import { isObjectRefusal, } from '../port.js';
14
15
  import { auditingRefusal } from './entry-writes-group.js';
15
16
  import { insertSpec, rowSpec } from './object-rows.js';
17
+ import { placeholders } from '../../util/sql.js';
16
18
  export function sqliteObjects(hippoRoot) {
17
19
  return {
18
20
  listObjects: (tenantId, kind, query) => onHandle(hippoRoot, (db) => listRows(db, tenantId, kind, query)),
@@ -80,7 +82,7 @@ function listRows(db, tenantId, kind, query) {
80
82
  function closeRow(db, tenantId, kind, id, close) {
81
83
  const spec = rowSpec(kind);
82
84
  return withWriteScopeOr(db, 'close_object', (rollback) => {
83
- const marks = close.from.map(() => '?').join(', ');
85
+ const marks = placeholders(close.from.length);
84
86
  const updated = db.prepare(`UPDATE ${spec.table} SET status = 'closed', closed_at = ? WHERE id = ? AND tenant_id = ? AND status IN (${marks})`).run(close.at, id, tenantId, ...close.from);
85
87
  if (updated.changes === 0) {
86
88
  const existing = db.prepare(`SELECT status FROM ${spec.table} WHERE id = ? AND tenant_id = ?`)
@@ -126,7 +128,7 @@ function insertRow(db, row) {
126
128
  }
127
129
  const result = db.prepare(`
128
130
  INSERT INTO ${rowSpec(row.kind).table}(${cols.join(', ')}, status, superseded_by, superseded_at, closed_at, created_at)
129
- VALUES (${cols.map(() => '?').join(', ')}, 'active', NULL, NULL, NULL, ?)
131
+ VALUES (${placeholders(cols.length)}, 'active', NULL, NULL, NULL, ?)
130
132
  `).run(...values, row.save.at);
131
133
  return Number(result.lastInsertRowid ?? 0);
132
134
  }
@@ -217,11 +219,17 @@ function saveAt(hippoRoot, tenantId, kind, save) {
217
219
  /** The linked ids are checked once the mirror is in and before the INSERT, so a refusal undoes the mirror with it. */
218
220
  function openIncidentRow(db, tenantId, memoryId, open) {
219
221
  const { incidentText, context, linkedMemoryIds } = open.fields;
220
- for (const linkId of linkedMemoryIds) {
221
- const held = db.prepare(`SELECT id FROM memories WHERE id = ? AND tenant_id = ?`).get(linkId, tenantId);
222
- if (!held)
223
- return { refused: 'unlinked', memoryId: linkId };
222
+ const held = new Set();
223
+ for (const ids of chunked(linkedMemoryIds)) {
224
+ const marks = placeholders(ids.length);
225
+ // SAFETY: rows' shape matches the one column named in the SELECT.
226
+ const found = db.prepare(`SELECT id FROM memories WHERE tenant_id = ? AND id IN (${marks})`).all(tenantId, ...ids);
227
+ for (const r of found)
228
+ held.add(r.id);
224
229
  }
230
+ const missing = linkedMemoryIds.find((linkId) => !held.has(linkId));
231
+ if (missing !== undefined)
232
+ return { refused: 'unlinked', memoryId: missing };
225
233
  const result = db.prepare(`
226
234
  INSERT INTO incidents(
227
235
  memory_id, tenant_id, incident_text, context,
@@ -1,4 +1,4 @@
1
- import type { HippoStore, RecallWrites, StoreGroups, Sync } from '../port.js';
1
+ import type { HippoStore, StoreGroups, Sync } from '../port.js';
2
2
  /** The store a request runs on: the served one, else hippo.db under its root, as the CLI and SDK callers have it. */
3
3
  export declare function storeFor(ctx: {
4
4
  readonly hippoRoot: string;
@@ -12,12 +12,5 @@ export type SqliteSyncStore = Sync<Omit<HippoStore, AsyncOnly>>;
12
12
  export declare function sqliteSyncStore(hippoRoot: string): SqliteSyncStore & Sync<Omit<StoreGroups, AsyncOnly>>;
13
13
  /** `sqliteSyncStore` as a served store: each method runs at once and answers through a Promise, so a throw rejects as another store's would. */
14
14
  export declare function sqliteStore(hippoRoot: string): HippoStore & StoreGroups;
15
- /** What a finished recall wrote after its audit rows: the trace's id, null when none was asked or its write failed, and the ids strengthened. */
16
- interface RecallFinish {
17
- readonly traceId: number | null;
18
- readonly strengthened: ReadonlySet<string>;
19
- }
20
- /** sqliteStore's finishRecall, for the synchronous recall that cannot await the port. */
21
- export declare function finishRecallAt(hippoRoot: string, writes: RecallWrites): RecallFinish;
22
15
  export {};
23
16
  //# sourceMappingURL=store.d.ts.map
@@ -4,17 +4,17 @@ import { listApiKeyRows, readApiKeyRecord } from '../auth.js';
4
4
  import { existsSync } from 'node:fs';
5
5
  import { appendAuditEvent, listAuditEventsAfter, queryAuditEvents } from '../audit.js';
6
6
  import { getHippoDbPath, withWriteScope } from '../../db/index.js';
7
- import { activeGoalsWithPolicies, localGoalRecallRows, writeGoalRecallLog } from '../goals.js';
7
+ import { activeGoalsWithPolicies } from '../goals.js';
8
8
  import { planningFallacyEvidenceAt } from '../planning-fallacy-evidence.js';
9
- import { writeRecallTrace } from '../recall-trace.js';
10
9
  import { recordTokenUse } from '../token-ledger.js';
11
10
  import { loadAmbientCandidates, loadContextCandidates } from '../candidates.js';
12
11
  import { loadEntriesByIds, loadFreshRawMemories } from '../entry-reads.js';
13
- import { strengthenRetrievedInOwnTx } from '../entry-writes.js';
14
12
  import { servedConnectorEvents, sqliteConnectorEvents } from './connector-events-group.js';
15
13
  import { servedConnectorWrites, sqliteConnectorWrites } from './connector-writes-group.js';
16
14
  import { sqliteDagReads } from './dag-reads-group.js';
17
15
  import { sqliteEntryWrites } from './entry-writes-group.js';
16
+ import { servedAuditMaintenance, servedLessonWrites, sqliteAuditMaintenance, sqliteLessonWrites } from './maintenance-groups.js';
17
+ import { finishRecallAt, servedLastRecall, sqliteLastRecall } from './last-recall-group.js';
18
18
  import { servedGraphReads, sqliteGraphReads } from './graph-reads-group.js';
19
19
  import { servedObjects, sqliteObjects } from './objects-group.js';
20
20
  import { servedPredictions, sqlitePredictions } from './predictions-group.js';
@@ -25,7 +25,7 @@ import { updateStats } from '../index-and-stats.js';
25
25
  import { auditHighIdAt, revokeKeyAt } from '../key-audit.js';
26
26
  import { createKeyAt, createSelfKeyAt } from '../key-writes.js';
27
27
  import { onHandle } from '../open.js';
28
- import { loadRecallSearchEntries } from '../search-rows.js';
28
+ import { loadRecallEntries } from '../search-rows.js';
29
29
  import { listSessionEvents, loadActiveTaskSnapshot } from '../sessions.js';
30
30
  import { entriesWithoutVectorAt, loadStoredVectorViews, writeVectorsAt } from '../vector-index.js';
31
31
  /** The store a request runs on: the served one, else hippo.db under its root, as the CLI and SDK callers have it. */
@@ -36,6 +36,7 @@ export function storeFor(ctx) {
36
36
  export function sqliteSyncStore(hippoRoot) {
37
37
  return {
38
38
  kind: 'sqlite',
39
+ localFiles: { hippoRoot },
39
40
  ...sqliteBaseReads(hippoRoot),
40
41
  ...sqliteRecallWrites(hippoRoot),
41
42
  keyAudit: sqliteKeyAudit(hippoRoot),
@@ -53,6 +54,9 @@ export function sqliteSyncStore(hippoRoot) {
53
54
  connectorEvents: sqliteConnectorEvents(hippoRoot),
54
55
  objects: sqliteObjects(hippoRoot),
55
56
  readiness: sqliteReadiness(hippoRoot),
57
+ lastRecall: sqliteLastRecall(hippoRoot),
58
+ auditMaintenance: sqliteAuditMaintenance(hippoRoot),
59
+ lessonWrites: sqliteLessonWrites(hippoRoot),
56
60
  close() { },
57
61
  };
58
62
  }
@@ -62,7 +66,7 @@ function sqliteBaseReads(hippoRoot) {
62
66
  return onHandle(hippoRoot, (db) => readApiKeyRecord(db, keyId));
63
67
  },
64
68
  searchRecallEntries(query, args) {
65
- return loadRecallSearchEntries(hippoRoot, query, args.limit, args.tenantId, args.requestedScope, args.explicitScopeMode, args.includeSuperseded, args.originProjects, args.ownScope);
69
+ return loadRecallEntries(hippoRoot, query, args);
66
70
  },
67
71
  entriesByIds(ids, tenantId) {
68
72
  return loadEntriesByIds(hippoRoot, ids, tenantId);
@@ -141,6 +145,7 @@ export function sqliteStore(hippoRoot) {
141
145
  const sync = sqliteSyncStore(hippoRoot);
142
146
  return {
143
147
  ...servedBaseMethods(sync),
148
+ localFiles: sync.localFiles,
144
149
  vectors: sqliteVectorReads(hippoRoot),
145
150
  vectorViews: { storedVectorViews: async (ids) => sync.vectorViews.storedVectorViews(ids) },
146
151
  ...servedKeyGroups(sync),
@@ -153,6 +158,9 @@ export function sqliteStore(hippoRoot) {
153
158
  connectorEvents: servedConnectorEvents(sync.connectorEvents),
154
159
  objects: servedObjects(sqliteObjects(hippoRoot)),
155
160
  readiness: { ping: async () => sync.readiness.ping() },
161
+ lastRecall: servedLastRecall(sync.lastRecall),
162
+ auditMaintenance: servedAuditMaintenance(sync.auditMaintenance),
163
+ lessonWrites: servedLessonWrites(sync.lessonWrites),
156
164
  close: async () => sync.close(),
157
165
  };
158
166
  }
@@ -274,21 +282,4 @@ function continuityAt(hippoRoot, tenantId, eventLimit, key) {
274
282
  recentSessionEvents: sessionId ? listSessionEvents(hippoRoot, tenantId, { session_id: sessionId, limit: eventLimit }) : [],
275
283
  };
276
284
  }
277
- /** sqliteStore's finishRecall, for the synchronous recall that cannot await the port. */
278
- export function finishRecallAt(hippoRoot, writes) {
279
- return onHandle(hippoRoot, (db) => {
280
- // With no row to write the scope would only take the write lock.
281
- if (writes.goalLog.length > 0 || writes.audit.length > 0) {
282
- withWriteScope(db, 'finish_recall', () => {
283
- writeGoalRecallLog(db, localGoalRecallRows(db, writes.goalLog));
284
- for (const event of writes.audit)
285
- appendAuditEvent(db, event);
286
- });
287
- }
288
- // Each opens its own transaction, so neither can share the scope above.
289
- const traceId = writes.trace ? writeRecallTrace(db, writes.trace) : null;
290
- const strengthened = writes.strengthen ? strengthenRetrievedInOwnTx(db, writes.strengthen.ids, writes.strengthen.opts) : new Set();
291
- return { traceId, strengthened };
292
- });
293
- }
294
285
  //# sourceMappingURL=store.js.map
@@ -2,11 +2,18 @@ import type { MemoryEntry } from '../core/memory.js';
2
2
  /** Host-wide loader for L2 topic summaries without an L3 parent, for consolidate phase 1.9 (buildEntityProfiles); SQL-level filter, since in-memory
3
3
  * `survivors` lacks L2s created by phase 1.7. Entries carry tenantId so per-cluster writes stay tenant-scoped. */
4
4
  export declare function loadAllL2Summaries(hippoRoot: string): MemoryEntry[];
5
- /** Dirty summaries across all tenants in one query, newest change first (latest_at DESC NULLS LAST, id ASC) so HIPPO_DAG_REBUILD_CAP takes the most
6
- * recently changed. Each entry carries its own tenantId so the children read and rebuild UPDATE stay tenant-scoped. */
7
- export declare function loadAllDirtySummaries(hippoRoot: string): MemoryEntry[];
5
+ /** Dirty summaries across all tenants, newest change first (latest_at DESC NULLS LAST, id ASC), at most `limit` (all when omitted)
6
+ * so HIPPO_DAG_REBUILD_CAP reads only the most recently changed. Each entry carries its tenantId so later writes stay tenant-scoped. */
7
+ export declare function loadAllDirtySummaries(hippoRoot: string, limit?: number): MemoryEntry[];
8
8
  /** Live (non-archived) children of a DAG summary, so a rebuild regenerates from the CURRENT child set; tenant-scoped as defence in depth. */
9
9
  export declare function loadChildrenOfSummary(hippoRoot: string, summaryId: string, tenantId: string): MemoryEntry[];
10
+ /** loadChildrenOfSummary for many summaries in one IN query per tenant chunk; the map key is `${tenantId}\u0000${summaryId}`, each list in created order. */
11
+ export declare function loadChildrenOfSummaries(hippoRoot: string, summaries: ReadonlyArray<{
12
+ id: string;
13
+ tenant_id: string;
14
+ }>): Map<string, MemoryEntry[]>;
15
+ /** Key into the map loadChildrenOfSummaries returns. */
16
+ export declare function childrenKey(tenantId: string, summaryId: string): string;
10
17
  /** Patch applied by applyRebuildResult; `bumpRebuildCount` is false for the zero-child case, true for a normal rebuild. */
11
18
  export interface RebuildPatch {
12
19
  content: string;
@@ -6,7 +6,9 @@ import { MEMORY_SELECT_COLUMNS, rowToEntry } from './rows.js';
6
6
  import { audit } from './audit-event.js';
7
7
  import { syncFtsRow } from './entry-row.js';
8
8
  import { onHandle, openStore } from './open.js';
9
+ import { chunked } from '../util/chunked.js';
9
10
  import { DIGEST_DISPLAY_CHARS } from '../util/token-text.js';
11
+ import { placeholders } from '../util/sql.js';
10
12
  // Sleep-cycle rebuild surface: lives here, not in src/consolidate/dag.ts, because it needs module-private MEMORY_SELECT_COLUMNS, MemoryRow, rowToEntry,
11
13
  // audit, syncFtsRow and assertTenantId. dag.ts keeps only the thin orchestrator rebuildDirtySummaries().
12
14
  /** Host-wide loader for L2 topic summaries without an L3 parent, for consolidate phase 1.9 (buildEntityProfiles); SQL-level filter, since in-memory
@@ -27,9 +29,9 @@ export function loadAllL2Summaries(hippoRoot) {
27
29
  return rows.map(rowToEntry);
28
30
  }, openStore);
29
31
  }
30
- /** Dirty summaries across all tenants in one query, newest change first (latest_at DESC NULLS LAST, id ASC) so HIPPO_DAG_REBUILD_CAP takes the most
31
- * recently changed. Each entry carries its own tenantId so the children read and rebuild UPDATE stay tenant-scoped. */
32
- export function loadAllDirtySummaries(hippoRoot) {
32
+ /** Dirty summaries across all tenants, newest change first (latest_at DESC NULLS LAST, id ASC), at most `limit` (all when omitted)
33
+ * so HIPPO_DAG_REBUILD_CAP reads only the most recently changed. Each entry carries its tenantId so later writes stay tenant-scoped. */
34
+ export function loadAllDirtySummaries(hippoRoot, limit) {
33
35
  return onHandle(hippoRoot, (db) => {
34
36
  // SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching
35
37
  // MemoryRow's field set.
@@ -39,7 +41,8 @@ export function loadAllDirtySummaries(hippoRoot) {
39
41
  WHERE summary_dirty = 1
40
42
  AND kind != 'archived'
41
43
  ORDER BY latest_at DESC NULLS LAST, id ASC
42
- `).all();
44
+ LIMIT ?
45
+ `).all(limit ?? -1);
43
46
  return rows.map(rowToEntry);
44
47
  }, openStore);
45
48
  }
@@ -61,10 +64,50 @@ export function loadChildrenOfSummary(hippoRoot, summaryId, tenantId) {
61
64
  return rows.map(rowToEntry);
62
65
  }, openStore);
63
66
  }
67
+ /** loadChildrenOfSummary for many summaries in one IN query per tenant chunk; the map key is `${tenantId}\u0000${summaryId}`, each list in created order. */
68
+ export function loadChildrenOfSummaries(hippoRoot, summaries) {
69
+ const byTenant = new Map();
70
+ for (const s of summaries) {
71
+ assertTenantId('loadChildrenOfSummaries', s.tenant_id);
72
+ const ids = byTenant.get(s.tenant_id) ?? [];
73
+ ids.push(s.id);
74
+ byTenant.set(s.tenant_id, ids);
75
+ }
76
+ const out = new Map();
77
+ onHandle(hippoRoot, (db) => {
78
+ for (const [tenantId, ids] of byTenant) {
79
+ for (const slice of chunked(ids)) {
80
+ // SAFETY: this query selects exactly MEMORY_SELECT_COLUMNS, matching MemoryRow's field set.
81
+ const rows = db.prepare(`
82
+ SELECT ${MEMORY_SELECT_COLUMNS}
83
+ FROM memories
84
+ WHERE dag_parent_id IN (${placeholders(slice.length)})
85
+ AND tenant_id = ?
86
+ AND kind != 'archived'
87
+ AND superseded_by IS NULL
88
+ ORDER BY created ASC
89
+ `).all(...slice, tenantId);
90
+ for (const entry of rows.map(rowToEntry)) {
91
+ const key = childrenKey(tenantId, entry.dag_parent_id ?? '');
92
+ const list = out.get(key);
93
+ if (list)
94
+ list.push(entry);
95
+ else
96
+ out.set(key, [entry]);
97
+ }
98
+ }
99
+ }
100
+ }, openStore);
101
+ return out;
102
+ }
103
+ /** Key into the map loadChildrenOfSummaries returns. */
104
+ export function childrenKey(tenantId, summaryId) {
105
+ return `${tenantId}\u0000${summaryId}`;
106
+ }
64
107
  /** Apply a rebuild result to a dirty summary in one write scope (UPDATE plus syncFtsRow); `AND summary_dirty = 1` makes a concurrent race-loser a no-op.
65
108
  * Returns `{ changed, refused }`: `refused` only when a tombstone hit suppressed the content write while the metadata UPDATE still landed. */
66
109
  export function applyRebuildResult(hippoRoot, summary, patch) {
67
- assertTenantId('applyRebuildResult', summary.tenantId);
110
+ assertTenantId('applyRebuildResult', summary.tenant_id);
68
111
  return onHandle(hippoRoot, (db) => {
69
112
  return withWriteScope(db, 'rebuild_summary', () => applyRebuildInSavepoint(db, summary, patch));
70
113
  }, openStore);
@@ -98,14 +141,14 @@ function applyRebuildInSavepoint(db, summary, patch) {
98
141
  // Check tombstones before choosing the UPDATE: this direct UPDATE bypasses upsertEntryRow's guard, and
99
142
  // a deterministic rebuild would otherwise re-assert a rejected value every sleep cycle.
100
143
  const tombstone = patch.bumpRebuildCount
101
- ? findRejectedValue(db, summary.tenantId, rejectionDigest(patch.content))
144
+ ? findRejectedValue(db, summary.tenant_id, rejectionDigest(patch.content))
102
145
  : null;
103
146
  // On a tombstone hit, write no content: take the zero-child metadata-only path (descendant_count/earliest_at/latest_at, summary_dirty cleared, no
104
147
  // rebuild_count bump). Clearing dirty is deliberate: leaving it set would make every later sleep re-attempt and re-refuse the same rebuild forever.
105
148
  const applyContentWrite = patch.bumpRebuildCount && !tombstone;
106
149
  const result = applyContentWrite
107
- ? db.prepare(REBUILD_CONTENT_SQL).run(patch.content, patch.descendant_count, patch.earliest_at, patch.latest_at, nowIso, summary.id, summary.tenantId)
108
- : db.prepare(REBUILD_METADATA_SQL).run(patch.descendant_count, patch.earliest_at, patch.latest_at, summary.id, summary.tenantId);
150
+ ? db.prepare(REBUILD_CONTENT_SQL).run(patch.content, patch.descendant_count, patch.earliest_at, patch.latest_at, nowIso, summary.id, summary.tenant_id)
151
+ : db.prepare(REBUILD_METADATA_SQL).run(patch.descendant_count, patch.earliest_at, patch.latest_at, summary.id, summary.tenant_id);
109
152
  // `changed` means THIS call's UPDATE hit a row, so a refusal still settles the cycle (false would retry
110
153
  // the doomed rebuild forever); `refused` lets the caller count it as refused rather than rebuilt.
111
154
  const changed = (result.changes ?? 0) > 0;
@@ -124,7 +167,7 @@ function auditRefusedRebuild(db, summary, patch, tombstone) {
124
167
  targetId: summary.id,
125
168
  metadata: { digest: tombstone.digest, reason: tombstone.reason },
126
169
  actor: patch.actor,
127
- tenantId: summary.tenantId
170
+ tenantId: summary.tenant_id
128
171
  });
129
172
  log.warn(`applyRebuildResult: refused rebuild content for ${summary.id} — matches a rejected value ` +
130
173
  `(digest ${tombstone.digest.slice(0, DIGEST_DISPLAY_CHARS)}...); metadata updated, content unchanged`);
@@ -138,7 +181,7 @@ function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
138
181
  descendant_count: patch.descendant_count,
139
182
  earliest_at: patch.earliest_at,
140
183
  latest_at: patch.latest_at,
141
- summary_dirty: 0,
184
+ summary_dirty: false,
142
185
  last_rebuilt_at: applyContentWrite ? nowIso : summary.last_rebuilt_at,
143
186
  rebuild_count: applyContentWrite
144
187
  ? (summary.rebuild_count ?? 0) + 1
@@ -151,7 +194,7 @@ function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
151
194
  source: 'E3-rebuild',
152
195
  zero_children: patch.zeroChildren,
153
196
  descendant_count: patch.descendant_count,
154
- }, actor: patch.actor, tenantId: summary.tenantId });
197
+ }, actor: patch.actor, tenantId: summary.tenant_id });
155
198
  }
156
199
  /** Clear summary_dirty on a new summary after buildDag's child-link loop (each member's writeEntry marks the parent dirty, so the same cycle would rebuild it).
157
200
  * Idempotent (no-op, no audit if not dirty); audit source='buildDag-clean' distinguishes it from the rebuild's. */
@@ -1,3 +1,4 @@
1
+ import { placeholders } from '../util/sql.js';
1
2
  export function insertTokenRow(db, row) {
2
3
  db.prepare(`INSERT INTO token_ledger (ts, tenant_id, session_id, surface, event, items, tokens, block_hash)
3
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(row.ts, row.tenantId, row.sessionId, row.surface, row.event, row.items, row.tokens, row.blockHash);
@@ -34,7 +35,7 @@ export function surfaceTotals(db, tenantId, sinceIso) {
34
35
  export function sessionTotals(db, tenantId, sinceIso, rereadSurfaces) {
35
36
  // SAFETY: the SELECT names exactly these four aggregate columns.
36
37
  return db.prepare(`SELECT COUNT(DISTINCT session_id) AS sessions,
37
- COUNT(DISTINCT CASE WHEN event <> 'reset' AND surface IN (${rereadSurfaces.map(() => '?').join(', ')}) THEN session_id END) AS hook_sessions,
38
+ COUNT(DISTINCT CASE WHEN event <> 'reset' AND surface IN (${placeholders(rereadSurfaces.length)}) THEN session_id END) AS hook_sessions,
38
39
  COUNT(DISTINCT CASE WHEN event = 'reread' THEN session_id END) AS reread_sessions,
39
40
  SUM(CASE WHEN event = 'inject' THEN tokens ELSE 0 END) AS tokens
40
41
  FROM token_ledger
@@ -53,7 +54,7 @@ export function sessionTokenRows(db, tenantId, sinceIso) {
53
54
  export function injectedBlocks(db, tenantId, sessionId, surfaces) {
54
55
  // SAFETY: the SELECT names exactly these three columns.
55
56
  return db.prepare(`SELECT ts, surface, tokens FROM token_ledger
56
- WHERE tenant_id = ? AND session_id = ? AND event = 'inject' AND surface IN (${surfaces.map(() => '?').join(', ')})`).all(tenantId, sessionId, ...surfaces);
57
+ WHERE tenant_id = ? AND session_id = ? AND event = 'inject' AND surface IN (${placeholders(surfaces.length)})`).all(tenantId, sessionId, ...surfaces);
57
58
  }
58
59
  export function deleteRereadRows(db, tenantId, sessionId) {
59
60
  db.prepare(`DELETE FROM token_ledger WHERE tenant_id = ? AND session_id = ? AND event = 'reread'`).run(tenantId, sessionId);