摘要

  • Concise Diagnostic Notation 第 28 版草案为 CBOR 提供更系统的可读表达和应用扩展,但源文本并不是自给自足的执行合同。
  • 高后果流程应保存一份“解释回执”,钉住草案版本、注册表快照、扩展实现与版本、允许清单、被忽略的指示符、警告、结果值以及必要时的编码字节。

诊断记法的价值,是让人不用先读二进制就能理解一个数据模型值。它的治理风险,也来自这种可读性:人容易把“我看懂了文本”误认为“所有决定结果的条件都写在文本里”。

IETF CBOR 工作组的 Concise Diagnostic Notation 草案试图把 CBOR 既有的文本记法汇总并形式化。带前缀的字符串并非普通字符串加一个标签。前缀会选择一段应用扩展逻辑:h 与 b64 可把文本转换为字节,dt 处理时间表达,ip 处理地址或前缀;带前缀的序列还可以携带参数,最终产生一个 CBOR 数据模型项。

方便之处在于,共同名字可以复用共同转换。边界则在于,文件只写了它想调用的名字。它没有自动证明解释器使用了哪个注册表快照、哪份扩展规范、哪一个实现和版本,也没有证明运营方允许该扩展运行。命令行选项、插件装载方式、允许清单和警告输出都可能留在文本之外。

第 28 版并未掩盖这些事实。草案明确说 CDN 面向人类,并不提供确定性表示;数据项变为文本再被读回时,不保证保持同一文本,也不保证得到同一编码字节。若扩展参数上带有编码指示符,而该扩展没有规定特别处理方式,消费方必须接受这个指示符,可以处理,也可以忽略;若未处理,建议给出警告。因此,“解析成功”无法证明评审者看到的每个信号都参与了结果计算。

安全章节把本地权力写得更清楚。工具必须避免攻击者调用运营方原本不打算暴露的扩展。显式启用或允许清单可以成为防线;是否启用可通过带外配置决定。于是,同一份源码在两个都理解语法的解释器里得到不同结果,不一定是谁读错了,也可能是两个责任主体作出了不同授权决定。

注册名字,不等于注册运行环境

草案提出应用扩展标识符注册表,并要求实现 h、b64、t1、b1、dt 与 ip 这组核心扩展。注册表解决命名碰撞,给不同文档提供共同词汇。然而,注册表条目、扩展规范、运行代码和部署策略仍是四个不同事实。

它采用 Expert Review 政策。草案也预留了一种情况:完整规范可能尚不可得,专家仍可为已经部署的标识符登记名字,避免后来发生冲突。这是合理的命名治理,却同时说明“已注册”不能被扩大为“语义已经完整稳定”“所有实现一致”“在这里安全启用”或“已获准驱动后续动作”。

设想一个发布流程:开发环境自动装载所有扩展,生产环境只允许经过批准的最小集合。同一个文件在开发环境生成一个值,在生产环境被拒绝。文件哈希相同,前缀也真实存在。差别落在本地允许清单。若发布证据只保存文件,就无法说明为什么昨天成功、今天失败。

再设想两个环境都显示成功。一个处理了可见的编码指示符,另一个按扩展规则忽略了它,并发出警告;构建平台随后丢弃了警告。最终的绿色状态完全相同,但语义证据并不相同。门禁必须比较警告与结果值,而不是只读退出码。

一份主动暴露不确定性的草案

Datatracker 显示,第 28 版是 CBOR 工作组的活跃 Internet-Draft,处于工作组最后征求意见阶段,IESG 状态为 “I-D Exists”。它不是 RFC,也不是已经批准的标准。

冻结资料还存在一个必须保留的状态冲突:草案正文页眉写着 “Intended status: Standards Track”,Datatracker API 却记录为 “Informational”。本文不替流程选择其中一个,更不会把任一字段包装成最终结论。

第 28 版开头的编辑说明尤其重要。它说本版尝试把邮件列表讨论过的功能删除,以相对第 27 版的差异形式反映出来;文本因此在一定程度上不一致,一些解释性章节可能已经不能完整反映技术内容,甚至可能产生误导;工作组对 CDN 名称以及 b1、t1 命名也尚未提供意见。27 到 28 的对比确实删除了此前的 CRI 扩展、编码指示符注册表、CDN 输入的二进制标签表示及相关处理部分。

这种公开不确定性值得信任,但也要求使用者降低断言强度。“支持第 28 版”不是充分证明。它还要回答:已删除功能是否真的从运行代码移除,是否仍藏在兼容选项之后,解析器采用哪一份注册表快照,哪些行为来自当前技术条款,哪些来自草案自己警告可能滞后的说明文字。

把“有效”拆回七条证据

一次成功解析至少压缩了七个问题:评审的源字节是否就是运行时收到的字节;哪个草案版本的语法接纳了它;哪个注册表快照解析了前缀;哪份扩展实现和版本处理了参数;哪一份允许清单和带外配置准许运行;哪些指示符被处理或忽略、哪些警告被保留;最终构造了哪个 CBOR 值,以及在字节重要时使用何种编码并得到什么哈希。

这些问题可独立变化。源码不变,插件包可能升级;注册表不变,生产允许清单可能收紧;数据模型值不变,编码字节可能改变;字节完全一致,也不代表应用有权用它修改网络、签名或下发设备。

因此需要一份解释回执。这是 Daniel Kade 的运营建议,不是第 28 版草案的规范要求。回执应记录源哈希、草案版本、注册表快照、扩展标识符与规范、具体实现和版本、参数、允许清单与其他带外配置、编码指示符策略、全部警告、结果值的稳定描述或哈希,以及在字节敏感场景中的编码配置与字节哈希。

回执也必须知道在哪里结束。模式校验、签名验证、动作授权、网络变更和业务效果,应各自留下后续证据。若把它们压成一个“有效”字段,组织就失去定位故障层的能力。

这与更广的互联网协调原则一致:共享符号可以降低协调成本,却不会自动取得本地未来决定的权力。CDN 改善的是地图层。真正运行的代码、配置、结果和动作属于运行现实。最小共享规范应清楚标出边界,而不是让共同名字悄悄接管本地授权。

冻结来源没有证明部署规模、采用率、互操作测试、具体产品行为、安全事故、漏洞、性能或中断。本文不需要制造这些故事。扩展模型、允许忽略指示符、注册表政策、带外启用和非确定性本身,已经足以证明结果依赖文本之外的控制面。

RFC 8949 与 RFC 8610 分别提供 CBOR 和 CDDL 背景;RFC 4648 与 RFC 3339 分别定义基础编码与时间格式。它们不能证明两个部署解释器使用相同代码和配置。RFC 9741 讨论一个值如何确定性编码,却不能决定扩展最初应构造哪个值。