验收的目的不是证明架构好,是决定下一季度只改哪一件事。
一、季度复盘:3.75 分与「紧」
2026 年 10 月 8 日晚上,陆远把四张表摊在屏幕上:模块依赖表、迁移台账、依赖清单、债务登记。他花了两小时给十二项检查打分,原以为会落在「稳」,结果加权总分是 3.75——按档位只能算「紧」。他的第一反应是列一张十二条的待办,第二反应是发现自己一个季度只有三十九小时架构预算,根本做不完。
以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。
问题不在分数,而在排序。十二项里每一项都「应该修」,但一个人的季度预算只够做两件,选错顺序就会在三个月后再做一次同样的复盘。
三十九小时不是新数字:3 小时/周 × 13 周 = 39 小时,来自全组统一的架构预算;它同时是这次复盘的分母,也是下一季度排期的上限。
验收的目的不是证明架构好,是决定下一季度只改哪一件事。 一张全是红叉的表没有用,一张能排出先后顺序的表才有用。
分数低不等于马上修,先看每小时换多少分。 同样是补一分,有的动作六小时,有的二十五小时;先做单位时间收益高的那件。
同一套权重下,单项动作有天花板。 权重把总分锁在四个维度的组合里,任何单项都只能买到自己那一份;不理解这一点,就会做出「只做一件事就能到 4.0」的错误计划。
二、十二项检查与打分口径
十二项检查分四个维度,每维三项,每项 0 到 5 分;维度分是三项的算术平均。打分口径必须提前写死:5 分是有自动检查且近九十天真实跑过,4 分是做到但靠人记,3 分是部分做到或只在本地,2 分是知道但没做,0 分是没意识到。
| 维度 | 检查项 | 通过判据 | 当前得分 |
|---|---|---|---|
| 结构 | 依赖方向无逆向 | 四层方向 ui → app → domain → infra,逆向引用 0 条 | 5 |
| 结构 | 模块行数无单一模块超 30% | 最大模块 12,800 行,占 54,400 行的 23.5% | 4 |
| 结构 | 边界检查在 CI 里跑 | 每次 push 与 release 都执行 120 行检查脚本 | 3 |
| 数据 | 迁移三步齐全 | 62 个迁移都能指出属于 expand、migrate、contract 哪一步 | 4 |
| 数据 | 破坏性迁移有回滚 | 18 个破坏性迁移都有可执行的 down 脚本 | 3 |
| 数据 | 最近一次恢复演练在 90 天内 | 演练记录日期与当前日期相差不超过 90 天 | 3.5 |
| 依赖 | 四个升级窗口都执行了 | 每季度一个窗口,全年 4 次,各有发布记录 | 5 |
| 依赖 | 无超过 2 个大版本的积压 | 41 个直接依赖中 major 落后不超过 2 个版本 | 4 |
| 依赖 | 锁文件进仓库 | 锁文件被跟踪,CI 与镜像都按锁文件安装 | 4.5 |
| 债务 | 18 条都有利息与复查日期 | 每条登记年利息与下次复查日 | 3 |
| 债务 | 高危已排期 | 4 条高危都有修复日期与执行人 | 3 |
| 债务 | 利息占工程时间 < 5% | 季度手算 60.8 ÷ 2,080 = 2.9%,月度无读数 | 3 |
结构三项里,依赖方向是唯一满分:逆向引用为零,四层方向写进了检查脚本。模块行数拿 4 分,因为 23.5% 虽然低于 30%,但这个比例是季度手算的,没有进检查脚本;边界检查只有 3 分,脚本只在本地跑。
数据三项的平均是 3.5:三步纪律执行得不错,但 18 个破坏性迁移里只有一部分写了 down 脚本,最近一次恢复演练在 78 天前,属于「做过但没形成节奏」。
依赖 4.5 分看起来高,其实有一项是 4.5 而不是 5:锁文件进了仓库,但还有一个 CI job 用可变安装,镜像构建因此不是逐字节可复现的。
债务三项都是 3 分:只有 4 条高危登记了复查日期,4 条里只有 2 条排了修复时间,利息只有季度手算、没有月度读数。三项都「部分做到」,平均正好 3.0。
三、四维加权:3.75 落在哪一档
权重不是平均分的另一种写法,它表达的是失败代价:结构和数据决定「改不改得动」,各占 0.3;依赖和债务决定「要不要停下来还」,各占 0.2。
| 维度 | 权重 | 当前分 | 加权分 | 每提升 1 分 |
|---|---|---|---|---|
| 结构 | 0.3 | 4.0 | 1.20 | +0.30 |
| 数据 | 0.3 | 3.5 | 1.05 | +0.30 |
| 依赖 | 0.2 | 4.5 | 0.90 | +0.20 |
| 债务 | 0.2 | 3.0 | 0.60 | +0.20 |
| 合计 | 1.0 | — | 3.75 | — |
档位只有三档:4.0 及以上为「稳」,3.0 及以上但低于 4.0 为「紧」,3.0 以下为「危」。3.75 落在「紧」,意思是「还能改,但没有余量」。
3.75 离 4.0 只差 0.25,四舍五入到一位是 3.8,不能当 4.0 用。档位是给决策用的,不是给汇报用的;把 3.75 说成「接近稳」,下一季度就不会真的动手。
这组分数下,四项直接平均也是 (4.0 + 3.5 + 4.5 + 3.0) ÷ 4 = 3.75,和加权结果相同。这是分数分布造成的巧合,不是权重无效的证据:一旦要算「提升一项值多少」,0.30 和 0.20 的差别立刻出现。
单看维度,数据 3.5 和债务 3.0 是短板,但短板不等于优先项。结构里的 CI 检查只值 3 分,补它可能只要一小时;债务里的高危排序,回报则要用年利息来算。优先项要按「每小时换多少分」排,而不是按分数高低排。
四、复算:只做一件为什么不够
结构加权:0.3 × 4.0 = 1.20
数据加权:0.3 × 3.5 = 1.05
依赖加权:0.2 × 4.5 = 0.90
债务加权:0.2 × 3.0 = 0.60
当前总分:1.20 + 1.05 + 0.90 + 0.60 = 3.75
补 18 个 down 脚本:6 小时,数据 3.5 → 4.0
数据增量:0.3 × 0.5 = 0.15
只做数据:3.75 + 0.15 = 3.90
还 4 条高危债:25 小时,债务 3.0 → 4.0
债务增量:0.2 × 1.0 = 0.20
只做债务:3.75 + 0.20 = 3.95
数据每小时:0.15 ÷ 6 = 0.025 分/小时
债务每小时:0.20 ÷ 25 = 0.008 分/小时
两项都做:3.75 + 0.15 + 0.20 = 4.10
季度预算占用:31 ÷ 39 = 79.5%
只做数据是 3.90,只做债务是 3.95,两项都到不了 4.0。原因在权重:数据从 3.5 抬到 4.0,只买到 0.15;债务从 3.0 抬到 4.0,买到 0.20。单项的天花板由「维度权重 × 可提升幅度」决定,不由努力程度决定。
按每小时换分排序,数据是 0.025 分/小时,债务是 0.008 分/小时,前者是后者的三倍多,所以先做数据。但如果只看季度末的分数、不看投入,就会选债务,因为它的绝对增量更大。
「只改一件事」在这套权重下不够,不是权重设计得刁钻,而是验收本身要防止「用一个漂亮动作掩盖另一个短板」。数据补到 4.0 只说明回滚脚本齐了,债务仍停在 3.0,利息还是每月在收。
两项都做是三十一小时,占季度预算三十九小时的 79.5%,还剩八小时应付突发。这个排期可行,但已经没有余量做第三件事;如果季度中出现一次线上事故,先砍的应该是债务那二十五小时,而不是回滚脚本那六小时。
这也是十篇的次序在验收里的用法:01 决定候选,02 定下边界,03 与 04 保证可回退、可升级,05 决定要不要停下来还债,06 定下抽象的时机,07 决定重构还是重写,08 决定怎么退出,09 保证异步不出错;10 不新增方法,只把前九篇的结果排成一张季度表。
五、行动清单与复算验收
- 把十二项检查与四个维度分写进一张表,固定打分口径后再打分。
- 给 18 个破坏性迁移补 down 脚本,每个不超过 20 分钟,合计 6 小时。
- 在预发库真实执行其中 3 个 down 脚本,确认回滚后数据与结构一致。
- 还掉 4 条高危债,按「年利息 ÷ 修复小时」从高到低做,合计 25 小时。
- 把边界检查脚本接进 CI,push 与 release 各跑一次。
- 把仍用可变安装的那个 CI job 改成按锁文件安装。
- 给 18 条债补上复查日期,并把利息读数改成每月一次。
- 三个月后只重跑这 12 项,记录变化项与分数,不重打全部维度。
验收标准:下一季度末四维加权总分不低于 4.0,且十二项里至少五项发生变化;若总分仍低于 4.0,必须写出是哪一项没做完。
这八条的顺序就是执行顺序:先补回滚与高危债这两件有明确小时数的事,再顺手补 CI 与锁文件这两个零成本项,最后才改登记口径。反过来做,会先把时间花在整理表格上。
三个月后再跑一次,只比十二项里变化的那几项。分数从 3.75 走到 4.10 是结果,真正要留下的是「哪两项动了、各花了多少小时、下一季度还差什么」这一行记录。
十篇读到这里,方法已经给完;剩下的不是再学一套检查,而是把这张表贴进日历,每季度末从三十九小时里拿出两小时做一次排序。表会旧,排序的动作不会。
使用边界与实操验收
分数不能跨产品比较。 权重是按一人 SaaS 的失败代价定的;换成有 SRE、有值班的团队,依赖维度的权重会下降,债务维度的权重会上升,同一套分数没有可比性。
十二项是体检,不是目标。 全部拿到 5 分既不必要也不经济;结构 4.0 已经够用,把补最后那一分的时间换成一次功能发布,可能更值。
没有四张表就不要打分。 模块依赖表、迁移台账、依赖清单、债务登记缺一张,对应维度就只能凭印象,分数不可复算,复盘会退化成讨论。
与 03、05 的边界要守住。 03 给迁移三步纪律,05 给债务利息公式,10 只读结果、不重新定义口径;在验收会上改口径,等于把尺子和被测物一起换掉。
什么时候该停下来。 当复盘会变成十二条待办的朗读会,或者你开始为了让分数好看而调整打分口径时,停下来——那不是验收,是自欺。
关键参考与核验范围
核验日期:2026-10-26。以下文档用于核对概念与规则,本文所有数字均取自全组教学基线,不取自这些文档。
- Architecture Decision Records :用于核对「架构决策要留一份可追溯记录」的形式,四张表就是这些记录的索引。
- Technical Debt :用于核对债务与本息的定义,05 与 10 共用同一口径。
- The Twelve-Factor App :用于核对配置、依赖与后台任务的边界,避免把部署问题算进架构分。
- Keep a Changelog :用于核对变更记录的写法,验收只比变化项,不比全量。
引用口径。 上述文档只用于核对记录形式、债务定义与边界划分;文中的 3.75、3.90、3.95、4.10 与三十一小时全部来自全组教学基线,不取自这些文档。
核验范围。 上述四个入口在 2026-10-26 实测可公开访问(HTTP 200);未核验各项目的最新版本、价格与配额。
如何自行复核。 取自己最近一个季度,按第二节的口径给十二项打分,用第三节的权重算一次总分;再取一项你打算做的改进,估出小时数与维度提升幅度,算「分/小时」,看它是否排在你以为的第一位。
系列导航
- 上一篇:后台任务与一致性:六个定时任务、幂等键与一次补偿
- 回到目录:一个人的架构:技术选型、模块边界与演进
- 相关阅读:技术债预算:十八条债、二十四分钟与 7.5% 的工程时间 、数据模型与迁移:三十四张表与一次只能动一处的改动 、单体优先:九个模块、一条依赖方向与一次边界检查
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。