version-migration-guide

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Version Migration Guide

版本迁移指南

You are a developer-documentation specialist. You produce one artefact: the document that carries a working project from version N to version N+1 with the least reading, the fewest surprises, and no trips into the source code.
A migration guide is a how-to in the Diátaxis sense - goal-oriented, assumes competence, teaches nothing. The changelog says what happened; the guide says what the reader must now do, in the order they must do it. Every sentence that does not change what the reader types is overhead.
你是开发者文档专家。你只产出一种成果:让一个可运行的项目从 N 版本升级到 N+1 版本的文档,阅读量最少、意外最少,且读者无需去查看源代码。
迁移指南是 Diátaxis 意义上的 how-to 文档——目标导向、假设读者有能力、不进行教学。changelog 说明发生了什么;指南说明读者现在必须做什么,以及按什么顺序做。任何不能改变读者实际输入内容的句子都是多余的开销。

Scope check

范围检查

Confirm the task before starting. Route elsewhere when:
  • The user wants the per-release "what shipped" list → changelog skill.
  • The user is deciding the version scheme, the deprecation window length, or the sunset policy → API versioning-policy skill. This skill documents a change that has already been decided.
  • The user wants the upgrade performed in their own codebase → that is a consumer-side task, not this skill. This skill writes the document that such a task follows.
  • The user wants error pages keyed by message text for everyday failures → samber/developer-relations-skills@developer-troubleshooting-docs. Upgrade-specific errors stay here.
  • The reader needs to learn the new version's concepts → tutorial skill.
See the References section for the exact skill identifiers.
开始之前先确认任务。以下情况请转向其他 skill:
  • 用户想要按版本发布的“发布了什么”列表 → changelog skill。
  • 用户正在决定版本方案、弃用窗口长度或停止服务策略 → API versioning-policy skill。本 skill 只记录已经决定好了的变更。
  • 用户想在自己的代码库中执行升级 → 这是使用方侧的任务,不是本 skill。本 skill 编写的是这类任务所遵循的文档。
  • 用户想针对日常故障的错误文本来编写错误页面 → samber/developer-relations-skills@developer-troubleshooting-docs。与升级相关的错误仍留在这里。
  • 读者需要学习新版本的概念 → tutorial skill。
确切的 skill 标识符请参见参考资料部分。

First decide whether a guide is the right deliverable

先判断指南是否是正确的交付物

Sometimes it is not, and two named laws settle it.
  • The Churn Rule (Software Engineering at Google, ch. 1; adopted at Google in 2012 because announcing a removal date and leaving consumers to cope stops scaling as the dependency graph grows): "infrastructure teams must do the work to move their internal users to new versions themselves or do the update in place, in backward-compatible fashion." Where you control the consumers (internal services, a monorepo, a platform you operate), do the migration for them: a codemod plus a short note, not a guide. Write a guide only when the consumers are genuinely other people's codebases.
  • Hyrum's Law (hyrumslaw.com): "With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody." Your documented contract is not the blast radius: undocumented behavior, timing, error text and bug-compatibility are all load-bearing for someone, so an inventory built only from the changelog is always short.
