Files
SimpleFarm/.workbuddy/memory/2026-09-23.md
T
snowy-yang d1692d7b10 docs: 记忆与验收技能跟上——存档改动必须真机验自动落盘
单元测试抓不住 autosave 失效(dirty 被高频清零这件事测试里复现
不了真机时序),所以技能里加一条:动了存档/会话层,必须 0 客户端
在线做一个动作、等 60s、直接查库那一行有没有更新。
2026-09-23 20:54:13 +08:00

2.3 KiB
Raw Blame History

2026-09-23 修网页版「点播种没反应」+ 顺手挖出自动存档失效的真 bug

  • 用户报网页版点播种没反应。服务端 plant 动作完全正常 → 定位到前端。
  • 根因 1(前端):播种按钮走 window.prompt 选作物,重置走 window.confirm ——这俩在 sandbox iframe(内置预览面板)里会被静默屏蔽:不弹窗、直接返回 null,于是"点了没反应"。普通浏览器里是好的,所以一直没暴露。 修复:改成页面内弹层(#pickmask + openCropPick,未锁定作物生成按钮 + 取消按钮,点遮罩关闭);重置改两步确认(第一次点变"再点一次确认",3 秒还原)。
  • 根因 2(后端,真 bug):顺着验证存档时发现 default 牧场根本没写进库 ——内存里每次重启都是新档。排查出 session.dirty 一个标志位伺二主: Publisher 推送循环每 ~250ms 就把 dirty 清掉(无人在线时更是直接清), 而 autosave() 每 60s 才看一眼 dirty——窗口太小,自动存档几乎永远不触发 (约 0.4% 撞率)。进度只在手动存档/优雅停机时落盘,进程被强杀就全丢。 修复:新增 session.unsaved 专管「有变化没落盘」,_on_change/load/ touch/advance_day 置位、只有成功的 save() 清位;autosave() 改看 unsaved;dirty 继续只管推送节流。hub.py 的推送循环一字未动。
  • 两只旧测试(test_autosave_skips_when_clean / ..._writes_when_dirty / autosave_all...)直接操纵 dirty 驱动 autosave,固化了被修掉的耦合—— 全部改成用 unsaved 表达意图。新增回归测试: 「推送循环清了 dirty 也要照常落盘」「没有新变化不重复写库」。
  • 真机验证:0 客户端在线、纯 HTTP 种一块地,70 秒内看到库行更新 (gold 120→112,种子钱都对得上)。
  • 门禁:ruff/pyright 全绿,515 项测试 OK(skip 35)。

教训

  • 嵌入预览面板里 window.prompt/confirm/alert 都不可信,交互一律用页面内 弹层实现。
  • 一个布尔标志被两个子系统共用时,其中一个高频清零,另一个低频读取—— 低频的那个等于瞎了。存盘依据必须由"成功的写入"来清。