hippo-memory 1.70.0 → 1.71.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 (629) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/claude-code.d.ts +4 -2
  3. package/dist/agent-memories/claude-code.js +14 -5
  4. package/dist/agent-memories/files.js +23 -12
  5. package/dist/agent-memories/markdown.d.ts +1 -3
  6. package/dist/agent-memories/markdown.js +1 -3
  7. package/dist/agent-memories/report.js +2 -1
  8. package/dist/agent-memories/sync.d.ts +4 -2
  9. package/dist/agent-memories/sync.js +10 -5
  10. package/dist/api/assemble.d.ts +7 -44
  11. package/dist/api/assemble.js +2 -22
  12. package/dist/api/audit.d.ts +5 -1
  13. package/dist/api/audit.js +9 -1
  14. package/dist/api/auth.d.ts +13 -22
  15. package/dist/api/auth.js +34 -24
  16. package/dist/api/auto-sleep.js +2 -2
  17. package/dist/api/availability.d.ts +2 -15
  18. package/dist/api/availability.js +2 -15
  19. package/dist/api/context-select.js +3 -4
  20. package/dist/api/context-types.d.ts +10 -35
  21. package/dist/api/context.d.ts +5 -22
  22. package/dist/api/context.js +21 -38
  23. package/dist/api/dormant.d.ts +5 -21
  24. package/dist/api/dormant.js +7 -26
  25. package/dist/api/drill-down.d.ts +7 -46
  26. package/dist/api/drill-down.js +5 -26
  27. package/dist/api/forget.d.ts +5 -24
  28. package/dist/api/forget.js +5 -28
  29. package/dist/api/graph.d.ts +8 -0
  30. package/dist/api/graph.js +7 -0
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.js +2 -0
  33. package/dist/api/instruction-detect.js +16 -5
  34. package/dist/api/ledger-db.d.ts +2 -1
  35. package/dist/api/ledger-db.js +5 -3
  36. package/dist/api/memories.d.ts +5 -0
  37. package/dist/api/memories.js +7 -0
  38. package/dist/api/objects.d.ts +9 -0
  39. package/dist/api/objects.js +11 -0
  40. package/dist/api/on-store.js +5 -3
  41. package/dist/api/predictions.d.ts +9 -0
  42. package/dist/api/predictions.js +18 -0
  43. package/dist/api/promote.d.ts +13 -17
  44. package/dist/api/promote.js +11 -19
  45. package/dist/api/prompt-hook.d.ts +4 -4
  46. package/dist/api/prompt-hook.js +10 -9
  47. package/dist/api/recall-cli.d.ts +55 -0
  48. package/dist/api/recall-cli.js +94 -0
  49. package/dist/api/recall-core.js +14 -6
  50. package/dist/api/recall-finish.d.ts +53 -0
  51. package/dist/api/recall-finish.js +30 -0
  52. package/dist/api/recall-history.d.ts +17 -84
  53. package/dist/api/recall-history.js +15 -88
  54. package/dist/api/recall-pipeline.d.ts +2 -3
  55. package/dist/api/recall-pipeline.js +16 -9
  56. package/dist/api/recall-types.d.ts +64 -304
  57. package/dist/api/recall.d.ts +5 -33
  58. package/dist/api/recall.js +59 -60
  59. package/dist/api/refine.d.ts +7 -0
  60. package/dist/api/refine.js +10 -0
  61. package/dist/api/remember-local.d.ts +57 -0
  62. package/dist/api/remember-local.js +90 -0
  63. package/dist/api/remember.d.ts +18 -1
  64. package/dist/api/remember.js +13 -1
  65. package/dist/api/sleep-run.d.ts +1 -3
  66. package/dist/api/sleep-run.js +17 -21
  67. package/dist/api/sleep.d.ts +9 -28
  68. package/dist/api/tokens.d.ts +3 -10
  69. package/dist/api/tokens.js +3 -10
  70. package/dist/api/types.d.ts +6 -29
  71. package/dist/api/types.js +4 -22
  72. package/dist/capture/command.d.ts +4 -12
  73. package/dist/capture/command.js +6 -22
  74. package/dist/capture/compact.d.ts +4 -15
  75. package/dist/capture/compact.js +16 -25
  76. package/dist/capture/compaction-record.js +101 -69
  77. package/dist/capture/compaction-spool.d.ts +1 -1
  78. package/dist/capture/compaction-spool.js +1 -1
  79. package/dist/capture/session-digest.d.ts +1 -1
  80. package/dist/capture/session-digest.js +13 -7
  81. package/dist/capture/transcript.d.ts +2 -10
  82. package/dist/capture/transcript.js +4 -18
  83. package/dist/cli/api-context.d.ts +3 -0
  84. package/dist/cli/api-context.js +6 -0
  85. package/dist/cli/audit-prune.d.ts +6 -39
  86. package/dist/cli/audit-prune.js +6 -39
  87. package/dist/cli/audit.d.ts +1 -1
  88. package/dist/cli/audit.js +33 -34
  89. package/dist/cli/auth.d.ts +2 -2
  90. package/dist/cli/auth.js +57 -39
  91. package/dist/cli/briefs.d.ts +4 -4
  92. package/dist/cli/briefs.js +18 -22
  93. package/dist/cli/card.d.ts +2 -2
  94. package/dist/cli/card.js +31 -32
  95. package/dist/cli/client.d.ts +7 -27
  96. package/dist/cli/client.js +24 -43
  97. package/dist/cli/compact-resume-payload.js +3 -2
  98. package/dist/cli/context.d.ts +1 -2
  99. package/dist/cli/context.js +12 -8
  100. package/dist/cli/continuity.d.ts +6 -6
  101. package/dist/cli/continuity.js +62 -64
  102. package/dist/cli/correction-latency.d.ts +2 -14
  103. package/dist/cli/correction-latency.js +2 -14
  104. package/dist/cli/curate.d.ts +13 -17
  105. package/dist/cli/curate.js +68 -92
  106. package/dist/cli/dag.d.ts +4 -4
  107. package/dist/cli/dag.js +33 -27
  108. package/dist/cli/decisions.d.ts +4 -4
  109. package/dist/cli/decisions.js +33 -47
  110. package/dist/cli/eval.js +15 -13
  111. package/dist/cli/exit.d.ts +6 -0
  112. package/dist/cli/exit.js +11 -0
  113. package/dist/cli/explain.d.ts +1 -2
  114. package/dist/cli/explain.js +6 -4
  115. package/dist/cli/flag-values.d.ts +6 -1
  116. package/dist/cli/flag-values.js +27 -10
  117. package/dist/cli/flags.d.ts +1 -0
  118. package/dist/cli/flags.js +1 -1
  119. package/dist/cli/github.d.ts +14 -0
  120. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  121. package/dist/cli/goals.d.ts +2 -2
  122. package/dist/cli/goals.js +46 -50
  123. package/dist/cli/hook-runtime.d.ts +9 -27
  124. package/dist/cli/hook-runtime.js +15 -31
  125. package/dist/cli/init.d.ts +2 -2
  126. package/dist/cli/init.js +6 -12
  127. package/dist/cli/install-steps.js +3 -12
  128. package/dist/cli/last-sleep.d.ts +2 -1
  129. package/dist/cli/last-sleep.js +3 -0
  130. package/dist/cli/maintenance.d.ts +4 -4
  131. package/dist/cli/maintenance.js +14 -19
  132. package/dist/cli/object-verbs.js +4 -3
  133. package/dist/cli/owner-validation.d.ts +5 -28
  134. package/dist/cli/owner-validation.js +5 -28
  135. package/dist/cli/playbooks.d.ts +4 -4
  136. package/dist/cli/playbooks.js +23 -28
  137. package/dist/cli/print.d.ts +2 -5
  138. package/dist/cli/print.js +1 -4
  139. package/dist/cli/projects.d.ts +2 -2
  140. package/dist/cli/projects.js +1 -3
  141. package/dist/cli/provenance-coverage.d.ts +2 -6
  142. package/dist/cli/provenance-coverage.js +2 -6
  143. package/dist/cli/quality-repair-once.js +2 -2
  144. package/dist/cli/recall.d.ts +2 -4
  145. package/dist/cli/recall.js +55 -131
  146. package/dist/cli/refine-llm.d.ts +5 -31
  147. package/dist/cli/refine-llm.js +9 -36
  148. package/dist/cli/remember.d.ts +3 -3
  149. package/dist/cli/remember.js +122 -180
  150. package/dist/cli/scheduler.d.ts +2 -17
  151. package/dist/cli/scheduler.js +12 -18
  152. package/dist/cli/serve.js +21 -12
  153. package/dist/cli/session-hooks.d.ts +10 -18
  154. package/dist/cli/session-hooks.js +112 -113
  155. package/dist/cli/setup.d.ts +4 -4
  156. package/dist/cli/setup.js +19 -21
  157. package/dist/cli/shared.d.ts +9 -23
  158. package/dist/cli/shared.js +9 -32
  159. package/dist/cli/slack.d.ts +2 -2
  160. package/dist/cli/slack.js +19 -23
  161. package/dist/cli/sleep.d.ts +3 -2
  162. package/dist/cli/sleep.js +15 -16
  163. package/dist/cli/status.d.ts +9 -12
  164. package/dist/cli/status.js +55 -98
  165. package/dist/cli/stdin.d.ts +4 -6
  166. package/dist/cli/stdin.js +2 -3
  167. package/dist/cli/transfer.d.ts +9 -9
  168. package/dist/cli/transfer.js +66 -89
  169. package/dist/cli/usage.js +11 -5
  170. package/dist/cli.d.ts +66 -448
  171. package/dist/cli.js +87 -263
  172. package/dist/connectors/github/backfill.d.ts +5 -25
  173. package/dist/connectors/github/backfill.js +14 -49
  174. package/dist/connectors/github/deletion.d.ts +4 -18
  175. package/dist/connectors/github/deletion.js +2 -15
  176. package/dist/connectors/github/dlq.d.ts +8 -33
  177. package/dist/connectors/github/dlq.js +12 -29
  178. package/dist/connectors/github/ingest.d.ts +2 -6
  179. package/dist/connectors/github/ingest.js +4 -10
  180. package/dist/connectors/github/octokit-client.d.ts +4 -16
  181. package/dist/connectors/github/octokit-client.js +27 -24
  182. package/dist/connectors/github/ratelimit.d.ts +3 -14
  183. package/dist/connectors/github/ratelimit.js +3 -14
  184. package/dist/connectors/github/scope.d.ts +3 -5
  185. package/dist/connectors/github/scope.js +3 -5
  186. package/dist/connectors/github/signature.d.ts +4 -26
  187. package/dist/connectors/github/signature.js +4 -26
  188. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  189. package/dist/connectors/github/tenant-routing.js +4 -26
  190. package/dist/connectors/github/transform.js +2 -16
  191. package/dist/connectors/github/types.d.ts +3 -15
  192. package/dist/connectors/github/types.js +2 -9
  193. package/dist/connectors/github/webhook.d.ts +2 -16
  194. package/dist/connectors/github/webhook.js +6 -22
  195. package/dist/connectors/slack/backfill.d.ts +4 -17
  196. package/dist/connectors/slack/backfill.js +4 -13
  197. package/dist/connectors/slack/dlq.d.ts +2 -19
  198. package/dist/connectors/slack/dlq.js +2 -19
  199. package/dist/connectors/slack/ingest.d.ts +2 -3
  200. package/dist/connectors/slack/ingest.js +2 -3
  201. package/dist/connectors/slack/scope.d.ts +2 -8
  202. package/dist/connectors/slack/scope.js +2 -8
  203. package/dist/connectors/slack/signature.d.ts +1 -6
  204. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  205. package/dist/connectors/slack/tenant-routing.js +2 -21
  206. package/dist/connectors/slack/transform.d.ts +2 -18
  207. package/dist/connectors/slack/transform.js +2 -18
  208. package/dist/connectors/slack/types.d.ts +3 -9
  209. package/dist/connectors/slack/types.js +2 -4
  210. package/dist/connectors/slack/web-client.js +33 -27
  211. package/dist/connectors/slack/webhook.d.ts +2 -19
  212. package/dist/connectors/slack/webhook.js +5 -26
  213. package/dist/connectors/slack/workspaces.d.ts +4 -24
  214. package/dist/connectors/slack/workspaces.js +4 -24
  215. package/dist/consolidate/conflicts.js +6 -14
  216. package/dist/consolidate/dag-summary.d.ts +8 -0
  217. package/dist/consolidate/dag-summary.js +41 -0
  218. package/dist/consolidate/dag.d.ts +5 -28
  219. package/dist/consolidate/dag.js +14 -75
  220. package/dist/consolidate/decay.js +7 -19
  221. package/dist/consolidate/dedupe.d.ts +6 -52
  222. package/dist/consolidate/dedupe.js +13 -71
  223. package/dist/consolidate/flush-units.d.ts +3 -4
  224. package/dist/consolidate/flush-units.js +3 -3
  225. package/dist/consolidate/half-life-migration.d.ts +3 -26
  226. package/dist/consolidate/half-life-migration.js +11 -28
  227. package/dist/consolidate/llm-passes.js +4 -21
  228. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  229. package/dist/consolidate/memory-value-weights.js +2 -13
  230. package/dist/consolidate/memory-value.d.ts +11 -84
  231. package/dist/consolidate/memory-value.js +16 -104
  232. package/dist/consolidate/merge.js +10 -31
  233. package/dist/consolidate/merged-row.js +2 -1
  234. package/dist/consolidate/physics-pass.js +1 -3
  235. package/dist/consolidate/replay.d.ts +6 -38
  236. package/dist/consolidate/replay.js +14 -52
  237. package/dist/consolidate/run.js +1 -1
  238. package/dist/consolidate/sleep.d.ts +1 -8
  239. package/dist/consolidate/sleep.js +5 -17
  240. package/dist/consolidate/trace.d.ts +3 -18
  241. package/dist/consolidate/trace.js +3 -18
  242. package/dist/consolidate/traces.js +6 -22
  243. package/dist/core/ablation.d.ts +4 -91
  244. package/dist/core/ablation.js +4 -91
  245. package/dist/core/ambient.d.ts +1 -8
  246. package/dist/core/ambient.js +1 -8
  247. package/dist/core/capture-contract.d.ts +4 -2
  248. package/dist/core/capture-contract.js +4 -2
  249. package/dist/core/card.d.ts +4 -1
  250. package/dist/core/card.js +8 -0
  251. package/dist/core/compare.d.ts +11 -67
  252. package/dist/core/compare.js +9 -63
  253. package/dist/core/config.d.ts +10 -24
  254. package/dist/core/config.js +13 -14
  255. package/dist/core/handoff.d.ts +1 -7
  256. package/dist/core/handoff.js +1 -7
  257. package/dist/core/memory-quality.js +1 -1
  258. package/dist/core/memory.d.ts +41 -164
  259. package/dist/core/memory.js +51 -221
  260. package/dist/core/package-root.d.ts +3 -0
  261. package/dist/core/package-root.js +5 -0
  262. package/dist/core/physics-config.d.ts +1 -4
  263. package/dist/core/physics-config.js +3 -8
  264. package/dist/core/physics.d.ts +15 -61
  265. package/dist/core/physics.js +59 -122
  266. package/dist/core/project-identity.d.ts +17 -58
  267. package/dist/core/project-identity.js +17 -38
  268. package/dist/core/project-remote.js +13 -2
  269. package/dist/core/raw-append-only.d.ts +5 -0
  270. package/dist/core/raw-append-only.js +7 -0
  271. package/dist/core/salience.d.ts +1 -7
  272. package/dist/core/salience.js +1 -7
  273. package/dist/dashboard/dashboard-actions.js +2 -2
  274. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  275. package/dist/dashboard/dashboard-snapshot.js +11 -2
  276. package/dist/dashboard/dashboard-types.d.ts +2 -1
  277. package/dist/dashboard/dashboard.d.ts +1 -0
  278. package/dist/dashboard/dashboard.js +50 -4
  279. package/dist/db/busy.d.ts +1 -1
  280. package/dist/db/busy.js +17 -8
  281. package/dist/db/connect.d.ts +1 -0
  282. package/dist/db/connect.js +3 -3
  283. package/dist/db/migrate.js +3 -3
  284. package/dist/db/migrations/types.d.ts +2 -5
  285. package/dist/db/migrations/v14.js +2 -3
  286. package/dist/db/migrations/v15.js +2 -8
  287. package/dist/db/migrations/v16.js +2 -3
  288. package/dist/db/migrations/v17.js +2 -3
  289. package/dist/db/migrations/v19.js +2 -5
  290. package/dist/db/migrations/v20.js +2 -7
  291. package/dist/db/migrations/v22.js +4 -17
  292. package/dist/db/migrations/v23.js +3 -14
  293. package/dist/db/migrations/v24.js +2 -4
  294. package/dist/db/migrations/v25.js +3 -8
  295. package/dist/db/migrations/v26.js +2 -13
  296. package/dist/db/migrations/v27.js +3 -11
  297. package/dist/db/migrations/v28.js +2 -14
  298. package/dist/db/migrations/v29.js +4 -18
  299. package/dist/db/migrations/v30.js +4 -16
  300. package/dist/db/migrations/v31.js +2 -15
  301. package/dist/db/migrations/v32.js +4 -22
  302. package/dist/db/migrations/v33.js +2 -15
  303. package/dist/db/migrations/v34.js +2 -11
  304. package/dist/db/migrations/v35.js +2 -11
  305. package/dist/db/migrations/v36.js +2 -11
  306. package/dist/db/migrations/v37.js +8 -33
  307. package/dist/db/migrations/v38.js +5 -38
  308. package/dist/db/migrations/v39.js +9 -20
  309. package/dist/db/migrations/v40.js +2 -9
  310. package/dist/db/migrations/v41.js +2 -24
  311. package/dist/db/migrations/v43.js +1 -1
  312. package/dist/db/migrations/v44.js +2 -8
  313. package/dist/db/migrations/v45.js +2 -7
  314. package/dist/db/migrations/v47.js +2 -3
  315. package/dist/db/migrations/v51.js +1 -1
  316. package/dist/db/open.d.ts +2 -0
  317. package/dist/db/open.js +17 -1
  318. package/dist/db/physics-state.d.ts +6 -22
  319. package/dist/db/physics-state.js +25 -36
  320. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  321. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  322. package/dist/db/vector-store.d.ts +2 -0
  323. package/dist/db/vector-store.js +8 -1
  324. package/dist/doctor.js +74 -19
  325. package/dist/entry/session-text.js +2 -1
  326. package/dist/eval/eval-stats.d.ts +15 -53
  327. package/dist/eval/eval-stats.js +12 -42
  328. package/dist/eval/eval-suite.d.ts +2 -13
  329. package/dist/eval/eval-suite.js +74 -34
  330. package/dist/eval/eval.d.ts +6 -24
  331. package/dist/eval/eval.js +7 -34
  332. package/dist/eval/judgment.d.ts +0 -3
  333. package/dist/eval/judgment.js +19 -11
  334. package/dist/extensions/openclaw-plugin/index.js +1 -1
  335. package/dist/graph/extract.d.ts +5 -27
  336. package/dist/graph/extract.js +7 -33
  337. package/dist/graph/recall.d.ts +7 -20
  338. package/dist/graph/recall.js +14 -76
  339. package/dist/graph/stream.d.ts +7 -39
  340. package/dist/graph/stream.js +11 -34
  341. package/dist/graph/view.d.ts +9 -35
  342. package/dist/graph/view.js +11 -39
  343. package/dist/hooks/codex-wrapper.js +2 -2
  344. package/dist/hooks/copilot.js +2 -1
  345. package/dist/hooks/hook-blocks.d.ts +6 -2
  346. package/dist/hooks/hook-blocks.js +37 -124
  347. package/dist/hooks/json-hooks.d.ts +4 -36
  348. package/dist/hooks/json-hooks.js +18 -57
  349. package/dist/hooks/opencode.d.ts +0 -38
  350. package/dist/hooks/opencode.js +9 -76
  351. package/dist/hooks/shared.d.ts +8 -17
  352. package/dist/hooks/shared.js +29 -20
  353. package/dist/importers/core.d.ts +12 -37
  354. package/dist/importers/core.js +9 -27
  355. package/dist/importers/markdown-parse.d.ts +8 -22
  356. package/dist/importers/markdown-parse.js +8 -25
  357. package/dist/importers/markdown.js +3 -12
  358. package/dist/importers/sources.js +7 -35
  359. package/dist/importers/vault.d.ts +2 -8
  360. package/dist/importers/vault.js +25 -81
  361. package/dist/index.d.ts +6 -2
  362. package/dist/index.js +6 -2
  363. package/dist/learn/autolearn.d.ts +14 -41
  364. package/dist/learn/autolearn.js +14 -41
  365. package/dist/learn/extract.js +2 -4
  366. package/dist/learn/forward-claim-detector.d.ts +6 -30
  367. package/dist/learn/forward-claim-detector.js +14 -66
  368. package/dist/learn/invalidation.d.ts +6 -18
  369. package/dist/learn/invalidation.js +9 -26
  370. package/dist/mcp/admin-tools.js +3 -5
  371. package/dist/mcp/memory-tools.js +4 -9
  372. package/dist/mcp/protocol.d.ts +8 -26
  373. package/dist/mcp/protocol.js +3 -6
  374. package/dist/mcp/recall-tools.js +3 -3
  375. package/dist/mcp/request.d.ts +3 -11
  376. package/dist/mcp/request.js +10 -26
  377. package/dist/mcp/server.d.ts +3 -9
  378. package/dist/mcp/server.js +5 -16
  379. package/dist/mcp/session-state.d.ts +1 -1
  380. package/dist/mcp/session-state.js +5 -11
  381. package/dist/mcp/stdio.d.ts +2 -6
  382. package/dist/mcp/stdio.js +48 -12
  383. package/dist/mcp/tools.js +5 -3
  384. package/dist/objects/customer-notes.d.ts +7 -42
  385. package/dist/objects/customer-notes.js +7 -48
  386. package/dist/objects/decisions.d.ts +12 -50
  387. package/dist/objects/decisions.js +15 -53
  388. package/dist/objects/incidents.d.ts +7 -38
  389. package/dist/objects/incidents.js +7 -41
  390. package/dist/objects/policies.d.ts +11 -89
  391. package/dist/objects/policies.js +11 -98
  392. package/dist/objects/processes.d.ts +7 -52
  393. package/dist/objects/processes.js +7 -61
  394. package/dist/objects/project-briefs.d.ts +11 -55
  395. package/dist/objects/project-briefs.js +14 -75
  396. package/dist/objects/skills.d.ts +7 -42
  397. package/dist/objects/skills.js +8 -54
  398. package/dist/postinstall.js +6 -19
  399. package/dist/predictions/planning-fallacy.d.ts +11 -34
  400. package/dist/rerankers/clef.js +3 -31
  401. package/dist/rerankers/cross-encoder.js +4 -6
  402. package/dist/rerankers/jev.js +9 -6
  403. package/dist/rerankers/llm.d.ts +2 -11
  404. package/dist/rerankers/llm.js +14 -14
  405. package/dist/rerankers/outage-warning.d.ts +2 -1
  406. package/dist/rerankers/outage-warning.js +2 -1
  407. package/dist/rerankers/remote.d.ts +1 -0
  408. package/dist/rerankers/remote.js +2 -0
  409. package/dist/rerankers/types.d.ts +2 -14
  410. package/dist/search/boosts.d.ts +0 -2
  411. package/dist/search/boosts.js +2 -2
  412. package/dist/search/goal-boost.d.ts +23 -0
  413. package/dist/search/goal-boost.js +90 -0
  414. package/dist/search/hybrid.d.ts +2 -0
  415. package/dist/search/multihop.js +2 -3
  416. package/dist/search/path-context.d.ts +5 -18
  417. package/dist/search/path-context.js +5 -18
  418. package/dist/search/physics-search.js +11 -8
  419. package/dist/search/rrf.d.ts +7 -35
  420. package/dist/search/rrf.js +5 -30
  421. package/dist/search/vector.d.ts +7 -0
  422. package/dist/search/vector.js +35 -5
  423. package/dist/server/auth.d.ts +9 -28
  424. package/dist/server/auth.js +32 -25
  425. package/dist/server/boot.d.ts +2 -21
  426. package/dist/server/boot.js +63 -96
  427. package/dist/server/client-ip.d.ts +3 -19
  428. package/dist/server/client-ip.js +5 -28
  429. package/dist/server/defaults.d.ts +3 -0
  430. package/dist/server/defaults.js +4 -0
  431. package/dist/server/key-check-bounds.d.ts +2 -1
  432. package/dist/server/lifecycle.d.ts +5 -4
  433. package/dist/server/lifecycle.js +19 -4
  434. package/dist/server/mcp-http.js +10 -44
  435. package/dist/server/rate-limit.d.ts +5 -18
  436. package/dist/server/rate-limit.js +4 -13
  437. package/dist/server/request.d.ts +4 -8
  438. package/dist/server/request.js +9 -17
  439. package/dist/server/route-table.js +42 -49
  440. package/dist/server/routes/admin.js +22 -28
  441. package/dist/server/routes/customer-notes.js +7 -12
  442. package/dist/server/routes/decisions.js +10 -17
  443. package/dist/server/routes/incidents.js +12 -20
  444. package/dist/server/routes/memories.js +12 -32
  445. package/dist/server/routes/object-routes.d.ts +0 -5
  446. package/dist/server/routes/object-routes.js +7 -15
  447. package/dist/server/routes/policies.js +10 -18
  448. package/dist/server/routes/predictions.js +13 -25
  449. package/dist/server/routes/processes.js +16 -26
  450. package/dist/server/routes/project-briefs.js +9 -16
  451. package/dist/server/routes/recall.js +10 -35
  452. package/dist/server/routes/skills.js +8 -18
  453. package/dist/server/server-detect.d.ts +9 -53
  454. package/dist/server/server-detect.js +24 -90
  455. package/dist/server/sleep-offload.js +4 -1
  456. package/dist/server/types.d.ts +12 -10
  457. package/dist/server/validation.d.ts +3 -1
  458. package/dist/server/validation.js +10 -23
  459. package/dist/server.d.ts +2 -2
  460. package/dist/server.js +3 -2
  461. package/dist/sharing/global-store.d.ts +19 -0
  462. package/dist/sharing/global-store.js +75 -0
  463. package/dist/sharing/global-sync.d.ts +6 -0
  464. package/dist/sharing/global-sync.js +80 -0
  465. package/dist/sharing/project-merge.d.ts +4 -5
  466. package/dist/sharing/project-merge.js +9 -7
  467. package/dist/sharing/scope.d.ts +4 -11
  468. package/dist/sharing/scope.js +4 -11
  469. package/dist/sharing/search-both.d.ts +60 -0
  470. package/dist/sharing/search-both.js +138 -0
  471. package/dist/sharing/share.d.ts +38 -0
  472. package/dist/sharing/share.js +226 -0
  473. package/dist/store/ambient.js +4 -9
  474. package/dist/store/audit-event.d.ts +4 -12
  475. package/dist/store/audit-event.js +4 -12
  476. package/dist/store/audit.d.ts +2 -5
  477. package/dist/store/audit.js +4 -12
  478. package/dist/store/auth.d.ts +6 -6
  479. package/dist/store/auth.js +10 -9
  480. package/dist/store/candidates.d.ts +20 -3
  481. package/dist/store/candidates.js +77 -48
  482. package/dist/store/card-detail.d.ts +2 -1
  483. package/dist/store/card-detail.js +2 -1
  484. package/dist/store/cards.d.ts +14 -9
  485. package/dist/store/cards.js +72 -126
  486. package/dist/store/conflicts.d.ts +4 -21
  487. package/dist/store/conflicts.js +71 -150
  488. package/dist/store/connectors/github.d.ts +10 -10
  489. package/dist/store/connectors/github.js +10 -10
  490. package/dist/store/dashboard-reads.js +4 -8
  491. package/dist/store/delete-and-batch.d.ts +11 -31
  492. package/dist/store/delete-and-batch.js +48 -64
  493. package/dist/store/delivery-recorder.d.ts +8 -4
  494. package/dist/store/delivery-recorder.js +25 -15
  495. package/dist/store/diagnostics.js +6 -13
  496. package/dist/store/dormant.d.ts +7 -29
  497. package/dist/store/dormant.js +15 -56
  498. package/dist/store/embeddings/index.d.ts +11 -80
  499. package/dist/store/embeddings/index.js +71 -207
  500. package/dist/store/embeddings/local.js +15 -32
  501. package/dist/store/embeddings/provider.d.ts +16 -53
  502. package/dist/store/embeddings/provider.js +41 -69
  503. package/dist/store/entry-reads.d.ts +21 -57
  504. package/dist/store/entry-reads.js +65 -126
  505. package/dist/store/entry-row.d.ts +6 -35
  506. package/dist/store/entry-row.js +9 -37
  507. package/dist/store/entry-writes.d.ts +10 -16
  508. package/dist/store/entry-writes.js +17 -35
  509. package/dist/store/goals.d.ts +3 -40
  510. package/dist/store/goals.js +21 -160
  511. package/dist/store/graph-queue.d.ts +6 -22
  512. package/dist/store/graph-queue.js +14 -45
  513. package/dist/store/graph-reads.d.ts +11 -35
  514. package/dist/store/graph-reads.js +20 -58
  515. package/dist/store/graph-rows.d.ts +3 -6
  516. package/dist/store/graph-rows.js +6 -9
  517. package/dist/store/graph-view-rows.d.ts +2 -1
  518. package/dist/store/graph-view-rows.js +2 -1
  519. package/dist/store/graph-writes.d.ts +6 -31
  520. package/dist/store/graph-writes.js +13 -37
  521. package/dist/store/half-life.d.ts +2 -1
  522. package/dist/store/half-life.js +14 -16
  523. package/dist/store/handoffs.d.ts +5 -11
  524. package/dist/store/handoffs.js +16 -34
  525. package/dist/store/index-and-stats.d.ts +6 -19
  526. package/dist/store/index-and-stats.js +34 -82
  527. package/dist/store/markdown.d.ts +2 -6
  528. package/dist/store/markdown.js +21 -20
  529. package/dist/store/mirrors.d.ts +2 -6
  530. package/dist/store/mirrors.js +14 -23
  531. package/dist/store/open.js +6 -13
  532. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  533. package/dist/store/planning-fallacy-evidence.js +8 -37
  534. package/dist/store/port.d.ts +82 -79
  535. package/dist/store/predictions.d.ts +11 -51
  536. package/dist/store/predictions.js +38 -119
  537. package/dist/{cli → store}/quality-repair.js +15 -31
  538. package/dist/store/raw-archive.d.ts +4 -16
  539. package/dist/store/raw-archive.js +14 -29
  540. package/dist/store/recall-scope.d.ts +19 -79
  541. package/dist/store/recall-scope.js +21 -82
  542. package/dist/store/recall-trace.d.ts +10 -77
  543. package/dist/store/recall-trace.js +19 -95
  544. package/dist/store/rejected-values.js +7 -19
  545. package/dist/store/rejection.d.ts +12 -58
  546. package/dist/store/rejection.js +13 -65
  547. package/dist/store/report-reads.d.ts +6 -0
  548. package/dist/store/report-reads.js +29 -0
  549. package/dist/store/rows.d.ts +9 -19
  550. package/dist/store/rows.js +36 -34
  551. package/dist/store/rule-sql.d.ts +5 -0
  552. package/dist/store/rule-sql.js +37 -0
  553. package/dist/store/search-rows.d.ts +7 -38
  554. package/dist/store/search-rows.js +14 -50
  555. package/dist/store/sessions.d.ts +10 -47
  556. package/dist/store/sessions.js +17 -73
  557. package/dist/store/sqlite/connector-events-group.js +2 -2
  558. package/dist/store/sqlite/entry-writes-group.js +2 -2
  559. package/dist/store/sqlite/error-codec.js +4 -2
  560. package/dist/store/sqlite/executor.d.ts +2 -1
  561. package/dist/store/sqlite/executor.js +2 -1
  562. package/dist/store/sqlite/local.d.ts +3 -3
  563. package/dist/store/sqlite/local.js +1 -0
  564. package/dist/store/sqlite/object-rows.js +6 -3
  565. package/dist/store/sqlite/objects-group.js +4 -2
  566. package/dist/store/sqlite/quarantine-group.js +2 -2
  567. package/dist/store/sqlite/store.d.ts +1 -4
  568. package/dist/store/sqlite/store.js +2 -3
  569. package/dist/store/sqlite/vector-reads-group.js +2 -2
  570. package/dist/store/sqlite/worker-jobs.js +1 -1
  571. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  572. package/dist/store/sqlite/worker-ops.js +13 -2
  573. package/dist/store/sqlite/worker-store.js +5 -2
  574. package/dist/store/summaries.d.ts +10 -62
  575. package/dist/store/summaries.js +34 -146
  576. package/dist/store/summary-dirty.js +1 -1
  577. package/dist/store/tenant-lookup.d.ts +6 -1
  578. package/dist/store/tenant-lookup.js +7 -0
  579. package/dist/store/tenant.d.ts +2 -16
  580. package/dist/store/tenant.js +4 -19
  581. package/dist/store/token-ledger.d.ts +13 -43
  582. package/dist/store/token-ledger.js +19 -50
  583. package/dist/store/usage-reports.js +5 -13
  584. package/dist/store/vector-index.d.ts +46 -0
  585. package/dist/store/vector-index.js +170 -0
  586. package/dist/store/working-memory.d.ts +6 -25
  587. package/dist/store/working-memory.js +18 -52
  588. package/dist/store/yaml.d.ts +1 -5
  589. package/dist/store/yaml.js +2 -6
  590. package/dist/support-bundle.js +7 -5
  591. package/dist/trust/reject-flow.js +1 -3
  592. package/dist/util/anthropic-messages.js +14 -2
  593. package/dist/util/atomic-write.d.ts +2 -1
  594. package/dist/util/atomic-write.js +35 -4
  595. package/dist/util/capped-json.d.ts +6 -0
  596. package/dist/util/capped-json.js +46 -0
  597. package/dist/util/crash-handlers.d.ts +8 -1
  598. package/dist/util/crash-handlers.js +52 -10
  599. package/dist/util/env.d.ts +13 -6
  600. package/dist/util/env.js +14 -7
  601. package/dist/util/home-path.d.ts +2 -1
  602. package/dist/util/home-path.js +4 -2
  603. package/dist/util/http-retry.d.ts +3 -1
  604. package/dist/util/http-retry.js +26 -5
  605. package/dist/util/log.d.ts +3 -2
  606. package/dist/util/log.js +25 -9
  607. package/dist/util/request-scope.d.ts +2 -1
  608. package/dist/util/request-scope.js +2 -1
  609. package/dist/util/secret-detect.d.ts +5 -30
  610. package/dist/util/secret-detect.js +13 -39
  611. package/dist/util/stored-json.d.ts +1 -1
  612. package/dist/util/stored-json.js +1 -1
  613. package/dist/util/token-text.d.ts +1 -4
  614. package/dist/util/token-text.js +1 -4
  615. package/dist/util/transcript-tail.d.ts +2 -0
  616. package/dist/util/transcript-tail.js +24 -23
  617. package/dist/util/version.d.ts +5 -20
  618. package/dist/util/version.js +5 -20
  619. package/extensions/openclaw-plugin/index.ts +1 -1
  620. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  621. package/extensions/openclaw-plugin/package.json +1 -1
  622. package/openclaw.plugin.json +1 -1
  623. package/package.json +1 -1
  624. package/dist/connectors/github/cli-impl.d.ts +0 -25
  625. package/dist/sharing/shared.d.ts +0 -187
  626. package/dist/sharing/shared.js +0 -563
  627. package/dist/store/vector-writes.d.ts +0 -13
  628. package/dist/store/vector-writes.js +0 -89
  629. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
