hippo-memory 1.71.0 → 1.72.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 (555) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/apply.d.ts +0 -11
  3. package/dist/agent-memories/apply.js +6 -21
  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 +1 -1
  12. package/dist/api/audit.d.ts +29 -1
  13. package/dist/api/audit.js +44 -5
  14. package/dist/api/auth.d.ts +7 -4
  15. package/dist/api/auth.js +12 -8
  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-render.js +4 -3
  24. package/dist/api/context-select.js +9 -11
  25. package/dist/api/context.js +17 -8
  26. package/dist/api/continuity.d.ts +47 -0
  27. package/dist/api/continuity.js +66 -0
  28. package/dist/api/dormant.js +4 -2
  29. package/dist/api/drill-down.js +1 -1
  30. package/dist/api/embeddings.d.ts +17 -0
  31. package/dist/api/embeddings.js +28 -0
  32. package/dist/api/error-reply.d.ts +8 -0
  33. package/dist/api/error-reply.js +21 -0
  34. package/dist/api/forget.d.ts +6 -2
  35. package/dist/api/forget.js +18 -7
  36. package/dist/api/goals.d.ts +1 -1
  37. package/dist/api/goals.js +5 -9
  38. package/dist/api/index.d.ts +4 -2
  39. package/dist/api/index.js +4 -2
  40. package/dist/api/instruction-detect.js +5 -1
  41. package/dist/api/learn.d.ts +4 -0
  42. package/dist/api/learn.js +53 -27
  43. package/dist/api/ledger-db.d.ts +2 -6
  44. package/dist/api/ledger-db.js +4 -36
  45. package/dist/api/memories.d.ts +19 -1
  46. package/dist/api/memories.js +39 -0
  47. package/dist/api/objects.d.ts +1 -1
  48. package/dist/api/outcome.js +1 -1
  49. package/dist/api/pilot-arm.d.ts +1 -11
  50. package/dist/api/pilot-arm.js +5 -45
  51. package/dist/api/predictions.d.ts +3 -1
  52. package/dist/api/predictions.js +6 -0
  53. package/dist/api/projects.d.ts +21 -0
  54. package/dist/api/projects.js +24 -0
  55. package/dist/api/promote.js +1 -1
  56. package/dist/api/prompt-hook.d.ts +15 -2
  57. package/dist/api/prompt-hook.js +44 -4
  58. package/dist/api/recall-cli.d.ts +3 -0
  59. package/dist/api/recall-cli.js +13 -4
  60. package/dist/api/recall-core.js +3 -3
  61. package/dist/api/recall-pipeline.js +6 -7
  62. package/dist/api/recall-request.js +1 -1
  63. package/dist/api/recall.d.ts +0 -3
  64. package/dist/api/recall.js +19 -44
  65. package/dist/api/remember-local.js +1 -1
  66. package/dist/api/remember.d.ts +2 -1
  67. package/dist/api/remember.js +3 -2
  68. package/dist/api/session-end.d.ts +22 -0
  69. package/dist/api/session-end.js +101 -0
  70. package/dist/api/sleep-run.d.ts +1 -1
  71. package/dist/api/sleep-run.js +13 -9
  72. package/dist/api/status.d.ts +24 -0
  73. package/dist/api/status.js +40 -0
  74. package/dist/api/store-init.d.ts +4 -0
  75. package/dist/api/store-init.js +9 -0
  76. package/dist/api/tokens.js +1 -1
  77. package/dist/api/types.d.ts +2 -0
  78. package/dist/api/types.js +6 -1
  79. package/dist/capture/caller-session.d.ts +0 -3
  80. package/dist/capture/caller-session.js +1 -12
  81. package/dist/capture/capture-error.d.ts +2 -2
  82. package/dist/capture/capture-error.js +23 -18
  83. package/dist/capture/codex-patch.js +3 -1
  84. package/dist/capture/command.js +36 -95
  85. package/dist/capture/compact.js +10 -5
  86. package/dist/capture/compaction-items-caller.js +11 -20
  87. package/dist/capture/compaction-record.d.ts +7 -93
  88. package/dist/capture/compaction-record.js +29 -426
  89. package/dist/capture/compaction-spool.d.ts +4 -2
  90. package/dist/capture/compaction-spool.js +20 -6
  91. package/dist/capture/copilot-transcript.d.ts +2 -1
  92. package/dist/capture/copilot-transcript.js +2 -1
  93. package/dist/capture/extract.d.ts +5 -2
  94. package/dist/capture/extract.js +4 -3
  95. package/dist/capture/failure-caller.d.ts +1 -1
  96. package/dist/capture/failure-caller.js +21 -16
  97. package/dist/capture/failure-reading.d.ts +2 -1
  98. package/dist/capture/failure-reading.js +7 -9
  99. package/dist/capture/pre-compact-caller.js +5 -4
  100. package/dist/capture/session-digest.js +4 -3
  101. package/dist/capture/session-end-caller.js +2 -1
  102. package/dist/capture/session-worker.js +3 -4
  103. package/dist/capture/transcript.d.ts +2 -1
  104. package/dist/capture/transcript.js +6 -3
  105. package/dist/capture/working-state.d.ts +4 -2
  106. package/dist/capture/working-state.js +4 -2
  107. package/dist/cli/audit-prune.d.ts +0 -25
  108. package/dist/cli/audit-prune.js +1 -27
  109. package/dist/cli/audit.js +13 -13
  110. package/dist/cli/auth.d.ts +1 -1
  111. package/dist/cli/auth.js +12 -13
  112. package/dist/cli/briefs.d.ts +1 -4
  113. package/dist/cli/briefs.js +37 -292
  114. package/dist/cli/card.js +41 -33
  115. package/dist/cli/client.d.ts +5 -0
  116. package/dist/cli/client.js +24 -8
  117. package/dist/cli/compact-resume-payload.js +1 -1
  118. package/dist/cli/context.d.ts +1 -1
  119. package/dist/cli/context.js +12 -12
  120. package/dist/cli/continuity.d.ts +1 -1
  121. package/dist/cli/continuity.js +36 -39
  122. package/dist/cli/curate.d.ts +1 -1
  123. package/dist/cli/curate.js +23 -27
  124. package/dist/cli/dag.d.ts +1 -1
  125. package/dist/cli/dag.js +23 -8
  126. package/dist/cli/decisions.d.ts +0 -2
  127. package/dist/cli/decisions.js +4 -281
  128. package/dist/cli/eval.d.ts +1 -1
  129. package/dist/cli/eval.js +12 -13
  130. package/dist/cli/explain.d.ts +1 -1
  131. package/dist/cli/explain.js +21 -25
  132. package/dist/cli/flag-values.js +16 -6
  133. package/dist/cli/flags.d.ts +0 -289
  134. package/dist/cli/flags.js +3 -138
  135. package/dist/cli/graph.d.ts +3 -0
  136. package/dist/cli/graph.js +83 -0
  137. package/dist/cli/hook-runtime.d.ts +3 -5
  138. package/dist/cli/hook-runtime.js +7 -34
  139. package/dist/cli/incidents.d.ts +3 -0
  140. package/dist/cli/incidents.js +112 -0
  141. package/dist/cli/init.d.ts +1 -1
  142. package/dist/cli/init.js +28 -19
  143. package/dist/cli/install-steps.d.ts +2 -1
  144. package/dist/cli/install-steps.js +11 -3
  145. package/dist/cli/last-sleep.js +1 -1
  146. package/dist/cli/lenient-id.d.ts +2 -0
  147. package/dist/cli/lenient-id.js +13 -0
  148. package/dist/cli/maintenance.d.ts +3 -3
  149. package/dist/cli/maintenance.js +29 -30
  150. package/dist/cli/notes.d.ts +2 -0
  151. package/dist/cli/notes.js +41 -0
  152. package/dist/cli/open-browser.d.ts +14 -0
  153. package/dist/cli/open-browser.js +26 -0
  154. package/dist/cli/playbooks.d.ts +3 -4
  155. package/dist/cli/playbooks.js +126 -290
  156. package/dist/cli/predictions.d.ts +3 -0
  157. package/dist/cli/predictions.js +175 -0
  158. package/dist/cli/print.js +2 -1
  159. package/dist/cli/projects.js +30 -22
  160. package/dist/cli/quality-repair-once.d.ts +1 -1
  161. package/dist/cli/quality-repair-once.js +6 -5
  162. package/dist/cli/recall.js +13 -7
  163. package/dist/cli/refine-llm.js +17 -17
  164. package/dist/cli/remember.js +12 -12
  165. package/dist/cli/scheduler.js +2 -1
  166. package/dist/cli/serve.js +3 -3
  167. package/dist/cli/session-hooks.d.ts +1 -1
  168. package/dist/cli/session-hooks.js +45 -115
  169. package/dist/cli/setup.d.ts +1 -1
  170. package/dist/cli/setup.js +17 -10
  171. package/dist/cli/shared.d.ts +2 -6
  172. package/dist/cli/shared.js +9 -29
  173. package/dist/cli/sleep-render.js +6 -3
  174. package/dist/cli/sleep.js +6 -37
  175. package/dist/cli/status.d.ts +3 -3
  176. package/dist/cli/status.js +32 -35
  177. package/dist/cli/transfer.d.ts +1 -1
  178. package/dist/cli/transfer.js +33 -31
  179. package/dist/cli/usage.d.ts +0 -79
  180. package/dist/cli/usage.js +1 -695
  181. package/dist/cli/verb-row.d.ts +32 -0
  182. package/dist/cli/verb-row.js +6 -0
  183. package/dist/cli/verbs/health.d.ts +27 -0
  184. package/dist/cli/verbs/health.js +232 -0
  185. package/dist/cli/verbs/memory.d.ts +16 -0
  186. package/dist/cli/verbs/memory.js +244 -0
  187. package/dist/cli/verbs/objects.d.ts +20 -0
  188. package/dist/cli/verbs/objects.js +254 -0
  189. package/dist/cli/verbs/sessions.d.ts +31 -0
  190. package/dist/cli/verbs/sessions.js +312 -0
  191. package/dist/cli/verbs.d.ts +81 -0
  192. package/dist/cli/verbs.js +7 -0
  193. package/dist/cli/versioned-verbs.d.ts +51 -0
  194. package/dist/cli/versioned-verbs.js +79 -0
  195. package/dist/cli.d.ts +1 -272
  196. package/dist/cli.js +23 -313
  197. package/dist/connectors/dlq.d.ts +39 -3
  198. package/dist/connectors/dlq.js +37 -3
  199. package/dist/connectors/github/backfill.js +12 -3
  200. package/dist/connectors/github/dlq.js +31 -73
  201. package/dist/connectors/github/ingest.d.ts +2 -6
  202. package/dist/connectors/github/ingest.js +3 -28
  203. package/dist/connectors/github/webhook.d.ts +2 -1
  204. package/dist/connectors/github/webhook.js +33 -2
  205. package/dist/connectors/ingest.d.ts +10 -0
  206. package/dist/connectors/ingest.js +28 -0
  207. package/dist/connectors/slack/dlq.js +49 -71
  208. package/dist/connectors/slack/ingest.d.ts +2 -6
  209. package/dist/connectors/slack/ingest.js +2 -27
  210. package/dist/connectors/slack/webhook.d.ts +2 -1
  211. package/dist/connectors/slack/webhook.js +2 -1
  212. package/dist/consolidate/conflicts.js +1 -1
  213. package/dist/consolidate/dag.js +15 -9
  214. package/dist/consolidate/dedupe.d.ts +7 -0
  215. package/dist/consolidate/dedupe.js +5 -3
  216. package/dist/consolidate/llm-passes.js +45 -19
  217. package/dist/consolidate/memory-value.js +2 -1
  218. package/dist/consolidate/merge.js +2 -2
  219. package/dist/consolidate/physics-pass.d.ts +6 -1
  220. package/dist/consolidate/physics-pass.js +26 -6
  221. package/dist/consolidate/replay.js +11 -4
  222. package/dist/consolidate/sleep.js +8 -5
  223. package/dist/consolidate/traces.js +3 -3
  224. package/dist/core/ablation.d.ts +10 -0
  225. package/dist/core/ablation.js +12 -0
  226. package/dist/{sharing/scope.d.ts → core/active-scope.d.ts} +1 -1
  227. package/dist/{sharing/scope.js → core/active-scope.js} +1 -1
  228. package/dist/core/ambient.d.ts +4 -0
  229. package/dist/core/ambient.js +39 -18
  230. package/dist/core/api-errors.d.ts +16 -0
  231. package/dist/core/api-errors.js +20 -0
  232. package/dist/core/card.js +3 -1
  233. package/dist/core/compaction-timing.d.ts +7 -0
  234. package/dist/core/compaction-timing.js +9 -0
  235. package/dist/core/config.d.ts +1 -1
  236. package/dist/core/config.js +7 -2
  237. package/dist/core/cosine.d.ts +3 -0
  238. package/dist/core/cosine.js +19 -0
  239. package/dist/{store → core}/markdown.d.ts +1 -1
  240. package/dist/{store → core}/markdown.js +2 -2
  241. package/dist/core/memory-audit.d.ts +17 -0
  242. package/dist/core/memory-audit.js +54 -0
  243. package/dist/core/memory.d.ts +10 -4
  244. package/dist/core/memory.js +25 -18
  245. package/dist/{consolidate → core}/merged-row.d.ts +1 -1
  246. package/dist/{consolidate → core}/merged-row.js +1 -1
  247. package/dist/core/physics.js +6 -16
  248. package/dist/core/prediction.d.ts +3 -0
  249. package/dist/core/prediction.js +6 -0
  250. package/dist/core/project-identity.d.ts +3 -0
  251. package/dist/core/project-identity.js +10 -1
  252. package/dist/{store → core}/recall-scope.d.ts +1 -10
  253. package/dist/{store → core}/recall-scope.js +2 -19
  254. package/dist/db/busy.d.ts +2 -7
  255. package/dist/db/busy.js +21 -26
  256. package/dist/db/connect.d.ts +0 -1
  257. package/dist/db/connect.js +5 -6
  258. package/dist/db/index.d.ts +3 -3
  259. package/dist/db/index.js +3 -3
  260. package/dist/db/migrations/index.d.ts +1 -1
  261. package/dist/db/migrations/index.js +3 -1
  262. package/dist/db/migrations/v55.d.ts +3 -0
  263. package/dist/db/migrations/v55.js +17 -0
  264. package/dist/db/open.d.ts +0 -2
  265. package/dist/db/open.js +6 -10
  266. package/dist/db/physics-state.js +3 -3
  267. package/dist/db/tables.d.ts +2 -0
  268. package/dist/db/tables.js +6 -2
  269. package/dist/db/vector-store.js +17 -4
  270. package/dist/db/wal-checkpointer.js +2 -1
  271. package/dist/doctor.js +11 -8
  272. package/dist/embeddings/local.d.ts +62 -0
  273. package/dist/embeddings/local.js +146 -0
  274. package/dist/{store/embeddings → embeddings}/provider.d.ts +5 -2
  275. package/dist/{store/embeddings → embeddings}/provider.js +18 -15
  276. package/dist/embeddings/transformers.d.ts +26 -0
  277. package/dist/embeddings/transformers.js +89 -0
  278. package/dist/entry/session-text.d.ts +1 -1
  279. package/dist/entry/session-text.js +1 -1
  280. package/dist/eval/eval-suite.js +17 -11
  281. package/dist/eval/eval.js +1 -1
  282. package/dist/eval/judgment.js +11 -4
  283. package/dist/graph/extract.js +3 -3
  284. package/dist/graph/recall.js +1 -1
  285. package/dist/graph/view.js +13 -5
  286. package/dist/graph/write.d.ts +1 -1
  287. package/dist/graph/write.js +9 -9
  288. package/dist/hooks/codex-session.js +3 -2
  289. package/dist/hooks/codex-wrapper.js +2 -1
  290. package/dist/hooks/json-hooks.js +4 -2
  291. package/dist/hooks/opencode.js +8 -5
  292. package/dist/hooks/shared.d.ts +0 -6
  293. package/dist/hooks/shared.js +4 -15
  294. package/dist/importers/core.js +1 -1
  295. package/dist/importers/sources.js +5 -4
  296. package/dist/importers/vault.js +7 -5
  297. package/dist/index.d.ts +3 -2
  298. package/dist/index.js +3 -2
  299. package/dist/learn/autolearn.d.ts +10 -2
  300. package/dist/learn/autolearn.js +32 -12
  301. package/dist/learn/churn-git.js +13 -4
  302. package/dist/learn/extract.d.ts +3 -2
  303. package/dist/learn/extract.js +6 -4
  304. package/dist/learn/forward-claim-detector.js +4 -2
  305. package/dist/learn/invalidation.js +10 -6
  306. package/dist/mcp/admin-tools.d.ts +2 -2
  307. package/dist/mcp/admin-tools.js +27 -48
  308. package/dist/mcp/format.js +3 -2
  309. package/dist/mcp/framing.d.ts +1 -0
  310. package/dist/mcp/framing.js +1 -1
  311. package/dist/mcp/memory-tools.js +3 -1
  312. package/dist/mcp/protocol.d.ts +11 -7
  313. package/dist/mcp/protocol.js +25 -12
  314. package/dist/mcp/recall-tools.js +12 -9
  315. package/dist/mcp/request.js +2 -1
  316. package/dist/mcp/stdio.js +24 -8
  317. package/dist/mcp/tool-args.js +2 -1
  318. package/dist/mcp/tools.js +44 -21
  319. package/dist/objects/customer-notes.d.ts +2 -2
  320. package/dist/objects/decisions.d.ts +2 -2
  321. package/dist/objects/descriptor.d.ts +1 -1
  322. package/dist/objects/incidents.d.ts +2 -2
  323. package/dist/objects/lifecycle.d.ts +1 -1
  324. package/dist/objects/lifecycle.js +2 -1
  325. package/dist/objects/policies.d.ts +2 -2
  326. package/dist/objects/policies.js +2 -1
  327. package/dist/objects/processes.d.ts +2 -2
  328. package/dist/objects/project-briefs.d.ts +2 -2
  329. package/dist/objects/project-briefs.js +2 -3
  330. package/dist/objects/skills.d.ts +2 -2
  331. package/dist/postinstall.js +1 -1
  332. package/dist/rerankers/clef.js +3 -6
  333. package/dist/rerankers/cross-encoder.d.ts +31 -2
  334. package/dist/rerankers/cross-encoder.js +63 -97
  335. package/dist/rerankers/index.js +5 -4
  336. package/dist/rerankers/jev.js +2 -4
  337. package/dist/rerankers/outage-warning.d.ts +3 -1
  338. package/dist/rerankers/outage-warning.js +5 -3
  339. package/dist/search/bm25-search.js +1 -1
  340. package/dist/search/boosts.js +1 -1
  341. package/dist/search/embed-memories.d.ts +9 -0
  342. package/dist/search/embed-memories.js +377 -0
  343. package/dist/search/goal-boost.d.ts +1 -1
  344. package/dist/search/goal-boost.js +6 -3
  345. package/dist/search/hybrid.d.ts +9 -2
  346. package/dist/search/hybrid.js +9 -4
  347. package/dist/search/physics-search.d.ts +6 -3
  348. package/dist/search/physics-search.js +22 -15
  349. package/dist/search/rerank.js +1 -1
  350. package/dist/search/vector.d.ts +8 -6
  351. package/dist/search/vector.js +10 -13
  352. package/dist/server/auth.d.ts +2 -0
  353. package/dist/server/auth.js +17 -7
  354. package/dist/server/boot.js +7 -66
  355. package/dist/server/client-ip.d.ts +0 -2
  356. package/dist/server/client-ip.js +3 -2
  357. package/dist/server/deadline.d.ts +0 -2
  358. package/dist/server/deadline.js +1 -7
  359. package/dist/server/defaults.d.ts +1 -0
  360. package/dist/server/defaults.js +1 -0
  361. package/dist/server/mcp-http.js +16 -11
  362. package/dist/server/request.js +7 -2
  363. package/dist/server/route-checks.d.ts +7 -0
  364. package/dist/server/route-checks.js +42 -0
  365. package/dist/server/route-table.d.ts +9 -8
  366. package/dist/server/route-table.js +127 -132
  367. package/dist/server/routes/admin.d.ts +8 -8
  368. package/dist/server/routes/admin.js +13 -21
  369. package/dist/server/routes/customer-notes.d.ts +6 -6
  370. package/dist/server/routes/customer-notes.js +1 -2
  371. package/dist/server/routes/decisions.d.ts +6 -6
  372. package/dist/server/routes/decisions.js +2 -4
  373. package/dist/server/routes/incidents.d.ts +6 -6
  374. package/dist/server/routes/incidents.js +2 -5
  375. package/dist/server/routes/memories.d.ts +9 -9
  376. package/dist/server/routes/memories.js +15 -38
  377. package/dist/server/routes/object-routes.d.ts +6 -6
  378. package/dist/server/routes/object-routes.js +4 -7
  379. package/dist/server/routes/policies.d.ts +7 -7
  380. package/dist/server/routes/policies.js +2 -4
  381. package/dist/server/routes/predictions.d.ts +6 -6
  382. package/dist/server/routes/predictions.js +9 -13
  383. package/dist/server/routes/processes.d.ts +6 -6
  384. package/dist/server/routes/processes.js +1 -2
  385. package/dist/server/routes/project-briefs.d.ts +7 -7
  386. package/dist/server/routes/project-briefs.js +2 -4
  387. package/dist/server/routes/recall.d.ts +5 -5
  388. package/dist/server/routes/recall.js +6 -10
  389. package/dist/server/routes/skills.d.ts +7 -7
  390. package/dist/server/routes/skills.js +2 -4
  391. package/dist/server/server-detect.d.ts +7 -1
  392. package/dist/server/server-detect.js +36 -11
  393. package/dist/server/sleep-child.js +26 -7
  394. package/dist/server/sleep-offload.d.ts +11 -5
  395. package/dist/server/sleep-offload.js +17 -11
  396. package/dist/server/types.d.ts +22 -10
  397. package/dist/server/validation.d.ts +1 -2
  398. package/dist/server/validation.js +6 -11
  399. package/dist/server.d.ts +5 -4
  400. package/dist/server.js +5 -4
  401. package/dist/sharing/global-store.js +2 -2
  402. package/dist/sharing/global-sync.js +38 -45
  403. package/dist/sharing/project-merge.d.ts +7 -14
  404. package/dist/sharing/project-merge.js +57 -121
  405. package/dist/sharing/search-both.js +1 -1
  406. package/dist/sharing/share.d.ts +2 -0
  407. package/dist/sharing/share.js +37 -34
  408. package/dist/store/ambient.js +5 -6
  409. package/dist/store/audit-event.d.ts +1 -1
  410. package/dist/store/audit.d.ts +0 -16
  411. package/dist/store/audit.js +4 -55
  412. package/dist/store/auth.d.ts +4 -2
  413. package/dist/store/auth.js +7 -3
  414. package/dist/store/candidates.d.ts +3 -2
  415. package/dist/store/candidates.js +42 -23
  416. package/dist/store/capture-write.d.ts +17 -0
  417. package/dist/store/capture-write.js +35 -0
  418. package/dist/store/cards.js +1 -1
  419. package/dist/store/compaction-caller.d.ts +18 -0
  420. package/dist/store/compaction-caller.js +29 -0
  421. package/dist/store/compactions-record.d.ts +115 -0
  422. package/dist/store/compactions-record.js +417 -0
  423. package/dist/store/compactions.js +6 -4
  424. package/dist/store/conflicts.js +7 -4
  425. package/dist/store/connectors/dlq.d.ts +10 -0
  426. package/dist/store/connectors/dlq.js +32 -0
  427. package/dist/store/connectors/github.d.ts +7 -9
  428. package/dist/store/connectors/github.js +30 -53
  429. package/dist/store/connectors/slack.d.ts +2 -11
  430. package/dist/store/connectors/slack.js +18 -47
  431. package/dist/store/dashboard-reads.js +7 -6
  432. package/dist/store/delete-and-batch.d.ts +6 -0
  433. package/dist/store/delete-and-batch.js +36 -3
  434. package/dist/store/delivery-recorder.d.ts +10 -3
  435. package/dist/store/delivery-recorder.js +12 -5
  436. package/dist/store/descendant-page.js +6 -3
  437. package/dist/store/dormant.d.ts +1 -1
  438. package/dist/store/dormant.js +3 -1
  439. package/dist/store/embeddings/index.d.ts +2 -12
  440. package/dist/store/embeddings/index.js +5 -374
  441. package/dist/store/entry-reads.d.ts +13 -4
  442. package/dist/store/entry-reads.js +47 -11
  443. package/dist/store/entry-writes.d.ts +5 -5
  444. package/dist/store/entry-writes.js +32 -12
  445. package/dist/store/failure-log-at.d.ts +8 -0
  446. package/dist/store/failure-log-at.js +16 -0
  447. package/dist/store/failure-log.d.ts +2 -2
  448. package/dist/store/failure-log.js +5 -3
  449. package/dist/{trust → store}/gated-write.d.ts +3 -1
  450. package/dist/{trust → store}/gated-write.js +7 -5
  451. package/dist/store/goals.js +20 -18
  452. package/dist/store/graph-reads.js +4 -2
  453. package/dist/store/graph-writes.d.ts +6 -6
  454. package/dist/store/graph-writes.js +48 -71
  455. package/dist/store/handoffs.d.ts +1 -1
  456. package/dist/store/handoffs.js +6 -6
  457. package/dist/store/index-and-stats.js +2 -2
  458. package/dist/store/key-writes.js +1 -1
  459. package/dist/store/ledger-turn.d.ts +9 -0
  460. package/dist/store/ledger-turn.js +38 -0
  461. package/dist/store/mirrors.js +10 -6
  462. package/dist/store/open.d.ts +0 -4
  463. package/dist/store/open.js +40 -53
  464. package/dist/store/pilot-arm.d.ts +12 -0
  465. package/dist/store/pilot-arm.js +42 -0
  466. package/dist/store/port.d.ts +9 -3
  467. package/dist/store/port.js +8 -0
  468. package/dist/store/predictions.d.ts +1 -2
  469. package/dist/store/predictions.js +3 -6
  470. package/dist/store/project-tags.d.ts +62 -0
  471. package/dist/store/project-tags.js +67 -0
  472. package/dist/store/quarantine.js +2 -1
  473. package/dist/store/recall-trace.d.ts +2 -0
  474. package/dist/store/recall-trace.js +18 -2
  475. package/dist/store/rejected-values.js +2 -1
  476. package/dist/store/rejection-probe.d.ts +4 -0
  477. package/dist/store/rejection-probe.js +19 -0
  478. package/dist/store/rejection.d.ts +0 -17
  479. package/dist/store/rejection.js +1 -21
  480. package/dist/store/rule-sql.d.ts +9 -0
  481. package/dist/store/rule-sql.js +21 -2
  482. package/dist/store/search-rows.js +9 -4
  483. package/dist/store/sessions.js +4 -2
  484. package/dist/store/set-aside.d.ts +14 -0
  485. package/dist/store/set-aside.js +23 -0
  486. package/dist/store/sqlite/busy.d.ts +3 -0
  487. package/dist/store/sqlite/busy.js +8 -0
  488. package/dist/store/sqlite/connector-events-group.js +4 -7
  489. package/dist/store/sqlite/connector-writes-group.js +3 -3
  490. package/dist/store/sqlite/entry-writes-group.js +2 -2
  491. package/dist/store/sqlite/error-codec.js +4 -3
  492. package/dist/store/sqlite/executor.js +10 -4
  493. package/dist/store/sqlite/graph-reads-group.js +1 -1
  494. package/dist/store/sqlite/held-connection.d.ts +9 -0
  495. package/dist/store/sqlite/held-connection.js +41 -0
  496. package/dist/store/sqlite/object-rows.d.ts +1 -1
  497. package/dist/store/sqlite/objects-group.d.ts +1 -1
  498. package/dist/store/sqlite/objects-group.js +1 -1
  499. package/dist/store/sqlite/store.js +14 -12
  500. package/dist/store/summaries.d.ts +3 -3
  501. package/dist/store/summaries.js +5 -4
  502. package/dist/store/token-ledger.d.ts +0 -7
  503. package/dist/store/token-ledger.js +0 -35
  504. package/dist/store/vector-index.js +3 -2
  505. package/dist/support-bundle.js +2 -3
  506. package/dist/trust/reject-flow.js +2 -2
  507. package/dist/util/agent-homes.d.ts +15 -0
  508. package/dist/util/agent-homes.js +34 -0
  509. package/dist/util/anthropic-messages.d.ts +3 -0
  510. package/dist/util/anthropic-messages.js +22 -5
  511. package/dist/util/chunked.d.ts +3 -0
  512. package/dist/util/chunked.js +10 -0
  513. package/dist/util/ellipsize.d.ts +3 -0
  514. package/dist/util/ellipsize.js +5 -0
  515. package/dist/util/env.d.ts +2 -1
  516. package/dist/util/env.js +2 -1
  517. package/dist/util/format.d.ts +3 -0
  518. package/dist/util/format.js +6 -0
  519. package/dist/util/hook-payload.d.ts +8 -0
  520. package/dist/util/hook-payload.js +37 -0
  521. package/dist/util/http-retry.d.ts +6 -0
  522. package/dist/util/http-retry.js +43 -5
  523. package/dist/util/http-util.d.ts +0 -8
  524. package/dist/util/http-util.js +10 -21
  525. package/dist/util/limits.d.ts +7 -0
  526. package/dist/util/limits.js +14 -0
  527. package/dist/util/log.d.ts +4 -0
  528. package/dist/util/log.js +9 -0
  529. package/dist/util/request-scope.d.ts +3 -1
  530. package/dist/util/request-scope.js +11 -6
  531. package/dist/util/secret-detect.js +6 -1
  532. package/dist/util/sqlite-blocked.d.ts +2 -0
  533. package/dist/util/sqlite-blocked.js +5 -0
  534. package/dist/util/stream-tee.d.ts +3 -0
  535. package/dist/util/stream-tee.js +35 -0
  536. package/dist/util/time.d.ts +4 -0
  537. package/dist/util/time.js +4 -0
  538. package/dist/util/version.d.ts +1 -1
  539. package/dist/util/version.js +1 -1
  540. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  541. package/extensions/openclaw-plugin/package.json +1 -1
  542. package/openclaw.plugin.json +1 -1
  543. package/package.json +2 -2
  544. package/dist/store/embeddings/local.d.ts +0 -15
  545. package/dist/store/embeddings/local.js +0 -175
  546. /package/dist/{cli → api}/correction-latency.d.ts +0 -0
  547. /package/dist/{cli → api}/correction-latency.js +0 -0
  548. /package/dist/{cli → api}/provenance-coverage.d.ts +0 -0
  549. /package/dist/{cli → api}/provenance-coverage.js +0 -0
  550. /package/dist/{store → core}/object-types.d.ts +0 -0
  551. /package/dist/{store → core}/object-types.js +0 -0
  552. /package/dist/{capture → util}/compaction-items.d.ts +0 -0
  553. /package/dist/{capture → util}/compaction-items.js +0 -0
  554. /package/dist/{store → util}/yaml.d.ts +0 -0
  555. /package/dist/{store → util}/yaml.js +0 -0
