feat(memory): 记忆整理 v1(design/23)——低峰定期扫描 + 事实包含判定 + 规则否决 + 只产建议队列(不自动应用)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

This commit is contained in:
AskaEth committed 2026-10-05 11:29:36 +08:00
1 parent 012e9f3ad4
commit 91a3209c9b
25 files changed
+3418 -13

No files matched your search

@@ -0,0 +1,14 @@
-- 0019 的回滚:先删索引(否则 SQLite 拒绝 DROP COLUMN),再删两张新表,
-- 最后按逆序删掉 memory_items 的整理列。
DROP INDEX IF EXISTS idx_memory_tidy_runs_started_at;
DROP TABLE IF EXISTS memory_tidy_runs;
DROP INDEX IF EXISTS idx_memory_tidy_candidates_status;
DROP TABLE IF EXISTS memory_tidy_candidates;
DROP INDEX IF EXISTS idx_memory_items_status;
ALTER TABLE memory_items DROP COLUMN expires_at;
ALTER TABLE memory_items DROP COLUMN valid_to;
ALTER TABLE memory_items DROP COLUMN occurred_at;
ALTER TABLE memory_items DROP COLUMN merge_count;
ALTER TABLE memory_items DROP COLUMN merged_from;
ALTER TABLE memory_items DROP COLUMN merged_into;
ALTER TABLE memory_items DROP COLUMN status;
@@ -0,0 +1,58 @@
-- 记忆整理与去重(design/23)。本迁移只落「建议侧」的结构:
-- ① memory_items 的整理列(全部带默认值 ⇒ 既有行行为逐字不变);
-- ② 整理候选表 memory_tidy_candidates(人工确认队列);
-- ③ 整理运行表 memory_tidy_runs(留痕,不靠会话)。
-- 第一版**不自动应用任何动作**(design/23 §7),因此 ① 的新列在此版本里
-- 只被读取(扫描过滤 status='active'),不被本迁移之后的代码改写。
ALTER TABLE memory_items ADD COLUMN status TEXT NOT NULL DEFAULT 'active';
ALTER TABLE memory_items ADD COLUMN merged_into TEXT NOT NULL DEFAULT '';
ALTER TABLE memory_items ADD COLUMN merged_from TEXT NOT NULL DEFAULT '[]';
ALTER TABLE memory_items ADD COLUMN merge_count INTEGER NOT NULL DEFAULT 1;
ALTER TABLE memory_items ADD COLUMN occurred_at TEXT NOT NULL DEFAULT '';
ALTER TABLE memory_items ADD COLUMN valid_to TEXT NOT NULL DEFAULT '';
ALTER TABLE memory_items ADD COLUMN expires_at TEXT NOT NULL DEFAULT '';
CREATE INDEX IF NOT EXISTS idx_memory_items_status
ON memory_items (persona_id, status);
CREATE TABLE IF NOT EXISTS memory_tidy_candidates (
id TEXT PRIMARY KEY,
persona_id TEXT NOT NULL,
scope TEXT NOT NULL,
project_id TEXT NOT NULL DEFAULT '',
kind TEXT NOT NULL DEFAULT '',
action TEXT NOT NULL,
source_ids TEXT NOT NULL DEFAULT '[]',
target_id TEXT NOT NULL DEFAULT '',
proposed_content TEXT NOT NULL DEFAULT '',
merged_content TEXT NOT NULL DEFAULT '',
reason TEXT NOT NULL DEFAULT '',
evidence TEXT NOT NULL DEFAULT '{}',
rule_version TEXT NOT NULL DEFAULT '',
score_min REAL NOT NULL DEFAULT 0,
score_max REAL NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'pending',
idempotency_key TEXT NOT NULL UNIQUE,
created_at TEXT NOT NULL,
decided_at TEXT NOT NULL DEFAULT '',
decided_by TEXT NOT NULL DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_memory_tidy_candidates_status
ON memory_tidy_candidates (status, scope);
CREATE TABLE IF NOT EXISTS memory_tidy_runs (
id TEXT PRIMARY KEY,
started_at TEXT NOT NULL,
finished_at TEXT NOT NULL DEFAULT '',
scanned INTEGER NOT NULL DEFAULT 0,
candidates INTEGER NOT NULL DEFAULT 0,
applied INTEGER NOT NULL DEFAULT 0,
skipped INTEGER NOT NULL DEFAULT 0,
errors INTEGER NOT NULL DEFAULT 0,
vetoed INTEGER NOT NULL DEFAULT 0,
veto_reasons TEXT NOT NULL DEFAULT '{}',
rule_version TEXT NOT NULL DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_memory_tidy_runs_started_at
ON memory_tidy_runs (started_at);