@@ -1,30 +1,30 @@
1
- import { closeHippoDb, openHippoDb, withWriteScope } from '../db/index.js';
1
+ import { DEFAULT_TENANT_ID } from '../util/env.js';
2
+ import { closeHippoDb, withWriteScope } from '../db/index.js';
2
3
  import { rejectionDigest, insertRejectedValue, normalizeValueForRejection } from './rejection.js';
3
4
  import { archiveRawMemory } from './raw-archive.js';
4
5
  import { rowToMemoryConflict } from './rows.js';
5
6
  import { audit } from './audit-event.js';
6
7
  import { syncChangedMirrors, purgeMirrorBestEffort } from './mirrors.js';
7
- import { selectEntriesByIds } from './entry-reads.js';
8
- import { openStore } from './open.js';
8
+ import { chunked, selectEntriesByIds } from './entry-reads.js';
9
+ import { onHandle, openStore } from './open.js';
9
10
  import { deleteEntryCore } from './delete-and-batch.js';
10
11
  import { BadRequestError } from '../core/api-errors.js';
11
12
  import { canTouchScope, isPersonalScope } from './recall-scope.js';
12
13
  import { selectMemoryReach } from './tenant-lookup.js';
14
+ // The one place MemoryConflictRow's columns are listed; CONFLICT_COLS_MC is the same list under the `mc` alias.
15
+ const CONFLICT_COLS = 'id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at';
16
+ const CONFLICT_COLS_MC = CONFLICT_COLS.split(', ').map((c) => `mc.${c}`).join(', ');
13
17
  function canonicalConflictPair(aId, bId) {
14
18
  return aId < bId
15
19
  ? { memory_a_id: aId, memory_b_id: bId }
16
20
  : { memory_a_id: bId, memory_b_id: aId };
17
21
  }