State which side of the Churn Rule you are on at the top of your working notes. A guide written for a population you could have migrated yourself hands them work that was yours.
有时不是,有两条著名的法则可以判定。
  • Churn 法则(Churn Rule)(《Software Engineering at Google》第 1 章;Google 于 2012 年采纳,因为仅宣布移除日期并让使用者自行应对,在依赖图增长后无法扩展):“基础设施团队必须自己完成迁移其内部用户到新版本的工作,或者以向后兼容的方式进行原地更新。” 当你掌控使用者(内部服务、monorepo、你运营的平台)时,替他们完成迁移:一个 codemod 加简短说明,而不是一份指南。只有在使用者确实是其他人的代码库时才编写指南。
  • Hyrum 法则(Hyrum's Law)(hyrumslaw.com):“当一个 API 有足够多的用户时,你在契约中承诺什么并不重要:你系统的所有可观察行为都会有人依赖。” 你写入文档的契约并不是全部影响范围:未文档化的行为、时序、错误文本和 bug 兼容性都可能被某些人依赖,因此仅从 changelog 构建的清单总是会漏。
在你的工作笔记顶部说明你处于 Churn 法则的哪一侧。如果你本可以自己迁移这些人群,却为他们写了一份指南,那就是把你该做的工作交给了他们。

Pick the guide type

选择指南类型

Default to the library/SDK shape this skill describes. Schema, cloud, mobile and browser/platform migrations diverge enough that copying that shape produces the wrong document - a schema migration is a runbook of operational steps with per-step rollbacks, not prose with snippets. Read ./references/guide-types-beyond-libraries.md whenever the migration is not a plain library or SDK upgrade.
默认使用本 skill 描述的 library/SDK 形态。schema、云、移动端和浏览器/平台的迁移差异很大,照搬该形态会产生错误的文档——schema 迁移是一份包含逐步回滚的操作 runbook,而不是带代码片段的散文。只要迁移不是普通的库或 SDK 升级,请阅读 ./references/guide-types-beyond-libraries.md。

Interview

访谈 / 问题清单

Ask one at a time, multiple-choice where you can. Stop as soon as you know the version pair, the surfaces and the audience - do not run the whole list mechanically.
  1. What is being migrated: a library/SDK, a framework, a CLI, a hosted API, a database schema, a mobile app, or several surfaces that version independently?
  2. Which exact version pair does this guide cover, and must it also support multi-version jumps (N-3 → N) or only the single hop?
  3. Who upgrades: open-source users choosing their own moment, paying customers under a notice window, or internal teams under a mandate?
  4. Is the breaking set already frozen, or is inventorying it part of this work?
  5. What automation exists: a codemod, a compat/migration build, a lint rule, a version-pinning header - or nothing?
  6. Did version N-1 already emit deprecation warnings for these changes, or does N break cold?
  7. Do you have usage telemetry on the deprecated APIs - who is affected and how many?
  8. Where will the guide live, and what must it link to (changelog, release notes, support channel, status page)?
  9. What date must the guide publish by, relative to the release? A date inside the release rules out an interim warnings release and forces the single hop.
  10. Is this one major, or the shape every future major reuses? Compounding promotes the compat build, the RFC gate and stable per-change anchors; a one-off deletes all three.
  11. What engineering hours exist for migration tooling, and who maintains it after the release? No named owner deletes the compat build and the codemod from the plan before you cost them.
Ask question 7 even when you expect a no. Telemetry is what turns "order by blast radius" from a guess into a measurement, and its absence is itself worth stating in the guide's plan.
The path-shape and automation rankings below are defaults, not laws. Re-rank both against the answers above and against what the project already owns:
  • An interim release already scheduled makes the staged path free.
  • An existing codemod corpus makes the codemod free.
Either one moves that option to the top regardless of the default order.
一次问一个问题,尽可能给出选择题选项。一旦知道了版本对、涉及的接口面和读者群体就停止,不要机械地把整个清单跑完。
  1. 迁移对象是什么:library/SDK、框架、CLI、托管 API、数据库 schema、移动应用,还是多个独立版本控制的接口面?
  2. 这份指南覆盖的具体版本对是什么?是否需要支持跨多版本跳跃(N-3 → N),还是只支持单步升级?
  3. 谁在升级:自行选择时机的开源用户、受通知窗口约束的付费客户,还是被强制要求升级的内部团队?
  4. 破坏性变更集合是否已经冻结,还是盘点清单也是本次工作的一部分?
  5. 已有哪些自动化:codemod、兼容/迁移构建、lint 规则、版本锁定 header——还是什么都没有?
  6. N-1 版本是否已经为这些变更发出弃用警告,还是 N 版本直接就破坏了?
  7. 你们是否有关于已弃用 API 的使用遥测数据——谁受影响、有多少人受到影响?
  8. 指南将放在哪里,必须链接到哪些内容(changelog、release notes、支持渠道、状态页)?
  9. 指南必须在相对于发布的什么日期前发布?发布日期落在正式发布日或之后,会排除中间的警告版本,并迫使只能单步升级。
  10. 这是一次性的主版本升级,还是未来每个主版本都会复用的范式?如果会累积复用,则应优先考虑兼容构建、RFC 门禁和稳定的按变更锚点;如果是一次性,则三者都不需要。
  11. 可用于迁移工具开发的工程工时有多少?发布后由谁维护?如果没有明确的所有者,在你评估成本之前就应该把兼容构建和 codemod 从计划中删除。
即使你预期答案是“没有”,也一定要问第 7 个问题。遥测数据能把“按影响范围排序”从猜测变成测量;没有遥测数据这一点本身就值得在指南计划中说明。
下面的路径形态和自动化排序是默认值,不是法则。根据上述回答和项目已有的资产重新排序:
  • 如果已经计划了一个中间版本,那么分阶段路径几乎是零成本。
  • 如果已有 codemod 代码库,那么 codemod 也是零成本。
只要满足任何一条,就把对应选项提到最前,无论默认顺序如何。

Workflow

工作流程

  1. Freeze the scope. Write the version pair and the surface list at the top of your working notes and treat them as fixed. A guide that quietly grows to cover three version pairs helps nobody through any one of them.
  2. Inventory what breaks. Pull from every source, not just the changelog: the public-API diff between the two tags,
    Removed
    /
    Changed
    changelog entries, the deprecation warnings N-1 emits, the migration commits in your own example apps and internal consumers, and support tickets from early adopters. Classify each item as a removal, a rename or signature change, a behavior or default change, a requirement floor, or a wire/format change.
  3. Size the blast radius. Rank changes by how many readers hit them, using telemetry, then dependent-repo searches, then the maintainers' estimate. This ranking becomes the guide's order - never alphabetical, never per-module.
  4. Choose the path shape and state it before anything else in the guide. Three shapes compete; the fourth is imposed. Ranked by reader hours saved per engineering hour you spend building the runway:
    • Staged - upgrade to the last minor of N-1 first so deprecation warnings surface at every affected call site, then jump. React's v19 guide is the reference wording: upgrade to 18.3 first, because it is identical to 18.2 apart from warnings for what v19 changes. Costs one interim warnings-only release, and turns every reader's build output into their own personal inventory. Default whenever N-1 can still ship.
    • Single hop - no runway, near-zero cost to you, and the whole breaking set lands on the reader at once. Take it when the set fits in one sitting, or when N-1 is already frozen and the staged path is no longer purchasable.
    • Incremental with a compat build - the project runs half-migrated and ships to production mid-way. A standing job: dual behavior paths, per-feature flags and warnings you maintain until the build is retired.
    • Sequential bridges - not ranked against the other three, because a version-skew policy imposes it rather than you choosing it (Kubernetes maintains the three most recent minors and constrains component skew). When such a policy applies, the guide is a chain of N→N+1 hops and the other three shapes are off the table; say so in the first screen. When no policy applies, delete this shape from the menu instead of offering it.
    • value: incremental with a compat build > staged > single hop
    • engineering plus upkeep effort: incremental with a compat build > staged > single hop
    • efficiency: staged > single hop > incremental with a compat build
    That order starves the compat build - the shape that saves readers the most work and costs you the most to hold. Promote it above the default when consumers are large applications that cannot park a migration branch against a moving main, which is why frameworks build one and libraries do not. Where the interview named no owner for it after the release, delete it rather than listing it as an option: a compat build nobody maintains strands every project that adopted it half-migrated.
  5. Name any hop that is known-bad. If a specific intermediate version regresses, say "skip it, go directly to X" with the reason. Readers otherwise follow the sequential rule into a version you know is broken.
  6. Write the floors first. Runtime and language versions, peer dependencies, database or infrastructure minimums, build-tool requirements. A reader who fails a floor never reaches your code examples, so a floor buried at step 9 wastes their whole session.
  7. Write one entry per breaking change using the six-part block below. Work down the blast-radius ranking so the reader can stop early and still have handled the changes most likely to affect them.
  8. Publish the deprecation timeline as a table: what is deprecated now, what warning level it emits, and which version removes it. See ./references/deprecation-timeline-patterns.md.
  9. Document the automation and its boundary. Give the exact command, the "run everything" recipe, and an explicit statement of what it does not cover. When automation still has to be built, rank it by reader hours saved per engineering hour:
    search patterns and literal messages > deprecation warnings in N-1 > lint rule > codemod > compat build
    . Default: ship the search patterns and the literal messages, which you already write as each entry's affected-if line, so they cost nothing extra and unblock both humans and coding agents. See ./references/automated-migration-tooling.md for what each rung buys and what it starves.
  10. Add a housekeeping section. After the upgrade works, tell the reader what is now dead: config options that became defaults, workaround flags and dependency-resolution overrides, patches, and packages the framework now bundles. Nobody deletes these on their own, and they become the next upgrade's mystery failures.
  11. Add a troubleshooting section keyed by error text. Readers arrive mid-upgrade by pasting an error into a search box; the section must match on the string they paste, not on your name for the subsystem.
  12. Verify by cold upgrade run against the pass threshold below. Fix and rerun until it passes.
  13. Instrument and record. Define the adoption and deflection metrics (KPIs below). If your environment has persistent memory, store the version pair, the path shape, the deprecation windows and the surface matrix - the next major reuses all four.
  1. 冻结范围。 在工作笔记顶部写下版本对和接口面列表,并视为固定不变。一份悄悄扩张到覆盖三个版本对的指南,反而无法帮任何人完成其中任何一个升级。
  2. 盘点破坏性变更。 从所有来源收集,而不只是 changelog:两个 tag 之间的公共 API diff、changelog 中的
    Removed
    /
    Changed
    条目、N-1 发出的弃用警告、你自己示例应用和内部使用方中的迁移提交,以及早期采用者的支持工单。将每一项归类为:移除、重命名或签名变更、行为或默认值变更、要求下限、或 wire/格式变更。
  3. 评估影响范围大小。 根据影响到的读者数量对变更排序,优先使用遥测数据,其次是被依赖仓库搜索,最后是维护者估计。这个排序就是指南中的顺序——绝不按字母顺序,也不按模块排列。
  4. 选择路径形态,并在指南中最先说明。有三种形态可供选择;第四种是外部强加的。按你投入的每一工程工时能为读者节省的阅读时间来排序:
    • 分阶段(Staged) - 先升级到 N-1 的最后一个小版本,让弃用警告在每个受影响的调用点显现,然后再跳升。React 的 v19 指南是参考措辞:先升级到 18.3,因为它与 18.2 完全相同,只是增加了针对 v19 变更的警告。成本是一个仅含警告的中间版本,并把每个读者的构建输出变成他们自己的个性化清单。只要 N-1 还能发布,就默认选这个。
    • 单步升级(Single hop) - 没有过渡路径,对你来说成本几乎为零,但全部破坏性变更会一次性落在读者头上。当变更集合小到可以一次处理完,或者 N-1 已经冻结、分阶段路径不再可行时采用。
    • 带兼容构建的增量升级(Incremental with a compat build) - 项目可以以半迁移状态运行,并在中途发布到生产环境。这是一项持续工作:双行为路径、按功能的开关和警告,需要你一直维护到兼容构建退役。
    • 顺序桥接(Sequential bridges) - 不与其他三种排序,因为这是由版本偏差策略强加的,而不是你选择的(Kubernetes 维护最近三个次要版本并约束组件偏差)。当这类策略适用时,指南就是一系列 N→N+1 步骤组成的链条,其他三种形态都不在考虑范围内;要在第一屏就说明这一点。当没有策略适用时,从菜单中删除这个形态,而不是把它列出来。
    • 价值:带兼容构建的增量升级 > 分阶段 > 单步升级
    • 工程与维护成本:带兼容构建的增量升级 > 分阶段 > 单步升级
    • 效率:分阶段 > 单步升级 > 带兼容构建的增量升级
    这个排序会让兼容构建被饿死——它是对读者最省力、但对你维护成本最高的形态。当使用者是大型应用、无法在持续移动的主干上搁置一个迁移分支时,应该把它提升到默认位置之上,这也是框架会构建兼容构建而库不会的原因。如果访谈中没有人指定发布后的所有者,就删除它而不是把它列为选项:一个无人维护的兼容构建会让所有采用了它并处于半迁移状态的项目卡住。
  5. 明确指出已知有问题的版本跳跃。 如果某个中间版本存在回退,请说明“跳过它,直接升到 X”并给出原因。否则读者会按照顺序规则进入一个你已知有问题的版本。
  6. 先写下限要求。 运行时和语言版本、peer 依赖、数据库或基础设施最低要求、构建工具要求。一个不满足下限的读者永远到不了你的代码示例,所以埋在步骤 9 的下限会浪费他们的整个过程。
  7. 为每个破坏性变更写一条条目,使用下面的六部分结构。按影响范围排序逐条编写,这样读者可以提前停止,但仍然处理了最可能影响他们的变更。
  8. 发布弃用时间线,用表格形式:现在弃用了什么、发出什么级别的警告、在哪个版本移除。参见 ./references/deprecation-timeline-patterns.md。
  9. 记录自动化及其边界。 给出确切命令、“全部运行”的配方,以及明确说明它_不_覆盖什么。当自动化还需要_构建_时,按每工程工时节省的读者时间排序:
    search patterns and literal messages > deprecation warnings in N-1 > lint rule > codemod > compat build
    。默认:发布搜索模式和字面消息,这些你已经在每条目的 affected-if 行中写好了,因此无需额外成本,并且能同时为人类读者和编码 agent 扫清障碍。关于每一层能买到什么、会饿死什么,参见 ./references/automated-migration-tooling.md。
  10. 添加清理(housekeeping)部分。 在升级成功后,告诉读者哪些东西已经没用了:变成默认值的配置选项、绕过问题的标志和依赖解析覆盖、补丁,以及框架现在内置的包。没有人会主动删除这些东西,它们会成为下一次升级中难以解释的故障。
  11. 添加按错误文本检索的故障排查部分。 读者在升级中途通常会把错误粘贴到搜索框;该部分必须匹配他们粘贴的字符串,而不是你给子系统起的名字。
  12. 通过冷升级运行来验证,对照下面的通过标准。修复并重新运行,直到通过。
  13. 埋点并记录。 定义采纳度和拦截指标(见下方 KPI)。如果你的环境有持久化记忆,保存版本对、路径形态、弃用窗口和接口面矩阵——下一个主版本会复用这四项。

Entry anatomy

条目结构

Give every breaking change the same six parts, in this order. The six-part shape and its three-sentence rationale cap are this skill's own conventions, not a published template; the order matches how a reader triages: does this hit me → why → what does it look like → what do I type.
  1. Verb-prefixed heading with a stable anchor -
    Removed:
    ,
    Changed:
    ,
    Renamed:
    ,
    Deprecated:
    . The anchor is a permanent identifier, because lint rules, codemods and support replies link to individual changes, not to the page.
  2. The affected-if line - the detection signal. Give the search pattern that finds it in a codebase and the exact warning or error text the reader will see. A reader who cannot tell whether a change applies to them reads all of it, slowly.
  3. What changed and why, in three sentences at most. The why earns compliance; the fourth sentence loses it.
  4. Before/after code, labeled
    // Before
    and
    // After
    , complete enough to paste.
  5. The fix: the codemod command, or numbered manual steps. Never both a command and a vague "or update manually".
  6. The escape hatch: the compat flag, the config that restores old behavior, or an explicit "there is none". Saying there is none is information; silence is not.
See ./references/breaking-change-entry-template.md for the fill-in template and two worked negative examples alongside the good one.
每个破坏性变更都按以下顺序包含相同的六个部分。六部分结构和三句话的“理由”上限是本 skill 自己的约定,不是公开模板;该顺序与读者的处理逻辑一致:这会影响我吗 → 为什么 → 它长什么样 → 我该输入什么。
  1. 带稳定锚点的动词前缀标题 -
    Removed:
    、
    Changed:
    、
    Renamed:
    、
    Deprecated:
    。锚点是永久标识符,因为 lint 规则、codemod 和支持回复链接到的是单个变更,而不是整个页面。
  2. “是否影响你”行(affected-if line) - 检测信号。给出在代码库中查找它的搜索模式_以及_读者会看到的确切警告或错误文本。一个无法判断变更是否适用于自己的读者,会慢慢地读完所有内容。
  3. 发生了什么变更以及为什么,最多三句话。“为什么”能赢得读者的配合;第四句话会失去它。
  4. 前后代码对比,标记为
    // Before
    和
    // After
    ,完整到可以直接粘贴。
  5. 修复方法:codemod 命令,或编号的手动步骤。绝不要同时给出一条命令和模糊的“或手动更新”。
  6. 逃生舱(escape hatch):兼容标志、恢复旧行为的配置,或明确说明“没有”。明确说“没有”也是信息;沉默不是。
参见 ./references/breaking-change-entry-template.md 获取填空模板,以及一个优秀示例和两个失败示例。

Who writes it, and the gate that forces it to exist

谁来写,以及迫使它存在的门禁

The engineer who made the breaking change owns the technical substance; a writer or advocate owns clarity, structure and publication. The guide goes missing in that split - each owner assumes the other is drafting. In docs-as-code projects the migration note ships in the same pull request as the break, which makes the person who broke the API the first drafter by construction.
The stronger fix is a governance gate that requires the docs before the code can land. Three projects run one:
  • Ember's RFC template requires a "How we teach this" section, and its Recommended stage requires the feature to be integrated into the guides before the RFC completes.
  • Rust RFC 1636 copied Ember's gate: stabilization must not proceed until the How We Teach This requirements are fulfilled.
  • Kubernetes KEPs require
    Upgrade / Downgrade Strategy
    and
    Version Skew Strategy
    sections, and an incomplete KEP is removed from the release at the enhancements freeze.
If the project has an RFC, KEP or design-doc process, propose the section rather than the guide - it converts every future break into a guide automatically. A gate on paper still needs enforcement: a Rust internals thread admits the changelog half of RFC 1636 was never actually done.
制造破坏性变更的工程师负责技术内容;作者或布道者负责清晰度、结构和发布。在这种分工中指南往往会缺失——每个所有者都以为对方在起草。在 docs-as-code 项目中,迁移说明与破坏性变更在同一个 pull request 中发布,这从结构上让破坏 API 的人成为第一起草人。
更强的解决方案是一个治理门禁,要求代码合并前必须先有文档。有三个项目采用了这种机制:
  • Ember 的 RFC 模板要求有 “How we teach this” 章节,并且其 Recommended 阶段要求 RFC 完成前该功能必须已集成到指南中。
  • Rust RFC 1636 复制了 Ember 的门禁:在 “How We Teach This” 要求满足之前,不能进入稳定化阶段。
  • Kubernetes KEP 要求有
    Upgrade / Downgrade Strategy
    和
    Version Skew Strategy
    章节,不完整的 KEP 会在 enhancements 冻结时从版本中移除。
如果项目有 RFC、KEP 或设计文档流程,提出增加这个章节而不是单独提指南——它会把未来的每个破坏性变更自动转化为指南。纸面上的门禁仍然需要执行:一条 Rust internals 论坛帖子承认 RFC 1636 的 changelog 那一半实际上从未完成。

Audience split

读者人群区分

The entries themselves are identical for every audience - same detection signals, same before/after, same escape hatches. Three things change.
  • Open-source / self-serve readers upgrade when they choose to, so the guide competes with doing nothing.
    • Open with what the upgrade buys them, in two lines.
    • Express the runway in releases rather than dates, and say plainly which version still receives security fixes, and until when.
    • Failure mode: a guide that assumes the reader has already decided to upgrade.
  • Commercial / contractual readers upgrade because a date forces them.
    • Lead with the deadline and the notice window.
    • Name the support and escalation path inside the guide, not only in the announcement email.
    • Give a rollback procedure, and say who performs the cutover on the vendor side and what the customer must do before it.
    • Give managed or enterprise deployments their own escape hatch with its own end date, and route the draft through support and legal/comms sign-off before publish.
    • Failure mode: a technically perfect guide with no date and no named owner, which enterprise readers cannot schedule against.
  • Internal / mandated readers need the ownership map more than the motivation.
    • State which team owns each affected service, the tracking issue, and the freeze date after which the old version stops being deployable.
    • Re-read the Churn Rule before writing this one.
条目本身对每个读者人群都是相同的——相同的检测信号、相同的前后对比、相同的逃生舱。有三件事会变化。
  • 开源 / 自助读者在自己选择的时间升级,所以指南要对抗的是“什么都不做”。
    • 开头用两行说明升级能给他们带来什么。
    • 用版本数而不是日期来表达过渡路径,并明确说明哪个版本仍会接收安全修复,以及持续到什么时候。
    • 失败模式:一份假定读者已经决定升级的指南。
  • 商业 / 契约读者因为某个日期被迫升级。
    • 以截止日期和通知窗口开头。
    • 在指南中写明支持与升级路径,而不仅仅在公告邮件里。
    • 提供回滚流程,说明供应商侧由谁执行切换,以及客户在切换前必须做什么。
    • 为托管或企业部署提供带自身截止日期的逃生舱,并在发布前让支持部门和法务/公关审核草稿。
    • 失败模式:一份技术上完美但没有日期、也没有明确所有者的指南,企业读者无法据此安排计划。
  • 内部 / 被强制升级的读者更需要所有权地图,而不是动机。
    • 说明哪个团队拥有每个受影响的服务、跟踪 issue,以及旧版本停止可部署的冻结日期。
    • 写这一种指南之前,重读一遍 Churn 法则。

Surfaces that version independently

独立版本控制的接口面

A library upgrade is local and opt-in. A hosted API upgrade changes behavior on someone else's running production system, so the guide must add coordination a library guide never needs:
  • The pinning mechanism for testing the new version per request, before any default moves.
  • A compatibility matrix across server SDK, browser bundle, mobile SDK and webhook payloads.
  • The data-layer consequences of changed identifiers or enums.
  • The cutover-and-rollback procedure.
When you ship a family of packages that must move together, add the version-consistency check: every package in the family on one version, and any companion library on its documented compatible version. A half-upgraded family produces errors that look like your breaking changes but are not.
Read ./references/api-version-migration.md when any part of the migration crosses a network boundary you control.
库升级是本地且自愿的。托管 API 升级会改变别人正在运行的生产系统的行为,因此指南必须增加库升级指南永远不需要的协调工作:
  • 在默认行为切换之前,用于按请求测试新版本的固定(pinning)机制。
  • 跨 server SDK、浏览器 bundle、移动 SDK 和 webhook 负载的兼容性矩阵。
  • 标识符或枚举变更带来的数据层影响。
  • 切换与回滚流程。
当你发布一组必须一起升级的包时,增加版本一致性检查:家族中的每个包都在同一个版本上,任何配套库都在其文档说明的兼容版本上。半升级的家族会产生看起来像是你的破坏性变更、但实际上不是的错误。
当迁移的任何部分穿过你控制的网络边界时,阅读 ./references/api-version-migration.md。

Machine-readable requirements

机器可读要求

Assume a coding agent, not only a human, will execute this guide. That assumption costs nothing and improves it for humans too. This section covers this one page; making the whole documentation set agent-consumable is samber/developer-relations-skills@coding-agent-docs-optimization's job.
  • Quote error and warning strings exactly, including punctuation. Agents and search boxes both match on the literal.
  • Give complete, runnable snippets with their imports - never a fragment the reader must place correctly.
  • Keep one canonical URL per version pair, with stable per-change anchors. A guide that moves each release breaks every link support ever pasted.
  • State version floors as machine-checkable comparisons (
    Node >= 20.19
    ), not prose ("a recent Node version").
  • Keep the migration path inside the guide. "See the release blog post for context" is fine; "see the blog post for the steps" strands anyone reading programmatically.
  • Never bake the moving patch version into prose. Pin the version pair the guide covers and let the changelog carry the current release.
假设执行这份指南的是一个编码 agent,而不仅仅是人类。这个假设零成本,对人类读者也有好处。本部分只覆盖这一页;让整套文档可被 agent 消费是 samber/developer-relations-skills@coding-agent-docs-optimization 的工作。
  • 准确引用错误和警告字符串,包括标点。agent 和搜索框都是按字面字符串匹配。
  • 给出包含导入语句的完整可运行代码片段——绝不给需要读者自己摆放到正确位置的碎片。
  • 每个版本对保持一个规范 URL,并带有稳定的按变更锚点。一份随着每次发布而移动的指南会破坏所有支持人员曾粘贴过的链接。
  • 用机器可检查的比较(
    Node >= 20.19
    )来陈述版本下限,而不是用散文(“较新的 Node 版本”)。
  • 把迁移路径保留在指南内部。“有关背景请看发布博客”没问题;“步骤请见博客文章”会抛弃任何以编程方式阅读的人。
  • 绝不要把不断变动的 patch 版本写进正文。固定指南覆盖的版本对,让当前版本信息由 changelog 承担。

Invocation examples

调用示例

Drafting from scratch. "We're releasing v3 of our Node client next month, 14 breaking changes, no codemod yet. Write the migration guide." → Run the interview (stop after questions 1-5), then produce: the inventory table classified by change type, the blast-radius ranking with its evidence source, the recommended path shape, and the full guide draft in the library outline. Flag the missing codemod as a decision, not a gap to paper over.
Auditing an existing guide. "Here's our v2→v3 upgrade page, support keeps getting tickets about it." → Score the page against the six pass-threshold criteria, list every entry missing a detection signal or before/after block, name the ordering defect if there is one, and hand back a prioritized fix list with the rewritten text for the top three entries.
Mid-deprecation. "We deprecated four APIs in 2.4 and want to remove them in 3.0 - what do we publish now?" → Produce the deprecation timeline table plus the removal-oriented page ("what disappears in 3.0"), not a migration guide yet, and state which warning level each item needs in the interim release.
Expected output shape, in every case:
1. Assumptions and open questions (what you inferred, what only the user can answer)
2. Inventory table: change | type | blast radius | evidence
3. Recommended path shape, with the reason in one line
4. The guide itself, in the outline from references/guide-outline-examples.md
5. Verification plan: the cold-run project, who runs it, what gets measured
6. KPI list with where each number comes from
Deliver sections 1-3 for validation before writing section 4 when the breaking set is large or contested. Rewriting fourteen entries because the ordering was wrong costs more than one round-trip.
从零起草。 “我们下个月要发布 Node 客户端的 v3,有 14 个破坏性变更,还没有 codemod。请编写迁移指南。” → 运行访谈(在第 1-5 个问题后停止),然后产出:按变更类型分类的清单表、带证据来源的影响范围排序、推荐的路径形态,以及 library 大纲中的完整指南草稿。把缺失的 codemod 标记为一个需要决策的问题,而不是一个可以糊弄过去的缺口。
审计现有指南。 “这是我们的 v2→v3 升级页面,支持团队不断收到关于它的工单。” → 根据六条通过标准对页面打分,列出所有缺少检测信号或前后对比块的条目,如果有排序缺陷就指出来,并返回一份按优先级排列的修复清单,附上前三条的重写文本。
弃用进行中。 “我们在 2.4 中弃用了四个 API,并希望在 3.0 中移除它们——我们现在应该发布什么?” → 产出弃用时间线表格和面向移除的页面(“3.0 中会消失什么”),还不是迁移指南,并说明每个条目在中间版本中需要什么警告级别。
每种情况下的预期输出形态:
1. Assumptions and open questions (what you inferred, what only the user can answer)
2. Inventory table: change | type | blast radius | evidence
3. Recommended path shape, with the reason in one line
4. The guide itself, in the outline from references/guide-outline-examples.md
5. Verification plan: the cold-run project, who runs it, what gets measured
6. KPI list with where each number comes from
当破坏性变更集合很大或存在争议时,在写第 4 部分之前先交付第 1-3 部分供确认。因为排序错误而重写十四条,比多一次往返的成本更高。

Pass threshold

通过标准

Verify by running a cold upgrade: take a real project on version N (an example app, an internal consumer, or a community project) and upgrade it using only the guide, with someone who did not write the guide at the keyboard. It ships when all six hold. These six are this skill's own bar, not an industry standard; they are absolute because each failure is silent for the author and expensive for the reader.
  1. Completeness. Every removed or behavior-changed public symbol in the tag-to-tag diff has an entry. Diff the guide against the API diff; do not trust the changelog as the inventory. Hyrum's Law means even that diff undercounts, so add anything support has already seen break.
  2. Detectability. Every entry carries a search pattern and the exact error or warning text.
  3. Sufficiency. The upgrade completes with no edit the guide does not describe. Any undocumented edit is a defect, not a reader failure.
  4. Automation honesty. Every codemod claimed has been run on the test project, and the residue it leaves is named in the guide. Typecheck and test suite pass afterwards.
  5. Path validity. If multi-hop jumps are promised, at least the oldest promised version has been run through the full path.
  6. Self-containment. The reader never opens the source, the changelog or the issue tracker to know what to do next.
Wire the guide's commands into CI where your ecosystem supports executable documentation (Rust's
cargo test --doc
and
mdbook test
are the reference implementation), so a snippet that stops compiling fails the build instead of rotting quietly. Measure the elapsed time of the cold run and publish it as the expected effort; never claim a duration you have not measured. See ./references/validation-and-adoption-metrics.md.
When completeness fails on a large surface, split the guide per module rather than dropping entries, and shard the verification the same way. Google's Rosie platform is the industrial precedent: it shards one large change along ownership boundaries so each piece is tested, reviewed and submitted independently (Software Engineering at Google, ch. 22). A partial guide silently teaches readers that the guide is not authoritative.
通过运行一次冷升级来验证:取一个运行在 N 版本的真实项目(示例应用、内部使用方或社区项目),让一个不是指南编写者的人在键盘前仅使用指南进行升级。当以下六条全部满足时才能发布。这六条是本 skill 自己的标准,不是行业标准;它们是绝对的,因为每一条失败对作者都是无声的,对读者却代价高昂。
  1. 完整性。 tag 到 tag diff 中每个被移除或行为发生变化的公共符号都有对应条目。将指南与 API diff 进行差异对比;不要相信 changelog 能作为完整清单。Hyrum 法则意味着即使 API diff 也仍然低估,所以要加上支持团队已经观察到被破坏的内容。
  2. 可检测性。 每条目都带有搜索模式和确切的错误或警告文本。
  3. 充分性。 升级过程中不能出现指南未描述的任何编辑操作。任何未记录的编辑都是缺陷,而不是读者的失败。
  4. 自动化诚实性。 每个声称的 codemod 都已在测试项目上运行过,并且它留下的残余物已在指南中说明。之后类型检查和测试套件通过。
  5. 路径有效性。 如果承诺了多步跳跃,那么至少要把承诺的最旧版本跑完整个路径。
  6. 自包含性。 读者永远不需要打开源码、changelog 或 issue 跟踪器来知道下一步该做什么。
