2 Commits
Author SHA1 Message Date
AskaEth 8a274e120d docs(memory): 到期清扫的注释改用符号引用,不再写会漂的行号
review r2(p2-1items)指出:r1 那笔注释里的行号是旧值 —— 我在文件更前面插了
12 行之后 `Stop` 整体下移,而注释里仍写着「`Stop` 在 `tidy_service.go:214` 就放锁,
到 `:219` 才 Wait」(214 是 `Stop` 的文档注释行、219 是 `s.mu.Lock()`)。

行号会漂、符号不会,因此改成符号 + 相对位置:
- 「在同一个 `func (s *TidyService) Stop` 里,`s.mu.Unlock()` 在前、`s.wg.Wait()`
  (另一个 goroutine 里)在后,两者之间没有锁」;
- 「`Start` 只在组合根启动期调一次(`cmd/cyrene/main.go` 的
  `a.memoryTidy.Start(ctx)`)、`Stop` 只在关停链里调一次(`cmd/cyrene/wire_services.go`
  的 `_ = a.memoryTidy.Stop(ctx)`)」。

同一类问题只此一处遗留(`expire.go` 里「照 `preinsert_gc.go:65-69` 的批删范式」
同样改成符号:`ingestReviewSweepBatchSize` / `maxIngestReviewSweepBatches` 那一对
常量)。已 grep 全部改动文件确认再无 `*.go:<行号>` 形式的引用。

(本提交信息刻意不复述任何行号。)
2026-10-13 21:54:38 +08:00
AskaEth a017ab6cf8 feat(memory): 临时记忆到期物理删除(有界清扫 + 同步清向量 + 删前审计)
design/23 §19 的第 ② / ③ 步:读侧时效闸(M1)只负责「看不见」,本切片负责
「真删掉」。三条护栏照 §19.3:删除是本包内唯一 DELETE 出口、有界(500 行/批 ×
20 批)、删前留审计。

- internal/runtime/memory/expire.go:扫描集合写死为「expires_at ≠ '' ∧
  expires_at ≤ now ∧ status='active' ∧ 来源非受限」。空 expires_at(长期/日常
  记忆,含 M2 登记的「INSERT 与补写之间中断」窗口)结构性进不了集合;受限来源
  复用 nonOwnerSource(与整理/审查同一处判据)。键集游标 (expires_at, rowid)
  保证被跳过的行只读一次、扫描位置一定前移。审计串 = id + persona_id + scope +
  expires_at + 按 rune 截断(48)的摘要 —— 本仓唯一一处允许携带内容片段的审计。
- internal/runtime/memory/expire_loop.go:清扫循环挂在 TidyService 的生命周期上
  (AttachExpirySweep 由组合根调用),随心跳 ctx 跑、随 Stop 停;一轮只写一行
  汇总日志,逐条的那一行进审计。
- internal/runtime/memory/vector/delete.go:新增可选删除能力 vector.Deleter +
  两个后端实现,删行时同步清向量(M1 reviewer 的 finding:过期向量占 top-K 预算)。
- cmd/cyrene/wire_memory_tidy.go:挂上清扫;顺带把已过时的「这十键」改成「这十一
  键」(M2 加了第十一键 tempTtlSec)。
2026-10-13 21:43:27 +08:00