18
22
  function selectConflictRowsInTenant(db, status, allStatuses, tenantId) {
19
- // Tenanted query — JOIN to memories on both conflict members and require
20
- // each in-tenant, so neither a normal cross-tenant pair nor a stale
21
- // pre-fix row surfaces (consistent with resolveConflict).
22
- // SAFETY: both branches select the same eight mc.* columns (aliased
23
- // to MemoryConflictRow's field names) from memory_conflicts.
23
+ // Tenanted query: JOIN memories on both members and require each in-tenant, so no cross-tenant or stale pre-fix pair surfaces.
24
+ // SAFETY: both branches select CONFLICT_COLS_MC, MemoryConflictRow's columns.
24
25
  return allStatuses
25
26
  ? db.prepare(`
26
- SELECT mc.id, mc.memory_a_id, mc.memory_b_id, mc.reason, mc.score,
27
- mc.status, mc.detected_at, mc.updated_at
27
+ SELECT ${CONFLICT_COLS_MC}
28
28
  FROM memory_conflicts mc
29
29
  JOIN memories ma ON ma.id = mc.memory_a_id
30
30
  JOIN memories mb ON mb.id = mc.memory_b_id
@@ -32,8 +32,7 @@ function selectConflictRowsInTenant(db, status, allStatuses, tenantId) {
32
32
  ORDER BY mc.updated_at DESC, mc.id DESC
33
33
  `).all(tenantId, tenantId)
34
34
  : db.prepare(`
35
- SELECT mc.id, mc.memory_a_id, mc.memory_b_id, mc.reason, mc.score,
36
- mc.status, mc.detected_at, mc.updated_at
35
+ SELECT ${CONFLICT_COLS_MC}
37
36
  FROM memory_conflicts mc
38
37
  JOIN memories ma ON ma.id = mc.memory_a_id
39
38
  JOIN memories mb ON mb.id = mc.memory_b_id
@@ -43,37 +42,29 @@ function selectConflictRowsInTenant(db, status, allStatuses, tenantId) {
43
42
  }
44
43
  function selectConflictRowsUnscoped(db, status, allStatuses) {
45
44
  // Unscoped query — legacy direct-mode (CLI, tests, consolidate).
46
- // SAFETY: both branches select the same eight columns matching
47
- // MemoryConflictRow's field set.
45
+ // SAFETY: both branches select CONFLICT_COLS, MemoryConflictRow's columns.
48
46
  return allStatuses
49
47
  ? db.prepare(`
50
- SELECT id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at
48
+ SELECT ${CONFLICT_COLS}
51
49
  FROM memory_conflicts
52
50
  ORDER BY updated_at DESC, id DESC
53
51
  `).all()
54
52
  : db.prepare(`
55
- SELECT id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at
53
+ SELECT ${CONFLICT_COLS}
56
54
  FROM memory_conflicts
57
55
  WHERE status = ?
58
56
  ORDER BY updated_at DESC, id DESC
59
57
  `).all(status);
60
58
  }
61
59
  export function listMemoryConflicts(hippoRoot, status = 'open', tenantId) {
62
- const db = openStore(hippoRoot);
63
- try {
64
- // v0.28 — '*' is a sentinel meaning "no status filter, return all rows".
65
- // Pre-v0.28 callers (cli/mcp/dashboard) always passed 'open' or default,
66
- // so this sentinel is purely additive. The 4 SQL branches below cover
67
- // {tenanted | unscoped} × {all-statuses | specific-status}.
60
+ return onHandle(hippoRoot, (db) => {
61
+ // '*' is a sentinel for no status filter; the 4 SQL branches below cover {tenanted | unscoped} x {all-statuses | specific-status}.
68
62
  const allStatuses = status === '*';
69
63
  const rows = tenantId !== undefined
70
64
  ? selectConflictRowsInTenant(db, status, allStatuses, tenantId)
71
65
  : selectConflictRowsUnscoped(db, status, allStatuses);
72
66
  return rows.map(rowToMemoryConflict);
73
- }
74
- finally {
75
- closeHippoDb(db);
76
- }
67
+ }, openStore);
77
68
  }
78
69
  // listMemoryConflicts' tenanted open set: both members in the tenant.
79
70
  const OPEN_IN_TENANT = `FROM memory_conflicts mc
@@ -82,22 +73,17 @@ const OPEN_IN_TENANT = `FROM memory_conflicts mc
82
73
  WHERE mc.status = 'open' AND ma.tenant_id = ? AND mb.tenant_id = ?`;
83
74
  /** How many open conflicts listMemoryConflicts returns for a tenant, without loading one. */
84
75
  export function countOpenConflicts(hippoRoot, tenantId) {
85
- const db = openStore(hippoRoot);
86
- try {
76
+ return onHandle(hippoRoot, (db) => {
87
77
  // SAFETY: one row with the single aliased count column.
88
78
  const row = db.prepare(`SELECT COUNT(*) AS n ${OPEN_IN_TENANT}`).get(tenantId, tenantId);
89
79
  return Number(row.n);
90
- }
91
- finally {
92
- closeHippoDb(db);
93
- }
80
+ }, openStore);
94
81
  }
95
82
  /** A tenant's open conflicts naming `memoryId`, in listMemoryConflicts' order, each with its other member read in one batch. */
96
83
  export function loadOpenConflictsOf(hippoRoot, tenantId, memoryId) {
97
- const db = openStore(hippoRoot);
98
- try {
99
- // SAFETY: selects the eight mc.* columns of MemoryConflictRow.
100
- const rows = db.prepare(`SELECT mc.id, mc.memory_a_id, mc.memory_b_id, mc.reason, mc.score, mc.status, mc.detected_at, mc.updated_at
84
+ return onHandle(hippoRoot, (db) => {
85
+ // SAFETY: selects CONFLICT_COLS_MC, MemoryConflictRow's columns.
86
+ const rows = db.prepare(`SELECT ${CONFLICT_COLS_MC}
101
87
  ${OPEN_IN_TENANT} AND (mc.memory_a_id = ? OR mc.memory_b_id = ?)
102
88
  ORDER BY mc.updated_at DESC, mc.id DESC`).all(tenantId, tenantId, memoryId, memoryId);
103
89
  const conflicts = rows.map(rowToMemoryConflict);
@@ -110,44 +96,47 @@ export function loadOpenConflictsOf(hippoRoot, tenantId, memoryId) {
110
96
  out.push({ conflict, other });
111
97
  }
112
98
  return out;
113
- }
114
- finally {
115
- closeHippoDb(db);
116
- }
99
+ }, openStore);
117
100
  }
118
101
  /** Conflicts whose two rows `actor` may both touch; someone else's personal row hides its whole pair. */
119
102
  export function listTouchableConflicts(hippoRoot, status, tenantId, actor) {
120
103
  const conflicts = listMemoryConflicts(hippoRoot, status, tenantId);
121
- const db = openHippoDb(hippoRoot);
122
- try {
104
+ return onHandle(hippoRoot, (db) => {
123
105
  return conflicts.filter((c) => [c.memory_a_id, c.memory_b_id].every((id) => canTouchScope(actor, selectMemoryReach(db, id)?.scope ?? null)));
124
- }
125
- finally {
126
- closeHippoDb(db);
127
- }
106
+ });
128
107
  }
129
108
  export function replaceDetectedConflicts(hippoRoot, detected, detectedAt = new Date().toISOString()) {
130
- const db = openStore(hippoRoot);
131
- try {
132
- const changedIds = writeConflictRefresh(db, readConflictRefresh(db), detected, detectedAt);
109
+ onHandle(hippoRoot, (db) => {
110
+ const changedIds = writeConflictRefresh(db, readConflictRefresh(db, detected), detected, detectedAt);
133
111
  syncChangedMirrors(hippoRoot, db, [...selectEntriesByIds(db, changedIds).values()]);
134
- }
135
- finally {
136
- closeHippoDb(db);
137
- }
112
+ }, openStore);
138
113
  }
139
- /** The refresh's read of the whole memories table, kept out of the write lock because it grows with the store. */
140
- function readConflictRefresh(db) {
114
+ /** The refresh's reads, kept out of the write lock; only rows holding refs, in an open conflict or in `detected` are loaded, not the whole table. */
115
+ function readConflictRefresh(db, detected) {
141
116
  // Tenant guard (E2): a conflict is meaningful only within one tenant, so cross-tenant pairs are
142
117
  // skipped on insert and on rebuild, and a stale cross-tenant row can neither persist nor leak a foreign id.
143
118
  const tenantById = new Map();
144
119
  const storedRefs = new Map();
145
120
  // SAFETY: rows' shape matches the three columns named in the SELECT.
146
- for (const r of db.prepare(`SELECT id, tenant_id, conflicts_with_json FROM memories`).all()) {
121
+ const rows = db.prepare(`
122
+ SELECT id, tenant_id, conflicts_with_json FROM memories
123
+ WHERE conflicts_with_json != '[]'
124
+ OR id IN (SELECT memory_a_id FROM memory_conflicts WHERE status = 'open')
125
+ OR id IN (SELECT memory_b_id FROM memory_conflicts WHERE status = 'open')
126
+ `).all();
127
+ for (const r of rows) {
147
128
  tenantById.set(r.id, r.tenant_id);
148
129
  if (r.conflicts_with_json !== '[]')
149
130
  storedRefs.set(r.id, r.conflicts_with_json);
150
131
  }
132
+ const given = [...new Set(detected.flatMap((c) => [c.memory_a_id, c.memory_b_id]))].filter((id) => !tenantById.has(id));
133
+ for (const ids of chunked(given)) {
134
+ const marks = ids.map(() => '?').join(',');
135
+ // SAFETY: rows' shape matches the two columns named in the SELECT.
136
+ const found = db.prepare(`SELECT id, tenant_id FROM memories WHERE id IN (${marks})`).all(...ids);
137
+ for (const r of found)
138
+ tenantById.set(r.id, r.tenant_id);
139
+ }
151
140
  const sameTenant = (a, b) => {
152
141
  const ta = tenantById.get(a);
153
142
  const tb = tenantById.get(b);
@@ -170,10 +159,9 @@ function writeConflictRefresh(db, reads, detected, detectedAt) {
170
159
  }
171
160
  function resolveStaleOpenConflicts(db, canonicalDetected, sameTenant, detectedAt) {
172
161
  const detectedKeys = new Set(canonicalDetected.map((conflict) => `${conflict.memory_a_id}::${conflict.memory_b_id}`));
173
- // SAFETY: openRows' shape matches the eight columns named in the SELECT
174
- // above.
162
+ // SAFETY: openRows' shape matches the columns named in CONFLICT_COLS.
175
163
  const openRows = db.prepare(`
176
- SELECT id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at
164
+ SELECT ${CONFLICT_COLS}
177
165
  FROM memory_conflicts
178
166
  WHERE status = 'open'
179
167
  `).all();
@@ -181,11 +169,7 @@ function resolveStaleOpenConflicts(db, canonicalDetected, sameTenant, detectedAt
181
169
  for (const row of openRows) {
182
170
  const key = `${row.memory_a_id}::${row.memory_b_id}`;
183
171
  const stale = !detectedKeys.has(key);
184
- // v1.11.0 residue: auto-resolve any open cross-tenant row. The insert
185
- // loop in upsertDetectedConflicts and the refMap rebuild skip
186
- // cross-tenant pairs, but the resolve-stale loop previously left
187
- // re-detected cross-tenant rows lingering status='open'. The
188
- // sameTenant() helper is already built one block up; no extra query.
172
+ // Auto-resolve any open cross-tenant row: the insert loop and refMap rebuild skip those pairs, so re-detected ones would linger as 'open'.
189
173
  const crossTenant = !sameTenant(row.memory_a_id, row.memory_b_id);
190
174
  if (stale || crossTenant)
191
175
  resolve.run(detectedAt, row.id);
@@ -242,10 +226,8 @@ function rebuildConflictsWithJson(db, { sameTenant, storedRefs }) {
242
226
  }
243
227
  return changedIds;
244
228
  }
245
- // When tenantId is set, the conflict lookup requires BOTH members in-tenant
246
- // and every memories mutation carries AND tenant_id = ?. A cross-tenant probe
247
- // then returns null, indistinguishable from a bad id. Omitted tenantId =
248
- // legacy unscoped behaviour (CLI direct mode, tests, consolidate.ts).
229
+ // With tenantId, both members must be in-tenant and every memories mutation carries AND tenant_id = ?; a cross-tenant probe returns null like a bad id.
230
+ // Omitted tenantId = unscoped (CLI direct mode, tests).
249
231
  function conflictMemScope(tenantId) {
250
232
  return {
251
233
  memScope: tenantId !== undefined ? ' AND tenant_id = ?' : '',
@@ -268,21 +250,8 @@ function findResolvableConflict(db, conflictId, keepId, tenantId) {
268
250
  return null;
269
251
  return { conflict, loserId };
270
252
  }
271
- /**
272
- * Resolve a conflict by keeping one memory and weakening the other.
273
- * Sets conflict status to 'resolved' and halves the loser's half-life.
274
- * If --forget is used, the loser is removed entirely (kind-aware: raw rows
275
- * are archived via archiveRawMemory, others deleted via deleteEntryCore —
276
- * AT1 fix for the pre-existing crash where a raw loser aborted the whole
277
- * resolve transaction against the append-only trigger). `opts.rejectLoserValue`
278
- * additionally tombstones the loser's normalized digest so it cannot be
279
- * re-asserted later.
280
- *
281
- * Every resolution path (weaken / forget / reject) emits a `conflict_resolve`
282
- * audit row (AT1 — previously resolveConflict wrote zero audit rows on any path).
283
- *
284
- * Returns the resolved conflict, or null if not found.
285
- */
253
+ /** Resolve a conflict by keeping one memory and halving the loser's half-life; `--forget` removes the loser, `opts.rejectLoserValue` also tombstones its
254
+ * digest. Every path emits a `conflict_resolve` audit row. Returns the resolved conflict, or null if not found. */
286
255
  export function resolveConflict(hippoRoot, conflictId, keepId, forgetLoser = false, tenantId, opts) {
287
256
  const db = openStore(hippoRoot);
288
257
  const scope = conflictMemScope(tenantId);
@@ -312,19 +281,17 @@ export function resolveConflict(hippoRoot, conflictId, keepId, forgetLoser = fal
312
281
  }
313
282
  }
314
283
  function selectConflictRow(db, conflictId, tenantId) {
315
- // SAFETY: both branches select the same eight columns (aliased in the
316
- // tenanted branch) matching MemoryConflictRow's field set.
284
+ // SAFETY: the branches select CONFLICT_COLS_MC and CONFLICT_COLS, MemoryConflictRow's columns.
317
285
  return (tenantId !== undefined
318
286
  ? db.prepare(`
319
- SELECT mc.id, mc.memory_a_id, mc.memory_b_id, mc.reason, mc.score,
320
- mc.status, mc.detected_at, mc.updated_at
287
+ SELECT ${CONFLICT_COLS_MC}
321
288
  FROM memory_conflicts mc
322
289
  JOIN memories ma ON ma.id = mc.memory_a_id
323
290
  JOIN memories mb ON mb.id = mc.memory_b_id
324
291
  WHERE mc.id = ? AND ma.tenant_id = ? AND mb.tenant_id = ?
325
292
  `).get(conflictId, tenantId, tenantId)
326
293
  : db.prepare(`
327
- SELECT id, memory_a_id, memory_b_id, reason, score, status, detected_at, updated_at
294
+ SELECT ${CONFLICT_COLS}
328
295
  FROM memory_conflicts WHERE id = ?
329
296
  `).get(conflictId));
330
297
  }
@@ -335,21 +302,13 @@ function weakenConflictLoser(db, t) {
335
302
  return { loserRemoved: false, loserWasRaw: false, rejectedDigest: undefined, extraRemovedIds: [], extraRemovedRawIds: [] };
336
303
  }
337
304
  function removeConflictLoser(db, t) {
338
- // AT1 (plan §5): removal (forgetLoser OR rejectLoserValue — a tombstoned
339
- // value cannot be left live) is now kind-aware. The old bare
340
- // `DELETE FROM memories WHERE id = ?` aborted the whole transaction when
341
- // the loser was kind='raw' (append-only trigger fires); route through
342
- // the same helpers the reject verb uses (both db-scoped, both compose
343
- // inside this BEGIN/COMMIT). loserRemoved / loserWasRaw drive both the
344
- // conflicts_with_json skip below and the post-commit mirror purge.
305
+ // Removal is kind-aware: a bare DELETE on a raw loser fires the append-only trigger, so use the same helpers as the reject verb.
306
+ // loserRemoved / loserWasRaw drive the conflicts_with_json skip below and the post-commit mirror purge.
345
307
  const removal = {
346
308
  loserRemoved: false,
347
309
  loserWasRaw: false,
348
310
  rejectedDigest: undefined,
349
- // AT1 P1 fix (codex): same-tenant duplicates of the loser's content that
350
- // rejectLoserValue also removes (see below) — separate from loserId so
351
- // the audit + post-commit mirror purge can cover ALL of them, not just
352
- // loserId.
311
+ // Same-tenant duplicates of the loser's content that rejectLoserValue also removes; kept apart from loserId so audit and mirror purge cover all of them.
353
312
  extraRemovedIds: [],
354
313
  extraRemovedRawIds: [],
355
314
  };
@@ -380,7 +339,7 @@ function removeConflictLoser(db, t) {
380
339
  }
381
340
  function recordRejectedLoserValue(db, t, loserRow, digest, who) {
382
341
  insertRejectedValue(db, {
383
- tenantId: loserRow.tenant_id ?? 'default',
342
+ tenantId: loserRow.tenant_id ?? DEFAULT_TENANT_ID,
384
343
  digest,
385
344
  reason: who.reason,
386
345
  rejectedBy: who.actor,
@@ -397,19 +356,9 @@ function tombstoneLoserValue(db, t, loserRow, who, removal) {
397
356
  const { actor, reason } = who;
398
357
  const rejectedDigest = rejectionDigest(loserRow.content);
399
358
  recordRejectedLoserValue(db, t, loserRow, rejectedDigest, who);
400
- // AT1 P1 fix (codex): reject-flow.ts's `rejectValue` removes ALL
401
- // live same-tenant rows whose normalized digest matches, not just
402
- // the one id passed — but this branch only ever removed loserId,
403
- // leaving same-TENANT duplicates live while their shared content
404
- // was tombstoned. Same O(N) scan pattern as reject-flow.ts (human-
405
- // triggered command, tenant's row count is human-scale). CRITICAL
406
- // BOUNDARY: tenant-scoped ONLY — tombstones are tenant-scoped by
407
- // design, so a same-content row in ANOTHER tenant is legitimately
408
- // live and must NOT be touched here. `keepId` is excluded even if
409
- // its content coincidentally matches: the human explicitly chose
410
- // to keep it in this same resolution, and this branch must not
411
- // undo that choice in the same transaction.
412
- const loserTenantId = loserRow.tenant_id ?? 'default';
359
+ // Remove ALL live same-tenant rows whose digest matches (as reject-flow.ts rejectValue does), not just loserId; the O(N) scan is human-scale.
360
+ // Tenant-scoped ONLY, since tombstones are; `keepId` is excluded even if its content matches, because the human chose to keep it.
361
+ const loserTenantId = loserRow.tenant_id ?? DEFAULT_TENANT_ID;
413
362
  // SAFETY: dupRows' shape matches the four columns named in the SELECT above.
414
363
  const dupRows = db
415
364
  .prepare(`SELECT id, kind, content, scope FROM memories WHERE tenant_id = ? AND id != ? AND id != ?`)
@@ -434,9 +383,8 @@ function tombstoneLoserValue(db, t, loserRow, who, removal) {
434
383
  function stripConflictRefs(db, t, loserRemoved) {
435
384
  const { memScope, memArgs } = t.scope;
436
385
  const { keepId, loserId } = t;
437
- // Clean up conflicts_with references
438
- // SAFETY: keepRow's shape matches the single `conflicts_with_json`
439
- // column selected above.
386
+ // Clean up conflicts_with references.
387
+ // SAFETY: keepRow's shape matches the single `conflicts_with_json` column selected above.
440
388
  const keepRow = db.prepare(`SELECT conflicts_with_json FROM memories WHERE id = ?${memScope}`).get(keepId, ...memArgs);
441
389
  if (keepRow) {
442
390
  const refs = JSON.parse(keepRow.conflicts_with_json || '[]');
@@ -458,56 +406,29 @@ function stripConflictRefs(db, t, loserRemoved) {
458
406
  }
459
407
  function auditConflictResolve(db, t, removal, tenantId) {
460
408
  const { loserRemoved, loserWasRaw, rejectedDigest, extraRemovedIds } = removal;
461
- // AT1: the missing audit (plan §5 — resolveConflict wrote ZERO audit_log
462
- // rows on any path before this). Every path — weaken, forget, reject —
463
- // lands exactly one conflict_resolve row.
409
+ // Every path (weaken, forget, reject) lands exactly one conflict_resolve audit row.
464
410
  const conflictResolveMeta = {
465
411
  conflictId: t.conflictId,
466
412
  keepId: t.keepId,
467
413
  loserId: t.loserId,
468
414
  disposition: loserRemoved ? (loserWasRaw ? 'archived_raw' : 'deleted') : 'weakened',
469
415
  rejected: Boolean(t.opts?.rejectLoserValue),
470
- // AT1 P1 fix: every row this call removed, not just loserId — the
471
- // same-tenant duplicate sweep above (extraRemovedIds) needs an
472
- // audit trail too.
416
+ // Every row this call removed, not just loserId, so the duplicate sweep (extraRemovedIds) is audited too.
473
417
  removedIds: loserRemoved ? [t.loserId, ...extraRemovedIds] : [],
474
418
  };
475
419
  // Assigned only when present so the serialized audit payload keeps
476
420
  // omitting the key, exactly as the pre-migration object literal did.
477
421
  if (rejectedDigest !== undefined)
478
422
  conflictResolveMeta.rejectedDigest = rejectedDigest;
479
- // Fresh spread literal: ConflictResolveMeta is a closed interface (no
480
- // index signature) and isn't directly assignable to audit()'s
481
- // Record<string, JsonValue> metadata param; a spread into a fresh
482
- // object literal satisfies it without widening the declared type above.
423
+ // Fresh spread literal: ConflictResolveMeta is a closed interface, not assignable to audit()'s Record<string, JsonValue> metadata otherwise.
483
424
  audit(db, 'conflict_resolve', { targetId: t.keepId, metadata: { ...conflictResolveMeta }, actor: t.opts?.rejectedBy ?? 'cli', tenantId });
484
425
  }
485
426
  function purgeRemovedLoserMirrors(hippoRoot, db, loserId, removal) {
486
- // AT1 P1b fix: mirror purge + reaper stamp for EVERY removed loser, not
487
- // just the rejectLoserValue path. Pre-AT1, the plain forgetLoser path on
488
- // a raw loser crashed outright (bare DELETE FROM memories hit the
489
- // append-only trigger) — there is no legacy "successful forget, no
490
- // purge" behavior to preserve for that case. Post-AT1's kind-aware
491
- // removal (archiveRawMemory / deleteEntryCore above) makes plain
492
- // --forget succeed on every kind, but until this fix the mirror was
493
- // only purged when rejectLoserValue was ALSO set: a plain raw --forget
494
- // left its markdown mirror orphaned (the reaper still catches it
495
- // eventually, since archiveRawMemory's own raw_archive insert leaves
496
- // mirror_cleaned_at NULL) and a plain non-raw --forget left its mirror
497
- // orphaned FOREVER (no reaper exists for non-raw rows). Same post-commit
498
- // purge+reaper pattern as the reject verb (src/trust/reject-flow.ts) and
499
- // api.archiveRaw — reusing removeEntryMirrors + raw_archive bookkeeping.
500
- // AT1 P1 fix: loop over loserId AND every same-tenant duplicate the
501
- // rejectLoserValue sweep above removed (extraRemovedIds) — previously
502
- // only loserId's mirror was purged, leaving duplicate mirrors orphaned
503
- // despite their rows being gone.
427
+ // Mirror purge and reaper stamp for EVERY removed loser (loserId and each extraRemovedIds duplicate), post-commit like the reject verb.
428
+ // A non-raw mirror has no reaper, so skipping the purge would orphan it forever.
504
429
  for (const removedId of [loserId, ...removal.extraRemovedIds]) {
505
430
  const isRaw = removedId === loserId ? removal.loserWasRaw : removal.extraRemovedRawIds.includes(removedId);
506
- // AT1 fix: purgeMirrorBestEffort retries once, then — for non-raw ids,
507
- // which cleanupArchivedMirrors' reaper never scans — reports the
508
- // EXPLICIT leftover path(s) instead of the false "will retry via
509
- // reaper" claim. See its own doc comment (store.ts, near
510
- // removeEntryMirrors) for the full rationale.
431
+ // purgeMirrorBestEffort retries once, then reports the explicit leftover paths for non-raw ids, which the cleanupArchivedMirrors reaper never scans.
511
432
  const mirrorOk = purgeMirrorBestEffort(hippoRoot, removedId, isRaw, 'resolveConflict');
512
433
  if (mirrorOk && isRaw) {
513
434
  db.prepare(`UPDATE raw_archive SET mirror_cleaned_at = ? WHERE memory_id = ?`).run(new Date().toISOString(), removedId);
@@ -516,7 +437,7 @@ function purgeRemovedLoserMirrors(hippoRoot, db, loserId, removal) {
516
437
  }
517
438
  /** The conflict and loser ids every conflict_resolve audit row names. */
518
439
  export function conflictResolveAuditsAt(db) {
519
- // SAFETY: SELECT of two fields every conflict_resolve audit row carries (ConflictResolveMeta in store.ts).
440
+ // SAFETY: SELECT of two fields every conflict_resolve audit row carries (ConflictResolveMeta above).
520
441
  return db.prepare(`SELECT json_extract(metadata_json, '$.conflictId') AS conflictId, json_extract(metadata_json, '$.loserId') AS loserId FROM audit_log WHERE op = 'conflict_resolve'`).all();
521
442
  }
522
443
  /** Every resolved conflict with both sides. */
@@ -1,6 +1,6 @@
1
1
  import { type DatabaseSyncLike } from '../../db/index.js';
2
2
  /** One github_event_log row to write; `memoryId` is null for an event that produced no memory. */
3
- export interface GithubEventLogEntry {
3
+ export interface GitHubEventLogEntry {
4
4
  idempotencyKey: string;
5
5
  deliveryId: string;
6
6
  eventName: string;
@@ -9,12 +9,12 @@ export interface GithubEventLogEntry {
9
9
  export declare function eventSeenAt(db: DatabaseSyncLike, idempotencyKey: string): boolean;
10
10
  export declare function eventMemoryAt(db: DatabaseSyncLike, idempotencyKey: string): string | null;
11
11
  /** False when the key was already logged, so a caller inside a write scope can roll its own row back. */
12
- export declare function logEventAt(db: DatabaseSyncLike, entry: GithubEventLogEntry): boolean;
12
+ export declare function logEventAt(db: DatabaseSyncLike, entry: GitHubEventLogEntry): boolean;
13
13
  /** The memory an already-seen key points at, or null when the key is new. */
14
14
  export declare function seenEvent(hippoRoot: string, idempotencyKey: string): {
15
15
  memoryId: string | null;
16
16
  } | null;
17
- export declare function logEvent(hippoRoot: string, entry: GithubEventLogEntry): void;
17
+ export declare function logEvent(hippoRoot: string, entry: GitHubEventLogEntry): void;
18
18
  export interface ArtifactDeletion {
19
19
  tenantId: string;
20
20
  artifactRef: string;
@@ -46,7 +46,7 @@ export interface DlqItem {
46
46
  bucket: DlqBucket | string;
47
47
  }
48
48
  /** One github_dlq row to write, already redacted by the caller; the four GitHub-only columns are stored NULL when left out. */
49
- export interface GithubDlqWrite {
49
+ export interface GitHubDlqInsert {
50
50
  tenantId: string;
51
51
  rawPayload: string;
52
52
  error: string;
@@ -57,12 +57,12 @@ export interface GithubDlqWrite {
57
57
  repoFullName?: string | null;
58
58
  bucket: DlqBucket;
59
59
  }
60
- export declare function insertDlq(hippoRoot: string, row: GithubDlqWrite): number;
61
- export declare function listDlqRows(hippoRoot: string, tenantId: string, limit: number): DlqItem[];
62
- export declare function dlqEntry(hippoRoot: string, id: number): DlqItem | null;
63
- export declare function bumpDlqRetry(hippoRoot: string, id: number): void;
60
+ export declare function insertGitHubDlq(hippoRoot: string, row: GitHubDlqInsert): number;
61
+ export declare function listGitHubDlq(hippoRoot: string, tenantId: string, limit: number): DlqItem[];
62
+ export declare function githubDlqEntry(hippoRoot: string, id: number): DlqItem | null;
63
+ export declare function bumpGitHubDlqRetryCount(hippoRoot: string, id: number): void;
64
64
  /** What the routing tables say about one webhook; `tenant` is the installation match, or the repo match when no installation was sent. */
65
- export interface GithubRouting {
65
+ export interface GitHubRouting {
66
66
  installations: number;
67
67
  repositories: number;
68
68
  tenant: string | null;
@@ -70,7 +70,7 @@ export interface GithubRouting {
70
70
  export declare function githubRouting(hippoRoot: string, args: {
71
71
  installationId?: string | null;
72
72
  repoFullName?: string | null;
73
- }): GithubRouting;
73
+ }): GitHubRouting;
74
74
  export type HwmColumn = 'issues_hwm' | 'issue_comments_hwm' | 'pr_review_comments_hwm';
75
75
  export interface StoredCursors {
76
76
  issues: string | null;
@@ -47,7 +47,7 @@ export function archiveDeletedArtifact(hippoRoot, del) {
47
47
  return { duplicate: false, archived: memoryIds.length };
48
48
  });
49
49
  }
50
- function insertDlqAt(db, row) {
50
+ function insertGitHubDlqAt(db, row) {
51
51
  const result = db
52
52
  .prepare(`INSERT INTO github_dlq
53
53
  (tenant_id, raw_payload, error, event_name, delivery_id, signature,
@@ -56,8 +56,8 @@ function insertDlqAt(db, row) {
56
56
  .run(row.tenantId, row.rawPayload, row.error, row.eventName ?? null, row.deliveryId ?? null, row.signature, row.installationId ?? null, row.repoFullName ?? null, new Date().toISOString(), row.bucket);
57
57
  return Number(result.lastInsertRowid);
58
58
  }
59
- export function insertDlq(hippoRoot, row) {
60
- return onHandle(hippoRoot, (db) => insertDlqAt(db, row));
59
+ export function insertGitHubDlq(hippoRoot, row) {
60
+ return onHandle(hippoRoot, (db) => insertGitHubDlqAt(db, row));
61
61
  }
62
62
  const SELECT_COLUMNS = `id, tenant_id, raw_payload, error, event_name, delivery_id,
63
63
  signature, installation_id, repo_full_name, retry_count,
@@ -79,7 +79,7 @@ function rowToItem(r) {
79
79
  bucket: r.bucket == null ? 'parse_error' : String(r.bucket),
80
80
  };
81
81
  }
82
- function listDlqAt(db, tenantId, limit) {
82
+ function listGitHubDlqAt(db, tenantId, limit) {
83
83
  // SAFETY: SELECT_COLUMNS projects exactly DlqRawRow's fields.
84
84
  const rows = db
85
85
  .prepare(`SELECT ${SELECT_COLUMNS}
@@ -90,10 +90,10 @@ function listDlqAt(db, tenantId, limit) {
90
90
  .all(tenantId, limit);
91
91
  return rows.map(rowToItem);
92
92
  }
93
- export function listDlqRows(hippoRoot, tenantId, limit) {
94
- return onHandle(hippoRoot, (db) => listDlqAt(db, tenantId, limit));
93
+ export function listGitHubDlq(hippoRoot, tenantId, limit) {
94
+ return onHandle(hippoRoot, (db) => listGitHubDlqAt(db, tenantId, limit));
95
95
  }
96
- function dlqEntryAt(db, id) {
96
+ function githubDlqEntryAt(db, id) {
97
97
  // SAFETY: SELECT_COLUMNS projects exactly DlqRawRow's fields.
98
98
  const row = db
99
99
  .prepare(`SELECT ${SELECT_COLUMNS}
@@ -104,10 +104,10 @@ function dlqEntryAt(db, id) {
104
104
  return null;
105
105
  return rowToItem(row);
106
106
  }
107
- export function dlqEntry(hippoRoot, id) {
108
- return onHandle(hippoRoot, (db) => dlqEntryAt(db, id));
107
+ export function githubDlqEntry(hippoRoot, id) {
108
+ return onHandle(hippoRoot, (db) => githubDlqEntryAt(db, id));
109
109
  }
110
- export function bumpDlqRetry(hippoRoot, id) {
110
+ export function bumpGitHubDlqRetryCount(hippoRoot, id) {
111
111
  onHandle(hippoRoot, (db) => {
112
112
  db.prepare(`UPDATE github_dlq
113
113
  SET retry_count = retry_count + 1,
@@ -5,7 +5,7 @@ import { withReadSnapshot } from '../db/busy.js';
5
5
  import { pragmaDataVersion } from '../db/meta.js';
6
6
  import { tableExists } from '../db/tables.js';
7
7
  import { storedVectorIds } from '../db/vector-store.js';
8
- import { openStore } from './open.js';
8
+ import { onHandle, openStore } from './open.js';
9
9
  import { QUARANTINE_SCOPE_PREFIX } from './quarantine.js';
10
10
  import { parseJsonArray } from './rows.js';
11
11
  const LIVE_COLUMNS = 'id, created, last_retrieved, retrieval_count, half_life_days, layer, tags_json, emotional_valence, outcome_positive, outcome_negative, pinned, confidence, content, superseded_by, kind, scope, origin_project';
@@ -24,7 +24,7 @@ function toDashboardRow(row) {
24
24
  retrieval_count: Number(row.retrieval_count ?? 0),
25
25
  half_life_days: Number(row.half_life_days ?? 7),
26
26
  layer: row.layer,
27
- tags: parseJsonArray(row.tags_json),
27
+ tags: parseJsonArray(row.tags_json, { table: 'memories', id: row.id, column: 'tags_json' }),
28
28
  emotional_valence: row.emotional_valence ?? 'neutral',
29
29
  outcome_positive: Number(row.outcome_positive ?? 0),
30
30
  outcome_negative: Number(row.outcome_negative ?? 0),
@@ -39,8 +39,7 @@ function toDashboardRow(row) {
39
39
  }
40
40
  /** One tenant's live rows and the counts of the rest, read in one transaction so the two agree. */
41
41
  export function loadDashboardRows(hippoRoot, tenantId) {
42
- const db = openStore(hippoRoot);
43
- try {
42
+ return onHandle(hippoRoot, (db) => {
44
43
  return withReadSnapshot(db, () => {
45
44
  // SAFETY: the SELECT names exactly LiveRow's columns.
46
45
  const live = db.prepare(`SELECT ${LIVE_COLUMNS} FROM memories WHERE tenant_id = ? AND ${LIVE} ORDER BY created ASC, id ASC`).all(tenantId);
@@ -56,10 +55,7 @@ export function loadDashboardRows(hippoRoot, tenantId) {
56
55
  excluded[why] = Number(n);
57
56
  return { live: live.map(toDashboardRow), excluded };
58
57
  });
59
- }
60
- finally {
61
- closeHippoDb(db);
62
- }
58
+ }, openStore);
63
59
  }
64
60
  /** The dashboard's one read-only connection, kept across refreshes for the commit signal; it opens on the first read that finds a database. */
65
61
  export class DashboardConnection {
@@ -8,16 +8,8 @@ export declare const MEMORY_BACKED_TABLES: readonly ["predictions", "decisions",
8
8
  export declare function memoriesBackingObjects(hippoRoot: string): Set<string>;
9
9
  /** memoriesBackingObjects on the caller's handle. */
10
10
  export declare function memoriesBackingObjectsOn(db: DatabaseSyncLike): Set<string>;
11
- /**
12
- * db-scoped delete core, so a delete can compose inside a caller's transaction.
13
- * NO filesystem I/O: the caller's transaction may still roll back, and mirrors are written post-commit.
14
- *
15
- * `opts.suppressForgetAudit` (default false): `rejectValue` and `resolveConflict` set it because each
16
- * writes its own aggregate audit row, so a removed row must not ALSO emit a `forget` row.
17
- *
18
- * Returns `{tenantId, dagParentId}` for the removed row, or `null` if no row with `id`
19
- * existed or `automatic` refused it (pinned, raw, kept for good or backing an object at DELETE time, so a late pin wins).
20
- */
11
+ /** db-scoped delete core, composable inside a caller's transaction; NO filesystem I/O, mirrors are written post-commit. `suppressForgetAudit` is set by
12
+ * rejectValue and resolveConflict (own audit row). Returns `{tenantId, dagParentId}`, or null if absent or `automatic` refused it. */
21
13
  export declare function deleteEntryCore(db: ReturnType<typeof openHippoDb>, id: string, opts?: {
22
14
  actor?: string;
23
15
  suppressForgetAudit?: boolean;
@@ -27,29 +19,17 @@ export declare function deleteEntryCore(db: ReturnType<typeof openHippoDb>, id:
27
19
  tenantId: string;
28
20
  dagParentId: string | null;
29
21
  } | null;
30
- /**
31
- * Delete an entry from SQLite and mirrors.
32
- *
33
- * `opts.actor` defaults to 'cli'. The api.* layer threads `ctx.actor` so HTTP
34
- * callers land with `api_key:<key_id>` in the audit log without a duplicate
35
- * emit from the api wrapper.
36
- *
37
- * Thin wrapper over `deleteEntryCore` (open → core → mirrors → close);
38
- * behavior is byte-identical to the pre-split implementation for every
39
- * existing caller.
40
- */
22
+ /** Delete an entry from SQLite and mirrors; thin wrapper over `deleteEntryCore` (open, core, mirrors, close).
23
+ * `opts.actor` defaults to 'cli'; the api layer threads `ctx.actor` so HTTP callers land as `api_key:<key_id>` in the audit log. */
41
24
  export declare function deleteEntry(hippoRoot: string, id: string, opts?: {
42
25
  actor?: string;
43
26
  reason?: string;
44
27
  automatic?: boolean;
45
28
  }): boolean;
46
- /** Writes, deletes and dormant moves in one transaction. With `snapshot` (rows as the caller loaded them), a write keeps only
47
- * the fields the caller changed, takes the rest from the live row, and never resurrects a row that is gone.
48
- *
49
- * `dormant` (src/store/dormant.ts): each move's snapshot is inserted into `dormant_memories` and its `memories` row
50
- * leaves exactly like a delete (FTS row, DAG parent dirty-mark, mirrors), in the same transaction, so a memory
51
- * is never in both places or in neither. Deletes and moves both skip rows that are no longer auto-deletable
52
- * (pinned, raw, kept for good or backing an object since the caller decided). Returns the ids that left `memories`, deleted or moved. */
29
+ /** Each row as the caller loaded it, by id; a `ReadonlyMap` fits. */
30
+ export type LoadedRows = Pick<ReadonlyMap<string, MemoryEntry>, 'get'>;
31
+ /** Writes, deletes and dormant moves in one transaction. With `snapshot`, a write keeps only the fields the caller changed and never resurrects a gone row.
32
+ * Dormant moves (src/store/dormant.ts) leave `memories` like a delete; both skip rows no longer auto-deletable. Returns ids that left `memories`. */
53
33
  export declare function batchWriteAndDelete(hippoRoot: string, toWrite: MemoryEntry[], toDeleteIds: string[], opts?: {
54
34
  snapshot?: ReadonlyMap<string, MemoryEntry>;
55
35
  dormant?: DormantMove[];
@@ -70,10 +50,10 @@ export declare function deleteEntriesOneByOne(hippoRoot: string, targets: readon
70
50
  actor?: string;
71
51
  automatic?: boolean;
72
52
  }): boolean[];
73
- /** Commits whole components in transactions of about `budget.holdMs` on one store handle, letting other writers in between; returns the ids that left `memories`.
74
- * The snapshot keeps what other writers changed after the caller loaded its rows. */
53
+ /** Commits whole components in transactions of about `budget.holdMs`, letting other writers in between; returns the ids that left `memories`.
54
+ * The snapshot keeps what other writers changed after the caller loaded its rows. */
75
55
  export declare function commitInChunks(hippoRoot: string, components: readonly FlushComponent[], opts: {
76
- snapshot: ReadonlyMap<string, MemoryEntry>;
56
+ snapshot: LoadedRows;
77
57
  budget: WriteBudget;
78
58
  busyWaitMs: number;
79
59
  }): Promise<string[]>;