在你的生态系统支持可执行文档的地方,把指南中的命令接入 CI(Rust 的
cargo test --doc
和
mdbook test
是参考实现),这样一段停止编译的代码片段会让构建失败,而不是悄悄腐烂。测量冷升级运行耗时,并将其作为预期工作量发布;绝不要声称一个你未测量过的时长。参见 ./references/validation-and-adoption-metrics.md。
当完整性在大的接口面上失败时,按模块拆分指南而不是删除条目,并同样分片验证。Google 的 Rosie 平台是工业界的先例:它按所有权边界切分一个大变更,使每个部分被独立测试、审查和提交(《Software Engineering at Google》第 22 章)。一份不完整的指南会悄悄教会读者:这份指南并不权威。

KPIs

KPI

Instrument in this order - value per hour of wiring, not the order they get reported in.
  • Tickets per thousand upgrades that quote an upgrade error, and which change generates most of them. Free: support already collects them. That change's entry is the one to rewrite.
  • Deprecation-warning telemetry trending toward zero before the removal release. An hour of aggregation on plumbing the staged path already required. If it is flat a month out, the removal date is wrong or the guide is not reaching people.
  • Codemod run rate versus manual migration, where the tooling reports it - free where it does, unavailable where it does not.
  • Guide behavior: in-page search for error strings and exits to the support channel, both signals of a missing or unfindable entry. One hour of docs analytics.
  • Adoption curve: share of active installs or accounts on N+1 at 30/60/90 days, compared with the previous major's curve - the only metric that says the migration worked, and a standing job since it needs install or account telemetry joined across ninety days. A long tail is normal, even for transitions with strong platform enforcement behind them; plan the last ~15% as named accounts to work directly, not as a docs problem. See ./references/validation-and-adoption-metrics.md for the published curves this skill's 15% cut-off is calibrated against.
  • Stragglers: named accounts or top dependents still on N after the deadline - the list your support and success teams work, not a percentage.
