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
@@ -1,29 +1,17 @@
1
1
  import type { MemoryEntry } from '../memory.js';
2
2
  import { type DatabaseSyncLike } from '../db.js';
3
3
  /**
4
- * v1.7.2 — recall-mode scope filter shape, exported so callers
5
- * (`loadRecallSearchEntries`) and tests can refer to it symbolically without
6
- * `Parameters<typeof loadSearchRows>[N]` indirection.
7
- *
8
- * Three modes:
9
- * - 'default-deny' — exclude scopes in `RECALL_DEFAULT_DENY_SCOPES` (T2).
10
- * - 'exact' — exact match on `m.scope = value` (api.recall's explicit-scope
11
- * request semantics).
12
- * - 'default-deny-or-exact' (v1.25.0) — the default-admitted set PLUS rows
13
- * whose scope equals `value`. This is the CLI `--scope` semantics: the
14
- * flag predates the envelope column as a TAG-boost ranking hint
15
- * (`scope:<v>` tags, HIPPO_SCOPE), so an explicit flag must UNLOCK the
16
- * named envelope scope in addition to the normal set rather than narrow
17
- * the result to it — narrowing would return zero rows for every
18
- * tag-scoped workflow (envelope scope NULL). Strictly safer than the
19
- * pre-v1.25.0 CLI behavior (no filter at all): other private scopes and
20
- * quarantine buckets stay denied.
4
+ * Recall-mode scope filter shape, exported so callers and tests can name it. Three modes:
5
+ * - 'default-deny': exclude scopes in `RECALL_DEFAULT_DENY_SCOPES`.
6
+ * - 'exact': exact match on `m.scope = value` (api.recall's explicit-scope request semantics).
7
+ * - 'default-deny-or-exact': the default-admitted set PLUS rows whose scope equals `value` (CLI `--scope`).
8
+ * The flag began as a tag-boost hint, so narrowing would return zero rows for tag-scoped workflows.
21
9
  *
22
10
  * Background pipelines (`consolidate`, `embeddings`, `refine-llm`, ...) call
23
11
  * `loadSearchEntries` (no scopeFilter arg) and see all rows including
24
12
  * quarantine.
25
13
  */
26
- /** @internal v1.7.2 — internal SQL-builder shape; not on the public API
14
+ /** @internal Internal SQL-builder shape; not on the public API
27
15
  * surface (not re-exported from `src/index.ts`). Subject to change. */
