package memory // schema DDL。internal/db 中的迁移框架是领域表的权威 // 机制,但这里刻意不用它:db 包的迁移测试断言精确的 // 迁移数量,而记忆存储必须自包含、 // 可在任意 *sql.DB 上使用。表与索引因此 // 由 NewStore 幂等创建。 const createMemoryItemsTable = ` CREATE TABLE IF NOT EXISTS memory_items ( id TEXT PRIMARY KEY, persona_id TEXT NOT NULL, role_id TEXT NOT NULL DEFAULT '', project_id TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL, kind TEXT NOT NULL, content TEXT NOT NULL, tags TEXT NOT NULL DEFAULT '[]', confidence REAL NOT NULL DEFAULT 1.0, source_conversation TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, decay_weight REAL NOT NULL DEFAULT 1.0, status TEXT NOT NULL DEFAULT 'active', merged_into TEXT NOT NULL DEFAULT '', merged_from TEXT NOT NULL DEFAULT '[]', merge_count INTEGER NOT NULL DEFAULT 1, occurred_at TEXT NOT NULL DEFAULT '', valid_to TEXT NOT NULL DEFAULT '', expires_at TEXT NOT NULL DEFAULT '', retention_tier TEXT NOT NULL DEFAULT '', temporal TEXT NOT NULL DEFAULT '', sensitive INTEGER NOT NULL DEFAULT 0 )` const createMemoryItemsPersonaIndex = ` CREATE INDEX IF NOT EXISTS idx_memory_items_persona_id ON memory_items (persona_id)` const createMemoryItemsPersonaCreatedIndex = ` CREATE INDEX IF NOT EXISTS idx_memory_items_persona_id_created_at ON memory_items (persona_id, created_at)` // createMemoryItemsRetentionTierIndex 是「留多久 / 干什么用」轴的读侧索引(迁移 0026)。 // 三条列表读路径的可选档位过滤(`retention_tier IN (...)`)与「只看未分型的行」 // (回填分型的入口)都吃它。列**必须**排在 CREATE TABLE 的最后:迁移的 // `ALTER TABLE ADD COLUMN` 也把新列追加在末尾,两份 DDL 才逐列同形 // (retention_migration_test.go 钉住这条同形,少一列就是「新库有、老库无」的漂移)。 // // ⚠️ 0027 之后 `retention_tier` **不再是最后一列**:`temporal`(迁移 0027)追加在 // 它之后,0028 又把 `sensitive` 追加在 `temporal` 之后。两条路径的尾序都是 // `… expires_at, retention_tier, temporal, sensitive`。新列一律追加在末尾这条口径 // 不变,只是「末尾」会随迁移推进(那条同形断言比对**列集合**,另外对尾序做一条 // 显式断言)。 const createMemoryItemsRetentionTierIndex = ` CREATE INDEX IF NOT EXISTS idx_memory_items_retention_tier ON memory_items (retention_tier)`