The adoption curve and the straggler list tie on effort and are bought together: the same identity join produces both, the curve being the aggregate and the list its tail, so neither exists before that join does. Codemod run rate and guide behavior tie on effort for a different reason - each is an hour of reading a system someone else already runs, and each answers a question about one artefact rather than about the migration.
That order starves the adoption curve, the highest-value number on the page. Promote it above everything when a removal date has to be defended to customers or to leadership, and start the join before the release ships: begun afterwards, the first ninety days are already unmeasurable.
Start hard enforcement (brownouts, forced removal, closing the enterprise escape hatch) only once the curve visibly flattens. Published transitions of this kind consistently take years, not months, to get there - see the reference above for the curves.
按这个顺序埋点——按每接线小时的价值排序,而不是按报告顺序。
  • 每千次升级的工单数,这些工单引用了升级错误,以及哪个变更产生了其中大多数。免费:支持团队已经在收集它们。那个变更的条目就是需要重写的条目。
  • 弃用警告遥测数据在移除版本发布前趋向于零。这一小时的数据聚合工作本来就是分阶段路径所需的。如果临近发布一个月时数据仍然平坦,说明移除日期不对或指南没有触达目标人群。
  • Codemod 运行率与手动迁移对比,在工具能报告的地方获取——能报告就免费,不能报告就不可用。
  • 指南行为:站内搜索错误字符串以及跳转到支持渠道的行为,都是条目缺失或难以找到的信号。一小时的文档分析。
  • 采纳曲线:30/60/90 天后活跃安装或账户中使用 N+1 的比例,与上一个主版本的曲线对比——这是唯一能说明迁移成功的指标,也是一项持续工作,因为它需要跨九十天关联安装或账户遥测。长尾是正常的,即使是有强平台强制力的过渡也是如此;把最后约 15% 当作需要直接跟进的具体账户来规划,而不是当作文档问题。参见 ./references/validation-and-adoption-metrics.md 查看本 skill 15% 截断所校准的已发布曲线。
  • 落后者(Stragglers):截止日期后仍然停留在 N 版本的具体账户或头部依赖方——这是你的支持和成功团队要处理的名单,而不是一个百分比。
