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
package/dist/goals.js CHANGED
@@ -29,7 +29,7 @@ export function pushGoal(hippoRoot, opts) {
29
29
  }
30
30
  }
31
31
  /**
32
- * v1.7.4 — depth-cap enforcer extracted from pushGoalWithDb and resumeGoal.
32
+ * Depth-cap enforcer shared by pushGoalWithDb and resumeGoal.
33
33
  * If the (tenant, session) has >= MAX_ACTIVE_GOAL_DEPTH active goals,
34
34
  * suspend the oldest `overflow` ones.
35
35
  *
@@ -38,7 +38,7 @@ export function pushGoal(hippoRoot, opts) {
38
38
  * is impossible to misread the contract at a call site. Both existing call
39
39
  * sites (pushGoalWithDb, resumeGoal) wrap in `BEGIN IMMEDIATE` already.
40
40
  *
41
- * @internal v1.7.4 -- internal goal-stack invariant. Subject to change.
41
+ * @internal Internal goal-stack invariant. Subject to change.
42
42
  */
43
43
  export function enforceDepthCapWithinTx(db, tenantId, sessionId) {
44
44
  // SAFETY: the row comes from the SELECT above, which projects exactly one
@@ -159,35 +159,11 @@ export function getActiveGoalsWithDb(db, opts) {
159
159
  `).all(opts.tenantId, opts.sessionId);
160
160
  return rows.map(rowToGoal);
161
161
  }
162
- /**
163
- * dlPFC goal-stack boost. Applies the multi-goal boost to entry-backed scored
164
- * rows when (tenant, session) has active goals and returns the log rows to
165
- * write, without writing them; {@link writeGoalRecallLog} persists them.
166
- *
167
- * Caller responsibilities:
168
- * - Do NOT call when an explicit `goalTag` is set (caller's gate)
169
- * - Pass entry-backed rows (with `entry.tags`, `entry.id`, optional
170
- * `entry.schema_fit`)
171
- * - Manage the db handle lifecycle (helper neither opens nor closes)
172
- * - Recompute `tokens` after if returned rows are projected to a budgeted
173
- * shape
174
- *
175
- * Log rows cover the top `limit` boosted rows that live in this store's
176
- * `memories` table (global-only ids are skipped to keep the FK on
177
- * goal_recall_log.memory_id valid).
178
- *
179
- * @internal Recall ranking helper. Subject to change.
180
- */
181
- export function computeGoalStackBoost(db, results, opts) {
182
- const { sessionId, tenantId, limit, trace } = opts;
183
- const active = getActiveGoalsWithDb(db, { sessionId, tenantId });
184
- if (active.length === 0)
185
- return { results, log: [] };
186
- const goalsByTag = new Map(active.map((g) => [g.goalName, g]));
187
- // Load retrieval_policy rows for active goals so per-policy multipliers
188
- // can compose onto the base goal-tag boost. Composed result is hard-capped
189
- // at MAX_FINAL_MULTIPLIER (3.0x) BEFORE applying to score -- even an
190
- // `errorPriority: 9.0` policy cannot exceed 3.0x.
162
+ // Load retrieval_policy rows for active goals so per-policy multipliers
163
+ // can compose onto the base goal-tag boost. Composed result is hard-capped
164
+ // at MAX_FINAL_MULTIPLIER (3.0x) BEFORE applying to score -- even an
165
+ // `errorPriority: 9.0` policy cannot exceed 3.0x.
166
+ function loadGoalPolicies(db, active) {
191
167
  const policiesByGoalId = new Map();
192
168
  for (const g of active) {
193
169
  if (!g.retrievalPolicyId)
@@ -210,67 +186,42 @@ export function computeGoalStackBoost(db, results, opts) {
210
186
  });
211
187
  }
212
188
  }
213
- // Goal-tag matches per boosted row, keyed by entry id. Kept as a side table
214
- // (rather than a spread-on `_goalMatches` marker property) so `boosted`
215
- // stays exactly R[] end to end, with no cast-tag-then-strip round trip.
216
- const matchesByEntryId = new Map();
217
- const boosted = results
218
- .map((r) => {
219
- const tags = r.entry.tags ?? [];
220
- const matches = tags.filter((t) => goalsByTag.has(t));
221
- if (matches.length === 0)
222
- return r;
223
- // Base 2.0x for first match, +0.5x per additional, capped at 3.0x.
224
- let multiplier = Math.min(2.0 + 0.5 * (matches.length - 1), MAX_FINAL_MULTIPLIER);
225
- // Compose per-policy multipliers per matched tag.
226
- for (const tag of matches) {
227
- const goal = goalsByTag.get(tag);
228
- const policy = policiesByGoalId.get(goal.id);
229
- if (!policy)
230
- continue;
231
- if (policy.policyType === 'error-prioritized' && tags.includes('error')) {
232
- multiplier *= policy.errorPriority;
233
- }
234
- else if (policy.policyType === 'schema-fit-biased') {
235
- // Linearly weight schema_fit in [0,1] up to (weightSchemaFit)x.
236
- // Default 1.0 is a no-op.
237
- multiplier *=
238
- 1.0 +
239
- Math.max(0, policy.weightSchemaFit - 1.0) *
240
- (r.entry.schema_fit ?? 0.5);
241
- }
242
- else if (policy.policyType === 'recency-first') {
243
- multiplier *= policy.weightRecency;
244
- }
245
- else if (policy.policyType === 'hybrid') {
246
- multiplier *= policy.weightOutcome;
247
- }
189
+ return policiesByGoalId;
190
+ }
191
+ /** The capped boost for one row whose tags match `matches` active goals. */
192
+ function goalBoostMultiplier(entry, tags, matches, goalsByTag, policiesByGoalId) {
193
+ // Base 2.0x for first match, +0.5x per additional, capped at 3.0x.
194
+ let multiplier = Math.min(2.0 + 0.5 * (matches.length - 1), MAX_FINAL_MULTIPLIER);
195
+ // Compose per-policy multipliers per matched tag.
196
+ for (const tag of matches) {
197
+ const goal = goalsByTag.get(tag);
198
+ const policy = policiesByGoalId.get(goal.id);
199
+ if (!policy)
200
+ continue;
201
+ if (policy.policyType === 'error-prioritized' && tags.includes('error')) {
202
+ multiplier *= policy.errorPriority;
248
203
  }
249
- // Hard cap AFTER all composition.
250
- multiplier = Math.min(multiplier, MAX_FINAL_MULTIPLIER);
251
- // A7 recall-trace side-channel: record the goal-boost step BEFORE the
252
- // score is mutated, keyed by entry id. Pure read of r.score here; the
253
- // mutation below is byte-identical to pre-A7.
254
- if (trace) {
255
- trace.set(r.entry.id, {
256
- stage: 'goal-boost',
257
- multiplier,
258
- scoreBefore: r.score,
259
- scoreAfter: r.score * multiplier,
260
- note: matches.join(', '),
261
- });
204
+ else if (policy.policyType === 'schema-fit-biased') {
205
+ // Linearly weight schema_fit in [0,1] up to (weightSchemaFit)x.
206
+ // Default 1.0 is a no-op.
207
+ multiplier *=
208
+ 1.0 +
209
+ Math.max(0, policy.weightSchemaFit - 1.0) *
210
+ (entry.schema_fit ?? 0.5);
262
211
  }
263
- matchesByEntryId.set(r.entry.id, matches);
264
- // SAFETY: spreading a generic-constrained `r: R` widens the result to
265
- // the spread's plain object type; only `score` changes, so the value
266
- // still satisfies R's shape exactly.
267
- return { ...r, score: r.score * multiplier };
268
- })
269
- // T2 note: deliberately a PLAIN stable score sort, no compareEntryIdentity
270
- // tail -- a re-sort of an already deterministically-ordered ranking
271
- // inherits its determinism via sort stability, and ties preserve the
272
- // prior (meaningful) rank instead of reordering by content.
273
- .sort((a, b) => b.score - a.score);
212
+ else if (policy.policyType === 'recency-first') {
213
+ multiplier *= policy.weightRecency;
214
+ }
215
+ else if (policy.policyType === 'hybrid') {
216
+ multiplier *= policy.weightOutcome;
217
+ }
218
+ }
219
+ // Hard cap AFTER all composition.
220
+ return Math.min(multiplier, MAX_FINAL_MULTIPLIER);
221
+ }
222
+ /** Log rows for the top `limit` boosted rows, one per matched goal. */
223
+ function buildGoalRecallLog(db, boosted, matchesByEntryId, goalsByTag, opts) {
224
+ const { sessionId, tenantId, limit } = opts;
274
225
  // Filter to local memories only -- global memory IDs aren't in this DB's
275
226
  // memories table, so the FK on goal_recall_log.memory_id would fail.
276
227
  // dlPFC depth's outcome propagation is session-scoped to local; boost on
@@ -301,7 +252,68 @@ export function computeGoalStackBoost(db, results, opts) {
301
252
  log.push({ goalId: goal.id, memoryId: r.entry.id, tenantId, sessionId, recalledAt, score: r.score });
302
253
  }
303
254
  }
304
- return { results: boosted, log };
255
+ return log;
256
+ }
257
+ /**
258
+ * dlPFC goal-stack boost. Applies the multi-goal boost to entry-backed scored
259
+ * rows when (tenant, session) has active goals and returns the log rows to
260
+ * write, without writing them; {@link writeGoalRecallLog} persists them.
261
+ *
262
+ * Caller responsibilities:
263
+ * - Do NOT call when an explicit `goalTag` is set (caller's gate)
264
+ * - Pass entry-backed rows (with `entry.tags`, `entry.id`, optional
265
+ * `entry.schema_fit`)
266
+ * - Manage the db handle lifecycle (helper neither opens nor closes)
267
+ * - Recompute `tokens` after if returned rows are projected to a budgeted
268
+ * shape
269
+ *
270
+ * Log rows cover the top `limit` boosted rows that live in this store's
271
+ * `memories` table (global-only ids are skipped to keep the FK on
272
+ * goal_recall_log.memory_id valid).
273
+ *
274
+ * @internal Recall ranking helper. Subject to change.
275
+ */
276
+ export function computeGoalStackBoost(db, results, opts) {
277
+ const { sessionId, tenantId, trace } = opts;
278
+ const active = getActiveGoalsWithDb(db, { sessionId, tenantId });
279
+ if (active.length === 0)
280
+ return { results, log: [] };
281
+ const goalsByTag = new Map(active.map((g) => [g.goalName, g]));
282
+ const policiesByGoalId = loadGoalPolicies(db, active);
283
+ // Goal-tag matches per boosted row, keyed by entry id. Kept as a side table
284
+ // (rather than a spread-on `_goalMatches` marker property) so `boosted`
285
+ // stays exactly R[] end to end, with no cast-tag-then-strip round trip.
286
+ const matchesByEntryId = new Map();
287
+ const boosted = results
288
+ .map((r) => {
289
+ const tags = r.entry.tags ?? [];
290
+ const matches = tags.filter((t) => goalsByTag.has(t));
291
+ if (matches.length === 0)
292
+ return r;
293
+ const multiplier = goalBoostMultiplier(r.entry, tags, matches, goalsByTag, policiesByGoalId);
294
+ // Recall-trace side-channel: record the goal-boost step BEFORE the
295
+ // score is mutated, keyed by entry id; a pure read of r.score.
296
+ if (trace) {
297
+ trace.set(r.entry.id, {
298
+ stage: 'goal-boost',
299
+ multiplier,
300
+ scoreBefore: r.score,
301
+ scoreAfter: r.score * multiplier,
302
+ note: matches.join(', '),
303
+ });
304
+ }
305
+ matchesByEntryId.set(r.entry.id, matches);
306
+ // SAFETY: spreading a generic-constrained `r: R` widens the result to
307
+ // the spread's plain object type; only `score` changes, so the value
308
+ // still satisfies R's shape exactly.
309
+ return { ...r, score: r.score * multiplier };
310
+ })
311
+ // Deliberately a PLAIN stable score sort, no compareEntryIdentity
312
+ // tail -- a re-sort of an already deterministically-ordered ranking
313
+ // inherits its determinism via sort stability, and ties preserve the
314
+ // prior (meaningful) rank instead of reordering by content.
315
+ .sort((a, b) => b.score - a.score);
316
+ return { results: boosted, log: buildGoalRecallLog(db, boosted, matchesByEntryId, goalsByTag, opts) };
305
317
  }
306
318
  /**
307
319
  * Writes goal-boost log rows. INSERT OR IGNORE because UNIQUE(memory_id, goal_id)
@@ -16,7 +16,7 @@ export declare function loadRelations(hippoRoot: string, tenantId: string, opts?
16
16
  limit?: number;
17
17
  }, txDb?: GraphTxDb): Relation[];
18
18
  /**
19
- * Map consolidated source memory ids -> their graph entities. The SEED step of E3.2
19
+ * Map consolidated source memory ids -> their graph entities. The SEED step of
20
20
  * multi-hop recall (recall result memory ids -> entities to traverse from). Tenant-
21
21
  * scoped, read-only; chunks the IN-list under the SQLite variable cap.
22
22
  */
@@ -28,7 +28,7 @@ export declare function loadEntitiesByMemoryId(hippoRoot: string, tenantId: stri
28
28
  export declare function loadEntitiesByIds(hippoRoot: string, tenantId: string, ids: number[], txDb?: GraphTxDb): Entity[];
29
29
  /**
30
30
  * All relations touching ANY of `entityIds` in EITHER direction (from OR to) — the
31
- * per-hop neighbour query for E3.2 multi-hop traversal. ONE query for the whole frontier
31
+ * per-hop neighbour query for multi-hop traversal. ONE query for the whole frontier
32
32
  * (not one per node): this is the bidirectional read `loadRelations` (from-only) lacks,
33
33
  * and avoids an N+1 across BFS frontier nodes. `limit` caps rows for the frontier and
34
34
  * must be a non-negative integer (the raw `LIMIT ?` rejects a fractional value).
@@ -98,14 +98,14 @@ export function loadRelations(hippoRoot, tenantId, opts = {}, txDb) {
98
98
  }
99
99
  }
100
100
  // ---------------------------------------------------------------------------
101
- // E3.2 multi-hop recall read helpers (SELECT-only; the check-graph-writes lint
101
+ // Multi-hop recall read helpers (SELECT-only; the check-graph-writes lint
102
102
  // permits these here and in the read-only consumer src/graph-recall.ts).
103
103
  // ---------------------------------------------------------------------------
104
104
  /** Chunk size for IN-list queries: well under SQLite's 999-bound-variable default
105
105
  * (leaves headroom for the tenant_id param + the doubled list in neighbour lookups). */
106
106
  const IN_LIST_CHUNK = 400;
107
107
  /**
108
- * Map consolidated source memory ids -> their graph entities. The SEED step of E3.2
108
+ * Map consolidated source memory ids -> their graph entities. The SEED step of
109
109
  * multi-hop recall (recall result memory ids -> entities to traverse from). Tenant-
110
110
  * scoped, read-only; chunks the IN-list under the SQLite variable cap.
111
111
  */
@@ -119,8 +119,7 @@ export function loadEntitiesByMemoryId(hippoRoot, tenantId, memoryIds) {
119
119
  for (let i = 0; i < memoryIds.length; i += IN_LIST_CHUNK) {
120
120
  const slice = memoryIds.slice(i, i + IN_LIST_CHUNK);
121
121
  const ph = slice.map(() => '?').join(',');
122
- // T2: no ORDER BY meant chunk-local scan order decided ties; id ASC
123
- // makes it deterministic (entities.id is an autoincrement integer PK).
122
+ // id ASC so chunk-local scan order never decides ties (id is an autoincrement PK).
124
123
  // SAFETY: rows' shape matches the columns named in ENTITY_COLS above.
125
124
  const rows = db.prepare(`
126
125
  SELECT ${ENTITY_COLS} FROM entities
@@ -166,7 +165,7 @@ export function loadEntitiesByIds(hippoRoot, tenantId, ids, txDb) {
166
165
  }
167
166
  /**
168
167
  * All relations touching ANY of `entityIds` in EITHER direction (from OR to) — the
169
- * per-hop neighbour query for E3.2 multi-hop traversal. ONE query for the whole frontier
168
+ * per-hop neighbour query for multi-hop traversal. ONE query for the whole frontier
170
169
  * (not one per node): this is the bidirectional read `loadRelations` (from-only) lacks,
171
170
  * and avoids an N+1 across BFS frontier nodes. `limit` caps rows for the frontier and
172
171
  * must be a non-negative integer (the raw `LIMIT ?` rejects a fractional value).
@@ -183,7 +182,7 @@ export function loadNeighborRelations(hippoRoot, tenantId, entityIds, opts = {},
183
182
  const db = txDb ?? ownDb;
184
183
  try {
185
184
  // `limit` is applied PER CHUNK; a frontier spanning >IN_LIST_CHUNK ids could return
186
- // up to limit*chunks rows before the by-id dedup below. Harmless for E3.2 (the
185
+ // up to limit*chunks rows before the by-id dedup below. Harmless for multi-hop recall (the
187
186
  // frontier is bounded by maxNeighbors <= 200 << IN_LIST_CHUNK, so a single chunk,
188
187
  // and the BFS re-enforces the per-hop fanout cap), but note the semantics if a
189
188
  // tighter total cap is ever needed.
@@ -8,10 +8,10 @@ export type RelationType = 'owns' | 'supersedes' | 'depends-on' | 'blocked-by' |
8
8
  export type GraphQueueStatus = 'pending' | 'processed' | 'skipped';
9
9
  /** The consolidated source kinds the graph is permitted to index (never 'raw'). */
10
10
  export type SourceKind = 'distilled' | 'superseded';
11
- /** The authoritative E2 object types a graph row may be anchored to (the object
11
+ /** The authoritative first-class object types a graph row may be anchored to (the object
12
12
  * provenance path, alongside the memory path). Maps to source_object_type. */
13
13
  export type SourceObjectType = 'decision' | 'policy' | 'customer' | 'project';
14
- /** A soft (type,id) pointer to the authoritative E2 row a graph row descends from.
14
+ /** A soft (type,id) pointer to the authoritative object row a graph row descends from.
15
15
  * Survives a mirror memory forget/prune (memory_id may go NULL); the rebuild
16
16
  * re-validates it (it is not a hard FK). */
17
17
  export interface SourceObjectRef {
@@ -32,8 +32,8 @@ export interface Entity {
32
32
  * its source_object provenance. */
33
33
  memoryId: string | null;
34
34
  sourceKind: SourceKind;
35
- /** The authoritative E2 object this entity is anchored to (E2-provenance path).
36
- * Set for E2-sourced entities; absent for memory-only (prose/NLP) entities. */
35
+ /** The authoritative object this entity is anchored to (object-provenance path).
36
+ * Set for object-sourced entities; absent for memory-only (prose/NLP) entities. */
37
37
  sourceObjectType?: SourceObjectType;
38
38
  sourceObjectId?: number;
39
39
  createdAt: string;
@@ -64,9 +64,9 @@ export interface InsertEntityOpts {
64
64
  entityType: EntityType;
65
65
  name: string;
66
66
  /** A consolidated (distilled/superseded) memory; raw is rejected. NULL/omitted when
67
- * the entity is anchored only to its E2 source object (mirror forgotten/pruned). */
67
+ * the entity is anchored only to its source object (mirror forgotten/pruned). */
68
68
  memoryId?: string | null;
69
- /** The authoritative E2 object this entity descends from. Required when memoryId is
69
+ /** The authoritative object this entity descends from. Required when memoryId is
70
70
  * null; optional alongside a live memory (both paths may be set). */
71
71
  sourceObject?: SourceObjectRef;
72
72
  }
@@ -75,9 +75,9 @@ export interface InsertRelationOpts {
75
75
  toEntityId: number;
76
76
  relType: RelationType;
77
77
  /** A consolidated (distilled/superseded) memory; raw is rejected. NULL/omitted when
78
- * the relation is anchored only to its E2 source object. */
78
+ * the relation is anchored only to its source object. */
79
79
  memoryId?: string | null;
80
- /** The authoritative E2 object this relation descends from. */
80
+ /** The authoritative object this relation descends from. */
81
81
  sourceObject?: SourceObjectRef;
82
82
  }
83
83
  //# sourceMappingURL=types.d.ts.map
@@ -1,6 +1,5 @@
1
1
  /**
2
- * E3.3 graph layer over consolidated state - the graph-on-consolidated guard.
3
- * (docs/plans/2026-06-01-e3-graph-guard.md).
2
+ * Graph layer over consolidated state - the graph-on-consolidated guard.
4
3
  *
5
4
  * A graph of canonical `entities` (person/project/customer/system/policy/decision) and
6
5
  * `relations` (owns/supersedes/depends-on/blocked-by/references) sits ON TOP OF
@@ -11,11 +10,6 @@
11
10
  * actual kind and enforce tenant-match - relations also reject cross-tenant edges), so
12
11
  * the forbidden state is unrepresentable regardless of code path. These helpers
13
12
  * surface the same guard as clear throws BEFORE hitting the trigger backstop.
14
- *
15
- * Scope (E3.3 first slice): the substrate + the guard + a thin insert/load/enqueue
16
- * API. The `graph_extraction_queue` is the interface the deferred `hippo sleep`
17
- * enqueue-hook + E3.1 entity extraction will call. No operator surface (CLI/HTTP/SDK)
18
- * until E3.2 multi-hop recall.
19
13
  */
20
14
  import { type GraphTxDb, type SourceObjectType, type Entity, type Relation, type GraphQueueItem, type InsertEntityOpts, type InsertRelationOpts } from './types.js';
21
15
  /**
@@ -30,8 +24,7 @@ export declare function insertEntity(hippoRoot: string, tenantId: string, opts:
30
24
  export declare function insertRelation(hippoRoot: string, tenantId: string, opts: InsertRelationOpts, txDb?: GraphTxDb): Relation;
31
25
  /**
32
26
  * Enqueue a consolidated memory for later graph extraction. Rejects a raw / missing /
33
- * cross-tenant memory (the DB trigger is the backstop). The producer hook in
34
- * `hippo sleep` is deferred (E3.1); this is the API it will call.
27
+ * cross-tenant memory (the DB trigger is the backstop).
35
28
  */
36
29
  export declare function enqueueExtraction(hippoRoot: string, tenantId: string, memoryId: string): GraphQueueItem;
37
30
  /**
@@ -46,7 +39,7 @@ export declare function markExtractionProcessed(hippoRoot: string, tenantId: str
46
39
  * the number of entities deleted. The rebuild primitive for graph extraction: the
47
40
  * deterministic graph is a pure derived function of the consolidated objects, so an
48
41
  * extract clears then re-derives. Lives in graph.ts (the sole sanctioned graph
49
- * writer), so the E3.3 CI lint permits this `DELETE FROM entities`. Does NOT touch
42
+ * writer), so the CI lint permits this `DELETE FROM entities`. Does NOT touch
50
43
  * graph_extraction_queue (the enqueue-hook's domain).
51
44
  */
52
45
  export declare function clearGraph(hippoRoot: string, tenantId: string, txDb?: GraphTxDb): number;
@@ -63,19 +56,19 @@ export declare function runGraphRebuildTransaction<T>(hippoRoot: string, tenantI
63
56
  /**
64
57
  * Fail-soft producer hook: mark a tenant dirty for graph re-extraction by
65
58
  * enqueuing its consolidated mirror memory. NEVER throws into the caller — a
66
- * graph-dirty signal failing must not abort a core E2 write. Graph staleness is
59
+ * graph-dirty signal failing must not abort a core object write. Graph staleness is
67
60
  * recoverable (next sleep / manual `graph extract`); a broken `hippo decide` is
68
- * not. Called POST-COMMIT from the E2 graph-source save/close mutations of
61
+ * not. Called POST-COMMIT from the graph-source save/close mutations of
69
62
  * decision, policy, customer_note and project_brief. A null memoryId (a
70
63
  * forgotten mirror) is a no-op.
71
64
  */
72
65
  export declare function markGraphDirty(hippoRoot: string, tenantId: string, memoryId: string | null): void;
73
66
  /**
74
- * Remove the graph rows sourced from one E2 object, by its (type, id). Used when a
67
+ * Remove the graph rows sourced from one first-class object, by its (type, id). Used when a
75
68
  * MIRRORLESS object is closed: it has no mirror memory, so `markGraphDirty` cannot
76
69
  * enqueue a rebuild (the queue is memory-keyed). Closing must still drop the object's
77
70
  * now-stale entity + edges from the graph, so we remove them directly here. Fail-soft
78
- * like `markGraphDirty` (never throws into the E2 close caller; graph staleness is
71
+ * like `markGraphDirty` (never throws into the object close caller; graph staleness is
79
72
  * recoverable). Deleting the entity cascade-deletes any relation where it is an endpoint
80
73
  * (relations FK entities ON DELETE CASCADE); the explicit relations DELETE also covers a
81
74
  * relation whose OWN provenance is this object (defensive — every such edge has the object
@@ -1,6 +1,5 @@
1
1
  /**
2
- * E3.3 graph layer over consolidated state - the graph-on-consolidated guard.
3
- * (docs/plans/2026-06-01-e3-graph-guard.md).
2
+ * Graph layer over consolidated state - the graph-on-consolidated guard.
4
3
  *
5
4
  * A graph of canonical `entities` (person/project/customer/system/policy/decision) and
6
5
  * `relations` (owns/supersedes/depends-on/blocked-by/references) sits ON TOP OF
@@ -11,11 +10,6 @@
11
10
  * actual kind and enforce tenant-match - relations also reject cross-tenant edges), so
12
11
  * the forbidden state is unrepresentable regardless of code path. These helpers
13
12
  * surface the same guard as clear throws BEFORE hitting the trigger backstop.
14
- *
15
- * Scope (E3.3 first slice): the substrate + the guard + a thin insert/load/enqueue
16
- * API. The `graph_extraction_queue` is the interface the deferred `hippo sleep`
17
- * enqueue-hook + E3.1 entity extraction will call. No operator surface (CLI/HTTP/SDK)
18
- * until E3.2 multi-hop recall.
19
13
  */
20
14
  import { openHippoDb, closeHippoDb } from '../db.js';
21
15
  import { assertTenantId } from '../tenant.js';
@@ -37,9 +31,9 @@ function resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, label)
37
31
  const row = db.prepare(`SELECT kind, tenant_id FROM memories WHERE id = ?`).get(memoryId);
38
32
  if (!row) {
39
33
  // Stale / forgotten mirror. Tolerate it IFF a valid source object provides provenance:
40
- // graph-extract reads E2 rows then inserts, and a mirror forgotten/pruned in that window
41
- // must NOT roll back the whole tenant rebuild - the active E2 object survives mirror loss
42
- // (v38 contract; codex round-4 race). Anchor to the object; drop the dead memory pointer.
34
+ // graph-extract reads object rows then inserts, and a mirror forgotten/pruned in that window
35
+ // must NOT roll back the whole tenant rebuild - the active object survives mirror loss.
36
+ // Anchor to the object; drop the dead memory pointer.
43
37
  if (sourceObject == null) {
44
38
  throw new Error(`${label}: source memory ${memoryId} not found`);
45
39
  }
@@ -58,8 +52,8 @@ function resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, label)
58
52
  memKind = row.kind;
59
53
  }
60
54
  }
61
- // Validate the object pointer WHENEVER it is provided - not only when memory is null
62
- // (codex review): a dual-set row whose object is wrong/closed/cross-tenant would become
55
+ // Validate the object pointer WHENEVER it is provided, not only when memory is null:
56
+ // a dual-set row whose object is wrong/closed/cross-tenant would become
63
57
  // the active provenance after ON DELETE SET NULL and could then block the memory delete.
64
58
  if (sourceObject != null) {
65
59
  const table = SOURCE_OBJECT_TABLE[sourceObject.type];
@@ -79,7 +73,7 @@ function resolveConsolidatedSource(db, tenantId, memoryId, sourceObject, label)
79
73
  }
80
74
  }
81
75
  // source_kind is the memory's kind when a memory is present, else 'distilled' for an
82
- // object-only row (E2 objects are consolidated by construction). All-null is rejected.
76
+ // object-only row (objects are consolidated by construction). All-null is rejected.
83
77
  if (memKind != null)
84
78
  return { sourceKind: memKind, memoryId: effectiveMemoryId };
85
79
  if (sourceObject != null)
@@ -170,12 +164,11 @@ export function insertRelation(hippoRoot, tenantId, opts, txDb) {
170
164
  }
171
165
  }
