Skip to content

专题验证(verification)

常驻目录。这里的文档不归档,跟着代码一起活到项目结束。 最后更新以 git log -1 -- docs/verification/README.md 为准(散文里的日期同样会漂)。


这个目录是什么

爆炸半径划分的专题验证清单,每份对应一个「出问题会静默、用户不会报障」的域。 功能迭代之后重跑对应专题,确认这一域仍然收敛。

docs/plans/ 的区别不是重要性,是生命周期:

docs/plans/本目录
用途一次性方案,做完就归档反复重跑的清单
现状一次性方案,做完即归档(现数:ls docs/plans/*.md docs/plans/archive/*.md | wc -l只增不 archive
放错的后果——清单被排进归档队列,下轮没人找得到

docs/smoke-test-runbook.md(发版前冒烟)是同一体裁的先例,暂留原处不动。


🔴 三层分工:只有中间一层是文档

这是本目录最重要的一条规矩。违反它,清单会变成第二本账。

放哪形态
机械层
能用数字或集合表达的
代码scripts/<专题>-verify.sh 或单测assert
判断层
要看上下文才能判的
本目录的 <专题>.md问句 + 假绿风险
每轮产物不留拆散进 CHANGELOG / backlog / 本清单的「已知未修」

为什么机械项必须下沉成断言

docs/plans/archive/admin-ops-acceptance-handoff.md 把机械项写成了散文清单。 2026-08-25 那轮复验实测出它自己有 4 处数字过期:测试通过数(写 70,实际 69/1 skipped)、 凭据条数(一处写 9 一处写 11)、探测 URL(还是换域名前的)、两处互相矛盾的通过基线。

散文里的数字必然漂移,而且是静默漂移——你照着过期的清单查,还以为查过了。 断言过期时会红,散文过期时不会。

为什么每轮报告要丢掉

留 10 份历史报告 = 回到 10 本烂账。价值应当当场拆散:

  • 修好的 → CHANGELOG.md(移动端的修复记 rvh/CHANGELOG.md —— as-built 每端各一份)
  • 待修的 → docs/plans/backlog.md
  • 有意不修的 → 本清单的「已知未修」节,且必须带「什么条件下重新处理」
  • 趋势 → 清单顶部的「验收台账」表,每轮一行

🚫 清单里不许出现的东西

数值快照。 「当前 DB 18.7MB / cron 5 个 / 测试 70 passed」这类。 它们看起来很有用("用于识别漂移"),实际是这份文档腐烂速度最快的部分, 而且腐烂后会主动误导:读的人会拿过期数字当期望值。

要现状就现查——scripts/<专题>-verify.sh 会打出来,且永远是新鲜的。

判据一律用**「怎么算对」的问句**表述,不用「应该等于 N」。


一份清单必须有的四节

  1. 判据表 —— 每行一个问句 + 一列「假绿风险」
  2. 反向验证配方 —— 怎么造一个失败输入,确认它真的会变红
  3. 已知未修 / 有意接受 —— 带重启条件(形同 ADR)
  4. 验收台账 —— 每轮一行:日期 / 版本 / 一句话结论 / commit

🔑 清单里最值钱的是「假绿风险」那一列

功能清单可以从代码重新生成,「这一格为什么可能骗你」不能——那是踩出来的。

所以清单的定位不是「功能覆盖表」,是失效模式的账本。 随着轮次推进,它应该在假绿列变长、在机械列变短(机械项不断下沉成断言)。

判断层反复要问的那句话:

如果它要判的那件事变了,这个数字会不会跟着变? 变不了,就是接错线——无论它当前显示什么颜色。


三种结果的语义

脚本与人工判断共用同一套,别把第三种读成第一种

  • PASS 拿到了值,且值对
  • FAIL 拿到了值,值不对
  • ⏭️ SKIP 没拿到值(缺凭据 / 网络不通 / 需人工介入)——这是「本次没验」

「取不到 ≠ 正常」是这套系统反复栽的跟头。任何一项 SKIP,整体就不是绿的ops-verify.sh 为此把退出码分成 0/1/2)。

同理:恒红的闸门与恒绿的一样坏。一道因为与所守之物无关的原因而常红的检查, 会让人学会忽略它。看到红的先问「它为什么红」—— 2026-08-25 抓到的 CI Rust 恒红 17 次(行尾问题,与它守的 schema 无关)就是这个形状。


现有专题

专题清单机械层覆盖
运维监控ops-monitoring.mdscripts/ops-verify.sh(24 条)备份心跳 / 巡检 / 容量 / 探测 / 告警通道 / 凭据台账 / 发布链路
同步与多端一致性sync-consistency.mdcargo test --lib sync(源码层)+ scripts/sync-verify.sh(14 条,部署态)同步矩阵完备性 / 红线 #5·#5b·#5i·#6b·#6d / 远端 trigger·RLS / PGRST204 契约
隐私与鉴权privacy-auth.mdpnpm --dir admin test(构建态+源码层)+ scripts/privacy-verify.sh(16 条,部署态)门与锁 / 红线 #2 聚合 / 密钥不下发 / 全库隐私分桶 / definer 授权 / Storage 桶 / 生产站点实测
发版链路release-chain.mdscripts/release-verify.sh(17 条 + --deep 再 1 条)updater 接线 / endpoint 匿名可取 / 平台键 vs 构建矩阵 / 资产可下 / 签名密钥与制品验签 / semver 可升级性 / 公开 Release 非草稿 / 下载直链 / 发版凭据
数据基线与迁移data-baseline.mdcargo test --lib db::migrations(18 条,源码层)+ scripts/migration-verify.sh(10 条,本机层)已出厂迁移的字节冻结(含 v28+ 内联 SQL)/ 冻结名单覆盖面 / 指纹清单 vs 发布 tag / 本机存量库 _sqlx_migrations 与 HEAD 逐条比 / 非空存量库升级 / 幂等加法式 / §10 登记
学习循环(查词/生词/SRS)learning-loop.mdcargo test --lib -- srs:: vocab_scope:: lemmatizer::(43 条,源码层)+ scripts/learning-loop-verify.sh(L 段跨仓 + M 段部署态)SM-2 三端黄金向量的锁还连着吗 / mastery 阶梯(向量管不到的第二个跨端纯函数)/ 红线 #9 结构守卫 / 专名三角色 / 共享表时间戳的 UTC 标识符与排期语义
上下文预算(恒加载区棘轮)context-budget.md../../scripts/context-budget.sh —— 🔴 仪表非闸门,恒 exit 0恒加载合计 / 分节 Top6 / 记忆库是否在用 / 与上轮台账对比

待建(按爆炸半径排,都是「静默失效」域)

专题为什么值得单列
阅读内容管线快照三态回落,缺一态 = 换设备后正文永久丢失

「学习循环」原本列在这里,理由写着 「用户会自己报障,优先级低」。 2026-08-27 建成时那句话被推翻了:用户报得出来的只有「卡片没出现」, 报不出来的是「卡片出现得不对」 —— 那一轮当场抓到一个跨端排期缺陷, 六道既有守卫在同一批数据面前全绿。「用户会报障」不是不建专题的理由, 要问的是「他报得出这一类失效吗」。


怎么跑一轮

bash
./scripts/ops-verify.sh                              # 运维监控
cargo test --lib sync && ./scripts/sync-verify.sh    # 同步与多端一致性
pnpm --dir admin test && ./scripts/privacy-verify.sh # 隐私与鉴权
./scripts/release-verify.sh                          # 发版链路(--deep 则真下一个制品验签)
cargo test --lib db::migrations && ./scripts/migration-verify.sh  # 数据基线与迁移
./scripts/learning-loop-verify.sh                    # 学习循环(源码层另跑 cargo test --lib)
bash scripts/context-budget.sh                       # 上下文预算(仪表,恒 exit 0;跑完记一行台账)

机械层绿了之后,把对应的 <专题>.md 交给一个 Claude 会话逐条过判断层。 产出按上面「每轮产物」那行拆散,不要新建一份报告文档