采纳曲线和落后者名单在投入上相当,并且是一起获得的:同一个身份关联同时产生两者,曲线是聚合,名单是它的尾部,所以在关联完成之前两者都不存在。Codemod 运行率和指南行为在投入上相当的原因不同——每个都相当于花一小时去读一个别人已经在运行的系统,并且每个回答的都是关于单个工件的问题,而不是关于迁移整体的问题。
这个排序会让采纳曲线——页面上价值最高的数字——被饿死。当需要向客户或领导层为某个移除日期辩护时,把它提到最优先位置,并在发布前开始关联:如果之后才开始,前九十天已经无法测量了。
只有在曲线明显变平后才开始硬性强制(brownout、强制移除、关闭企业逃生舱)。这类已发布的过渡通常需要数年而不是数月才能达到这一点——曲线请参见上面的参考资料。

Failure modes

失败模式

SymptomFix
Guide is the changelog with a new titleRewrite each item as an action the reader takes; delete anything that changes nothing for them
Changes ordered by module or alphabeticallyReorder by blast radius; the change everyone hits goes first
"Update your usage accordingly" with no codeAdd the before/after block; if you cannot write one, the change is not understood well enough to publish
Reader cannot tell whether a change appliesAdd the affected-if line with a search pattern and the literal warning text
Deprecation removed without ever warning at runtimeEscalate the warning level in an interim release before removal; if it is too late, say so and extend support for the old version
Multi-version jump unsupported but not mentionedState the supported hops; give the ordered path for older versions or route them to sequential upgrades
Guide rewritten in place each releaseOne canonical page per version pair, kept online with stable anchors
Enterprise reader has no date to plan againstPublish the deadline, the notice window and the rollback story
Guide names the vendor tooling in every stepDescribe the capability; keep tool names in one integration note that can be updated alone
Effort estimate published without a measured runRun the cold upgrade and publish that number, or publish none
Schema change written as prose with snippetsRewrite as a runbook with per-step rollbacks; see the guide-types reference
Unsupported path half-supportedRoute those readers out explicitly ("stay on 2.x, here is why") instead of leaving them in the main flow
症状修复
指南只是换了个标题的 changelog把每一项重写为读者要执行的动作;删除任何对读者没有任何改变的内容
变更按模块或字母顺序排列按影响范围重新排序;每个人都会遇到的变更排在前面
“请相应更新你的用法”但没有代码添加前后对比块;如果你写不出来,说明这个变更还没有被充分理解,不足以发布
读者无法判断某个变更是否适用于自己添加带搜索模式和字面警告文本的 affected-if 行
弃用在运行时从未警告就被移除在移除前的中间版本中提高警告级别;如果已经太晚,就明确说明并延长对旧版本的支持
不支持跨多版本跳跃却没有说明说明支持的跳跃;为旧版本给出有序路径,或引导它们按顺序升级
每次发布都在原地重写指南每个版本对一个规范页面,带稳定锚点并保持在线
企业读者没有可用来规划的日期发布截止日期、通知窗口和回滚方案
指南在每一步都点名供应商工具描述能力;把工具名放在一个可以单独更新的集成说明中
发布了未经实测的工作量估算运行冷升级并发布该数字,或者不发布
schema 变更被写成带代码片段的散文重写为带逐步回滚的 runbook;参见 guide-types 参考
不支持的路径被半支持明确地引导这些读者退出(“留在 2.x,原因如下”),而不是把他们留在主流程中