28
16
  export type RecallScopeFilter = {
29
17
  mode: 'default-deny';
@@ -34,6 +22,8 @@ export type RecallScopeFilter = {
34
22
  mode: 'default-deny-or-exact';
35
23
  value: string;
36
24
  };
25
+ /** One project name, or every name a project's rows carry. */
26
+ export type OriginFilter = string | readonly string[];
37
27
  /** Scope rule for recall: none requested is default-deny; 'exact' narrows to the request; 'additive' adds it to the default set. */
38
28
  export declare function recallScopeFilter(requestedScope: string | undefined, mode: 'exact' | 'additive'): RecallScopeFilter;
39
29
  /**
@@ -45,31 +35,24 @@ export declare function recallScopeFilter(requestedScope: string | undefined, mo
45
35
  */
46
36
  export declare function loadSearchEntries(hippoRoot: string, query: string, limit?: number, tenantId?: string): MemoryEntry[];
47
37
  /**
48
- * v1.7.1 — recall-mode loader. Pushes the recall-side scope predicate into
49
- * SQL so `unknown:legacy` cannot leak via any consumer that hasn't remembered
50
- * to re-filter (root-cause-over-patches: codex flagged this on v1.6.5 review).
38
+ * Recall-mode loader. Pushes the recall-side scope predicate into SQL so
39
+ * `unknown:legacy` cannot leak via any consumer that hasn't remembered to re-filter.
51
40
  *
52
41
  * - `requestedScope` undefined / '': default-deny on `unknown:legacy`.
53
42
  * - `requestedScope` non-empty string: exact match on `m.scope = requestedScope`.
54
43
  *
55
- * Private-scope (`<source>:private:*`) exclusion: SQL applies a conservative
56
- * pre-window approximation (`NOT LIKE '%:private:%'`, v1.25.0 — codex P2:
57
- * post-window-only filtering let private rows starve admitted candidates out
58
- * of the LIMIT window); the exact anchored regex
59
- * (`passesScopeFilterForRecall`) remains the authoritative JS post-filter in
60
- * the recall consumers.
44
+ * Private scopes: SQL applies a conservative `NOT LIKE '%:private:%'` before the LIMIT window so private
45
+ * rows cannot starve admitted ones; `passesScopeFilterForRecall` stays the exact JS post-filter.
61
46
  *
62
- * Consumers: `api.recall` (v1.7.1+), `cmdRecall`/`cmdExplain` direct CLI paths
63
- * and `searchBothHybrid` recall mode (v1.25.0). Background pipelines
47
+ * Consumers: `api.recall`, `cmdRecall`/`cmdExplain` direct CLI paths
48
+ * and `searchBothHybrid` recall mode. Background pipelines
64
49
  * (`consolidate`, `embeddings`, `refine-llm`, ...) keep using
65
50
  * `loadSearchEntries` so they can see quarantined rows when needed.
66
51
  *
67
- * `tenantId` widened to optional in v1.25.0 for the searchBothHybrid recall
68
- * mode (its `tenantId` option is optional); `loadSearchRows` already treats
69
- * undefined as "no tenant filter" for legacy callers.
52
+ * `tenantId` is optional because searchBothHybrid's is; undefined means no tenant filter.
70
53
  */
71
- export declare function loadRecallSearchEntries(hippoRoot: string, query: string, limit?: number, tenantId?: string, requestedScope?: string, explicitScopeMode?: 'exact' | 'additive', includeSuperseded?: boolean): MemoryEntry[];
72
- export declare function loadRecallSearchEntriesFromDb(db: DatabaseSyncLike, query: string, limit?: number, tenantId?: string, requestedScope?: string, explicitScopeMode?: 'exact' | 'additive', includeSuperseded?: boolean): MemoryEntry[];
54
+ export declare function loadRecallSearchEntries(hippoRoot: string, query: string, limit?: number, tenantId?: string, requestedScope?: string, explicitScopeMode?: 'exact' | 'additive', includeSuperseded?: boolean, originProjects?: OriginFilter): MemoryEntry[];
55
+ export declare function loadRecallSearchEntriesFromDb(db: DatabaseSyncLike, query: string, limit?: number, tenantId?: string, requestedScope?: string, explicitScopeMode?: 'exact' | 'additive', includeSuperseded?: boolean, originProjects?: OriginFilter): MemoryEntry[];
73
56
  /** Which rows the vector arm of hybrid search may add: the same tenant, scope and superseded rules as the lexical load. */
74
57
  export interface VectorCandidateSpec {
75
58
  tenantId?: string;
@@ -4,9 +4,11 @@ import { tokenize } from '../tokenize.js';
4
4
  import { RECALL_DEFAULT_DENY_SCOPES } from '../recall-scope.js';
5
5
  import { RAREST_TERM_COUNT, rarestPromptTerms } from '../prompt-recall.js';
6
6
  import { log } from '../log.js';
7
+ import { originInSql } from '../project-identity.js';
7
8
  import { topVectorMatches } from '../vector-store.js';
8
9
  import { MEMORY_SELECT_COLUMNS, MEMORY_SEARCH_COLUMNS, DEFAULT_SEARCH_CANDIDATE_LIMIT, rowToEntry, } from './rows.js';
9
10
  import { openStore } from './open.js';
11
+ import { escapeLike } from '../escape.js';
10
12
  /** The recall scope rule for a table column prefix (`m.` or none); `passesScopeFilterForRecall` in recall-scope.ts is its JS twin. */
11
13
  function recallScopeClause(col, scopeFilter) {
12
14
  if (scopeFilter === undefined)
@@ -22,6 +24,14 @@ function recallScopeClause(col, scopeFilter) {
22
24
  // The trailing arm keeps a deliberately requested scope loadable, private or quarantined included.
23
25
  return { sql: ` AND (${admitted} OR ${col}scope = ?)`, params: [...RECALL_DEFAULT_DENY_SCOPES, scopeFilter.value] };
24
26
  }
27
+ // In SQL, not after the window cut, so other projects' matches cannot crowd the project's own rows out of the LIMIT.
28
+ function withProject(scope, col, origin) {
29
+ if (origin === undefined)
30
+ return scope;
31
+ // A string is the shape published callers passed before a project could carry several names.
32
+ const originProjects = [origin].flat();
33
+ return { sql: `${scope.sql} AND (${col}origin_project = '' OR ${originInSql(originProjects, `${col}origin_project`)})`, params: [...scope.params, ...originProjects] };
34
+ }
25
35
  /** Scope rule for recall: none requested is default-deny; 'exact' narrows to the request; 'additive' adds it to the default set. */
26
36
  export function recallScopeFilter(requestedScope, mode) {
27
37
  if (!requestedScope)
@@ -29,22 +39,15 @@ export function recallScopeFilter(requestedScope, mode) {
29
39
  return mode === 'additive' ? { mode: 'default-deny-or-exact', value: requestedScope } : { mode: 'exact', value: requestedScope };
30
40
  }
31
41
  const FTS_QUERY_SYNTAX_RE = /fts5: syntax error|unterminated string/i;
32
- function loadSearchRows(db, query, limit, tenantId, scopeFilter, includeSuperseded = true) {
33
- const p = searchPredicates(tenantId, scopeFilter, includeSuperseded);
42
+ function loadSearchRows(db, query, limit, tenantId, scopeFilter, includeSuperseded = true, originProjects) {
43
+ const p = searchPredicates(tenantId, scopeFilter, includeSuperseded, originProjects);
34
44
  const terms = Array.from(new Set(tokenize(query)));
35
45
  if (terms.length === 0) {
36
- // F3 (v1.7.0) self-review: empty-query path is the second uncapped
37
- // path (codex diff-pass caught the full-store fallback at the bottom;
38
- // this no-terms path had the same shape). Apply LIMIT so all four
39
- // candidate paths honour the caller's cap when set.
46
+ // LIMIT here too, so every candidate path honours the caller's cap.
40
47
  return selectAllCandidates(db, p, limit);
41
48
  }
42
- // v1.7.1 — test/diagnostic hook: `HIPPO_FORCE_LIKE_PATH=1` forces the
43
- // LIKE-fallback path here only. Gated at the read-call site so writes
44
- // (`syncFtsRow`, `deleteFtsRow`, `raw-archive.ts::archiveRaw`) keep using
45
- // `isFtsAvailable` honestly and never silently skip FTS index sync.
46
- // Lets tests exercise the LIKE branch deterministically without
47
- // poisoning the on-disk FTS state.
49
+ // `HIPPO_FORCE_LIKE_PATH=1` forces the LIKE path for tests; gated at this read site so
50
+ // writes keep using `isFtsAvailable` and never silently skip FTS index sync.
48
51
  const forceLikePath = envForceLikePath();
49
52
  if (!forceLikePath && isFtsAvailable(db)) {
50
53
  const rows = selectFtsCandidates(db, terms, p, limit);
@@ -54,14 +57,11 @@ function loadSearchRows(db, query, limit, tenantId, scopeFilter, includeSupersed
54
57
  const rows = selectLikeCandidates(db, terms, p, limit);
55
58
  if (rows.length > 0)
56
59
  return rows;
57
- // F3 (v1.7.0) codex P1: pre-v1.7.0 the full-store fallback ignored
58
- // `limit` and could return the whole tenant store. With scorerWindow
59
- // now reported on RecallResult, an unbounded fallback would lie about
60
- // candidate-pool size. Apply LIMIT here so all four paths honour the
61
- // caller's cap.
60
+ // LIMIT the full-store fallback too: RecallResult reports the scorer window, so an
61
+ // unbounded fallback would misstate the candidate-pool size.
62
62
  return selectAllCandidates(db, p, limit);
63
63
  }
64
- function searchPredicates(tenantId, scopeFilter, includeSuperseded) {
64
+ function searchPredicates(tenantId, scopeFilter, includeSuperseded, originProjects) {
65
65
  // tenantId undefined = no tenant filter (legacy callers / cross-deployment
66
66
  // helpers). tenantId set = strict tenant isolation, leveraging the composite
67
67
  // idx_memories_tenant_created (leading column tenant_id, O(log n) lookup).
@@ -69,19 +69,8 @@ function searchPredicates(tenantId, scopeFilter, includeSuperseded) {
69
69
  const tenantPredicateNoAlias = tenantId !== undefined ? ` AND tenant_id = ?` : '';
70
70
  const tenantOnlyPredicate = tenantId !== undefined ? ` WHERE tenant_id = ?` : '';
71
71
  const tenantParams = tenantId !== undefined ? [tenantId] : [];
72
- // v1.12.6 — belt-and-suspenders against `kind='archived'` leaking into recall.
73
- // `kind='archived'` is a transient sentinel inside `archiveRawMemory`'s
74
- // SAVEPOINT (src/raw-archive.ts:56): UPDATE kind = 'archived' immediately
75
- // followed by DELETE, both inside one savepoint that commits or rolls back
76
- // atomically. SQLite atomicity guarantees no concurrent reader sees the
77
- // intermediate state. This filter is defensive-only against:
78
- // (a) future bugs that drop the SAVEPOINT,
79
- // (b) future bugs that introduce kind='archived' as a persisted state,
80
- // (c) external direct-SQL writes that bypass archiveRawMemory.
81
- // tenantOnlyPredicate starts with " WHERE tenant_id = ?" when tenant is set;
82
- // when unset, we have no WHERE yet, so the archived clause needs both AND
83
- // and WHERE forms. The "tenant-only" path always has WHERE (from tenant or
84
- // we synthesize one).
72
+ // Defensive: kind='archived' is a transient sentinel inside archiveRawMemory's SAVEPOINT, so this only
73
+ // guards against a dropped SAVEPOINT, a persisted 'archived' state, or direct-SQL writes.
85
74
  const archivedClauseAlias = ` AND m.kind != 'archived'`;
86
75
  const archivedClauseNoAlias = ` AND kind != 'archived'`;
87
76
  // For the "tenant-only" path: if no tenant set, tenantOnlyPredicate is '',
@@ -89,8 +78,8 @@ function searchPredicates(tenantId, scopeFilter, includeSuperseded) {
89
78
  // by always joining `tenantOnlyPredicate + archivedClauseTenantOnly` where
90
79
  // the latter switches between " AND" and " WHERE" based on caller context.
91
80
  const archivedClauseTenantOnly = tenantId !== undefined ? ` AND kind != 'archived'` : ` WHERE kind != 'archived'`;
92
- const aliasScope = recallScopeClause('m.', scopeFilter);
93
- const plainScope = recallScopeClause('', scopeFilter);
81
+ const aliasScope = withProject(recallScopeClause('m.', scopeFilter), 'm.', originProjects);
82
+ const plainScope = withProject(recallScopeClause('', scopeFilter), '', originProjects);
94
83
  const scopeParams = aliasScope.params;
95
84
  const currentAlias = includeSuperseded ? '' : ' AND m.superseded_by IS NULL';
96
85
  const currentNoAlias = includeSuperseded ? '' : ' AND superseded_by IS NULL';
@@ -114,9 +103,6 @@ function selectFtsCandidates(db, terms, p, limit) {
114
103
  // memories_fts virtual table has no tenant_id column; filter via the
115
104
  // joined memories row (cheap with idx_memories_tenant_created leading
116
105
  // on tenant_id).
117
- // F1 (v1.7.0): MEMORY_SEARCH_COLUMNS adds bm25_score as the trailing
118
- // result column. Every other column is m.<col> AS <col> so rowToEntry
119
- // sees the same shape it always has.
120
106
  // SAFETY: MEMORY_SEARCH_COLUMNS aliases every column to the same name
121
107
  // MEMORY_SELECT_COLUMNS uses (plus bm25_score), matching MemoryRow.
122
108
  return db.prepare(`
@@ -137,7 +123,6 @@ function selectFtsCandidates(db, terms, p, limit) {
137
123
  }
138
124
  }
139
125
  function selectLikeCandidates(db, terms, p, limit) {
140
- const escapeLike = (term) => term.replace(/[%_\\]/g, '\\$&');
141
126
  const where = terms.map(() => `(LOWER(content) LIKE ? ESCAPE '\\' OR LOWER(tags_json) LIKE ? ESCAPE '\\')`).join(' OR ');
142
127
  const params = terms.flatMap((term) => {
143
128
  const like = `%${escapeLike(term)}%`;
@@ -170,42 +155,35 @@ export function loadSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDI
170
155
  }
171
156
  }
172
157
  /**
173
- * v1.7.1 — recall-mode loader. Pushes the recall-side scope predicate into
174
- * SQL so `unknown:legacy` cannot leak via any consumer that hasn't remembered
175
- * to re-filter (root-cause-over-patches: codex flagged this on v1.6.5 review).
158
+ * Recall-mode loader. Pushes the recall-side scope predicate into SQL so
159
+ * `unknown:legacy` cannot leak via any consumer that hasn't remembered to re-filter.
176
160
  *
177
161
  * - `requestedScope` undefined / '': default-deny on `unknown:legacy`.
178
162
  * - `requestedScope` non-empty string: exact match on `m.scope = requestedScope`.
179
163
  *
180
- * Private-scope (`<source>:private:*`) exclusion: SQL applies a conservative
181
- * pre-window approximation (`NOT LIKE '%:private:%'`, v1.25.0 — codex P2:
182
- * post-window-only filtering let private rows starve admitted candidates out
183
- * of the LIMIT window); the exact anchored regex
184
- * (`passesScopeFilterForRecall`) remains the authoritative JS post-filter in
185
- * the recall consumers.
164
+ * Private scopes: SQL applies a conservative `NOT LIKE '%:private:%'` before the LIMIT window so private
165
+ * rows cannot starve admitted ones; `passesScopeFilterForRecall` stays the exact JS post-filter.
186
166
  *
187
- * Consumers: `api.recall` (v1.7.1+), `cmdRecall`/`cmdExplain` direct CLI paths
188
- * and `searchBothHybrid` recall mode (v1.25.0). Background pipelines
167
+ * Consumers: `api.recall`, `cmdRecall`/`cmdExplain` direct CLI paths
168
+ * and `searchBothHybrid` recall mode. Background pipelines
189
169
  * (`consolidate`, `embeddings`, `refine-llm`, ...) keep using
190
170
  * `loadSearchEntries` so they can see quarantined rows when needed.
191
171
  *
192
- * `tenantId` widened to optional in v1.25.0 for the searchBothHybrid recall
193
- * mode (its `tenantId` option is optional); `loadSearchRows` already treats
194
- * undefined as "no tenant filter" for legacy callers.
172
+ * `tenantId` is optional because searchBothHybrid's is; undefined means no tenant filter.
195
173
  */
196
- export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true) {
174
+ export function loadRecallSearchEntries(hippoRoot, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true, originProjects) {
197
175
  const db = openStore(hippoRoot);
198
176
  try {
199
- return loadRecallSearchEntriesFromDb(db, query, limit, tenantId, requestedScope, explicitScopeMode, includeSuperseded);
177
+ return loadRecallSearchEntriesFromDb(db, query, limit, tenantId, requestedScope, explicitScopeMode, includeSuperseded, originProjects);
200
178
  }
201
179
  finally {
202
180
  closeHippoDb(db);
203
181
  }
204
182
  }
205
- // Split out so callers with an already-open db (Z1 prompt-recall path) skip
183
+ // Split out so callers with an already-open db (the prompt-recall path) skip
206
184
  // the initStore+open/close cycle per store per call.
207
- export function loadRecallSearchEntriesFromDb(db, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true) {
208
- return loadSearchRows(db, query, limit, tenantId, recallScopeFilter(requestedScope, explicitScopeMode), includeSuperseded).map(rowToEntry);
185
+ export function loadRecallSearchEntriesFromDb(db, query, limit = DEFAULT_SEARCH_CANDIDATE_LIMIT, tenantId, requestedScope, explicitScopeMode = 'exact', includeSuperseded = true, originProjects) {
186
+ return loadSearchRows(db, query, limit, tenantId, recallScopeFilter(requestedScope, explicitScopeMode), includeSuperseded, originProjects).map(rowToEntry);
209
187
  }
210
188
  /** The rows nearest `queryVector` that pass `spec`, nearest first. */
211
189
  export function loadVectorCandidateEntries(hippoRoot, queryVector, spec) {
@@ -9,8 +9,7 @@ export declare function saveActiveTaskSnapshot(hippoRoot: string, tenantId: stri
9
9
  }): TaskSnapshot;
10
10
  export declare function loadActiveTaskSnapshot(hippoRoot: string, tenantId: string): TaskSnapshot | null;
11
11
  /**
12
- * Default freshness bound for AMBIENT active-task-snapshot reads (DF1,
13
- * docs/plans/2026-08-23-df1-snapshot-lifecycle.md): 72h, chosen over 48h so
12
+ * Default freshness bound for AMBIENT active-task-snapshot reads: 72h, chosen over 48h so
14
13
  * a Friday-evening orphan still offers continuity on Monday morning.
15
14
  * Exported so callers can override via `loadFreshActiveTaskSnapshot`'s
16
15
  * `opts.maxAgeMs`; deliberately no env knob (Simplicity First).
@@ -18,7 +17,7 @@ export declare function loadActiveTaskSnapshot(hippoRoot: string, tenantId: stri
18
17
  export declare const SNAPSHOT_AMBIENT_MAX_AGE_MS: number;
19
18
  /**
20
19
  * Bounded read for AMBIENT active-task-snapshot surfaces (UserPromptSubmit
21
- * hook context, MCP recall block) — the never-expires fix for DF1. A
20
+ * hook context, MCP recall block), so snapshots expire. A
22
21
  * snapshot written by `hippo pre-compact` has no death path tied to the
23
22
  * session that owns it, so an orphaned row would otherwise inject into
24
23
  * every prompt of every later session forever. Wraps `loadActiveTaskSnapshot`
@@ -45,8 +44,8 @@ export declare function loadFreshActiveTaskSnapshot(hippoRoot: string, tenantId:
45
44
  }): TaskSnapshot | null;
46
45
  export declare function clearActiveTaskSnapshot(hippoRoot: string, tenantId: string, clearedStatus?: string): boolean;
47
46
  /**
48
- * Close the `active` task snapshot(s) owned by `sessionId`, for the T3
49
- * session-end death path (DF1, docs/plans/2026-08-23-df1-snapshot-lifecycle.md).
47
+ * Close the `active` task snapshot(s) owned by `sessionId`, for the
48
+ * session-end death path.
50
49
  * Only one `active` row exists per tenant in practice (supersession happens
51
50
  * at save), but the WHERE clause scopes on `session_id` too — not just
52
51
  * `status='active' AND tenant_id=?` — so an ending session can never close a
@@ -68,8 +68,7 @@ export function loadActiveTaskSnapshot(hippoRoot, tenantId) {
68
68
  }
69
69
  }
70
70
  /**
71
- * Default freshness bound for AMBIENT active-task-snapshot reads (DF1,
72
- * docs/plans/2026-08-23-df1-snapshot-lifecycle.md): 72h, chosen over 48h so
71
+ * Default freshness bound for AMBIENT active-task-snapshot reads: 72h, chosen over 48h so
73
72
  * a Friday-evening orphan still offers continuity on Monday morning.
74
73
  * Exported so callers can override via `loadFreshActiveTaskSnapshot`'s
75
74
  * `opts.maxAgeMs`; deliberately no env knob (Simplicity First).
@@ -83,7 +82,7 @@ function isNonEmptySessionId(value) {
83
82
  }
84
83
  /**
85
84
  * Bounded read for AMBIENT active-task-snapshot surfaces (UserPromptSubmit
86
- * hook context, MCP recall block) — the never-expires fix for DF1. A
85
+ * hook context, MCP recall block), so snapshots expire. A
87
86
  * snapshot written by `hippo pre-compact` has no death path tied to the
88
87
  * session that owns it, so an orphaned row would otherwise inject into
89
88
  * every prompt of every later session forever. Wraps `loadActiveTaskSnapshot`
@@ -138,8 +137,8 @@ export function clearActiveTaskSnapshot(hippoRoot, tenantId, clearedStatus = 'cl
138
137
  }
139
138
  }
140
139
  /**
141
- * Close the `active` task snapshot(s) owned by `sessionId`, for the T3
142
- * session-end death path (DF1, docs/plans/2026-08-23-df1-snapshot-lifecycle.md).
140
+ * Close the `active` task snapshot(s) owned by `sessionId`, for the
141
+ * session-end death path.
143
142
  * Only one `active` row exists per tenant in practice (supersession happens
144
143
  * at save), but the WHERE clause scopes on `session_id` too — not just
145
144
  * `status='active' AND tenant_id=?` — so an ending session can never close a
@@ -162,7 +161,7 @@ export function appendSessionEvent(hippoRoot, tenantId, event) {
162
161
  assertTenantId('appendSessionEvent', tenantId);
163
162
  const db = openStore(hippoRoot);
164
163
  const now = new Date().toISOString();
165
- // v1.2: scope is wired through. Default-deny in api.recall + cmdRecall
164
+ // Scope is stored as given; default-deny in api.recall + cmdRecall
166
165
  // continuity reads applies to slack:private:* and 'unknown:legacy' rows.
167
166
  try {
168
167
  const result = db.prepare(`
@@ -1,7 +1,7 @@
1
1
  import type { MemoryEntry } from '../memory.js';
2
2
  /**
3
3
  * Load summaries flagged dirty for the given tenant. Sorted by latest_at
4
- * DESC (NULLS LAST) so E3's rebuild cap (HIPPO_DAG_REBUILD_CAP, default 20)
4
+ * DESC (NULLS LAST) so the rebuild cap (HIPPO_DAG_REBUILD_CAP, default 20)
5
5
  * takes the most-recently-changed summaries first.
6
6
  *
7
7
  * Returns full MemoryEntry shape via MEMORY_SELECT_COLUMNS + rowToEntry
@@ -11,21 +11,20 @@ export declare function loadDirtySummaries(hippoRoot: string, tenantId: string):
11
11
  /**
12
12
  * Mark a summary as dirty. Idempotent (re-marking dirty is a no-op + no
13
13
  * second audit row). Tenant-scoped to prevent cross-tenant writes via
14
- * parent-lookup. Called by E2 from invalidation.ts / writeEntry /
14
+ * parent-lookup. Called from invalidation.ts / writeEntry /
15
15
  * forgetMemory / archiveRawMemory whenever a child is invalidated,
16
16
  * superseded, forgotten, or archived.
17
17
  *
18
- * Quietly no-ops if the target row doesn't exist or isn't a level-2
19
- * summary (E5 will widen the dag_level guard to IN (2, 3) when level-3
20
- * build path lands). Emits a 'summary_marked_dirty' audit row on actual
18
+ * Quietly no-ops if the target row doesn't exist or isn't a level-2/3
19
+ * summary. Emits a 'summary_marked_dirty' audit row on actual
21
20
  * state transitions (0 -> 1) via the audit() helper, which try/catches
22
21
  * for missing audit_log (the v27 self-heal scenario).
23
22
  */
24
23
  export declare function markSummaryDirty(hippoRoot: string, summaryId: string, tenantId: string, actor?: string): void;
25
24
  /**
26
- * v0.30 / E5 — host-wide loader for L2 topic summaries without an L3 parent.
25
+ * Host-wide loader for L2 topic summaries without an L3 parent.
27
26
  * Used by consolidate phase 1.9 (buildEntityProfiles) to cluster L2s into
28
- * L3 entity profiles. Mirrors loadAllDirtySummaries pattern (E3): SQL-level
27
+ * L3 entity profiles. Mirrors loadAllDirtySummaries: SQL-level
29
28
  * filter is cheaper than reusing in-memory `survivors` (which doesn't
30
29
  * contain L2s freshly created by phase 1.7 buildDag).
31
30
  *
@@ -34,7 +33,7 @@ export declare function markSummaryDirty(hippoRoot: string, summaryId: string, t
34
33
  */
35
34
  export declare function loadAllL2Summaries(hippoRoot: string): MemoryEntry[];
36
35
  /**
37
- * v0.30 / E3 — host-wide variant of loadDirtySummaries. Iterates all tenants
36
+ * Host-wide variant of loadDirtySummaries. Iterates all tenants
38
37
  * in one query so consolidate.ts (host-wide per L106-109) does not need a
39
38
  * per-tenant loop. Each returned MemoryEntry carries its own tenantId (via
40
39
  * rowToEntry), so per-summary children + rebuild UPDATE stay tenant-scoped.
@@ -44,7 +43,7 @@ export declare function loadAllL2Summaries(hippoRoot: string): MemoryEntry[];
44
43
  */
45
44
  export declare function loadAllDirtySummaries(hippoRoot: string): MemoryEntry[];
46
45
  /**
47
- * v0.30 / E3 — load live children of a DAG summary. Used by
46
+ * Load live children of a DAG summary. Used by
48
47
  * rebuildDirtySummaries to regenerate content from the CURRENT child set
49
48
  * (not the children at create-time). Skips archived. Tenant-scoped
50
49
  * (defence in depth — dag_parent_id is unique-ish but tenant guard is
@@ -52,7 +51,7 @@ export declare function loadAllDirtySummaries(hippoRoot: string): MemoryEntry[];
52
51
  */
53
52
  export declare function loadChildrenOfSummary(hippoRoot: string, summaryId: string, tenantId: string): MemoryEntry[];
54
53
  /**
55
- * v0.30 / E3 — patch applied by applyRebuildResult. Two-branch shape
54
+ * Patch applied by applyRebuildResult. Two-branch shape
56
55
  * (bumpRebuildCount false for zero-child case, true for normal rebuild).
57
56
  */
58
57
  export interface RebuildPatch {
@@ -65,7 +64,7 @@ export interface RebuildPatch {
65
64
  actor: string;
66
65
  }
67
66
  /**
68
- * v0.30 / E3 — apply a rebuild result to a dirty summary. Atomic: one
67
+ * Apply a rebuild result to a dirty summary. Atomic: one
69
68
  * prepared UPDATE statement plus syncFtsRow inside one SAVEPOINT.
70
69
  * WHERE includes `AND summary_dirty = 1` so concurrent sleep's race-loser
71
70
  * becomes a no-op (no rebuild_count bump, no audit row).
@@ -81,14 +80,11 @@ export declare function applyRebuildResult(hippoRoot: string, summary: MemoryEnt
81
80
  refused: boolean;
82
81
  };
83
82
  /**
84
- * v0.30 / E3 — clear summary_dirty on a freshly-built summary. Called by
85
- * buildDag immediately after the child-link loop finishes. Without this,
86
- * each member's writeEntry call fires markSummaryDirtyInTx on the just-
87
- * created parent (E2 hook at store.ts:1214), and the same sleep cycle's
88
- * E3 rebuild phase would re-rebuild every new summary (2x LLM cost).
83
+ * Clear summary_dirty on a freshly-built summary. Called by buildDag right after the child-link loop:
84
+ * each member's writeEntry marks the new parent dirty, so the same cycle's rebuild would redo every new summary.
89
85
  *
90
86
  * Idempotent: no-op + no audit if summary isn't dirty. Audit
91
- * source='buildDag-clean' distinguishes from E3-rebuild source.
87
+ * source='buildDag-clean' distinguishes it from the rebuild's source.
92
88
  */
93
89
  export declare function clearSummaryDirtyAfterBuild(hippoRoot: string, summaryId: string, tenantId: string, actor?: string, source?: string): void;
94
90
  //# sourceMappingURL=summaries.d.ts.map