hippo-memory 1.62.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 (370) hide show
  1. package/README.md +9 -0
  2. package/dist/agent-memories/apply.d.ts +2 -0
  3. package/dist/agent-memories/apply.js +23 -1
  4. package/dist/agent-memories/claude-code.d.ts +2 -1
  5. package/dist/agent-memories/claude-code.js +4 -4
  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.js +37 -23
  9. package/dist/ambient-store.d.ts +4 -4
  10. package/dist/ambient-store.js +4 -3
  11. package/dist/api/assemble.d.ts +7 -10
  12. package/dist/api/assemble.js +7 -12
  13. package/dist/api/audit.d.ts +2 -2
  14. package/dist/api/audit.js +2 -2
  15. package/dist/api/auth.d.ts +6 -6
  16. package/dist/api/auth.js +5 -7
  17. package/dist/api/context-select.d.ts +4 -3
  18. package/dist/api/context-select.js +9 -11
  19. package/dist/api/context-types.d.ts +12 -17
  20. package/dist/api/context.d.ts +3 -2
  21. package/dist/api/context.js +20 -20
  22. package/dist/api/dormant.js +1 -1
  23. package/dist/api/drill-down.d.ts +4 -4
  24. package/dist/api/drill-down.js +22 -10
  25. package/dist/api/outcome.d.ts +8 -13
  26. package/dist/api/outcome.js +13 -17
  27. package/dist/api/promote.d.ts +5 -8
  28. package/dist/api/quarantine.js +3 -2
  29. package/dist/api/recall-types.d.ts +43 -55
  30. package/dist/api/recall.d.ts +3 -3
  31. package/dist/api/recall.js +7 -18
  32. package/dist/api/remember.d.ts +2 -2
  33. package/dist/api/sleep.d.ts +7 -35
  34. package/dist/api/sleep.js +3 -2
  35. package/dist/api/tokens.d.ts +2 -2
  36. package/dist/api/tokens.js +2 -2
  37. package/dist/api/types.d.ts +6 -10
  38. package/dist/api/types.js +2 -4
  39. package/dist/audit-prune.d.ts +4 -6
  40. package/dist/audit-prune.js +3 -5
  41. package/dist/audit.js +11 -33
  42. package/dist/auth.d.ts +8 -9
  43. package/dist/auth.js +5 -7
  44. package/dist/autolearn.d.ts +1 -1
  45. package/dist/autolearn.js +1 -1
  46. package/dist/availability.js +3 -5
  47. package/dist/capture/command.d.ts +5 -4
  48. package/dist/capture/command.js +8 -22
  49. package/dist/capture/compact.d.ts +1 -1
  50. package/dist/capture/compact.js +9 -13
  51. package/dist/capture/extract.js +37 -115
  52. package/dist/capture-error.d.ts +1 -1
  53. package/dist/capture-error.js +1 -1
  54. package/dist/churn-git.d.ts +1 -1
  55. package/dist/churn-git.js +1 -1
  56. package/dist/cli/audit.js +3 -4
  57. package/dist/cli/auth.js +3 -6
  58. package/dist/cli/curate.d.ts +1 -1
  59. package/dist/cli/curate.js +8 -24
  60. package/dist/cli/dag.js +5 -9
  61. package/dist/cli/decisions.js +10 -21
  62. package/dist/cli/explain.js +2 -1
  63. package/dist/cli/goals.js +1 -1
  64. package/dist/cli/init.js +1 -1
  65. package/dist/cli/playbooks.js +4 -9
  66. package/dist/cli/projects.js +3 -1
  67. package/dist/cli/recall.js +2 -1
  68. package/dist/cli/remember.js +6 -18
  69. package/dist/cli/session-hooks.js +21 -40
  70. package/dist/cli/setup.d.ts +1 -1
  71. package/dist/cli/setup.js +2 -6
  72. package/dist/cli/shared.js +3 -3
  73. package/dist/cli/slack.js +1 -1
  74. package/dist/cli/sleep.js +27 -1
  75. package/dist/cli/status.d.ts +4 -4
  76. package/dist/cli/status.js +7 -12
  77. package/dist/cli/transfer.js +8 -13
  78. package/dist/cli/usage.js +9 -6
  79. package/dist/cli.d.ts +1 -1
  80. package/dist/cli.js +4 -9
  81. package/dist/compaction-record.d.ts +2 -0
  82. package/dist/compaction-record.js +89 -68
  83. package/dist/compare.d.ts +11 -16
  84. package/dist/compare.js +11 -16
  85. package/dist/config.d.ts +19 -18
  86. package/dist/config.js +90 -67
  87. package/dist/connectors/github/backfill.d.ts +2 -2
  88. package/dist/connectors/github/backfill.js +8 -15
  89. package/dist/connectors/github/cli-impl.js +3 -8
  90. package/dist/connectors/github/deletion.d.ts +5 -12
  91. package/dist/connectors/github/deletion.js +5 -12
  92. package/dist/connectors/github/dlq.d.ts +6 -9
  93. package/dist/connectors/github/dlq.js +2 -3
  94. package/dist/connectors/github/ingest.d.ts +5 -7
  95. package/dist/connectors/github/ingest.js +8 -12
  96. package/dist/connectors/github/octokit-client.d.ts +3 -5
  97. package/dist/connectors/github/octokit-client.js +5 -6
  98. package/dist/connectors/github/signature.d.ts +9 -39
  99. package/dist/connectors/github/signature.js +9 -39
  100. package/dist/connectors/github/tenant-routing.d.ts +1 -1
  101. package/dist/connectors/github/tenant-routing.js +1 -1
  102. package/dist/connectors/github/transform.js +2 -2
  103. package/dist/connectors/github/types.d.ts +2 -10
  104. package/dist/connectors/github/types.js +1 -3
  105. package/dist/connectors/slack/deletion.d.ts +3 -8
  106. package/dist/connectors/slack/deletion.js +3 -8
  107. package/dist/connectors/slack/dlq.d.ts +1 -1
  108. package/dist/connectors/slack/ingest.d.ts +1 -1
  109. package/dist/connectors/slack/ingest.js +7 -16
  110. package/dist/connectors/slack/signature.d.ts +1 -1
  111. package/dist/connectors/slack/tenant-routing.d.ts +3 -5
  112. package/dist/connectors/slack/tenant-routing.js +3 -5
  113. package/dist/connectors/slack/transform.d.ts +5 -6
  114. package/dist/connectors/slack/transform.js +5 -6
  115. package/dist/connectors/slack/types.d.ts +2 -6
  116. package/dist/connectors/slack/types.js +1 -3
  117. package/dist/connectors/slack/web-client.js +10 -3
  118. package/dist/connectors/slack/workspaces.d.ts +3 -5
  119. package/dist/connectors/slack/workspaces.js +3 -5
  120. package/dist/consolidate/conflicts.js +3 -14
  121. package/dist/consolidate/decay.js +9 -29
  122. package/dist/consolidate/llm-passes.js +4 -5
  123. package/dist/consolidate/merge.js +8 -23
  124. package/dist/consolidate/run.d.ts +1 -8
  125. package/dist/consolidate/run.js +3 -25
  126. package/dist/consolidate/sleep.js +5 -17
  127. package/dist/consolidate/traces.js +9 -21
  128. package/dist/customer-notes.d.ts +5 -7
  129. package/dist/customer-notes.js +6 -9
  130. package/dist/dag.d.ts +10 -21
  131. package/dist/dag.js +23 -73
  132. package/dist/db/continuity.js +2 -2
  133. package/dist/db/migrations/v14.js +1 -1
  134. package/dist/db/migrations/v15.js +1 -2
  135. package/dist/db/migrations/v16.js +3 -4
  136. package/dist/db/migrations/v17.js +2 -3
  137. package/dist/db/migrations/v19.js +1 -1
  138. package/dist/db/migrations/v20.js +1 -1
  139. package/dist/db/migrations/v21.js +2 -6
  140. package/dist/db/migrations/v22.js +2 -4
  141. package/dist/db/migrations/v23.js +1 -1
  142. package/dist/db/migrations/v24.js +4 -6
  143. package/dist/db/migrations/v25.js +2 -3
  144. package/dist/db/migrations/v26.js +3 -3
  145. package/dist/db/migrations/v27.js +2 -10
  146. package/dist/db/migrations/v28.js +5 -8
  147. package/dist/db/migrations/v29.js +3 -4
  148. package/dist/db/migrations/v30.js +2 -2
  149. package/dist/db/migrations/v31.js +1 -1
  150. package/dist/db/migrations/v32.js +1 -1
  151. package/dist/db/migrations/v33.js +3 -3
  152. package/dist/db/migrations/v34.js +1 -1
  153. package/dist/db/migrations/v35.js +3 -4
  154. package/dist/db/migrations/v36.js +3 -4
  155. package/dist/db/migrations/v37.js +5 -5
  156. package/dist/db/migrations/v38.js +7 -8
  157. package/dist/db/migrations/v39.js +1 -1
  158. package/dist/db/migrations/v40.js +4 -16
  159. package/dist/db/migrations/v41.js +3 -4
  160. package/dist/db/migrations/v42.js +3 -4
  161. package/dist/db/migrations/v45.js +1 -1
  162. package/dist/db/migrations/v46.js +1 -1
  163. package/dist/db/migrations/v47.js +1 -1
  164. package/dist/db/migrations/v48.js +1 -1
  165. package/dist/decisions.d.ts +2 -2
  166. package/dist/decisions.js +6 -6
  167. package/dist/dedupe.js +86 -61
  168. package/dist/delivery-recorder.js +154 -135
  169. package/dist/doctor.js +119 -104
  170. package/dist/dormant.js +1 -4
  171. package/dist/embedding-provider.d.ts +4 -8
  172. package/dist/embedding-provider.js +4 -8
  173. package/dist/embeddings.js +55 -47
  174. package/dist/env.d.ts +1 -1
  175. package/dist/env.js +12 -12
  176. package/dist/escape.d.ts +5 -0
  177. package/dist/escape.js +10 -0
  178. package/dist/eval-stats.d.ts +1 -2
  179. package/dist/eval-stats.js +1 -2
  180. package/dist/eval-suite.js +27 -21
  181. package/dist/extract.js +4 -9
  182. package/dist/failure-log.d.ts +3 -3
  183. package/dist/failure-log.js +1 -1
  184. package/dist/forward-claim-detector.d.ts +2 -4
  185. package/dist/forward-claim-detector.js +6 -11
  186. package/dist/goals.d.ts +3 -3
  187. package/dist/goals.js +5 -6
  188. package/dist/graph/read.d.ts +2 -2
  189. package/dist/graph/read.js +5 -6
  190. package/dist/graph/types.d.ts +8 -8
  191. package/dist/graph/write.d.ts +7 -14
  192. package/dist/graph/write.js +16 -23
  193. package/dist/graph-extract.d.ts +7 -8
  194. package/dist/graph-extract.js +62 -72
  195. package/dist/graph-recall.d.ts +2 -2
  196. package/dist/graph-recall.js +55 -49
  197. package/dist/graph-stream.d.ts +5 -6
  198. package/dist/graph-stream.js +66 -57
  199. package/dist/graph-view.d.ts +2 -2
  200. package/dist/graph-view.js +7 -7
  201. package/dist/half-life-migration.d.ts +1 -2
  202. package/dist/half-life-migration.js +2 -3
  203. package/dist/hooks/codex-session.js +1 -1
  204. package/dist/hooks/codex-wrapper.d.ts +1 -1
  205. package/dist/hooks/codex-wrapper.js +3 -2
  206. package/dist/hooks/json-hooks.d.ts +2 -2
  207. package/dist/hooks/json-hooks.js +5 -4
  208. package/dist/hooks/opencode.d.ts +1 -1
  209. package/dist/hooks/opencode.js +5 -4
  210. package/dist/hooks/shared.d.ts +3 -7
  211. package/dist/hooks/shared.js +1 -8
  212. package/dist/http-util.d.ts +2 -3
  213. package/dist/http-util.js +3 -0
  214. package/dist/importers/core.d.ts +2 -9
  215. package/dist/importers/core.js +15 -30
  216. package/dist/importers/sources.js +2 -1
  217. package/dist/importers/vault.js +2 -20
  218. package/dist/incidents.d.ts +1 -1
  219. package/dist/incidents.js +1 -1
  220. package/dist/instruction-detect.d.ts +1 -1
  221. package/dist/instruction-detect.js +1 -1
  222. package/dist/invalidation.d.ts +3 -0
  223. package/dist/invalidation.js +160 -114
  224. package/dist/json.d.ts +5 -0
  225. package/dist/json.js +4 -0
  226. package/dist/judgment.js +1 -2
  227. package/dist/local-embedding.js +1 -1
  228. package/dist/mcp/admin-tools.js +7 -17
  229. package/dist/mcp/format.js +1 -1
  230. package/dist/mcp/framing.js +3 -6
  231. package/dist/mcp/protocol.d.ts +2 -5
  232. package/dist/mcp/protocol.js +1 -3
  233. package/dist/mcp/recall-tools.js +12 -15
  234. package/dist/mcp/request.js +4 -3
  235. package/dist/mcp/session-state.js +2 -3
  236. package/dist/mcp/stdio.js +2 -1
  237. package/dist/mcp/tools.js +9 -6
  238. package/dist/memory-value-weights.d.ts +5 -8
  239. package/dist/memory-value-weights.js +5 -8
  240. package/dist/memory-value.d.ts +13 -13
  241. package/dist/memory-value.js +26 -37
  242. package/dist/memory.d.ts +20 -22
  243. package/dist/memory.js +24 -48
  244. package/dist/multihop.d.ts +1 -1
  245. package/dist/multihop.js +3 -2
  246. package/dist/owner-validation.d.ts +4 -5
  247. package/dist/owner-validation.js +4 -5
  248. package/dist/physics.d.ts +4 -4
  249. package/dist/physics.js +7 -9
  250. package/dist/policies.d.ts +9 -10
  251. package/dist/policies.js +12 -14
  252. package/dist/postinstall.js +3 -6
  253. package/dist/predictions/planning-fallacy.d.ts +9 -14
  254. package/dist/predictions/planning-fallacy.js +10 -16
  255. package/dist/predictions/store.d.ts +15 -23
  256. package/dist/predictions/store.js +36 -33
  257. package/dist/processes.d.ts +2 -7
  258. package/dist/processes.js +3 -3
  259. package/dist/project-briefs.d.ts +2 -3
  260. package/dist/project-briefs.js +9 -13
  261. package/dist/project-identity.d.ts +22 -9
  262. package/dist/project-identity.js +47 -12
  263. package/dist/project-merge.d.ts +17 -2
  264. package/dist/project-merge.js +109 -27
  265. package/dist/project-remote.d.ts +12 -0
  266. package/dist/project-remote.js +138 -0
  267. package/dist/prompt-recall.js +1 -2
  268. package/dist/rate-limit.d.ts +1 -1
  269. package/dist/rate-limit.js +1 -1
  270. package/dist/raw-archive.d.ts +9 -0
  271. package/dist/raw-archive.js +70 -53
  272. package/dist/recall-history.d.ts +19 -20
  273. package/dist/recall-history.js +24 -42
  274. package/dist/recall-pipeline.js +4 -28
  275. package/dist/recall-scope.d.ts +7 -8
  276. package/dist/recall-scope.js +7 -8
  277. package/dist/recall-trace.d.ts +5 -9
  278. package/dist/recall-trace.js +6 -10
  279. package/dist/refine-llm.d.ts +1 -1
  280. package/dist/refine-llm.js +2 -2
  281. package/dist/reject-flow.d.ts +3 -4
  282. package/dist/reject-flow.js +122 -117
  283. package/dist/rejection.d.ts +5 -6
  284. package/dist/rejection.js +7 -15
  285. package/dist/rerankers/clef.d.ts +1 -1
  286. package/dist/rerankers/jev.d.ts +1 -2
  287. package/dist/rerankers/jev.js +4 -5
  288. package/dist/rerankers/llm.d.ts +1 -2
  289. package/dist/rerankers/llm.js +1 -2
  290. package/dist/rerankers/types.d.ts +1 -2
  291. package/dist/rrf.d.ts +2 -2
  292. package/dist/rrf.js +2 -2
  293. package/dist/search/bm25-search.d.ts +1 -1
  294. package/dist/search/bm25-search.js +2 -1
  295. package/dist/search/boosts.js +2 -1
  296. package/dist/search/hybrid.d.ts +1 -1
  297. package/dist/search/hybrid.js +2 -1
  298. package/dist/search/physics-search.d.ts +1 -1
  299. package/dist/search/physics-search.js +2 -1
  300. package/dist/search/types.d.ts +2 -0
  301. package/dist/search/types.js +3 -1
  302. package/dist/secret-detect.d.ts +4 -5
  303. package/dist/secret-detect.js +6 -10
  304. package/dist/server/auth.js +5 -5
  305. package/dist/server/client-ip.js +1 -1
  306. package/dist/server/cursor.js +2 -1
  307. package/dist/server/mcp-http.js +4 -4
  308. package/dist/server/request.d.ts +3 -6
  309. package/dist/server/request.js +6 -7
  310. package/dist/server/routes/admin.js +5 -4
  311. package/dist/server/routes/customer-notes.js +6 -5
  312. package/dist/server/routes/decisions.js +4 -3
  313. package/dist/server/routes/incidents.js +7 -5
  314. package/dist/server/routes/memories.js +7 -7
  315. package/dist/server/routes/policies.js +3 -2
  316. package/dist/server/routes/predictions.js +12 -15
  317. package/dist/server/routes/processes.js +3 -2
  318. package/dist/server/routes/project-briefs.js +8 -7
  319. package/dist/server/routes/recall.js +95 -93
  320. package/dist/server/routes/skills.js +6 -5
  321. package/dist/server/types.d.ts +1 -1
  322. package/dist/server/validation.d.ts +1 -2
  323. package/dist/server/validation.js +7 -14
  324. package/dist/server-detect.js +72 -58
  325. package/dist/server.d.ts +2 -2
  326. package/dist/server.js +131 -117
  327. package/dist/shared.d.ts +17 -17
  328. package/dist/shared.js +93 -97
  329. package/dist/skills.d.ts +3 -3
  330. package/dist/skills.js +8 -8
  331. package/dist/store/audit-event.d.ts +2 -2
  332. package/dist/store/audit-event.js +1 -1
  333. package/dist/store/candidates.d.ts +2 -2
  334. package/dist/store/candidates.js +4 -3
  335. package/dist/store/conflicts.js +30 -22
  336. package/dist/store/delete-and-batch.d.ts +11 -14
  337. package/dist/store/delete-and-batch.js +40 -91
  338. package/dist/store/entry-reads.d.ts +17 -25
  339. package/dist/store/entry-reads.js +59 -40
  340. package/dist/store/entry-row.d.ts +6 -24
  341. package/dist/store/entry-row.js +6 -24
  342. package/dist/store/entry-writes.d.ts +6 -7
  343. package/dist/store/entry-writes.js +13 -11
  344. package/dist/store/handoffs.d.ts +1 -1
  345. package/dist/store/handoffs.js +7 -10
  346. package/dist/store/index-and-stats.d.ts +2 -6
  347. package/dist/store/index-and-stats.js +4 -10
  348. package/dist/store/mirrors.d.ts +6 -19
  349. package/dist/store/mirrors.js +14 -39
  350. package/dist/store/open.js +9 -31
  351. package/dist/store/rows.d.ts +5 -11
  352. package/dist/store/rows.js +6 -11
  353. package/dist/store/search-rows.d.ts +17 -34
  354. package/dist/store/search-rows.js +31 -59
  355. package/dist/store/sessions.d.ts +4 -5
  356. package/dist/store/sessions.js +5 -6
  357. package/dist/store/summaries.d.ts +13 -17
  358. package/dist/store/summaries.js +26 -70
  359. package/dist/support-bundle.js +4 -8
  360. package/dist/tenant.d.ts +1 -5
  361. package/dist/token-ledger.d.ts +1 -1
  362. package/dist/token-ledger.js +3 -5
  363. package/dist/trace.js +1 -3
  364. package/dist/version.d.ts +1 -1
  365. package/dist/version.js +1 -1
  366. package/dist/working-memory.d.ts +1 -1
  367. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  368. package/extensions/openclaw-plugin/package.json +1 -1
  369. package/openclaw.plugin.json +1 -1
  370. package/package.json +1 -1
