用户要求这份记忆跟着仓库走,而不是只留在本机。 .gitignore 里挡路的是 `.workbuddy/`。改成反忽略六行,并且**只放行 .md**: 别用 `!.workbuddy/memory/**`——它会把 memory 下任何文件都放行,本项目真发生过 `web.test.exe` 混进暂存。复核用 `git check-ignore -q --no-index` 逐条打靶: memory/*.png、memory/sub/x.md、memory/MEMORY.md.bak、plans/a.md 全 IGNORED, 17 个 .md 全 included;`git add -An .workbuddy/` 恰好 16 个文件。 其余 .workbuddy 内容(计划、本地设置、临时产物)继续忽略。记忆里没有真凭据 (唯一命中是 2026-09-14.md 里的 `password=rond-admin`,那是项目默认口令)。 顺带做两件整理: 1. 取证了注入上限。以前按「字节数」判断 MEMORY.md 是否超限是错的: WorkBuddy 的 `getWorkingMemoryContent()` 用 `MAX_MEMORY_CHARS = 1e4` 比 JS `content.length`,即**字符数**(中文 1 字算 1);超了 substring 截断、尾部静默丢失。 本 details 与每日日志都不参与注入,只有 MEMORY.md 受约束。 现已从 6604 字符收到上限的 66%,并把这条上限写进索引抬头。 2. 把「备份合并」「导出/恢复三条铁律」两段长文迁进 MEMORY-details.md 的卅一/卅二节, 索引只留关键词指针。行尾统一为 LF(仓库 .gitattributes 是 `* text=auto eol=lf`)。
6.8 KiB
2026-09-28
rondbackup「差异分析 → 合并执行」实测(真机导出包 20260928_183908)
环境 conf/app.ini(库 rond_with_you、data_dir=storage/data、:8080),数据集 id=9;
把真机新导出的 data/20260928_183908.rondbackup(955 到访 / 432 地点)合并进已有 867 到访的数据集。
主链路生效(真跑路由 + 站长登录):POST /admin/preview → GET 差异页 → POST /admin/preview/{token}/merge,
add_new=1、冲突留默认 ⇒ 新增 70 地点 / 1 活动 / 134 到访,随到访带入 24 位移 / 32 天气;
到访 867→1001、地点 368→438、位移 791→815、天气 557→589;孤儿位移 0、无地点到访 0、重复 UUID 0 组。
逐条核对:备份里 953 条带 UUID 的到访全部命中且到达时间微秒级零误差;站内 2 条 app 已删的 UUID 到访被正确保留。
合并后 12 个关键页全 200。报告:storage/.mergetest/报告-rondbackup合并实测-20260928.md
三个问题
- 🟠 同名同坐标的重复地点不幂等:
DiffPlaces的byCoord/byName是单槽位 map +used[], 同一坐标下 N 条备份地点最多只能配 2 条 ⇒ 第 3 条永远判「备份新增」,每次合并多插一条。 实测备份里同名同坐标共 10 组、只有「柳州站」count=3 ⇒ 每次合并固定多 1 个重复地点,差异永不归零 (438→439→…)。修法:多值 map 逐条消费 +mergePlacesINSERT 前按PlaceCoordKey去重兜底。 - 🟠 到访冲突被「活动改名」放大:
visitFieldChanges比的是活动名称不是身份;16 个活动改名 (餐厅→吃饭…)⇒ 355 条到访冲突全部同因(库内挂在改名活动下的 378 条 − 站内独有 23 条 = 355,精确吻合), 活动类型本身只报 16 条。且对到访选「用实机」不会改活动名(activity_id按 UUID 映射回同一个) ⇒ 冲突永不收敛。修法:到访层面按活动身份(ZUID_/id)比对,改名只在活动层报一次。 - 🟡 21 个长沙地点两边坐标差 661~748m,实测 20 条满足「站内坐标 == 反纠偏(备份坐标)」
⇒ 坐标系不一致(站内那侧被多做了一次 GCJ→WGS 反向换算);差异页冲突的默认选项是「用实机」,
直接点合并会把这批坐标覆盖、地图上跳 ~660m。另有 分类 12 处(站内中文标签 vs 备份
MKPOICategory*原始枚举)。
备份 / 回滚:storage/.mergetest/rond_with_you-before-20260928.sql(整库 pg_dump);
差异页快照 diff-before-merge.html / diff-after-merge.html。库内最终状态 = 合并一次(我重复跑测试
多插的 1 个重复地点已回退)。
方法(可复用):临时 Go 测试(package web,才能拿到非导出的 srv.captcha)——
httptest.NewServer(srv.Handler()) + cookie jar + CheckRedirect: http.ErrUseLastResponse
(站点用 303,必须关掉自动跟随才能读到 Location);验证码答案直接读 captcha.Store.Answer(id),
绕开图像识别;管理员口令是默认 rond-admin(pbkdf2 可离线核对)。跑完删掉测试文件,git status 保持干净。
同日晚:修复 + 复测(回档数据库后重跑)
按上面前两条问题改了代码,5 个文件 +172/−22:
internal/rond/diff.goDiffPlaces:byCoord/byName由单槽位 map 改为多值索引(map[string][]StoredPlace), 抽出take()逐条认领未使用的候选(认领即置used)。classify不再自己置 used。internal/rond/diff.govisitFieldChanges:到访的「活动」改为按身份比(新增参数actUUID), 两边都缺 UUID 才退回名称;DiffVisits传入b.ActivityUUID。StoredVisit新增ActivityUUID。internal/web/backup_diff.goloadStoredVisits:多 JOIN 一次entity_raw(entity='ZACTIVITY',按a.src_pk)取ZUID_。
复测结果(回档 → 重跑同一份备份,同环境):到访冲突 253 → 6(247 条活动改名假冲突消失); 地点新增 70 → 67,合并后再比对 地点新增 1 → 0;再点合并由「再插 1 个重复地点」变成 「按当前的选择没有要写入的改动,数据未变」,地点 435→435、「柳州站」稳定 3 条。 到访 1001 / 位移 815 / 天气 589 与修复前一致;953 条 UUID 到访全命中、到达时间 0 偏差、孤儿位移 0。
新增守护:TestDiffPlacesAlignsDuplicateNameCoordGroups(含「站内真少两条仍报新增 2」反向断言)、
TestDiffVisitsIgnoresActivityRename、TestDiffVisitsReportsActivityChange、
TestDiffVisitsActivityWithoutUUIDFallsBackToName;TestBackupDiffIdentical 补地点新增断言、
两个 merge 幂等用例补「地点差异归零」。变异验证:把两处改回旧逻辑,对应用例确实全挂
(⚠️ 变异要忠于旧行为:旧 byCoord 是 map「后者覆盖前者」=取最后一条;我第一次写成「取第一条」,
误报 8 条,与真实旧行为不符,改用 byCoord[k] = []StoredPlace{sp} + byName 只留第一条才复现出正确的 1 条)。
仍未动:21~24 个长沙地点坐标系差 ~660m(默认「用实机」会覆盖站内;现连带 25 条到访「地点」冲突)、
分类 12 处中文标签 vs MKPOICategory* 枚举、16 个活动改名需选「用实机」才同步。
报告已更新为「实测 → 修复 → 复测」完整版。
收尾:回滚 + 推送 + 重建(19:35)
- 回滚:
DROP/CREATE rond_with_you+ 恢复storage/.mergetest/rond_with_you-before-20260928.sql, 核对回到合并前基线 867 到访 / 368 地点 / 31 活动 / 791 位移 / 557 天气 / 2538 留档 / 柳州站 3。 - 推送:提交
10d23e0(5 文件 +172/−22),git push origin master(远端git.shiroko.one)。 本地原本就领先远端 8 个提交,一并推上去了(78865fc..10d23e0)。 ⚠️ 推送凭据陷阱:~/.git-credentials(store)与 GCM 里缓存的 token 都已失效 (remote: Failed to authenticate user),SSH 22 端口Network is unreachable(只有 HTTP 代理http.proxy=http://100.104.48.63:11882能通)。别加GIT_TERMINAL_PROMPT=0——它会让 GCM 直接放弃认证;去掉这个变量、让 GCM 自己走一遍交互认证即可成功(13 秒完成)。 - 重建:
go build -o bin/rond.exe .(bin/rond.exe原本还是 9-20 的旧构建,不含修复; 旧文件留了副本bin/rond.exe.bak-20260920)。只读冒烟:/healthz//admin/login均 200、/admin303,随后taskkill //F //IM rond.exe停掉、8080 释放,库内计数不变。 - 注意:
go build那次bin/rond.exe~(9-20 12:14 的更旧副本)不见了;原因未查明, 两个都是修复前的旧产物,无实际损失。