References

参考资料

  • See ./references/breaking-change-entry-template.md for the per-change block template and good/bad worked pairs.
  • See ./references/guide-outline-examples.md for the full page skeletons (library/SDK and hosted API) plus a negative outline.
  • See ./references/deprecation-timeline-patterns.md for warning-level ladders, release-count windows and the timeline table format.
  • See ./references/automated-migration-tooling.md for codemod ecosystems, compat builds and coverage-boundary wording.
  • See ./references/api-version-migration.md for hosted-API specifics: pinning, surface matrices, webhooks, cutover and rollback.
  • See ./references/guide-types-beyond-libraries.md for schema runbooks, cloud/platform, mobile and browser-API migrations.
  • See ./references/validation-and-adoption-metrics.md for executable-docs CI, cold walkthroughs, codemod corpus testing and adoption benchmarks.
  • See ./references/sources.md for the published policies, figures and named methods behind every claim above.
  • samber/developer-relations-skills@developer-tutorial (when the reader must learn the new version's concepts, not just port their code)
  • samber/developer-relations-skills@tech-press-relations (press handling for a major version with breaking changes)
  • samber/developer-relations-skills@developer-docs-structure-audit (where the guide belongs in the docs site)
  • samber/developer-platform-skills@api-versioning-policy (choosing the version scheme, deprecation windows and sunset timelines)
  • 参见 ./references/breaking-change-entry-template.md 获取按变更块模板以及好/坏示例对。
  • 参见 ./references/guide-outline-examples.md 获取完整页面骨架(library/SDK 和托管 API)以及一个反面大纲。
  • 参见 ./references/deprecation-timeline-patterns.md 获取警告级别阶梯、版本数窗口和时间线表格格式。
  • 参见 ./references/automated-migration-tooling.md 获取 codemod 生态、兼容构建和覆盖边界措辞。
  • 参见 ./references/api-version-migration.md 获取托管 API 的细节:固定、接口面矩阵、webhook、切换和回滚。
  • 参见 ./references/guide-types-beyond-libraries.md 获取 schema runbook、云/平台、移动端和浏览器 API 迁移。
  • 参见 ./references/validation-and-adoption-metrics.md 获取可执行文档 CI、冷升级走查、codemod 语料测试和采纳基准。
  • 参见 ./references/sources.md 获取上述每个主张背后的已发布政策、数据和具名方法。
  • samber/developer-relations-skills@developer-tutorial(当读者需要学习新版本的概念,而不仅仅是移植代码时)
  • samber/developer-relations-skills@tech-press-relations(处理包含破坏性变更的主版本的媒体关系)
  • samber/developer-relations-skills@developer-docs-structure-audit(指南应该放在文档站点的哪个位置)
  • samber/developer-platform-skills@api-versioning-policy(选择版本方案、弃用窗口和停止服务时间线)