hippo-memory 1.60.0 → 1.61.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 (585) hide show
  1. package/README.md +1 -1
  2. package/dist/ablation.js +9 -27
  3. package/dist/agent-memories/apply.js +4 -1
  4. package/dist/agent-memories/claude-code.js +1 -1
  5. package/dist/agent-memories/codex.js +1 -1
  6. package/dist/agent-memories/gemini.js +1 -1
  7. package/dist/agent-memories/legacy.js +1 -1
  8. package/dist/agent-memories/source.js +1 -1
  9. package/dist/agent-memories/sync.js +8 -3
  10. package/dist/ambient-store.d.ts +14 -0
  11. package/dist/ambient-store.js +90 -0
  12. package/dist/ambient.d.ts +23 -0
  13. package/dist/ambient.js +72 -50
  14. package/dist/api/assemble.d.ts +93 -0
  15. package/dist/api/assemble.js +152 -0
  16. package/dist/api/audit.d.ts +17 -0
  17. package/dist/api/audit.js +23 -0
  18. package/dist/api/auth.d.ts +79 -0
  19. package/dist/api/auth.js +178 -0
  20. package/dist/api/context-types.d.ts +105 -0
  21. package/dist/api/context-types.js +3 -0
  22. package/dist/api/context.d.ts +31 -0
  23. package/dist/api/context.js +705 -0
  24. package/dist/api/dormant.d.ts +30 -0
  25. package/dist/api/dormant.js +140 -0
  26. package/dist/api/drill-down.d.ts +84 -0
  27. package/dist/api/drill-down.js +123 -0
  28. package/dist/api/forget.d.ts +57 -0
  29. package/dist/api/forget.js +87 -0
  30. package/dist/api/goals.d.ts +18 -0
  31. package/dist/api/goals.js +33 -0
  32. package/dist/api/learn.d.ts +31 -0
  33. package/dist/api/learn.js +88 -0
  34. package/dist/api/outcome.d.ts +61 -0
  35. package/dist/api/outcome.js +66 -0
  36. package/dist/api/promote.d.ts +54 -0
  37. package/dist/api/promote.js +203 -0
  38. package/dist/api/quarantine.d.ts +24 -0
  39. package/dist/api/quarantine.js +121 -0
  40. package/dist/api/recall-types.d.ts +390 -0
  41. package/dist/api/recall-types.js +3 -0
  42. package/dist/api/recall.d.ts +36 -0
  43. package/dist/api/recall.js +634 -0
  44. package/dist/api/remember.d.ts +35 -0
  45. package/dist/api/remember.js +43 -0
  46. package/dist/api/sleep.d.ts +136 -0
  47. package/dist/api/sleep.js +271 -0
  48. package/dist/api/tokens.d.ts +26 -0
  49. package/dist/api/tokens.js +60 -0
  50. package/dist/api/types.d.ts +56 -0
  51. package/dist/api/types.js +38 -0
  52. package/dist/api.d.ts +20 -1262
  53. package/dist/api.js +25 -2727
  54. package/dist/audit.d.ts +3 -0
  55. package/dist/audit.js +6 -3
  56. package/dist/auth.d.ts +45 -4
  57. package/dist/auth.js +125 -48
  58. package/dist/autolearn.js +2 -2
  59. package/dist/capture/command.d.ts +33 -0
  60. package/dist/capture/command.js +264 -0
  61. package/dist/capture/compact.d.ts +44 -0
  62. package/dist/capture/compact.js +354 -0
  63. package/dist/capture/extract.d.ts +21 -0
  64. package/dist/capture/extract.js +464 -0
  65. package/dist/capture/transcript.d.ts +40 -0
  66. package/dist/capture/transcript.js +193 -0
  67. package/dist/capture-error.js +2 -1
  68. package/dist/churn-git.js +4 -2
  69. package/dist/cli/audit.d.ts +3 -0
  70. package/dist/cli/audit.js +159 -0
  71. package/dist/cli/auth.d.ts +2 -0
  72. package/dist/cli/auth.js +171 -0
  73. package/dist/cli/briefs.d.ts +4 -0
  74. package/dist/cli/briefs.js +435 -0
  75. package/dist/cli/card.d.ts +3 -0
  76. package/dist/cli/card.js +333 -0
  77. package/dist/cli/context.d.ts +15 -0
  78. package/dist/cli/context.js +366 -0
  79. package/dist/cli/continuity.d.ts +6 -0
  80. package/dist/cli/continuity.js +445 -0
  81. package/dist/cli/curate.d.ts +19 -0
  82. package/dist/cli/curate.js +555 -0
  83. package/dist/cli/dag.d.ts +5 -0
  84. package/dist/cli/dag.js +177 -0
  85. package/dist/cli/decisions.d.ts +4 -0
  86. package/dist/cli/decisions.js +528 -0
  87. package/dist/cli/eval.d.ts +5 -0
  88. package/dist/cli/eval.js +213 -0
  89. package/dist/cli/explain.d.ts +4 -0
  90. package/dist/cli/explain.js +150 -0
  91. package/dist/cli/goals.d.ts +2 -0
  92. package/dist/cli/goals.js +196 -0
  93. package/dist/cli/hook-blocks.d.ts +18 -0
  94. package/dist/cli/hook-blocks.js +233 -0
  95. package/dist/cli/init.d.ts +2 -0
  96. package/dist/cli/init.js +305 -0
  97. package/dist/cli/maintenance.d.ts +4 -0
  98. package/dist/cli/maintenance.js +179 -0
  99. package/dist/cli/playbooks.d.ts +4 -0
  100. package/dist/cli/playbooks.js +556 -0
  101. package/dist/cli/projects.js +1 -1
  102. package/dist/cli/recall.d.ts +7 -0
  103. package/dist/cli/recall.js +597 -0
  104. package/dist/cli/remember.d.ts +5 -0
  105. package/dist/cli/remember.js +442 -0
  106. package/dist/cli/serve.d.ts +5 -0
  107. package/dist/cli/serve.js +40 -0
  108. package/dist/cli/session-hooks.d.ts +29 -0
  109. package/dist/cli/session-hooks.js +637 -0
  110. package/dist/cli/setup.d.ts +4 -0
  111. package/dist/cli/setup.js +376 -0
  112. package/dist/cli/shared.d.ts +15 -19
  113. package/dist/cli/shared.js +50 -341
  114. package/dist/cli/slack.d.ts +2 -0
  115. package/dist/cli/slack.js +171 -0
  116. package/dist/cli/status.d.ts +18 -0
  117. package/dist/cli/status.js +400 -0
  118. package/dist/cli/transfer.d.ts +10 -0
  119. package/dist/cli/transfer.js +438 -0
  120. package/dist/cli/usage.d.ts +85 -0
  121. package/dist/cli/usage.js +741 -0
  122. package/dist/cli.d.ts +71 -120
  123. package/dist/cli.js +170 -8469
  124. package/dist/client.js +15 -8
  125. package/dist/compaction-record.js +6 -4
  126. package/dist/connectors/github/backfill.js +94 -87
  127. package/dist/connectors/github/cli-impl.js +4 -3
  128. package/dist/connectors/github/dlq.js +67 -54
  129. package/dist/connectors/github/ingest.js +34 -35
  130. package/dist/connectors/github/tenant-routing.js +3 -2
  131. package/dist/connectors/github/webhook.js +135 -216
  132. package/dist/connectors/slack/dlq.js +49 -61
  133. package/dist/connectors/slack/ingest.js +55 -48
  134. package/dist/connectors/slack/tenant-routing.js +4 -3
  135. package/dist/connectors/slack/webhook.js +72 -74
  136. package/dist/consolidate/conflicts.d.ts +10 -0
  137. package/dist/consolidate/conflicts.js +178 -0
  138. package/dist/consolidate/decay.d.ts +12 -0
  139. package/dist/consolidate/decay.js +145 -0
  140. package/dist/consolidate/llm-passes.d.ts +3 -0
  141. package/dist/consolidate/llm-passes.js +141 -0
  142. package/dist/consolidate/merge.d.ts +7 -0
  143. package/dist/consolidate/merge.js +251 -0
  144. package/dist/consolidate/physics-pass.d.ts +3 -0
  145. package/dist/consolidate/physics-pass.js +60 -0
  146. package/dist/consolidate/run.d.ts +69 -0
  147. package/dist/consolidate/run.js +76 -0
  148. package/dist/consolidate/sleep.d.ts +18 -0
  149. package/dist/consolidate/sleep.js +209 -0
  150. package/dist/consolidate/traces.d.ts +4 -0
  151. package/dist/consolidate/traces.js +178 -0
  152. package/dist/context-auto.js +7 -11
  153. package/dist/context-render.d.ts +1 -1
  154. package/dist/context-render.js +1 -1
  155. package/dist/customer-notes.d.ts +3 -0
  156. package/dist/customer-notes.js +6 -4
  157. package/dist/dag.js +6 -5
  158. package/dist/dashboard-actions.d.ts +20 -0
  159. package/dist/dashboard-actions.js +88 -0
  160. package/dist/dashboard-params.d.ts +45 -0
  161. package/dist/dashboard-params.js +127 -0
  162. package/dist/dashboard-queries.d.ts +15 -0
  163. package/dist/dashboard-queries.js +355 -0
  164. package/dist/dashboard-snapshot.d.ts +138 -0
  165. package/dist/dashboard-snapshot.js +308 -0
  166. package/dist/dashboard-types.d.ts +163 -0
  167. package/dist/dashboard-types.js +3 -0
  168. package/dist/dashboard.d.ts +6 -7
  169. package/dist/dashboard.js +228 -202
  170. package/dist/db/busy.d.ts +5 -0
  171. package/dist/db/busy.js +24 -0
  172. package/dist/db/continuity.d.ts +5 -0
  173. package/dist/db/continuity.js +145 -0
  174. package/dist/db/meta.d.ts +8 -0
  175. package/dist/db/meta.js +35 -0
  176. package/dist/db/migrate.d.ts +9 -0
  177. package/dist/db/migrate.js +138 -0
  178. package/dist/db/migrations/index.d.ts +5 -0
  179. package/dist/db/migrations/index.js +109 -0
  180. package/dist/db/migrations/types.d.ts +14 -0
  181. package/dist/db/migrations/types.js +2 -0
  182. package/dist/db/migrations/v01.d.ts +3 -0
  183. package/dist/db/migrations/v01.js +38 -0
  184. package/dist/db/migrations/v02.d.ts +3 -0
  185. package/dist/db/migrations/v02.js +21 -0
  186. package/dist/db/migrations/v03.d.ts +3 -0
  187. package/dist/db/migrations/v03.js +22 -0
  188. package/dist/db/migrations/v04.d.ts +3 -0
  189. package/dist/db/migrations/v04.js +28 -0
  190. package/dist/db/migrations/v05.d.ts +3 -0
  191. package/dist/db/migrations/v05.js +21 -0
  192. package/dist/db/migrations/v06.d.ts +3 -0
  193. package/dist/db/migrations/v06.js +25 -0
  194. package/dist/db/migrations/v07.d.ts +3 -0
  195. package/dist/db/migrations/v07.js +13 -0
  196. package/dist/db/migrations/v08.d.ts +3 -0
  197. package/dist/db/migrations/v08.js +8 -0
  198. package/dist/db/migrations/v09.d.ts +3 -0
  199. package/dist/db/migrations/v09.js +13 -0
  200. package/dist/db/migrations/v10.d.ts +3 -0
  201. package/dist/db/migrations/v10.js +17 -0
  202. package/dist/db/migrations/v11.d.ts +3 -0
  203. package/dist/db/migrations/v11.js +15 -0
  204. package/dist/db/migrations/v12.d.ts +3 -0
  205. package/dist/db/migrations/v12.js +11 -0
  206. package/dist/db/migrations/v13.d.ts +3 -0
  207. package/dist/db/migrations/v13.js +15 -0
  208. package/dist/db/migrations/v14.d.ts +3 -0
  209. package/dist/db/migrations/v14.js +66 -0
  210. package/dist/db/migrations/v15.d.ts +3 -0
  211. package/dist/db/migrations/v15.js +42 -0
  212. package/dist/db/migrations/v16.d.ts +3 -0
  213. package/dist/db/migrations/v16.js +61 -0
  214. package/dist/db/migrations/v17.d.ts +3 -0
  215. package/dist/db/migrations/v17.js +46 -0
  216. package/dist/db/migrations/v18.d.ts +3 -0
  217. package/dist/db/migrations/v18.js +60 -0
  218. package/dist/db/migrations/v19.d.ts +3 -0
  219. package/dist/db/migrations/v19.js +28 -0
  220. package/dist/db/migrations/v20.d.ts +3 -0
  221. package/dist/db/migrations/v20.js +42 -0
  222. package/dist/db/migrations/v21.d.ts +3 -0
  223. package/dist/db/migrations/v21.js +16 -0
  224. package/dist/db/migrations/v22.d.ts +3 -0
  225. package/dist/db/migrations/v22.js +82 -0
  226. package/dist/db/migrations/v23.d.ts +3 -0
  227. package/dist/db/migrations/v23.js +48 -0
  228. package/dist/db/migrations/v24.d.ts +3 -0
  229. package/dist/db/migrations/v24.js +72 -0
  230. package/dist/db/migrations/v25.d.ts +3 -0
  231. package/dist/db/migrations/v25.js +46 -0
  232. package/dist/db/migrations/v26.d.ts +3 -0
  233. package/dist/db/migrations/v26.js +23 -0
  234. package/dist/db/migrations/v27.d.ts +3 -0
  235. package/dist/db/migrations/v27.js +57 -0
  236. package/dist/db/migrations/v28.d.ts +3 -0
  237. package/dist/db/migrations/v28.js +38 -0
  238. package/dist/db/migrations/v29.d.ts +3 -0
  239. package/dist/db/migrations/v29.js +78 -0
  240. package/dist/db/migrations/v30.d.ts +3 -0
  241. package/dist/db/migrations/v30.js +92 -0
  242. package/dist/db/migrations/v31.d.ts +3 -0
  243. package/dist/db/migrations/v31.js +74 -0
  244. package/dist/db/migrations/v32.d.ts +3 -0
  245. package/dist/db/migrations/v32.js +102 -0
  246. package/dist/db/migrations/v33.d.ts +3 -0
  247. package/dist/db/migrations/v33.js +104 -0
  248. package/dist/db/migrations/v34.d.ts +3 -0
  249. package/dist/db/migrations/v34.js +93 -0
  250. package/dist/db/migrations/v35.d.ts +3 -0
  251. package/dist/db/migrations/v35.js +98 -0
  252. package/dist/db/migrations/v36.d.ts +3 -0
  253. package/dist/db/migrations/v36.js +98 -0
  254. package/dist/db/migrations/v37.d.ts +3 -0
  255. package/dist/db/migrations/v37.js +219 -0
  256. package/dist/db/migrations/v38.d.ts +3 -0
  257. package/dist/db/migrations/v38.js +277 -0
  258. package/dist/db/migrations/v39.d.ts +3 -0
  259. package/dist/db/migrations/v39.js +59 -0
  260. package/dist/db/migrations/v40.d.ts +3 -0
  261. package/dist/db/migrations/v40.js +74 -0
  262. package/dist/db/migrations/v41.d.ts +3 -0
  263. package/dist/db/migrations/v41.js +43 -0
  264. package/dist/db/migrations/v42.d.ts +3 -0
  265. package/dist/db/migrations/v42.js +41 -0
  266. package/dist/db/migrations/v43.d.ts +3 -0
  267. package/dist/db/migrations/v43.js +67 -0
  268. package/dist/db/migrations/v44.d.ts +3 -0
  269. package/dist/db/migrations/v44.js +28 -0
  270. package/dist/db/migrations/v45.d.ts +3 -0
  271. package/dist/db/migrations/v45.js +30 -0
  272. package/dist/db/migrations/v46.d.ts +3 -0
  273. package/dist/db/migrations/v46.js +25 -0
  274. package/dist/db/migrations/v47.d.ts +3 -0
  275. package/dist/db/migrations/v47.js +17 -0
  276. package/dist/db/migrations/v48.d.ts +3 -0
  277. package/dist/db/migrations/v48.js +10 -0
  278. package/dist/db/migrations/v49.d.ts +3 -0
  279. package/dist/db/migrations/v49.js +31 -0
  280. package/dist/db/migrations/v50.d.ts +3 -0
  281. package/dist/db/migrations/v50.js +67 -0
  282. package/dist/db/migrations/v51.d.ts +3 -0
  283. package/dist/db/migrations/v51.js +14 -0
  284. package/dist/db/migrations/v52.d.ts +3 -0
  285. package/dist/db/migrations/v52.js +7 -0
  286. package/dist/db/open.d.ts +23 -0
  287. package/dist/db/open.js +146 -0
  288. package/dist/db/sqlite.d.ts +21 -0
  289. package/dist/db/sqlite.js +8 -0
  290. package/dist/db/tables.d.ts +7 -0
  291. package/dist/db/tables.js +38 -0
  292. package/dist/db.d.ts +6 -46
  293. package/dist/db.js +5 -3049
  294. package/dist/decisions.d.ts +4 -1
  295. package/dist/decisions.js +9 -7
  296. package/dist/dedupe.js +3 -2
  297. package/dist/delivery-recorder.js +4 -1
  298. package/dist/doctor.js +3 -3
  299. package/dist/embedding-provider.d.ts +1 -1
  300. package/dist/embedding-provider.js +4 -3
  301. package/dist/embeddings.d.ts +9 -52
  302. package/dist/embeddings.js +43 -297
  303. package/dist/env.d.ts +75 -0
  304. package/dist/env.js +119 -0
  305. package/dist/eval-suite.js +1 -1
  306. package/dist/eval.js +2 -2
  307. package/dist/extract.js +1 -1
  308. package/dist/gated-write.js +3 -1
  309. package/dist/goals.d.ts +3 -1
  310. package/dist/goals.js +18 -0
  311. package/dist/graph/read.d.ts +73 -0
  312. package/dist/graph/read.js +325 -0
  313. package/dist/graph/rows.d.ts +45 -0
  314. package/dist/graph/rows.js +51 -0
  315. package/dist/graph/types.d.ts +83 -0
  316. package/dist/graph/types.js +11 -0
  317. package/dist/graph/write.d.ts +93 -0
  318. package/dist/{graph.js → graph/write.js} +6 -384
  319. package/dist/graph-extract.js +2 -1
  320. package/dist/graph-recall.d.ts +1 -1
  321. package/dist/graph-recall.js +2 -2
  322. package/dist/graph-stream.js +1 -1
  323. package/dist/graph-view.d.ts +1 -1
  324. package/dist/graph-view.js +1 -1
  325. package/dist/half-life-migration.d.ts +1 -1
  326. package/dist/half-life-migration.js +2 -1
  327. package/dist/hooks/codex-session.d.ts +8 -0
  328. package/dist/hooks/codex-session.js +76 -0
  329. package/dist/hooks/codex-wrapper.d.ts +55 -0
  330. package/dist/hooks/codex-wrapper.js +288 -0
  331. package/dist/hooks/json-hooks.d.ts +63 -0
  332. package/dist/hooks/json-hooks.js +356 -0
  333. package/dist/hooks/opencode.d.ts +50 -0
  334. package/dist/hooks/opencode.js +202 -0
  335. package/dist/hooks/shared.d.ts +54 -0
  336. package/dist/hooks/shared.js +77 -0
  337. package/dist/http-retry.d.ts +2 -0
  338. package/dist/http-retry.js +4 -3
  339. package/dist/http-util.d.ts +3 -0
  340. package/dist/http-util.js +10 -0
  341. package/dist/{importers.d.ts → importers/core.d.ts} +13 -17
  342. package/dist/importers/core.js +141 -0
  343. package/dist/importers/markdown-parse.d.ts +41 -0
  344. package/dist/importers/markdown-parse.js +132 -0
  345. package/dist/importers/markdown.d.ts +3 -0
  346. package/dist/importers/markdown.js +92 -0
  347. package/dist/importers/sources.d.ts +7 -0
  348. package/dist/importers/sources.js +229 -0
  349. package/dist/importers/vault.d.ts +11 -0
  350. package/dist/importers/vault.js +352 -0
  351. package/dist/incidents.d.ts +3 -0
  352. package/dist/incidents.js +7 -5
  353. package/dist/index.d.ts +25 -6
  354. package/dist/index.js +23 -6
  355. package/dist/invalidation.js +2 -1
  356. package/dist/judgment.js +2 -1
  357. package/dist/keyset.d.ts +13 -0
  358. package/dist/keyset.js +8 -0
  359. package/dist/local-embedding.d.ts +13 -0
  360. package/dist/local-embedding.js +165 -0
  361. package/dist/log.d.ts +7 -0
  362. package/dist/log.js +19 -1
  363. package/dist/mcp/admin-tools.d.ts +8 -0
  364. package/dist/mcp/admin-tools.js +116 -0
  365. package/dist/mcp/format.d.ts +27 -0
  366. package/dist/mcp/format.js +135 -0
  367. package/dist/mcp/memory-tools.d.ts +5 -0
  368. package/dist/mcp/memory-tools.js +83 -0
  369. package/dist/mcp/protocol.d.ts +83 -0
  370. package/dist/mcp/protocol.js +55 -0
  371. package/dist/mcp/recall-tools.d.ts +6 -0
  372. package/dist/mcp/recall-tools.js +320 -0
  373. package/dist/mcp/request.d.ts +10 -0
  374. package/dist/mcp/request.js +163 -0
  375. package/dist/mcp/server.d.ts +4 -75
  376. package/dist/mcp/server.js +7 -1190
  377. package/dist/mcp/session-state.d.ts +11 -0
  378. package/dist/mcp/session-state.js +28 -0
  379. package/dist/mcp/stdio.d.ts +8 -0
  380. package/dist/mcp/stdio.js +79 -0
  381. package/dist/mcp/tools.d.ts +11 -0
  382. package/dist/mcp/tools.js +247 -0
  383. package/dist/memory.d.ts +3 -0
  384. package/dist/memory.js +27 -1
  385. package/dist/multihop.d.ts +1 -1
  386. package/dist/multihop.js +2 -1
  387. package/dist/owner-validation.js +2 -1
  388. package/dist/physics-state.js +10 -7
  389. package/dist/policies.d.ts +3 -0
  390. package/dist/policies.js +8 -6
  391. package/dist/postinstall.js +3 -2
  392. package/dist/predictions/planning-fallacy.d.ts +100 -0
  393. package/dist/predictions/planning-fallacy.js +190 -0
  394. package/dist/{predictions.d.ts → predictions/store.d.ts} +7 -102
  395. package/dist/predictions/store.js +434 -0
  396. package/dist/processes.d.ts +3 -0
  397. package/dist/processes.js +7 -5
  398. package/dist/project-briefs.d.ts +3 -0
  399. package/dist/project-briefs.js +7 -5
  400. package/dist/project-identity.js +3 -2
  401. package/dist/project-merge.js +3 -1
  402. package/dist/quarantine.d.ts +2 -1
  403. package/dist/quarantine.js +8 -5
  404. package/dist/raw-archive.js +1 -1
  405. package/dist/recall-history.js +3 -2
  406. package/dist/recall-pipeline.d.ts +2 -2
  407. package/dist/recall-pipeline.js +16 -8
  408. package/dist/recall-scope.js +1 -1
  409. package/dist/recall-trace.d.ts +1 -1
  410. package/dist/refine-llm.js +2 -1
  411. package/dist/reject-flow.js +6 -1
  412. package/dist/rerankers/clef.js +6 -5
  413. package/dist/rerankers/jev.d.ts +1 -1
  414. package/dist/rerankers/jev.js +4 -4
  415. package/dist/rerankers/llm.d.ts +4 -2
  416. package/dist/rerankers/llm.js +58 -38
  417. package/dist/rerankers/types.d.ts +1 -1
  418. package/dist/salience.js +1 -1
  419. package/dist/scheduler.d.ts +1 -0
  420. package/dist/scheduler.js +26 -4
  421. package/dist/scope.js +4 -3
  422. package/dist/search/as-of.d.ts +10 -0
  423. package/dist/search/as-of.js +22 -0
  424. package/dist/search/bm25-search.d.ts +14 -0
  425. package/dist/search/bm25-search.js +43 -0
  426. package/dist/search/bm25.d.ts +15 -0
  427. package/dist/search/bm25.js +54 -0
  428. package/dist/search/boosts.d.ts +54 -0
  429. package/dist/search/boosts.js +94 -0
  430. package/dist/search/breakdown.d.ts +7 -0
  431. package/dist/search/breakdown.js +20 -0
  432. package/dist/search/explain.d.ts +25 -0
  433. package/dist/search/explain.js +31 -0
  434. package/dist/search/finalize.d.ts +8 -0
  435. package/dist/search/finalize.js +52 -0
  436. package/dist/search/fusion.d.ts +27 -0
  437. package/dist/search/fusion.js +42 -0
  438. package/dist/search/hybrid-score.d.ts +20 -0
  439. package/dist/search/hybrid-score.js +73 -0
  440. package/dist/search/hybrid.d.ts +46 -0
  441. package/dist/search/hybrid.js +64 -0
  442. package/dist/search/physics-search.d.ts +29 -0
  443. package/dist/search/physics-search.js +162 -0
  444. package/dist/search/rerank.d.ts +10 -0
  445. package/dist/search/rerank.js +72 -0
  446. package/dist/search/temporal.d.ts +15 -0
  447. package/dist/search/temporal.js +45 -0
  448. package/dist/search/types.d.ts +91 -0
  449. package/dist/search/types.js +2 -0
  450. package/dist/search/vector.d.ts +30 -0
  451. package/dist/search/vector.js +71 -0
  452. package/dist/secret-detect.d.ts +2 -0
  453. package/dist/secret-detect.js +2 -1
  454. package/dist/server/auth.d.ts +52 -0
  455. package/dist/server/auth.js +221 -0
  456. package/dist/server/client-ip.d.ts +25 -0
  457. package/dist/server/client-ip.js +92 -0
  458. package/dist/server/cursor.d.ts +23 -0
  459. package/dist/server/cursor.js +58 -0
  460. package/dist/server/lifecycle.d.ts +7 -0
  461. package/dist/server/lifecycle.js +29 -0
  462. package/dist/server/mcp-http.d.ts +5 -0
  463. package/dist/server/mcp-http.js +199 -0
  464. package/dist/server/request.d.ts +33 -0
  465. package/dist/server/request.js +103 -0
  466. package/dist/server/routes/admin.d.ts +9 -0
  467. package/dist/server/routes/admin.js +158 -0
  468. package/dist/server/routes/customer-notes.d.ts +7 -0
  469. package/dist/server/routes/customer-notes.js +112 -0
  470. package/dist/server/routes/decisions.d.ts +7 -0
  471. package/dist/server/routes/decisions.js +133 -0
  472. package/dist/server/routes/incidents.d.ts +7 -0
  473. package/dist/server/routes/incidents.js +126 -0
  474. package/dist/server/routes/memories.d.ts +10 -0
  475. package/dist/server/routes/memories.js +179 -0
  476. package/dist/server/routes/policies.d.ts +8 -0
  477. package/dist/server/routes/policies.js +151 -0
  478. package/dist/server/routes/predictions.d.ts +7 -0
  479. package/dist/server/routes/predictions.js +164 -0
  480. package/dist/server/routes/processes.d.ts +7 -0
  481. package/dist/server/routes/processes.js +161 -0
  482. package/dist/server/routes/project-briefs.d.ts +8 -0
  483. package/dist/server/routes/project-briefs.js +136 -0
  484. package/dist/server/routes/recall.d.ts +8 -0
  485. package/dist/server/routes/recall.js +340 -0
  486. package/dist/server/routes/skills.d.ts +8 -0
  487. package/dist/server/routes/skills.js +150 -0
  488. package/dist/server/types.d.ts +56 -0
  489. package/dist/server/types.js +2 -0
  490. package/dist/server/validation.d.ts +14 -0
  491. package/dist/server/validation.js +91 -0
  492. package/dist/server.d.ts +7 -61
  493. package/dist/server.js +69 -2362
  494. package/dist/session-digest.d.ts +1 -1
  495. package/dist/session-digest.js +9 -2
  496. package/dist/shared.d.ts +3 -1
  497. package/dist/shared.js +26 -22
  498. package/dist/skills.d.ts +3 -0
  499. package/dist/skills.js +7 -5
  500. package/dist/stdin.js +2 -2
  501. package/dist/store/audit-event.d.ts +19 -0
  502. package/dist/store/audit-event.js +33 -0
  503. package/dist/store/candidates.d.ts +42 -0
  504. package/dist/store/candidates.js +152 -0
  505. package/dist/store/conflicts.d.ts +44 -0
  506. package/dist/store/conflicts.js +444 -0
  507. package/dist/store/delete-and-batch.d.ts +63 -0
  508. package/dist/store/delete-and-batch.js +310 -0
  509. package/dist/store/entry-reads.d.ts +92 -0
  510. package/dist/store/entry-reads.js +255 -0
  511. package/dist/store/entry-row.d.ts +67 -0
  512. package/dist/store/entry-row.js +208 -0
  513. package/dist/store/entry-writes.d.ts +46 -0
  514. package/dist/store/entry-writes.js +148 -0
  515. package/dist/store/handoffs.d.ts +26 -0
  516. package/dist/store/handoffs.js +184 -0
  517. package/dist/store/index-and-stats.d.ts +52 -0
  518. package/dist/store/index-and-stats.js +214 -0
  519. package/dist/store/markdown.d.ts +10 -0
  520. package/dist/store/markdown.js +108 -0
  521. package/dist/store/mirrors.d.ts +49 -0
  522. package/dist/store/mirrors.js +312 -0
  523. package/dist/store/open.d.ts +15 -0
  524. package/dist/store/open.js +223 -0
  525. package/dist/store/rows.d.ts +178 -0
  526. package/dist/store/rows.js +158 -0
  527. package/dist/store/search-rows.d.ts +86 -0
  528. package/dist/store/search-rows.js +254 -0
  529. package/dist/store/sessions.d.ts +83 -0
  530. package/dist/store/sessions.js +272 -0
  531. package/dist/store/summaries.d.ts +94 -0
  532. package/dist/store/summaries.js +377 -0
  533. package/dist/store/tenant-lookup.d.ts +12 -0
  534. package/dist/store/tenant-lookup.js +16 -0
  535. package/dist/store-cards.js +2 -1
  536. package/dist/summary-dirty.d.ts +4 -0
  537. package/dist/summary-dirty.js +32 -0
  538. package/dist/support-bundle.js +4 -3
  539. package/dist/tenant.js +2 -2
  540. package/dist/tokenize.d.ts +2 -0
  541. package/dist/tokenize.js +16 -0
  542. package/dist/transcript-tail.d.ts +7 -0
  543. package/dist/transcript-tail.js +48 -0
  544. package/dist/vector-store.d.ts +27 -0
  545. package/dist/vector-store.js +210 -0
  546. package/dist/version.d.ts +2 -2
  547. package/dist/version.js +2 -2
  548. package/dist/working-memory.js +1 -1
  549. package/dist/yaml.js +36 -11
  550. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  551. package/dist-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  552. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  553. package/dist-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  554. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  555. package/dist-ui/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  556. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  557. package/dist-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  558. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  559. package/dist-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  560. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  561. package/dist-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  562. package/dist-ui/assets/index-DPN7cP19.js +33 -0
  563. package/dist-ui/assets/index-dFloKRVr.css +1 -0
  564. package/dist-ui/index.html +3 -25
  565. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  566. package/extensions/openclaw-plugin/package.json +1 -1
  567. package/openclaw.plugin.json +1 -1
  568. package/package.json +1 -1
  569. package/dist/capture.d.ts +0 -155
  570. package/dist/capture.js +0 -1295
  571. package/dist/consolidate.d.ts +0 -58
  572. package/dist/consolidate.js +0 -1124
  573. package/dist/graph.d.ts +0 -245
  574. package/dist/hooks.d.ts +0 -208
  575. package/dist/hooks.js +0 -1076
  576. package/dist/importers.js +0 -900
  577. package/dist/predictions.js +0 -620
  578. package/dist/search.d.ts +0 -320
  579. package/dist/search.js +0 -970
  580. package/dist/store.d.ts +0 -776
  581. package/dist/store.js +0 -3473
  582. package/dist-ui/assets/d3-BiWEKnn4.js +0 -1
  583. package/dist-ui/assets/index-BhT8RvO6.js +0 -61
  584. package/dist-ui/assets/index-RoXXJ5dq.css +0 -1
  585. package/dist-ui/assets/three-BDgTxR1l.js +0 -4112
