diff --git a/packages/core/src/migrations.ts b/packages/core/src/migrations.ts index 4a34dcb2..8990af60 100644 --- a/packages/core/src/migrations.ts +++ b/packages/core/src/migrations.ts @@ -551,6 +551,27 @@ export function initSchema(db: Database.Database): void { db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (?)').run(43); } + // v44: thread identity (resolution-as-fan-out slice 1). Adds + // memories.thread_id (correlation id minted by the engine's threads + // registry) + memories.supersede_reason (audit trail for the supersede + // action). Index lives here, not SCHEMA_SQL, per the v42 boot-order rule. + if (currentVersion < 44 && v40Applied) { + const memoryColumns = new Set( + (db.prepare(`PRAGMA table_info(memories)`).all() as Array<{ name: string }>).map((row) => row.name) + ); + + if (!memoryColumns.has('thread_id')) { + db.exec(`ALTER TABLE memories ADD COLUMN thread_id TEXT`); + } + if (!memoryColumns.has('supersede_reason')) { + db.exec(`ALTER TABLE memories ADD COLUMN supersede_reason TEXT`); + } + + db.exec(`CREATE INDEX IF NOT EXISTS idx_memories_thread_id ON memories(thread_id)`); + + db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (?)').run(44); + } + // Only stamp SCHEMA_VERSION at the end if every migration ran. Dry-run // skips v40 → leave schema_version at 39 so the next non-dry-run boot // re-enters the v40 branch. diff --git a/packages/core/src/schema.ts b/packages/core/src/schema.ts index 5fd08fb7..32dde6ce 100644 --- a/packages/core/src/schema.ts +++ b/packages/core/src/schema.ts @@ -10,7 +10,7 @@ // ============================================================================= /** Current schema version - bump when schema changes */ -export const SCHEMA_VERSION = 43; +export const SCHEMA_VERSION = 44; /** State database filename */ export const STATE_DB_FILENAME = 'state.db'; @@ -391,13 +391,16 @@ CREATE TABLE IF NOT EXISTS memories ( ttl_days INTEGER, superseded_by INTEGER REFERENCES memories(id), visibility TEXT NOT NULL DEFAULT 'shared', - owner_scope TEXT NOT NULL DEFAULT 'global' + owner_scope TEXT NOT NULL DEFAULT 'global', + thread_id TEXT, + supersede_reason TEXT ); CREATE INDEX IF NOT EXISTS idx_memories_key ON memories(key); CREATE INDEX IF NOT EXISTS idx_memories_entity ON memories(entity); CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type); -- idx_memories_key_owner_scope (UNIQUE) and idx_memories_owner_scope are created -- by the v42 migration in migrations.ts, after that migration adds owner_scope. +-- idx_memories_thread_id is created by the v44 migration, after it adds thread_id. CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5( key, value, diff --git a/packages/mcp-server/src/core/write/memory.ts b/packages/mcp-server/src/core/write/memory.ts index 8f90827f..32d0a31c 100644 --- a/packages/mcp-server/src/core/write/memory.ts +++ b/packages/mcp-server/src/core/write/memory.ts @@ -33,6 +33,8 @@ export interface Memory { superseded_by: number | null; visibility: string; owner_scope: string; + thread_id: string | null; + supersede_reason: string | null; } export interface StoreMemoryOptions { @@ -45,6 +47,23 @@ export interface StoreMemoryOptions { agent_id?: string; session_id?: string; visibility?: 'shared' | 'private'; + thread_id?: string; +} + +export interface SupersedeMemoryOptions { + /** Supersede every current memory carrying this thread correlation id. */ + thread_id?: string; + /** Supersede the single current memory under this key (caller's scope). */ + key?: string; + /** Audit reason recorded on each superseded row (e.g. "thread-resolved"). */ + reason?: string; + agent_id?: string; +} + +export interface SupersedeMemoryResult { + superseded: Array<{ id: number; key: string; owner_scope: string }>; + /** Rows matched but already superseded — idempotent no-op count. */ + already_superseded: number; } export interface SearchMemoryOptions { @@ -222,6 +241,7 @@ export function storeMemory( agent_id, session_id, visibility = 'shared', + thread_id, } = options; const ownerScope = resolveOwnerScope(agent_id, visibility); @@ -237,40 +257,53 @@ export function storeMemory( // Check if memory with this key already exists const existing = stateDb.db.prepare( - 'SELECT id FROM memories WHERE key = ? AND owner_scope = ?' - ).get(key, ownerScope) as { id: number } | undefined; + 'SELECT id, superseded_by FROM memories WHERE key = ? AND owner_scope = ?' + ).get(key, ownerScope) as { id: number; superseded_by: number | null } | undefined; if (existing) { - // Upsert: update existing memory + // Upsert: update existing memory. + // + // Supersession is PRESERVED, never reset (thread-identity slice 1). + // The previous shape set `superseded_by = NULL` here, which meant any + // routine same-key re-store (cron jobs idempotently re-storing facts) + // silently resurrected a tombstoned memory — the upsert-resurrection + // bug. A superseded fact stays superseded; explicit revival is + // forget-then-store. thread_id is updated only when the caller provides + // one, so re-stores without thread context don't strip the correlation id. stateDb.db.prepare(` UPDATE memories SET value = ?, memory_type = ?, entity = ?, entities_json = ?, source_agent_id = ?, source_session_id = ?, confidence = ?, updated_at = ?, accessed_at = ?, - ttl_days = ?, visibility = ?, owner_scope = ?, superseded_by = NULL + ttl_days = ?, visibility = ?, owner_scope = ?, + thread_id = COALESCE(?, thread_id) WHERE key = ? AND owner_scope = ? `).run( value, type, entity ?? null, entitiesJson, agent_id ?? null, session_id ?? null, confidence, now, now, - ttl_days ?? null, visibility, ownerScope, key, ownerScope, + ttl_days ?? null, visibility, ownerScope, + thread_id ?? null, + key, ownerScope, ); } else { // Insert new memory stateDb.db.prepare(` INSERT INTO memories (key, value, memory_type, entity, entities_json, source_agent_id, source_session_id, confidence, - created_at, updated_at, accessed_at, ttl_days, visibility, owner_scope) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + created_at, updated_at, accessed_at, ttl_days, visibility, owner_scope, thread_id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).run( key, value, type, entity ?? null, entitiesJson, agent_id ?? null, session_id ?? null, confidence, - now, now, now, ttl_days ?? null, visibility, ownerScope, + now, now, now, ttl_days ?? null, visibility, ownerScope, thread_id ?? null, ); } // Private memories must not leak into shared graph-derived signals. - if (visibility === 'shared') { + // A superseded row stays out of the graph: its edges were removed at + // supersede time and a re-store must not resurrect them either. + if (visibility === 'shared' && !(existing && existing.superseded_by !== null)) { updateGraphSignals(stateDb, key, detectedEntities); } @@ -423,6 +456,73 @@ export function forgetMemory( return true; } +/** + * Supersede memories — the resolution-as-fan-out consumer (slice 1). + * + * Marks current memories as superseded (tombstoned, retained for audit) + * without deleting them. Targets either every current row carrying a + * thread correlation id, or the single current row under a key in the + * caller's scope. Idempotent: already-superseded rows are counted, not + * an error, and a repeat call is a no-op. + * + * superseded_by is set to the row's own id — the self-pointer is the + * tombstone-without-successor marker (every read path already filters + * `superseded_by IS NULL`, so the fact disappears from get/search/list/ + * brief the moment this commits). supersede_reason carries the audit why. + * + * Graph edges for shared/global rows are removed (mirrors forgetMemory) so + * stale memory:{key} edges don't outlive the fact. + */ +export function supersedeMemories( + stateDb: StateDb, + options: SupersedeMemoryOptions, +): SupersedeMemoryResult { + const { thread_id, key, reason, agent_id } = options; + + if (!thread_id && !key) { + throw new Error('supersede requires thread_id or key'); + } + + const conditions: string[] = []; + const params: unknown[] = []; + + if (thread_id) { + conditions.push('thread_id = ?'); + params.push(thread_id); + } + if (key) { + conditions.push('key = ?'); + params.push(key); + } + // Scope rule (council round 1): a caller may only close facts it can see — + // global rows plus its own agent scope. Never another agent's private facts. + applyVisibilityFilter(conditions, params, agent_id); + + const matched = stateDb.db.prepare( + `SELECT id, key, owner_scope, visibility, superseded_by FROM memories WHERE ${conditions.join(' AND ')}` + ).all(...params) as Array>; + + const current = matched.filter((m) => m.superseded_by === null); + const alreadySuperseded = matched.length - current.length; + + const now = Date.now(); + const stamp = stateDb.db.prepare( + 'UPDATE memories SET superseded_by = id, supersede_reason = ?, updated_at = ? WHERE id = ? AND superseded_by IS NULL' + ); + + for (const m of current) { + stamp.run(reason ?? null, now, m.id); + if (m.visibility === 'shared' && m.owner_scope === GLOBAL_OWNER_SCOPE) { + removeGraphSignals(stateDb, m.key); + } + } + + return { + superseded: current.map((m) => ({ id: m.id, key: m.key, owner_scope: m.owner_scope })), + already_superseded: alreadySuperseded, + }; +} + // ============================================================================= // SESSION SUMMARIES // ============================================================================= diff --git a/packages/mcp-server/src/generated/tool-embeddings.generated.ts b/packages/mcp-server/src/generated/tool-embeddings.generated.ts index fcc24f07..4d80add5 100644 --- a/packages/mcp-server/src/generated/tool-embeddings.generated.ts +++ b/packages/mcp-server/src/generated/tool-embeddings.generated.ts @@ -5,7 +5,7 @@ * Model: Xenova/all-MiniLM-L6-v2 * Dims: 384 * Tools: 20 - * Generated: 2026-04-20T17:52:49.403Z + * Generated: 2026-06-07T13:49:09.942Z */ /* eslint-disable */ @@ -14,8 +14,8 @@ export const TOOL_EMBEDDINGS_MANIFEST = { model: 'Xenova/all-MiniLM-L6-v2', dims: 384, version: 1, - generatedAt: '2026-04-20T17:52:49.403Z', - sourceHash: 'c60088e1313f3836', + generatedAt: '2026-06-07T13:49:09.942Z', + sourceHash: '511afe0b32e93c9d', tools: [ { name: 'correct', category: 'corrections', tier: 2, descriptionHash: 'ab104cbbf9d936e7', embedding: [-0.112137,0.050770,0.026377,0.010174,-0.059357,0.026808,-0.014668,-0.030909,0.033262,0.027611,0.027976,0.036543,0.000227,-0.032873,0.017395,0.041123,-0.002190,0.110179,0.028379,-0.018504,0.006275,0.070822,0.039700,0.003946,0.013957,0.023896,-0.104276,0.002763,-0.014054,-0.122577,-0.015989,0.079155,0.027459,0.044122,-0.023387,0.090762,-0.021924,-0.017856,0.051318,-0.045432,-0.009773,-0.022173,-0.053484,-0.041077,0.000213,-0.032980,-0.059949,-0.032224,-0.090868,0.061656,0.015128,-0.063887,-0.043796,0.059185,-0.016482,0.094751,0.033966,0.075673,-0.026640,-0.036574,0.108109,-0.040591,-0.060051,-0.043626,-0.030352,0.026759,0.053429,-0.068346,0.052479,-0.034162,0.052643,-0.011244,0.011792,-0.015615,-0.004771,-0.001779,-0.025966,0.037190,-0.031432,-0.093345,-0.016200,-0.065183,0.010272,0.051686,0.063362,-0.027996,-0.043456,-0.045347,0.034818,0.080175,-0.025879,-0.094627,0.141497,-0.005965,-0.065652,0.031484,-0.006416,-0.008356,0.069022,0.060329,0.058135,0.106371,-0.034696,0.010363,0.079416,-0.010569,-0.009815,0.013082,-0.049440,-0.053058,-0.000614,0.025107,0.045675,-0.026209,0.028465,-0.037018,-0.016706,0.011322,-0.053478,0.049009,0.072959,-0.018558,-0.017536,0.015453,-0.056476,-0.025292,-0.000853,0.000000,0.109517,0.051035,-0.004360,-0.025460,0.053702,0.012196,-0.092574,-0.067859,-0.082448,-0.030584,0.049530,0.005629,0.018349,0.036023,-0.048056,0.022057,-0.008418,0.093832,0.020071,0.060862,0.018577,0.046417,-0.022997,-0.010351,0.028345,0.073876,-0.000445,-0.014539,-0.027922,-0.016345,0.026120,-0.048091,0.067337,0.029427,0.042862,0.028650,0.037074,-0.067455,-0.039382,-0.083748,0.014111,0.041082,-0.044054,-0.088079,-0.022421,-0.026242,0.001517,0.029601,0.083941,-0.007021,0.042373,0.076519,-0.038581,-0.023357,0.001342,0.004167,0.014898,0.026353,0.004946,0.075959,0.121664,-0.006181,-0.041190,0.000188,-0.053050,0.056259,-0.014163,-0.082006,0.033895,-0.003682,-0.067722,0.006538,0.030868,0.050463,-0.005444,-0.090016,-0.078164,-0.049525,0.012905,0.001820,-0.055408,-0.059239,-0.064490,0.095689,-0.028328,-0.075978,0.008404,-0.073829,-0.039537,0.014228,0.004733,-0.006572,-0.023809,0.026930,0.053276,-0.000000,0.043507,-0.026395,-0.059847,0.074179,-0.057412,-0.026139,0.027878,0.079916,0.068508,0.005595,0.004638,-0.038802,-0.077282,-0.020645,-0.000466,-0.035289,-0.048797,-0.027662,-0.011941,0.038905,0.052053,-0.019324,-0.015524,0.115244,0.052004,0.022335,0.009845,-0.043505,0.032588,-0.057991,0.014567,0.004846,-0.054494,-0.026246,0.052980,-0.087103,0.053247,-0.008393,-0.078638,0.009214,0.065006,0.055170,-0.039030,0.099940,0.049050,-0.018042,-0.048194,0.078942,-0.003651,-0.035746,0.038990,-0.058707,-0.019853,-0.017654,0.048571,0.028416,0.026525,-0.093748,-0.026548,0.031670,-0.052844,0.060918,-0.052816,0.029207,0.042988,-0.001484,-0.045086,-0.030614,-0.019668,0.006990,0.035397,-0.026120,-0.018835,-0.107687,0.147089,-0.099558,-0.066147,-0.036173,-0.044325,-0.037926,-0.016089,-0.020625,0.080158,0.083126,-0.035453,-0.012411,-0.018514,0.065440,-0.045800,0.016839,-0.034864,-0.020352,0.016488,-0.014599,-0.071506,-0.000000,-0.170263,0.022366,-0.019692,-0.009536,0.057014,0.006094,-0.027565,0.095143,-0.029668,-0.056879,-0.001233,0.009667,-0.043449,-0.102301,0.013517,-0.034099,0.034423,0.053725,-0.069814,0.018209,-0.069986,0.058077,-0.019755,-0.056135,0.006730,0.004859,0.013008,0.092358,0.022798,-0.002356,0.044878,-0.009630,0.083680,0.036551,-0.006654,-0.057746,0.104987,-0.026351,0.060275,0.022709,0.028620,0.036379,-0.046548,0.078990,-0.023751,-0.032051,0.013826,-0.071854,0.011729,-0.125561,0.010702,-0.000061,-0.074215,0.029655,-0.039268,0.102985,0.100883,-0.048536,0.038982,-0.036561,0.157337,-0.026732,0.042879,-0.055083] }, { name: 'discover_tools', category: 'search', tier: 1, descriptionHash: 'aa8995ef7f47401b', embedding: [-0.075188,-0.021086,-0.070189,0.027863,-0.011663,-0.111824,-0.030346,-0.055104,-0.028948,-0.009640,0.048634,-0.057464,0.033817,0.007175,0.011836,0.053405,-0.013156,-0.036403,0.089025,-0.065241,0.005382,0.037918,-0.005621,-0.040135,0.019724,-0.022742,-0.055146,-0.045270,0.020070,-0.009524,-0.016252,0.057074,-0.004075,0.000505,0.084357,0.105241,0.058140,0.016512,-0.020480,-0.089392,-0.017279,-0.059956,-0.042557,-0.020422,-0.013626,-0.053287,-0.116333,-0.027996,-0.010748,0.003943,-0.046903,-0.094901,-0.063350,0.072725,0.058132,0.109191,0.007471,-0.012742,-0.025956,-0.022849,0.067187,-0.000983,-0.048119,0.016697,-0.041044,0.044199,0.021653,-0.044895,0.081919,-0.116255,0.015069,-0.009135,-0.039679,0.027543,0.106306,0.056589,0.032697,0.038454,-0.035896,-0.151718,-0.069043,0.051894,-0.029377,0.069531,-0.023954,0.071038,-0.014322,-0.028599,0.076246,0.016156,0.020133,-0.134726,-0.073939,-0.071862,-0.018366,0.013815,0.007942,-0.036760,0.034956,-0.010209,-0.077494,-0.009537,0.029254,-0.084394,-0.044125,0.099604,-0.063872,-0.014194,0.061705,0.017144,-0.021457,0.001541,0.076249,-0.033957,0.053548,0.035583,-0.067036,-0.020214,-0.051770,0.071649,0.052922,0.109373,0.044848,-0.055537,-0.018694,0.098885,-0.056785,-0.000000,0.105679,-0.019862,0.002447,0.062664,-0.003153,0.034860,0.047175,0.018801,-0.059901,0.025770,-0.057711,0.059793,-0.061608,-0.007361,0.028895,0.046272,0.042275,0.057409,0.035205,-0.040239,-0.005299,-0.014404,-0.029234,0.043057,0.101209,0.053609,-0.010400,-0.003749,0.005548,0.025031,-0.062580,-0.024213,0.034139,0.067818,-0.018895,0.079705,-0.010918,-0.026168,-0.028529,-0.015760,0.023614,-0.019583,-0.054301,-0.089354,0.020601,-0.080503,-0.067058,0.028848,0.072858,-0.012721,-0.016256,0.007214,0.073557,0.006098,-0.011199,-0.002130,-0.016420,0.033319,0.053211,0.038781,0.033251,0.018787,-0.070695,0.089868,0.011783,0.003361,0.016143,-0.046838,0.008084,0.089449,-0.043313,0.061697,-0.040691,0.012123,0.024459,-0.148406,-0.037517,-0.057303,0.024418,-0.007207,-0.019377,-0.052320,-0.046205,0.058728,0.005983,0.013952,0.021432,-0.042616,-0.043659,-0.068847,-0.091945,0.009479,-0.061069,0.032148,0.009958,-0.000000,0.040652,-0.068116,0.072305,0.035184,-0.020632,-0.057712,-0.028410,-0.082632,-0.013210,0.019844,0.090441,0.035095,-0.044615,-0.129175,0.114251,0.070678,-0.063627,-0.100181,0.025629,0.109847,-0.035361,0.001383,-0.115486,0.040720,0.041929,-0.067248,0.008969,-0.002463,0.018072,0.000135,0.009092,0.080653,-0.035027,0.004950,-0.045352,0.017452,0.099040,-0.027698,-0.000527,-0.025174,0.003514,0.049152,-0.099115,0.007461,-0.007823,0.040005,-0.014621,0.059240,-0.024107,-0.047808,0.085614,0.017335,-0.010463,-0.049807,0.002247,0.064009,0.042356,0.018684,-0.040498,-0.020599,0.036185,-0.010663,-0.043319,0.083483,-0.007926,-0.006604,-0.023185,0.024318,-0.090426,-0.045626,0.019900,0.022690,0.040662,-0.096964,0.028033,-0.036186,-0.087325,-0.038926,-0.023116,0.027710,0.019014,-0.001276,0.118484,0.010463,-0.033128,0.007546,-0.015151,0.083676,-0.035601,-0.003541,-0.089467,-0.032535,-0.070525,0.024172,0.023750,-0.000000,-0.021465,0.044607,0.014306,-0.047116,0.075083,0.085343,-0.012816,0.157587,-0.034197,0.001913,-0.029213,-0.019289,-0.014942,0.041905,0.029948,-0.013572,0.025128,0.009812,-0.059942,-0.056379,0.005458,-0.002520,0.057553,0.003015,0.007678,-0.072857,-0.057614,0.030144,0.038096,0.003422,-0.009920,-0.052856,0.067301,-0.007253,0.093171,0.057181,0.024557,0.003957,0.015116,0.049431,0.007994,0.033472,-0.005896,-0.035395,-0.084564,-0.018945,0.027141,0.028566,0.020801,-0.028642,-0.002580,-0.023189,-0.007276,0.001472,0.000377,0.105597,0.040329,-0.052133,0.055025,-0.054046,0.021824,-0.046932,0.064667,-0.002851] }, @@ -27,7 +27,7 @@ export const TOOL_EMBEDDINGS_MANIFEST = { { name: 'init_semantic', category: 'search', tier: 2, descriptionHash: '33cdfeef485b49c6', embedding: [-0.025452,-0.048845,-0.011618,0.023209,-0.024364,0.031370,-0.053247,-0.042608,-0.051363,-0.036246,0.011666,-0.082152,0.056721,-0.003851,0.042404,0.117140,0.091872,-0.002772,0.010569,-0.027861,0.058213,0.036962,0.042226,-0.037348,-0.043087,-0.006366,-0.083984,-0.041254,0.058968,-0.014554,0.081354,0.118492,-0.024363,0.128628,-0.022981,0.039297,-0.043987,-0.045190,-0.000359,-0.093715,-0.035612,0.024908,-0.043093,0.013066,0.041861,0.004982,-0.101195,-0.062399,-0.034330,0.026001,-0.119525,-0.000020,-0.046593,-0.006613,0.058065,0.051141,-0.044697,0.044936,-0.015020,-0.096312,0.018980,-0.077467,0.033712,-0.007687,-0.021349,-0.025106,0.045974,-0.023106,0.073984,-0.050748,0.052893,-0.014656,-0.045655,-0.015265,0.003907,0.066162,0.005096,0.011062,-0.029671,-0.135103,-0.064705,-0.032250,0.048150,0.039630,0.057509,-0.052253,0.039816,-0.093817,-0.000008,0.031132,0.084445,-0.099612,-0.028810,0.008035,0.045018,-0.016475,0.027816,0.015622,0.091962,0.009961,-0.014911,0.056744,0.024435,0.026216,-0.053843,-0.019819,-0.014845,-0.010925,0.046932,-0.103588,0.000033,0.014263,0.087409,-0.035952,0.001046,-0.005150,0.025704,-0.072284,0.118985,0.060917,0.031497,0.072897,-0.043803,-0.042411,-0.109211,0.033810,-0.042281,0.000000,0.080843,-0.013474,0.008398,0.057869,-0.011194,0.037514,0.039225,0.088839,-0.113120,-0.059102,-0.070631,0.031955,-0.019724,0.075456,0.020453,-0.050863,-0.068314,-0.000681,-0.007973,-0.007078,0.050153,0.029361,-0.046185,-0.036473,0.015387,0.028065,0.056587,-0.094002,-0.010984,0.019087,-0.069289,-0.027765,-0.059082,0.025227,0.011601,-0.000500,-0.029371,0.048577,-0.090619,-0.123844,-0.027863,0.028224,0.000535,-0.129364,-0.057459,0.006837,-0.042504,0.018358,0.066213,-0.016728,0.046329,0.059504,-0.014251,0.005446,0.092261,0.033873,0.043768,0.044972,0.018907,0.010377,0.001453,-0.012784,0.004795,0.076529,-0.031376,0.061178,0.041996,-0.013850,0.089266,0.025233,0.057706,0.017261,0.029684,-0.062645,-0.008791,-0.110273,-0.031590,-0.104761,-0.041266,0.033456,-0.053093,-0.028247,0.005277,-0.010504,0.016490,-0.016958,0.021029,-0.144161,0.042318,-0.017862,0.014535,-0.064415,-0.031891,0.005534,-0.003548,-0.000000,0.028299,-0.048146,0.035547,0.046838,-0.055222,-0.033674,0.047132,0.056980,-0.006422,0.070455,0.040918,-0.017008,0.031049,-0.010847,-0.041375,0.059624,-0.037186,-0.015125,0.032650,0.114630,-0.020689,0.058846,-0.086132,0.109765,0.038341,0.074075,0.031486,-0.030692,-0.020264,-0.093453,0.030645,-0.084510,-0.111201,-0.031115,-0.076444,0.003180,0.001952,-0.027520,-0.113340,0.044092,0.001005,0.073434,-0.082935,0.044757,0.030054,-0.025717,-0.081733,0.034689,0.023261,-0.057735,0.024434,-0.008957,0.040186,-0.026614,-0.006759,-0.082044,0.022979,0.038621,-0.129556,0.026753,0.041397,0.001654,0.037205,-0.011891,-0.001465,-0.000990,-0.026155,0.039496,-0.046137,-0.007432,-0.039458,0.021466,0.039666,0.041490,0.067237,0.015889,0.000928,-0.051473,0.004571,-0.054656,-0.064496,-0.016879,0.064129,0.088521,-0.034872,-0.010411,-0.006583,0.064146,-0.029104,0.015446,0.009899,-0.030396,-0.020139,0.080347,0.015771,-0.000000,-0.073344,-0.004747,-0.049687,0.017255,-0.003607,-0.029109,0.037577,0.063634,-0.052339,0.008628,0.025821,-0.011665,-0.068610,0.046917,0.015224,0.003369,0.018254,-0.004173,-0.026802,-0.048630,-0.010136,0.065597,0.003896,0.037951,0.018301,0.000592,0.039073,0.047300,0.117625,0.036979,-0.052532,0.046389,-0.058179,-0.017938,0.024611,0.067018,0.068666,-0.018001,-0.027935,0.039049,0.061025,-0.026152,-0.029787,-0.030583,0.072493,0.033637,-0.103820,-0.027076,0.058482,0.012085,-0.025303,-0.021042,-0.052113,0.075843,0.003589,0.047474,0.005525,0.003801,0.101010,-0.055940,0.057585,-0.068710,0.072151,0.013319] }, { name: 'insights', category: 'temporal', tier: 2, descriptionHash: '855ab4926f7a6801', embedding: [-0.063295,-0.008142,-0.038172,0.035320,0.040686,-0.016714,-0.056257,-0.003287,0.015134,-0.013824,0.003625,0.044585,-0.007921,0.031275,-0.031442,0.044995,-0.051089,-0.029658,-0.004379,-0.087946,0.005864,0.029223,0.050495,-0.007364,-0.010813,0.046810,-0.086689,-0.042294,-0.017436,-0.029906,0.015441,0.105912,0.054930,0.006903,0.039625,0.112582,-0.013149,0.016343,0.038377,-0.038804,-0.040300,-0.050240,-0.017444,0.014813,0.011559,-0.086677,-0.098450,-0.070249,-0.098581,0.075896,-0.097783,-0.061588,-0.042206,0.029136,0.008246,0.081454,-0.020084,0.040595,-0.056448,-0.059379,0.112695,-0.025232,-0.014015,-0.009531,-0.012755,0.080807,0.019995,0.031223,0.061335,-0.051002,0.010578,-0.018452,-0.063230,-0.018173,0.029556,0.022824,-0.006672,-0.058070,-0.001342,-0.169312,-0.022267,-0.035658,-0.022863,0.026652,0.041582,-0.056788,0.015566,-0.053985,0.010757,0.019046,0.051278,-0.058026,0.074028,-0.017678,0.045720,0.000945,-0.008300,-0.048410,0.024786,0.069194,-0.008031,0.079203,-0.020793,0.009091,0.067237,-0.003414,0.006468,0.011636,-0.013383,0.027493,-0.018058,0.005521,0.042896,-0.047974,0.077419,-0.021558,-0.070058,0.071013,0.017298,0.117801,0.111450,0.007351,-0.001886,-0.043286,-0.037469,0.001474,-0.024378,0.000000,0.017595,-0.040932,-0.066118,0.042636,-0.014735,-0.049733,0.004119,-0.031842,-0.068389,-0.018239,0.017547,0.071217,-0.052611,0.029461,0.019291,-0.006557,-0.046121,0.124387,0.057962,-0.016263,0.031911,0.002563,0.017743,-0.063720,0.131525,-0.017698,0.029113,-0.006087,-0.081771,-0.008083,0.003806,0.005042,0.001100,0.008354,0.036325,0.006888,0.035691,-0.060973,0.050427,-0.058276,-0.016176,0.017070,-0.013841,-0.076850,0.013712,-0.000134,0.040153,0.007312,0.038825,0.014188,-0.033648,0.034613,-0.021067,-0.041681,-0.040003,-0.026887,0.021195,-0.016114,-0.008157,-0.019636,0.111264,0.023740,-0.047121,-0.032056,-0.065580,0.078405,-0.036886,0.009887,0.068641,0.054370,-0.007860,0.027193,-0.007320,-0.009859,-0.017397,-0.086631,-0.012240,-0.015872,0.016682,-0.031038,-0.033485,-0.075074,-0.075209,0.040362,-0.000030,0.015816,0.048215,-0.056939,-0.033508,-0.005876,-0.096742,-0.007803,-0.001240,0.005309,0.014088,-0.000000,0.019582,-0.037564,-0.060406,0.081961,0.054123,0.024889,-0.090945,0.035492,0.015563,0.062908,-0.002693,0.008820,-0.036524,-0.045377,0.028222,-0.009982,-0.007162,-0.095401,-0.018318,0.108199,0.046605,-0.031605,-0.120001,0.049391,0.051344,0.052646,0.009646,-0.027193,0.019156,-0.027546,-0.016975,-0.058494,-0.033116,0.007577,-0.027853,-0.018491,0.100959,-0.180773,-0.093329,0.022668,0.093884,0.038685,-0.037316,-0.002991,-0.031772,0.059880,-0.027200,0.086657,-0.087114,-0.092333,0.105338,0.002276,-0.013072,-0.056543,-0.010290,0.060305,0.022462,-0.033421,-0.066583,0.045748,0.024946,0.059303,-0.067325,-0.015552,0.020745,-0.023447,0.002772,-0.000351,-0.151103,0.025064,0.079183,-0.004840,-0.027406,-0.090547,0.038329,-0.026243,-0.081134,-0.067797,-0.014319,-0.086898,-0.045973,-0.002054,0.049931,0.059267,0.001532,0.085472,-0.033852,0.050924,-0.002367,0.028192,-0.045562,-0.084460,-0.062257,0.012305,-0.026982,-0.000000,-0.027423,0.090977,0.002768,0.011862,0.075439,-0.037147,-0.013720,0.094814,0.054414,0.019731,0.095440,-0.043872,-0.073898,-0.035133,0.031111,-0.023116,-0.019305,0.033497,-0.040037,-0.016253,0.051564,0.077346,0.004027,-0.103212,-0.016498,-0.000260,0.007975,0.128707,0.038103,-0.006535,0.019882,0.031399,0.058017,-0.075234,0.033050,0.033512,0.067870,-0.037298,-0.007957,0.068908,-0.025023,0.066633,-0.050597,0.074426,-0.007160,-0.016750,-0.068840,-0.032860,0.027107,-0.031027,-0.014358,-0.033560,-0.024072,0.067223,0.065775,0.068417,0.079966,-0.010847,0.000171,0.026273,0.169434,-0.050325,0.011726,0.013154] }, { name: 'link', category: 'wikilinks', tier: 2, descriptionHash: 'f5991633e71ac0e6', embedding: [-0.105211,-0.051175,-0.014955,0.070203,0.094131,0.013247,0.002462,0.061895,0.003523,0.038099,0.000262,0.009244,0.018201,0.036586,-0.026886,0.121965,-0.023067,0.038931,0.040324,-0.045367,0.055688,0.048809,0.067382,-0.012725,0.025349,-0.139325,-0.134768,0.034046,-0.023531,-0.077858,0.014222,0.076492,-0.089917,-0.048617,-0.011276,0.050469,-0.028663,-0.026588,0.040878,-0.018980,0.025442,0.005891,-0.039509,0.035192,-0.039439,0.049857,-0.018329,-0.065998,-0.113633,0.117079,-0.137705,-0.029588,0.032657,-0.011592,0.027898,0.018984,-0.129855,-0.005585,0.010630,-0.074039,0.067858,-0.032616,-0.077555,-0.041351,0.002928,0.023920,-0.013358,0.078737,-0.034541,-0.025256,0.007842,-0.054307,-0.002470,0.017511,0.030964,-0.008747,-0.047385,0.016456,-0.057913,-0.093447,-0.004794,0.011713,0.049448,-0.001893,0.055055,0.060197,0.008172,-0.017526,-0.014227,0.043367,0.036180,-0.086497,0.112268,-0.031951,-0.022605,0.035890,-0.011521,-0.043530,-0.003027,0.072896,0.022479,0.038038,0.049187,-0.029073,-0.031375,-0.032972,0.051462,0.115384,0.007451,0.021359,-0.059937,-0.009478,-0.085658,-0.084651,-0.014569,-0.040287,-0.004465,-0.001215,0.089086,-0.008498,0.065111,0.031575,0.042459,0.013246,-0.063517,-0.013246,-0.031999,0.000000,0.115188,0.101182,-0.034179,-0.015912,0.017986,-0.004269,-0.078143,-0.049314,-0.097431,-0.026028,-0.052334,0.080905,-0.011248,0.012377,-0.024596,0.022708,0.003039,0.083423,-0.046848,-0.062428,0.011718,0.084491,-0.019870,0.000156,0.055500,0.003028,-0.001340,-0.013151,-0.040286,0.017924,0.027800,0.000114,0.016917,0.049588,0.070486,0.019654,-0.057675,-0.066234,-0.018768,-0.065281,0.011376,-0.004547,-0.052151,-0.011786,-0.017052,0.029821,0.026028,-0.027522,0.028279,-0.015119,0.007861,0.014754,0.020151,0.012127,0.019077,-0.004529,-0.098239,0.052583,0.020760,0.010897,0.045988,-0.003608,-0.022366,-0.074248,-0.066018,0.055597,-0.059601,0.034221,0.044492,-0.038879,-0.007190,0.015953,0.032836,0.023192,-0.038382,-0.055607,-0.115347,-0.136553,-0.028439,0.009282,-0.080226,-0.169079,-0.055861,0.036114,0.067252,-0.023551,0.035797,-0.058662,-0.024751,-0.024102,0.010495,0.020854,-0.019832,0.056418,-0.005782,-0.000000,0.075746,-0.002897,0.030092,0.034463,-0.009709,0.025326,0.002244,0.013144,0.078235,-0.000355,0.063440,-0.069930,-0.063164,0.017734,0.012112,-0.007685,0.002749,-0.044044,0.004284,0.085672,0.043681,0.015488,-0.017667,0.062590,0.016398,0.012530,0.126432,-0.022014,0.039742,-0.009333,-0.025210,0.012180,-0.063496,-0.012530,0.017962,0.029351,-0.019498,-0.004882,-0.028020,-0.007356,0.149432,-0.018531,-0.035931,0.001085,-0.019631,-0.009240,-0.079662,0.019230,-0.070051,-0.064508,0.048826,0.010655,-0.017871,-0.081734,-0.034362,0.059971,0.017234,0.025876,-0.086982,-0.001010,-0.006568,0.044154,-0.058022,0.061645,0.070019,-0.094105,-0.021322,0.011796,-0.040228,-0.015751,0.025438,-0.007740,0.008335,-0.099734,0.071584,-0.053004,0.026579,-0.034326,0.037723,-0.074485,-0.024437,0.031958,0.077181,0.006378,0.036474,-0.001893,-0.037769,0.083712,-0.023617,-0.003828,0.040877,-0.087152,0.038940,0.137603,-0.084336,-0.000000,0.005716,0.083963,-0.006980,0.021144,0.016048,0.026998,-0.003916,0.050464,-0.034483,0.031494,0.030571,0.021726,-0.121230,-0.045023,0.085973,-0.071658,-0.031606,0.061912,-0.028220,-0.031827,-0.047078,-0.009682,0.011240,0.025411,0.009235,0.004972,-0.035519,0.042622,0.015422,-0.026236,-0.008137,0.013488,-0.066525,-0.049611,-0.007290,0.068035,-0.007959,-0.057080,0.004760,-0.024400,0.066389,0.024302,-0.026597,0.062248,0.036823,0.040825,0.022060,-0.097542,0.049637,-0.097868,0.015866,-0.040273,0.046721,0.014174,-0.013605,0.095691,0.044490,0.016153,-0.036602,-0.034800,0.150135,-0.026655,0.005699,0.041633] }, - { name: 'memory', category: 'memory', tier: 1, descriptionHash: '25c2b24cc5b4a121', embedding: [-0.002967,0.029200,-0.083955,0.047693,-0.008922,0.035597,0.031361,0.014390,0.086798,0.026344,0.021194,0.043847,0.012293,0.021961,0.033802,0.043503,-0.023724,0.080508,-0.014029,-0.005713,0.054743,-0.012974,0.066345,0.025673,-0.005405,-0.034771,-0.116739,0.008610,0.019271,-0.052219,0.033640,0.033332,-0.017917,0.020729,0.059426,0.117579,-0.051498,0.019620,-0.017495,-0.098386,-0.015124,-0.028567,-0.057323,0.042753,0.007293,0.013748,-0.109922,-0.024028,-0.045192,0.034012,-0.008473,0.047890,-0.031256,0.082305,-0.008016,0.109721,-0.041072,0.024424,-0.090816,0.004906,0.031516,-0.060533,0.005070,-0.060493,-0.025348,0.058256,0.116627,0.030155,0.059583,-0.112574,-0.000900,-0.046616,-0.022092,0.016317,-0.016877,0.080597,-0.011868,-0.034861,-0.090255,-0.049962,-0.055335,-0.021476,0.020443,-0.026941,-0.004941,0.085029,-0.015044,-0.062060,-0.057902,0.007002,-0.013306,-0.087565,0.082237,-0.051530,-0.008900,0.008396,-0.007581,-0.035945,0.006247,0.014253,0.056098,0.152574,0.030106,0.027698,0.027072,-0.021758,0.055038,0.033343,-0.046887,0.002741,0.013465,0.051725,-0.010897,0.037164,0.040380,-0.055056,-0.078254,0.011770,0.032827,0.020839,0.130595,0.009821,0.032039,0.024124,-0.122094,-0.089690,0.016036,0.000000,0.029166,0.010439,-0.020506,0.018112,-0.010686,-0.003725,-0.001355,0.017039,-0.034493,0.007169,-0.043819,0.013424,-0.007580,-0.032349,-0.027837,0.021231,-0.087186,0.117433,0.097573,-0.013162,-0.004552,0.095011,0.041595,-0.035867,0.109936,0.002255,-0.024449,0.009070,-0.063154,-0.000388,-0.028850,-0.013520,0.039243,-0.000513,0.116323,0.024797,0.032259,-0.055204,-0.033803,-0.075286,0.049192,0.017142,0.020683,-0.094582,-0.106883,-0.063551,0.026213,0.001624,0.022852,-0.006859,-0.032327,0.027870,-0.094019,-0.003012,-0.018564,-0.059482,0.015619,-0.040033,0.029125,0.065765,0.013004,0.013338,-0.006823,-0.042044,-0.038654,0.024290,-0.060916,0.002978,0.012193,-0.018729,-0.020627,0.047284,0.035665,0.018163,-0.010907,-0.063236,0.021329,-0.008993,-0.041689,-0.016951,0.092749,-0.095680,-0.022799,0.107924,-0.018949,0.072079,0.052044,-0.113747,-0.037936,-0.047629,-0.023087,-0.040554,0.010356,0.010681,-0.034113,-0.000000,0.030450,-0.052261,-0.047850,0.022170,0.005827,0.026704,-0.016956,-0.019768,-0.100344,-0.029157,-0.021321,0.010115,0.021860,-0.036310,0.006852,-0.009448,-0.009422,-0.081483,0.011482,0.062847,-0.030125,-0.020484,0.018217,0.064343,0.009299,0.015792,0.004389,-0.055926,0.014352,-0.050855,0.089945,-0.012325,-0.051604,-0.005095,-0.044570,-0.131811,0.066453,-0.050308,-0.066412,0.017194,0.096315,-0.016928,-0.065133,-0.035750,0.000684,-0.005099,-0.046071,0.095695,0.042416,-0.014265,0.046727,-0.062073,-0.065587,-0.085799,-0.007729,0.026956,0.049176,-0.007128,0.013250,-0.099339,0.004731,0.033452,-0.070990,0.023513,0.047070,-0.058137,0.016700,0.028713,-0.172814,0.048942,0.035175,-0.056685,0.034382,-0.040369,0.059448,-0.017899,-0.050205,-0.098138,0.029532,-0.034668,-0.044215,0.009883,0.050426,0.054928,0.025762,0.003843,-0.036830,0.091373,-0.054554,0.011735,-0.053112,0.003541,-0.055476,0.017425,0.015579,-0.000000,-0.052828,0.037990,-0.015563,0.002230,0.012540,-0.073075,0.022081,0.122224,0.021420,0.014028,0.032270,-0.021846,-0.125723,-0.056009,-0.016955,0.017492,-0.031057,0.011510,-0.003358,-0.042194,-0.005058,-0.003061,0.049183,-0.066510,0.036679,0.014254,0.049261,0.188905,0.068821,0.001195,0.052415,0.002109,0.028756,-0.010776,0.009239,0.066083,0.069114,-0.013359,-0.007211,0.067029,-0.009168,-0.020640,-0.024787,0.094346,0.017746,0.023965,-0.042927,0.018889,0.028578,-0.044161,-0.013133,-0.035566,-0.021997,0.080537,0.005381,0.032396,0.079130,-0.033378,0.127068,-0.029876,0.123560,-0.038354,-0.015720,-0.011906] }, + { name: 'memory', category: 'memory', tier: 1, descriptionHash: '25c3d1480117aa55', embedding: [-0.006213,0.044677,-0.098899,0.020991,-0.022739,0.022756,0.030625,0.005864,0.071600,0.040999,0.018274,0.041469,0.028690,0.008951,-0.002995,0.031585,-0.012770,0.092611,-0.019567,-0.028043,0.051410,-0.001153,0.058720,0.027632,0.004861,-0.057928,-0.116350,0.012639,0.017456,-0.063673,0.020370,0.008086,-0.015193,0.006097,0.056158,0.135225,-0.037306,0.013406,-0.017500,-0.092528,-0.016865,-0.023045,-0.076035,0.048897,-0.019425,0.004336,-0.120637,-0.023169,-0.030127,0.020410,-0.025721,0.063570,-0.029167,0.085138,-0.000184,0.094039,-0.027307,0.012013,-0.099478,-0.004936,0.051246,-0.035235,0.012780,-0.064574,-0.019275,0.066077,0.130504,0.031227,0.062461,-0.101491,0.009239,-0.040696,-0.033399,0.026774,-0.045862,0.069496,-0.006621,-0.035344,-0.103452,-0.053199,-0.050336,-0.010975,0.038078,-0.028252,-0.008654,0.069102,-0.020854,-0.063638,-0.040829,0.007053,-0.012888,-0.076824,0.085296,-0.070574,0.019168,0.009349,0.001730,-0.017876,0.003483,0.021301,0.037335,0.126421,0.018446,0.003287,0.031072,-0.010827,0.038346,0.024165,-0.044437,-0.019996,0.018773,0.056296,-0.009916,0.041995,0.043767,-0.016176,-0.061915,0.016111,0.022635,0.015727,0.165094,0.022335,0.038384,0.026270,-0.118574,-0.073627,0.021748,0.000000,0.021245,0.014679,-0.031982,0.019313,-0.016512,0.012312,-0.004139,0.028073,-0.020013,0.016814,-0.043140,0.004993,-0.025625,-0.057062,-0.010166,0.024218,-0.067197,0.135890,0.081669,-0.016926,0.005972,0.083068,0.028613,-0.030272,0.112899,-0.001278,-0.016232,-0.007475,-0.067271,0.003184,-0.041058,-0.026925,0.038990,0.008723,0.101608,0.016453,0.012967,-0.065140,-0.038241,-0.087475,0.037244,0.016956,0.005208,-0.093896,-0.098504,-0.050409,-0.002500,0.028971,0.017956,0.015063,-0.011587,0.033568,-0.065737,0.015407,-0.019942,-0.054057,0.026521,-0.044154,0.038327,0.074688,0.012940,0.012025,-0.021868,-0.011722,-0.029074,0.023678,-0.065056,0.021803,0.029041,-0.001428,-0.028684,0.054404,0.022739,0.037908,-0.017000,-0.063133,0.018256,-0.021881,-0.056888,-0.020166,0.085099,-0.084381,-0.021992,0.088651,-0.025012,0.082981,0.045684,-0.086744,-0.037665,-0.057469,-0.026516,-0.016081,0.021115,0.009001,-0.041307,-0.000000,0.013373,-0.060267,-0.053484,0.031296,0.011394,0.027646,-0.034932,-0.039278,-0.121485,-0.034289,-0.024882,0.006364,0.030151,-0.026397,0.043119,-0.025673,-0.007959,-0.074109,0.021482,0.089800,-0.030128,-0.029847,0.008870,0.068950,0.022947,0.009872,-0.000240,-0.058403,0.017728,-0.047908,0.086880,-0.005219,-0.064503,-0.007616,-0.050684,-0.124248,0.063652,-0.049491,-0.068538,0.028154,0.088448,-0.002550,-0.046696,-0.024548,-0.017912,-0.004820,-0.049809,0.062047,0.051904,-0.015590,0.051706,-0.073602,-0.046255,-0.088526,-0.011426,0.030236,0.040468,-0.000557,0.013087,-0.086863,0.015062,0.035564,-0.072529,0.031442,0.050362,-0.069620,0.017278,0.016756,-0.185794,0.050022,0.074186,-0.051586,0.028572,-0.015308,0.042069,-0.001424,-0.039869,-0.109195,0.019309,-0.033953,-0.043854,0.007296,0.065126,0.019434,0.012925,-0.001428,-0.028036,0.101805,-0.055973,0.012449,-0.049762,0.003588,-0.065735,-0.001443,0.024153,-0.000000,-0.037205,0.054431,-0.019553,-0.005817,0.015843,-0.084169,0.023090,0.115240,0.026360,0.002613,0.036019,-0.014297,-0.109973,-0.054939,-0.020399,-0.003783,-0.054508,0.017112,-0.012288,-0.053327,-0.001118,-0.007262,0.032254,-0.074135,0.006286,0.007049,0.073894,0.196024,0.076203,-0.003619,0.053833,0.003667,0.041034,-0.009955,-0.008219,0.080295,0.055721,0.009164,0.004233,0.065845,-0.032550,-0.012407,-0.010689,0.086618,0.017777,0.009958,-0.057618,0.019086,0.013557,-0.037166,-0.014944,-0.055904,-0.016392,0.073052,0.020244,0.046956,0.079466,-0.026581,0.125052,-0.030950,0.113833,-0.035737,-0.008103,-0.014642] }, { name: 'note', category: 'write', tier: 1, descriptionHash: '3e8bfc6657987a66', embedding: [-0.073957,-0.026990,-0.025850,-0.000509,-0.012373,-0.007228,-0.031394,-0.010666,0.052885,0.021141,0.071385,0.070243,0.034667,-0.025462,0.002262,0.045500,-0.057889,0.051976,0.008296,0.016885,0.068006,0.000241,0.045268,0.023741,0.073587,-0.015234,-0.083013,0.020846,-0.036931,-0.086603,0.014864,0.044497,0.004478,-0.044275,0.042595,0.190474,-0.027630,-0.033967,-0.018483,-0.047596,0.036461,-0.040424,-0.030981,0.010382,-0.004960,-0.038777,-0.027746,-0.010047,-0.030849,0.058015,0.026177,-0.089892,-0.121183,0.063380,-0.016365,0.090336,-0.000152,0.067063,-0.012471,-0.015939,0.168171,0.025249,-0.014295,-0.061816,0.019035,0.003895,0.057884,0.027702,0.041907,-0.094560,0.066349,-0.001360,-0.006358,0.053214,0.022875,-0.019760,-0.019401,0.044530,-0.108252,-0.087031,0.046100,-0.012465,0.027369,0.022200,0.009654,0.042696,-0.023888,-0.075489,0.029460,0.022367,0.045795,-0.101703,0.089091,-0.054552,-0.015896,0.002146,-0.052728,-0.024412,0.043075,0.033362,0.009491,0.070758,0.043773,0.055546,0.075086,0.036604,-0.004768,0.056473,-0.060627,-0.057949,-0.007228,-0.014648,0.043888,-0.033268,-0.013523,-0.044358,-0.078010,0.044046,-0.006199,0.066572,0.109526,0.014316,-0.006660,-0.020551,-0.099970,-0.053105,-0.062204,0.000000,0.074564,0.089284,-0.064875,0.028975,0.101483,-0.062138,-0.008725,0.016298,-0.097910,-0.063115,0.049293,-0.078098,0.027976,-0.007189,-0.023207,-0.064691,-0.018222,0.062493,0.073943,-0.011719,-0.006799,0.102628,-0.032906,-0.041929,0.027460,0.007312,-0.024120,-0.070573,-0.035577,-0.026071,-0.008290,-0.023612,0.017891,0.025817,0.004379,-0.001402,-0.028445,-0.065262,0.000263,-0.071138,0.063030,0.022009,-0.077007,-0.011007,0.071706,0.006585,0.033290,0.043151,0.052190,-0.033273,0.037786,0.028961,-0.006840,0.005610,-0.078657,-0.084009,-0.016878,-0.028570,-0.016087,0.009942,0.062494,0.024741,-0.072805,0.106118,-0.044228,-0.035760,-0.023612,-0.040737,0.029890,-0.029976,-0.070778,-0.013388,-0.019833,0.016274,-0.067174,-0.104414,-0.068596,-0.026904,-0.009425,-0.053787,-0.067523,-0.038721,-0.041946,0.053459,0.041400,0.023406,0.031587,-0.184371,0.016199,-0.059929,-0.027572,-0.008578,0.018390,-0.017665,0.067254,-0.000000,0.026980,-0.019508,-0.033277,0.049222,-0.081309,0.060084,-0.008742,0.069832,-0.020723,0.026203,-0.028528,0.050147,-0.035088,-0.044311,-0.007442,-0.039405,-0.000402,-0.040369,-0.092010,0.039578,-0.019295,0.013897,-0.008507,0.087125,0.072949,-0.030516,0.029830,-0.001207,0.054510,-0.018653,-0.017218,-0.021711,-0.034229,-0.034901,0.028571,0.006573,0.035894,-0.026519,-0.059443,0.052081,0.106475,-0.017189,0.003344,-0.008586,-0.014357,0.035250,-0.012374,0.032953,-0.074198,-0.045629,0.079049,-0.056371,-0.011545,-0.105335,0.041247,0.068897,0.083915,-0.006698,-0.032037,-0.042173,0.042671,0.052511,-0.041935,0.028978,0.039179,-0.047924,-0.026856,0.020033,-0.129763,0.015819,0.005854,0.045184,0.025568,-0.094690,0.086469,-0.079264,0.009695,-0.061552,-0.067542,-0.061721,0.026909,0.011100,0.029986,0.015153,-0.018393,-0.018964,0.017105,0.056680,-0.059674,0.025250,-0.044245,0.004368,0.139692,0.019382,-0.028190,-0.000000,-0.090367,0.042894,-0.039325,-0.004452,0.023607,-0.002647,0.001741,0.088502,0.060794,0.006056,0.023131,0.002891,-0.080992,-0.053175,-0.050261,-0.031779,0.032081,0.066178,-0.038531,-0.043303,-0.037960,0.055011,-0.002725,-0.014031,0.005492,-0.046923,0.067477,0.097102,0.054436,0.005215,0.008823,-0.013734,0.046952,0.074132,-0.041623,0.033449,0.066160,0.059184,0.010081,0.064163,0.013825,0.060763,-0.043966,0.046578,-0.044959,-0.084198,-0.029994,-0.037867,0.033784,-0.059444,-0.021924,0.030415,-0.005649,0.000509,0.003831,0.095641,0.108121,0.024334,0.006746,-0.012384,0.094623,0.013422,0.073376,-0.026498] }, { name: 'policy', category: 'write', tier: 1, descriptionHash: '7a335825d5069f92', embedding: [-0.061378,0.052609,-0.034423,0.004626,0.006833,-0.013802,-0.035890,-0.038252,0.003206,0.030274,0.012406,0.044190,0.011664,-0.013780,0.083422,0.041864,-0.028673,0.061812,-0.028216,-0.090714,0.080808,0.030473,0.040385,0.038609,-0.060769,-0.036059,-0.060334,0.039777,-0.034248,-0.042992,0.036513,-0.022787,0.005725,0.023507,0.060807,0.150381,0.004177,-0.049090,-0.062982,-0.023765,-0.027615,-0.008795,-0.055033,0.008722,-0.004548,-0.126182,-0.085754,-0.079504,-0.077028,0.092748,0.001564,-0.119298,0.030999,-0.004569,0.029578,0.073398,-0.004205,-0.022485,-0.028945,-0.088355,0.012963,-0.008824,-0.066902,-0.040465,-0.051425,0.051636,0.004925,-0.002271,0.017744,-0.044561,-0.020551,-0.081026,-0.022594,-0.008973,-0.067442,0.007684,-0.020927,-0.011270,-0.056454,-0.140704,-0.022400,-0.006088,-0.003096,0.072555,-0.024475,0.017245,-0.015495,-0.024816,0.111616,0.065376,0.036297,-0.036038,0.060214,-0.059303,0.014900,0.019664,-0.033538,-0.113550,-0.038828,0.031310,0.008357,0.006774,0.026045,-0.047473,0.108552,-0.009414,0.014718,-0.015672,-0.057427,0.009571,-0.027021,0.053688,0.065104,-0.048283,0.027302,-0.000933,-0.053889,0.070040,-0.071758,0.065551,0.151602,0.059198,0.044838,-0.031363,-0.019857,-0.040957,-0.002455,0.000000,0.095560,-0.025826,-0.011906,0.042833,0.077461,-0.062565,0.060010,-0.047451,-0.056441,-0.008392,0.064395,0.082127,-0.060988,0.009099,-0.020487,0.003460,-0.041593,0.113961,0.079926,0.020959,0.008702,-0.014424,-0.020814,-0.029119,0.001131,-0.008804,-0.003407,0.023117,-0.043525,0.020880,0.051236,-0.027391,0.048720,-0.006581,0.021536,0.032533,-0.034327,0.016028,0.012491,-0.037292,0.028607,-0.037193,0.017814,-0.055966,0.020182,-0.031235,-0.009836,0.030001,0.159675,0.014262,0.072466,0.042605,-0.014475,-0.069598,0.011062,-0.075969,-0.002901,0.038648,-0.018091,0.025446,0.019665,-0.005446,-0.052538,0.007727,-0.082957,0.000060,-0.078416,-0.069555,0.000460,0.013397,-0.063853,0.053047,-0.000800,0.036706,0.018351,-0.127254,0.033498,-0.018418,-0.019411,-0.021009,-0.032147,-0.029229,-0.115651,0.109863,0.044863,0.034838,0.003602,0.029547,-0.073976,-0.021139,-0.064608,-0.082810,0.055654,-0.005954,0.083583,-0.000000,0.041057,-0.049144,-0.049130,0.061740,-0.060589,-0.029324,0.007576,-0.018926,0.029083,0.023511,-0.045863,0.019120,-0.010101,-0.013188,0.018829,-0.062253,-0.078133,-0.057670,0.003564,0.013918,0.031157,0.048149,0.023128,0.133605,0.018459,-0.016602,0.030991,0.019987,0.057942,-0.043554,0.076430,-0.048093,-0.055847,0.041188,0.010944,-0.092736,0.044392,-0.012735,-0.047860,0.057662,0.104384,-0.049476,-0.027512,-0.013061,-0.033714,0.033048,0.021910,-0.021859,-0.007963,-0.068611,-0.002212,-0.014531,-0.048863,0.041753,-0.002776,0.011227,0.040791,-0.043505,-0.026416,0.056103,-0.038767,0.074429,0.037364,0.021667,0.002587,-0.060045,-0.016504,0.005716,-0.005107,0.015654,0.004278,-0.036730,-0.036992,-0.067853,0.082298,-0.064781,-0.028886,-0.131914,-0.006349,0.037886,-0.013733,0.049623,-0.017633,0.025392,-0.004107,-0.053298,0.000010,0.070677,-0.004839,0.113657,-0.017459,-0.039279,0.005354,0.029863,-0.044276,-0.000000,-0.112675,0.050223,0.079491,0.000274,0.007282,-0.025207,0.025398,0.030352,0.029478,-0.079296,0.068184,0.035646,-0.056374,-0.050404,0.019149,-0.061238,-0.023860,0.124463,-0.032231,-0.016526,-0.037152,0.008970,-0.018234,-0.053387,-0.023472,0.068131,0.028698,0.070420,0.058540,0.055611,0.074321,-0.005207,0.079289,-0.012818,-0.063601,-0.018961,0.080501,0.001947,0.117746,0.031979,0.013938,0.002892,-0.056939,0.018994,-0.069773,0.011912,-0.062795,-0.040190,-0.001135,-0.024889,-0.009001,-0.049787,0.005540,0.089868,-0.014879,0.035921,0.108039,-0.099962,0.065499,0.003452,0.085594,-0.046928,0.099176,0.002159] }, { name: 'read', category: 'read', tier: 1, descriptionHash: 'ae72ff7d01d6bbb4', embedding: [0.000132,0.010335,-0.060510,0.036002,-0.002919,0.002965,0.004075,0.033834,0.026391,-0.025604,0.018875,0.055001,0.065242,-0.015923,0.031747,0.006773,-0.026440,0.066241,-0.001371,-0.025164,0.073077,0.065371,0.056097,-0.029799,-0.103016,0.063609,-0.179638,-0.032018,-0.042069,-0.014709,0.037949,-0.002472,0.106785,0.030330,0.042412,0.093971,-0.022410,-0.016684,-0.032050,-0.022940,-0.026277,-0.045587,-0.060382,0.049079,0.069633,-0.061013,-0.063179,-0.039923,-0.016033,0.076846,-0.016657,-0.070788,-0.030548,0.084095,0.005803,0.104547,-0.030356,0.002973,-0.031943,-0.076497,0.076568,-0.030269,-0.041384,-0.062604,-0.020591,0.040116,0.076326,0.023750,0.029941,-0.138758,0.013627,-0.000078,0.030476,0.030483,-0.017656,0.029458,-0.023475,-0.013998,-0.047322,-0.115534,-0.014175,-0.004173,0.007183,0.036348,0.015474,0.055865,-0.043056,-0.072193,0.006579,0.039187,0.056505,-0.144417,0.024595,-0.042061,-0.044986,0.054265,-0.040648,-0.056311,0.042045,0.008303,0.019886,0.053484,0.037828,0.008470,0.014319,-0.008968,0.008459,0.049849,-0.045521,-0.016889,0.000935,0.035591,0.022136,-0.033698,0.037595,-0.059531,-0.021738,-0.011808,0.006414,0.076724,0.112137,0.020812,0.019971,-0.012535,-0.061339,-0.078335,-0.038607,0.000000,0.014973,0.050502,-0.015055,0.020878,-0.050682,-0.064746,0.038573,-0.012753,-0.083533,-0.008546,0.034032,0.002093,-0.019478,0.033027,-0.053016,0.013436,-0.030818,0.075763,0.052504,-0.019793,-0.010872,0.051813,0.034311,-0.050677,0.053813,-0.026496,-0.044172,-0.060959,-0.086201,-0.004698,0.011777,-0.041339,0.036533,-0.031858,0.042711,-0.009092,0.018078,-0.016466,-0.016038,-0.075204,0.001099,0.000449,0.098104,-0.073709,-0.045295,0.022639,-0.058974,0.050169,0.062146,0.000682,0.015900,0.030625,-0.073312,-0.035595,0.010876,-0.040879,0.013805,0.039805,-0.013857,0.025666,0.064348,0.003867,0.000115,0.028688,-0.072613,0.013996,-0.050502,-0.038953,0.018088,0.016647,-0.061280,0.025325,0.013735,0.042121,-0.024177,-0.091440,-0.014690,-0.031480,0.024565,-0.039851,-0.038473,-0.046353,0.007548,0.122998,-0.067174,0.066129,0.047627,-0.141569,-0.000965,-0.123259,-0.025663,-0.044007,-0.045573,-0.092269,0.033813,-0.000000,0.087707,-0.064994,-0.039344,0.007891,-0.046343,0.046397,-0.035811,0.016138,0.027992,0.038505,-0.002606,0.078832,-0.030749,-0.008288,0.033191,0.012755,0.005661,-0.058977,0.019688,0.064116,-0.043483,-0.050179,-0.049675,0.081211,0.013369,-0.002234,-0.000350,-0.020805,0.075426,-0.027952,0.001681,-0.003359,-0.041188,0.023581,-0.070964,-0.064118,0.051521,-0.060787,-0.093732,0.062203,0.080646,0.043349,-0.019429,-0.055492,-0.029807,0.010937,0.009196,0.080164,-0.043874,-0.045242,0.069903,-0.043901,-0.023092,-0.030777,0.025240,0.083789,0.036785,0.007312,-0.037470,-0.068570,0.012623,0.107377,-0.097226,0.049900,0.026160,-0.051557,0.026413,-0.038734,-0.160092,0.012713,0.008468,-0.086909,0.070193,-0.056083,0.081252,0.010348,-0.041486,-0.068312,-0.042653,0.018218,0.007995,0.017700,0.014439,0.102174,0.036010,0.017531,-0.022273,0.068238,-0.044227,-0.000652,-0.034036,-0.046310,0.072168,0.050320,0.019010,-0.000000,-0.092256,0.018216,-0.050550,-0.021174,0.012714,0.034780,-0.007501,0.035737,-0.005349,0.000979,0.062893,-0.038277,-0.096058,-0.084872,-0.031886,0.039583,0.023157,0.034679,-0.055789,-0.015754,0.011685,0.074288,-0.034259,-0.069542,0.067289,0.060006,0.016165,0.109718,0.105964,0.017775,0.089914,0.001022,0.025548,-0.034426,0.007546,0.075671,0.103504,-0.023584,0.027519,0.134851,0.030426,-0.025303,-0.018844,0.058731,0.005602,0.021594,-0.048693,-0.017700,0.076256,-0.057563,0.000170,-0.028701,-0.004200,0.040331,-0.040411,0.045967,0.091167,-0.014190,0.073455,-0.034989,0.115306,-0.019198,0.044754,0.008180] }, diff --git a/packages/mcp-server/src/tools/write/memory.ts b/packages/mcp-server/src/tools/write/memory.ts index c9d7e4e1..dcf6635f 100644 --- a/packages/mcp-server/src/tools/write/memory.ts +++ b/packages/mcp-server/src/tools/write/memory.ts @@ -12,6 +12,7 @@ import { searchMemories, listMemories, forgetMemory, + supersedeMemories, storeSessionSummary, } from '../../core/write/memory.js'; import { runBrief } from '../read/brief.js'; @@ -25,10 +26,12 @@ export function registerMemoryTools( ): void { server.tool( 'memory', - 'Entity-linked vault facts and session summaries. action: store — save a fact (auto-links entities). get — by key. search — FTS5 over memories. list — browse. forget — delete. summarize_session — session summary. Returns stored/retrieved content. Does not operate on vault note bodies. e.g. { action:"store", key:"sarah.pref", value:"email" }', + 'Entity-linked vault facts and session summaries. action: store — save a fact (auto-links entities). get — by key. search — FTS5. list — browse. forget — delete. supersede — idempotent tombstone by thread_id or key (kept for audit). summarize_session. Returns stored content. Does not operate on vault note bodies. e.g. { action:"store", key:"sarah.pref" }', { - action: z.enum(['store', 'get', 'search', 'list', 'forget', 'summarize_session', 'brief']).describe('Operation to perform'), - key: z.string().optional().describe('[store|get|forget] Memory key (e.g., "user.pref.theme", "project.x.deadline")'), + action: z.enum(['store', 'get', 'search', 'list', 'forget', 'supersede', 'summarize_session', 'brief']).describe('Operation to perform'), + key: z.string().optional().describe('[store|get|forget|supersede] Memory key (e.g., "user.pref.theme", "project.x.deadline")'), + thread_id: z.string().optional().describe('[store|supersede] Thread correlation id (short GUID minted by the engine threads registry). store: stamps the fact. supersede: tombstones every current fact carrying the id.'), + reason: z.string().optional().describe('[supersede] Audit reason recorded on each superseded row (e.g. "thread-resolved: shipped in PR #12")'), value: z.string().optional().describe('[store] The fact/preference/observation to store (up to 2000 chars)'), type: z.enum(['fact', 'preference', 'observation', 'summary']).optional().describe('[store|search] Memory type'), entity: z.string().optional().describe('[store|search] Primary entity association'), @@ -86,6 +89,7 @@ export function registerMemoryTools( agent_id: agentId, session_id: sessionId, visibility: args.visibility ?? (agentId ? 'private' : 'shared'), + thread_id: args.thread_id, }); return { content: [{ @@ -101,7 +105,12 @@ export function registerMemoryTools( confidence: memory.confidence, visibility: memory.visibility, owner_scope: memory.owner_scope, + ...(memory.thread_id ? { thread_id: memory.thread_id } : {}), }, + // Upsert preserves supersession: a re-store on a tombstoned key + // updates content but does NOT resurrect the fact. Surface that + // so callers aren't misled by stored:true. + ...(memory.superseded_by !== null ? { still_superseded: true } : {}), }, null, 2), }], }; @@ -220,6 +229,31 @@ export function registerMemoryTools( }; } + case 'supersede': { + if (!args.thread_id && !args.key) { + return { + content: [{ type: 'text' as const, text: JSON.stringify({ error: 'supersede requires thread_id or key' }) }], + isError: true, + }; + } + const result = supersedeMemories(stateDb, { + thread_id: args.thread_id, + key: args.key, + reason: args.reason, + agent_id: agentId, + }); + return { + content: [{ + type: 'text' as const, + text: JSON.stringify({ + superseded_count: result.superseded.length, + superseded: result.superseded, + already_superseded: result.already_superseded, + }, null, 2), + }], + }; + } + case 'summarize_session': { const sid = args.session_id || sessionId; if (!sid || !args.summary) { diff --git a/packages/mcp-server/test/write/core/memorySupersede.test.ts b/packages/mcp-server/test/write/core/memorySupersede.test.ts new file mode 100644 index 00000000..943bb473 --- /dev/null +++ b/packages/mcp-server/test/write/core/memorySupersede.test.ts @@ -0,0 +1,180 @@ +/** + * Tests for thread-identity slice 1: supersedeMemories + the upsert + * resurrection fix. + * + * The release gate (plan v5): a superseded fact must never resurface in + * get/search/list after supersede — INCLUDING after a routine same-key + * cron re-store, which previously reset superseded_by = NULL. + */ + +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { + createTempVault, + cleanupTempVault, + openStateDb, + deleteStateDb, + type StateDb, +} from '../../helpers/testUtils.js'; +import { + storeMemory, + getMemory, + searchMemories, + listMemories, + supersedeMemories, + type Memory, +} from '../../../src/core/write/memory.js'; + +describe('supersedeMemories + upsert resurrection fix', () => { + let tempVault: string; + let stateDb: StateDb; + + beforeEach(async () => { + tempVault = await createTempVault(); + stateDb = openStateDb(tempVault); + }); + + afterEach(async () => { + stateDb.db.close(); + deleteStateDb(tempVault); + await cleanupTempVault(tempVault); + }); + + function rawRow(key: string): Memory | undefined { + return stateDb.db.prepare('SELECT * FROM memories WHERE key = ?').get(key) as Memory | undefined; + } + + it('v44 migration shape: thread_id + supersede_reason columns and index exist', () => { + const columns = new Set( + (stateDb.db.prepare('PRAGMA table_info(memories)').all() as Array<{ name: string }>).map((r) => r.name) + ); + expect(columns.has('thread_id')).toBe(true); + expect(columns.has('supersede_reason')).toBe(true); + + const indexes = (stateDb.db.prepare('PRAGMA index_list(memories)').all() as Array<{ name: string }>).map((r) => r.name); + expect(indexes).toContain('idx_memories_thread_id'); + }); + + it('store stamps thread_id; supersede by thread_id tombstones all current rows', () => { + storeMemory(stateDb, { key: 'fact.a', value: 'alpha fact', type: 'fact', thread_id: 'thr-abc123' }); + storeMemory(stateDb, { key: 'fact.b', value: 'beta fact', type: 'fact', thread_id: 'thr-abc123' }); + storeMemory(stateDb, { key: 'fact.c', value: 'gamma fact', type: 'fact', thread_id: 'thr-other' }); + + const result = supersedeMemories(stateDb, { thread_id: 'thr-abc123', reason: 'thread-resolved' }); + + expect(result.superseded.map((m) => m.key).sort()).toEqual(['fact.a', 'fact.b']); + expect(result.already_superseded).toBe(0); + + // Tombstoned rows vanish from every read path but are retained in the table + expect(getMemory(stateDb, 'fact.a')).toBeNull(); + expect(getMemory(stateDb, 'fact.b')).toBeNull(); + expect(getMemory(stateDb, 'fact.c')).not.toBeNull(); + expect(listMemories(stateDb).map((m) => m.key)).toEqual(['fact.c']); + expect(searchMemories(stateDb, { query: 'alpha' })).toHaveLength(0); + + const row = rawRow('fact.a'); + expect(row).toBeDefined(); + expect(row!.superseded_by).toBe(row!.id); // self-pointer tombstone + expect(row!.supersede_reason).toBe('thread-resolved'); + }); + + it('supersede is idempotent: repeat call is a counted no-op', () => { + storeMemory(stateDb, { key: 'fact.a', value: 'alpha', type: 'fact', thread_id: 'thr-x' }); + + const first = supersedeMemories(stateDb, { thread_id: 'thr-x' }); + expect(first.superseded).toHaveLength(1); + expect(first.already_superseded).toBe(0); + + const second = supersedeMemories(stateDb, { thread_id: 'thr-x' }); + expect(second.superseded).toHaveLength(0); + expect(second.already_superseded).toBe(1); + }); + + it('supersede by key tombstones the single current row in scope', () => { + storeMemory(stateDb, { key: 'fact.solo', value: 'solo', type: 'fact' }); + + const result = supersedeMemories(stateDb, { key: 'fact.solo', reason: 'closed' }); + expect(result.superseded).toHaveLength(1); + expect(getMemory(stateDb, 'fact.solo')).toBeNull(); + }); + + it('supersede requires thread_id or key', () => { + expect(() => supersedeMemories(stateDb, {})).toThrow(/thread_id or key/); + }); + + it('RELEASE GATE: same-key re-store does NOT resurrect a superseded fact', () => { + storeMemory(stateDb, { key: 'fact.cron', value: 'original', type: 'fact', thread_id: 'thr-y' }); + supersedeMemories(stateDb, { thread_id: 'thr-y', reason: 'thread-resolved' }); + expect(getMemory(stateDb, 'fact.cron')).toBeNull(); + + // The cron job idempotently re-stores the same fact — the old upsert + // reset superseded_by = NULL here and silently un-superseded it. + const restored = storeMemory(stateDb, { key: 'fact.cron', value: 'original', type: 'fact' }); + + expect(restored.superseded_by).not.toBeNull(); // store result reflects tombstone + expect(getMemory(stateDb, 'fact.cron')).toBeNull(); + expect(listMemories(stateDb).map((m) => m.key)).not.toContain('fact.cron'); + expect(searchMemories(stateDb, { query: 'original' })).toHaveLength(0); + + const row = rawRow('fact.cron'); + expect(row!.supersede_reason).toBe('thread-resolved'); // audit trail preserved + expect(row!.thread_id).toBe('thr-y'); // correlation id not stripped by re-store + }); + + it('re-store without thread_id keeps the existing thread_id; with one, updates it', () => { + storeMemory(stateDb, { key: 'fact.t', value: 'v1', type: 'fact', thread_id: 'thr-keep' }); + storeMemory(stateDb, { key: 'fact.t', value: 'v2', type: 'fact' }); + expect(rawRow('fact.t')!.thread_id).toBe('thr-keep'); + + storeMemory(stateDb, { key: 'fact.t', value: 'v3', type: 'fact', thread_id: 'thr-new' }); + expect(rawRow('fact.t')!.thread_id).toBe('thr-new'); + }); + + it('scope rule: caller without agent_id cannot supersede private facts on the thread', () => { + storeMemory(stateDb, { key: 'fact.private', value: 'secret', type: 'fact', thread_id: 'thr-z', agent_id: 'agent-1', visibility: 'private' }); + storeMemory(stateDb, { key: 'fact.global', value: 'public', type: 'fact', thread_id: 'thr-z' }); + + const result = supersedeMemories(stateDb, { thread_id: 'thr-z' }); + expect(result.superseded.map((m) => m.key)).toEqual(['fact.global']); + + // private fact untouched, still visible to its owner + expect(getMemory(stateDb, 'fact.private', 'agent-1')).not.toBeNull(); + + // owner's call closes it + const owned = supersedeMemories(stateDb, { thread_id: 'thr-z', agent_id: 'agent-1' }); + expect(owned.superseded.map((m) => m.key)).toEqual(['fact.private']); + expect(getMemory(stateDb, 'fact.private', 'agent-1')).toBeNull(); + }); + + it('supersede removes graph edges for shared/global facts (no stale memory:{key} edges)', () => { + // Seed an entity so detection creates a memory→entity edge + stateDb.db.prepare(` + INSERT INTO entities (name, name_lower, path, category) VALUES ('Kuramoto', 'kuramoto', 'notes/Kuramoto.md', 'concepts') + `).run(); + + storeMemory(stateDb, { key: 'fact.edge', value: 'Kuramoto sync threshold proven', type: 'fact', thread_id: 'thr-e' }); + const edgesBefore = stateDb.db.prepare( + "SELECT COUNT(*) as c FROM note_links WHERE note_path = 'memory:fact.edge'" + ).get() as { c: number }; + expect(edgesBefore.c).toBeGreaterThan(0); + + supersedeMemories(stateDb, { thread_id: 'thr-e' }); + const edgesAfter = stateDb.db.prepare( + "SELECT COUNT(*) as c FROM note_links WHERE note_path = 'memory:fact.edge'" + ).get() as { c: number }; + expect(edgesAfter.c).toBe(0); + }); + + it('re-store on a superseded shared fact does not resurrect graph edges', () => { + stateDb.db.prepare(` + INSERT INTO entities (name, name_lower, path, category) VALUES ('Kuramoto', 'kuramoto', 'notes/Kuramoto.md', 'concepts') + `).run(); + storeMemory(stateDb, { key: 'fact.ghost', value: 'Kuramoto fact', type: 'fact', thread_id: 'thr-g' }); + supersedeMemories(stateDb, { thread_id: 'thr-g' }); + + storeMemory(stateDb, { key: 'fact.ghost', value: 'Kuramoto fact', type: 'fact' }); + const edges = stateDb.db.prepare( + "SELECT COUNT(*) as c FROM note_links WHERE note_path = 'memory:fact.ghost'" + ).get() as { c: number }; + expect(edges.c).toBe(0); + }); +});