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
@@ -10,17 +10,18 @@
10
10
  import * as fs from 'fs';
11
11
  import * as path from 'path';
12
12
  import { createMemory, Layer, calculateStrength, } from '../memory.js';
13
- import { hybridSearch, physicsSearch, markRetrieved } from '../search.js';
14
- import { isRecallBoostAblated, evalNow } from '../ablation.js';
15
- import { loadAllEntries, writeEntry, readEntry, loadFreshActiveTaskSnapshot, listMemoryConflicts, resolveConflict, RECALL_DEFAULT_DENY_SCOPES } from '../store.js';
16
- import { shareMemory, listPeers, getGlobalRoot } from '../shared.js';
13
+ import { hybridSearch, physicsSearch, estimateTokens } from '../search.js';
14
+ import { evalNow } from '../ablation.js';
15
+ import { loadAllEntries, writeEntry, strengthenRetrieved, readEntry, loadFreshActiveTaskSnapshot, listMemoryConflicts, resolveConflict, RECALL_DEFAULT_DENY_SCOPES, countCreatedSinceLastSleep } from '../store.js';
16
+ import { shareMemory, listPeers, getGlobalRoot, initGlobal } from '../shared.js';
17
17
  import { consolidate } from '../consolidate.js';
18
18
  import { execSync } from 'child_process';
19
19
  import { fetchGitLog, extractLessons, partitionLessons, deduplicateLesson, isGitRepo } from '../autolearn.js';
20
20
  import { loadConfig } from '../config.js';
21
21
  import { confidenceLabel } from '../memory.js';
22
22
  import { resolveTenantId } from '../tenant.js';
23
- import { recall as apiRecall, remember as apiRemember, outcome as apiOutcome, drillDown as apiDrillDown, assemble as apiAssemble, isPrivateScope, passesScopeFilterForRecall, adminActor, buildSuppressionSummary, ambientSecretAdmit } from '../api.js';
23
+ import { recall as apiRecall, remember as apiRemember, outcome as apiOutcome, drillDown as apiDrillDown, assemble as apiAssemble, isPrivateScope, passesScopeFilterForRecall, buildSuppressionSummary, ambientSecretAdmit } from '../api.js';
24
+ import { assertScopeRequestAllowed } from '../recall-scope.js';
24
25
  import { resolveProjectIdentity, classifyOriginProject, findHippoStoreDir } from '../project-identity.js';
25
26
  import { computePredictionBaserate } from '../predictions.js';
26
27
  import { appendAuditEvent } from '../audit.js';
@@ -38,6 +39,7 @@ export function __resetSessionRecallHistoryMcp() {
38
39
  }
39
40
  import { applyGoalStackBoost } from '../goals.js';
40
41
  import { openHippoDb, closeHippoDb } from '../db.js';
42
+ import { recordTokenUse } from '../token-ledger.js';
41
43
  import { PACKAGE_VERSION } from '../version.js';
42
44
  // ── Find hippo root ──
43
45
  /** Same bounded walk as the CLI (ends at home, so HIPPO_HOME wins over ~/.hippo); cwd/opts are the test seam. */
@@ -49,6 +51,14 @@ export function findHippoRoot(cwd = process.cwd(), opts) {
49
51
  const global = getGlobalRoot();
50
52
  return fs.existsSync(global) ? global : null;
51
53
  }
54
+ /**
55
+ * The api-layer actor for a tool call. Stdio (no ctx) is the local operator
56
+ * and runs as admin; over HTTP the transport's authenticated role is used, so
57
+ * a member key never acts as admin through MCP.
58
+ */
59
+ function mcpActor(ctx) {
60
+ return { subject: ctx?.actor ?? 'mcp', role: ctx?.role ?? 'admin' };
61
+ }
52
62
  // MCP stdio transport spec: messages are newline-delimited JSON-RPC, no embedded newlines.
53
63
  // https://modelcontextprotocol.io/specification/.../basic/transports#stdio
