hippo-memory 1.61.0 → 1.63.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 (377) hide show
  1. package/README.md +37 -53
  2. package/dist/agent-memories/apply.d.ts +3 -1
  3. package/dist/agent-memories/apply.js +23 -1
  4. package/dist/agent-memories/claude-code.d.ts +4 -1
  5. package/dist/agent-memories/claude-code.js +53 -9
  6. package/dist/agent-memories/report.d.ts +1 -0
  7. package/dist/agent-memories/report.js +2 -2
  8. package/dist/agent-memories/sync.d.ts +3 -3
  9. package/dist/agent-memories/sync.js +46 -24
  10. package/dist/agent-memories/types.d.ts +0 -2
  11. package/dist/ambient-store.d.ts +4 -4
  12. package/dist/ambient-store.js +4 -3
  13. package/dist/api/assemble.d.ts +7 -10
  14. package/dist/api/assemble.js +62 -66
  15. package/dist/api/audit.d.ts +2 -2
  16. package/dist/api/audit.js +2 -2
  17. package/dist/api/auth.d.ts +6 -6
  18. package/dist/api/auth.js +5 -7
  19. package/dist/api/context-select.d.ts +50 -0
  20. package/dist/api/context-select.js +342 -0
  21. package/dist/api/context-types.d.ts +12 -17
  22. package/dist/api/context.d.ts +5 -4
  23. package/dist/api/context.js +208 -535
  24. package/dist/api/dormant.js +1 -1
  25. package/dist/api/drill-down.d.ts +4 -4
  26. package/dist/api/drill-down.js +56 -41
  27. package/dist/api/outcome.d.ts +8 -13
  28. package/dist/api/outcome.js +13 -17
  29. package/dist/api/promote.d.ts +5 -8
  30. package/dist/api/promote.js +55 -66
  31. package/dist/api/quarantine.js +3 -2
  32. package/dist/api/recall-types.d.ts +43 -55
  33. package/dist/api/recall.d.ts +3 -3
  34. package/dist/api/recall.js +310 -456
  35. package/dist/api/remember.d.ts +2 -2
  36. package/dist/api/sleep.d.ts +7 -35
  37. package/dist/api/sleep.js +206 -220
  38. package/dist/api/tokens.d.ts +2 -2
  39. package/dist/api/tokens.js +2 -2
  40. package/dist/api/types.d.ts +6 -10
  41. package/dist/api/types.js +2 -4
  42. package/dist/audit-prune.d.ts +4 -6
  43. package/dist/audit-prune.js +3 -5
  44. package/dist/audit.js +11 -33
  45. package/dist/auth.d.ts +8 -9
  46. package/dist/auth.js +5 -7
  47. package/dist/autolearn.d.ts +1 -1
  48. package/dist/autolearn.js +1 -1
  49. package/dist/availability.js +3 -5
  50. package/dist/capture/command.d.ts +5 -4
  51. package/dist/capture/command.js +8 -22
  52. package/dist/capture/compact.d.ts +2 -2
  53. package/dist/capture/compact.js +11 -15
  54. package/dist/capture/extract.js +37 -115
  55. package/dist/capture-error.d.ts +1 -1
  56. package/dist/capture-error.js +1 -1
  57. package/dist/churn-git.d.ts +1 -1
  58. package/dist/churn-git.js +1 -1
  59. package/dist/cli/audit.js +3 -4
  60. package/dist/cli/auth.js +3 -6
  61. package/dist/cli/briefs.js +324 -306
  62. package/dist/cli/context.js +44 -34
  63. package/dist/cli/continuity.js +283 -271
  64. package/dist/cli/curate.d.ts +1 -1
  65. package/dist/cli/curate.js +43 -58
  66. package/dist/cli/dag.js +5 -9
  67. package/dist/cli/decisions.js +334 -345
  68. package/dist/cli/explain.js +68 -61
  69. package/dist/cli/goals.js +1 -1
  70. package/dist/cli/init.js +1 -1
  71. package/dist/cli/maintenance.js +62 -51
  72. package/dist/cli/playbooks.js +391 -379
  73. package/dist/cli/projects.js +11 -6
  74. package/dist/cli/recall.js +30 -44
  75. package/dist/cli/remember.js +118 -87
  76. package/dist/cli/session-hooks.js +106 -115
  77. package/dist/cli/setup.d.ts +1 -1
  78. package/dist/cli/setup.js +267 -250
  79. package/dist/cli/shared.js +3 -3
  80. package/dist/cli/slack.js +1 -1
  81. package/dist/cli/sleep.js +27 -1
  82. package/dist/cli/status.d.ts +4 -4
  83. package/dist/cli/status.js +80 -76
  84. package/dist/cli/transfer.js +88 -107
  85. package/dist/cli/usage.js +9 -6
  86. package/dist/cli.d.ts +1 -1
  87. package/dist/cli.js +4 -9
  88. package/dist/compaction-record.d.ts +2 -2
  89. package/dist/compaction-record.js +89 -68
  90. package/dist/compare.d.ts +11 -16
  91. package/dist/compare.js +11 -16
  92. package/dist/config.d.ts +19 -18
  93. package/dist/config.js +90 -67
  94. package/dist/connectors/github/backfill.d.ts +2 -2
  95. package/dist/connectors/github/backfill.js +8 -15
  96. package/dist/connectors/github/cli-impl.js +3 -8
  97. package/dist/connectors/github/deletion.d.ts +5 -12
  98. package/dist/connectors/github/deletion.js +5 -12
  99. package/dist/connectors/github/dlq.d.ts +6 -9
  100. package/dist/connectors/github/dlq.js +2 -3
  101. package/dist/connectors/github/ingest.d.ts +5 -7
  102. package/dist/connectors/github/ingest.js +8 -12
  103. package/dist/connectors/github/octokit-client.d.ts +3 -5
  104. package/dist/connectors/github/octokit-client.js +5 -6
  105. package/dist/connectors/github/signature.d.ts +9 -39
  106. package/dist/connectors/github/signature.js +9 -39
  107. package/dist/connectors/github/tenant-routing.d.ts +1 -1
  108. package/dist/connectors/github/tenant-routing.js +1 -1
  109. package/dist/connectors/github/transform.js +2 -2
  110. package/dist/connectors/github/types.d.ts +2 -10
  111. package/dist/connectors/github/types.js +1 -3
  112. package/dist/connectors/slack/deletion.d.ts +3 -8
  113. package/dist/connectors/slack/deletion.js +3 -8
  114. package/dist/connectors/slack/dlq.d.ts +1 -1
  115. package/dist/connectors/slack/ingest.d.ts +1 -1
  116. package/dist/connectors/slack/ingest.js +7 -16
  117. package/dist/connectors/slack/signature.d.ts +1 -1
  118. package/dist/connectors/slack/tenant-routing.d.ts +3 -5
  119. package/dist/connectors/slack/tenant-routing.js +3 -5
  120. package/dist/connectors/slack/transform.d.ts +5 -6
  121. package/dist/connectors/slack/transform.js +5 -6
  122. package/dist/connectors/slack/types.d.ts +2 -6
  123. package/dist/connectors/slack/types.js +1 -3
  124. package/dist/connectors/slack/web-client.js +10 -3
  125. package/dist/connectors/slack/workspaces.d.ts +3 -5
  126. package/dist/connectors/slack/workspaces.js +3 -5
  127. package/dist/consolidate/conflicts.js +3 -14
  128. package/dist/consolidate/decay.js +9 -29
  129. package/dist/consolidate/llm-passes.js +4 -5
  130. package/dist/consolidate/merge.js +8 -23
  131. package/dist/consolidate/run.d.ts +1 -8
  132. package/dist/consolidate/run.js +3 -25
  133. package/dist/consolidate/sleep.js +5 -17
  134. package/dist/consolidate/traces.js +9 -21
  135. package/dist/customer-notes.d.ts +5 -7
  136. package/dist/customer-notes.js +82 -76
  137. package/dist/dag.d.ts +10 -21
  138. package/dist/dag.js +189 -203
  139. package/dist/db/continuity.js +2 -2
  140. package/dist/db/migrations/v14.js +1 -1
  141. package/dist/db/migrations/v15.js +1 -2
  142. package/dist/db/migrations/v16.js +3 -4
  143. package/dist/db/migrations/v17.js +2 -3
  144. package/dist/db/migrations/v19.js +1 -1
  145. package/dist/db/migrations/v20.js +1 -1
  146. package/dist/db/migrations/v21.js +2 -6
  147. package/dist/db/migrations/v22.js +2 -4
  148. package/dist/db/migrations/v23.js +1 -1
  149. package/dist/db/migrations/v24.js +4 -6
  150. package/dist/db/migrations/v25.js +2 -3
  151. package/dist/db/migrations/v26.js +3 -3
  152. package/dist/db/migrations/v27.js +2 -10
  153. package/dist/db/migrations/v28.js +5 -8
  154. package/dist/db/migrations/v29.js +3 -4
  155. package/dist/db/migrations/v30.js +2 -2
  156. package/dist/db/migrations/v31.js +1 -1
  157. package/dist/db/migrations/v32.js +1 -1
  158. package/dist/db/migrations/v33.js +3 -3
  159. package/dist/db/migrations/v34.js +1 -1
  160. package/dist/db/migrations/v35.js +3 -4
  161. package/dist/db/migrations/v36.js +3 -4
  162. package/dist/db/migrations/v37.js +5 -5
  163. package/dist/db/migrations/v38.js +7 -8
  164. package/dist/db/migrations/v39.js +1 -1
  165. package/dist/db/migrations/v40.js +4 -16
  166. package/dist/db/migrations/v41.js +3 -4
  167. package/dist/db/migrations/v42.js +3 -4
  168. package/dist/db/migrations/v45.js +1 -1
  169. package/dist/db/migrations/v46.js +1 -1
  170. package/dist/db/migrations/v47.js +1 -1
  171. package/dist/db/migrations/v48.js +1 -1
  172. package/dist/decisions.d.ts +2 -2
  173. package/dist/decisions.js +97 -80
  174. package/dist/dedupe.js +86 -61
  175. package/dist/delivery-recorder.js +154 -135
  176. package/dist/doctor.js +129 -110
  177. package/dist/dormant.js +1 -4
  178. package/dist/embedding-provider.d.ts +4 -8
  179. package/dist/embedding-provider.js +4 -8
  180. package/dist/embeddings.js +55 -47
  181. package/dist/env.d.ts +1 -1
  182. package/dist/env.js +12 -12
  183. package/dist/escape.d.ts +5 -0
  184. package/dist/escape.js +10 -0
  185. package/dist/eval-stats.d.ts +1 -2
  186. package/dist/eval-stats.js +1 -2
  187. package/dist/eval-suite.js +27 -21
  188. package/dist/extract.js +4 -9
  189. package/dist/failure-log.d.ts +3 -3
  190. package/dist/failure-log.js +1 -1
  191. package/dist/forward-claim-detector.d.ts +2 -4
  192. package/dist/forward-claim-detector.js +6 -11
  193. package/dist/goals.d.ts +3 -3
  194. package/dist/goals.js +103 -91
  195. package/dist/graph/read.d.ts +2 -2
  196. package/dist/graph/read.js +5 -6
  197. package/dist/graph/types.d.ts +8 -8
  198. package/dist/graph/write.d.ts +7 -14
  199. package/dist/graph/write.js +16 -23
  200. package/dist/graph-extract.d.ts +7 -8
  201. package/dist/graph-extract.js +62 -72
  202. package/dist/graph-recall.d.ts +2 -2
  203. package/dist/graph-recall.js +55 -49
  204. package/dist/graph-stream.d.ts +5 -6
  205. package/dist/graph-stream.js +66 -57
  206. package/dist/graph-view.d.ts +2 -2
  207. package/dist/graph-view.js +7 -7
  208. package/dist/half-life-migration.d.ts +1 -2
  209. package/dist/half-life-migration.js +2 -3
  210. package/dist/hooks/codex-session.js +1 -1
  211. package/dist/hooks/codex-wrapper.d.ts +1 -1
  212. package/dist/hooks/codex-wrapper.js +3 -2
  213. package/dist/hooks/json-hooks.d.ts +2 -2
  214. package/dist/hooks/json-hooks.js +5 -4
  215. package/dist/hooks/opencode.d.ts +1 -1
  216. package/dist/hooks/opencode.js +5 -4
  217. package/dist/hooks/shared.d.ts +3 -7
  218. package/dist/hooks/shared.js +1 -8
  219. package/dist/http-util.d.ts +2 -3
  220. package/dist/http-util.js +3 -0
  221. package/dist/importers/core.d.ts +2 -9
  222. package/dist/importers/core.js +15 -30
  223. package/dist/importers/sources.js +2 -1
  224. package/dist/importers/vault.js +2 -20
  225. package/dist/incidents.d.ts +1 -1
  226. package/dist/incidents.js +46 -39
  227. package/dist/instruction-detect.d.ts +1 -1
  228. package/dist/instruction-detect.js +1 -1
  229. package/dist/invalidation.d.ts +3 -0
  230. package/dist/invalidation.js +160 -114
  231. package/dist/json.d.ts +5 -0
  232. package/dist/json.js +4 -0
  233. package/dist/judgment.js +1 -2
  234. package/dist/local-embedding.js +1 -1
  235. package/dist/mcp/admin-tools.js +7 -17
  236. package/dist/mcp/format.js +1 -1
  237. package/dist/mcp/framing.js +3 -6
  238. package/dist/mcp/protocol.d.ts +2 -5
  239. package/dist/mcp/protocol.js +1 -3
  240. package/dist/mcp/recall-tools.js +12 -15
  241. package/dist/mcp/request.js +4 -3
  242. package/dist/mcp/session-state.js +2 -3
  243. package/dist/mcp/stdio.js +2 -1
  244. package/dist/mcp/tools.js +9 -6
  245. package/dist/memory-value-weights.d.ts +5 -8
  246. package/dist/memory-value-weights.js +5 -8
  247. package/dist/memory-value.d.ts +13 -13
  248. package/dist/memory-value.js +26 -37
  249. package/dist/memory.d.ts +20 -22
  250. package/dist/memory.js +24 -48
  251. package/dist/multihop.d.ts +1 -1
  252. package/dist/multihop.js +3 -2
  253. package/dist/owner-validation.d.ts +4 -5
  254. package/dist/owner-validation.js +4 -5
  255. package/dist/physics.d.ts +4 -4
  256. package/dist/physics.js +7 -9
  257. package/dist/policies.d.ts +9 -10
  258. package/dist/policies.js +96 -81
  259. package/dist/postinstall.js +3 -6
  260. package/dist/predictions/planning-fallacy.d.ts +9 -14
  261. package/dist/predictions/planning-fallacy.js +10 -16
  262. package/dist/predictions/store.d.ts +15 -23
  263. package/dist/predictions/store.js +36 -33
  264. package/dist/processes.d.ts +2 -7
  265. package/dist/processes.js +88 -72
  266. package/dist/project-briefs.d.ts +2 -3
  267. package/dist/project-briefs.js +141 -118
  268. package/dist/project-identity.d.ts +22 -9
  269. package/dist/project-identity.js +47 -12
  270. package/dist/project-merge.d.ts +28 -5
  271. package/dist/project-merge.js +213 -46
  272. package/dist/project-remote.d.ts +12 -0
  273. package/dist/project-remote.js +138 -0
  274. package/dist/prompt-recall.js +1 -2
  275. package/dist/rate-limit.d.ts +1 -1
  276. package/dist/rate-limit.js +1 -1
  277. package/dist/raw-archive.d.ts +9 -0
  278. package/dist/raw-archive.js +70 -53
  279. package/dist/recall-history.d.ts +19 -20
  280. package/dist/recall-history.js +24 -42
  281. package/dist/recall-pipeline.js +4 -28
  282. package/dist/recall-scope.d.ts +7 -8
  283. package/dist/recall-scope.js +7 -8
  284. package/dist/recall-trace.d.ts +5 -9
  285. package/dist/recall-trace.js +6 -10
  286. package/dist/refine-llm.d.ts +1 -1
  287. package/dist/refine-llm.js +2 -2
  288. package/dist/reject-flow.d.ts +3 -4
  289. package/dist/reject-flow.js +122 -117
  290. package/dist/rejection.d.ts +5 -6
  291. package/dist/rejection.js +7 -15
  292. package/dist/rerankers/clef.d.ts +1 -1
  293. package/dist/rerankers/jev.d.ts +1 -2
  294. package/dist/rerankers/jev.js +4 -5
  295. package/dist/rerankers/llm.d.ts +1 -2
  296. package/dist/rerankers/llm.js +1 -2
  297. package/dist/rerankers/types.d.ts +1 -2
  298. package/dist/rrf.d.ts +2 -2
  299. package/dist/rrf.js +2 -2
  300. package/dist/search/bm25-search.d.ts +1 -1
  301. package/dist/search/bm25-search.js +2 -1
  302. package/dist/search/boosts.js +2 -1
  303. package/dist/search/hybrid.d.ts +1 -1
  304. package/dist/search/hybrid.js +2 -1
  305. package/dist/search/physics-search.d.ts +1 -1
  306. package/dist/search/physics-search.js +2 -1
  307. package/dist/search/types.d.ts +2 -0
  308. package/dist/search/types.js +3 -1
  309. package/dist/secret-detect.d.ts +4 -5
  310. package/dist/secret-detect.js +6 -10
  311. package/dist/server/auth.js +5 -5
  312. package/dist/server/client-ip.js +1 -1
  313. package/dist/server/cursor.js +2 -1
  314. package/dist/server/mcp-http.js +4 -4
  315. package/dist/server/request.d.ts +3 -6
  316. package/dist/server/request.js +6 -7
  317. package/dist/server/routes/admin.js +5 -4
  318. package/dist/server/routes/customer-notes.js +6 -5
  319. package/dist/server/routes/decisions.js +4 -3
  320. package/dist/server/routes/incidents.js +7 -5
  321. package/dist/server/routes/memories.js +7 -7
  322. package/dist/server/routes/policies.js +3 -2
  323. package/dist/server/routes/predictions.js +12 -15
  324. package/dist/server/routes/processes.js +3 -2
  325. package/dist/server/routes/project-briefs.js +8 -7
  326. package/dist/server/routes/recall.js +95 -93
  327. package/dist/server/routes/skills.js +6 -5
  328. package/dist/server/types.d.ts +1 -1
  329. package/dist/server/validation.d.ts +1 -2
  330. package/dist/server/validation.js +7 -14
  331. package/dist/server-detect.js +72 -58
  332. package/dist/server.d.ts +2 -2
  333. package/dist/server.js +131 -117
  334. package/dist/shared.d.ts +26 -17
  335. package/dist/shared.js +102 -104
  336. package/dist/skills.d.ts +3 -3
  337. package/dist/skills.js +88 -72
  338. package/dist/store/audit-event.d.ts +2 -2
  339. package/dist/store/audit-event.js +1 -1
  340. package/dist/store/candidates.d.ts +2 -2
  341. package/dist/store/candidates.js +4 -3
  342. package/dist/store/conflicts.js +30 -22
  343. package/dist/store/delete-and-batch.d.ts +11 -14
  344. package/dist/store/delete-and-batch.js +40 -91
  345. package/dist/store/entry-reads.d.ts +17 -25
  346. package/dist/store/entry-reads.js +59 -40
  347. package/dist/store/entry-row.d.ts +6 -24
  348. package/dist/store/entry-row.js +6 -24
  349. package/dist/store/entry-writes.d.ts +6 -7
  350. package/dist/store/entry-writes.js +13 -11
  351. package/dist/store/handoffs.d.ts +1 -1
  352. package/dist/store/handoffs.js +7 -10
  353. package/dist/store/index-and-stats.d.ts +2 -6
  354. package/dist/store/index-and-stats.js +4 -10
  355. package/dist/store/mirrors.d.ts +6 -19
  356. package/dist/store/mirrors.js +14 -39
  357. package/dist/store/open.js +9 -31
  358. package/dist/store/rows.d.ts +5 -11
  359. package/dist/store/rows.js +6 -11
  360. package/dist/store/search-rows.d.ts +17 -34
  361. package/dist/store/search-rows.js +34 -56
  362. package/dist/store/sessions.d.ts +4 -5
  363. package/dist/store/sessions.js +5 -6
  364. package/dist/store/summaries.d.ts +13 -17
  365. package/dist/store/summaries.js +26 -70
  366. package/dist/support-bundle.js +4 -8
  367. package/dist/tenant.d.ts +1 -5
  368. package/dist/token-ledger.d.ts +1 -1
  369. package/dist/token-ledger.js +3 -5
  370. package/dist/trace.js +1 -3
  371. package/dist/version.d.ts +1 -1
  372. package/dist/version.js +1 -1
  373. package/dist/working-memory.d.ts +1 -1
  374. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  375. package/extensions/openclaw-plugin/package.json +1 -1
  376. package/openclaw.plugin.json +1 -1
  377. package/package.json +1 -1
