AskaEth
91101dedfb
feat(memory): M45 提取器时间性元数据位 temporal 驱动留存判定
背景(M37 复审的原话):「真正卡住上游的是提取器的改写:一次性事件被写成
30~80 字的第三人称长期陈述……这不是阈值问题,是判定链缺信息位。」本片补的
就是那一位,不动 N1~N7 的任何阈值。
产出侧
- temporal.go:TemporalKind 闭集(one_off / recurring / durable / unknown,
空串 = 未分型),normalizeTemporal 只认四个字面值,其余一律归 unknown(绝不猜
同义词);提取提示词追加该枚举(模型只负责标注,判定在 Go 闭集 switch 里)。
- llmextractor:候选解析后归一并随 MemoryItem 带出;非法/缺失值不报错、不拖累
同批其他候选。
落库
- 迁移 0027_memory_temporal(up: ADD COLUMN temporal TEXT NOT NULL DEFAULT '';
down: DROP COLUMN,只撤结构、不改写任何行数据)+ NewStore 的自举前滚
(duplicate column 是预期路径);Store.Add 的同一笔 INSERT 写该列,判定与
留痕不分叉。
判定(仍是 resolveRetention 一处收口,judgeIngest 一字未改)
- one_off ⇒ temp(+ expires_at),但先过 temporalSanityVeto 六条语义安全阀:
显式「记住」/ 在陈述约定 / 习惯词 / 硬性长期事实词 / 永久化 / 状态改变 ——
命中即不给结论、落回 N1~N7。依据是离线重放的实测:去掉「记住+约定」两条时
21 条长期约定会被判 temp(4.80%),全开后在最近 500 条窗口内翻转条数为 0。
- durable / recurring ⇒ long 且不再跑规则;unknown / 未分型 ⇒ 落回 N1~N7
(不许因为「正文看着像今天的事」就判 temp)。
- IngestRuleVersion d3.4 → d3.5(判定结论会变,留痕必须可分)。
验证
- go build ./... + go vet ./... 全绿;go test -count=1 ./internal/runtime/memory/...
./internal/db/... 全绿;memory -race 全绿。
- 新增 temporal_test.go(验收点 ①~⑤ + 两条交叉护栏 + 闭集/归一化)与
temporal_migration_test.go(0027 up/down/同形/真实启动顺序)。变异实测:
摘掉 one_off 支路 ⇒ ① 全红;关掉 temporalSanityVeto ⇒ 三条护栏用例全红。
- 迁移测试的「回滚 N 步」改为从 schema_migrations 现算(migrateDownToBefore),
新加一条迁移不再打红 0025/0026 的用例。
2026-10-26 18:57:38 +08:00
..
2026-10-26 18:57:38 +08:00
2026-09-06 10:40:06 +08:00
2026-09-06 10:39:27 +08:00
2026-10-05 13:47:25 +08:00
2026-10-04 17:07:24 +08:00
2026-10-05 16:19:32 +08:00
2026-10-03 16:47:55 +08:00
2026-10-03 20:12:29 +08:00
2026-10-03 20:12:29 +08:00
2026-10-05 09:46:10 +08:00
2026-10-06 09:04:06 +08:00
2026-09-06 04:26:02 +08:00