54
64
  function send(msg) {
@@ -136,7 +146,7 @@ const TOOLS = [
136
146
  type: 'object',
137
147
  properties: {
138
148
  query: { type: 'string', description: 'What to search for in memory (natural language)' },
139
- budget: { type: 'number', description: 'Max tokens to return (default: 1500)' },
149
+ budget: { type: 'number', description: 'Max tokens to return (default: config.defaultBudget, 4000)' },
140
150
  include_continuity: {
141
151
  type: 'boolean',
142
152
  description: 'Append continuity context (active snapshot + handoff + last 5 session events) below the memory results. Useful at session boot.',
@@ -265,7 +275,7 @@ const TOOLS = [
265
275
  inputSchema: {
266
276
  type: 'object',
267
277
  properties: {
268
- budget: { type: 'number', minimum: 0, description: 'Max tokens (default: 1500)' },
278
+ budget: { type: 'number', minimum: 0, description: 'Max tokens (default: config.defaultContextBudget, 3000)' },
269
279
  scope: {
270
280
  type: 'string',
271
281
  description: 'Restrict memories and snapshot to this scope exactly. When omitted, default-deny applies to ANY <source>:private:* (slack, github, ...) and unknown-legacy rows.',
@@ -359,6 +369,7 @@ const TOOLS = [
359
369
  // `${tenantId}:default` if a McpContext is constructed in tests without a
360
370
  // pid-bound transport.
361
371
  const lastRecalledIds = new Map();
372
+ const autoSleepInFlight = new Set();
362
373
  function resolveClientKey(ctx) {
363
374
  if (ctx?.clientKey)
364
375
  return ctx.clientKey;
@@ -366,6 +377,53 @@ function resolveClientKey(ctx) {
366
377
  return `stdio-${process.pid}:${ctx.tenantId}`;
367
378
  return `stdio-${process.pid}:default`;
368
379
  }
380
+ /**
381
+ * Zero-install first run (`npx -y hippo-memory mcp` with no store anywhere):
382
+ * create the global store instead of failing every tool call, and say so on
383
+ * stderr (stdout carries the protocol). `hippo init` in a project later adds
384
+ * a project store, which then takes precedence.
385
+ */
386
+ function createGlobalStoreOnFirstRun() {
387
+ initGlobal();
388
+ const root = getGlobalRoot();
389
+ console.error(`hippo: no memory store found; created the global store at ${root}. Run \`hippo init\` in a project for a project store.`);
390
+ return root;
391
+ }
392
+ // ── Token ledger (ROADMAP TE0) ──
393
+ const MCP_TOKEN_SURFACES = new Map([
394
+ ['hippo_recall', 'mcp_recall'],
395
+ ['hippo_context', 'mcp_context'],
396
+ ]);
397
+ /**
398
+ * Record the memory text a recall or context tool returned. Best-effort: a
399
+ * ledger failure never fails the tool call. Other tools are not recorded.
400
+ */
401
+ function recordMcpTokens(toolName, output, ctx) {
402
+ const surface = MCP_TOKEN_SURFACES.get(toolName);
403
+ if (!surface || !output)
404
+ return;
405
+ try {
406
+ const hippoRoot = ctx?.hippoRoot ?? findHippoRoot();
407
+ if (!hippoRoot)
408
+ return;
409
+ const db = openHippoDb(hippoRoot);
410
+ try {
411
+ recordTokenUse(db, {
412
+ tenantId: ctx?.tenantId ?? resolveTenantId({}),
413
+ surface,
414
+ event: 'inject',
415
+ items: 0,
416
+ tokens: estimateTokens(output),
417
+ });
418
+ }
419
+ finally {
420
+ closeHippoDb(db);
421
+ }
422
+ }
423
+ catch {
424
+ // Ledger is best-effort.
425
+ }
426
+ }
369
427
  // ── Tool execution ──
370
428
  async function executeTool(name, args, ctx) {
371
429
  // When a transport hands us a context (HTTP path), trust it: the HTTP
@@ -373,9 +431,7 @@ async function executeTool(name, args, ctx) {
373
431
  // from the Bearer token (or the loopback fallback). The stdio path
374
432
  // continues to walk from cwd / fall back to the global root, and to
375
433
  // resolve tenant from HIPPO_TENANT.
376
- const hippoRoot = ctx?.hippoRoot ?? findHippoRoot();
377
- if (!hippoRoot)
378
- return 'No .hippo/ store found. Run: hippo init';
434
+ const hippoRoot = ctx?.hippoRoot ?? findHippoRoot() ?? createGlobalStoreOnFirstRun();
379
435
  const config = loadConfig(hippoRoot);
380
436
  // A5: every loadAllEntries() in this server returns to the caller and is
381
437
  // tenant-isolated. Resolved once per tool call: prefer the transport's
@@ -422,7 +478,7 @@ async function executeTool(name, args, ctx) {
422
478
  const apiCtx = {
423
479
  hippoRoot,
424
480
  tenantId,
425
- actor: adminActor(ctx?.actor ?? 'mcp'),
481
+ actor: mcpActor(ctx),
426
482
  };
427
483
  // Route through api.recall for audit + (when requested) continuity block.
428
484
  // api.recall already applies the same default-deny / exact-match rules
@@ -527,15 +583,9 @@ async function executeTool(name, args, ctx) {
527
583
  closeHippoDb(dbForBoost);
528
584
  }
529
585
  }
530
- // Mark retrieved and persist
531
- const retrieved = markRetrieved(results.map((r) => r.entry));
532
- // EVAL-ONLY ablation (see ablation.ts): skip persistence under the recall
533
- // flag; ids below stay populated for outcome attribution.
534
- if (!isRecallBoostAblated()) {
535
- for (const entry of retrieved)
536
- writeEntry(hippoRoot, entry, { actor: ctx?.actor ?? 'mcp' });
537
- }
538
- lastRecalledIds.set(resolveClientKey(ctx), retrieved.map((e) => e.id));
586
+ const retrievedIds = results.map((r) => r.entry.id);
587
+ strengthenRetrieved(hippoRoot, retrievedIds);
588
+ lastRecalledIds.set(resolveClientKey(ctx), retrievedIds);
539
589
  // v0.33 / J1 — MCP per-pipeline anchoring detector. UNLIKE J3.2's
540
590
  // planningFallacyHint (which is pipeline-invariant because it
541
591
  // depends only on queryText + predictions table state), the
@@ -776,7 +826,7 @@ async function executeTool(name, args, ctx) {
776
826
  const apiCtx = {
777
827
  hippoRoot,
778
828
  tenantId,
779
- actor: adminActor(ctx?.actor ?? 'mcp'),
829
+ actor: mcpActor(ctx),
780
830
  };
781
831
  const explicitScope = isJsonString(args.scope) && args.scope.length > 0
782
832
  ? args.scope
@@ -820,7 +870,7 @@ async function executeTool(name, args, ctx) {
820
870
  const apiCtx = {
821
871
  hippoRoot,
822
872
  tenantId,
823
- actor: adminActor(ctx?.actor ?? 'mcp'),
873
+ actor: mcpActor(ctx),
824
874
  };
825
875
  const drillExtra = {};
826
876
  if (Number.isFinite(limit) && limit > 0)
@@ -895,29 +945,24 @@ async function executeTool(name, args, ctx) {
895
945
  const apiCtx = {
896
946
  hippoRoot,
897
947
  tenantId,
898
- actor: adminActor(ctx?.actor ?? 'mcp'),
948
+ actor: mcpActor(ctx),
899
949
  };
900
950
  const result = apiRemember(apiCtx, {
901
951
  content: text,
902
952
  tags,
903
953
  });
904
954
  const entry = readEntry(hippoRoot, result.id, tenantId);
905
- // Auto-sleep check
906
- if (config.autoSleep.enabled) {
907
- const allEntries = loadAllEntries(hippoRoot, tenantId);
908
- const recentCount = allEntries.filter((e) => {
909
- const age = (Date.now() - new Date(e.created).getTime()) / (1000 * 60 * 60);
910
- return age < 24; // created in last 24 hours
911
- }).length;
912
- if (recentCount >= config.autoSleep.threshold) {
913
- // Fire-and-forget by design (never block the remember response), but
914
- // an unhandled rejection here can kill the MCP server process — any
915
- // consolidate error (DB contention, or the memoryValue fail-loud
916
- // throw) must land as a logged line, not a crash.
917
- consolidate(hippoRoot).catch((err) => {
918
- console.error(`auto-sleep consolidate failed: ${err instanceof Error ? err.message : err}`);
919
- });
920
- }
955
+ // Auto-sleep: one run per store at a time, triggered by what arrived since the last one.
956
+ if (config.autoSleep.enabled &&
957
+ !autoSleepInFlight.has(hippoRoot) &&
958
+ countCreatedSinceLastSleep(hippoRoot, tenantId) >= config.autoSleep.threshold) {
959
+ autoSleepInFlight.add(hippoRoot);
960
+ // Fire-and-forget (never block the response); an unhandled rejection would kill the server, so log it.
961
+ consolidate(hippoRoot)
962
+ .catch((err) => {
963
+ console.error(`auto-sleep consolidate failed (tenant ${tenantId}): ${err instanceof Error ? err.message : err}`);
964
+ })
965
+ .finally(() => autoSleepInFlight.delete(hippoRoot));
921
966
  }
922
967
  const halfLife = entry?.half_life_days ?? config.defaultHalfLifeDays;
923
968
  const tagStr = entry?.tags.join(', ') || tags.join(', ') || 'none';
@@ -936,7 +981,7 @@ async function executeTool(name, args, ctx) {
936
981
  const apiCtx = {
937
982
  hippoRoot,
938
983
  tenantId,
939
- actor: adminActor(ctx?.actor ?? 'mcp'),
984
+ actor: mcpActor(ctx),
940
985
  };
941
986
  const { applied } = apiOutcome(apiCtx, ids, good);
942
987
  return `Applied ${good ? 'positive' : 'negative'} outcome to ${applied} memories`;
@@ -967,6 +1012,7 @@ async function executeTool(name, args, ctx) {
967
1012
  // results and the snapshot. Pre-v1.2 this surface returned all memories
968
1013
  // and the snapshot unfiltered, which would have leaked private-channel
969
1014
  // content to no-scope MCP callers once scope writers shipped.
1015
+ assertScopeRequestAllowed(mcpActor(ctx).role, explicitScope);
970
1016
  const allEntries = loadAllEntries(hippoRoot, tenantId);
971
1017
  // v39 memory scope isolation: this surface reads the LOCAL store only,
972
1018
  // but synced-down or legacy rows can still carry another project's
@@ -1000,14 +1046,9 @@ async function executeTool(name, args, ctx) {
1000
1046
  const results = usePhysicsCtx
1001
1047
  ? await physicsSearch(query, entries, { budget, hippoRoot, physicsConfig: config.physics })
1002
1048
  : await hybridSearch(query, entries, { budget, hippoRoot });
1003
- const retrieved = markRetrieved(results.map((r) => r.entry));
1004
- // EVAL-ONLY ablation (see ablation.ts): skip persistence under the recall
1005
- // flag; ids below stay populated for outcome attribution.
1006
- if (!isRecallBoostAblated()) {
1007
- for (const entry of retrieved)
1008
- writeEntry(hippoRoot, entry, { actor: ctx?.actor ?? 'mcp' });
1009
- }
1010
- lastRecalledIds.set(resolveClientKey(ctx), retrieved.map((e) => e.id));
1049
+ const retrievedIds = results.map((r) => r.entry.id);
1050
+ strengthenRetrieved(hippoRoot, retrievedIds);
1051
+ lastRecalledIds.set(resolveClientKey(ctx), retrievedIds);
1011
1052
  // DF1 (docs/plans/2026-08-23-df1-snapshot-lifecycle.md, T2): bounded
1012
1053
  // read, no session id available on this surface (freshness bound
1013
1054
  // only) — an orphaned snapshot must age out here too, not just on the
@@ -1199,6 +1240,7 @@ export async function handleMcpRequest(req, ctx) {
1199
1240
  const argumentsValue = params?.arguments;
1200
1241
  const toolArgs = isJsonObjectRecord(argumentsValue) ? argumentsValue : {};
1201
1242
  const output = await executeTool(toolName, toolArgs, ctx);
1243
+ recordMcpTokens(toolName, output, ctx);
1202
1244
  return {
1203
1245
  jsonrpc: '2.0',
1204
1246
  id,
package/dist/memory.d.ts CHANGED
@@ -141,6 +141,12 @@ export declare function _resetLossAversionRatioCacheForTests(): void;
141
141
  * decay slower; consistent negative outcomes decay faster.
142
142
  */
143
143
  export declare function calculateRewardFactor(entry: MemoryEntry): number;
144
+ /**
145
+ * Net wrongness: bad outcome marks past good ones, never below zero.
146
+ * Strength halves per unit (capped at 3) and recall stops strengthening
147
+ * the memory, so a correction outranks pinning, error tags and heavy recall.
148
+ */
149
+ export declare function netWrong(entry: MemoryEntry): number;
144
150
  /**
145
151
  * Options for decay basis.
146
152
  * - clock: wall-clock time (default pre-v0.15)
@@ -163,7 +169,7 @@ export interface DecayOptions {
163
169
  * - session: decay by sleep cycles instead of days (sessionsSince / halfLife)
164
170
  * - adaptive: wall-clock decay with half-life scaled by session frequency
165
171
  *
166
- * Pinned memories always return 1.0 (no decay).
172
+ * Pinned memories skip time decay; being marked wrong still fades them (netWrong).
167
173
  */
168
174
  export declare function calculateStrength(entry: MemoryEntry, now?: Date, options?: DecayOptions): number;
169
175
  /**
@@ -203,6 +209,17 @@ export declare function confidenceLabel(entry: MemoryEntry, now?: Date): {
203
209
  * returns 'stale'. Otherwise returns the stored confidence value.
204
210
  */
205
211
  export declare function resolveConfidence(entry: MemoryEntry, now?: Date): ConfidenceLevel;
212
+ /**
213
+ * Base half-life for a new memory, in days, before `deriveHalfLife`'s
214
+ * write-time multipliers. 365 since 1.46.0: the pre-registered E1 decision
215
+ * (docs/evals/2026-09-24-decay-default-result.md and prereg-2) found 7 days
216
+ * lost the current fact far more often (29% vs 75% in the top five), and
217
+ * 730 days and decay off tied with 365. `hippo sleep` moves memories still
218
+ * on an older base (src/half-life-migration.ts).
219
+ */
220
+ export declare const DEFAULT_HALF_LIFE_DAYS = 365;
221
+ export declare const AUTO_DELETABLE_SQL = "pinned = 0 AND kind != 'raw'";
222
+ export declare function canAutoDelete(entry: Pick<MemoryEntry, 'pinned' | 'kind'>): boolean;
206
223
  /**
207
224
  * Create a new memory entry with defaults.
208
225
  */
package/dist/memory.js CHANGED
@@ -143,6 +143,18 @@ export function calculateRewardFactor(entry) {
143
143
  const ratio = (pos - neg) / (pos + neg + 1);
144
144
  return 1 + 0.5 * ratio;
145
145
  }
146
+ /** Bad marks alone never push a memory under sleep's 0.05 retire line; supersede is the hard correction. */
147
+ const MAX_WRONG_HALVINGS = 3;
148
+ /**
149
+ * Net wrongness: bad outcome marks past good ones, never below zero.
150
+ * Strength halves per unit (capped at 3) and recall stops strengthening
151
+ * the memory, so a correction outranks pinning, error tags and heavy recall.
152
+ */
153
+ export function netWrong(entry) {
154
+ if (isOutcomeSlowAblated() || isDecayAblated())
155
+ return 0;
156
+ return Math.max(0, (entry.outcome_negative ?? 0) - (entry.outcome_positive ?? 0));
157
+ }
146
158
  /**
147
159
  * Calculate current strength at a given time.
148
160
  * strength(t) = base_strength * decay * retrieval_boost * emotional_multiplier
@@ -152,14 +164,16 @@ export function calculateRewardFactor(entry) {
152
164
  * - session: decay by sleep cycles instead of days (sessionsSince / halfLife)
153
165
  * - adaptive: wall-clock decay with half-life scaled by session frequency
154
166
  *
155
- * Pinned memories always return 1.0 (no decay).
167
+ * Pinned memories skip time decay; being marked wrong still fades them (netWrong).
156
168
  */
157
169
  export function calculateStrength(entry,
158
170
  // evalNow(): the real clock unless HIPPO_FAKE_NOW is set (eval-only,
159
171
  // simulated-time protocols; see ablation.ts). Explicit `now` always wins.
160
172
  now = evalNow(), options = {}) {
173
+ // Being marked wrong outranks every shield: pinning, error tags, heavy recall.
174
+ const wrongPenalty = Math.pow(0.5, Math.min(netWrong(entry), MAX_WRONG_HALVINGS));
161
175
  if (entry.pinned)
162
- return 1.0;
176
+ return wrongPenalty;
163
177
  // EVAL-ONLY ablation (see ablation.ts): with recall-strengthening ablated,
164
178
  // anchor decay at CREATION, not last_retrieved. A never-strengthened memory
165
179
  // decays from when it was made; using last_retrieved would let clock resets
@@ -205,7 +219,7 @@ now = evalNow(), options = {}) {
205
219
  // the READ side too, so a store with PRIOR retrieval history (counts > 0
206
220
  // written before the flag was set) does not leak strengthening into an
207
221
  // ablated arm's rankings (codex P2).
208
- const retrievalBoost = isRecallBoostAblated()
222
+ const retrievalBoost = isRecallBoostAblated() || netWrong(entry) > 0
209
223
  ? 1.0
210
224
  : 1 + 0.1 * Math.log2(entry.retrieval_count + 1);
211
225
  // Emotional multiplier
@@ -218,7 +232,7 @@ now = evalNow(), options = {}) {
218
232
  const raw = decay * retrievalBoost * emotionalMultiplier;
219
233
  // Clamp to [0, 1] with NaN guard
220
234
  const clamped = Math.min(1.0, Math.max(0.0, raw));
221
- return Number.isFinite(clamped) ? clamped : 0.0;
235
+ return Number.isFinite(clamped) ? clamped * wrongPenalty : 0.0;
222
236
  }
223
237
  /**
224
238
  * Derive half-life based on signals, as per PLAN.md table.
@@ -296,6 +310,20 @@ export function confidenceLabel(entry, now = evalNow()) {
296
310
  export function resolveConfidence(entry, now = evalNow()) {
297
311
  return isAgedOut(entry, now) ? 'stale' : entry.confidence;
298
312
  }
313
+ /**
314
+ * Base half-life for a new memory, in days, before `deriveHalfLife`'s
315
+ * write-time multipliers. 365 since 1.46.0: the pre-registered E1 decision
316
+ * (docs/evals/2026-09-24-decay-default-result.md and prereg-2) found 7 days
317
+ * lost the current fact far more often (29% vs 75% in the top five), and
318
+ * 730 days and decay off tied with 365. `hippo sleep` moves memories still
319
+ * on an older base (src/half-life-migration.ts).
320
+ */
321
+ export const DEFAULT_HALF_LIFE_DAYS = 365;
322
+ // Pinned means keep; raw rows leave only through archiveRawMemory. The SQL twin guards the DELETE itself.
323
+ export const AUTO_DELETABLE_SQL = "pinned = 0 AND kind != 'raw'";
324
+ export function canAutoDelete(entry) {
325
+ return !entry.pinned && entry.kind !== 'raw';
326
+ }
299
327
  /**
300
328
  * Create a new memory entry with defaults.
301
329
  */
@@ -314,7 +342,7 @@ export function createMemory(content, options = {}) {
314
342
  const emotional_valence = options.emotional_valence ?? inferValence(tags);
315
343
  const schema_fit = options.schema_fit ?? 0.5;
316
344
  const partial = { tags, schema_fit };
317
- const half_life_days = deriveHalfLife(options.baseHalfLifeDays ?? 7, partial);
345
+ const half_life_days = deriveHalfLife(options.baseHalfLifeDays ?? DEFAULT_HALF_LIFE_DAYS, partial);
318
346
  const entry = {
319
347
  id: generateId(layer === Layer.Semantic ? 'sem' : 'mem'),
320
348
  created: now,
@@ -3,7 +3,11 @@
3
3
  * All constants are tunable; defaults calibrated for ~500 memory corpus.
4
4
  */
5
5
  export const DEFAULT_PHYSICS_CONFIG = {
6
- enabled: 'auto',
6
+ // Off by default: the paired ablation (benchmarks/physics-ablation/) found
7
+ // physics worse than classic hybrid on every metric, CI excluding zero
8
+ // (MRR 0.68 vs 0.84, R@5 74% vs 84%). Opt in with physics.enabled 'auto'
9
+ // or true.
10
+ enabled: false,
7
11
  G_query: 2.0,
8
12
  G_memory: 0.01,
9
13
  K_repulsion: 0.5,
@@ -57,4 +57,28 @@ export declare function passesScopeFilterForRecall(scope: string | null, request
57
57
  * denied.
58
58
  */
59
59
  export declare function passesCliRecallScopeFilter(scope: string | null, requested: string | undefined): boolean;
60
+ /**
61
+ * Thrown when a caller requests a scope its role may not read. The HTTP layer
62
+ * maps it to 403.
63
+ */
64
+ export declare class ScopeForbiddenError extends Error {
65
+ readonly scope: string;
66
+ constructor(scope: string);
67
+ }
68
+ /**
69
+ * True for scopes that default-deny hides: `<source>:private:*` and the
70
+ * quarantine buckets. Naming one explicitly is what unlocks it, so naming one
71
+ * is the act that needs authorization.
72
+ */
73
+ export declare function isRestrictedScope(scope: string | null | undefined): boolean;
74
+ /**
75
+ * Authorize an explicitly requested scope before any read honours it.
76
+ *
77
+ * An admin (tenant owner, the local CLI, loopback without a key) may unlock
78
+ * any scope in its tenant. A member key may not unlock a restricted scope by
79
+ * naming it: before this check, any key in a tenant could read every private
80
+ * channel or repo by passing its scope string. Per-scope grants for member
81
+ * keys belong to ROADMAP Part VIII EI2 (permission-aware recall).
82
+ */
83
+ export declare function assertScopeRequestAllowed(role: 'admin' | 'member', requested: string | undefined): void;
60
84
  //# sourceMappingURL=recall-scope.d.ts.map
@@ -86,4 +86,45 @@ export function passesCliRecallScopeFilter(scope, requested) {
86
86
  }
87
87
  return passesScopeFilterForRecall(scope, undefined);
88
88
  }
89
+ /**
90
+ * Thrown when a caller requests a scope its role may not read. The HTTP layer
91
+ * maps it to 403.
92
+ */
93
+ export class ScopeForbiddenError extends Error {
94
+ scope;
95
+ constructor(scope) {
96
+ super(`scope ${scope} requires admin role`);
97
+ this.name = 'ScopeForbiddenError';
98
+ this.scope = scope;
99
+ }
100
+ }
101
+ /**
102
+ * True for scopes that default-deny hides: `<source>:private:*` and the
103
+ * quarantine buckets. Naming one explicitly is what unlocks it, so naming one
104
+ * is the act that needs authorization.
105
+ */
106
+ export function isRestrictedScope(scope) {
107
+ if (!isScopeString(scope))
108
+ return false;
109
+ // SAFETY: RECALL_DEFAULT_DENY_SCOPES is a readonly tuple of string
110
+ // literals; widening the array (not the input) lets .includes() take any scope.
111
+ return isPrivateScope(scope) || RECALL_DEFAULT_DENY_SCOPES.includes(scope);
112
+ }
113
+ /**
114
+ * Authorize an explicitly requested scope before any read honours it.
115
+ *
116
+ * An admin (tenant owner, the local CLI, loopback without a key) may unlock
117
+ * any scope in its tenant. A member key may not unlock a restricted scope by
118
+ * naming it: before this check, any key in a tenant could read every private
119
+ * channel or repo by passing its scope string. Per-scope grants for member
120
+ * keys belong to ROADMAP Part VIII EI2 (permission-aware recall).
121
+ */
122
+ export function assertScopeRequestAllowed(role, requested) {
123
+ if (requested === undefined || requested === '')
124
+ return;
125
+ if (role === 'admin')
126
+ return;
127
+ if (isRestrictedScope(requested))
128
+ throw new ScopeForbiddenError(requested);
129
+ }
89
130
  //# sourceMappingURL=recall-scope.js.map
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { Layer } from './memory.js';
16
16
  import { loadAllEntries, readEntry, writeEntry } from './store.js';
17
+ import { redactSecrets } from './secret-detect.js';
17
18
  const REFINED_TAG = 'llm-refined';
18
19
  const CONSOLIDATED_MARKERS = [
19
20
  '[Consolidated from',
@@ -29,7 +30,7 @@ export async function refineSemanticMemory(merged, sources, opts) {
29
30
  const fetchFn = opts.fetcher ?? fetch;
30
31
  const sourceBlock = sources
31
32
  .slice(0, 8)
32
- .map((s, i) => `[source ${i + 1}] ${s.content.slice(0, 400)}`)
33
+ .map((s, i) => `[source ${i + 1}] ${redactSecrets(s.content).slice(0, 400)}`)
33
34
  .join('\n\n');
34
35
  const prompt = `You are refining a semantic memory in an agent's memory store. The rule-based consolidator merged several related episodic memories into one, but the output is clumsy. Produce a single coherent semantic memory that captures the underlying principle.
35
36
 
@@ -41,7 +42,7 @@ Rules:
41
42
  - Do NOT include the "[Consolidated from N ...]" marker.
42
43
 
43
44
  Current merged content:
44
- ${merged}
45
+ ${redactSecrets(merged)}
45
46
 
46
47
  Source memories (up to 8 shown):
47
48
  ${sourceBlock}`;
@@ -7,9 +7,9 @@
7
7
  * SAME multi-step transaction + post-commit mirror-purge flow. Extracted
8
8
  * here (leaf module) so neither duplicates it.
9
9
  *
10
- * Module direction: this file imports from store.ts, rejection.ts, and
11
- * raw-archive.ts. Nothing imports FROM this file except cli.ts and api.ts,
12
- * so it introduces no cycle.
10
+ * Module direction: this file imports from store.ts, rejection.ts,
11
+ * raw-archive.ts and dormant.ts. Nothing imports FROM this file except
12
+ * cli.ts and api.ts, so it introduces no cycle.
13
13
  */
14
14
  import { type RejectedValueRow } from './rejection.js';
15
15
  export interface RejectFlowOpts {
@@ -7,13 +7,14 @@
7
7
  * SAME multi-step transaction + post-commit mirror-purge flow. Extracted
8
8
  * here (leaf module) so neither duplicates it.
9
9
  *
10
- * Module direction: this file imports from store.ts, rejection.ts, and
11
- * raw-archive.ts. Nothing imports FROM this file except cli.ts and api.ts,
12
- * so it introduces no cycle.
10
+ * Module direction: this file imports from store.ts, rejection.ts,
11
+ * raw-archive.ts and dormant.ts. Nothing imports FROM this file except
12
+ * cli.ts and api.ts, so it introduces no cycle.
13
13
  */
14
14
  import { openHippoDb, closeHippoDb } from './db.js';
15
15
  import { appendAuditEvent } from './audit.js';
16
16
  import { archiveRawMemory } from './raw-archive.js';
17
+ import { purgeDormantByDigest } from './dormant.js';
17
18
  import { initStore, deleteEntryCore, purgeMirrorBestEffort, writeIndexMirror, buildIndexFromDb, } from './store.js';
18
19
  import { rejectionDigest, normalizeValueForRejection, insertRejectedValue, deleteRejectedValue, listRejectedValues, } from './rejection.js';
19
20
  /**
@@ -102,6 +103,12 @@ export function rejectValue(opts) {
102
103
  }
103
104
  removedIds.push(row.id);
104
105
  }
106
+ // Dormant copies (src/dormant.ts) go too, in the same transaction: a
107
+ // rejected value may not linger where `hippo dormant restore` could
108
+ // bring it back. They have no markdown mirror, so the post-commit
109
+ // mirror purge below is a no-op for them; they join removedIds for the
110
+ // audit trail and the caller's report.
111
+ removedIds.push(...purgeDormantByDigest(db, opts.tenantId, digest));
105
112
  try {
106
113
  appendAuditEvent(db, {
107
114
  tenantId: opts.tenantId,
@@ -1,4 +1,5 @@
1
1
  import { crossEncoderReranker } from './cross-encoder.js';
2
+ import { redactSecrets } from '../secret-detect.js';
2
3
  const ENDPOINT = 'https://api.typesafe.ai/v1/systemone';
3
4
  const DEFAULT_TIMEOUT_MS = 5_000;
4
5
  const TRUNCATE_CHARS = 1200;
@@ -32,8 +33,8 @@ async function requestScores(query, head) {
32
33
  const key = process.env.TYPESAFE_API_KEY;
33
34
  if (!key)
34
35
  throw new Error('TYPESAFE_API_KEY not set');
35
- const lines = head.map((r, i) => `[${i + 1}] ${truncate(r.entry.content, TRUNCATE_CHARS)}`);
36
- const state = `Query: ${query}\n\nNumbered candidate memories from an AI coding agent's project store:\n\n${lines.join('\n\n')}`;
36
+ const lines = head.map((r, i) => `[${i + 1}] ${truncate(redactSecrets(r.entry.content), TRUNCATE_CHARS)}`);
37
+ const state = `Query: ${redactSecrets(query)}\n\nNumbered candidate memories from an AI coding agent's project store:\n\n${lines.join('\n\n')}`;
37
38
  const questions = {};
38
39
  for (let i = 1; i <= head.length; i++) {
39
40
  questions[`c${i}`] = {
@@ -1,3 +1,4 @@
1
+ import { redactSecrets } from '../secret-detect.js';
1
2
  const DEFAULT_TIMEOUT_MS = 30_000;
2
3
  /**
3
4
  * Track 3 reranker: listwise LLM rerank. Uses a customer-supplied
@@ -21,8 +22,8 @@ export const llmReranker = async (query, results, options) => {
21
22
  const head = results.slice(0, topK);
22
23
  const prompt = [
23
24
  `Rerank the candidates below by relevance to the query. Output a JSON array of indices (zero-indexed) in best-first order.`,
24
- `Query: ${query}`,
25
- ...head.map((r, i) => `[${i}] ${r.entry.content}`),
25
+ `Query: ${redactSecrets(query)}`,
26
+ ...head.map((r, i) => `[${i}] ${redactSecrets(r.entry.content)}`),
26
27
  `Output format: [<int>, <int>, ...] with all ${head.length} indices.`,
27
28
  ].join('\n');
28
29
  const timeoutMs = Number.parseInt(process.env.HIPPO_LLM_RERANKER_TIMEOUT_MS ?? '', 10) || DEFAULT_TIMEOUT_MS;
package/dist/search.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  * BM25 search + optional embedding hybrid search for Hippo.
3
3
  * Zero external dependencies when embeddings are not available.
4
4
  */
5
+ import { estimateTokens } from './token-ledger.js';
5
6
  import { MemoryEntry } from './memory.js';
6
7
  import type { PhysicsConfig } from './physics-config.js';
7
8
  export declare function tokenize(text: string): string[];
@@ -17,10 +18,9 @@ export interface BM25Corpus {
17
18
  N: number;
18
19
  }
19
20
  export declare function buildCorpus(texts: string[]): BM25Corpus;
20
- /**
21
- * Rough token estimate: characters / 4 (works well for English text).
22
- */
23
- export declare function estimateTokens(text: string): number;
21
+ export { estimateTokens };
22
+ /** Retrieval-time outcome nudge in [0.85, 1.15]; the E1 bm25-outcome baseline ranks with it too. */
23
+ export declare function outcomeMultiplier(entry: MemoryEntry): number;
24
24
  export declare function detectTemporalDirection(query: string): 'recent' | 'oldest' | null;
25
25
  export interface TemporalRange {
26
26
  minTime: number;