24. 版本、兼容性与变更管理
本章说明 OpenAgenet (OAN) 的版本对象不是单一数字,而是多层坐标:
| 层级 | 例子 | 作用 |
|---|---|---|
| 规范 | 统一技术规范主/次/修订版本 | 定义语义和要求 |
| 协议 | 节点 API、错误和事件版本 | 定义交互契约 |
| 数据模式 | DID文档、资源包、VC、治理事件 schema/profile | 定义可解析结构 |
| 方法 | did:oan 方法规则 |
定义标识符和解析语义 |
| 实现 | Rust crate、npm 包、官网构建提交 | 提供具体代码 |
| 部署 | 配置、二进制、服务提交 | 定义运行环境 |
发布记录必须把上述层级关联起来,不能用 Cargo 或 npm 版本号替代协议、模式或部署版本。一个实现版本可以同时支持多个协议或模式版本,一个资源 DID 也可以对应多个历史 DID 文档和资源包版本;因此发布、兼容、迁移和回滚都必须记录实际映射关系。版本记录还要区分“代码已提交”“产物已构建”“服务已部署”和“变更已生效”,避免把仓库状态误认为线上状态。
版本层级之间的关系可按以下方式核对:
| 变更对象 | 直接影响 | 不应直接推断 |
|---|---|---|
| Rust crate 或 npm 包 | 某个实现或客户端能力 | 协议、DID 方法或线上部署已升级 |
| 协议/API | 节点间请求、响应和错误处理 | 历史资源包已经迁移 |
| 资源模式/profile | DID 文档、资源包、VC 或事件的解析 | 控制权或资源 DID 已改变 |
did:oan 方法 |
标识符解析和控制语义 | 普通资源版本必须更换 DID |
| 部署产物和配置 | 某一环境的运行行为 | 所有节点或第三方实现都已升级 |
24.1 规范版本管理
统一技术规范采用主版本、次版本和修订版本记录结构、语义和勘误变化。主版本变化表示既有实现可能无法直接互操作,次版本用于兼容性扩展,修订版本用于不改变规范语义的澄清或错误修正;每次发布保留受影响章节、发布日期、状态和实现映射。
| 级别 | 适用变化 | 必须保留 |
|---|---|---|
| 主版本 | 破坏既有互操作或语义 | 影响范围、迁移和批准 |
| 次版本 | 向后兼容扩展 | 新字段、兼容测试和实现映射 |
| 修订版本 | 澄清或勘误 | 条款、原意和发布日期 |
24.2 协议版本管理
节点协议和公共 API 应明确版本标识、支持范围、请求/响应模式、错误语义和协商方式。旧客户端在过渡期内只能使用服务端仍声明支持的 profile;服务端不得因为兼容旧请求而静默改变签名、版本、发布序列或治理判断,无法兼容时返回可识别的不兼容错误。
client-supported profiles ∩ server-supported profiles
empty intersection -> explicit incompatible response
因此,协议兼容不仅要检查请求能否被反序列化,还要检查同一输入在签名验证、发布序列、治理判断、错误码和重试行为上的结果是否仍然一致。服务端不能因为兼容旧请求而静默改变这些语义;若旧版本仍可读取但不能安全写入,应分别声明读、写和查询能力。
| 能力 | 兼容性问题 | 记录方式 |
|---|---|---|
| 读取 | 旧客户端是否能解析响应和未知字段 | 支持的响应 profile 与样例 |
| 写入 | 请求是否会生成不同签名、版本或发布事件 | 支持的写入版本和拒绝条件 |
| 查询 | 分页游标、排序、语义过滤是否保持含义 | 查询版本、错误和边界样例 |
| 重试 | 重试是否造成重复注册或重复发布 | 幂等键、序列和重复请求测试 |
24.3 资源模式版本管理
资源元数据、资源包、VC、治理事件和发现响应分别记录 schema 或 profile 版本。它们并非同一个版本:资源包中的 packageVersion 描述资源内容版本,DID 文档的模式版本描述文档结构,VC 的模式版本描述凭证声明和证明结构,治理事件版本描述事件载荷和事件语义。读取方应先识别各自版本,再选择解析器和验证规则,不能用资源包版本替代凭证或事件模式版本。
字段变化的处理边界如下:
| 变化 | 默认处理 | 额外要求 |
|---|---|---|
| 新增可选字段 | 兼容候选 | 旧读取方应忽略或保留,新增方提供回退行为 |
| 新增必填字段 | 可能破坏 | 提供默认语义、升级 profile 或迁移旧数据 |
| 字段改名、改类型或改变单位 | 破坏性 | 新版本、转换规则和负向样例 |
| 改变摘要算法或签名覆盖范围 | 破坏性 | 新验证规则、测试向量和重新发布 |
| 新增未知状态或治理事件 | 需显式处理 | 旧实现不得将未知状态当作有效或已完成 |
{
"schemaVersion": "<resource-package-schema>",
"packageVersion": "<resource-version>",
"resourceDid": "did:oan:<method-specific-id>",
"metadataHash": "<hash>",
"verificationProfile": "<verification-profile>"
}
上例仅为字段关系示例,尖括号内容不是 OAN 的固定取值。对于历史材料,读取方应保留原始版本、摘要和验证结果;无法理解的必填字段、摘要算法、签名结构或状态值必须拒绝或进入明确的隔离状态,不能静默当作当前有效数据。
读取方应先识别 schema/profile,再校验必填字段、摘要算法、签名结构和状态值。删除、改名、改类型或改变签名覆盖范围时,应生成新 profile、迁移说明和负向样例。
24.4 DID 方法兼容性
did:oan 方法变化必须同时评估 DID Core 数据结构、方法特定标识符、解析器、DID 文档、历史资源和发布证据。正常资源版本升级通常保持资源 DID 不变,通过新的 DID 文档、资源包、内容摘要、控制证明或发布证据表达版本变化;这与解析器实现版本或节点软件版本不是同一层面的变化。若方法解析规则、标识符规范化或控制语义发生破坏性变化,应定义旧 DID 的继续解析、迁移或停用策略,不能只更新实现版本。
| 对象 | 必须检查 |
|---|---|
| 标识符 | 语法、大小写、语义代码和规范化 |
| DID文档 | id、验证方法、服务和扩展字段 |
| 控制语义 | 公钥、签名覆盖和更新授权 |
| 历史资源 | 旧 DID、版本、VC 和发布证明 |
| 解析器 | 成功、错误、未知方法和迁移行为 |
资源 DID 不变并不意味着文档内容永远不变。更新方仍须证明其拥有该 DID 对应的控制权,并使新文档、资源包版本、VC 和发布记录能够相互校验;发现服务节点应按其支持的版本和新鲜度规则选择当前可用版本,保留历史版本的可追溯关系。反过来,单纯更换服务器、SDK 或解析器,也不能自动产生新的资源版本。
24.5 向后兼容变更与破坏性变更
兼容性判断以旧客户端、旧节点、历史数据和签名验证行为的可验证结果为准,而不只看字段是否仍能反序列化。评估至少覆盖注册提交、根平台发布、内容分发、发现索引、治理校验、SDK/Skill 调用和失败恢复;任一环节把同一输入解释为不同资源、版本、状态或信任结果,都不能仅按“可解析”认定为兼容。
| 变更类型 | 默认判定 | 必要动作 |
|---|---|---|
| 新增可选字段 | 兼容候选 | 旧客户端回归测试 |
| 错误澄清 | 需评估 | 检查拒绝行为是否变化 |
| 删除必填字段 | 破坏性 | 提高版本并迁移 |
| 改变签名或治理语义 | 破坏性 | 治理审批、重发布和重测 |
24.5.1 兼容性变更
兼容变更保持既有必填字段、签名语义、状态含义和接口成功/失败规则,新增内容应可被旧实现安全忽略或通过协商识别。即使代码可以编译,也要用旧客户端、旧节点和历史数据验证结果一致。
- [ ] 旧必填字段和错误语义仍有效。
- [ ] 旧签名、状态和版本选择结果不变。
- [ ] 旧客户端能读取或安全忽略新增内容。
- [ ] 历史资源、DID文档和凭证仍可验证。
24.5.2 破坏性变更
破坏性变更包括删除或重命名必需字段、改变 DID 或签名语义、改变资源状态、协议路径、版本选择或治理授权判断。此类变更必须提高版本、公布影响、安排迁移窗口,并阻止未完成迁移的节点误把新旧材料混用。 破坏性变更发布前应完成以下检查:
- [ ] 列出受影响的节点、客户端、SDK/Skill、DID文档、资源包、VC、发布证明和索引。
- [ ] 明确旧版本在过渡期内的读取、写入和发现行为。
- [ ] 提供迁移前后样例、负向样例、回滚数据和重测记录。
- [ ] 阻止未迁移组件把新旧材料混合解释为同一有效版本。
发布前应冻结影响范围,明确受影响节点、客户端、DID 文档、资源包、VC、发布证明、治理状态和数据库;未迁移对象不得混用新旧材料。对于无法一次迁移的历史对象,应明确它们是继续可读、仅可验证、禁止更新,还是进入隔离区,并在发现结果中避免把过期或未验证对象显示为当前有效版本。
24.5.3 版本标识
版本标识应说明所属层级、格式、来源和比较规则,例如规范版本、协议版本、资源包版本、schema 版本、Rust crate 版本、npm 包版本和部署提交不能互相替代。资源包版本与资源 DID 稳定性分开记录,证据中同时保存版本和内容摘要。
{
"specVersion": "<spec>",
"protocolVersion": "<protocol>",
"schemaVersion": "<schema>",
"resourceVersion": "<resource>",
"implementationCommit": "<commit>",
"deploymentId": "<deployment>"
}
24.5.4 迁移和过渡期
过渡期应规定旧新版本并行支持范围、开始和结束时间、数据双读/单写策略、节点升级顺序、失败回滚和停止旧版本条件。过渡期内不得让不同版本对同一 DID 产生无法解释的有效版本分叉;结束时重测注册、根平台发布、内容分发、发现查询和治理链路。若旧版本只能读取而不能写入,服务端应在协议能力声明和错误响应中明确表达,不能让调用方通过试错判断迁移状态。 迁移计划至少应记录:
| 阶段 | 允许操作 | 必须观察 |
|---|---|---|
| 双读 | 读取旧、新格式 | 解析和摘要一致性 |
| 单写切换 | 只生成新格式 | 旧客户端错误是否可识别 |
| 收敛 | 补齐历史和索引 | DID、版本和发布证据一致 |
| 结束 | 关闭旧路径 | 回滚入口和残留数据 |
推荐先扩展读取能力,再切换写入方,最后关闭旧读取路径;全程保存数据库迁移、回滚和发现/发布重测证据。
24.6 治理控制的规范变更
涉及节点授权、治理事件、资源状态、根平台可信发布证明、信任判断或节点协议的变更,应经过正式提案、影响评估、治理批准、发布和生效记录。提案、审批、代码实现、构建产物、部署状态和线上生效是不同证据,必须分别记录;签发者、验证者和受影响节点必须明确,不能以代码已经合并或网站已更新替代治理生效。
flowchart LR
A[变更提案] --> B[影响评估]
B --> C[治理批准]
C --> D[实现与测试]
D --> E[发布与生效观察]
24.6.1 变更提案
提案说明动机、范围、受影响章节和对象、兼容性等级、迁移方案、测试证据、风险、回滚方式及拟生效时间。涉及签名、授权或 DID 解析的提案还应列出历史数据和第三方节点的影响。
| 项目 | 应填写内容 |
|---|---|
| 动机与范围 | 原因、角色和对象 |
| 兼容性 | 主/次/修订级别及依据 |
| 迁移 | 数据、节点、客户端和证据 |
| 验证 | 测试向量、集成测试和回滚演练 |
| 生效 | 批准主体、条件和时间 |
24.6.2 治理审批
审批应形成可验证的治理记录,说明决策主体、批准内容、版本、范围、条件和生效依据。普通实现提交、运营口头确认或单个节点本地配置不能替代需要治理授权的事实。 治理审批记录应至少回答“谁批准、批准了什么、何时生效、由谁验证、哪些对象受影响”:
approver: <governance-authority>
approvedScope: [protocol, schema, node-policy]
effectiveCondition: <event-or-time>
verificationEvidence: <record>
24.6.3 发布和生效
发布记录关联规范版本、协议/schema 版本、代码提交、产物哈希和配置。生效应按声明的时间、治理事件或节点升级条件执行,并在生效前完成备份、兼容检查和符合性重测;页面更新不等于协议已经生效。
生效后还应观察跨节点状态、客户端错误、发布游标、索引延迟、版本分布和回滚可行性,确认实现状态与规范声明一致。若部署完成但发现服务节点仍使用旧协议、旧模式或旧治理配置,应将其记录为“已部署但未完全生效”,不能直接标记为完成。
24.6.4 回滚和紧急变更
紧急变更仅限修复安全、数据完整性或重大可用性风险,并记录原因、授权、影响范围和临时期限。回滚必须考虑数据库、发布序列、治理状态和历史证据,不能只把服务二进制换回旧版本;事后补齐正式审查记录。 紧急变更的回滚检查应按对象执行:
| 对象 | 回滚要求 |
|---|---|
| 二进制和配置 | 恢复可验证的构建产物和配置摘要 |
| 数据库 | 保留迁移前备份和恢复校验 |
| 同步游标 | 防止重复处理或跳过事件 |
| 发布状态 | 不把失败发布留作有效事实 |
| 缓存和索引 | 清理与重新同步范围明确 |
回滚检查还应覆盖同步游标、缓存和未完成的发布任务;紧急变更结束后必须补齐正式审批和重测。
24.7 弃用与迁移策略
弃用对象可以是接口路径、字段、摘要算法、协议版本、节点二进制、SDK/Skill 包或配置项。通知应说明对象、替代方案、支持期限、影响版本、迁移工具、验证方法和停止服务条件,并分别说明旧对象在过渡期内是可读、可写、可发现还是可调用。旧接口或字段在过渡期可返回明确的弃用信息,但不得静默改变结果;节点和客户端完成迁移后,按记录的条件停止旧版本并保留审计证据。
通知至少应给出迁移前后样例、验证命令、支持截止时间和失败回滚入口。
24.8 变更记录与发布说明
每次变更记录受影响章节、数据结构、接口、代码仓、数据库迁移、测试、部署、回滚、操作者和已知影响,并明确规范条款与实现状态不一致时的责任人和期限。发布说明应让维护者知道“改了什么、为什么改、谁需要动作以及如何验证”,并能沿着变更编号追溯到批准、提交、产物、部署和生效检查。
changeId: CHANGE-<id>
scope: [spec, protocol, schema, implementation, deployment]
affectedChapters: []
repositories: []
compatibility: compatible|breaking|deprecated
tests: []
deployment: <commit-or-artifact>
rollback: <procedure>
owners: []
knownImpact: <summary>
上述 YAML 是发布记录的示例,不是 OAN 固定配置。状态核对可按以下顺序进行:代码提交后记录提交标识,构建完成后记录产物摘要,部署完成后记录目标环境和服务状态,烟测通过后记录测试结果,满足协议、数据和治理生效条件后再记录 effective。任一阶段失败,都应保留失败原因和回滚动作,而不是覆盖为成功。
24.8.1 规范变更记录
记录章节、条款、版本、变更类型、原文与新意图、兼容性结论、批准记录和生效时间。勘误、澄清和规范语义变化分开标识,避免把实质变更包装成文字修订。 规范变更记录可用如下字段核对:
| 字段 | 内容 |
|---|---|
| affectedChapters | 受影响章节和条款 |
| changeType | 勘误、澄清、兼容扩展或语义变更 |
| approval | 批准记录 |
| effectiveAt | 生效条件或时间 |
| implementationMap | 对应代码、模式和部署版本 |
24.8.2 协议变更记录
记录路由、请求/响应、状态码、错误、签名、游标、版本协商和节点互操作变化,并关联协议测试和旧版本支持期限。至少应说明旧请求是否仍能注册、发布、查询和重试,以及不兼容时返回什么稳定的错误语义。 协议变更记录应把路由、请求/响应、状态码、错误、签名、游标和协商行为分别列出,并至少附一组旧版成功样例、一组新版成功样例和一组不兼容样例。
24.8.3 实现变更记录
记录受影响仓库、提交、依赖、Cargo/package 版本、数据库迁移、构建产物和部署环境。实现修复若尚未同步规范,应明确临时状态和后续规范更新责任;Rust crate、npm 包、官网构建和节点二进制分别记录,不能把其中一个版本号当作整套 OAN 实现的版本号。 实现变更记录应区分“代码已合并”“构建已完成”“已部署”“烟测通过”四个状态,避免提交号存在就被解释为线上已生效。
24.8.4 迁移提示和已知影响
列出需要升级的节点、客户端、SDK/Skill、配置和数据库,说明旧资源、历史 DID、VC、发布证明、索引和缓存的影响,以及迁移失败和回滚后的已知限制。 迁移提示应按角色列出动作和影响,并把“需要升级”与“可以继续读取”区分开:
| 角色 | 需要关注 |
|---|---|
| 资源提供方 | 资源包、DID文档和签名生成方式 |
| 节点运营方 | 配置、数据库、游标和服务升级顺序 |
| 客户端和 SDK | 版本协商、错误处理和缓存失效 |
| 审查方 | 旧资源、历史证据和重测范围 |