第 10 章 版本管理

权威来源声明(Single Source of Truth)。 DTP 版本管理的策略以第 1 章 §1.7「版本管理与兼容性」为唯一权威来源。本章 不得 重新定义 §1.7 已规定的策略;本章仅提供 §1.7 规则的操作性机制(线格式绑定、错误码具体载荷、协商时序、实现声明模板)与治理流程(目录与状态约定、定稿标准动作)。本章任何陈述与 §1.7 发生歧义时,必须 以 §1.7 为准。

10.1 版本号格式(操作性引用)

DTP 协议版本号的语义、MAJOR.MINOR 两级结构(无 PATCH)、变更判定规则与正交轴定义见 §1.7.1 与 §1.7.2,本章不重述。

线格式绑定:每个 LogicalFrame 的帧头 必须 携带完整的 ProtocolVersion 字段(参见第 4.4 节):

interface ProtocolVersion {
  major: number;  // 非负整数
  minor: number;  // 非负整数
}

本规范定义的协议初始版本 必须{ major: 1, minor: 0 }(即 dtp/1.0)。

10.2 版本兼容性矩阵(§1.7.3 的操作性补充)

兼容性与协商的规范性规则见 §1.7.3。下表为其在帧处理层面的操作性落地,必须 依据 §1.7.3 解读,二者如有歧义以 §1.7.3 为准。

接收帧版本处理方式
等于接收方最高版本正常处理
等于接收方最高版本的前一个主版本(major - 1)兼容处理(按旧规范处理)
高于接收方最高版本必须 返回 VERSION_INCOMPATIBLE(7001)
低于 (接收方最高版本 - 1) 的主版本必须 返回 VERSION_INCOMPATIBLE(7001)
同主版本,更低次版本正常处理(向后兼容)
同主版本,更高次版本 处理(忽略不识别的可选字段)

10.2.1 次版本号容错(§1.7.3 的操作性落地)

接收到主版本号相同但次版本号更高的帧时,实现 必须

  1. 处理已知字段;
  2. 忽略未知的可选字段;
  3. 不得 因未知可选字段而拒绝整个帧;
  4. 不得 抛出错误。

10.3 版本不兼容处理(操作机制)

10.3.1 接收方处理

接收方收到协议版本号高于自身支持版本(且超出兼容范围)的 LogicalFrame 时 必须

  1. 不处理 该帧;
  2. 向发送方发送 VERSION_INCOMPATIBLE 错误(7001);
  3. 在错误通知的 details 字段中包含自身支持的最高版本号:
{
  errorCode: 7001,
  errorMessage: "Protocol version higher than supported",
  details: {
    supportedMaxVersion: { major: 1, minor: 0 }
  }
}

错误码 7001 的语义以第 9 章错误码表与 schema 为准,本章不另立定义。

10.3.2 发送方处理

发送方收到 VERSION_INCOMPATIBLE 错误后 选择:

  1. 降级到对端支持的版本 重新发送该帧( 优先选择,前提是双方存在共同 MAJOR;跨 MAJOR 不降级,见 §1.7.3);
  2. 通知上层应用 版本不兼容,不得 自动持续重试。

实现 不得 在收到版本不兼容错误后立即关闭会话, 给予降级机会。

10.3.3 会话内版本一致性与协商时序

DTP 会话建立时,双方 必须 协商一致的协议版本(协商规则见 §1.7.3)。会话期间:

  1. 协商后整个会话 必须 使用统一的版本;
  2. 不得 在会话进行中切换协议版本。

版本协商 遵循以下时序,具体承载方式(CAP 扩展、首个 Request_Frame/Response_Frame 等) 由实现选择,但 必须 在第一个数据帧发送前完成:

DTP_A                              DTP_B
  |                                   |
  |-- Hello (supported_versions) --->|
  |                                   |
  |<-- Hello_Ack (chosen_version) ---|
  |                                   |
  |    [双方使用 chosen_version]       |

10.4 协议演进与治理

本节给出 §1.7 治理规则的操作流程。其中涉及的 git tag 格式、文档状态枚举、编辑版次定义,必须 以 §1.7 为规则锚点,本节不重定义。

10.4.1 目录与状态约定(与 Faying Protocol 一致)

  • 文档状态是 front matter 标记,不得 编码进路径(见 §1.7.1)。
  • specification/必须 仅保留唯一一个可变工作区 draft/(滚动更新)。
  • draft/ 外的所有目录 必须 以发布日期命名(如 2025-10-25/),代表一个冻结的已发布版次;「非草案即已发布」。
  • 某发布版次当前是 Final 还是 Deprecated / Obsolete 由其文件的 status 字段决定,不得 依据目录名判断。
  • 禁止 创建以状态命名的目录(如 final/)——否则版次被弃用时需搬移目录、破坏链接。
  • WHEN 发生状态流转,必须 仅修改 front matter 的 status,且目录 不得 移动。

10.4.2 草案与正式版本

  • 草案:文档存放于 docs/{lang}/specification/draft/,schema 存放于 schema/draft/;草案版本号 使用 { major: 0, minor: N }Draft 期间 兼容性承诺(见 §1.7.5),且 不得 用于生产环境。
  • 正式版本:必须 经过完整评审与公开讨论,拥有不可变的版本快照;文档存放于 docs/{lang}/specification/{YYYY-MM-DD}/,schema 存放于 schema/{YYYY-MM-DD}/。第一个正式版本为 2025-10-25,对应协议版本 dtp/1.0
  • 版本快照不可变性:正式版本一经发布 必须 保持不可变;纯文字勘误按 §1.7.4 以新的发布日期目录承载,既有目录冻结,不得 原地改写已发布快照的规范内容或 schema。

10.4.3 定稿标准动作(Draft → Final)

WHEN 执行定稿,Doc Governance Process 必须 依次完成以下动作:

  1. 通过 git mvdraft/ 下全部文件迁移至发布日期目录(文件名不变),并清空 draft/
  2. 逐文件将 statusDraft 改为 Final
  3. date 固化为正式发布日期,将 editors 锁定为定稿署名名单,并保持 version 不变;
  4. 在 README front matter 中写入 replaces 历史链(指向草案目录及其定稿提交短哈希);
  5. 打 tag dtp-v<MAJOR.MINOR>-final,该 tag 必须 同时覆盖正文 + 测试向量 + schema;
  6. 涉及多语言 / 多文件时,必须 在同一次提交中一并迁移,不得 单边发布。

10.4.4 弃用与移除

实现 通过以下流程弃用功能:

  1. 标记为弃用:在 MINOR 版本中将功能标记为 deprecated,但 必须 继续支持;
  2. 过渡期:至少经过一个完整的 MAJOR 版本周期;
  3. 移除:在下一个 MAJOR 版本中移除。

实现 不得MINOR 版本中移除已弃用的功能。

10.5 实现声明

DTP 实现 必须 在文档中声明:

  1. 支持的最高协议版本;
  2. 支持的所有前序主版本;
  3. 是否支持未来兼容(处理更高次版本的帧);
  4. 实现定义的扩展(如有)。

例如:

DTP 实现 X 版本声明:

  • 支持的最高协议版本:1.0
  • 兼容前序版本:无(首个正式版本)
  • 未来兼容:支持,会忽略未知的可选字段
  • 加密算法:AES-256-GCM、ChaCha20-Poly1305
  • 传输适配器:BLE、WebSocket、TCP