1.4 需求变更管理

一句话

变更管不住,不是因为 “客户爱改”,而是因为没有基线、没有定价、没有出口;变更管理的目标不是减少变更次数,而是让每一次变更都明码标价——谁提的、影响什么、换出什么、谁批、什么时候生效。

三条事实,先接受再设计流程

事实 含义 对流程的要求
变更必然发生 需求在被使用之前不可能完整;一次写对的只有 “已经做过三遍” 的需求 流程要能吸收变更,而不是假设没有变更
变更成本随阶段上升 经典量级:需求 1× → 设计 3–6× → 编码 10× → 测试 20–50× → 上线后 100×+ 越晚的变更越要定价,不能默默吸收
免费的变更 = 无限的变更 没有代价的变更请求会无限供给(缺了价格机制) 每次变更必须显式换出等量工作,或显式改期

关于那条成本曲线(Boehm 1981 的经典引用):不同研究给出的倍数差得很远,3× 到 100× 都有,但方向一致,所以引用时给量级就够,给精确倍数会被反驳。它的常见误用是论证 “必须一次写对”;正确结论是 “晚变更贵,所以要早定价”。

基线:没有基线就没有变更

“变更” 是相对基线而言的。没有基线的项目,所有需求都永远处于 “还在谈” 的状态,于是每次会议都能重开。

基线 定什么 谁有权改 改了通知谁
需求基线 本次迭代进入开发的需求集合 + 验收标准 产品 + 技术负责人 全体开发、测试
发布基线 本次发布的功能范围 + 上线条件 产品 + 发布负责人 运维、客服、市场
合同基线 交付范围、里程碑、验收方式 商务 + 客户 项目组、法务

基线不是 “不许改”,而是 “改要留痕”。三个基线对应三种流程,别混用:迭代内改需求走需求基线,发布前加功能走发布基线,客户改范围走合同流程——最后一种通常连带触发商务谈判。

四条通道:任何变更只能走这四条之一

