hippo-memory 1.16.0 → 1.17.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.
@@ -3,27 +3,43 @@
3
3
  * (docs/plans/2026-06-01-e3-deterministic-extraction.md).
4
4
  *
5
5
  * Populates the E3 graph from the already-structured consolidated E2-object tables -
6
- * NO NLP, no precision gate. The graph is a pure derived function of the current E2
7
- * state, so `extractGraph` is an idempotent REBUILD: clear the tenant's graph, then
8
- * re-derive entities + `supersedes` relations from decisions / policies /
9
- * customer_notes / project_briefs (the four E2 types whose kind maps to the
10
- * `entity_type` enum). All writes go through the src/graph.ts consolidated-source
11
- * guard (insertEntity / insertRelation / clearGraph); this module issues no raw SQL.
6
+ * 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
8
+ * 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
10
+ * `entity_type` enum). All writes go through the src/graph.ts consolidated-source guard
11
+ * (insertEntity / insertRelation / clearGraph); this module issues no raw SQL.
12
12
  *
13
- * Deferred (follow-ups): NLP prose-extraction from raw/distilled memories (the
14
- * 80%-precision gold-set part); skill/incident/process entities (not in the
15
- * entity_type enum); cross-object relations beyond supersedes; the `hippo sleep`
16
- * enqueue-hook; E3.2 multi-hop recall. When a SECOND producer (NLP) lands, extraction
17
- * will need a `source` marker so the rebuild scopes to only the deterministically-
18
- * extracted rows.
13
+ * Pass 3 (E3 cross-object, docs/plans/2026-06-02-e3-cross-object-references.md) adds the
14
+ * first CROSS-OBJECT relations: a deterministic NAME-MATCH heuristic that emits a
15
+ * `references` edge when one consolidated object's text contains another entity's name.
16
+ * It is conservative (word-boundary, length-bounded, ambiguity-guarded, per-source
17
+ * capped); its precision is measured + reported, not assumed.
18
+ *
19
+ * Deferred (follow-ups): NLP prose-extraction (semantic depends-on / blocked-by / owns);
20
+ * skill/incident/process entities (not in the entity_type enum - needs a migration); the
21
+ * `hippo sleep` enqueue-hook.
19
22
  */
20
23
  /** Per-type load cap (the loaders default to 100). A type whose active or superseded
21
24
  * set exceeds this is truncated; `ExtractResult.truncated` records it so the
22
25
  * incompleteness is observable rather than silent. */
23
26
  export declare const MAX_EXTRACT_PER_TYPE = 10000;
