hippo-memory 1.44.0 → 1.46.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 (554) hide show
  1. package/README.md +68 -24
  2. package/bin/hippo.js +3 -1
  3. package/dist/ablation.d.ts +10 -1
  4. package/dist/ablation.js +17 -1
  5. package/dist/api.d.ts +81 -22
  6. package/dist/api.js +258 -49
  7. package/dist/audit.d.ts +2 -2
  8. package/dist/audit.js +9 -0
  9. package/dist/autolearn.d.ts +1 -1
  10. package/dist/autolearn.js +2 -1
  11. package/dist/capture-error.d.ts +20 -0
  12. package/dist/capture-error.js +82 -0
  13. package/dist/capture.d.ts +25 -8
  14. package/dist/capture.js +100 -5
  15. package/dist/cli.d.ts +9 -1
  16. package/dist/cli.js +531 -119
  17. package/dist/client.d.ts +4 -21
  18. package/dist/client.js +3 -112
  19. package/dist/config.d.ts +20 -0
  20. package/dist/config.js +37 -1
  21. package/dist/consolidate.d.ts +9 -0
  22. package/dist/consolidate.js +133 -46
  23. package/dist/dag.d.ts +1 -0
  24. package/dist/dag.js +10 -5
  25. package/dist/dashboard.js +7 -3
  26. package/dist/db.js +69 -24
  27. package/dist/dedupe.d.ts +1 -0
  28. package/dist/dedupe.js +4 -7
  29. package/dist/doctor.d.ts +34 -0
  30. package/dist/doctor.js +174 -0
  31. package/dist/dormant.d.ts +91 -0
  32. package/dist/dormant.js +121 -0
  33. package/dist/embedding-provider.js +2 -1
  34. package/dist/embeddings.js +81 -8
  35. package/dist/eval-stats.d.ts +123 -0
  36. package/dist/eval-stats.js +187 -0
  37. package/dist/extract.d.ts +2 -0
  38. package/dist/extract.js +9 -4
  39. package/dist/half-life-migration.d.ts +55 -0
  40. package/dist/half-life-migration.js +111 -0
  41. package/dist/hooks.d.ts +4 -0
  42. package/dist/hooks.js +47 -0
  43. package/dist/mcp/server.d.ts +6 -0
  44. package/dist/mcp/server.js +90 -48
  45. package/dist/memory.d.ts +18 -1
  46. package/dist/memory.js +33 -5
  47. package/dist/physics-config.js +5 -1
  48. package/dist/recall-scope.d.ts +24 -0
  49. package/dist/recall-scope.js +41 -0
  50. package/dist/refine-llm.js +3 -2
  51. package/dist/reject-flow.d.ts +3 -3
  52. package/dist/reject-flow.js +10 -3
  53. package/dist/rerankers/jev.js +3 -2
  54. package/dist/rerankers/llm.js +3 -2
  55. package/dist/search.d.ts +4 -4
  56. package/dist/search.js +26 -21
  57. package/dist/server.d.ts +5 -0
  58. package/dist/server.js +49 -29
  59. package/dist/shared.js +1 -1
  60. package/dist/store.d.ts +29 -11
  61. package/dist/store.js +197 -70
  62. package/dist/token-ledger.d.ts +119 -0
  63. package/dist/token-ledger.js +181 -0
  64. package/dist/version.d.ts +4 -6
  65. package/dist/version.js +4 -7
  66. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  67. package/extensions/openclaw-plugin/package.json +1 -1
  68. package/openclaw.plugin.json +1 -1
  69. package/package.json +7 -3
  70. package/dist/ablation.d.ts.map +0 -1
  71. package/dist/ablation.js.map +0 -1
  72. package/dist/ambient.d.ts.map +0 -1
  73. package/dist/ambient.js.map +0 -1
  74. package/dist/api.d.ts.map +0 -1
  75. package/dist/api.js.map +0 -1
  76. package/dist/audit-prune.d.ts.map +0 -1
  77. package/dist/audit-prune.js.map +0 -1
  78. package/dist/audit.d.ts.map +0 -1
  79. package/dist/audit.js.map +0 -1
  80. package/dist/auth.d.ts.map +0 -1
  81. package/dist/auth.js.map +0 -1
  82. package/dist/autolearn.d.ts.map +0 -1
  83. package/dist/autolearn.js.map +0 -1
  84. package/dist/availability.d.ts.map +0 -1
  85. package/dist/availability.js.map +0 -1
  86. package/dist/benchmarks/e1.3/incident-recall-eval.js +0 -78
  87. package/dist/benchmarks/e1.3/incident-recall-eval.js.map +0 -1
  88. package/dist/benchmarks/e1.3/slack-1000-event-smoke.js +0 -103
  89. package/dist/benchmarks/e1.3/slack-1000-event-smoke.js.map +0 -1
  90. package/dist/capture.d.ts.map +0 -1
  91. package/dist/capture.js.map +0 -1
  92. package/dist/card-detail.d.ts.map +0 -1
  93. package/dist/card-detail.js.map +0 -1
  94. package/dist/card.d.ts.map +0 -1
  95. package/dist/card.js.map +0 -1
  96. package/dist/cli.d.ts.map +0 -1
  97. package/dist/cli.js.map +0 -1
  98. package/dist/client.d.ts.map +0 -1
  99. package/dist/client.js.map +0 -1
  100. package/dist/compare.d.ts.map +0 -1
  101. package/dist/compare.js.map +0 -1
  102. package/dist/config.d.ts.map +0 -1
  103. package/dist/config.js.map +0 -1
  104. package/dist/connectors/github/backfill.d.ts.map +0 -1
  105. package/dist/connectors/github/backfill.js.map +0 -1
  106. package/dist/connectors/github/cli-impl.d.ts.map +0 -1
  107. package/dist/connectors/github/cli-impl.js.map +0 -1
  108. package/dist/connectors/github/deletion.d.ts.map +0 -1
  109. package/dist/connectors/github/deletion.js.map +0 -1
  110. package/dist/connectors/github/dlq.d.ts.map +0 -1
  111. package/dist/connectors/github/dlq.js.map +0 -1
  112. package/dist/connectors/github/idempotency.d.ts.map +0 -1
  113. package/dist/connectors/github/idempotency.js.map +0 -1
  114. package/dist/connectors/github/ingest.d.ts.map +0 -1
  115. package/dist/connectors/github/ingest.js.map +0 -1
  116. package/dist/connectors/github/octokit-client.d.ts.map +0 -1
  117. package/dist/connectors/github/octokit-client.js.map +0 -1
  118. package/dist/connectors/github/ratelimit.d.ts.map +0 -1
  119. package/dist/connectors/github/ratelimit.js.map +0 -1
  120. package/dist/connectors/github/scope.d.ts.map +0 -1
  121. package/dist/connectors/github/scope.js.map +0 -1
  122. package/dist/connectors/github/signature.d.ts.map +0 -1
  123. package/dist/connectors/github/signature.js.map +0 -1
  124. package/dist/connectors/github/tenant-routing.d.ts.map +0 -1
  125. package/dist/connectors/github/tenant-routing.js.map +0 -1
  126. package/dist/connectors/github/transform.d.ts.map +0 -1
  127. package/dist/connectors/github/transform.js.map +0 -1
  128. package/dist/connectors/github/types.d.ts.map +0 -1
  129. package/dist/connectors/github/types.js.map +0 -1
  130. package/dist/connectors/slack/backfill.d.ts.map +0 -1
  131. package/dist/connectors/slack/backfill.js.map +0 -1
  132. package/dist/connectors/slack/deletion.d.ts.map +0 -1
  133. package/dist/connectors/slack/deletion.js.map +0 -1
  134. package/dist/connectors/slack/dlq.d.ts.map +0 -1
  135. package/dist/connectors/slack/dlq.js.map +0 -1
  136. package/dist/connectors/slack/idempotency.d.ts.map +0 -1
  137. package/dist/connectors/slack/idempotency.js.map +0 -1
  138. package/dist/connectors/slack/ingest.d.ts.map +0 -1
  139. package/dist/connectors/slack/ingest.js.map +0 -1
  140. package/dist/connectors/slack/ratelimit.d.ts.map +0 -1
  141. package/dist/connectors/slack/ratelimit.js.map +0 -1
  142. package/dist/connectors/slack/scope.d.ts.map +0 -1
  143. package/dist/connectors/slack/scope.js.map +0 -1
  144. package/dist/connectors/slack/signature.d.ts.map +0 -1
  145. package/dist/connectors/slack/signature.js.map +0 -1
  146. package/dist/connectors/slack/tenant-routing.d.ts.map +0 -1
  147. package/dist/connectors/slack/tenant-routing.js.map +0 -1
  148. package/dist/connectors/slack/transform.d.ts.map +0 -1
  149. package/dist/connectors/slack/transform.js.map +0 -1
  150. package/dist/connectors/slack/types.d.ts.map +0 -1
  151. package/dist/connectors/slack/types.js.map +0 -1
  152. package/dist/connectors/slack/web-client.d.ts.map +0 -1
  153. package/dist/connectors/slack/web-client.js.map +0 -1
  154. package/dist/connectors/slack/workspaces.d.ts.map +0 -1
  155. package/dist/connectors/slack/workspaces.js.map +0 -1
  156. package/dist/consolidate.d.ts.map +0 -1
  157. package/dist/consolidate.js.map +0 -1
  158. package/dist/correction-latency.d.ts.map +0 -1
  159. package/dist/correction-latency.js.map +0 -1
  160. package/dist/customer-notes.d.ts.map +0 -1
  161. package/dist/customer-notes.js.map +0 -1
  162. package/dist/dag.d.ts.map +0 -1
  163. package/dist/dag.js.map +0 -1
  164. package/dist/dashboard.d.ts.map +0 -1
  165. package/dist/dashboard.js.map +0 -1
  166. package/dist/db.d.ts.map +0 -1
  167. package/dist/db.js.map +0 -1
  168. package/dist/decisions.d.ts.map +0 -1
  169. package/dist/decisions.js.map +0 -1
  170. package/dist/dedupe.d.ts.map +0 -1
  171. package/dist/dedupe.js.map +0 -1
  172. package/dist/embedding-provider.d.ts.map +0 -1
  173. package/dist/embedding-provider.js.map +0 -1
  174. package/dist/embeddings.d.ts.map +0 -1
  175. package/dist/embeddings.js.map +0 -1
  176. package/dist/eval-suite.d.ts.map +0 -1
  177. package/dist/eval-suite.js.map +0 -1
  178. package/dist/eval.d.ts.map +0 -1
  179. package/dist/eval.js.map +0 -1
  180. package/dist/extensions/openclaw-plugin/index.js.map +0 -1
  181. package/dist/extract.d.ts.map +0 -1
  182. package/dist/extract.js.map +0 -1
  183. package/dist/forward-claim-detector.d.ts.map +0 -1
  184. package/dist/forward-claim-detector.js.map +0 -1
  185. package/dist/goals.d.ts.map +0 -1
  186. package/dist/goals.js.map +0 -1
  187. package/dist/graph-extract.d.ts.map +0 -1
  188. package/dist/graph-extract.js.map +0 -1
  189. package/dist/graph-recall.d.ts.map +0 -1
  190. package/dist/graph-recall.js.map +0 -1
  191. package/dist/graph-stream.d.ts.map +0 -1
  192. package/dist/graph-stream.js.map +0 -1
  193. package/dist/graph-view.d.ts.map +0 -1
  194. package/dist/graph-view.js.map +0 -1
  195. package/dist/graph.d.ts.map +0 -1
  196. package/dist/graph.js.map +0 -1
  197. package/dist/handoff.d.ts.map +0 -1
  198. package/dist/handoff.js.map +0 -1
  199. package/dist/hooks.d.ts.map +0 -1
  200. package/dist/hooks.js.map +0 -1
  201. package/dist/importers.d.ts.map +0 -1
  202. package/dist/importers.js.map +0 -1
  203. package/dist/incidents.d.ts.map +0 -1
  204. package/dist/incidents.js.map +0 -1
  205. package/dist/index.d.ts.map +0 -1
  206. package/dist/index.js.map +0 -1
  207. package/dist/invalidation.d.ts.map +0 -1
  208. package/dist/invalidation.js.map +0 -1
  209. package/dist/mcp/framing.d.ts.map +0 -1
  210. package/dist/mcp/framing.js.map +0 -1
  211. package/dist/mcp/server.d.ts.map +0 -1
  212. package/dist/mcp/server.js.map +0 -1
  213. package/dist/memory-value-weights.d.ts.map +0 -1
  214. package/dist/memory-value-weights.js.map +0 -1
  215. package/dist/memory-value.d.ts.map +0 -1
  216. package/dist/memory-value.js.map +0 -1
  217. package/dist/memory.d.ts.map +0 -1
  218. package/dist/memory.js.map +0 -1
  219. package/dist/multihop.d.ts.map +0 -1
  220. package/dist/multihop.js.map +0 -1
  221. package/dist/owner-validation.d.ts.map +0 -1
  222. package/dist/owner-validation.js.map +0 -1
  223. package/dist/path-context.d.ts.map +0 -1
  224. package/dist/path-context.js.map +0 -1
  225. package/dist/physics-config.d.ts.map +0 -1
  226. package/dist/physics-config.js.map +0 -1
  227. package/dist/physics-state.d.ts.map +0 -1
  228. package/dist/physics-state.js.map +0 -1
  229. package/dist/physics.d.ts.map +0 -1
  230. package/dist/physics.js.map +0 -1
  231. package/dist/policies.d.ts.map +0 -1
  232. package/dist/policies.js.map +0 -1
  233. package/dist/postinstall.d.ts.map +0 -1
  234. package/dist/postinstall.js.map +0 -1
  235. package/dist/predictions.d.ts.map +0 -1
  236. package/dist/predictions.js.map +0 -1
  237. package/dist/processes.d.ts.map +0 -1
  238. package/dist/processes.js.map +0 -1
  239. package/dist/project-briefs.d.ts.map +0 -1
  240. package/dist/project-briefs.js.map +0 -1
  241. package/dist/project-identity.d.ts.map +0 -1
  242. package/dist/project-identity.js.map +0 -1
  243. package/dist/provenance-coverage.d.ts.map +0 -1
  244. package/dist/provenance-coverage.js.map +0 -1
  245. package/dist/rate-limit.d.ts.map +0 -1
  246. package/dist/rate-limit.js.map +0 -1
  247. package/dist/raw-archive-mirror-cleanup.d.ts.map +0 -1
  248. package/dist/raw-archive-mirror-cleanup.js.map +0 -1
  249. package/dist/raw-archive.d.ts.map +0 -1
  250. package/dist/raw-archive.js.map +0 -1
  251. package/dist/recall-history.d.ts.map +0 -1
  252. package/dist/recall-history.js.map +0 -1
  253. package/dist/recall-scope.d.ts.map +0 -1
  254. package/dist/recall-scope.js.map +0 -1
  255. package/dist/recall-trace.d.ts.map +0 -1
  256. package/dist/recall-trace.js.map +0 -1
  257. package/dist/refine-llm.d.ts.map +0 -1
  258. package/dist/refine-llm.js.map +0 -1
  259. package/dist/reject-flow.d.ts.map +0 -1
  260. package/dist/reject-flow.js.map +0 -1
  261. package/dist/rejection.d.ts.map +0 -1
  262. package/dist/rejection.js.map +0 -1
  263. package/dist/replay.d.ts.map +0 -1
  264. package/dist/replay.js.map +0 -1
  265. package/dist/rerankers/cross-encoder.d.ts.map +0 -1
  266. package/dist/rerankers/cross-encoder.js.map +0 -1
  267. package/dist/rerankers/index.d.ts.map +0 -1
  268. package/dist/rerankers/index.js.map +0 -1
  269. package/dist/rerankers/jev.d.ts.map +0 -1
  270. package/dist/rerankers/jev.js.map +0 -1
  271. package/dist/rerankers/llm.d.ts.map +0 -1
  272. package/dist/rerankers/llm.js.map +0 -1
  273. package/dist/rerankers/types.d.ts.map +0 -1
  274. package/dist/rerankers/types.js.map +0 -1
  275. package/dist/rrf.d.ts.map +0 -1
  276. package/dist/rrf.js.map +0 -1
  277. package/dist/salience.d.ts.map +0 -1
  278. package/dist/salience.js.map +0 -1
  279. package/dist/scheduler.d.ts.map +0 -1
  280. package/dist/scheduler.js.map +0 -1
  281. package/dist/scope.d.ts.map +0 -1
  282. package/dist/scope.js.map +0 -1
  283. package/dist/search.d.ts.map +0 -1
  284. package/dist/search.js.map +0 -1
  285. package/dist/secret-detect.d.ts.map +0 -1
  286. package/dist/secret-detect.js.map +0 -1
  287. package/dist/server-detect.d.ts.map +0 -1
  288. package/dist/server-detect.js.map +0 -1
  289. package/dist/server.d.ts.map +0 -1
  290. package/dist/server.js.map +0 -1
  291. package/dist/shared.d.ts.map +0 -1
  292. package/dist/shared.js.map +0 -1
  293. package/dist/skills.d.ts.map +0 -1
  294. package/dist/skills.js.map +0 -1
  295. package/dist/sleep-redact.d.ts +0 -58
  296. package/dist/sleep-redact.d.ts.map +0 -1
  297. package/dist/sleep-redact.js +0 -80
  298. package/dist/sleep-redact.js.map +0 -1
  299. package/dist/src/ablation.js +0 -138
  300. package/dist/src/ablation.js.map +0 -1
  301. package/dist/src/ambient.js +0 -148
  302. package/dist/src/ambient.js.map +0 -1
  303. package/dist/src/api.js +0 -2109
  304. package/dist/src/api.js.map +0 -1
  305. package/dist/src/audit-prune.js +0 -109
  306. package/dist/src/audit-prune.js.map +0 -1
  307. package/dist/src/audit.js +0 -213
  308. package/dist/src/audit.js.map +0 -1
  309. package/dist/src/auth.js +0 -97
  310. package/dist/src/auth.js.map +0 -1
  311. package/dist/src/autolearn.js +0 -174
  312. package/dist/src/autolearn.js.map +0 -1
  313. package/dist/src/availability.js +0 -94
  314. package/dist/src/availability.js.map +0 -1
  315. package/dist/src/capture.js +0 -1346
  316. package/dist/src/capture.js.map +0 -1
  317. package/dist/src/card-detail.js +0 -15
  318. package/dist/src/card-detail.js.map +0 -1
  319. package/dist/src/card.js +0 -19
  320. package/dist/src/card.js.map +0 -1
  321. package/dist/src/cli.js +0 -9387
  322. package/dist/src/cli.js.map +0 -1
  323. package/dist/src/client.js +0 -237
  324. package/dist/src/client.js.map +0 -1
  325. package/dist/src/compare.js +0 -122
  326. package/dist/src/compare.js.map +0 -1
  327. package/dist/src/config.js +0 -135
  328. package/dist/src/config.js.map +0 -1
  329. package/dist/src/connectors/github/backfill.js +0 -281
  330. package/dist/src/connectors/github/backfill.js.map +0 -1
  331. package/dist/src/connectors/github/cli-impl.js +0 -234
  332. package/dist/src/connectors/github/cli-impl.js.map +0 -1
  333. package/dist/src/connectors/github/deletion.js +0 -85
  334. package/dist/src/connectors/github/deletion.js.map +0 -1
  335. package/dist/src/connectors/github/dlq.js +0 -190
  336. package/dist/src/connectors/github/dlq.js.map +0 -1
  337. package/dist/src/connectors/github/idempotency.js +0 -27
  338. package/dist/src/connectors/github/idempotency.js.map +0 -1
  339. package/dist/src/connectors/github/ingest.js +0 -156
  340. package/dist/src/connectors/github/ingest.js.map +0 -1
  341. package/dist/src/connectors/github/octokit-client.js +0 -70
  342. package/dist/src/connectors/github/octokit-client.js.map +0 -1
  343. package/dist/src/connectors/github/ratelimit.js +0 -31
  344. package/dist/src/connectors/github/ratelimit.js.map +0 -1
  345. package/dist/src/connectors/github/scope.js +0 -13
  346. package/dist/src/connectors/github/scope.js.map +0 -1
  347. package/dist/src/connectors/github/signature.js +0 -81
  348. package/dist/src/connectors/github/signature.js.map +0 -1
  349. package/dist/src/connectors/github/tenant-routing.js +0 -69
  350. package/dist/src/connectors/github/tenant-routing.js.map +0 -1
  351. package/dist/src/connectors/github/transform.js +0 -103
  352. package/dist/src/connectors/github/transform.js.map +0 -1
  353. package/dist/src/connectors/github/types.js +0 -100
  354. package/dist/src/connectors/github/types.js.map +0 -1
  355. package/dist/src/connectors/slack/backfill.js +0 -78
  356. package/dist/src/connectors/slack/backfill.js.map +0 -1
  357. package/dist/src/connectors/slack/deletion.js +0 -59
  358. package/dist/src/connectors/slack/deletion.js.map +0 -1
  359. package/dist/src/connectors/slack/dlq.js +0 -224
  360. package/dist/src/connectors/slack/dlq.js.map +0 -1
  361. package/dist/src/connectors/slack/idempotency.js +0 -31
  362. package/dist/src/connectors/slack/idempotency.js.map +0 -1
  363. package/dist/src/connectors/slack/ingest.js +0 -109
  364. package/dist/src/connectors/slack/ingest.js.map +0 -1
  365. package/dist/src/connectors/slack/ratelimit.js +0 -18
  366. package/dist/src/connectors/slack/ratelimit.js.map +0 -1
  367. package/dist/src/connectors/slack/scope.js +0 -13
  368. package/dist/src/connectors/slack/scope.js.map +0 -1
  369. package/dist/src/connectors/slack/signature.js +0 -27
  370. package/dist/src/connectors/slack/signature.js.map +0 -1
  371. package/dist/src/connectors/slack/tenant-routing.js +0 -41
  372. package/dist/src/connectors/slack/tenant-routing.js.map +0 -1
  373. package/dist/src/connectors/slack/transform.js +0 -47
  374. package/dist/src/connectors/slack/transform.js.map +0 -1
  375. package/dist/src/connectors/slack/types.js +0 -35
  376. package/dist/src/connectors/slack/types.js.map +0 -1
  377. package/dist/src/connectors/slack/web-client.js +0 -43
  378. package/dist/src/connectors/slack/web-client.js.map +0 -1
  379. package/dist/src/connectors/slack/workspaces.js +0 -62
  380. package/dist/src/connectors/slack/workspaces.js.map +0 -1
  381. package/dist/src/consolidate.js +0 -978
  382. package/dist/src/consolidate.js.map +0 -1
  383. package/dist/src/correction-latency.js +0 -74
  384. package/dist/src/correction-latency.js.map +0 -1
  385. package/dist/src/customer-notes.js +0 -325
  386. package/dist/src/customer-notes.js.map +0 -1
  387. package/dist/src/dag.js +0 -352
  388. package/dist/src/dag.js.map +0 -1
  389. package/dist/src/dashboard.js +0 -258
  390. package/dist/src/dashboard.js.map +0 -1
  391. package/dist/src/db.js +0 -2731
  392. package/dist/src/db.js.map +0 -1
  393. package/dist/src/decisions.js +0 -304
  394. package/dist/src/decisions.js.map +0 -1
  395. package/dist/src/dedupe.js +0 -141
  396. package/dist/src/dedupe.js.map +0 -1
  397. package/dist/src/embedding-provider.js +0 -314
  398. package/dist/src/embedding-provider.js.map +0 -1
  399. package/dist/src/embeddings.js +0 -543
  400. package/dist/src/embeddings.js.map +0 -1
  401. package/dist/src/eval-suite.js +0 -294
  402. package/dist/src/eval-suite.js.map +0 -1
  403. package/dist/src/eval.js +0 -187
  404. package/dist/src/eval.js.map +0 -1
  405. package/dist/src/extract.js +0 -117
  406. package/dist/src/extract.js.map +0 -1
  407. package/dist/src/forward-claim-detector.js +0 -117
  408. package/dist/src/forward-claim-detector.js.map +0 -1
  409. package/dist/src/goals.js +0 -399
  410. package/dist/src/goals.js.map +0 -1
  411. package/dist/src/graph-extract.js +0 -314
  412. package/dist/src/graph-extract.js.map +0 -1
  413. package/dist/src/graph-recall.js +0 -277
  414. package/dist/src/graph-recall.js.map +0 -1
  415. package/dist/src/graph-stream.js +0 -176
  416. package/dist/src/graph-stream.js.map +0 -1
  417. package/dist/src/graph-view.js +0 -310
  418. package/dist/src/graph-view.js.map +0 -1
  419. package/dist/src/graph.js +0 -762
  420. package/dist/src/graph.js.map +0 -1
  421. package/dist/src/handoff.js +0 -65
  422. package/dist/src/handoff.js.map +0 -1
  423. package/dist/src/hooks.js +0 -926
  424. package/dist/src/hooks.js.map +0 -1
  425. package/dist/src/importers.js +0 -881
  426. package/dist/src/importers.js.map +0 -1
  427. package/dist/src/incidents.js +0 -336
  428. package/dist/src/incidents.js.map +0 -1
  429. package/dist/src/index.js +0 -32
  430. package/dist/src/index.js.map +0 -1
  431. package/dist/src/invalidation.js +0 -129
  432. package/dist/src/invalidation.js.map +0 -1
  433. package/dist/src/mcp/framing.js +0 -45
  434. package/dist/src/mcp/framing.js.map +0 -1
  435. package/dist/src/mcp/server.js +0 -1298
  436. package/dist/src/mcp/server.js.map +0 -1
  437. package/dist/src/memory-value-weights.js +0 -31
  438. package/dist/src/memory-value-weights.js.map +0 -1
  439. package/dist/src/memory-value.js +0 -261
  440. package/dist/src/memory-value.js.map +0 -1
  441. package/dist/src/memory.js +0 -425
  442. package/dist/src/memory.js.map +0 -1
  443. package/dist/src/multihop.js +0 -35
  444. package/dist/src/multihop.js.map +0 -1
  445. package/dist/src/owner-validation.js +0 -56
  446. package/dist/src/owner-validation.js.map +0 -1
  447. package/dist/src/path-context.js +0 -48
  448. package/dist/src/path-context.js.map +0 -1
  449. package/dist/src/physics-config.js +0 -26
  450. package/dist/src/physics-config.js.map +0 -1
  451. package/dist/src/physics-state.js +0 -172
  452. package/dist/src/physics-state.js.map +0 -1
  453. package/dist/src/physics.js +0 -378
  454. package/dist/src/physics.js.map +0 -1
  455. package/dist/src/policies.js +0 -414
  456. package/dist/src/policies.js.map +0 -1
  457. package/dist/src/postinstall.js +0 -101
  458. package/dist/src/postinstall.js.map +0 -1
  459. package/dist/src/predictions.js +0 -629
  460. package/dist/src/predictions.js.map +0 -1
  461. package/dist/src/processes.js +0 -349
  462. package/dist/src/processes.js.map +0 -1
  463. package/dist/src/project-briefs.js +0 -492
  464. package/dist/src/project-briefs.js.map +0 -1
  465. package/dist/src/project-identity.js +0 -200
  466. package/dist/src/project-identity.js.map +0 -1
  467. package/dist/src/provenance-coverage.js +0 -23
  468. package/dist/src/provenance-coverage.js.map +0 -1
  469. package/dist/src/rate-limit.js +0 -60
  470. package/dist/src/rate-limit.js.map +0 -1
  471. package/dist/src/raw-archive-mirror-cleanup.js +0 -55
  472. package/dist/src/raw-archive-mirror-cleanup.js.map +0 -1
  473. package/dist/src/raw-archive.js +0 -91
  474. package/dist/src/raw-archive.js.map +0 -1
  475. package/dist/src/recall-history.js +0 -235
  476. package/dist/src/recall-history.js.map +0 -1
  477. package/dist/src/recall-scope.js +0 -89
  478. package/dist/src/recall-scope.js.map +0 -1
  479. package/dist/src/recall-trace.js +0 -186
  480. package/dist/src/recall-trace.js.map +0 -1
  481. package/dist/src/refine-llm.js +0 -156
  482. package/dist/src/refine-llm.js.map +0 -1
  483. package/dist/src/reject-flow.js +0 -209
  484. package/dist/src/reject-flow.js.map +0 -1
  485. package/dist/src/rejection.js +0 -160
  486. package/dist/src/rejection.js.map +0 -1
  487. package/dist/src/replay.js +0 -122
  488. package/dist/src/replay.js.map +0 -1
  489. package/dist/src/rerankers/cross-encoder.js +0 -137
  490. package/dist/src/rerankers/cross-encoder.js.map +0 -1
  491. package/dist/src/rerankers/index.js +0 -20
  492. package/dist/src/rerankers/index.js.map +0 -1
  493. package/dist/src/rerankers/jev.js +0 -119
  494. package/dist/src/rerankers/jev.js.map +0 -1
  495. package/dist/src/rerankers/llm.js +0 -80
  496. package/dist/src/rerankers/llm.js.map +0 -1
  497. package/dist/src/rerankers/types.js +0 -2
  498. package/dist/src/rerankers/types.js.map +0 -1
  499. package/dist/src/rrf.js +0 -61
  500. package/dist/src/rrf.js.map +0 -1
  501. package/dist/src/salience.js +0 -74
  502. package/dist/src/salience.js.map +0 -1
  503. package/dist/src/scheduler.js +0 -77
  504. package/dist/src/scheduler.js.map +0 -1
  505. package/dist/src/scope.js +0 -35
  506. package/dist/src/scope.js.map +0 -1
  507. package/dist/src/search.js +0 -1003
  508. package/dist/src/search.js.map +0 -1
  509. package/dist/src/secret-detect.js +0 -95
  510. package/dist/src/secret-detect.js.map +0 -1
  511. package/dist/src/server-detect.js +0 -231
  512. package/dist/src/server-detect.js.map +0 -1
  513. package/dist/src/server.js +0 -3255
  514. package/dist/src/server.js.map +0 -1
  515. package/dist/src/shared.js +0 -502
  516. package/dist/src/shared.js.map +0 -1
  517. package/dist/src/skills.js +0 -346
  518. package/dist/src/skills.js.map +0 -1
  519. package/dist/src/sleep-redact.js +0 -80
  520. package/dist/src/sleep-redact.js.map +0 -1
  521. package/dist/src/sso.js +0 -22
  522. package/dist/src/sso.js.map +0 -1
  523. package/dist/src/stdin.js +0 -41
  524. package/dist/src/stdin.js.map +0 -1
  525. package/dist/src/store.js +0 -3749
  526. package/dist/src/store.js.map +0 -1
  527. package/dist/src/tenant.js +0 -17
  528. package/dist/src/tenant.js.map +0 -1
  529. package/dist/src/trace.js +0 -72
  530. package/dist/src/trace.js.map +0 -1
  531. package/dist/src/version.js +0 -40
  532. package/dist/src/version.js.map +0 -1
  533. package/dist/src/working-memory.js +0 -157
  534. package/dist/src/working-memory.js.map +0 -1
  535. package/dist/src/yaml.js +0 -107
  536. package/dist/src/yaml.js.map +0 -1
  537. package/dist/sso.d.ts +0 -13
  538. package/dist/sso.d.ts.map +0 -1
  539. package/dist/sso.js +0 -22
  540. package/dist/sso.js.map +0 -1
  541. package/dist/stdin.d.ts.map +0 -1
  542. package/dist/stdin.js.map +0 -1
  543. package/dist/store.d.ts.map +0 -1
  544. package/dist/store.js.map +0 -1
  545. package/dist/tenant.d.ts.map +0 -1
  546. package/dist/tenant.js.map +0 -1
  547. package/dist/trace.d.ts.map +0 -1
  548. package/dist/trace.js.map +0 -1
  549. package/dist/version.d.ts.map +0 -1
  550. package/dist/version.js.map +0 -1
  551. package/dist/working-memory.d.ts.map +0 -1
  552. package/dist/working-memory.js.map +0 -1
  553. package/dist/yaml.d.ts.map +0 -1
  554. package/dist/yaml.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🦛 Hippo