@@ -37,17 +37,13 @@ function mem(id, content, opts = {}) {
37
37
  entry.created = opts.created;
38
38
  return entry;
39
39
  }
40
- export function buildSyntheticCorpus() {
41
- const entries = [];
42
- const cases = [];
43
- // =========================================================================
44
- // 1. DIRECT RECALL — basic keyword matching
45
- // =========================================================================
40
+ /** Direct recall: basic keyword matching. */
41
+ function addDirectRecall(entries, cases) {
46
42
  entries.push(mem('dr-1', 'The PostgreSQL database migration failed because the users table had a NOT NULL constraint on the email column', { created: dateOffset(1), tags: ['topic:database'] }), mem('dr-2', 'React component rendering performance improved by 40% after memoizing the expensive computation in useMemo', { created: dateOffset(2), tags: ['topic:frontend'] }), mem('dr-3', 'The API rate limiter should use a sliding window algorithm instead of fixed window to prevent burst traffic', { created: dateOffset(3), tags: ['topic:api'] }), mem('dr-4', 'Docker container memory limits need to be set to 512MB for the worker service to prevent OOM kills', { created: dateOffset(4), tags: ['topic:devops'] }), mem('dr-5', 'The JWT token expiration was set to 24 hours but should be reduced to 1 hour for security compliance', { created: dateOffset(5), tags: ['topic:security'] }), mem('dr-6', 'Webpack bundle size grew to 2.3MB because lodash was imported as a whole instead of cherry-picking', { created: dateOffset(6), tags: ['topic:frontend'] }), mem('dr-7', 'The Redis cache TTL for user sessions should match the JWT expiration to prevent stale sessions', { created: dateOffset(7), tags: ['topic:caching'] }), mem('dr-8', 'GraphQL resolver for nested comments has N+1 query problem solved by DataLoader batching', { created: dateOffset(8), tags: ['topic:api'] }));
47
43
  cases.push({ id: 'dr-q1', category: 'direct-recall', query: 'PostgreSQL migration NOT NULL constraint', expectedIds: ['dr-1'], description: 'exact keyword match on DB migration' }, { id: 'dr-q2', category: 'direct-recall', query: 'React useMemo performance memoizing', expectedIds: ['dr-2'], description: 'React performance optimization' }, { id: 'dr-q3', category: 'direct-recall', query: 'sliding window rate limiter API', expectedIds: ['dr-3'], description: 'API rate limiting approach' }, { id: 'dr-q4', category: 'direct-recall', query: 'Docker OOM memory limits worker', expectedIds: ['dr-4'], description: 'Docker memory config' }, { id: 'dr-q5', category: 'direct-recall', query: 'JWT token expiration security', expectedIds: ['dr-5'], description: 'JWT security setting' }, { id: 'dr-q6', category: 'direct-recall', query: 'webpack bundle size lodash', expectedIds: ['dr-6'], description: 'bundle size issue' }, { id: 'dr-q7', category: 'direct-recall', query: 'Redis cache TTL session expiration', expectedIds: ['dr-7'], description: 'cache TTL config' }, { id: 'dr-q8', category: 'direct-recall', query: 'GraphQL N+1 DataLoader batching', expectedIds: ['dr-8'], description: 'GraphQL N+1 fix' });
48
- // =========================================================================
49
- // 2. EXTRACTION PREFERENCE — extracted facts should rank above raw source
50
- // =========================================================================
44
+ }
45
+ /** Extraction preference: extracted facts should rank above raw source. */
46
+ function addExtractionPreference(entries, cases) {
51
47
  entries.push(mem('ep-src-1', 'speaker:Alice: So we had this big meeting yesterday about the deployment pipeline and Bob mentioned that the staging environment is using Kubernetes 1.28 and we should upgrade to 1.30 before the end of Q2 because of the security patches', {
52
48
  created: dateOffset(10), tags: ['speaker:Alice', 'topic:infrastructure', 'session:meeting-1'],
53
49
  }), mem('ep-ext-1', 'The staging environment runs Kubernetes 1.28 and needs to be upgraded to 1.30 before end of Q2 for security patches', {
@@ -65,9 +61,9 @@ export function buildSyntheticCorpus() {
65
61
  extracted_from: 'ep-src-3',
66
62
  }));
67
63
  cases.push({ id: 'ep-q1', category: 'extraction-preference', query: 'Kubernetes upgrade staging environment', expectedIds: ['ep-ext-1'], description: 'extracted fact about K8s upgrade should rank above raw utterance' }, { id: 'ep-q2', category: 'extraction-preference', query: 'Datadog Grafana alerting migration', expectedIds: ['ep-ext-2'], description: 'extracted fact about monitoring switch' }, { id: 'ep-q3', category: 'extraction-preference', query: 'OAuth2 PKCE login page redesign', expectedIds: ['ep-ext-3'], description: 'extracted fact about auth work' });
68
- // =========================================================================
69
- // 3. DAG DRILL-DOWN — summary nodes should surface children
70
- // =========================================================================
64
+ }
65
+ /** Dag drill-down: summary nodes should surface children. */
66
+ function addDagDrilldown(entries, cases) {
71
67
  entries.push(mem('dag-child-1', 'The API response time for /users endpoint degraded from 50ms to 300ms after adding the permissions check', {
72
68
  created: dateOffset(15), layer: Layer.Semantic, tags: ['topic:api-performance', 'extracted'],
73
69
  dag_level: 1,
@@ -86,14 +82,14 @@ export function buildSyntheticCorpus() {
86
82
  child.dag_parent_id = 'dag-summary-1';
87
83
  }
88
84
  cases.push({ id: 'dag-q1', category: 'dag-drilldown', query: 'API performance problems latency', expectedIds: ['dag-child-1', 'dag-child-2', 'dag-child-3', 'dag-summary-1'], description: 'summary should drill down to all children' }, { id: 'dag-q2', category: 'dag-drilldown', query: 'endpoint response time degradation', expectedIds: ['dag-child-1', 'dag-child-2', 'dag-summary-1'], description: 'query matching summary should surface relevant children' });
89
- // =========================================================================
90
- // 4. TEMPORAL — recency/oldest cues should affect ranking
91
- // =========================================================================
85
+ }
86
+ /** Temporal: recency/oldest cues should affect ranking. */
87
+ function addTemporal(entries, cases) {
92
88
  entries.push(mem('tmp-1', 'The team decided to use TypeScript for the new service', { created: dateOffset(-30), tags: ['topic:architecture'] }), mem('tmp-2', 'The team evaluated Rust as an alternative language for the service', { created: dateOffset(-20), tags: ['topic:architecture'] }), mem('tmp-3', 'The team added Go as a candidate language for the service rewrite', { created: dateOffset(-10), tags: ['topic:architecture'] }), mem('tmp-4', 'The team finalized the language choice as Go for the service rewrite', { created: dateOffset(-1), tags: ['topic:architecture'] }));
93
89
  cases.push({ id: 'tmp-q1', category: 'temporal', query: 'what did the team recently decide about the service language', expectedIds: ['tmp-4'], description: 'recent cue should boost newest entry' }, { id: 'tmp-q2', category: 'temporal', query: 'what was the first language choice for the service', expectedIds: ['tmp-1'], description: 'oldest cue should boost earliest entry' }, { id: 'tmp-q3', category: 'temporal', query: 'latest update on the service rewrite language', expectedIds: ['tmp-4'], description: 'latest should boost most recent' }, { id: 'tmp-q4', category: 'temporal', query: 'original architecture decision for the service', expectedIds: ['tmp-1'], description: 'original should boost earliest' });
94
- // =========================================================================
95
- // 5. NOISE RESISTANCE — relevant memories found despite noise
96
- // =========================================================================
90
+ }
91
+ /** Noise resistance: relevant memories found despite noise. */
92
+ function addNoiseResistance(entries, cases) {
97
93
  // Add 30 noise entries
98
94
  const noiseTopics = [
99
95
  'breakfast meeting catering ordered sandwiches', 'office temperature thermostat adjusted',
@@ -121,9 +117,9 @@ export function buildSyntheticCorpus() {
121
117
  created: dateOffset(21), tags: ['topic:security', 'topic:s3'],
122
118
  }));
123
119
  cases.push({ id: 'nr-q1', category: 'noise-resistance', query: 'database connection pool exhausted max connections', expectedIds: ['nr-1'], description: 'find DB issue despite 30 noise entries' }, { id: 'nr-q2', category: 'noise-resistance', query: 'S3 bucket public access security misconfiguration', expectedIds: ['nr-2'], description: 'find S3 issue despite noise' }, { id: 'nr-q3', category: 'noise-resistance', query: 'PostgreSQL migration constraint', expectedIds: ['dr-1'], description: 'find earlier DB entry despite noise' }, { id: 'nr-q4', category: 'noise-resistance', query: 'JWT token security expiration', expectedIds: ['dr-5'], description: 'find security entry despite noise' });
124
- // =========================================================================
125
- // 6. MULTI-HOP — entity chaining across sessions
126
- // =========================================================================
120
+ }
121
+ /** Multi-hop: entity chaining across sessions. */
122
+ function addMultiHop(entries, cases) {
127
123
  entries.push(mem('mh-1', 'speaker:Alice works on the payment gateway integration with Stripe. She found a webhook signature validation bug.', {
128
124
  created: dateOffset(25), tags: ['speaker:Alice', 'topic:payments'],
129
125
  }), mem('mh-2', 'speaker:Bob reviewed the Stripe webhook code and confirmed the signature validation uses the wrong secret key from the test environment.', {
@@ -134,6 +130,16 @@ export function buildSyntheticCorpus() {
134
130
  created: dateOffset(28), tags: ['speaker:Carol', 'topic:billing'],
135
131
  }));
136
132
  cases.push({ id: 'mh-q1', category: 'multi-hop', query: 'Who fixed the Stripe webhook bug and what was the root cause?', expectedIds: ['mh-1', 'mh-2', 'mh-3'], description: 'chain Alice -> Stripe -> Bob -> fix' }, { id: 'mh-q2', category: 'multi-hop', query: 'What are all the payment-related issues the team discussed?', expectedIds: ['mh-1', 'mh-2', 'mh-3', 'mh-4'], description: 'find all payment topics across speakers' });
133
+ }
134
+ export function buildSyntheticCorpus() {
135
+ const entries = [];
136
+ const cases = [];
137
+ addDirectRecall(entries, cases);
138
+ addExtractionPreference(entries, cases);
139
+ addDagDrilldown(entries, cases);
140
+ addTemporal(entries, cases);
141
+ addNoiseResistance(entries, cases);
142
+ addMultiHop(entries, cases);
137
143
  return { entries, cases };
138
144
  }
139
145
  // ---------------------------------------------------------------------------
package/dist/extract.js CHANGED
@@ -6,9 +6,7 @@ import { redactSecretsStrict } from './secret-detect.js';
6
6
  import { fetchWithRetry, llmTimeoutMs } from './http-retry.js';
7
7
  import { neverAutoShareTags } from './shared.js';
8
8
  import { log } from './log.js';
9
- function isJsonString(value) {
10
- return typeof value === 'string';
11
- }
9
+ import { isJsonString } from './json.js';
12
10
  const EXTRACTION_PROMPT = `You are extracting factual statements from a conversation or memory entry. Extract 1-8 standalone factual statements that would be useful to remember later.
13
11
 
14
12
  Rules:
@@ -101,15 +99,12 @@ export function storeExtractedFacts(hippoRoot, source, facts) {
101
99
  source: source.source,
102
100
  extracted_from: source.id,
103
101
  scope: source.scope,
104
- // T1 executor check (2026-08-15 hardening pass): same defect as the
105
- // consolidate.ts merge/trace passes — createMemory with no tenantId
106
- // option stamps 'default' (memory.ts:535) regardless of the source
107
- // entry's own tenant. Thread it through so extracted facts land in
108
- // the same tenant as the episodic memory they were extracted from.
102
+ // Without it createMemory stamps 'default', and extracted facts leave
103
+ // the tenant of the episodic memory they were extracted from.
109
104
  tenantId: source.tenantId,
110
105
  baseHalfLifeDays,
111
106
  }), origin_project: source.origin_project };
112
- // AT1 containment: a refusal is per-VALUE — one rejected fact must not
107
+ // A refusal is per-VALUE: one rejected fact must not
113
108
  // drop the rest of this batch. writeEntry has already audited the
114
109
  // refusal (reject_refusal) before rethrowing, so skip-and-count here.
115
110
  try {
@@ -1,4 +1,4 @@
1
- /** Failure log (ROADMAP CD13): every failed tool call the capture-error hook sees, stored or not. */
1
+ /** Failure log: every failed tool call the capture-error hook sees, stored or not. */
2
2
  import type { CaptureErrorOutcome, RoutineRule } from './capture-error.js';
3
3
  import type { DatabaseSyncLike } from './db.js';
4
4
  /** Rows older than this are pruned on write, which also bounds how far back a repeat can be found. */
@@ -31,9 +31,9 @@ export interface SessionFailures {
31
31
  /** Of those, failures whose signature another session hit first. */
32
32
  repeats: number;
33
33
  }
34
- /** Rated failures per session since `sinceIso`, the input for repeat-error rate per arm (CD11, CD12). */
34
+ /** Rated failures per session since `sinceIso`, the input for repeat-error rate per arm. */
35
35
  export declare function failuresBySession(db: DatabaseSyncLike, tenantId: string, sinceIso: string): SessionFailures[];
36
- /** Failure log totals over a window, for {@link summarizeFailures}. Counts only: a rate needs a holdout arm (CD11). */
36
+ /** Failure log totals over a window, for {@link summarizeFailures}. Counts only: a rate needs a holdout arm. */
37
37
  export interface FailureSummary {
38
38
  /** ISO start of the window (inclusive). */
39
39
  since: string;
@@ -11,7 +11,7 @@ export function recordFailure(db, event) {
11
11
  const cutoff = new Date(Date.parse(now) - FAILURE_LOG_RETENTION_DAYS * 86_400_000).toISOString();
12
12
  db.prepare(`DELETE FROM failure_log WHERE ts < ?`).run(cutoff);
13
13
  }
14
- /** Rated failures per session since `sinceIso`, the input for repeat-error rate per arm (CD11, CD12). */
14
+ /** Rated failures per session since `sinceIso`, the input for repeat-error rate per arm. */
15
15
  export function failuresBySession(db, tenantId, sinceIso) {
16
16
  // SAFETY: the SELECT names exactly these three TEXT columns.
17
17
  const rows = db.prepare(`SELECT ts, session_id, sig_hash FROM failure_log
@@ -1,5 +1,5 @@
1
1
  /**
2
- * J3.2 forward-claim detector — pure-function regex set + token extraction.
2
+ * Forward-claim detector: pure-function regex set + token extraction.
3
3
  *
4
4
  * No DB. No state. No dependencies beyond stdlib regex + String.
5
5
  *
@@ -13,9 +13,7 @@
13
13
  * Iteration signal: the `recall_autodebias_hint_no_class_match` audit op
14
14
  * (emitted by computePlanningFallacyOutput when a phrase matches but no class
15
15
  * resolves) is the telemetry channel for deciding whether to add an
16
- * embedding-based detector in J3.3.
17
- *
18
- * Plan: docs/plans/2026-05-26-j32-auto-injection.md (Task 1).
16
+ * embedding-based detector.
19
17
  */
20
18
  export interface ForwardClaimMatch {
21
19
  /** The regex match snippet, e.g. "will take" or "~3 days". Surfaced
@@ -1,5 +1,5 @@
1
1
  /**
2
- * J3.2 forward-claim detector — pure-function regex set + token extraction.
2
+ * Forward-claim detector: pure-function regex set + token extraction.
3
3
  *
4
4
  * No DB. No state. No dependencies beyond stdlib regex + String.
5
5
  *
@@ -13,12 +13,10 @@
13
13
  * Iteration signal: the `recall_autodebias_hint_no_class_match` audit op
14
14
  * (emitted by computePlanningFallacyOutput when a phrase matches but no class
15
15
  * resolves) is the telemetry channel for deciding whether to add an
16
- * embedding-based detector in J3.3.
17
- *
18
- * Plan: docs/plans/2026-05-26-j32-auto-injection.md (Task 1).
16
+ * embedding-based detector.
19
17
  */
20
18
  /**
21
- * Patterns ship-locked at v1.13.x. Each pattern is intentionally narrow —
19
+ * Each pattern is intentionally narrow:
22
20
  * adding a pattern should require evidence from the
23
21
  * `recall_autodebias_hint_no_class_match` audit channel that real forward-
24
22
  * claims are slipping through, NOT speculative "this might match more".
@@ -29,8 +27,7 @@
29
27
  */
30
28
  // Reused fragment for ALL duration-suffix patterns. Requires a digit + unit
31
29
  // so 'will take ownership' / 'ship in Docker' (no time component) don't
32
- // match. Codex round 2 P2: patterns that allowed verb-only matches fired
33
- // on every-day non-estimate queries that happened to share a class-token.
30
+ // match: verb-only patterns fire on everyday non-estimate queries that share a class-token.
34
31
  // Accepts `<N> unit` (3 days), `a/an unit` (a week — implicit 1), and
35
32
  // `one unit` so natural English forward-claims aren't lost.
36
33
  const DURATION_TAIL = String.raw `(?:about|around|~|≈)?\s*(?:\d+|a|an|one)\s*(?:day|week|month|hour|hr|min(?:ute)?|sec(?:ond)?)s?\b`;
@@ -51,8 +48,7 @@ const FORWARD_CLAIM_PATTERNS = [
51
48
  // Lookbehind asserts start-of-string OR whitespace before the tilde
52
49
  // because \b before ~ requires a word char immediately preceding (~ is
53
50
  // not a word character), so /\b~/ would only match in 'foo~3 days'
54
- // (malformed) and silently miss the legitimate cases. Codex review
55
- // round 1 catch.
51
+ // (malformed) and silently miss the legitimate cases.
56
52
  /(?<=^|\s)~\s*\d+\s*(?:day|week|month|hour)s?\b/i,
57
53
  // Should + verb + duration tail. Same tightening as the leading 'will
58
54
  // take' rule: 'should ship by EOD' must include a quantifier.
@@ -78,8 +74,7 @@ const STOP_WORDS = new Set([
78
74
  // Duration units appear in every forward-claim phrase by design (the
79
75
  // regex set REQUIRES a `<N> <unit>` quantifier after the verb). Letting
80
76
  // them through to class resolution lets a class tag containing 'days'
81
- // win or tie on the unit token instead of the domain token. Codex round
82
- // 2 P3 catch.
77
+ // win or tie on the unit token instead of the domain token.
83
78
  'day', 'days', 'week', 'weeks', 'month', 'months',
84
79
  'hour', 'hours', 'hr', 'hrs',
85
80
  'min', 'mins', 'minute', 'minutes', 'sec', 'secs', 'second', 'seconds',
package/dist/goals.d.ts CHANGED
@@ -60,7 +60,7 @@ export interface PushGoalOpts {
60
60
  }
61
61
  export declare function pushGoal(hippoRoot: string, opts: PushGoalOpts): Goal;
62
62
  /**
63
- * v1.7.4 — depth-cap enforcer extracted from pushGoalWithDb and resumeGoal.
63
+ * Depth-cap enforcer shared by pushGoalWithDb and resumeGoal.
64
64
  * If the (tenant, session) has >= MAX_ACTIVE_GOAL_DEPTH active goals,
65
65
  * suspend the oldest `overflow` ones.
66
66
  *
@@ -69,7 +69,7 @@ export declare function pushGoal(hippoRoot: string, opts: PushGoalOpts): Goal;
69
69
  * is impossible to misread the contract at a call site. Both existing call
70
70
  * sites (pushGoalWithDb, resumeGoal) wrap in `BEGIN IMMEDIATE` already.
71
71
  *
72
- * @internal v1.7.4 -- internal goal-stack invariant. Subject to change.
72
+ * @internal Internal goal-stack invariant. Subject to change.
73
73
  */
74
74
  export declare function enforceDepthCapWithinTx(db: DatabaseSyncLike, tenantId: string, sessionId: string): void;
75
75
  export declare function pushGoalWithDb(db: DatabaseSyncLike, opts: PushGoalOpts): Goal;
@@ -148,7 +148,7 @@ export declare function applyGoalStackBoost<R extends {
148
148
  export interface CompleteGoalOpts {
149
149
  outcomeScore?: number;
150
150
  /**
151
- * v1.7.4 — when true, skip the strength-multiplier propagation block.
151
+ * When true, skip the strength-multiplier propagation block.
152
152
  * Default false (propagate). The goal's status still transitions to
153
153
  * 'completed' and `outcome_score` is still recorded; only the side-effect
154
154
  * on recalled memories' strength is suppressed.
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
@@ -291,9 +291,8 @@ export function computeGoalStackBoost(db, results, opts) {
291
291
  if (matches.length === 0)
292
292
  return r;
293
293
  const multiplier = goalBoostMultiplier(r.entry, tags, matches, goalsByTag, policiesByGoalId);
294
- // A7 recall-trace side-channel: record the goal-boost step BEFORE the
295
- // score is mutated, keyed by entry id. Pure read of r.score here; the
296
- // mutation below is byte-identical to pre-A7.
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.
297
296
  if (trace) {
298
297
  trace.set(r.entry.id, {
299
298
  stage: 'goal-boost',
@@ -309,7 +308,7 @@ export function computeGoalStackBoost(db, results, opts) {
309
308
  // still satisfies R's shape exactly.
310
309
  return { ...r, score: r.score * multiplier };
311
310
  })
312
- // T2 note: deliberately a PLAIN stable score sort, no compareEntryIdentity
311
+ // Deliberately a PLAIN stable score sort, no compareEntryIdentity
313
312
  // tail -- a re-sort of an already deterministically-ordered ranking
314
313
  // inherits its determinism via sort stability, and ties preserve the
315
314
  // prior (meaningful) rank instead of reordering by content.
@@ -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