通道 适用 代价(必须显式写出) 谁批 生效
等量交换(swap) 迭代内必须做,且原计划有可换出的需求 换出哪一条?它去哪(下迭代 / Won't) 产品 + 技术负责人 本迭代
排入下个迭代 优先级高但不紧急 交付日期推后 1 个迭代 产品 下迭代
紧急通道 合规、资损、线上事故 中断当前工作,写明被挤掉的是哪条 业务 + 技术负责人(可事后补审) 立即
记入 Won't 复盘后判定不值得做 写清复议触发条件 产品 不生效

🔑 “等量交换” 是这套流程里唯一能防住范围蔓延的机制:迭代产能是常数,“加一条” 必须回答 “减哪一条”。答不出来,说明这次变更是 “延期” 而不是 “变更”,应该直接改发布日期。

紧急通道必须留,但要留得贵:每用一次,都在复盘里记一笔 “为什么不能等一个迭代”。若每迭代超过 1 次,说明漏点在需求发现阶段,不在变更流程。

通道的选择由优先级决定:被 “排入下个迭代” 的那一条必须回到优先级表里重新排队,而不是默认插到队头,排序方法见 1.3 需求优先级。

变更单:七个必填,缺一个就会扯皮

# CR-2026-041.yaml —— 变更单模板,可直接抄
id: CR-2026-041
title: 发票抬头支持税号自动校验
source: 财务部 / 客户 A 工单 #8821          # 谁提的:外部客户 / 内部部门 / 缺陷修正 / 合规
requested_at: 2026-10-28
target: 迭代 24(2026-11-02 起)            # 希望什么时候生效
change: |                                   # 改什么:写行为,不写实现
  开票页填写税号时调用税务校验接口;不合法则禁止提交并提示具体错误码。
impact:                                     # 影响分析八项,逐项写「有/无 + 一句话」
  data_model: 有 —— 发票表加 tax_no_verified,需 expand-contract
  api_contract: 有 —— /invoice 请求体加可选字段,向后兼容
  downstream: 有 —— 财务系统需确认认识新字段
  slo: 无 —— 新增一次外部调用,P99 +约 80ms,仍在 300ms 预算内
  compliance: 有 —— 税号属企业信息,需确认留存期限
  test: 有 —— 新增 6 条用例(通过 / 失败 / 超时 / 降级 / 重试 / 幂等)
  docs: 有 —— 开票帮助页需更新
  ops: 无
cost: 3 人日(含测试)                       # 代价:必须量化
trade_off: 换出 CR-2026-038(报表导出优化)   # 换出什么:不许留空
approver: 产品负责人 + 技术负责人             # 谁批:按分级表
window: 迭代 24 第 1 周                      # 生效窗口
rollback: 特性开关 invoice.tax_check=false    # 怎么退

七个必填是:谁提的(source)、改什么(change)、影响什么(impact)、代价(cost)、换出什么(trade_off)、谁批(approver)、什么时候生效(window);id 与时间戳只是记账字段,rollback 是退路。任何一项空着,这次变更就会在两周后以 “当时没说清” 的形式返工。

八项里最常被漏的是 downstream(下游系统) 与 slo(对现有指标的影响):前者导致 “上线后别的系统读不出数据”,后者导致 “加了个小功能,首页变慢了”。这两项不在本次改动的代码里,所以必须写 “有/无 + 一句话” 逼作者去问别人。

分级审批:按 “可逆性 × 影响面”,不按金额或职级

级别 判据 审批 时限 例子
I 类 改数据模型 / 接口契约 / 合规口径 / 跨系统边界;不可逆 架构评审 + 业务负责人(流程见 58.3 架构评审) 3 个工作日 加一张表、改税率算法、换主键
II 类 改本次迭代范围、改验收标准、影响工期 产品 + 技术负责人 1 个工作日 加一个筛选条件、改导出字段
III 类 文案、交互细节、字段顺序、默认值 开发自行判断,事后记录 当天 按钮文案、提示语

分级的目的不是 “有流程感”,而是把审批成本花在不可逆的地方。III 类也开评审会,团队两周内就学会绕过流程;I 类不评审,代价在上线后按 10–100 倍偿还。

I 类变更的结论要落成决策记录(谁拍、代价、失效条件),否则三个月后没人能说清当时为什么批——记录字段与台账形态见 4.6 决策框架与决策记录。

追溯:影响分析靠反查,不靠记忆

需求追溯矩阵(RTM)只有一个用途:改了 X,谁能告诉我哪些东西会坏。

需求 ID 设计 代码 测试 状态
REQ-1042 发票税号校验 ADR-031 invoice/validate.go TestTaxNo_*(6 条) 已实现
REQ-1043 发票重开 — — — 待开发

轻量落地方式:把需求 ID 写进分支名、commit、测试名,不做矩阵表也能反查。

# 反查:这条需求改了哪些文件、哪些测试
git log --oneline --grep="REQ-1042"
# 示例输出(每个仓库不同)
# a1b2c3d REQ-1042 发票税号校验:接入税务校验接口
# d4e5f6a REQ-1042 补 6 条用例,覆盖超时与降级

# 正查:这个文件被哪些需求改过(判断改动影响面)
git log --oneline -- invoice/validate.go

反查出来的是文件清单,下一步是圈回归范围——用最小用例集覆盖这些文件的影响面,方法见 53.10 回归测试与缺陷管理。

变更的度量:四个数看流程是否失效

下表的区间是本节给的经验阈值,不是行业标准;团队应先用自己三个迭代的数据校准,再定自己的门限。

指标 定义 经验阈值 说明
需求稳定度 1 − 迭代内变更点数 / 迭代内需求总点数 ≥ 80% 低于 60% 说明问题在需求发现,不在变更流程
变更失败率 因变更引入的缺陷 / 变更总数 ≤ 15% 偏高说明影响分析八项在走过场
返工占比 返工工时 / 总工时 ≤ 20% 持续高于 30% 时,加人只会加快烧钱
紧急通道使用率 每迭代紧急变更次数 ≤ 1 偏高说明缺的不是流程,是需求评审

⚠️ 需求稳定度低,最诱人的解法是 “加强变更审批”。这是把病治在出口:真正的漏点在入口——需求没写验收标准、没列异常流、没和业务对齐口径(判据见 1.2 用户故事与用例)。变更率高是症状,需求质量差是病因。

三条把变更变便宜的手段(比 “禁止变更” 有效)

手段 做法 效果 代价
特性开关 代码先上线、功能不生效,变更从 “改代码” 变成 “改配置” 变更生效从 “一个发布周期” 缩到分钟级 每个开关都是一条长期分支(见 55.2 特性开关)
向后兼容 加字段安全、删改字段危险,变更只做加法 下游不必跟着改 兼容层要有人清理(见 55.5 向后兼容)
版本化 + 变更日志 破坏性变更走大版本,附迁移说明 变更可预期、可回滚 维护成本(见 51.3 语义化版本与变更日志)

三条的共同点:把 “需求变更” 转成 “配置 / 兼容 / 版本” 问题,让变更不必重走一遍需求流程。前提是需求本身写在行为层、不绑实现——那正是翻译要做的事,见 1.5 需求到技术的翻译。

反模式

反模式 后果
口头变更,事后补文档 测试按旧口径、代码按新口径,缺陷归因不清
变更当 bug 修 免费变更,需求池无限膨胀,且不进考核
一律拒绝变更 交付了没人要的功能,客户流失
每条变更都开评审会 审批成本超过变更成本,团队学会绕过流程
变更单只有 “改什么”,没有 “换出什么” 迭代范围静默膨胀,每次延期都归因于 “开发慢”
影响分析只写 “影响前端” 下游系统与 SLO 影响漏掉,上线后才暴露
变更不更新验收标准 测试无法判定通过,交付靠嘴
基线随时可改 没有基线,“延期” 无法判定
只在项目结束复盘变更 同类变更下个项目再来一遍

三条铁律

🔑 每次变更必须显式付出代价:换出等量工作,或改发布日期。免费吸收的变更,迟早以更大代价还回来。

🔑 变更单的价值在 “影响分析八项” 与 “换出什么”,不在 “变更描述”;写不出换出项的变更,不是变更,是加需求。

🔑 变更率高时先查需求质量,再查流程;把审批加严,只是把变更推到线下。

自检

Q1 客户在迭代第 6 天要求加一个 “紧急” 功能。走哪条通道?必须先回答哪个问题?

▸ 答案:走 swap(等量交换) 或 紧急通道,但无论如何要先回答 “换出哪一条、换出的那条去哪”。迭代产能是常数,第 6 天插进一条 3 人日的需求,等价于把原计划某条推迟 3 人日;不回答这个问题,等于把迭代悄悄延长了 3 人日——这就是范围蔓延的准确定义。

Q2 影响分析八项里,为什么下游系统与 SLO 影响最容易被漏?

▸ 答案:因为它们不在本次改动的代码里。数据模型与接口契约改的是自己的仓库,一眼看得见;下游在别的团队,SLO 影响要等压测或监控才暴露。漏掉后的典型事故:加了个字段,下游反序列化失败;加了一次外部校验调用,P99 从 200ms 涨到 320ms 触发告警。

Q3 需求稳定度只有 45%,老板要求 “加强变更审批”。为什么这个解法大概率无效?

▸ 答案:45% 意味着过半需求在迭代内被改动,这是入口质量问题:验收标准没写、异常流没列、口径没和业务对齐。审批加严只会让变更不进系统(口头变更、当 bug 修),度量变漂亮、返工照旧。正确顺序是先补需求的验收标准与异常流,再谈审批分级。

Q4 一个功能的上线日期已被三个客户写进合同,但它还在改需求。用什么手段把 “变更” 与 “上线” 解耦?

▸ 答案:特性开关 + 向后兼容。把已承诺部分做成可交付的最小版本先上线(开关关闭),剩余调整在开关后面继续做;同时用兼容策略(加字段、不删改)让下游不必跟着改。这样合同日期承诺的是可用能力,变更影响的是开关打开的范围,两者不再互相绑架。

Q5 为什么 III 类变更(文案、默认值)也要求 “事后记录”?

▸ 答案:因为 III 类量最大。单条无成本,聚合起来会改变产品形态:默认值改了、文案改了,用户感知到的是产品改版,但没有任何需求记录支持复盘。记录的粒度可以是 commit message 里带需求 ID,成本接近零,却让 “这个功能什么时候变的、为什么变” 可查。

关联