2
2
 
3
- **The secret to good memory isn't remembering more. It's knowing what to forget.**
3
+ **Hippo learns what is wrong and stops repeating it.** Good memory is knowing what to forget: what turned out wrong, what got replaced, what nobody used.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/hippo-memory)](https://npmjs.com/package/hippo-memory)
6
6
  [![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
@@ -10,7 +10,7 @@
10
10
  <img src="./assets/hippo-init.svg" alt="hippo init --scan ~ — initializing memory across all repos" width="720">
11
11
  </p>
12
12
 
13
- A memory layer for AI agents. Modeled on the hippocampus. Decay by default, strength through use, provenance on every memory. SQLite under the hood, zero runtime deps, works with every CLI agent you have.
13
+ A memory layer for AI agents. Mark a memory wrong and it stops coming back. A newer fact replaces the old one. Memories you use get stronger. Provenance on every memory. SQLite under the hood, zero runtime deps, works with every CLI agent you have.
14
14
 
15
15
  ```bash
16
16
  npm install -g hippo-memory && hippo init --scan ~
@@ -18,6 +18,8 @@ npm install -g hippo-memory && hippo init --scan ~
18
18
 
19
19
  One command. Every git repo on your machine gets memory.
20
20
 
21
+ Having an AI agent install it? Point it at [llms-install.md](llms-install.md): it installs, wires hippo into the agents it finds, and verifies with `hippo doctor`.
22
+
21
23
  ```
22
24
  Works with: Claude Code, Codex, Cursor, OpenClaw, OpenCode, Pi, any MCP client
23
25
  Imports from: ChatGPT, Claude (CLAUDE.md), Cursor (.cursorrules), Slack, markdown
@@ -31,7 +33,7 @@ Dependencies: Zero runtime deps. Node.js 22.16+. Optional embeddings: bring-you
31
33
 
32
34
  Most "AI memory" systems save everything and search later. That's storage with semantic search bolted on. It's why your agent kept hitting the same deploy bug last week. And the week before. The system saw the failure four times. It had no way to know it should remember.
33
35
 
34
- Hippo applies the thing brains have been getting right for 500 million years. Memories decay over time. Retrieval makes them stronger. Three biological layers (buffer, episodic, semantic) consolidate during sleep. Hard lessons stick because you used them. Trivia fades because you didn't.
36
+ Hippo learns from outcomes. When a recalled memory turns out wrong, mark it bad and it drops out of the top results. When a fact changes, the new version supersedes the old one. Memories you keep using get stronger. Those are the parts we measured helping ([mechanism audit, round 2](https://github.com/kitfunso/hippo-memory/pull/232)). The design borrows from the hippocampus (decay, three layers, sleep consolidation), but that is inspiration. We have not measured decay or sleep making recall better.
35
37
 
36
38
  It also fixes the portability problem. Your ChatGPT memories don't travel to Claude. Your `.cursorrules` don't travel to Codex. Hippo is one process behind every agent. CLAUDE.md, Cursor rules, ChatGPT exports, Slack history, all in one SQLite store, all queryable from any tool that speaks MCP or HTTP.
37
39
 
@@ -49,7 +51,7 @@ claim we retracted.
49
51
  - **R@1 0.41 to 0.62 with `hippo recall "<query>" --reranker jev`** on a private 300-query developer store ([full eval](docs/evals/2026-09-19-jev-reranker.md)). The opt-in [TypeSafe Jev](https://typesafe.ai) reranker, off by default, about 0.0004 USD a recall. 2000-draw paired bootstrap; the margin held in 20 of 20 seeds and a permutation null reached it in 0 of 200 runs. Ranking only: three graded tests did **not** show a better answer rate than the free local cross-encoder, and that negative result is in the same doc. What it buys today is a shorter context, 2 memories ranked by Jev answering as well as 5 ranked by the cross-encoder.
50
52
  - **10 of 10 incident scenarios beat transcript replay** on a staged Slack corpus ([benchmarks/e1.3/](benchmarks/e1.3/)). Recall surfaces the cause faster than scrolling the last N messages.
51
53
  - **0 outbound HTTP** on the 1000-event ingestion smoke. Proven by a `globalThis.fetch` spy that throws on call, not a hardcoded zero. The default recall path makes no network call either; opt-in features such as the Jev reranker above, the LLM reranker and the API embedders do.
52
- - **926 tests, real DB, zero mocks.** Project rule. The one mocks-vs-prod divergence that bit us early is now the constraint that kept the next ten releases honest.
54
+ - **3,500+ tests on a real database.** No module mocks and no mocked store; only paid network calls are stubbed. Project rule. The one mocks-vs-prod divergence that bit us early is now the constraint that kept the next ten releases honest.
53
55
  - **dlPFC goal-conditioned cluster discrimination, 3/3 queries pass** — full goal stack with policy weighting and lifespan-windowed outcome propagation. Per-goal lift on a 3-cluster fixture where BM25 alone cannot discriminate; deterministic test in [`benchmarks/micro/results/b3-depth.json`](benchmarks/micro/results/b3-depth.json).
54
56
 
55
57
  ---
@@ -254,6 +256,8 @@ hippo recall "data pipeline" --why --limit 5
254
256
 
255
257
  Input enters the buffer. Important things get encoded into episodic memory. During "sleep," repeated episodes compress into semantic patterns. Weak memories decay and disappear.
256
258
 
259
+ The store is SQLite (`.hippo/hippo.db`). The markdown files and `index.json` are mirrors written after each change. From 1.46.0, `index.json` is no longer refreshed on every write; it comes only from an explicit export, so read the store through the CLI, the MCP server or the HTTP API.
260
+
257
261
  ```mermaid
258
262
  flowchart TD
259
263
  I[New information] --> B[Buffer<br/>session-only, no decay]
@@ -295,16 +299,15 @@ sequenceDiagram
295
299
 
296
300
  ### Decay by default
297
301
 
298
- Every memory has a half-life. 7 days by default. Persistence is earned.
302
+ Every memory has a half-life: 365 days by default. Until 1.46.0 the default was 7 days. A pre-registered evaluation found 7 days lost the current version of a fact far more often: it was in the top five 29% of the time at 7 days and 75% at 365 ([result](docs/evals/2026-09-24-decay-default-result.md)). 730 days and decay off both tied with 365. So 365 was not tuned: it is the tested value that tied with the others, and on that test decay made no measurable difference to recall. `hippo sleep` moves memories still on the old 7-day base to the new one, once, and records each move in the audit log. Set `defaultHalfLifeDays` in `.hippo/config.json` to choose your own.
299
303
 
300
304
  ```bash
301
305
  hippo remember "always check cache contents after refresh"
302
- # stored with half_life: 7d, strength: 1.0
306
+ # stored with half_life: 365d, strength: 1.0
303
307
 
304
- # 14 days later with no retrieval:
308
+ # two years later with no retrieval:
305
309
  hippo inspect mem_a1b2c3
306
310
  # strength: 0.25 (decayed by 2 half-lives)
307
- # at risk of removal on next sleep
308
311
  ```
309
312
 
310
313
  ---
@@ -316,12 +319,12 @@ Use it or lose it. Each recall boosts the half-life by 2 days.
316
319
  ```bash
317
320
  hippo recall "cache issues"
318
321
  # finds mem_a1b2c3, retrieval_count: 1 -> 2
319
- # half_life extended: 7d -> 9d
322
+ # half_life extended: 365d -> 367d
320
323
  # strength recalculated from retrieval timestamp
321
324
 
322
325
  hippo recall "cache issues" # again next week
323
326
  # retrieval_count: 2 -> 3
324
- # half_life: 9d -> 11d
327
+ # half_life: 367d -> 369d
325
328
  # this memory is learning to survive
326
329
  ```
327
330
 
@@ -452,6 +455,8 @@ hippo sleep
452
455
 
453
456
  Three or more related episodes get merged into a single semantic memory. The originals decay. The pattern survives.
454
457
 
458
+ Sleep keeps the store tidy. It has not been shown to improve recall. In round 2 of the mechanism audit, a slept LongMemEval store scored 3.6 points lower at hit@5 than the same store never slept, and no scorer showed sleep helping ([PR #232](https://github.com/kitfunso/hippo-memory/pull/232)).
459
+
455
460
  **Experimental: learned memory-value rescue (opt-in, default off).** With
456
461
  `{"memoryValue":{"enabled":true}}` in `.hippo/config.json`, sleep consults a learned
457
462
  linear memory-value scorer before deleting a decayed memory: a memory that scores in the
@@ -465,6 +470,34 @@ usage, NOT real usage value — treat the flag as an experiment, not a recommend
465
470
  Tenants with fewer than 10 non-pinned memories never rescue (rank statistics are noise at
466
471
  tiny scale).
467
472
 
473
+ **Faded memories go dormant, not gone (on by default).** Sleep moves a memory that faded
474
+ below the decay threshold into a dormant store instead of deleting it. A dormant memory
475
+ leaves recall and context exactly like a deleted one and sits out every later sleep, so
476
+ your agent's context stays as lean as before, but nothing is lost:
477
+
478
+ ```bash
479
+ hippo dormant # list, newest first (--json, --limit <n>)
480
+ hippo dormant "staging hostname" # search: every term must match
481
+ hippo dormant restore mem_a1b2c3 # back to active memory, as if just recalled
482
+ hippo dormant forget mem_a1b2c3 # delete for good
483
+ ```
484
+
485
+ A restored memory comes back with a fresh recall clock, so it gets a full half-life before
486
+ it can fade again, and every restore is logged (`hippo audit list --op dormant_restore`) as
487
+ a "forgot it, then needed it" signal. Two guardrails: a faded memory that the secret
488
+ detector flags is deleted, never kept dormant, and a dormant memory nobody restores within
489
+ `dormant.retentionDays` (default 180, `0` keeps them forever) is deleted for good. Rejecting
490
+ a value (`hippo reject`) removes its dormant copies too. To delete faded memories straight
491
+ away as before, set `{"dormant":{"enabled":false}}` in `.hippo/config.json`. Sleep never
492
+ removes pinned memories or raw receipts (Slack, GitHub, vault imports) either way, and
493
+ duplicate removal and junk cleanup still delete.
494
+
495
+ **See what memory costs in tokens.** Every block of memory text hippo hands an agent (the
496
+ per-prompt hook, `hippo context`, `hippo recall`, the MCP tools, the HTTP API) is recorded
497
+ in a token ledger: counts, surface and session, never the text. `hippo tokens` shows the
498
+ totals for the last 30 days (`--days`, `--json`). Counts are estimates (characters / 4), the
499
+ same estimate every budget uses. Rows older than 90 days are pruned.
500
+
468
501
  ---
469
502
 
470
503
  ### Outcome feedback
@@ -486,6 +519,8 @@ hippo outcome --bad
486
519
 
487
520
  Outcomes are cumulative. A memory with 5 positive outcomes and 0 negative has a reward factor of ~1.42, making its effective half-life 42% longer. A memory with 0 positive and 3 negative has a factor of ~0.63, decaying nearly twice as fast. Mixed outcomes converge toward neutral (1.0).
488
521
 
522
+ This is the mechanism with the clearest measured win. On the synthetic E1 test, plain BM25 plus the outcome nudge cut how often a marked-bad memory stayed in the top five from 71.9% to 0.0% ([mechanism audit, round 2](https://github.com/kitfunso/hippo-memory/pull/232)). Every mark in E1 is correct; real marks are noisier, since `--bad` marks the whole recall batch.
523
+
489
524
  ---
490
525
 
491
526
  ### Token budgets
@@ -590,6 +625,11 @@ hippo watch "npm run build"
590
625
  | `hippo outcome --id <id> --good` | Target a specific memory |
591
626
  | `hippo inspect <id>` | Full detail on one memory |
592
627
  | `hippo forget <id>` | Force remove a memory |
628
+ | `hippo dormant [<query>]` | List faded memories sleep kept instead of deleting |
629
+ | `hippo dormant restore <id>` | Bring a dormant memory back to active memory |
630
+ | `hippo dormant forget <id>` | Delete a dormant memory permanently |
631
+ | `hippo doctor [--json]` | Check the install: Node, store, schema, sleep, agent hooks; each problem names its fix |
632
+ | `hippo tokens [--days n]` | Estimated tokens of memory text handed to agents, per surface, and what skipping unchanged hook blocks saved |
593
633
  | `hippo embed` | Embed all memories for semantic search |
594
634
  | `hippo embed --status` | Show embedding coverage |
595
635
  | `hippo watch "<command>"` | Run command, auto-learn from failures |
@@ -681,9 +721,11 @@ This adds a `<!-- hippo:start -->` ... `<!-- hippo:end -->` block that tells the
681
721
  For Claude Code, it also adds:
682
722
  - a `SessionEnd` hook so `hippo sleep` runs automatically when the session exits
683
723
  - a `SessionStart` hook that prints the previous session's consolidation output
684
- - a `UserPromptSubmit` hook that runs `hippo context --pinned-only --include-recent 5 --format additional-context` every turn. It re-injects pinned memories (`hippo remember <text> --pin`) plus the last 5 writes, so fresh same-session lessons appear on the next prompt before you pin them. Opt out with `{"pinnedInject":{"enabled":false}}` in `.hippo/config.json`.
724
+ - a `UserPromptSubmit` hook that runs `hippo context --pinned-only --include-recent 5 --format additional-context` every turn. It re-injects pinned memories (`hippo remember <text> --pin`) plus the last 5 writes, so fresh same-session lessons appear on the next prompt before you pin them. The block is rendered without live strength percentages, so it stays byte-identical while its memories do not change, and it is sent only when it changed since the session's last prompt: an unchanged block is skipped, resent every 10 skips (`pinnedInject.refreshTurns`, `0` never resends) and resent after compaction. `{"pinnedInject":{"skipUnchanged":false}}` sends it every turn as before. Opt out entirely with `{"pinnedInject":{"enabled":false}}` in `.hippo/config.json`.
685
725
  - a `PreCompact` hook that runs `hippo pre-compact` before the transcript gets summarized. It saves a working-state snapshot (task/summary/next step) and extracts durable memories from the tail, so mid-session compaction can't drop them.
686
726
  - a second `SessionStart` hook (matcher `compact`) that runs `hippo compact-resume`, printing that snapshot plus the recent session trail back into context right after compaction.
727
+ - a `PostCompact` hook that runs `hippo post-compact`, which tells you what was saved ("Hippo saved your task snapshot and 2 new memories before compacting"). It prints nothing when nothing was saved.
728
+ - a `PostToolUseFailure` hook that runs `hippo capture-error`, which stores a failed tool call as an error memory. It skips interrupts, declined permissions and searches that found nothing, and stores a repeated failure once.
687
729
 
688
730
  To remove: `hippo hook uninstall claude-code`
689
731
 
@@ -723,7 +765,9 @@ Add to your MCP config (e.g. `.cursor/mcp.json` or `claude_desktop_config.json`)
723
765
  }
724
766
  ```
725
767
 
726
- Exposes tools: `hippo_recall`, `hippo_remember`, `hippo_outcome`, `hippo_context`, `hippo_status`, `hippo_learn`, `hippo_wm_push`.
768
+ No global install needed: `"command": "npx", "args": ["-y", "hippo-memory", "mcp"]` works too. With no store anywhere, the first tool call creates the global store (`~/.hippo`); `hippo init` in a project adds a project store. Check any install with `hippo doctor`.
769
+
770
+ Exposes 13 tools: `hippo_recall`, `hippo_assemble`, `hippo_drill`, `hippo_remember`, `hippo_outcome`, `hippo_context`, `hippo_status`, `hippo_learn`, `hippo_conflicts`, `hippo_resolve`, `hippo_share`, `hippo_peers`, `hippo_predict_baserate`.
727
771
 
728
772
  ### OpenClaw Plugin
729
773
 
@@ -745,7 +789,7 @@ Plugin docs: [extensions/openclaw-plugin/](extensions/openclaw-plugin/). Integra
745
789
 
746
790
  ### Claude Code Plugin
747
791
 
748
- Plugin with SessionStart/Stop hooks and error auto-capture. See [extensions/claude-code-plugin/](extensions/claude-code-plugin/).
792
+ Plugin with session, prompt and compaction hooks plus error auto-capture. See [extensions/claude-code-plugin/](extensions/claude-code-plugin/).
749
793
 
750
794
  Full integration details: [integrations/](integrations/)
751
795
 
@@ -753,11 +797,11 @@ Full integration details: [integrations/](integrations/)
753
797
 
754
798
  ## The Neuroscience
755
799
 
756
- Hippo is modeled on seven properties of the human hippocampus. Not metaphorically. Literally.
800
+ Hippo's design borrows seven properties of the human hippocampus. This section is design inspiration, not measured benefit. For what we measured, see the Receipts and [PR #232](https://github.com/kitfunso/hippo-memory/pull/232).
757
801
 
758
802
  **Why two stores?** The brain uses a fast hippocampal buffer + a slow neocortical store (Complementary Learning Systems theory, McClelland et al. 1995). If the neocortex learned fast, new information would overwrite old knowledge. The buffer absorbs new episodes; the neocortex extracts patterns over time.
759
803
 
760
- **Why does decay help?** New neurons born in the dentate gyrus actively disrupt old memory traces (Frankland et al. 2013). This is adaptive: it reduces interference from outdated information. Forgetting isn't failure. It's maintenance.
804
+ **Why decay at all?** In the brain, new neurons born in the dentate gyrus disrupt old memory traces (Frankland et al. 2013), which may reduce interference from outdated information. That is why hippo has decay. In hippo's own tests, age-based decay made no measurable difference to recall: at the 365-day default it tied with decay switched off. The forgetting that measured helpful is by evidence: a bad outcome mark, or a newer fact superseding an old one.
761
805
 
762
806
  **Why do errors stick?** The amygdala modulates hippocampal consolidation based on emotional significance. Fear and error signals boost encoding. Your first production incident is burned into memory. Your 200th uneventful deploy isn't.
763
807
 
@@ -799,16 +843,16 @@ The AI-memory category matured fast in 2026. Hippo's specific take — bio-decay
799
843
  | Auto-hook install | Yes | No | No | No | No | No | No | No | No | No |
800
844
  | MCP server | Yes | Yes | No | No | Yes (stdio + HTTP/OAuth) | Partial (managed) | Yes (via Letta Code) | Yes (first-party Claude/LangGraph) | Yes | ? |
801
845
  | Zero runtime deps | Yes | No (ChromaDB) | No | No | No (PGLite or PG+pgvector) | No (managed service) | No (Python deps) | No (Python deps) | Yes (single Rust binary) | No (managed + OSS) |
802
- | LongMemEval (best published) | 98.6% default / 99.8% voyage R@5 (s_cleaned, per-haystack)\* | 96.6% raw / 100% reranked R@5 | ~49-85% R@5 | N/A | 97.6-97.9% R@5 (s_cleaned\*) | N/A (LoCoMo 80.3%) | N/A | N/A | 88.78% overall accuracy w/ reader\*\* | 83.00% overall\*\* (LoCoMo 93.05%, HaluMem 93.04%) |
846
+ | LongMemEval (best published) | 98.0% local / 99.8% voyage R@5 (s_cleaned, per-haystack)\* | 96.6% raw / 100% reranked R@5 | ~49-85% R@5 | N/A | 97.6-97.9% R@5 (s_cleaned\*) | N/A (LoCoMo 80.3%) | N/A | N/A | 88.78% overall accuracy w/ reader\*\* | 83.00% overall\*\* (LoCoMo 93.05%, HaluMem 93.04%) |
803
847
  | Git-friendly | Yes | No | No | Yes | Yes | No | No | No | Yes (Git is the model) | ? |
804
848
  | Framework agnostic | Yes | Yes | Partial | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
805
849
  | License | MIT | (open) | Apache-2.0 | (open) | MIT | Apache-2.0 (community) | Apache-2.0 | MIT (core) | Apache-2.0 | Apache-2.0 (OSS) + cloud |
806
850
 
807
- \* Hippo's 98.6% (zero-dep default) and 99.8% (voyage-3-large) are on `longmemeval_s_cleaned`, per-question haystack, directly comparable to gbrain's 97.6% on the same split and metric (measured 2026-06-09, see [`docs/evals/2026-06-09-longmemeval-per-haystack-dual.md`](docs/evals/2026-06-09-longmemeval-per-haystack-dual.md)). gbrain's figure is their published claim. An older hippo number, 86.8% R@5 on `longmemeval_oracle` under pooled (non-per-haystack) retrieval, is not comparable to per-haystack figures.
851
+ \* Hippo's 98.0% uses the free local MiniLM embedder (an optional install) and 99.8% uses voyage-3-large (measured 2026-06-09, not re-run). Both are on `longmemeval_s_cleaned` with a per-question haystack, the split and metric of gbrain's published 97.6%. Each is the best of five retrieval settings in the benchmark scripts, not `hippo recall`. At 500 questions the 95% interval is about ±1.2 points, so 98.0 and 97.6 are a tie. The June 2026 build scored 98.6; [`docs/evals/2026-09-23-longmemeval-reproduction.md`](docs/evals/2026-09-23-longmemeval-reproduction.md) has both runs. An older hippo number, 86.8% R@5 on `longmemeval_oracle` under pooled (non-per-haystack) retrieval, is not comparable to per-haystack figures.
808
852
 
809
853
  \*\* Different metric: Memoria's 88.78% and EverMind's 83% are reported as overall accuracy with a reader LLM, not retrieval R@5. Higher denominator + LLM helps. Not directly comparable to retrieval-only R@5 numbers above.
810
854
 
811
- Different tools answer different questions. Mem0 and Basic Memory implement "save everything, search later." MemPalace implements "store everything, organize spatially for retrieval." gbrain, Zep, and Cognee implement "extract typed entities and relationships into a knowledge graph." Letta implements "the agent edits its own memory blocks." Memoria implements "Git-style version control over the memory state itself." EverMind implements "self-evolving Skill Memory + multi-modal retrieval over hierarchical scopes." Hippo implements "forget by default, earn persistence through use." These are complementary takes, not a single-axis ranking: bio-lifecycle (Hippo) + GraphRAG (gbrain/Cognee/Zep) + agent-self-edit (Letta) + memory-VCS (Memoria) + skill-distillation (EverMind) cover different parts of the same problem.
855
+ Different tools answer different questions. Mem0 and Basic Memory implement "save everything, search later." MemPalace implements "store everything, organize spatially for retrieval." gbrain, Zep, and Cognee implement "extract typed entities and relationships into a knowledge graph." Letta implements "the agent edits its own memory blocks." Memoria implements "Git-style version control over the memory state itself." EverMind implements "self-evolving Skill Memory + multi-modal retrieval over hierarchical scopes." Hippo implements "learn what is wrong and stop repeating it." These are complementary takes, not a single-axis ranking: bio-lifecycle (Hippo) + GraphRAG (gbrain/Cognee/Zep) + agent-self-edit (Letta) + memory-VCS (Memoria) + skill-distillation (EverMind) cover different parts of the same problem.
812
856
 
813
857
  ---
814
858
 
@@ -820,16 +864,16 @@ Three benchmarks testing three different things. Full details in [`benchmarks/`]
820
864
 
821
865
  [LongMemEval](https://arxiv.org/abs/2410.10813) (ICLR 2025) is the industry-standard benchmark: 500 questions across 5 memory abilities, embedded in 115k+ token chat histories.
822
866
 
823
- **Standard per-haystack result (`_s` split, measured 2026-06-09).** Each question is scored against its own ~48-session haystack, the same way gbrain and other published systems report. The v1.23.0 pluggable embedding provider lets you choose the embedder:
867
+ **Standard per-haystack result (`_s` split; MiniLM re-measured 2026-09-23, voyage measured 2026-06-09).** Each question is scored against its own ~48-session haystack, the same way gbrain and other published systems report. The v1.23.0 pluggable embedding provider lets you choose the embedder:
824
868
 
825
869
  | Embedder | Dense-only R@5 | Best hybrid R@5 | R@1 |
826
870
  |----------|----------------|-----------------|-----|
827
- | MiniLM-L6 (zero-dependency default) | 96.6 | 98.6 | 89.6 |
828
- | voyage-3-large (opt-in) | 99.8 | 99.8 | 94.6 |
871
+ | MiniLM-L6 (local, optional install) | 96.8 | 98.0 | 88.4 |
872
+ | voyage-3-large (opt-in, paid) | 99.8 | 99.8 | 94.6 |
829
873
 
830
- gbrain reports 97.6 R@5 on this split with a paid frontier embedder. Hippo's free, local, zero-dependency default reaches 98.6. Retrieval recall on the standard task is effectively saturated, so the embedder is a swappable commodity, not the differentiator. Method and the global-pool comparison: [`docs/evals/2026-06-09-longmemeval-per-haystack-dual.md`](docs/evals/2026-06-09-longmemeval-per-haystack-dual.md).
874
+ gbrain reports 97.6 R@5 on this split with a paid frontier embedder. Hippo reaches 98.0 with a free local embedder, a tie at 500 questions. These numbers come from the scripts in `benchmarks/longmemeval/`, which index every turn and fuse BM25 with dense ranks; they are not `hippo recall`, and a default install has no embedder. Re-measure: [`docs/evals/2026-09-23-longmemeval-reproduction.md`](docs/evals/2026-09-23-longmemeval-reproduction.md). Retrieval recall on the standard task is effectively saturated, so the embedder is a swappable commodity, not the differentiator. Method and the global-pool comparison: [`docs/evals/2026-06-09-longmemeval-per-haystack-dual.md`](docs/evals/2026-06-09-longmemeval-per-haystack-dual.md).
831
875
 
832
- The differentiator is what happens as one store grows. Point retrieval at a single unified memory of tens of thousands of sessions, with no pre-scoped haystack, and recall stops being free (default 47, voyage 56 on the 19,195-session `_s` store). That is where memory lifecycle (decay, consolidation, supersession) earns its keep, and it is what hippo measures next (see ROADMAP Part III).
876
+ The differentiator is what happens as one store grows. Point retrieval at a single unified memory of tens of thousands of sessions, with no pre-scoped haystack, and recall stops being free (MiniLM 47, voyage 56 on the 19,195-session `_s` store, June 2026). That is where we expect the memory lifecycle to matter, and it is what hippo measures next (see ROADMAP Part III). It is not shown yet: in our tests so far, decay made no measurable difference and sleep cost recall. Outcome marks and supersession are what measured helpful.
833
877
 
834
878
  **Hippo v0.28.0 oracle-split results (hybrid BM25 + cosine, full 500 questions, pooled retrieval):**
835
879
 
@@ -909,7 +953,7 @@ node run.mjs --adapter all
909
953
  Issues and PRs welcome. Before contributing, run `hippo status` in the repo root to see the project's own memory.
910
954
 
911
955
  The interesting problems:
912
- - **LongMemEval retrieval (standard task: done).** Per-question-haystack R@5 is 98.6% with the zero-dependency default and 99.8% with voyage-3-large (measured 2026-06-09), at or above the published frontier. Retrieval is no longer the gap; the lifecycle stress eval (ROADMAP Part III) is the next measurement.
956
+ - **LongMemEval retrieval (standard task: done).** Per-question-haystack R@5 is 98.0% with the free local embedder (re-measured 2026-09-23; the June build gave 98.6) and 99.8% with voyage-3-large (measured 2026-06-09), level with the published frontier. Retrieval is no longer the gap; the lifecycle stress eval (ROADMAP Part III) is the next measurement.
913
957
  - Better consolidation heuristics (LLM-powered merge vs current text overlap)
914
958
  - Web UI / dashboard for visualizing decay curves and memory health
915
959
  - Optimal decay parameter tuning from real usage data
package/bin/hippo.js CHANGED
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import '../dist/cli.js';
2
+ import { runCli } from '../dist/cli.js';
3
+
4
+ runCli();
@@ -50,7 +50,13 @@
50
50
  * arms must not pass it.
51
51
  * HIPPO_ABLATE_OUTCOME_SLOW rewardFactor := 1 (no half-life modulation).
52
52
  * HIPPO_ABLATE_OUTCOME_FAST hybridSearch outcomeBoost := 1.
53
- * HIPPO_FAKE_NOW timestamp injected as the default `now` for
53
+ * HIPPO_ABLATE_RECENCY search recency factor := 1 (the creation-age
54
+ * multiplier 0.8 + 0.2*exp(-age/30d)); decay,
55
+ * strengthening and outcomes stay live.
56
+ * HIPPO_EVAL_RECENCY_DAYS a positive number replaces the 30-day scale of
57
+ * that recency factor (tuning grids only). Unset,
58
+ * zero, negative or junk values keep 30.
59
+ * HIPPO_FAKE_NOW timestamp injected as the default `now` for
54
60
  * strength computation and retrieval stamping
55
61
  * (simulated-time protocols). MUST be the exact
56
62
  * Date.toISOString() form
@@ -82,6 +88,9 @@ export declare function isDecayAblated(): boolean;
82
88
  export declare function isRecallBoostAblated(): boolean;
83
89
  export declare function isOutcomeSlowAblated(): boolean;
84
90
  export declare function isOutcomeFastAblated(): boolean;
91
+ export declare function isRecencyAblated(): boolean;
92
+ /** HIPPO_EVAL_RECENCY_DAYS when it is a positive number, else null (callers keep their default). */
93
+ export declare function evalRecencyScaleDays(): number | null;
85
94
  /**
86
95
  * The default `now` for lifecycle computations: HIPPO_FAKE_NOW when set and
87
96
  * parseable, else the real clock. Callers that already take an explicit `now`
package/dist/ablation.js CHANGED
@@ -50,7 +50,13 @@
50
50
  * arms must not pass it.
51
51
  * HIPPO_ABLATE_OUTCOME_SLOW rewardFactor := 1 (no half-life modulation).
52
52
  * HIPPO_ABLATE_OUTCOME_FAST hybridSearch outcomeBoost := 1.
53
- * HIPPO_FAKE_NOW timestamp injected as the default `now` for
53
+ * HIPPO_ABLATE_RECENCY search recency factor := 1 (the creation-age
54
+ * multiplier 0.8 + 0.2*exp(-age/30d)); decay,
55
+ * strengthening and outcomes stay live.
56
+ * HIPPO_EVAL_RECENCY_DAYS a positive number replaces the 30-day scale of
57
+ * that recency factor (tuning grids only). Unset,
58
+ * zero, negative or junk values keep 30.
59
+ * HIPPO_FAKE_NOW timestamp injected as the default `now` for
54
60
  * strength computation and retrieval stamping
55
61
  * (simulated-time protocols). MUST be the exact
56
62
  * Date.toISOString() form
@@ -101,11 +107,14 @@ function readFlags() {
101
107
  fakeNowMs = parsed;
102
108
  }
103
109
  }
110
+ const recencyDays = Number(process.env.HIPPO_EVAL_RECENCY_DAYS);
104
111
  _cache = {
105
112
  decay: isTruthy(process.env.HIPPO_ABLATE_DECAY),
106
113
  recallBoost: isTruthy(process.env.HIPPO_ABLATE_RECALL_BOOST),
107
114
  outcomeSlow: outcomeBoth || isTruthy(process.env.HIPPO_ABLATE_OUTCOME_SLOW),
108
115
  outcomeFast: outcomeBoth || isTruthy(process.env.HIPPO_ABLATE_OUTCOME_FAST),
116
+ recency: isTruthy(process.env.HIPPO_ABLATE_RECENCY),
117
+ recencyDays: Number.isFinite(recencyDays) && recencyDays > 0 ? recencyDays : null,
109
118
  fakeNowMs,
110
119
  };
111
120
  return _cache;
@@ -122,6 +131,13 @@ export function isOutcomeSlowAblated() {
122
131
  export function isOutcomeFastAblated() {
123
132
  return readFlags().outcomeFast;
124
133
  }
134
+ export function isRecencyAblated() {
135
+ return readFlags().recency;
136
+ }
137
+ /** HIPPO_EVAL_RECENCY_DAYS when it is a positive number, else null (callers keep their default). */
138
+ export function evalRecencyScaleDays() {
139
+ return readFlags().recencyDays;
140
+ }
125
141
  /**
126
142
  * The default `now` for lifecycle computations: HIPPO_FAKE_NOW when set and
127
143
  * parseable, else the real clock. Callers that already take an explicit `now`
package/dist/api.d.ts CHANGED
@@ -9,6 +9,8 @@
9
9
  import { type DatabaseSyncLike } from './db.js';
10
10
  import { deleteEntry, loadAllEntries, type TaskSnapshot, type SessionEvent } from './store.js';
11
11
  import { type RejectedValueRow } from './rejection.js';
12
+ import { type DormantMemory, type ListDormantOpts } from './dormant.js';
13
+ import { type TokenSummary, type TokenSurface } from './token-ledger.js';
12
14
  import { type SessionHandoff } from './handoff.js';
13
15
  import { type MemoryKind, type MemoryEntry } from './memory.js';
14
16
  import { auditMemories, type AuditEvent, type AuditOp } from './audit.js';
@@ -31,7 +33,7 @@ import { type AvailabilityHint } from './availability.js';
31
33
  * object carrying both the audit-log subject (formerly the string itself) and
32
34
  * a role for /v1/sleep admin gating. Audit helpers continue accepting `string`
33
35
  * — callers pass `ctx.actor.subject`. Role checks happen at the request
34
- * boundary (e.g. /v1/sleep), not inside api functions.
36
+ * boundary (e.g. /v1/sleep), except in authCreate and authRevoke (ForbiddenError).
35
37
  */
36
38
  export interface Actor {
37
39
  /** 'cli' | 'localhost:cli' | 'api_key:<key_id>' | 'mcp' | 'connector:slack' | 'connector:github' */
@@ -72,9 +74,14 @@ export declare class RecallContractError extends Error {
72
74
  readonly code: 'fresh_tail_requires_session_id' | 'invalid_scorer_window';
73
75
  constructor(code: 'fresh_tail_requires_session_id' | 'invalid_scorer_window', message: string);
74
76
  }
77
+ /** The actor's role or identity does not allow the operation. HTTP maps it to 403. */
78
+ export declare class ForbiddenError extends Error {
79
+ constructor(message: string);
80
+ }
75
81
  import { isPrivateScope, passesScopeFilterForRecall } from './recall-scope.js';
76
82
  export { isPrivateScope, passesScopeFilterForRecall };
77
- export { passesCliRecallScopeFilter } from './recall-scope.js';
83
+ export { passesCliRecallScopeFilter, ScopeForbiddenError } from './recall-scope.js';
84
+ export type { TokenSummary, TokenSurface, TokenSurfaceSummary } from './token-ledger.js';
78
85
  export { classifyOriginProject } from './project-identity.js';
79
86
  /**
80
87
  * v39 S4: the secret half of the ambient policy on its own, for surfaces
@@ -141,6 +148,7 @@ export interface RecallOpts {
141
148
  * (e.g. mean-of-children summary re-rank).
142
149
  */
143
150
  scorerWindow?: number;
151
+ /** Candidate order. `recall` always keeps the BM25 order; `retrieve` honours this. */
144
152
  mode?: 'bm25' | 'hybrid' | 'physics';
145
153
  /**
146
154
  * Restrict results to memories whose `scope` equals this value exactly.
@@ -495,9 +503,8 @@ export declare function buildSuppressionSummary(counts: {
495
503
  }): RecallSuppressionSummary;
496
504
  /**
497
505
  * Domain-level recall. Loads BM25-ranked candidates from SQLite scoped to
498
- * `ctx.tenantId`. The `mode` flag is accepted for forward compatibility (the
499
- * CLI exposes hybrid/physics paths) but Task 2 wires only the BM25 candidate
500
- * loader; later tasks can extend this to call the physics/hybrid scorer.
506
+ * `ctx.tenantId` and keeps that order whatever `mode` says; `retrieve` is the
507
+ * mode-aware, strengthening variant the HTTP route uses.
501
508
  *
502
509
  * **api.recall does NOT mutate `index.last_retrieval_ids`** (v1.11.5 contract
503
510
  * lock). The CLI `cmdRecall` (cli.ts) writes `last_retrieval_ids` because the
@@ -510,6 +517,8 @@ export declare function buildSuppressionSummary(counts: {
510
517
  * `tests/api-recall-no-side-effects.test.ts`.
511
518
  */
512
519
  export declare function recall(ctx: Context, opts: RecallOpts): RecallResult;
520
+ /** Mode-aware recall that strengthens each returned row; never writes last_retrieval_ids (v1.11.5 lock). */
521
+ export declare function retrieve(ctx: Context, opts: RecallOpts): Promise<RecallResult>;
513
522
  export interface AssembleOpts {
514
523
  /** Token budget. Default 4000. */
515
524
  budget?: number;
@@ -833,9 +842,8 @@ export interface AuthCreateResult {
833
842
  * `src/server.ts` POST /v1/auth/keys mirrors this: it ignores any body
834
843
  * `tenantId` and uses the resolved Bearer's tenant exclusively.
835
844
  *
836
- * Per A5 v2 follow-ups (TODOS.md), `auth_create` is currently unaudited —
837
- * we intentionally match that behavior here for consistency. When A5 v2
838
- * lands and adds the audit op, this function should mirror the cli handler.
845
+ * Only an admin actor can mint (ForbiddenError otherwise), so a member key
846
+ * can never create a key, least of all an admin one.
839
847
  */
840
848
  export declare function authCreate(ctx: Context, opts: AuthCreateOpts): AuthCreateResult;
841
849
  /**
@@ -853,8 +861,8 @@ export declare function authList(ctx: Context, opts: {
853
861
  * Revoke an API key.
854
862
  *
855
863
  * Security: the key must belong to `ctx.tenantId`. Cross-tenant revoke is
856
- * rejected with the same "not found" message used for missing keys, so that a
857
- * caller cannot probe which key_ids exist on other tenants.
864
+ * rejected with the "not found" message used for missing keys, and a member may
865
+ * revoke only its own key (checked first), so no caller can probe other key_ids.
858
866
  *
859
867
  * Audit: emits 'auth_revoke' with `tenantId` set to the KEY ROW's tenant_id
860
868
  * (M1 fix from A5 review, mirrors src/cli.ts:cmdAuthRevoke). Skipped on no-op
@@ -993,9 +1001,65 @@ export interface SleepOpts {
993
1001
  */
994
1002
  __phases?: Partial<SleepPhases>;
995
1003
  }
1004
+ /**
1005
+ * Record memory text handed to an agent in the token ledger (ROADMAP TE0).
1006
+ * Best-effort: never throws, because a ledger failure must not fail the
1007
+ * recall or context call that produced the text.
1008
+ */
1009
+ export declare function recordTokens(ctx: Context, surface: TokenSurface, use: {
1010
+ items: number;
1011
+ tokens: number;
1012
+ sessionId?: string | null;
1013
+ }): void;
1014
+ /**
1015
+ * Token ledger totals for the tenant over the last `days` days (default 30):
1016
+ * tokens sent per surface, blocks skipped as unchanged and the tokens that
1017
+ * saved, and mean tokens per session.
1018
+ */
1019
+ export declare function tokenSummary(ctx: Context, opts?: {
1020
+ days?: number;
1021
+ }): TokenSummary;
1022
+ /**
1023
+ * A tenant's dormant memories (src/dormant.ts): what sleep moved out of
1024
+ * active memory instead of deleting, when `dormant.enabled` is on. Newest
1025
+ * first; `opts.query` keeps rows containing every term (case-insensitive).
1026
+ */
1027
+ export declare function listDormant(ctx: Context, opts?: ListDormantOpts): DormantMemory[];
1028
+ /**
1029
+ * Bring a dormant memory back into active memory. It returns as if just
1030
+ * recalled: `last_retrieved` is now, so it gets a full half-life before it
1031
+ * can fade again. Every other field is the snapshot taken when it went
1032
+ * dormant.
1033
+ *
1034
+ * Throws when the tenant has no dormant memory with that id (another
1035
+ * tenant's id reads the same way), when a live memory already holds the id,
1036
+ * and RejectedValueError when the value has been rejected since. On any
1037
+ * throw the dormant copy stays where it is.
1038
+ */
1039
+ export declare function restoreDormant(ctx: Context, id: string): MemoryEntry;
1040
+ /**
1041
+ * Permanently delete a dormant memory: the explicit "forget it for good"
1042
+ * that dormant storage leaves to the user. Throws when the tenant has no
1043
+ * dormant memory with that id.
1044
+ */
1045
+ export declare function forgetDormant(ctx: Context, id: string): void;
1046
+ /** Whether the tenant holds a dormant memory with this id (for "not found" hints). */
1047
+ export declare function isDormant(ctx: Context, id: string): boolean;
996
1048
  export interface SleepResult {
997
1049
  active: number;
998
1050
  removed: number;
1051
+ /**
1052
+ * Faded memories the decay pass moved to the dormant store instead of
1053
+ * deleting (config `dormant.enabled`). Absent when 0. Per-invocation
1054
+ * activity counter, same class as `removed`.
1055
+ */
1056
+ dormant?: number;
1057
+ /**
1058
+ * Dormant memories deleted for good this sleep because they outlived
1059
+ * `dormant.retentionDays`. Absent when 0. Same per-invocation class as
1060
+ * `removed`.
1061
+ */
1062
+ dormantExpired?: number;
999
1063
  mergedEpisodic: number;
1000
1064
  newSemantic: number;
1001
1065
  dryRun: boolean;
@@ -1014,26 +1078,22 @@ export interface SleepResult {
1014
1078
  * v1.25.0: count of memories the auto-share secret veto withheld this sleep
1015
1079
  * — rows that passed every other admission gate (transfer score,
1016
1080
  * not-already-global) and were blocked solely by `detectSecret`. Absent
1017
- * when 0 or when auto-share did not run. Same redaction class as `shared`
1018
- * (per-invocation activity counter, NOT redacted on egress — see the
1019
- * "NOT redacted" list in src/sleep-redact.ts).
1081
+ * when 0 or when auto-share did not run.
1020
1082
  */
1021
1083
  secretSkipped?: number;
1022
1084
  /**
1023
1085
  * AT1: count of auto-share candidates the GLOBAL store's rejection
1024
1086
  * tombstone refused this sleep (docs/plans/2026-08-15-at1-rejected-value-tombstone.md
1025
1087
  * plan §3 — copy paths must not let one rejected candidate abort the
1026
- * batch). Absent when 0 or when auto-share did not run. Same
1027
- * per-invocation-activity class as `secretSkipped` (sibling counter,
1028
- * same autoShare call) — NOT redacted on egress, see sleep-redact.ts.
1088
+ * batch). Absent when 0 or when auto-share did not run.
1029
1089
  */
1030
1090
  rejectedSkipped?: number;
1031
1091
  ambient?: AmbientState | null;
1032
1092
  /**
1033
1093
  * E3 sleep enqueue-hook: graph re-extraction totals across the tenants rebuilt
1034
1094
  * this sleep. Absent when no tenant was dirty, and under dryRun (the graph
1035
- * phase runs only on a real sleep). Cross-tenant aggregate — zeroed on
1036
- * non-loopback non-self egress by sleep-redact.ts.
1095
+ * phase runs only on a real sleep). Cross-tenant aggregate, one reason
1096
+ * /v1/sleep stays loopback-only.
1037
1097
  */
1038
1098
  graph?: {
1039
1099
  tenants: number;
@@ -1054,10 +1114,9 @@ export interface SleepResult {
1054
1114
  * serving lands — at that point the route will need an admin-role gate OR
1055
1115
  * api.sleep itself will need to scope dedup / audit / delete by ctx.tenantId.
1056
1116
  *
1057
- * Audit emission gap: the consolidation phases (dedup, audit-delete) do
1058
- * NOT emit audit_log rows today, matching pre-refactor cmdSleepCore. Same
1059
- * CLI/MCP parity gap that T6 fixed for cmdOutcome, now visible at the api
1060
- * surface. Tracked in TODOS.md "Episode A follow-ups" for a future minor.
1117
+ * Dedup and audit deletes each log a `forget` row with the ctx actor and a
1118
+ * `metadata.reason`. Pinned and raw rows are never auto-deleted (canAutoDelete).
1119
+ * dryRun previews consolidate, dedup and audit, then returns before share/ambient.
1061
1120
  */
1062
1121
  /**
1063
1122
  * v1.12.2: Test-only DI seam shape for `sleep`'s phase dependencies.