@@ -5,14 +5,16 @@ import { DAY_MS } from '../util/time.js';
5
5
  export const FAILURE_LOG_RETENTION_DAYS = 90;
6
6
  /** Longest session id or tool name kept; the hook payload is not trusted to be short. */
7
7
  const MAX_FIELD = 128;
8
- /** Append one failure row and prune rows past {@link FAILURE_LOG_RETENTION_DAYS}. */
8
+ /** Prune rows past {@link FAILURE_LOG_RETENTION_DAYS}, then append one failure row; returns the new row's id. */
9
9
  export function recordFailure(db, event) {
10
10
  // Normalised, because the window and prune compare timestamps as strings.
11
11
  const now = new Date(event.now ?? Date.now()).toISOString();
12
- db.prepare(`INSERT INTO failure_log (ts, tenant_id, session_id, tool, outcome, skip_rule, sig_hash, detail_hash, owner_subject, origin_project, request_id)
13
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(now, event.tenantId, event.sessionId?.slice(0, MAX_FIELD) ?? null, event.tool?.slice(0, MAX_FIELD) ?? null, event.outcome, event.rule ?? null, event.sigHash ?? null, event.detailHash ?? null, event.ownerSubject ?? null, event.originProject ?? null, event.requestId ?? null);
12
+ // Prune first: nothing after the insert can throw, so a returned id always means a committed row.
14
13
  const cutoff = new Date(Date.parse(now) - FAILURE_LOG_RETENTION_DAYS * DAY_MS).toISOString();
15
14
  db.prepare(`DELETE FROM failure_log WHERE ts < ?`).run(cutoff);
15
+ const inserted = db.prepare(`INSERT INTO failure_log (ts, tenant_id, session_id, tool, outcome, skip_rule, sig_hash, detail_hash, owner_subject, origin_project, request_id)
16
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(now, event.tenantId, event.sessionId?.slice(0, MAX_FIELD) ?? null, event.tool?.slice(0, MAX_FIELD) ?? null, event.outcome, event.rule ?? null, event.sigHash ?? null, event.detailHash ?? null, event.ownerSubject ?? null, event.originProject ?? null, event.requestId ?? null);
17
+ return Number(inserted.lastInsertRowid);
16
18
  }
17
19
  /** The outcome logged for a caller's request id, or null, so a retried send finds the first one; another session's id is a ConflictError. */
18
20
  export function requestOutcome(db, tenantId, requestId, sessionId) {
@@ -1,7 +1,9 @@
1
1
  import type { DatabaseSyncLike } from '../db/index.js';
2
2
  import type { MemoryEntry } from '../core/memory.js';
3
3
  export type GatedWriteResult = 'written' | 'skipped:not-worth-storing' | 'skipped:secret' | 'skipped:rejected';
4
- /** Runs on the caller's handle so it nests in the caller's transaction (writeEntry would open a second handle and wait on that lock); the caller mirrors after commit with an entry it stamped itself. The rejection audit lands inside that transaction, which is safe because a batch that rolls back stays `summarised` and replay writes the audit again. */
4
+ /** Runs on the caller's handle so it nests in the caller's transaction (writeEntry would open a second handle and wait on that lock); the
5
+ * caller mirrors after commit with an entry it stamped itself. The rejection audit lands inside that transaction, which is safe because
6
+ * a batch that rolls back stays `summarised` and replay writes the audit again. */
5
7
  export declare function gatedWrite(db: DatabaseSyncLike, hippoRoot: string, entry: MemoryEntry, opts?: {
6
8
  actor?: string;
7
9
  worthCheck?: boolean;
@@ -1,11 +1,13 @@
1
1
  // The one write path for text no person typed into hippo: capture, compaction items and imported agent memories.
2
2
  import { isContentWorthStoring } from '../core/memory-quality.js';
3
- import { RejectedValueError } from '../store/rejection.js';
3
+ import { RejectedValueError } from '../core/api-errors.js';
4
4
  import { detectSecret } from '../util/secret-detect.js';
5
- import { auditRejectionRefusal } from '../store/audit-event.js';
6
- import { stampOriginProject } from '../store/entry-row.js';
7
- import { writeEntryDbOnly } from '../store/entry-writes.js';
8
- /** Runs on the caller's handle so it nests in the caller's transaction (writeEntry would open a second handle and wait on that lock); the caller mirrors after commit with an entry it stamped itself. The rejection audit lands inside that transaction, which is safe because a batch that rolls back stays `summarised` and replay writes the audit again. */
5
+ import { auditRejectionRefusal } from './audit-event.js';
6
+ import { stampOriginProject } from './entry-row.js';
7
+ import { writeEntryDbOnly } from './entry-writes.js';
8
+ /** Runs on the caller's handle so it nests in the caller's transaction (writeEntry would open a second handle and wait on that lock); the
9
+ * caller mirrors after commit with an entry it stamped itself. The rejection audit lands inside that transaction, which is safe because
10
+ * a batch that rolls back stays `summarised` and replay writes the audit again. */
9
11
  export function gatedWrite(db, hippoRoot, entry, opts) {
10
12
  // Off for imported agent memories: a person wrote those notes, and a one-line preference fails the check.
11
13
  if (opts?.worthCheck !== false && !isContentWorthStoring(entry.content))
@@ -146,26 +146,28 @@ function getActiveGoalsWithDb(db, opts) {
146
146
  // Per-goal retrieval_policy multipliers compose onto the base goal-tag boost and are hard-capped at MAX_FINAL_MULTIPLIER (3.0x) before scoring.
147
147
  function loadGoalPolicies(db, active) {
148
148
  const policiesByGoalId = new Map();
149
+ const policyIds = [...new Set(active.flatMap((g) => (g.retrievalPolicyId ? [g.retrievalPolicyId] : [])))];
150
+ if (policyIds.length === 0)
151
+ return policiesByGoalId;
152
+ // SAFETY: the SELECT projects exactly these seven retrieval_policy columns; MAX_ACTIVE_GOAL_DEPTH bounds the IN list.
153
+ const rows = db.prepare(`
154
+ SELECT id, goal_id, policy_type, weight_schema_fit, weight_recency, weight_outcome, error_priority
155
+ FROM retrieval_policy WHERE id IN (${policyIds.map(() => '?').join(',')})
156
+ `).all(...policyIds);
157
+ const byId = new Map(rows.map((row) => [row.id, row]));
149
158
  for (const g of active) {
150
- if (!g.retrievalPolicyId)
159
+ const row = g.retrievalPolicyId ? byId.get(g.retrievalPolicyId) : undefined;
160
+ if (!row)
151
161
  continue;
152
- // SAFETY: the row comes from the SELECT above, which projects exactly
153
- // these seven retrieval_policy columns.
154
- const row = db.prepare(`
155
- SELECT id, goal_id, policy_type, weight_schema_fit, weight_recency, weight_outcome, error_priority
156
- FROM retrieval_policy WHERE id = ?
157
- `).get(g.retrievalPolicyId);
158
- if (row) {
159
- policiesByGoalId.set(g.id, {
160
- id: row.id,
161
- goalId: row.goal_id,
162
- policyType: row.policy_type,
163
- weightSchemaFit: row.weight_schema_fit,
164
- weightRecency: row.weight_recency,
165
- weightOutcome: row.weight_outcome,
166
- errorPriority: row.error_priority,
167
- });
168
- }
162
+ policiesByGoalId.set(g.id, {
163
+ id: row.id,
164
+ goalId: row.goal_id,
165
+ policyType: row.policy_type,
166
+ weightSchemaFit: row.weight_schema_fit,
167
+ weightRecency: row.weight_recency,
168
+ weightOutcome: row.weight_outcome,
169
+ errorPriority: row.error_priority,
170
+ });
169
171
  }
170
172
  return policiesByGoalId;
171
173
  }
@@ -1,9 +1,10 @@
1
1
  // The graph reads a view and a traversal share. Each opens hippo.db itself unless the caller hands it the handle its snapshot runs on.
2
+ import { DEFAULT_LIST_LIMIT } from '../util/limits.js';
2
3
  import { openHippoDb, closeHippoDb, withReadSnapshot } from '../db/index.js';
3
4
  import { onHandle } from './open.js';
4
5
  import { assertTenantId } from './tenant.js';
5
6
  import { GRAPH_ENTITY_TYPES, rowToEntity, rowToRelation, ENTITY_COLS, RELATION_COLS } from './graph-rows.js';
6
- const DEFAULT_GRAPH_PAGE_SIZE = 100;
7
+ const DEFAULT_GRAPH_PAGE_SIZE = DEFAULT_LIST_LIMIT;
7
8
  const DEFAULT_GRAPH_SCAN_LIMIT = 1000;
8
9
  /** Entities with an exact `name`, bounded by `limit` in SQL with a deterministic order, so graph-view focus finds `--entity NAME` directly
9
10
  * without materializing every same-name row. */
@@ -207,7 +208,8 @@ export function storedGraphOn(db, tenantId, memoryIds) {
207
208
  // SAFETY: the SELECT names exactly the columns of StoredEntity.
208
209
  const entities = db.prepare(`SELECT id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id FROM entities WHERE tenant_id = ? ORDER BY id`).all(tenantId);
209
210
  // SAFETY: the SELECT names exactly the columns of StoredRelation.
210
- const relations = db.prepare(`SELECT id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id FROM relations WHERE tenant_id = ? ORDER BY id`).all(tenantId);
211
+ const relations = db.prepare(`SELECT id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id ` +
212
+ `FROM relations WHERE tenant_id = ? ORDER BY id`).all(tenantId);
211
213
  return { kinds, entities, relations };
212
214
  }
213
215
  function memoryKindsOn(db, memoryIds) {
@@ -7,13 +7,13 @@ interface ResolvedGraphSource {
7
7
  memoryId: string | null;
8
8
  }
9
9
  export declare function resolveConsolidatedSource(db: DatabaseSyncLike, tenantId: string, memoryId: string | null, sourceObject: SourceObjectRef | null, label: string): ResolvedGraphSource;
10
- /** Insert a graph entity extracted from a consolidated memory; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
11
- export declare function insertEntity(hippoRoot: string, tenantId: string, opts: InsertEntityOpts, txDb?: DatabaseSyncLike): Entity;
12
- /** Renames an entity or moves its memory provenance in place, keeping id and created_at; null when the row is gone.
10
+ /** Insert a graph entity on the caller's handle; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
11
+ export declare function insertEntityRow(db: DatabaseSyncLike, tenantId: string, opts: InsertEntityOpts): Entity;
12
+ /** Renames an entity or moves its memory provenance in place on the caller's handle, keeping id and created_at; null when the row is gone.
13
13
  * A delete plus an insert would cascade away every relation that points at it. */
14
- export declare function updateEntity(hippoRoot: string, tenantId: string, id: number, opts: UpdateEntityOpts, txDb?: DatabaseSyncLike): Entity | null;
15
- /** Insert a graph relation between two same-tenant entities, sourced from a consolidated memory. */
16
- export declare function insertRelation(hippoRoot: string, tenantId: string, opts: InsertRelationOpts, txDb?: DatabaseSyncLike): Relation;
14
+ export declare function updateEntityRow(db: DatabaseSyncLike, tenantId: string, id: number, opts: UpdateEntityOpts): Entity | null;
15
+ /** Insert a graph relation between two same-tenant entities on the caller's handle, sourced from a consolidated memory. */
16
+ export declare function insertRelationRow(db: DatabaseSyncLike, tenantId: string, opts: InsertRelationOpts): Relation;
17
17
  /** The source object still holds the loader's rule (active or superseded); a closed or gone one gets no new graph row. */
18
18
  export declare function objectInForce(db: DatabaseSyncLike, tenantId: string, ref: SourceObjectRef): boolean;
19
19
  /** The lowest-id entity of this type anchored to the source object, which is the row a rebuild keeps. */
@@ -71,8 +71,8 @@ function assertSourceObjectUsable(db, tenantId, sourceObject, label) {
71
71
  }
72
72
  }
73
73
  }
74
- /** Insert a graph entity extracted from a consolidated memory; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
75
- export function insertEntity(hippoRoot, tenantId, opts, txDb) {
74
+ /** Insert a graph entity on the caller's handle; throws if the source memory is missing / cross-tenant / raw (the DB trigger is the backstop). */
75
+ export function insertEntityRow(db, tenantId, opts) {
76
76
  assertTenantId('insertEntity', tenantId);
77
77
  if (!GRAPH_ENTITY_TYPES.has(opts.entityType)) {
78
78
  throw new Error(`insertEntity: entityType must be one of ${Array.from(GRAPH_ENTITY_TYPES).join('|')}; got ${opts.entityType}`);
@@ -81,25 +81,17 @@ export function insertEntity(hippoRoot, tenantId, opts, txDb) {
81
81
  const now = new Date().toISOString();
82
82
  const memoryId = opts.memoryId ?? null;
83
83
  const sourceObject = opts.sourceObject ?? null;
84
- const ownDb = txDb ? null : openHippoDb(hippoRoot);
85
- const db = txDb ?? ownDb;
86
- try {
87
- const { sourceKind, memoryId: effectiveMemoryId } = resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, 'insertEntity');
88
- const result = db.prepare(`
89
- INSERT INTO entities(tenant_id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id, created_at)
90
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
91
- `).run(tenantId, opts.entityType, name, effectiveMemoryId, sourceKind, sourceObject?.type ?? null, sourceObject?.id ?? null, now);
92
- const id = Number(result.lastInsertRowid ?? 0);
93
- // SAFETY: row's shape matches the columns named in ENTITY_COLS above.
94
- const row = db.prepare(`SELECT ${ENTITY_COLS} FROM entities WHERE id = ?`).get(id);
95
- if (!row)
96
- throw new Error('insertEntity: failed to reload inserted entity');
97
- return rowToEntity(row);
98
- }
99
- finally {
100
- if (ownDb)
101
- closeHippoDb(ownDb);
102
- }
84
+ const { sourceKind, memoryId: effectiveMemoryId } = resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, 'insertEntity');
85
+ const result = db.prepare(`
86
+ INSERT INTO entities(tenant_id, entity_type, name, memory_id, source_kind, source_object_type, source_object_id, created_at)
87
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
88
+ `).run(tenantId, opts.entityType, name, effectiveMemoryId, sourceKind, sourceObject?.type ?? null, sourceObject?.id ?? null, now);
89
+ const id = Number(result.lastInsertRowid ?? 0);
90
+ // SAFETY: row's shape matches the columns named in ENTITY_COLS above.
91
+ const row = db.prepare(`SELECT ${ENTITY_COLS} FROM entities WHERE id = ?`).get(id);
92
+ if (!row)
93
+ throw new Error('insertEntity: failed to reload inserted entity');
94
+ return rowToEntity(row);
103
95
  }
104
96
  function checkedName(label, raw) {
105
97
  const name = (raw ?? '').trim();
@@ -110,33 +102,26 @@ function checkedName(label, raw) {
110
102
  }
111
103
  return name;
112
104
  }
113
- /** Renames an entity or moves its memory provenance in place, keeping id and created_at; null when the row is gone.
105
+ /** Renames an entity or moves its memory provenance in place on the caller's handle, keeping id and created_at; null when the row is gone.
114
106
  * A delete plus an insert would cascade away every relation that points at it. */
115
- export function updateEntity(hippoRoot, tenantId, id, opts, txDb) {
107
+ export function updateEntityRow(db, tenantId, id, opts) {
116
108
  assertTenantId('updateEntity', tenantId);
117
109
  const name = checkedName('updateEntity', opts.name);
118
- const db = txDb ?? openHippoDb(hippoRoot);
119
- try {
120
- // SAFETY: row's shape matches the columns named in ENTITY_COLS above.
121
- const row = db.prepare(`SELECT ${ENTITY_COLS} FROM entities WHERE id = ? AND tenant_id = ?`).get(id, tenantId);
122
- if (!row)
123
- return null;
124
- const entity = rowToEntity(row);
125
- const sourceObject = entity.sourceObjectType === undefined || entity.sourceObjectId === undefined
126
- ? null
127
- : { type: entity.sourceObjectType, id: entity.sourceObjectId };
128
- const resolved = resolveConsolidatedSource(db, tenantId, opts.memoryId ?? null, sourceObject, 'updateEntity');
129
- db.prepare(`UPDATE entities SET name = ?, memory_id = ?, source_kind = ? WHERE id = ? AND tenant_id = ?`)
130
- .run(name, resolved.memoryId, resolved.sourceKind, id, tenantId);
131
- return { ...entity, name, memoryId: resolved.memoryId, sourceKind: resolved.sourceKind };
132
- }
133
- finally {
134
- if (db !== txDb)
135
- closeHippoDb(db);
136
- }
110
+ // SAFETY: row's shape matches the columns named in ENTITY_COLS above.
111
+ const row = db.prepare(`SELECT ${ENTITY_COLS} FROM entities WHERE id = ? AND tenant_id = ?`).get(id, tenantId);
112
+ if (!row)
113
+ return null;
114
+ const entity = rowToEntity(row);
115
+ const sourceObject = entity.sourceObjectType === undefined || entity.sourceObjectId === undefined
116
+ ? null
117
+ : { type: entity.sourceObjectType, id: entity.sourceObjectId };
118
+ const resolved = resolveConsolidatedSource(db, tenantId, opts.memoryId ?? null, sourceObject, 'updateEntity');
119
+ db.prepare(`UPDATE entities SET name = ?, memory_id = ?, source_kind = ? WHERE id = ? AND tenant_id = ?`)
120
+ .run(name, resolved.memoryId, resolved.sourceKind, id, tenantId);
121
+ return { ...entity, name, memoryId: resolved.memoryId, sourceKind: resolved.sourceKind };
137
122
  }
138
- /** Insert a graph relation between two same-tenant entities, sourced from a consolidated memory. */
139
- export function insertRelation(hippoRoot, tenantId, opts, txDb) {
123
+ /** Insert a graph relation between two same-tenant entities on the caller's handle, sourced from a consolidated memory. */
124
+ export function insertRelationRow(db, tenantId, opts) {
140
125
  assertTenantId('insertRelation', tenantId);
141
126
  if (!GRAPH_RELATION_TYPES.has(opts.relType)) {
142
127
  throw new Error(`insertRelation: relType must be one of ${Array.from(GRAPH_RELATION_TYPES).join('|')}; got ${opts.relType}`);
@@ -144,35 +129,27 @@ export function insertRelation(hippoRoot, tenantId, opts, txDb) {
144
129
  const now = new Date().toISOString();
145
130
  const memoryId = opts.memoryId ?? null;
146
131
  const sourceObject = opts.sourceObject ?? null;
147
- const ownDb = txDb ? null : openHippoDb(hippoRoot);
148
- const db = txDb ?? ownDb;
149
- try {
150
- for (const [eid, role] of [[opts.fromEntityId, 'from'], [opts.toEntityId, 'to']]) {
151
- // SAFETY: ent's shape matches the single `tenant_id` column named in
152
- // the SELECT above.
153
- const ent = db.prepare(`SELECT tenant_id FROM entities WHERE id = ?`).get(eid);
154
- if (!ent)
155
- throw new Error(`insertRelation: ${role}_entity ${eid} not found`);
156
- if (ent.tenant_id !== tenantId) {
157
- throw new Error(`insertRelation: ${role}_entity ${eid} belongs to another tenant (no cross-tenant edges)`);
158
- }
132
+ for (const [eid, role] of [[opts.fromEntityId, 'from'], [opts.toEntityId, 'to']]) {
133
+ // SAFETY: ent's shape matches the single `tenant_id` column named in
134
+ // the SELECT above.
135
+ const ent = db.prepare(`SELECT tenant_id FROM entities WHERE id = ?`).get(eid);
136
+ if (!ent)
137
+ throw new Error(`insertRelation: ${role}_entity ${eid} not found`);
138
+ if (ent.tenant_id !== tenantId) {
139
+ throw new Error(`insertRelation: ${role}_entity ${eid} belongs to another tenant (no cross-tenant edges)`);
159
140
  }
160
- const { sourceKind, memoryId: effectiveMemoryId } = resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, 'insertRelation');
161
- const result = db.prepare(`
162
- INSERT INTO relations(tenant_id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id, created_at)
163
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
164
- `).run(tenantId, opts.fromEntityId, opts.toEntityId, opts.relType, effectiveMemoryId, sourceKind, sourceObject?.type ?? null, sourceObject?.id ?? null, now);
165
- const id = Number(result.lastInsertRowid ?? 0);
166
- // SAFETY: row's shape matches the columns named in RELATION_COLS above.
167
- const row = db.prepare(`SELECT ${RELATION_COLS} FROM relations WHERE id = ?`).get(id);
168
- if (!row)
169
- throw new Error('insertRelation: failed to reload inserted relation');
170
- return rowToRelation(row);
171
- }
172
- finally {
173
- if (ownDb)
174
- closeHippoDb(ownDb);
175
141
  }
142
+ const { sourceKind, memoryId: effectiveMemoryId } = resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, 'insertRelation');
143
+ const result = db.prepare(`
144
+ INSERT INTO relations(tenant_id, from_entity_id, to_entity_id, rel_type, memory_id, source_kind, source_object_type, source_object_id, created_at)
145
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
146
+ `).run(tenantId, opts.fromEntityId, opts.toEntityId, opts.relType, effectiveMemoryId, sourceKind, sourceObject?.type ?? null, sourceObject?.id ?? null, now);
147
+ const id = Number(result.lastInsertRowid ?? 0);
148
+ // SAFETY: row's shape matches the columns named in RELATION_COLS above.
149
+ const row = db.prepare(`SELECT ${RELATION_COLS} FROM relations WHERE id = ?`).get(id);
150
+ if (!row)
151
+ throw new Error('insertRelation: failed to reload inserted relation');
152
+ return rowToRelation(row);
176
153
  }
177
154
  /** The source object still holds the loader's rule (active or superseded); a closed or gone one gets no new graph row. */
178
155
  export function objectInForce(db, tenantId, ref) {
@@ -2,7 +2,7 @@ import { type SessionHandoff, type HandoffOutcome, type HandoffEvidence } from '
2
2
  import type { TaskSnapshot } from './rows.js';
3
3
  import { type ContinuityKey } from './sessions.js';
4
4
  /** Column list shared by every session_handoffs SELECT; cards.ts reuses it for the card handoff lookup. */
5
- export declare const HANDOFF_COLUMNS = "id, session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, created_at, constraints_json, evidence_json, outcome, target_runtime, card_id";
5
+ export declare const HANDOFF_COLUMNS: string;
6
6
  /** Save a session handoff record; returns the persisted handoff. */
7
7
  export declare function saveSessionHandoff(hippoRoot: string, tenantId: string, handoff: Omit<SessionHandoff, 'updatedAt'>, key?: ContinuityKey): SessionHandoff;
8
8
  interface HandoffFilter {
@@ -1,11 +1,12 @@
1
1
  import { closeHippoDb } from '../db/index.js';
2
2
  import { rowToSessionHandoff, isHandoffOutcome, } from '../core/handoff.js';
3
- import { scopeAdmitSql } from './recall-scope.js';
3
+ import { scopeAdmitSql } from './rule-sql.js';
4
4
  import { assertTenantId } from './tenant.js';
5
5
  import { onHandle, openStore } from './open.js';
6
6
  import { continuityStamp, continuityWhere, loadActiveTaskSnapshot } from './sessions.js';
7
7
  /** Column list shared by every session_handoffs SELECT; cards.ts reuses it for the card handoff lookup. */
8
- export const HANDOFF_COLUMNS = 'id, session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, created_at, constraints_json, evidence_json, outcome, target_runtime, card_id';
8
+ export const HANDOFF_COLUMNS = 'id, session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, created_at, constraints_json, ' +
9
+ 'evidence_json, outcome, target_runtime, card_id';
9
10
  /** Save a session handoff record; returns the persisted handoff. */
10
11
  export function saveSessionHandoff(hippoRoot, tenantId, handoff, key) {
11
12
  assertTenantId('saveSessionHandoff', tenantId);
@@ -15,10 +16,9 @@ export function saveSessionHandoff(hippoRoot, tenantId, handoff, key) {
15
16
  // Scope is stored as given; read-side default-deny in api.recall + cmdRecall
16
17
  // continuity excludes slack:private:* and 'unknown:legacy'.
17
18
  try {
18
- const result = db.prepare(`
19
- INSERT INTO session_handoffs(session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, tenant_id, created_at, constraints_json, evidence_json, outcome, target_runtime, card_id, owner_subject, origin_project)
20
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
21
- `).run(handoff.sessionId, handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, tenantId, now, JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, stamp?.owner ?? null, stamp?.origin ?? null);
19
+ const result = db.prepare(`\n INSERT INTO session_handoffs(session_id, repo_root, task_id, summary, next_action, artifacts_json, scope, tenant_id, created_at, ` +
20
+ `constraints_json, evidence_json, outcome, target_runtime, card_id, owner_subject, origin_project)\n` +
21
+ ` VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(handoff.sessionId, handoff.repoRoot ?? null, handoff.taskId ?? null, handoff.summary, handoff.nextAction ?? null, JSON.stringify(handoff.artifacts ?? []), handoff.scope ?? null, tenantId, now, JSON.stringify(handoff.constraints ?? []), handoff.evidence ? JSON.stringify(handoff.evidence) : null, handoff.outcome ?? null, handoff.targetRuntime ?? null, handoff.cardId ?? null, stamp?.owner ?? null, stamp?.origin ?? null);
22
22
  const id = Number(result.lastInsertRowid ?? 0);
23
23
  // SAFETY: row's shape matches HANDOFF_COLUMNS.
24
24
  const row = db.prepare(`SELECT ${HANDOFF_COLUMNS} FROM session_handoffs WHERE id = ?`).get(id);
@@ -1,5 +1,5 @@
1
1
  import { withWriteScope, setMeta, isSqliteBusy, pruneConsolidationRuns, getMeta } from '../db/index.js';
2
- import { RejectedValueError } from './rejection.js';
2
+ import { RejectedValueError } from '../core/api-errors.js';
3
3
  import { log } from '../util/log.js';
4
4
  import { audit } from './audit-event.js';
5
5
  import { stampOriginProjectForImport, upsertEntryRow } from './entry-row.js';
@@ -113,7 +113,7 @@ export function loadStats(hippoRoot) {
113
113
  export function appendConsolidationRun(hippoRoot, run) {
114
114
  onHandle(hippoRoot, (db) => {
115
115
  db.prepare(`INSERT INTO consolidation_runs(timestamp, decayed, merged, removed) VALUES (?, ?, ?, ?)`).run(run.timestamp, run.decayed, run.merged, run.removed);
116
- pruneConsolidationRuns(db, 50);
116
+ pruneConsolidationRuns(db);
117
117
  writeStatsMirror(hippoRoot, buildStatsFromDb(db));
118
118
  }, openStore);
119
119
  }
@@ -3,7 +3,7 @@ import { BadRequestError, ConflictError, NotFoundError } from '../core/api-error
3
3
  import { appendAuditEvent } from './audit.js';
4
4
  import { grantScope, insertApiKey, listLiveOwnedKeyIds, revokeApiKey, ungrantScope } from './auth.js';
5
5
  import { withWriteScope } from '../db/index.js';
6
- import { isRestrictedScope } from './recall-scope.js';
6
+ import { isRestrictedScope } from '../core/recall-scope.js';
7
7
  import { selectApiKeyOwner } from './tenant-lookup.js';
8
8
  /** The auth_create row a mint writes; the plaintext never reaches it. */
9
9
  function createAuditOf({ key, actor, metadata }) {
@@ -1,5 +1,9 @@
1
1
  import type { DeliveryEventInput } from './delivery-recorder.js';
2
2
  import { type LastSent, type TokenSurface, type TokenUse } from './token-ledger.js';
3
+ import { type PilotArm } from './pilot-arm.js';
4
+ /** Says why a ledger row did not land, at the level its class earns: busy warns once through
5
+ * noteStoreBusy, absent is debug with no stack, unexpected warns once with the error class and stack. */
6
+ export declare function noteLedgerRowSkipped<E>(error: E): void;
3
7
  /** Stores one delivery event and returns its id, or null when the write failed. */
4
8
  export type DeliveryWrite = (input: DeliveryEventInput) => number | null;
5
9
  /** The token rows of one turn and the delivery event that follows them. */
@@ -14,4 +18,9 @@ export interface LedgerTurn {
14
18
  export declare function recordLedgerTurn(hippoRoot: string, turn: LedgerTurn): void;
15
19
  /** What the session last sent on `surface`, or null, as lastSentState reads it. */
16
20
  export declare function lastSentOnSurface(hippoRoot: string, tenantId: string, sessionId: string | null | undefined, surface: TokenSurface): LastSent | null;
21
+ /** The session's pilot arm: `write` books it as ensurePilotArm does, else the stored arm or the hash arm. */
22
+ export declare function pilotArmOnRoot(hippoRoot: string, tenantId: string, sessionId: string, rateBp: number, opts: {
23
+ write: boolean;
24
+ ownTenantOnly?: boolean;
25
+ }): PilotArm;
17
26
  //# sourceMappingURL=ledger-turn.d.ts.map
@@ -1,6 +1,37 @@
1
+ // One hook or context turn's token-ledger work by store root: each call opens hippo.db, runs on one connection and closes it.
2
+ import { isSqliteBusy, noteStoreBusy } from '../db/index.js';
3
+ import { errorFields, errorMessage, log } from '../util/log.js';
1
4
  import { lastSentState, recordTokenUse } from './token-ledger.js';
2
5
  import { onHandle } from './open.js';
6
+ import { ensurePilotArm, hashArm, readPilotArm } from './pilot-arm.js';
3
7
  import { writeDeliveryEventOnHandle } from './recall-trace.js';
8
+ // SQLite's result codes for a hippo.db it cannot read: a corrupt image, and a file that is no database.
9
+ const SQLITE_CORRUPT = 11;
10
+ const SQLITE_NOTADB = 26;
11
+ /** The one rule for a skipped ledger row. `absent` is a store with no token_ledger table or a hippo.db
12
+ * SQLite cannot read; the command that owns the store reports that, and a hook must stay quiet about it. */
13
+ function ledgerSkipClass(error) {
14
+ if (isSqliteBusy(error))
15
+ return 'busy';
16
+ const code = error instanceof Error && 'errcode' in error ? error.errcode : undefined;
17
+ if (code === SQLITE_CORRUPT || code === SQLITE_NOTADB)
18
+ return 'absent';
19
+ return errorMessage(error).includes('no such table: token_ledger') ? 'absent' : 'unexpected';
20
+ }
21
+ /** Says why a ledger row did not land, at the level its class earns: busy warns once through
22
+ * noteStoreBusy, absent is debug with no stack, unexpected warns once with the error class and stack. */
23
+ export function noteLedgerRowSkipped(error) {
24
+ const skip = ledgerSkipClass(error);
25
+ if (skip === 'busy') {
26
+ noteStoreBusy('token ledger row skipped');
27
+ return;
28
+ }
29
+ const message = `token ledger row skipped: ${errorMessage(error)}`;
30
+ if (skip === 'absent')
31
+ log.debug(message);
32
+ else
33
+ log.warnThenDebug('token-ledger-row', message, errorFields(error));
34
+ }
4
35
  /** Books a turn's token rows, then its delivery event, on one connection. */
5
36
  export function recordLedgerTurn(hippoRoot, turn) {
6
37
  const { onRowError } = turn;
@@ -24,4 +55,11 @@ export function recordLedgerTurn(hippoRoot, turn) {
24
55
  export function lastSentOnSurface(hippoRoot, tenantId, sessionId, surface) {
25
56
  return onHandle(hippoRoot, (db) => lastSentState(db, tenantId, sessionId, surface));
26
57
  }
58
+ /** The session's pilot arm: `write` books it as ensurePilotArm does, else the stored arm or the hash arm. */
59
+ export function pilotArmOnRoot(hippoRoot, tenantId, sessionId, rateBp, opts) {
60
+ const { ownTenantOnly } = opts;
61
+ return onHandle(hippoRoot, (db) => opts.write
62
+ ? ensurePilotArm(db, tenantId, sessionId, rateBp, { ownTenantOnly })
63
+ : readPilotArm(db, sessionId, ownTenantOnly ? tenantId : undefined) ?? hashArm(sessionId, rateBp));
64
+ }
27
65
  //# sourceMappingURL=ledger-turn.js.map
@@ -2,12 +2,12 @@ import { DEFAULT_TENANT_ID } from '../util/env.js';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import { Layer } from '../core/memory.js';
5
- import { dumpFrontmatter } from './yaml.js';
6
- import { getMeta } from '../db/index.js';
5
+ import { dumpFrontmatter } from '../util/yaml.js';
6
+ import { getMeta, CONSOLIDATION_RUNS_KEPT } from '../db/index.js';
7
7
  import { oncePerStore } from '../db/connect.js';
8
8
  import { errorFields, errorMessage, log } from '../util/log.js';
9
9
  import { parseJsonArray, INDEX_VERSION, parseLastTraceId, MEMORY_SELECT_COLUMNS, rowToEntry, rowToMemoryConflict, } from './rows.js';
10
- import { serializeEntry } from './markdown.js';
10
+ import { serializeEntry } from '../core/markdown.js';
11
11
  const SCORE_DECIMALS = 3;
12
12
  export function layerDir(root, layer) {
13
13
  return path.join(root, layer);
@@ -223,8 +223,12 @@ export function readLastRecall(db) {
223
223
  };
224
224
  }
225
225
  export function buildStatsFromDb(db) {
226
- // SAFETY: runs' shape matches the four columns named in the SELECT above.
227
- const runs = db.prepare(`SELECT timestamp, decayed, merged, removed FROM consolidation_runs ORDER BY timestamp ASC, id ASC`).all();
226
+ // SAFETY: runs' shape matches the four columns named in the SELECT below.
227
+ const runs = db.prepare(`
228
+ SELECT timestamp, decayed, merged, removed FROM (
229
+ SELECT id, timestamp, decayed, merged, removed FROM consolidation_runs ORDER BY timestamp DESC, id DESC LIMIT ?
230
+ ) ORDER BY timestamp ASC, id ASC
231
+ `).all(CONSOLIDATION_RUNS_KEPT);
228
232
  return {
229
233
  total_remembered: Number(getMeta(db, 'total_remembered', '0')),
230
234
  total_recalled: Number(getMeta(db, 'total_recalled', '0')),
@@ -240,7 +244,7 @@ export function buildStatsFromDb(db) {
240
244
  /** Write the `index.json` mirror file for an already-derived index. Exported for
241
245
  * `rebuildIndex` (the only index.json writer) and the longmemeval benchmark. */
242
246
  export function writeIndexMirror(hippoRoot, index) {
243
- mirrorBestEffort('index.json', () => fs.writeFileSync(path.join(hippoRoot, 'index.json'), JSON.stringify(index, null, 2), 'utf8'));
247
+ mirrorBestEffort('index.json', () => overwriteInPlace(path.join(hippoRoot, 'index.json'), JSON.stringify(index, null, 2)));
244
248
  }
245
249
  export function writeStatsMirror(hippoRoot, stats) {
246
250
  mirrorBestEffort('stats.json', () => overwriteInPlace(path.join(hippoRoot, 'stats.json'), JSON.stringify(stats, null, 2)));
@@ -1,9 +1,5 @@
1
1
  import { type MemoryEntry } from '../core/memory.js';
2
2
  import { type DatabaseSyncLike } from '../db/index.js';
3
- import { type ResolveProjectIdentityOpts } from '../core/project-identity.js';
4
- /** Nearest ancestor store like git; the strict join is the fallback so `hippo init` still creates `<cwd>/.hippo`. */
5
- export declare function getHippoRoot(cwd?: string, opts?: ResolveProjectIdentityOpts): string;
6
- export declare function isInitialized(hippoRoot: string): boolean;
7
3
  export declare function initStore(hippoRoot: string): void;
8
4
  /** One open connection with init done on it, for callers who used to pay for `initStore` + a second `openHippoDb`. */
9
5
  export declare function openStore(hippoRoot: string, opts?: {