@@ -0,0 +1,69 @@
1
+ import { MemoryEntry, type DecayOptions } from '../memory.js';
2
+ import { type DatabaseSyncLike } from '../db.js';
3
+ import { type DormantMove } from '../dormant.js';
4
+ import { loadConfig } from '../config.js';
5
+ export interface ConsolidationResult {
6
+ decayed: number;
7
+ removed: number;
8
+ /** Faded memories moved to the dormant store instead of deleted (config
9
+ * `dormant.enabled`; src/dormant.ts). Always 0 when that is off. */
10
+ dormant: number;
11
+ /** Dormant memories deleted for good this sleep because they outlived
12
+ * `dormant.retentionDays` without a restore. */
13
+ dormantExpired: number;
14
+ merged: number;
15
+ semanticCreated: number;
16
+ replayed: number;
17
+ promotedTraces: number;
18
+ /** T7: sessions skipped because their events span two derivation scopes. */
19
+ tracesSkippedMixedScope: number;
20
+ extractionCandidates: number;
21
+ extracted: number;
22
+ dagCandidateClusters: number;
23
+ dagSummariesCreated: number;
24
+ summariesRebuilt: number;
25
+ summariesRebuildFailed: number;
26
+ summariesZeroChildSkipped: number;
27
+ summariesRebuildRefused: number;
28
+ summariesRebuildCapped: boolean;
29
+ entityProfilesCreated: number;
30
+ dryRun: boolean;
31
+ details: string[];
32
+ physicsSimulated: number;
33
+ /** Ids the decay pass removes (or would remove, under dryRun). */
34
+ removedIds?: string[];
35
+ }
36
+ export declare const REPLAY_COUNT_DEFAULT = 5;
37
+ export declare function keptAsWritten(entry: MemoryEntry): boolean;
38
+ /** JSON value shape for a session event's free-form metadata field, cast to
39
+ * once at its `Record<string, unknown>` origin so it can be narrowed via
40
+ * isJsonString below rather than left as unparsed `unknown`. */
41
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
42
+ [key: string]: JsonValue;
43
+ };
44
+ export declare function isJsonString(value: JsonValue): value is string;
45
+ /** The sleep's one tombstone-check handle: opened on first use, never under dryRun, closed once. */
46
+ interface LazyDb {
47
+ get: () => DatabaseSyncLike | null;
48
+ close: () => void;
49
+ }
50
+ export declare function lazyConsolidateDb(hippoRoot: string, dryRun: boolean): LazyDb;
51
+ /** State every sleep stage reads or appends to; the pending lists are flushed in one transaction at the end. */
52
+ export interface SleepRun {
53
+ hippoRoot: string;
54
+ now: Date;
55
+ dryRun: boolean;
56
+ config: ReturnType<typeof loadConfig>;
57
+ decayOpts: DecayOptions;
58
+ result: ConsolidationResult;
59
+ all: MemoryEntry[];
60
+ retirable: (entry: MemoryEntry) => boolean;
61
+ getConsolidateDb: () => DatabaseSyncLike | null;
62
+ survivors: MemoryEntry[];
63
+ pendingWrites: MemoryEntry[];
64
+ pendingDeletes: string[];
65
+ pendingDormant: DormantMove[];
66
+ }
67
+ export declare function newConsolidationResult(dryRun: boolean): ConsolidationResult;
68
+ export {};
69
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1,76 @@
1
+ import { openHippoDb, closeHippoDb } from '../db.js';
2
+ import { NO_MERGE_TAGS } from '../shared.js';
3
+ export const REPLAY_COUNT_DEFAULT = 5;
4
+ export function keptAsWritten(entry) {
5
+ return entry.tags.some((tag) => NO_MERGE_TAGS.has(tag));
6
+ }
7
+ export function isJsonString(value) {
8
+ return typeof value === 'string';
9
+ }
10
+ // AT1 rejection-guard db handle (docs/plans/2026-08-15-at1-rejected-value-tombstone.md):
11
+ // covers BOTH the auto-promote pass (1.4) and the merge
12
+ // pass (3) — both build deterministic content that
13
+ // batchWriteAndDelete writes through the guard's bypass, so both need a
14
+ // producer-side tombstone check before pushing to pendingWrites.
15
+ //
16
+ // T3 fix (2026-08-15 hardening pass, perf hygiene): memoized lazy getter,
17
+ // not an eager open. The handle only serves these two tombstone checks —
18
+ // a sleep with zero promotable sessions and zero merge clusters never
19
+ // reaches either use site, so opening it unconditionally on every
20
+ // non-dry-run sleep paid a db-open cost for nothing. dryRun still never
21
+ // opens (getConsolidateDb short-circuits before touching the handle).
22
+ // consolidateDbOpened (not just a truthy handle check) is the
23
+ // single source of truth for "was this ever opened", so the finally
24
+ // closes it exactly once and never double-opens.
25
+ //
26
+ // AT1 P2 fix (codex, handle-leak restructure): the getter's lifetime must
27
+ // start IMMEDIATELY before the try whose finally closes it, covering every
28
+ // phase that can touch it — not just the merge pass. An exception thrown by
29
+ // auto-promote (1.4), replay (1.5), batch extraction (1.6), the DAG
30
+ // passes (1.7-1.9), or physics (2) would otherwise propagate past an open handle
31
+ // with nothing to close it.
32
+ export function lazyConsolidateDb(hippoRoot, dryRun) {
33
+ let consolidateDbHandle = null;
34
+ let consolidateDbOpened = false;
35
+ const get = () => {
36
+ if (dryRun)
37
+ return null;
38
+ if (!consolidateDbOpened) {
39
+ consolidateDbHandle = openHippoDb(hippoRoot);
40
+ consolidateDbOpened = true;
41
+ }
42
+ return consolidateDbHandle;
43
+ };
44
+ const close = () => {
45
+ if (consolidateDbHandle)
46
+ closeHippoDb(consolidateDbHandle);
47
+ };
48
+ return { get, close };
49
+ }
50
+ export function newConsolidationResult(dryRun) {
51
+ return {
52
+ decayed: 0,
53
+ removed: 0,
54
+ dormant: 0,
55
+ dormantExpired: 0,
56
+ merged: 0,
57
+ semanticCreated: 0,
58
+ replayed: 0,
59
+ promotedTraces: 0,
60
+ tracesSkippedMixedScope: 0,
61
+ extractionCandidates: 0,
62
+ extracted: 0,
63
+ dagCandidateClusters: 0,
64
+ dagSummariesCreated: 0,
65
+ summariesRebuilt: 0,
66
+ summariesRebuildFailed: 0,
67
+ summariesZeroChildSkipped: 0,
68
+ summariesRebuildRefused: 0,
69
+ summariesRebuildCapped: false,
70
+ entityProfilesCreated: 0,
71
+ dryRun,
72
+ details: [],
73
+ physicsSimulated: 0,
74
+ };
75
+ }
76
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Consolidation engine ("Sleep") for Hippo.
3
+ *
4
+ * Steps:
5
+ * 1. Decay pass - remove entries below strength threshold
6
+ * 2. Merge pass - find episodic entries with high text overlap, create semantic summaries
7
+ * 3. Stats tracking
8
+ */
9
+ import { type ConsolidationResult } from './run.js';
10
+ /**
11
+ * Run a full consolidation pass.
12
+ */
13
+ export declare function consolidate(hippoRoot: string, options?: {
14
+ dryRun?: boolean;
15
+ now?: Date;
16
+ fetcher?: typeof fetch;
17
+ }): Promise<ConsolidationResult>;
18
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Consolidation engine ("Sleep") for Hippo.
3
+ *
4
+ * Steps:
5
+ * 1. Decay pass - remove entries below strength threshold
6
+ * 2. Merge pass - find episodic entries with high text overlap, create semantic summaries
7
+ * 3. Stats tracking
8
+ */
9
+ import { evalNow } from '../ablation.js';
10
+ import { canAutoDelete } from '../memory.js';
11
+ import { loadAllEntries } from '../store/entry-reads.js';
12
+ import { batchWriteAndDelete, memoriesBackingObjects } from '../store/delete-and-batch.js';
13
+ import { appendConsolidationRun, loadSessionDecayContext, incrementSleepCount } from '../store/index-and-stats.js';
14
+ import { replaceDetectedConflicts } from '../store/conflicts.js';
15
+ import { openHippoDb, closeHippoDb } from '../db.js';
16
+ import { countExpiredDormant, purgeExpiredDormant } from '../dormant.js';
17
+ import { loadConfig } from '../config.js';
18
+ import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
19
+ import { migrateDefaultHalfLife, LEGACY_TYPED_HALF_LIFE } from '../half-life-migration.js';
20
+ import { log } from '../log.js';
21
+ import { decayPass } from './decay.js';
22
+ import { retireHeldTexts, mergePass } from './merge.js';
23
+ import { detectConflicts } from './conflicts.js';
24
+ import { lazyConsolidateDb, newConsolidationResult } from './run.js';
25
+ import { promoteSessionTraces, replayPass } from './traces.js';
26
+ import { llmPasses } from './llm-passes.js';
27
+ import { physicsPass } from './physics-pass.js';
28
+ /**
29
+ * Run a full consolidation pass.
30
+ */
31
+ export async function consolidate(hippoRoot, options = {}) {
32
+ const now = options.now ?? evalNow(); // honors HIPPO_FAKE_NOW (eval-only; see ablation.ts)
33
+ const dryRun = options.dryRun ?? false;
34
+ const result = newConsolidationResult(dryRun);
35
+ const halfLife = migrateHalfLives(hippoRoot, dryRun, result);
36
+ // L9: host-wide by design. Consolidation runs across all tenants in one
37
+ // pass — per-tenant filtering would create N consolidation runs per host
38
+ // with no cross-tenant dedup. The api.sleep audit row tags this with the
39
+ // admin synthetic actor; see api.ts:2050 for the rationale.
40
+ const all = loadAllEntries(hippoRoot);
41
+ if (dryRun)
42
+ for (const e of all)
43
+ e.half_life_days = halfLife.halfLives.get(e.id) ?? e.half_life_days;
44
+ const backingObjects = memoriesBackingObjects(hippoRoot);
45
+ // Retirable: auto-deletable (never pinned, raw or kept for good) and not backing a first-class object.
46
+ const retirable = (entry) => canAutoDelete(entry) && !backingObjects.has(entry.id);
47
+ const snapshot = new Map(structuredClone(all).map((e) => [e.id, e]));
48
+ // Load decay options from config + session context
49
+ const config = loadConfig(hippoRoot);
50
+ const sessionCtx = loadSessionDecayContext(hippoRoot);
51
+ const decayOpts = {
52
+ decayBasis: config.decayBasis,
53
+ avgSessionIntervalDays: sessionCtx.avgSessionIntervalDays,
54
+ sleepCount: sessionCtx.sleepCount,
55
+ };
56
+ const consolidateDb = lazyConsolidateDb(hippoRoot, dryRun);
57
+ const run = {
58
+ hippoRoot, now, dryRun, config, decayOpts, result, all, retirable,
59
+ getConsolidateDb: consolidateDb.get,
60
+ survivors: [],
61
+ // Collect all writes/deletes and batch them at the end
62
+ pendingWrites: [],
63
+ pendingDeletes: [],
64
+ pendingDormant: [],
65
+ };
66
+ const decay = decayPass(run);
67
+ let mergesSkippedRejected = 0;
68
+ try {
69
+ promoteSessionTraces(run);
70
+ replayPass(run);
71
+ await llmPasses(run, options.fetcher);
72
+ physicsPass(run);
73
+ retireHeldTexts(run);
74
+ mergesSkippedRejected = mergePass(run);
75
+ }
76
+ finally {
77
+ consolidateDb.close();
78
+ }
79
+ if (mergesSkippedRejected > 0) {
80
+ log.warn(`consolidate: skipped ${mergesSkippedRejected} merge(s) whose content matches a rejected value`);
81
+ }
82
+ flushPending(run, snapshot);
83
+ expireDormant(run);
84
+ if (!dryRun)
85
+ logRun(run, decay);
86
+ return result;
87
+ }
88
+ // A changed default half-life moves memories still on the old base first,
89
+ // so this pass decays them at the new one (src/half-life-migration.ts).
90
+ function migrateHalfLives(hippoRoot, dryRun, result) {
91
+ const halfLife = migrateDefaultHalfLife(hippoRoot, loadConfig(hippoRoot).defaultHalfLifeDays, { dryRun });
92
+ if (halfLife.rescaled > 0) {
93
+ result.details.push(` ⏳ ${dryRun ? 'would move' : 'moved'} ${halfLife.rescaled} memories from the ${halfLife.from}-day to the ${halfLife.to}-day half-life`);
94
+ }
95
+ if (halfLife.typed > 0) {
96
+ result.details.push(` ⏳ ${dryRun ? 'would move' : 'moved'} ${halfLife.typed} memories of decisions, incidents and other objects from the ${LEGACY_TYPED_HALF_LIFE}-day to the ${halfLife.to}-day half-life`);
97
+ }
98
+ return halfLife;
99
+ }
100
+ function flushPending(run, snapshot) {
101
+ const { result, pendingDeletes, pendingDormant } = run;
102
+ result.removedIds = pendingDeletes;
103
+ // One transaction; the snapshot keeps what the DAG passes and other writers changed while sleep ran.
104
+ // Dormant moves ride in the same transaction (src/dormant.ts).
105
+ if (run.dryRun)
106
+ return;
107
+ const left = new Set(batchWriteAndDelete(run.hippoRoot, run.pendingWrites, pendingDeletes, { snapshot, dormant: pendingDormant }));
108
+ for (const id of [...pendingDeletes, ...pendingDormant.map((m) => m.entry.id)]) {
109
+ if (!left.has(id))
110
+ result.details.push(` ↩ ${id} not removed: pinned or already gone before sleep saved`);
111
+ }
112
+ result.removedIds = pendingDeletes.filter((id) => left.has(id));
113
+ result.removed = result.removedIds.length;
114
+ result.dormant = pendingDormant.filter((m) => left.has(m.entry.id)).length;
115
+ }
116
+ // Dormant retention: a dormant memory nobody restored within
117
+ // dormant.retentionDays is deleted for good (0 keeps them forever). Runs
118
+ // even when dormant.enabled is off, so turning it off still ages out what
119
+ // earlier sleeps kept.
120
+ function expireDormant(run) {
121
+ const { config, result, dryRun } = run;
122
+ if (!(config.dormant.retentionDays > 0))
123
+ return;
124
+ const cutoff = new Date(run.now.getTime() - config.dormant.retentionDays * 24 * 60 * 60 * 1000).toISOString();
125
+ const db = openHippoDb(run.hippoRoot);
126
+ try {
127
+ result.dormantExpired = dryRun ? countExpiredDormant(db, cutoff) : purgeExpiredDormant(db, cutoff);
128
+ }
129
+ finally {
130
+ closeHippoDb(db);
131
+ }
132
+ if (result.dormantExpired > 0) {
133
+ result.details.push(` ⌛ ${dryRun ? 'would expire' : 'expired'} ${result.dormantExpired} dormant memor${result.dormantExpired === 1 ? 'y' : 'ies'} older than ${config.dormant.retentionDays} days`);
134
+ }
135
+ }
136
+ // -------------------------------------------------------------------------
137
+ // 4. Log run
138
+ // -------------------------------------------------------------------------
139
+ function logRun(run, decay) {
140
+ const { hippoRoot, now, result } = run;
141
+ const detectedConflicts = detectConflicts(run.survivors, now, run.decayOpts, decay.rescuedIds);
142
+ replaceDetectedConflicts(hippoRoot, detectedConflicts, now.toISOString());
143
+ if (detectedConflicts.length > 0) {
144
+ result.details.push(` ⚠️ detected ${detectedConflicts.length} memory conflict${detectedConflicts.length === 1 ? '' : 's'}`);
145
+ }
146
+ appendConsolidationRun(hippoRoot, {
147
+ timestamp: now.toISOString(),
148
+ decayed: result.decayed,
149
+ merged: result.merged,
150
+ removed: result.removed,
151
+ });
152
+ incrementSleepCount(hippoRoot);
153
+ if (decay.rescuedEntries.length > 0)
154
+ auditRescues(run, decay);
155
+ }
156
+ // One audit row per rescue (attributability, D1). Written here, AFTER
157
+ // batchWriteAndDelete has committed this cycle's writes/deletes
158
+ // (and after conflict detection + run logging), not inline in the decay
159
+ // pass — same durability posture as api.ts's top-level 'consolidate'
160
+ // summary audit row (written only once the whole sleep has completed).
161
+ // Writing it earlier would assert rescues for a cycle whose effects
162
+ // never landed if a later phase threw. Real writes only — dry-run
163
+ // previews the decision (details line above) but persists nothing.
164
+ function auditRescues(run, { rescuedEntries, rankById }) {
165
+ const { result } = run;
166
+ try {
167
+ const auditDb = openHippoDb(run.hippoRoot);
168
+ try {
169
+ // Review-round F5: per-row try/catch, not one try/catch around the
170
+ // whole loop — a single failed appendAuditEvent must not silently
171
+ // drop every remaining row. Mirrors the physics pass's
172
+ // skipped-warning precedent: count losses, keep
173
+ // the overall fail-soft posture, tell the operator via details.
174
+ let auditFailures = 0;
175
+ for (const entry of rescuedEntries) {
176
+ try {
177
+ const rank = rankById.get(entry.id);
178
+ appendAuditEvent(auditDb, {
179
+ tenantId: entry.tenantId,
180
+ actor: 'sleep',
181
+ op: 'mv_rescue',
182
+ targetId: entry.id,
183
+ metadata: rank
184
+ ? { rank: rank.rank, totalNonPinned: rank.totalNonPinned, keepN: rank.keepN, score: rank.score }
185
+ : {},
186
+ });
187
+ }
188
+ catch (error) {
189
+ auditFailures++;
190
+ reportAuditWriteFailure('mv_rescue', String(error), entry.id);
191
+ }
192
+ }
193
+ if (auditFailures > 0) {
194
+ result.details.push(` ⚠️ memory-value: ${auditFailures} mv_rescue audit row${auditFailures === 1 ? '' : 's'} ` +
195
+ `failed to write (the rescue itself still landed)`);
196
+ }
197
+ }
198
+ finally {
199
+ closeHippoDb(auditDb);
200
+ }
201
+ }
202
+ catch {
203
+ // openHippoDb/closeHippoDb-level failure: audit must never crash a
204
+ // mutation (mirrors store.ts's audit() posture).
205
+ result.details.push(` ⚠️ memory-value: mv_rescue audit unavailable this cycle ` +
206
+ `(${rescuedEntries.length} rescue${rescuedEntries.length === 1 ? '' : 's'} not audited)`);
207
+ }
208
+ }
209
+ //# sourceMappingURL=sleep.js.map
@@ -0,0 +1,4 @@
1
+ import { type SleepRun } from './run.js';
2
+ export declare function promoteSessionTraces(run: SleepRun): void;
3
+ export declare function replayPass(run: SleepRun): void;
4
+ //# sourceMappingURL=traces.d.ts.map
@@ -0,0 +1,178 @@
1
+ import { isRecallBoostAblated } from '../ablation.js';
2
+ import { Layer, createMemory, markRetrieved } from '../memory.js';
3
+ import { findPromotableSessions, traceExistsForSession, listSessionEvents } from '../store/sessions.js';
4
+ import { rejectionDigest, findRejectedValue } from '../rejection.js';
5
+ import { sampleForReplay } from '../replay.js';
6
+ import { renderTraceContent } from '../trace.js';
7
+ import { resolveTenantId } from '../tenant.js';
8
+ import { appendAuditEvent, reportAuditWriteFailure } from '../audit.js';
9
+ import { commonDerivationScope } from '../recall-scope.js';
10
+ import { log } from '../log.js';
11
+ import { REPLAY_COUNT_DEFAULT, isJsonString } from './run.js';
12
+ // -------------------------------------------------------------------------
13
+ // 1.4. Auto-promote complete sessions to traces
14
+ // -------------------------------------------------------------------------
15
+ //
16
+ // For each session within the configured window that has a `session_complete`
17
+ // event and no existing trace (idempotency via the source_session_id column),
18
+ // render the action sequence as markdown and persist a Layer.Trace memory.
19
+ // Traces inherit decay, search, replay, and physics from the base MemoryEntry.
20
+ export function promoteSessionTraces(run) {
21
+ const { result } = run;
22
+ if (run.dryRun || run.config.autoTraceCapture === false)
23
+ return;
24
+ let tracesSkippedRejected = 0;
25
+ const windowDays = run.config.autoTraceWindowDays ?? 7;
26
+ const sinceMs = run.now.getTime() - windowDays * 24 * 60 * 60 * 1000;
27
+ // Auto-trace currently runs in a single-tenant context (the env-resolved
28
+ // tenant for this process). Multi-tenant deployments that want
29
+ // consolidation across all tenants need a per-tenant loop layered on top
30
+ // of this — tracked in docs/plans/2026-05-02-continuity-tables-tenant-scope.md.
31
+ const consolidationTenant = resolveTenantId({});
32
+ const promotable = findPromotableSessions(run.hippoRoot, consolidationTenant, sinceMs);
33
+ for (const session of promotable) {
34
+ const built = sessionTrace(run, consolidationTenant, session.session_id);
35
+ if (!built)
36
+ continue;
37
+ const { trace, outcome } = built;
38
+ if (traceRejected(run, trace, session.session_id)) {
39
+ tracesSkippedRejected++;
40
+ continue;
41
+ }
42
+ run.pendingWrites.push(trace);
43
+ run.survivors.push(trace);
44
+ result.promotedTraces++;
45
+ result.details.push(` 🧬 promoted trace ${trace.id} from session ${session.session_id} (${outcome})`);
46
+ }
47
+ if (result.promotedTraces > 0) {
48
+ result.details.push(` 🧬 promoted ${result.promotedTraces} trace${result.promotedTraces === 1 ? '' : 's'} from completed session${result.promotedTraces === 1 ? '' : 's'}`);
49
+ }
50
+ if (tracesSkippedRejected > 0) {
51
+ log.warn(`consolidate: skipped ${tracesSkippedRejected} auto-promoted trace(s) whose content matches a rejected value`);
52
+ }
53
+ }
54
+ /** The trace a completed session renders to, or null when it already has one or cannot be promoted. */
55
+ function sessionTrace(run, consolidationTenant, sessionId) {
56
+ // Idempotency: skip if a trace for this session already exists.
57
+ if (traceExistsForSession(run.hippoRoot, consolidationTenant, sessionId))
58
+ return null;
59
+ const events = listSessionEvents(run.hippoRoot, consolidationTenant, {
60
+ session_id: sessionId,
61
+ limit: 1000,
62
+ });
63
+ // T7: a mixed-scope session would otherwise leak into one trace.
64
+ const sessionScope = commonDerivationScope(events.map((e) => e.scope));
65
+ if (!sessionScope.ok) {
66
+ run.result.tracesSkippedMixedScope++;
67
+ run.result.details.push(` ⏭ skipped session ${sessionId}: events span mixed scopes`);
68
+ return null;
69
+ }
70
+ const completeEvent = events.find((e) => e.event_type === 'session_complete');
71
+ if (!completeEvent)
72
+ return null; // defence-in-depth; findPromotableSessions filters already.
73
+ const outcomeRaw = completeEvent.content;
74
+ if (outcomeRaw !== 'success' && outcomeRaw !== 'failure' && outcomeRaw !== 'partial') {
75
+ // Malformed terminal event — skip rather than crash the whole sleep.
76
+ return null;
77
+ }
78
+ const outcome = outcomeRaw;
79
+ const steps = events
80
+ .filter((e) => e.event_type !== 'session_complete')
81
+ .map((e) => ({ action: e.content, observation: '' }));
82
+ // SAFETY: session event metadata is a free-form Record<string, unknown>
83
+ // bag; summary is optional and is only trusted once isJsonString below
84
+ // confirms it is actually a string.
85
+ const summaryValue = completeEvent.metadata.summary;
86
+ const summary = isJsonString(summaryValue) ? summaryValue : '(untitled)';
87
+ const trace = createMemory(renderTraceContent({ task: summary, steps, outcome }), {
88
+ layer: Layer.Trace,
89
+ trace_outcome: outcome,
90
+ source_session_id: sessionId,
91
+ tags: ['auto-promoted'],
92
+ source: 'auto-promote',
93
+ scope: sessionScope.scope,
94
+ // T1 fix (2026-08-15 hardening pass): stamp the trace into the SAME
95
+ // tenant the traceExistsForSession idempotency check (above) runs
96
+ // under. Before
97
+ // this, createMemory omitted tenantId and the trace always landed
98
+ // 'default' (memory.ts:535) while the idempotency check ran under
99
+ // consolidationTenant — for any non-default tenant that check never
100
+ // hit, and the trace regenerated every sleep.
101
+ tenantId: consolidationTenant,
102
+ baseHalfLifeDays: run.config.defaultHalfLifeDays,
103
+ });
104
+ return { trace, outcome };
105
+ }
106
+ // AT1 (same producer-side pattern as the merge pass below): traceExistsForSession
107
+ // only sees rows CURRENTLY in the store — once a rejected trace is
108
+ // removed, that idempotency check no longer blocks regeneration, and
109
+ // this write would otherwise reach batchWriteAndDelete's guard bypass
110
+ // unchecked, resurrecting it every sleep. Check under THE ENTRY'S OWN
111
+ // stamped tenantId (read off `trace` after createMemory — never guess
112
+ // the tenant) + the built content's digest. A hit skips the push
113
+ // entirely: not counted as promoted, not added to survivors.
114
+ function traceRejected(run, trace, sessionId) {
115
+ const consolidateDb = run.getConsolidateDb();
116
+ if (!consolidateDb)
117
+ return false;
118
+ const traceDigest = rejectionDigest(trace.content);
119
+ const tombstone = findRejectedValue(consolidateDb, trace.tenantId, traceDigest);
120
+ if (!tombstone)
121
+ return false;
122
+ try {
123
+ appendAuditEvent(consolidateDb, {
124
+ tenantId: trace.tenantId,
125
+ actor: 'sleep',
126
+ op: 'reject_refusal',
127
+ metadata: {
128
+ digest: traceDigest,
129
+ reason: tombstone.reason,
130
+ sourceSessionId: sessionId,
131
+ },
132
+ });
133
+ }
134
+ catch (error) {
135
+ reportAuditWriteFailure('reject_refusal', String(error));
136
+ }
137
+ return true;
138
+ }
139
+ // -------------------------------------------------------------------------
140
+ // 1.5. Replay pass — rehearse high-value survivors
141
+ // -------------------------------------------------------------------------
142
+ //
143
+ // Biologically-inspired counterpart to hippocampal replay during slow-wave
144
+ // sleep: sample N memories weighted by outcome + valence + under-rehearsal
145
+ // + idle time, then apply the same retrieval-strengthening `markRetrieved`
146
+ // applies to real queries. Distinct from decay (removal), physics (motion),
147
+ // and merge (compression) — this is the "rehearse the important stuff so
148
+ // it doesn't fade" pass.
149
+ export function replayPass(run) {
150
+ const { survivors, now } = run;
151
+ const replayCount = run.config.replay?.count ?? REPLAY_COUNT_DEFAULT;
152
+ // EVAL-ONLY ablation (see ablation.ts): replay rehearsal IS recall
153
+ // strengthening (same markRetrieved dynamics), so the strengthen-off arm
154
+ // silences the whole pass - markRetrieved would return unmutated entries
155
+ // and persisting them anyway would still refresh updated_at / mirrors.
156
+ if (!(replayCount > 0 && survivors.length > 0 && !isRecallBoostAblated()))
157
+ return;
158
+ const seed = Math.floor(now.getTime() / 1000) & 0xffffffff;
159
+ const picked = sampleForReplay(survivors, replayCount, now, seed);
160
+ if (picked.length === 0)
161
+ return;
162
+ const rehearsed = markRetrieved(picked, now);
163
+ const rehearsedById = new Map(rehearsed.map((e) => [e.id, e]));
164
+ // Update survivors in place so downstream passes see rehearsed state.
165
+ for (let i = 0; i < survivors.length; i++) {
166
+ const replacement = rehearsedById.get(survivors[i].id);
167
+ if (replacement)
168
+ survivors[i] = replacement;
169
+ }
170
+ run.result.replayed = rehearsed.length;
171
+ run.result.details.push(` 💭 replayed ${rehearsed.length} memor${rehearsed.length === 1 ? 'y' : 'ies'}: ` +
172
+ rehearsed.map((e) => e.id).join(', '));
173
+ if (!run.dryRun) {
174
+ for (const r of rehearsed)
175
+ run.pendingWrites.push(r);
176
+ }
177
+ }
178
+ //# sourceMappingURL=traces.js.map
@@ -1,13 +1,13 @@
1
- import { execSync } from 'child_process';
1
+ import { execFileSync } from 'child_process';
2
2
  const SKIPPED_PATH_TERMS = ['src', 'dist', 'test', 'tests', 'node_modules', 'index'];
