Files
rond-with-you/.workbuddy/memory/2026-09-24.md
T
tamakyi 3f1b737a78 记忆:把 .workbuddy/memory 纳入版本控制
用户要求这份记忆跟着仓库走,而不是只留在本机。

.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`)。
2026-09-30 18:31:08 +08:00

8.1 KiB
Raw Blame History

2026-09-24 工作日志

稳定性基线实测(回答「现在稳定了吗」,把数字钉下来)

  • 覆盖率(go test -cover ./...,全套环境变量):web 53.2%、stats 62.2%、auth 50.5%、db 53.4%、 fog 52.9%、ingest 47.6%、rond 38.8%、exif 69.7%、media 64.6%、setting 85.0%、config 75.0%、 captcha 90.6%;按源码行数加权 ≈ 51%。 geo/gpx/notes/votes 报 0.0% 只是 -cover 不统计跨包执行,它们被 web/stats 的用例间接跑到。
  • 「不带环境变量 = 假绿」的规模变大了:只跑 ./internal/web/ ./internal/rond/ ./internal/stats/ (不设四件套)→ 三个包全 ok、exit=0,但 95 PASS / 86 SKIP。 原始报告基线是 62 SKIP;本轮的回归守卫几乎都带 DB 夹具 ⇒ 假绿面反而扩大。
  • 路由触达:92 条注册路由里,41 条在测试里被直接引用过(51 条没有;但不少 handler 是用函数直调 覆盖的,这个比例高估了缺口)。
  • 无 CI、无 Makefile、无 linter 配置 ⇒ 0-skip 验收完全靠人记住六个环境变量。
  • 仓库卫生:tools/__pycache__/*.pyc 已入库(编译产物);6 个 tools/*probe 探针工具在库里 (技能里写的是「用完删掉」)。
  • 未提交:48 个修改 + 38 个新增文件仍全在工作区。

P0(落地)

  • 一键验收 scripts/verify.sh(无 make,用 bash):自己从 conf/app-test.ini 取 DSN(不写死口令); 库名不含 test 直接拒跑;数 SKIP 并让非 0 失败;两段式导出(先产纯净包再全量); 支持 --fast(gofmt+vet+build)/--race/--cover/--pkg/--run。 实测:--fast 通过;DSN 指 postgres → 拒跑;缺 ROND_SRC → 拒跑;未知参数 → exit 2。
  • 仓库卫生:删掉 6 个一次性探针(colprobe/diffprobe/exportprobe/fogprobe/idprobe/sqlprobe) 与误入库的 tools/__pycache__/photo_coord_audit.cpython-313.pyc;.gitignore 补 __pycache__/、*.pyc; 新增 tools/README.md 说明留下的 4 个工具(verify_export_structure / verify_rondbackup / photo_coord_audit / audit_db.sql)与验收命令。
  • 分 3 个提交落地(工作区已干净): b4c2a84 后端(安全/数据一致性/性能)70 文件、d5f6dfa 前端(模板/CSS/JS+无障碍)18 文件、 d2e4392 验收脚本 + 工具整理 + 排查报告。每个提交都过了 go build ./... && go vet ./...。 提交顺序说明:前端守卫要读模板/静态文件,所以读前端产物的测试(frontend_fixes / tb_static / templates_test / wide_table_layout / tb_stack / map_async_cancel / map_escape)跟模板放同一提交。

P1

  • 全新库冒烟 internal/db/fresh_db_test.go:空库 → Open 自动建库 → Migrate(跑两遍验幂等) → 断言 21 张表、迁移块补出来的列(places.coord_*、三张表的 place_key…)、三张附属表的主键 已搬到坐标键、4 个索引,最后用 stats.DB{DB: d} 真打 18 个读查询(空库上不报错)。 变异验证:把 CREATE INDEX idx_place_images_key 移到 CREATE TABLE place_images 之前 ⇒ 新库报 关系 "place_images" 不存在 (SQLSTATE 42P01) 变红;同一条语句在老库上 psql -c 却提示「已存在,跳过」⇒ 正是「开发库无症、新库起不来」。已还原(git diff 空)。
  • web 整包 -race:./scripts/verify.sh --race --pkg ./internal/web/(脚本自动把 mingw 加进 PATH) ⇒ 161 PASS / 0 FAIL / 0 SKIP / 0 个 DATA RACE。此前只有迷雾索引那一条验过 race。
  • 脚本补丁:SKIP/FAIL 计数改成 ^[[:space:]]*--- ,连子测试一起数(只数顶层会漏掉子测试的跳过)。
  • 最终验收(HEAD,一条命令):244 顶层用例 / 271 含子测试 / 0 FAIL / 0 SKIP,12 包全 ok; 往返包 823/323/8/30/791/557/2246 全等、坐标 0、时间 0s、迷雾 8701 块。--fast 干净。
  • 提交:b4c2a84 后端 → d5f6dfa 前端 → d2e4392 脚本/工具/报告 → ff59412 脚本补丁。 中间提交未单独跑全量(实现与其守卫同批落地,拆开必假红),最终状态已验收。
  • 仍剩的 P2(未做):rond 38.8% 覆盖率补主路径、关键页面 CDP 冒烟、导出包真机导入(唯一终审)。

P2(落地,只做了前两项;真机导入仍需站长操作)

覆盖率:先纠正口径,rond 根本不是 38.8%

  • go test -cover 只统计「测试文件所在那个包」自己的执行。internal/rond 一半的代码 (export.go 1416 行)由 internal/web 的 TestMovementCleanExport 跑;geo/notes/votes 同理。 按 -cover 量这些包一律假报 0%(gpx 也报 0%,但那条是真的)。
  • 正确口径 -coverpkg=./internal/...:rond 82.2%(假读 38.8%)、geo 92.9%(假读 0%)、 stats 83.7%(假读 62.2%)、web 53.2%(它自己不假)。项目合计 62.3%。
  • ⚠️ 解析 profile 必须按 (文件,行段) 取 max:-coverpkg 下每个测试二进制都给同一段代码写一条, 求和 = 语句数乘份数 ⇒ 每包都像只有 1/N(第一版 awk 就这么错的,web 印成 4.4%)。
  • scripts/verify.sh --cover 已切到该口径并按包打印。

补的用例(只补「线上会走到」的,不追 nil/错误返回)

  • internal/rond/merge_clash_test.go:BuildMergePlan 的地点/活动冲突(placePick/activityPick 长期 0%,而差异页线上确实会提交这两类选择)+ 删除逐条勾选。merge.go 64.3% → 96.4%。
  • internal/gpx/gpx_test.go:该包整包零测试(0/61 语句),而它解析的是用户上传的 XML。 8 条用例覆盖 trk/rte 两分支、名字退回 metadata>name、(0,0) 丢弃、单点轨迹丢弃、非法 XML、 无轨迹点、时间错不致命、里程数值。⇒ 0% → 96.0%。
  • 两处死代码(全仓核查含模板后确认零引用):rond.Counts.Total()、gpx.Track.BBox(),已删; 没给它们写测试(给死代码补用例等于把死代码固化)。
  • 一条实测否证:gpx.haversine 没有 geo.Haversine 那道 math.Min(1,…) 夹子, 本以为会出 NaN;实测对跖点 h 最多到 1+2^-52,而 sqrt(1+2^-52) 回舍成正好 1.0, asin(1.0)=π/2 ⇒ 改不动,也没改代码,只留 TestLengthKmAntipodalIsFinite 钉住该性质。 三条 haversine 公式两个半径(6371.0 / 6371.0088)差 0.20 m/146 km,纯口径不统一。

关键页冒烟 scripts/smoke.py(16 页)

  • 三种口径:站长浏览器(200 + 落点路径 + 内容区尺寸非 0 + 零 JS 报错)、访客纯 HTTP (公开页 200、后台页必须 303 跳登录,不跟随跳转即可,比开 Chrome 快一个数量级)、 访客浏览器抽检 / 与地点详情。接进 verify.sh --smoke / --all。
  • 三个坑:①关键区块不能取 nav.nav(在 layout 里,内容块没渲染它照样在); ②用 .card 不用 div.card(专题卡片是 <a class="card topic-card">,选不中时 querySelector 返回 null ⇒ 尺寸也是 0,打印出来跟「被压成 0 宽」一模一样); ③--min-body 只兜「整页空白」(专题列表正文天生 166 字)。
  • 变异验证:timeline.html 里塞 <script>throw new Error(...)</script> (debug=true 模板热加载,不用重启)⇒ 冒烟红在「JS 报错」,而状态码/内容区尺寸全正常 ⇒ 没有这条断言就会放过它。已还原。
  • ⚠️ verify.sh 给 Windows python 传路径要用 $ABS(C:\...),传 $ROOT(/c/...) 会被拼成 C:\c\... 报 No such file。
  • site_cdp.py 不报 HTTP 状态;用 performance.getEntriesByType('navigation')[0].responseStatus。

收尾验收与提交

  • ./scripts/verify.sh ⇒ 284 PASS / 0 FAIL / 0 SKIP(P1 时 244,本轮 +新用例); --all ⇒ 冒烟 16 页全绿;--cover ⇒ 62.3%;--fast 干净。
  • 提交:05c6e97 测试与死代码 → 256620e 验收脚本与冒烟 → f2ce664 报告。工作区已干净。