27
+ /** A target entity name must be in [MIN, MAX] chars to be matched: MIN skips short /
28
+ * generic words; MAX skips prose (a decision's prose name is never a target, only a
29
+ * source). */
30
+ export declare const MIN_REF_NAME_LEN = 4;
31
+ export declare const MAX_REF_NAME_LEN = 80;
32
+ /** Per-source cap so one object cannot explode the graph with references edges. */
33
+ export declare const MAX_REFERENCES_PER_OBJECT = 25;
34
+ /** Regex-size bound: at most this many distinct target names enter the combined
35
+ * alternation, keeping the scan regex sane on a huge store. */
36
+ export declare const MAX_TARGET_NAMES = 5000;
24
37
  export interface ExtractResult {
25
38
  entities: number;
26
39
  relations: number;
40
+ /** Of `relations`, how many are cross-object `references` edges (the rest are
41
+ * `supersedes`). Surfaced so the heuristic's output volume is observable. */
42
+ references: number;
27
43
  /** Entity count per extracted type. */
28
44
  byType: Record<string, number>;
29
45
  /** Entity types whose active or superseded load hit MAX_EXTRACT_PER_TYPE (the graph
@@ -1 +1 @@
1
- {"version":3,"file":"graph-extract.d.ts","sourceRoot":"","sources":["../src/graph-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH;;uDAEuD;AACvD,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;yCACqC;IACrC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAkDD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAgF/E"}
1
+ {"version":3,"file":"graph-extract.d.ts","sourceRoot":"","sources":["../src/graph-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH;;uDAEuD;AACvD,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAG1C;;eAEe;AACf,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,mFAAmF;AACnF,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C;gEACgE;AAChE,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;kFAC8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;yCACqC;IACrC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AA+ED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAiG/E"}
@@ -3,19 +3,22 @@
3
3
  * (docs/plans/2026-06-01-e3-deterministic-extraction.md).
4
4
  *
5
5
  * Populates the E3 graph from the already-structured consolidated E2-object tables -
6
- * NO NLP, no precision gate. The graph is a pure derived function of the current E2
7
- * state, so `extractGraph` is an idempotent REBUILD: clear the tenant's graph, then
8
- * re-derive entities + `supersedes` relations from decisions / policies /
9
- * customer_notes / project_briefs (the four E2 types whose kind maps to the
10
- * `entity_type` enum). All writes go through the src/graph.ts consolidated-source
11
- * guard (insertEntity / insertRelation / clearGraph); this module issues no raw SQL.
6
+ * 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
8
+ * 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
10
+ * `entity_type` enum). All writes go through the src/graph.ts consolidated-source guard
11
+ * (insertEntity / insertRelation / clearGraph); this module issues no raw SQL.
12
12
  *
13
- * Deferred (follow-ups): NLP prose-extraction from raw/distilled memories (the
14
- * 80%-precision gold-set part); skill/incident/process entities (not in the
15
- * entity_type enum); cross-object relations beyond supersedes; the `hippo sleep`
16
- * enqueue-hook; E3.2 multi-hop recall. When a SECOND producer (NLP) lands, extraction
17
- * will need a `source` marker so the rebuild scopes to only the deterministically-
18
- * extracted rows.
13
+ * Pass 3 (E3 cross-object, docs/plans/2026-06-02-e3-cross-object-references.md) adds the
14
+ * first CROSS-OBJECT relations: a deterministic NAME-MATCH heuristic that emits a
15
+ * `references` edge when one consolidated object's text contains another entity's name.
16
+ * It is conservative (word-boundary, length-bounded, ambiguity-guarded, per-source
17
+ * capped); its precision is measured + reported, not assumed.
18
+ *
19
+ * Deferred (follow-ups): NLP prose-extraction (semantic depends-on / blocked-by / owns);
20
+ * skill/incident/process entities (not in the entity_type enum - needs a migration); the
21
+ * `hippo sleep` enqueue-hook.
19
22
  */
20
23
  import { clearGraph, insertEntity, insertRelation, MAX_ENTITY_NAME_LEN } from './graph.js';
21
24
  import { loadDecisions } from './decisions.js';
@@ -27,10 +30,29 @@ import { assertTenantId } from './store.js';
27
30
  * set exceeds this is truncated; `ExtractResult.truncated` records it so the
28
31
  * incompleteness is observable rather than silent. */
29
32
  export const MAX_EXTRACT_PER_TYPE = 10000;
33
+ // --- Pass 3 (cross-object references) tunables ------------------------------------
34
+ /** A target entity name must be in [MIN, MAX] chars to be matched: MIN skips short /
35
+ * generic words; MAX skips prose (a decision's prose name is never a target, only a
36
+ * source). */
37
+ export const MIN_REF_NAME_LEN = 4;
38
+ export const MAX_REF_NAME_LEN = 80;
39
+ /** Per-source cap so one object cannot explode the graph with references edges. */
40
+ export const MAX_REFERENCES_PER_OBJECT = 25;
41
+ /** Regex-size bound: at most this many distinct target names enter the combined
42
+ * alternation, keeping the scan regex sane on a huge store. */
43
+ export const MAX_TARGET_NAMES = 5000;
30
44
  /** Stable map key: entity types share an id space across tables, so key by both. */
31
45
  function keyOf(entityType, e2Id) {
32
46
  return `${entityType}:${e2Id}`;
33
47
  }
48
+ /** Escape a string for safe use as a literal inside a RegExp alternation. */
49
+ function escapeRegex(s) {
50
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
51
+ }
52
+ /** Unordered entity-id pair key, so a relation between a,b is found in either direction. */
53
+ function pairKey(a, b) {
54
+ return a < b ? `${a}:${b}` : `${b}:${a}`;
55
+ }
34
56
  /**
35
57
  * Load a type's ACTIVE + SUPERSEDED rows (excluding `closed` = retired), normalised.
36
58
  * Calls the loader once per status so MAX_EXTRACT_PER_TYPE is a per-status budget
@@ -40,7 +62,9 @@ function loadType(hippoRoot, tenantId, entityType,
40
62
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
63
  loadFn,
42
64
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
- nameOf) {
65
+ nameOf,
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ textOf) {
44
68
  const rows = [];
45
69
  let hitCap = false;
46
70
  for (const status of ['active', 'superseded']) {
@@ -52,6 +76,7 @@ nameOf) {
52
76
  entityType,
53
77
  e2Id: r.id,
54
78
  name: nameOf(r),
79
+ searchText: textOf(r),
55
80
  memoryId: (r.memoryId ?? null),
56
81
  supersededBy: (r.supersededBy ?? null),
57
82
  });
@@ -67,10 +92,10 @@ nameOf) {
67
92
  export function extractGraph(hippoRoot, tenantId) {
68
93
  assertTenantId('extractGraph', tenantId);
69
94
  const sources = [
70
- { entityType: 'decision', loadFn: loadDecisions, nameOf: (r) => r.decisionText },
71
- { entityType: 'policy', loadFn: loadPolicies, nameOf: (r) => r.policyName },
72
- { entityType: 'customer', loadFn: loadCustomerNotes, nameOf: (r) => r.customer },
73
- { entityType: 'project', loadFn: loadProjectBriefs, nameOf: (r) => r.repo },
95
+ { entityType: 'decision', loadFn: loadDecisions, nameOf: (r) => r.decisionText, textOf: (r) => [r.decisionText, r.context].filter(Boolean).join(' ') },
96
+ { entityType: 'policy', loadFn: loadPolicies, nameOf: (r) => r.policyName, textOf: (r) => [r.policyName, r.policyText].filter(Boolean).join(' ') },
97
+ { entityType: 'customer', loadFn: loadCustomerNotes, nameOf: (r) => r.customer, textOf: (r) => [r.customer, r.note].filter(Boolean).join(' ') },
98
+ { entityType: 'project', loadFn: loadProjectBriefs, nameOf: (r) => r.repo, textOf: (r) => [r.repo, r.summary].filter(Boolean).join(' ') },
74
99
  ];
75
100
  // Rebuild from scratch: the graph is derived, so clear then re-derive.
76
101
  clearGraph(hippoRoot, tenantId);
@@ -79,10 +104,12 @@ export function extractGraph(hippoRoot, tenantId) {
79
104
  const allRows = [];
80
105
  const entityIdByKey = new Map();
81
106
  const memoryIdByKey = new Map();
107
+ // Created entities ONLY (drives Pass 3 sources + targets), in stable insertion order.
108
+ const created = [];
82
109
  // Pass 1: entities. Skip rows whose source memory was forgotten (NULL memory_id) -
83
110
  // an entity must reference a consolidated memory (entities.memory_id is NOT NULL).
84
111
  for (const src of sources) {
85
- const { rows, hitCap } = loadType(hippoRoot, tenantId, src.entityType, src.loadFn, src.nameOf);
112
+ const { rows, hitCap } = loadType(hippoRoot, tenantId, src.entityType, src.loadFn, src.nameOf, src.textOf);
86
113
  if (hitCap)
87
114
  truncated.push(src.entityType);
88
115
  byType[src.entityType] = 0;
@@ -110,6 +137,7 @@ export function extractGraph(hippoRoot, tenantId) {
110
137
  const k = keyOf(row.entityType, row.e2Id);
111
138
  entityIdByKey.set(k, entity.id);
112
139
  memoryIdByKey.set(k, row.memoryId);
140
+ created.push({ entityId: entity.id, entityType: row.entityType, memoryId: row.memoryId, name, searchText: row.searchText ?? '', superseded: row.supersededBy !== null });
113
141
  byType[src.entityType] += 1;
114
142
  }
115
143
  }
@@ -117,6 +145,11 @@ export function extractGraph(hippoRoot, tenantId) {
117
145
  // "Y supersedes X" - but only when BOTH X and Y were extracted (e.g. Y may be closed
118
146
  // and absent). The relation is sourced from Y's consolidated memory.
119
147
  let relations = 0;
148
+ // Entity-id pairs already related by supersedes (unordered). Pass 3 skips a references
149
+ // edge for such a pair: a version-extends-its-predecessor's-name containment (e.g.
150
+ // "Adopt X (managed)" contains "Adopt X") is a name artifact, not a cross-reference,
151
+ // and supersedes already captures their relationship.
152
+ const supersededPairs = new Set();
120
153
  for (const row of allRows) {
121
154
  if (row.supersededBy === null)
122
155
  continue;
@@ -133,9 +166,94 @@ export function extractGraph(hippoRoot, tenantId) {
133
166
  relType: 'supersedes',
134
167
  memoryId: yMemoryId,
135
168
  });
169
+ supersededPairs.add(pairKey(fromId, toId));
136
170
  relations += 1;
137
171
  }
138
- const entities = Array.from(entityIdByKey.keys()).length;
139
- return { entities, relations, byType, truncated };
172
+ // Pass 3: cross-object `references` edges via conservative name matching. A source's
173
+ // text containing a target entity's name -> "source references target". Sources +
174
+ // targets are CREATED entities only, so insertRelation never sees a null source memory.
175
+ const references = extractReferences(hippoRoot, tenantId, created, supersededPairs, truncated);
176
+ relations += references;
177
+ const entities = created.length;
178
+ return { entities, relations, references, byType, truncated };
179
+ }
180
+ /**
181
+ * Pass 3. Build a target-name index from the created entities (names within the length
182
+ * bounds, ambiguous names dropped), scan each created entity's text once with one
183
+ * combined word-boundary regex, and emit `references` edges (self-skipped, deduped,
184
+ * per-source capped). Returns the number of references edges written.
185
+ */
186
+ function extractReferences(hippoRoot, tenantId, created, supersededPairs, truncated) {
187
+ // Build the target index: normalised name -> single entity id. A name is a target only
188
+ // if its length is in bounds; a name shared by >1 entity is AMBIGUOUS and dropped.
189
+ const nameToId = new Map();
190
+ const ambiguous = new Set();
191
+ for (const e of created) {
192
+ // References are among ACTIVE entities only: a superseded (outdated) row is not a
193
+ // current cross-reference target (codex).
194
+ if (e.superseded)
195
+ continue;
196
+ // Decisions are SOURCE-only: their name is decision prose, referenced by supersedes,
197
+ // not by name-mention. Excluding them as targets also prevents a decision's own name
198
+ // (== its searchText) from whole-string self-matching and shadowing embedded targets.
199
+ if (e.entityType === 'decision')
200
+ continue;
201
+ const norm = e.name.trim().toLowerCase();
202
+ if (norm.length < MIN_REF_NAME_LEN || norm.length > MAX_REF_NAME_LEN)
203
+ continue;
204
+ if (ambiguous.has(norm))
205
+ continue;
206
+ if (nameToId.has(norm)) {
207
+ // Second distinct entity with this name (and not its own id repeated) -> ambiguous.
208
+ if (nameToId.get(norm) !== e.entityId) {
209
+ nameToId.delete(norm);
210
+ ambiguous.add(norm);
211
+ }
212
+ continue;
213
+ }
214
+ nameToId.set(norm, e.entityId);
215
+ }
216
+ if (nameToId.size === 0)
217
+ return 0;
218
+ // Record the truncation (observability, mirroring MAX_EXTRACT_PER_TYPE) so a >cap
219
+ // store's under-matched references are not silent.
220
+ if (nameToId.size > MAX_TARGET_NAMES)
221
+ truncated.push('references-targets');
222
+ // LONGEST name first, then alphabetical: JS regex alternation is leftmost-first, so
223
+ // ordering longer names before their prefixes makes the match longest-at-position
224
+ // (`postgres pro` wins over `postgres`; codex). Deterministic, so truncation is stable.
225
+ const targetNames = [...nameToId.keys()]
226
+ .sort((a, b) => b.length - a.length || (a < b ? -1 : a > b ? 1 : 0))
227
+ .slice(0, MAX_TARGET_NAMES);
228
+ const pattern = `\\b(?:${targetNames.map(escapeRegex).join('|')})\\b`;
229
+ const re = new RegExp(pattern, 'gi');
230
+ let references = 0;
231
+ for (const src of created) {
232
+ if (src.superseded)
233
+ continue; // superseded sources hold only stale references (codex)
234
+ if (!src.searchText)
235
+ continue;
236
+ const targets = new Set();
237
+ for (const m of src.searchText.matchAll(re)) {
238
+ const targetId = nameToId.get(m[0].toLowerCase());
239
+ if (targetId === undefined || targetId === src.entityId)
240
+ continue; // miss / self
241
+ if (supersededPairs.has(pairKey(src.entityId, targetId)))
242
+ continue; // already version-related
243
+ targets.add(targetId);
244
+ if (targets.size >= MAX_REFERENCES_PER_OBJECT)
245
+ break; // per-source cap
246
+ }
247
+ for (const targetId of targets) {
248
+ insertRelation(hippoRoot, tenantId, {
249
+ fromEntityId: src.entityId,
250
+ toEntityId: targetId,
251
+ relType: 'references',
252
+ memoryId: src.memoryId, // the source object's consolidated memory
253
+ });
254
+ references += 1;
255
+ }
256
+ }
257
+ return references;
140
258
  }
141
259
  //# sourceMappingURL=graph-extract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-extract.js","sourceRoot":"","sources":["../src/graph-extract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph-extract.js","sourceRoot":"","sources":["../src/graph-extract.ts"],"names":[],"mappings":"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"}
package/dist/src/cli.js CHANGED
@@ -4433,7 +4433,8 @@ function cmdGraph(hippoRoot, args, _flags) {
4433
4433
  const byType = Object.entries(result.byType)
4434
4434
  .map(([t, n]) => `${t} ${n}`)
4435
4435
  .join(', ');
4436
- console.log(`Graph extracted: ${result.entities} entities (${byType}) + ${result.relations} supersedes relations.`);
4436
+ const supersedes = result.relations - result.references;
4437
+ console.log(`Graph extracted: ${result.entities} entities (${byType}) + ${result.relations} relations (${supersedes} supersedes, ${result.references} references).`);
4437
4438
  if (result.truncated.length > 0) {
4438
4439
  console.error(`WARNING: under-extracted (hit the per-type cap): ${result.truncated.join(', ')}. The graph is incomplete for those types.`);
4439
4440
  }