172
166
  // ---------------------------------------------------------------------------
173
- // Extraction queue (the interface the deferred sleep enqueue-hook + E3.1 will use)
167
+ // Extraction queue
174
168
  // ---------------------------------------------------------------------------
175
169
  /**
176
170
  * Enqueue a consolidated memory for later graph extraction. Rejects a raw / missing /
177
- * cross-tenant memory (the DB trigger is the backstop). The producer hook in
178
- * `hippo sleep` is deferred (E3.1); this is the API it will call.
171
+ * cross-tenant memory (the DB trigger is the backstop).
179
172
  */
180
173
  export function enqueueExtraction(hippoRoot, tenantId, memoryId) {
181
174
  assertTenantId('enqueueExtraction', tenantId);
@@ -241,7 +234,7 @@ export function markExtractionProcessed(hippoRoot, tenantId, id, status = 'proce
241
234
  * the number of entities deleted. The rebuild primitive for graph extraction: the
242
235
  * deterministic graph is a pure derived function of the consolidated objects, so an
243
236
  * extract clears then re-derives. Lives in graph.ts (the sole sanctioned graph
244
- * writer), so the E3.3 CI lint permits this `DELETE FROM entities`. Does NOT touch
237
+ * writer), so the CI lint permits this `DELETE FROM entities`. Does NOT touch
245
238
  * graph_extraction_queue (the enqueue-hook's domain).
246
239
  */
247
240
  export function clearGraph(hippoRoot, tenantId, txDb) {
@@ -292,14 +285,14 @@ export function runGraphRebuildTransaction(hippoRoot, tenantId, fn) {
292
285
  }
293
286
  }
294
287
  // ---------------------------------------------------------------------------
295
- // E3 sleep enqueue-hook — producer helper + drain support
288
+ // Sleep enqueue-hook: producer helper + drain support
296
289
  // ---------------------------------------------------------------------------
297
290
  /**
298
291
  * Fail-soft producer hook: mark a tenant dirty for graph re-extraction by
299
292
  * enqueuing its consolidated mirror memory. NEVER throws into the caller — a
300
- * graph-dirty signal failing must not abort a core E2 write. Graph staleness is
293
+ * graph-dirty signal failing must not abort a core object write. Graph staleness is
301
294
  * recoverable (next sleep / manual `graph extract`); a broken `hippo decide` is
302
- * not. Called POST-COMMIT from the E2 graph-source save/close mutations of
295
+ * not. Called POST-COMMIT from the graph-source save/close mutations of
303
296
  * decision, policy, customer_note and project_brief. A null memoryId (a
304
297
  * forgotten mirror) is a no-op.
305
298
  */
@@ -311,16 +304,16 @@ export function markGraphDirty(hippoRoot, tenantId, memoryId) {
311
304
  }
312
305
  catch (err) {
313
306
  // Logged (warn) so a SYSTEMATIC enqueue failure surfaces to operators, but
314
- // swallowed so the already-committed E2 write is never rolled back.
307
+ // swallowed so the already-committed object write is never rolled back.
315
308
  log.warn(`markGraphDirty: enqueue failed for tenant=${tenantId} memory=${memoryId}: ${err instanceof Error ? err.message : String(err)}`);
316
309
  }
317
310
  }
318
311
  /**
319
- * Remove the graph rows sourced from one E2 object, by its (type, id). Used when a
312
+ * Remove the graph rows sourced from one first-class object, by its (type, id). Used when a
320
313
  * MIRRORLESS object is closed: it has no mirror memory, so `markGraphDirty` cannot
321
314
  * enqueue a rebuild (the queue is memory-keyed). Closing must still drop the object's
322
315
  * now-stale entity + edges from the graph, so we remove them directly here. Fail-soft
323
- * like `markGraphDirty` (never throws into the E2 close caller; graph staleness is
316
+ * like `markGraphDirty` (never throws into the object close caller; graph staleness is
324
317
  * recoverable). Deleting the entity cascade-deletes any relation where it is an endpoint
325
318
  * (relations FK entities ON DELETE CASCADE); the explicit relations DELETE also covers a
326
319
  * relation whose OWN provenance is this object (defensive — every such edge has the object
@@ -1,16 +1,15 @@
1
1
  /**
2
- * E3.1 deterministic entity extraction (first slice)
3
- * (docs/plans/2026-06-01-e3-deterministic-extraction.md).
2
+ * Deterministic entity extraction.
4
3
  *
5
- * Populates the E3 graph from the already-structured consolidated E2-object tables -
4
+ * Populates the graph from the already-structured consolidated first-class object tables -
6
5
  * NO NLP, no precision gate for entities + supersedes. The graph is a pure derived
7
- * function of the current E2 state, so `extractGraph` is an idempotent REBUILD: clear
6
+ * function of the current object state, so `extractGraph` is an idempotent REBUILD: clear
8
7
  * the tenant's graph, then re-derive entities + `supersedes` relations from decisions /
9
- * policies / customer_notes / project_briefs (the four E2 types whose kind maps to the
8
+ * policies / customer_notes / project_briefs (the four object types whose kind maps to the
10
9
  * `entity_type` enum). All writes go through the src/graph.ts consolidated-source guard
11
10
  * (insertEntity / insertRelation / clearGraph); this module issues no raw SQL.
12
11
  *
13
- * Pass 3 (E3 cross-object, docs/plans/2026-06-02-e3-cross-object-references.md) adds the
12
+ * Pass 3 adds the
14
13
  * first CROSS-OBJECT relations: a deterministic NAME-MATCH heuristic that emits a
15
14
  * `references` edge when one consolidated object's text contains another entity's name.
16
15
  * It is conservative (word-boundary, length-bounded, ambiguity-guarded, per-source
@@ -47,9 +46,9 @@ export interface ExtractResult {
47
46
  truncated: string[];
48
47
  }
49
48
  /**
50
- * Idempotent rebuild of the tenant's deterministic graph from its consolidated E2
49
+ * Idempotent rebuild of the tenant's deterministic graph from its consolidated first-class
51
50
  * objects. Returns the entity/relation counts (+ which types were truncated at the
52
- * per-type cap). Safe to re-run: output is a pure function of the current E2 state.
51
+ * per-type cap). Safe to re-run: output is a pure function of the current object state.
53
52
  */
54
53
  export declare function extractGraph(hippoRoot: string, tenantId: string): ExtractResult;
55
54
  //# sourceMappingURL=graph-extract.d.ts.map