@@ -20,11 +20,7 @@ export function cmdOutcome(hippoRoot, flags) {
20
20
  printError('Specify --good or --bad');
21
21
  process.exit(1);
22
22
  }
23
- // Behavior fix (v1.11.3): cmdOutcome used to bypass api.outcome and do its
24
- // own readEntry/writeEntry inline, which silently skipped the audit_log
25
- // emission that the MCP outcome path already has via api.outcome. T6
26
- // rewires through api.outcome so every successful CLI 'outcome' call now
27
- // writes one audit_log row per affected id, matching MCP parity.
23
+ // Through api.outcome so every CLI outcome writes one audit_log row per id, as the MCP path does.
28
24
  const ctx = {
29
25
  hippoRoot,
30
26
  tenantId: resolveTenantId({}),
@@ -54,7 +50,7 @@ function cmdForget(hippoRoot, id, flags) {
54
50
  tenantId: resolveTenantId({}),
55
51
  actor: api.adminActor('cli'),
56
52
  };
57
- // A3: raw memories (Slack / GitHub connector ingestion) are append-only — a
53
+ // Raw memories (Slack / GitHub connector ingestion) are append-only: a
58
54
  // BEFORE-DELETE trigger aborts any delete. archiveRaw is the sanctioned
59
55
  // removal path; it records ctx.actor as the archiver for provenance.
60
56
  if (flags['archive'] === true) {
@@ -175,11 +171,8 @@ export function cmdResolve(hippoRoot, args, flags) {
175
171
  return;
176
172
  }
177
173
  const forgetLoser = Boolean(flags['forget']);
178
- // AT1: --reject-loser tombstones the loser's normalized digest so it
179
- // cannot be re-asserted later, in addition to removing it (kind-aware).
180
- // --reason defaults to a conflict-context string when omitted (resolve
181
- // already has the conflict id + keepId; unlike `hippo reject`, a reason
182
- // is not strictly required here).
174
+ // --reject-loser tombstones the loser's digest so it cannot be re-asserted, as well as removing it.
175
+ // --reason is optional here, unlike `hippo reject`: resolve already has the conflict id and keepId.
183
176
  const rejectLoser = Boolean(flags['reject-loser']);
184
177
  const reasonFlag = typeof flags['reason'] === 'string' ? flags['reason'] : undefined;
185
178
  const result = resolveConflict(hippoRoot, conflictId, keepId, forgetLoser, tenantId, {
@@ -198,16 +191,14 @@ export function cmdResolve(hippoRoot, args, flags) {
198
191
  console.log(`Resolved conflict ${conflictId}: kept ${keepId}, ${action} ${result.loserId}`);
199
192
  }
200
193
  // ---------------------------------------------------------------------------
201
- // AT1: reject / rejections / unreject
202
- // docs/plans/2026-08-15-at1-rejected-value-tombstone.md §4
194
+ // reject / rejections / unreject
203
195
  // ---------------------------------------------------------------------------
204
196
  export function cmdReject(hippoRoot, args, flags) {
205
197
  // Store resolution mirrors `hippo remember`: --global writes to the
206
198
  // global store, otherwise the local store (requireInit'd via resolveAuthRoot).
207
199
  const root = resolveAuthRoot(hippoRoot, flags);
208
200
  const tenantId = resolveTenantId({});
209
- // --reason is REQUIRED (plan §4, grill issue 4): the tombstone stores no
210
- // content, so reason is its only human-readable identity.
201
+ // --reason is REQUIRED: the tombstone stores no content, so reason is its only human-readable identity.
211
202
  const reason = typeof flags['reason'] === 'string' ? flags['reason'].trim() : '';
212
203
  if (!reason) {
213
204
  printError('hippo reject requires --reason "<why>" (the tombstone stores no content; reason is its only identity).');
@@ -221,8 +212,7 @@ export function cmdReject(hippoRoot, args, flags) {
221
212
  process.exit(1);
222
213
  }
223
214
  if (memoryId && valueFlag !== undefined) {
224
- // Ambiguous ask: silently preferring one form would ignore the other
225
- // without feedback (code-review round-1 low).
215
+ // Ambiguous ask: silently preferring one form would ignore the other without feedback.
226
216
  printError('hippo reject takes EITHER a memory id OR --value, not both.');
227
217
  process.exit(1);
228
218
  }
@@ -372,7 +362,7 @@ export function cmdDormant(hippoRoot, args, flags) {
372
362
  }
373
363
  console.log('Bring one back: hippo dormant restore <id> Delete for good: hippo dormant forget <id>');
374
364
  }
375
- /** `hippo quarantine [list] [--all] [--json] [--global]`, `quarantine approve <id>`, `quarantine reject <id>` (CD5 poisoning defence). */
365
+ /** `hippo quarantine [list] [--all] [--json] [--global]`, `quarantine approve <id>`, `quarantine reject <id>` (poisoning defence). */
376
366
  export function cmdQuarantine(hippoRoot, args, flags) {
377
367
  const root = resolveAuthRoot(hippoRoot, flags);
378
368
  const ctx = {
@@ -465,44 +455,45 @@ export async function handleForget({ hippoRoot, args, flags }) {
465
455
  return;
466
456
  cmdForget(hippoRoot, id, flags);
467
457
  }
468
- export function handleInvalidate({ hippoRoot, args, flags }) {
469
- requireInit(hippoRoot);
470
- if (flags['churn'] === true) {
471
- if (args[0] || flags['id'] !== undefined) {
472
- printError('Usage: hippo invalidate --churn [--dry-run]');
473
- printError('--churn takes no pattern or --id.');
474
- process.exit(1);
458
+ function invalidateChurn(hippoRoot, args, flags) {
459
+ if (args[0] || flags['id'] !== undefined) {
460
+ printError('Usage: hippo invalidate --churn [--dry-run]');
461
+ printError('--churn takes no pattern or --id.');
462
+ process.exit(1);
463
+ }
464
+ if (!isGitRepo(process.cwd())) {
465
+ printError('hippo invalidate --churn must run inside a git repository.');
466
+ process.exit(1);
467
+ }
468
+ const churnDryRun = flags['dry-run'] === true;
469
+ let churnFailed = false;
470
+ for (const { root, result } of runChurnStaleForRepo(hippoRoot, churnDryRun)) {
471
+ if (result.error) {
472
+ printError(`Churn-staleness check failed for ${root}: ${result.error}`);
473
+ churnFailed = true;
474
+ continue;
475
475
  }
476
- if (!isGitRepo(process.cwd())) {
477
- printError('hippo invalidate --churn must run inside a git repository.');
478
- process.exit(1);
476
+ if (result.preview.length === 0) {
477
+ console.log(`No churn-stale candidates in ${root}.`);
479
478
  }
480
- const churnDryRun = flags['dry-run'] === true;
481
- let churnFailed = false;
482
- for (const { root, result } of runChurnStaleForRepo(hippoRoot, churnDryRun)) {
483
- if (result.error) {
484
- printError(`Churn-staleness check failed for ${root}: ${result.error}`);
485
- churnFailed = true;
486
- continue;
487
- }
488
- if (result.preview.length === 0) {
489
- console.log(`No churn-stale candidates in ${root}.`);
490
- }
491
- else if (churnDryRun) {
492
- console.log(`DRY RUN - ${result.marked} memories in ${root} WOULD be tagged churn-stale (${result.alreadyMarked} already tagged):`);
493
- }
494
- else {
495
- console.log(`Tagged ${result.marked} memories churn-stale in ${root} (${result.alreadyMarked} already tagged):`);
496
- }
497
- result.preview.forEach(p => console.log(` ${p.id} ${p.evidence} ${p.already ? '(already) ' : ''}${p.headline}`));
498
- if (result.skippedPinned.length > 0) {
499
- console.log(`Skipped ${result.skippedPinned.length} pinned: ${result.skippedPinned.join(', ')}`);
500
- }
479
+ else if (churnDryRun) {
480
+ console.log(`DRY RUN - ${result.marked} memories in ${root} WOULD be tagged churn-stale (${result.alreadyMarked} already tagged):`);
481
+ }
482
+ else {
483
+ console.log(`Tagged ${result.marked} memories churn-stale in ${root} (${result.alreadyMarked} already tagged):`);
484
+ }
485
+ result.preview.forEach(p => console.log(` ${p.id} ${p.evidence} ${p.already ? '(already) ' : ''}${p.headline}`));
486
+ if (result.skippedPinned.length > 0) {
487
+ console.log(`Skipped ${result.skippedPinned.length} pinned: ${result.skippedPinned.join(', ')}`);
501
488
  }
502
- if (churnFailed)
503
- process.exit(1);
504
- return;
505
489
  }
490
+ if (churnFailed)
491
+ process.exit(1);
492
+ }
493
+ export function handleInvalidate({ hippoRoot, args, flags }) {
494
+ requireInit(hippoRoot);
495
+ if (flags['churn'] === true)
496
+ return invalidateChurn(hippoRoot, args, flags);
506
497
  const target = args[0];
507
498
  if (flags['id'] === true) {
508
499
  // Value-less --id must never silently fall through to pattern mode
@@ -511,12 +502,6 @@ export function handleInvalidate({ hippoRoot, args, flags }) {
511
502
  process.exit(1);
512
503
  }
513
504
  const onlyId = typeof flags['id'] === 'string' ? flags['id'] : undefined;
514
- if (typeof flags['dry-run'] === 'string') {
515
- // Dead: the earlier global BOOLEAN_FLAGS guard now exits first on any --dry-run=<v>.
516
- // Kept as defence in depth on a destructive command.
517
- printError('--dry-run takes no value');
518
- process.exit(1);
519
- }
520
505
  const dryRun = flags['dry-run'] === true;
521
506
  if ((target && onlyId) || (!target && !onlyId)) {
522
507
  printError('Usage: hippo invalidate "<old pattern>" [--dry-run] [--reason "<why>"]');
package/dist/cli/dag.js CHANGED
@@ -26,9 +26,7 @@ export function cmdDag(hippoRoot, flags) {
26
26
  console.log(` Unlinked facts: ${unlinked}`);
27
27
  return;
28
28
  }
29
- // Tree view: v0.30 / E5 renders L3 entity profiles as roots (with L2
30
- // children indented), then orphan L2 summaries (no L3 parent) at top
31
- // level. Pre-E5 behavior was L2-only roots; rendering now covers L3.
29
+ // Tree view: L3 entity profiles as roots with L2 children indented, then orphan L2 summaries at top level.
32
30
  const profiles = entries.filter((e) => e.dag_level === 3);
33
31
  const l2List = entries.filter((e) => e.dag_level === 2);
34
32
  const orphanL2 = l2List.filter((e) => !e.dag_parent_id);
@@ -62,7 +60,7 @@ export function cmdDag(hippoRoot, flags) {
62
60
  }
63
61
  }
64
62
  }
65
- // Orphan L2 summaries (no L3 parent) at top level — pre-E5 default shape.
63
+ // Orphan L2 summaries (no L3 parent) at top level.
66
64
  for (const summary of orphanL2) {
67
65
  const summaryTags = summary.tags.filter((t) => t !== 'dag-summary').join(', ');
68
66
  console.log(`\nšŸ“Œ ${summary.content.slice(0, 80)}`);
@@ -113,8 +111,7 @@ function cmdDrillDown(hippoRoot, summaryId, flags) {
113
111
  const limit = typeof flags['limit'] === 'string' ? Number(flags['limit']) : undefined;
114
112
  // Absent stays undefined so the api default applies; the 0 fallback is unreachable.
115
113
  const budget = flags['budget'] === undefined ? undefined : parseBudgetFlag(flags['budget'], 0);
116
- // v0.30 / E5: --depth N walks N levels down (default 1, hard cap 10).
117
- // L4 fold: reject out-of-range explicitly (no silent clamp).
114
+ // --depth N walks N levels down (default 1, hard cap 10); out-of-range is rejected, never silently clamped.
118
115
  const rawDepth = typeof flags['depth'] === 'string' ? Number(flags['depth']) : undefined;
119
116
  let depth;
120
117
  if (rawDepth !== undefined) {
@@ -136,9 +133,8 @@ function cmdDrillDown(hippoRoot, summaryId, flags) {
136
133
  cost: drillCost,
137
134
  });
138
135
  if ('failure' in r) {
139
- // v1.6.4: only `not_drillable` is caller-actionable. `not_found`
140
- // intentionally collapses cross-tenant + scope-blocked + missing
141
- // (codex round 3 P1: distinguishing scope_blocked leaked existence).
136
+ // Only `not_drillable` is caller-actionable. `not_found` collapses cross-tenant, scope-blocked
137
+ // and missing on purpose: telling scope_blocked apart would leak that the row exists.
142
138
  if (r.failure === 'not_drillable') {
143
139
  printError(`Id ${summaryId} is a leaf row, not a level-2+ summary; nothing to drill into.`);
144
140
  }