3
+ // stderr is dropped because git's warnings (line-ending notices, for one) would otherwise become query terms.
4
+ function readGit(args) {
5
+ return execFileSync('git', args, { encoding: 'utf8', timeout: 3000, stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true }).trim();
6
+ }
3
7
  /** A context query from the cwd's git state ('' means `getContext` lists by strength); kept out of the api layer, which never shells out. */
4
8
  export function autoDetectContext() {
5
9
  try {
6
- const diff = execSync('git diff --name-only HEAD 2>&1', {
7
- encoding: 'utf8',
8
- timeout: 3000,
9
- windowsHide: true,
10
- }).trim();
10
+ const diff = readGit(['diff', '--name-only', 'HEAD']);
11
11
  if (diff) {
12
12
  const terms = diff
13
13
  .split('\n')
@@ -17,11 +17,7 @@ export function autoDetectContext() {
17
17
  if (terms.length > 0)
18
18
  return terms.join(' ');
19
19
  }
20
- const branch = execSync('git branch --show-current 2>&1', {
21
- encoding: 'utf8',
22
- timeout: 3000,
23
- windowsHide: true,
24
- }).trim();
20
+ const branch = readGit(['branch', '--show-current']);
25
21
  if (branch && branch !== 'main' && branch !== 'master') {
26
22
  return branch.replace(/[-_/]/g, ' ');
27
23
  }
@@ -1,6 +1,6 @@
1
1
  import { type MemoryEntry } from './memory.js';
2
2
  import { type SessionHandoff } from './handoff.js';
3
- import type { SessionEvent, TaskSnapshot } from './store.js';
3
+ import type { SessionEvent, TaskSnapshot } from './store/rows.js';
4
4
  import type { AssembleCost, AssembleResult, AssembledContextItem, ContextCost, ContextResultEntry, DrillDownChild, DrillDownCost, DrillDownResult } from './api.js';
5
5
  export declare function snapshotText(s: TaskSnapshot): string;
6
6
  export declare function handoffText(h: SessionHandoff): string;
@@ -1,7 +1,7 @@
1
1
  // The strings a context block prints. The budget prices these same strings, so selection and print cannot drift.
2
2
  import { calculateStrength, confidenceFacets, confidenceLabel } from './memory.js';
3
3
  import { evalNow } from './ablation.js';
4
- import { estimateTokens } from './search.js';
4
+ import { estimateTokens } from './token-ledger.js';
5
5
  import { renderAmbientSummary } from './ambient.js';
6
6
  import { formatHandoffEvidenceLine } from './handoff.js';
7
7
  export function snapshotText(s) {
@@ -19,6 +19,7 @@
19
19
  *
20
20
  * Lifecycle: active -> superseded (a corrected version) or active -> closed (retired).
21
21
  */
22
+ import { type KeysetPosition } from './keyset.js';
22
23
  export type NoteStatus = 'active' | 'superseded' | 'closed';
23
24
  export declare const VALID_NOTE_STATES: ReadonlySet<NoteStatus>;
24
25
  /** Field caps (untrusted at the HTTP/SDK boundary). note is a body, so a larger cap
@@ -61,6 +62,8 @@ export interface ListCustomerNotesOpts {
61
62
  /** Filter to a single customer. */
62
63
  customer?: string;
63
64
  limit?: number;
65
+ /** Resume after this row: the position the previous page ended on. */
66
+ after?: KeysetPosition;
64
67
  }
65
68
  /**
66
69
  * Create a customer_note (or a new version that supersedes an existing one). Writes
@@ -21,12 +21,13 @@
21
21
  */
22
22
  import { BadRequestError, ConflictError, NotFoundError } from './api-errors.js';
23
23
  import { openHippoDb, closeHippoDb } from './db.js';
24
- import { writeEntry } from './store.js';
24
+ import { writeEntry } from './store/entry-writes.js';
25
25
  import { assertTenantId } from './tenant.js';
26
- import { markGraphDirty, removeGraphEntitiesForObject } from './graph.js';
26
+ import { markGraphDirty, removeGraphEntitiesForObject } from './graph/write.js';
27
27
  import { createMemory, Layer } from './memory.js';
28
28
  import { appendAuditEvent } from './audit.js';
29
29
  import { objectHalfLifeDays } from './half-life-migration.js';
30
+ import { keysetAfter } from './keyset.js';
30
31
  export const VALID_NOTE_STATES = new Set([
31
32
  'active',
32
33
  'superseded',
@@ -284,6 +285,7 @@ export function loadCustomerNoteById(hippoRoot, tenantId, id) {
284
285
  export function loadCustomerNotes(hippoRoot, tenantId, opts = {}) {
285
286
  assertTenantId('loadCustomerNotes', tenantId);
286
287
  const limit = opts.limit ?? 100;
288
+ const after = keysetAfter('created_at', 'id', opts.after);
287
289
  if (opts.status && !VALID_NOTE_STATES.has(opts.status)) {
288
290
  throw new BadRequestError(`loadCustomerNotes: status must be one of ${Array.from(VALID_NOTE_STATES).join('|')}; got ${opts.status}`);
289
291
  }
@@ -299,13 +301,13 @@ export function loadCustomerNotes(hippoRoot, tenantId, opts = {}) {
299
301
  clauses.push('customer = ?');
300
302
  params.push(opts.customer);
301
303
  }
302
- params.push(limit);
304
+ params.push(...after.params, limit);
303
305
  // SAFETY: SELECT ${NOTE_COLS} projects exactly the CustomerNoteRow columns
304
306
  // regardless of the dynamic WHERE clause built above; .all() returns rows
305
307
  // in that shape.
306
308
  const rows = db.prepare(`
307
309
  SELECT ${NOTE_COLS} FROM customer_notes
308
- WHERE ${clauses.join(' AND ')}
310
+ WHERE ${clauses.join(' AND ')}${after.sql}
309
311
  ORDER BY created_at DESC, id DESC
310
312
  LIMIT ?
311
313
  `).all(...params);