# 2026-09-22 ## 第十批(P6 / P7 / P3)——性能:缓存上限、重复查询、批量往返 ### P6 `fillupCache` 无界增长 `fillup.go` 的 `fillupCache` 是全局 map 只写不清。改成**带上限的 FIFO**:超过 `fillupCacheMax`(2048) 丢最旧的四分之一(`fillupOrder` 记插入顺序),覆盖写同一键不重复记账(否则 order 比 cache 长、淘汰错删)。 守卫 `fillup_cache_test.go`;变异(阈值抬到 ×1000)⇒ 红。 ### P7 统计页「周几」查两遍 `handlers_public.go` 的 `d.Weekday` 已在 `runJobs` 的 weekday 任务里查过,渲染前又同步查了一遍 (第二个纯多余)。删掉后者。守卫 `stats_weekday_once_test.go`(`s.q.Weekday(` 必须恰好 1 次);变异 ⇒ 红。 ### P3 `adminNotesBulk` 逐条往返 三个分支原本都是 `for _, id := range ids` 逐条调 store(勾 50 个地点 = 50 次、清空 100 次往返)。 新增 `notes.DeleteBulk` / `notes.SetNoteBulk` / `votes.SaveVerdictBulk`,统一用 `p.src_pk = ANY($3::bigint[])`。 `SetNoteBulk` 两条语句等价于逐条 `SetNote(..., "")`:先删「别名与 rond 备注都空」的行、再清其余行的 手写 note(顺带把 `dataset_id/src_pk` 刷成当前数据集的值,与逐条 upsert 对齐)。 守卫 `admin_notes_bulk_test.go`:①静态扫描(函数体不许再出现逐条的 `Delete(`/`SetNote(`/`SaveVerdict(`、 必须有三个 `*Bulk`);②端到端(3 个地点依次走 结论/清空/取消/删除,每步断言**全部**生效)。 变异:①退回逐条循环 ⇒ 静态守卫红;②给批量 INSERT 加 `LIMIT 1` ⇒ 端到端红(「实际 1」)。 **新事实**:pgx v5 stdlib(走 `database/sql`)**直接接受 `[]int64` 作为 `ANY($3::bigint[])` 的数组参数**, 既不用 `pq.Array`,也不必手写 `IN` 占位符——实测通过(`TestAdminNotesBulkAppliesToEveryCheckedPlace`)。 ### 第十批验收 - 全量 `go test -count=1 -v ./...`:**234 PASS / 0 FAIL / 0 SKIP,exit=0**(第十批新增 4 条)。 - 两段式导出 823/323/8/30/791/557/2246 全等、坐标 0.000000000、时间 0s;迷雾 8701 块逐字节一致(未碰 rond 数据路径)。 - → 已更新 `audit-2026-09-21.md`(新增「修复记录(第十批)」+ 重写「尚未处理」表,删掉 P3/P6/P7; 「尚未处理」只剩 F5/F6/F8–F10/F14/F16–F18 这批前端交互/无障碍细节)。 ## 收尾:MEMORY.md 精简(注入被截断) `.workbuddy/memory/MEMORY.md` 注入时被截断——尾部「安全/跳转」「口径/404/验收」两节根本进不来, 等于白写。就地精简:**12452 → 8888 字符(-29%)**,保留全部规矩与守卫名,把「验证机制细节」 (四件套环境变量之外的那些:静态守卫禁相对路径、`?` 绑定顺序、`-race` 的 mingw PATH 等) 指向技能 `rond-fix-verify`,只留两个最容易「假绿」的坑(缺 `ROND_SRC` 静默 skip、共用库写数据集串味)。 (随后第十批又补了 2 条性能规矩,当前 9277 字符 —— 已贴近注入上限,**后续新规矩优先写进 `MEMORY-details.md` 或技能,别再往这个索引里堆**。)