Persistent-state migrations
Persistent-state migrations 是主人确认的 house policy,管理 durable state 在程序版本之间的迁移、兼容性、rollout、验证与恢复。durable state 是程序写入后会被同一程序或后续程序版本继续读取的状态,不限于关系数据库:文件、对象、消息、设备配置、嵌入式存储或其他跨版本数据都在范围内。
- 交付
- 治理
目录
Definition
Persistent-state migrations 是主人确认的 house policy,管理 durable state 在程序版本之间的迁移、兼容性、rollout、验证与恢复。durable state 是程序写入后会被同一程序或后续程序版本继续读取的状态,不限于关系数据库:文件、对象、消息、设备配置、嵌入式存储或其他跨版本数据都在范围内。
关系数据库和 embedded database 是 durable state 的实现案例,不是这个 Topic 的前提。本 Topic 是 migration policy 的主归属:它不分配 version identity、tag 或 release label,也不从迁移实现单独决定 public API impact;SemVer change governance 负责跨合同的 version-impact classification。
When to use
当交付会创建、读取、转换、替换或停止读取跨程序版本存在的 state 时使用。数据库 schema migration、文件格式演进、队列 payload 演进、设备配置转换以及历史数据修复都应先判断是否命中。只改临时 cache、fixture 或保证不跨版本存续的内部数据时,不应套用本 Topic。
实现同时涉及 public API 时,应先读取 SemVer change governance 的 classification contract;本 Topic 补充 state 的实现与验证证据。只需要 version identity、release label 或 tag 的任务应使用相邻 delivery Topic,而不是把本 Topic 当作泛化发布流程。
Habits / defaults
- 每项迁移使用
skills/policies/persistent-state-migrations/assets/templates/persistent-state-migration-record.example.json记录 durable state、source compatibility range、操作顺序、rollout/observability、recovery 与 validation。记录不绑定数据库引擎、migration tool、外部 SaaS、实现语言或特定交付工作流。 - 已部署 migration 不可变。直接回退程序不会自动 reverse、compensate 或 down-migrate 已持久化 state;停止 faulty release 后,新的程序版本必须 forward repair 并能处理它已经留下的 state。backup restore 是独立的 disaster recovery,不可当作普通 rollback 的隐性部分。
- structural change 与 data backfill 可以在同一 release 发生,但必须是 separate、ordered、observable、pauseable operations。每一步都要有自己的完成信号和暂停点;不得把 schema/structure 与历史数据转换封成一笔不可分割的 migration transaction。
Database migrations: DDL, DML, and historical data
数据库属于 durable state 的一种实现时,DDL 表示 schema 或其他 structural changes;DML 表示对当前数据的操作;historical-data backfill/transformation 表示为既有数据补全、重写或转换。三者必须在 migration record 中分开描述、排序并验证,即使某个 release 只包含其中一类。DDL 完成并不证明历史数据已可用,DML/backfill 成功也不能掩盖 structural compatibility 问题。
Compatibility, recovery, and required validation
| Verified impact | Public API contract | Persistent-state compatibility and recovery | Required test evidence |
|---|---|---|---|
patch | public API nonbreaking | patch 写入的 state 必须被同一 Minor 内所有受支持的较早程序版本使用;程序可停止或回退,但不自动变更其已写 state | 证明 public API nonbreaking;由 candidate 写入/转换 state 后,用每个受支持 earlier same-Minor program 读取并完成其受支持操作;证明 deployed migration 可重复识别且不会被重写 |
minor | public API 在同一 Major 内 compatible | earlier-Minor program 不要求读取 newly migrated state;candidate 必须处理支持范围内 earlier-Minor state。发生故障时以新 patch 的 forward repair 处理 stopped release 留下的 state | 证明 API compatibility;从每个支持的 earlier Minor state upgrade 到 candidate,并验证 candidate 读写;模拟 stopped faulty release 的 state,验证 repair version 可观察地继续或修复 |
major | public API may break | state 只支持 immediately preceding Major 到 current Major;direct major skipping 不受支持。故障仍以 forward repair 处理当前已存在 state | 证明 adjacent-Major source state 可升级并由 current program 读写;证明 skipped-Major input 被拒绝或需要明确中间升级;模拟 stopped release state 的 repair path |
Minor 的 state incompatibility 不会自动把 public API classification 提升为 Major。应分别记录 API 和 state 证据,再由 SemVer change governance 在 release unit 层取 maximum verified impact。
Reference implementations
当前没有已入库 project snapshot 覆盖完整的跨 storage migration policy,因此不把 owner policy 写成既有项目事实;medium confidence 表示政策已批准,代表性采用证据仍待累积。
skills/style-playbook/references/topics/semver-change-governance/TOPIC.md:负责 planned/current/verified version-impact 及 release unit 的 maximum verified impact;本 Topic 提供 state migration 所需的实现与验证证据。skills/style-playbook/references/topics/sqlite/TOPIC.md:负责 SQLite-specific ownership、路径、volume 与运行策略;它应消费本 Topic 的 release-to-release compatibility policy,而不把 SQLite 细节泛化为全部 durable state。projects/style-playbook-skills.md:记录当前库使用 SQLite 保存 generation/state 的事实,说明 database 只是 durable state 的一个 implementation case,不证明本 Topic 已在该项目完整采用。
Failure modes
- 将 durable state 窄化为数据库,会遗漏文件、设备配置或其他跨版本数据;先追踪谁写、哪些版本读、支持范围是什么,再决定 storage-specific implementation。
- 把 deployed migration 当作可随着程序 rollback 自动反转的代码,会破坏已存在 state 的可读性;停止 faulty release 后必须新增 forward repair,backup restore 只走独立 disaster recovery。
- 把 DDL、DML 和 historical-data backfill/transformation 合并为一个“migration 已完成”状态,会掩盖顺序、进度和暂停边界;每项必须独立 observable、pauseable 并可验证。
- 以 successful DDL 代替 state validation,或只测试新程序而不测试定义的 source compatibility range,会造成未发现的 version boundary 失败。
- 要求 earlier Minor 读取新 state,或允许 direct major skipping,却没有把额外 bridge 明确写入支持范围,会违反本政策的兼容性边界。
- 因 Minor state incompatibility 直接推导 public API Major,或把 label、tag、数据库引擎和 CI tool 写成统一前提,会越过本 Topic 的边界;这些事项分别交给
SemVer change governance和相邻 Topic。
Evidence index
skills/style-playbook/references/topics/persistent-state-migrations/TOPIC.mdskills/policies/persistent-state-migrations/assets/templates/persistent-state-migration-record.example.jsonskills/style-playbook/references/topics/semver-change-governance/TOPIC.mdskills/style-playbook/references/topics/sqlite/TOPIC.mdprojects/style-playbook-skills.md