RFC 10:Documentation Conventions——当技术讨论开始扩容,RFC 如何成为一套可运行的协作协议

RFC 10 没有定义一个网络报文,却解决了另一个同样真实的系统问题:当参与 ARPANET 协议设计的人和站点迅速增加时,技术意见怎样被唯一编号、稳定引用、可靠分发,又怎样避免“写成文档就自动变成权威结论”。它对 RFC 3 的修订幅度并不大,恰恰因此更值得读——真正发生变化的不是写作哲学,而是这套协作机制开始从几个人之间的工作笔记,向一个需要治理编号、参与者和分发拓扑的技术基础设施演化。

前言

假设一个开发团队只有五个人。

有人在会议里提出一个协议修改,其他人都听到了;有人写了一页草稿,直接复印几份放到桌上;两份文档标题重名,也不是什么大事,因为大家知道“你说的是哪一份”。

现在把参与者换成分布在 UCLA、SRI、Utah、UCSB、RAND、Lincoln Laboratory、BBN、ARPA、SDC 等不同机构的一群工程师。

问题立刻变了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
谁都可以写技术意见,
那怎样保证两个人不会使用同一个文档编号?

标题允许重复,
那引用时到底靠什么定位?

作者把文档写完以后,
怎样保证所有相关站点都能拿到?

联系人换了、地址变了,
分发系统怎样维护?

一份草稿被写成正式文字以后,
别人会不会误认为它已经获得某种官方批准?

RFC 10 解决的就是这些问题。

它的标题仍然是 Documentation Conventions(文档约定),并且开门见山:

1
This note is a revision of NWG/RFC #3

这意味着阅读 RFC 10 时,真正需要问的并不是:

“它规定了哪些文档格式?”

而是:

为什么 RFC 3 才发布几个月,就已经需要修订?哪些规则必须保持不变,哪些运行细节已经跟不上工作组扩张?

答案非常有意思。

RFC 10 几乎完整保留了 RFC 3 最重要的几条原则:

  • Membership is not closed
  • 任何站点、任何人都可以产生 NWG Note;
  • 内容可以只是一个想法、建议、实现技巧,甚至只有问题没有答案;
  • 文档应该 timely rather than polished
  • 一篇 Note 最短只需要一句话;
  • “写下来了”不等于“有权威”;
  • 标题不要求唯一。

真正修改的主要是:

1
2
3
4
参与者名单
编号负责人
分发名单
联系地址

换句话说,RFC 10 面对的主要不是“写作规范不够好”,而是一个典型的系统扩容问题:

协议设计社区正在变大,原来靠少数人彼此认识就能维持的协作方式,需要开始显式管理身份、编号、路由和目录。

读懂 RFC 10,真正有价值的不是记住 1969 年某个人的电话号码。

而是看懂一套技术协作机制怎样从:

1
非正式讨论

逐渐长出:

1
2
3
4
5
6
7
稳定标识
集中编号
最小元数据
开放投稿
分布式复制
联系人目录
显式版本替代

这些结构。

这套机制后来当然发生了巨大变化。今天 RFC 不再是“一句话也可以”的最终出版物,正式 RFC 通常从 Internet-Draft 开始,经讨论、评审、修订、批准和编辑后才获得 RFC 编号。

但如果想理解为什么现代技术组织喜欢用:

1
2
3
4
5
RFC
Design Proposal
ADR
Issue
Pull Request

把尚未定稿的设计放进一个可讨论、可追踪的公共空间,RFC 10 是一篇很好的早期样本。

RFC 基本信息

项目 内容
RFC RFC 10
Official Title Documentation conventions
发布时间 1969 年 7 月 29 日
作者 S. D. Crocker / Steve Crocker,UCLA
Status Unknown,属于现代分类建立前的 Legacy Stream
Updates
Updated by RFC 24、RFC 27、RFC 30
Obsoletes RFC 3
Obsoleted by RFC 16
原文 RFC 10
RFC Editor 信息页 RFC 10 Info

这里最容易误解的是 Status: Unknown

RFC 10 发布于现代 IETF Standards Track、BCP、Informational、Historic 等完整分类体系出现之前,因此不能把 Unknown 理解成:

1
“现在还不知道它是不是有效标准。”

它是一份 Legacy RFC

RFC Editor 当前还明确给出了它的演化关系:

1
2
3
4
5
RFC 3
↓ Obsoleted by
RFC 10
↓ Obsoleted by
RFC 16

同时 RFC 24、27、30 又在后续继续更新这套 Documentation Conventions。

这看起来不像今天干净的版本树,原因在于这些最早期 RFC 本来就不是按后来成熟的 Updates / Obsoletes 语义设计的;今天看到的关系,是对早期文档演化历史的结构化整理。

RFC 10 在当时也不是“互联网标准”。

它更接近:

Network Working Group 用来规定自己怎样产生、编号和分发技术工作笔记的一份运行规则。

为什么会有这篇 RFC

RFC 10 要解决的问题,只有和 RFC 3 对照起来才真正清楚。

1969 年 4 月的 RFC 3 已经建立了最基本的规则:

1
2
3
4
5
6
7
8
9
10
11
任何人都能写

内容不必成熟

获得一个 RFC Serial Number

带上作者、机构、日期、标题

发送给固定联系人

各站点自己复制

这套机制在一个极小的工作组中足够好。

RFC 3 列出的 Network Working Group 核心成员主要来自:

1
2
3
Utah
SRI
UCLA

文档分发名单只有 6 个联系人,RFC 编号由:

1
Bill Duvall at SRI

分配。

几个月以后,RFC 10 列出的参与者已经扩展到:

1
2
3
4
5
Utah
SRI
UCLA
RAND
Lincoln Labs

分发点也扩展到:

1
2
3
4
5
6
7
8
9
UCLA
UCSB
SRI
Utah
RAND
Lincoln Labs
BBN
ARPA
SDC

一共 9 个。

这里最重要的变化不是“名单多了几个人”。

而是系统规模发生了变化。

一个只有三四个机构的讨论组,可以大量依赖:

1
2
3
4
大家互相认识
大家知道谁手里有最新版
大家知道谁负责编号
地址有变化直接告诉熟人

当参与者不断增加,这种隐式知识就会开始失效。

可以把 RFC 3 到 RFC 10 的变化看成一个很典型的扩容过程:

flowchart LR
    A[少量站点<br/>人员彼此熟悉]
    B[更多站点加入]
    C[编号冲突风险上升]
    D[分发路径变复杂]
    E[联系人与地址需要维护]
    F[协作规则必须显式化]

    A --> B
    B --> C
    B --> D
    B --> E
    C --> F
    D --> F
    E --> F

已有方法哪里不够

RFC 3 的原则本身没有失效。

事实上,RFC 10 几乎逐字保留了最核心的 CONTENT 部分。

真正不足的是它的运行配置

编号负责人需要变化

RFC 3:

1
Serial numbers are assigned by Bill Duvall at SRI

RFC 10 改成:

1
Serial numbers are assigned by Steve Crocker at UCLA

RFC 10 没有解释为什么换人,因此不能伪造“作者认为应该由 UCLA 中心化管理”之类的结论。

但从系统角度可以明确看到:

RFC 编号需要一个单一协调点,否则“任何人都能写”很容易变成“任何人都能随便占号”。

开放作者权和受控命名空间并不矛盾。

反而是二者必须同时存在:

1
2
3
4
5
内容生产:
分布式、开放

全局 ID:
集中协调、唯一

分发名单需要扩容

RFC 3 只要求作者站点把一份副本发给 6 个联系人。

RFC 10 扩成 9 个。

这意味着文档系统已经出现了最朴素的 fan-out distribution(扇出分发)

1
2
3
4
5
6
7
8
9
10
11
Author Site

├── UCLA
├── UCSB
├── SRI
├── Utah
├── RAND
├── Lincoln Labs
├── BBN
├── ARPA
└── SDC

作者不负责给每一位工程师复制几十份。

作者只负责把:

1
one copy

送到每个分发节点。

然后:

1
Reproduction if desired may be handled locally.

也就是:

各站点自己完成本地复制。

这是一个很合理的层次:

1
2
3
4
5
跨站点传播
→ 由 RFC 分发规则解决

站点内部传播
→ 由本地自行解决

如果把所有复制压力都放在作者身上,随着站点数量增加,成本会迅速失控。

联系方式已经成为系统状态

RFC 10 比 RFC 3 多了一个很长的:

1
ADDRESSES

章节。

里面记录:

  • 邮寄地址;
  • 机构;
  • 电话;
  • 分机号。

并且作者明确写:

1
2
Below are the most current addresses I have.
Please correct as necessary.

这句话其实很重要。

它说明 RFC 分发系统已经遇到一个所有分布式目录都会遇到的问题:

目录里的地址会过期。

一个联系人:

1
2
3
4
离职
换办公室
换机构
电话号码变化

都会使分发拓扑失效。

所以 RFC 10 不只是在管理“文档”。

它实际上还在维护:

1
Document Routing Directory

RFC 10 的真正设计目标

从原文可以把目标重建成四层。

Problem

1
2
技术讨论需要跨多个 ARPANET 相关站点流动,
但参与者增加以后,仅靠口头约定无法稳定管理文档身份和分发。

Goal

建立一个足够轻量的机制,使技术意见能够:

1
2
3
4
5
6
快速发表
稳定编号
明确作者
跨站点分发
本地复制
持续接受评论

Constraint

当时没有今天的:

1
2
3
4
5
6
GitHub
Email Distribution List
Datatracker
Web Archive
Collaborative Editor
CI Document Builder

更关键的是,ARPANET 本身甚至还没有成为一个稳定可用的文档分发网络。

所以制度必须建立在:

1
2
3
4
纸质 / 离线副本
人工编号
固定联系人
本地复制

之上。

Non-goal

RFC 10 并没有定义:

  • 一篇 Note 怎样“批准”为标准;
  • 怎样判定 Working Group Consensus;
  • 怎样做技术评审;
  • 怎样解决两种冲突提案;
  • 怎样定义 Standards Track;
  • 怎样管理版权或知识产权;
  • 怎样验证文档作者身份;
  • 怎样进行数字签名;
  • 怎样保证副本可靠送达;
  • 怎样给一篇 RFC 发布修订版而保持同一个编号。

这些今天看起来很重要的机制,要么当时根本还没有形成,要么并不是 RFC 10 要解决的问题。

RFC 10 的设计范围非常窄:

先保证想法能够低门槛地产生,并进入一个有编号、有作者、有分发路径的共享讨论空间。

核心内容

RFC 10 最值得理解的不是 CONTENT / FORM / DISTRIBUTION / ADDRESSES 四个标题本身,而是它们组合以后形成的四个关键设计选择。

开放写作,但拒绝“文档天然有权威”

RFC 10 最核心的一段和 RFC 3 基本不变。

它允许 NWG Note 是:

  • 一个抽象观点;
  • 一个具体实现技巧;
  • 没有背景说明的建议;
  • 一个没有答案的问题;
  • 最短只有一句话。

同时明确提出:

1
timely rather than polished

这不是随便降低质量标准。

它解决的是两个不同但相关的问题。

问题 1:写成文字以后,人们会自动赋予它权威

RFC 10 明确担心:

1
2
written statement
→ ipso facto authoritative

也就是一旦某个设计写成一份有标题、有编号、有作者的文档,读者很容易把它理解成:

1
2
3
已经被批准
已经形成共识
已经是官方方案

但 Network Working Group 当时正处于探索期。

如果只有“已经足够正确”的东西才能被编号,很多真正需要讨论的错误假设根本不会被暴露出来。

所以 RFC 10 的选择是:

1
降低文档的默认权威性

而不是:

1
提高进入讨论系统的门槛。

收益是:

1
2
3
问题可以更早暴露
设计可以更早被挑战
反馈进入得更快

代价也很明显:

1
2
读者不能把 RFC 编号本身
当作“这个设计已经正确”的证明。

这一点直到今天仍然重要:

RFC Number 从来不自动等于 Internet Standard。

现代 RFC 已经有更明确的 Stream、Status 和审批流程来解决这个问题;1969 年的做法则更原始,主要依靠文化约定告诉参与者:

1
“它只是 Request for Comments。”

作者可以分布式产生文档,但编号必须全局唯一

RFC 10 仍然坚持:

1
Notes may be produced at any site by anybody

这是高度去中心化的作者模型。

但如果每个站点都自行给文档编号,就会立刻出现经典的分布式 ID 冲突:

1
2
3
4
5
UCLA:
“这是 RFC 42。”

SRI:
“巧了,我们也刚发了 RFC 42。”

于是 RFC 10 采用:

1
2
3
Distributed Authoring
+
Centralized Serial Allocation

即:

flowchart LR
    A[UCLA Author]
    B[SRI Author]
    C[RAND Author]
    D[Steve Crocker / UCLA<br/>Serial Number Authority]
    E[RFC N]
    F[RFC N+1]
    G[RFC N+2]

    A --> D
    B --> D
    C --> D
    D --> E
    D --> F
    D --> G

RFC 3 的编号负责人是 Bill Duvall / SRI,RFC 10 改成 Steve Crocker / UCLA。

负责人是谁是历史配置。

真正长期有效的设计思想是:

开放生产内容,不等于开放生成全局唯一身份。

命名空间需要协调。

标题可以重复,所以 Serial Number 才是真正的 Identity

RFC 10 再次明确:

1
The title need not be unique.

这句话非常容易被忽略。

如果标题不唯一,那么:

1
2
Documentation Conventions
Host Software

都不能作为文档主键。

实际上:

1
2
3
4
5
RFC 3
RFC 10
RFC 24
RFC 27
RFC 30

就有多篇叫 Documentation Conventions

这意味着 RFC 系列很早就做出了一个正确的信息系统设计:

1
2
3
4
5
6
7
Human-readable Title

Identity

Serial Number
=
Stable Identity

可以类比:

1
2
3
4
5
6
7
8
9
10
11
数据库:
display_name 可以重复
primary_key 不可以

GitHub:
Issue Title 可以重复
Issue #123 不可以

RFC:
Title 可以重复
RFC 10 不可以重复

这让引用和演化关系成为可能。

如果后来有人写:

1
This note is a revision of NWG/RFC 10

不会因为标题重复而产生歧义。

分发采用“跨站点单副本 + 本地复制”的两级结构

RFC 10 的 Distribution 不是一个无聊的通讯录。

它实际上定义了一种分层复制策略。

作者站点只负责:

1
2
对每个指定站点
发送一份

各站点负责:

1
2
根据本地需要
继续复制

可以表示为:

flowchart TD
    A[Author Site]
    U[UCLA Contact]
    S[SRI Contact]
    R[RAND Contact]
    B[BBN Contact]

    U1[UCLA Local Readers]
    S1[SRI Local Readers]
    R1[RAND Local Readers]
    B1[BBN Local Readers]

    A -->|one copy| U
    A -->|one copy| S
    A -->|one copy| R
    A -->|one copy| B

    U -->|local reproduction| U1
    S -->|local reproduction| S1
    R -->|local reproduction| R1
    B -->|local reproduction| B1

为什么不让作者直接把文档寄给所有读者?

因为作者并不知道每个机构内部到底有多少人需要阅读。

把责任拆开以后:

1
2
3
4
5
Global Distribution
只关心 Site

Local Distribution
只关心 Site 内部人员

这是一个很典型的层次化扩展策略。

代价是:

1
中间联系人变成关键依赖。

如果一个站点联系人失效,整个站点可能收不到新文档。

于是 RFC 10 才必须增加 ADDRESSES,并要求大家纠正过期信息。

这四个设计并不是独立知识点。

它们共同构成一套可以运行的协作系统:

1
2
3
4
5
6
7
8
9
10
11
12
13
低门槛产生内容

集中分配唯一 ID

加最小元数据

按站点扇出

站点本地复制

读者产生评论

形成下一篇带新编号的 RFC

关键机制与工作流程

RFC 10 没有网络报文,因此这里最值得“跑起来”的不是 Packet,而是它定义的 RFC 产生与传播流程

假设 RAND 的 John Haefner 发现当前 Host-Host Protocol 有一个问题:

两个 Host 同时建立连接时,现有规则是否会产生竞态?

他甚至还没有答案。

按照 RFC 10,这并不妨碍他发一份 NWG Note。

正常路径:一份 RFC 怎样进入工作组

第一步:作者形成一个尚未成熟的问题

此时作者掌握的是:

1
2
3
4
5
6
7
8
Problem:
可能存在竞态

Solution:
不知道

Evidence:
可能只有一次实验或一个推断

RFC 10 明确允许这种情况。

它没有要求:

1
2
3
必须先完成实现
必须有 benchmark
必须给最终算法

这一步的设计目标是:

1
让问题尽早进入共享认知。

第二步:文档获得 Serial Number

RFC 10 规定:

1
Serial numbers are assigned by Steve Crocker at UCLA

因此作者不能自己决定:

1
“我这篇叫 RFC 10。”

编号器维护全局序列。

Steve Crocker 在后来的 RFC 8700 回忆中补充说,他当时会等 Note 完成后才分配编号,以减少编号序列中的空洞。

这条“完成后再编号”是后来的历史回忆,不是 RFC 10 正文规则,因此需要和 RFC 10 本身区分开来。

第三步:加上最小元数据

RFC 10 要求每份 Note 至少带:

1
2
3
4
5
Network Working Group
Request for Comments: X
Author and affiliation
Date
Title

可以看成一个极简 Header:

1
2
3
4
5
6
7
8
9
10
11
12
+-----------------------------------+
| Series: Network Working Group |
| ID: Request for Comments: X |
| Author |
| Affiliation |
| Date |
| Title |
+-----------------------------------+
| |
| Body |
| |
+-----------------------------------+

这些字段各自解决不同问题:

字段 谁生成 谁使用 为什么需要
Network Working Group 文档作者 所有读者 表明所属文档系列
Request for Comments: X 编号负责人提供 X,作者写入 读者、后续 RFC 稳定唯一引用
Author 作者 读者 知道意见来源
Affiliation 作者 读者 知道其机构上下文
Date 作者 读者 判断时间顺序和历史语境
Title 作者 人类读者 快速识别主题,但不承担唯一身份

如果 Title 重复,没有问题。

如果 RFC Number 重复,就会破坏整个系列的引用能力。

所以:

1
RFC Number

才是这套系统最关键的标识字段。

第四步:作者站点向分发节点各发送一份副本

RFC 10 列出 9 个分发联系人。

作者不需要知道:

1
2
3
UCLA 到底有多少程序员
BBN 哪些人负责 IMP
SRI 哪些人关注 NLS

他只需要把文档送到站点入口。

sequenceDiagram
    participant A as RAND Author
    participant N as RFC Number Coordinator / UCLA
    participant U as UCLA Contact
    participant S as SRI Contact
    participant B as BBN Contact
    participant L as Local Readers

    A->>N: 获取 Serial Number
    N-->>A: RFC X
    A->>A: 写入 Author / Affiliation / Date / Title
    A->>U: One Copy
    A->>S: One Copy
    A->>B: One Copy
    U->>L: Local Reproduction

这里没有:

1
2
3
ACK
重传
Delivery Receipt

RFC 10 也没有定义文档可靠交付协议。

它依赖的是:

1
2
3
人工邮件 / 邮寄
固定联系人
社会协作

所以这是一个管理制度,不是可靠传输协议。

第五步:其他人产生新的 RFC,而不是覆盖旧文档

RFC 10 自己就是一个最好的例子:

1
2
3
4
5
6
RFC 3
没有被偷偷改写

而是:
RFC 10
明确写“这是 RFC 3 的 revision”

从系统设计角度,这相当于:

1
2
3
Immutable Historical Artifact
+
New Version as New Artifact

而不是:

1
2
documentation-conventions.txt
永远覆盖保存

后续也继续如此:

flowchart LR
    R3[RFC 3]
    R10[RFC 10]
    R16[RFC 16]
    R24[RFC 24]
    R27[RFC 27]
    R30[RFC 30]

    R3 -->|revision / obsolete| R10
    R10 --> R16
    R10 --> R24
    R16 --> R24
    R24 --> R27
    R10 --> R27
    R16 --> R27
    R27 --> R30
    R24 --> R30
    R10 --> R30
    R16 --> R30

这张图看起来比现代 SemVer 复杂,但它有一个非常有价值的性质:

历史不会因为规则改变而被静默覆盖。

Failure Path 1:两篇文档标题一样怎么办

RFC 10 已经明确允许:

1
Title need not be unique.

因此:

1
Documentation Conventions

可以同时对应多个 RFC。

定位完全依赖:

1
RFC Number

结果:

1
2
3
4
5
RFC 3: Documentation conventions
RFC 10: Documentation conventions
RFC 24: Documentation Conventions
RFC 27: Documentation Conventions
RFC 30: Documentation Conventions

都可以共存。

这就是为什么“标题”只应该用于人类理解,而不应该承担系统 Identity。

Failure Path 2:两个作者同时想要下一个编号怎么办

RFC 10 没有描述一个并发算法。

它直接通过组织设计消除问题:

1
只有一个编号负责人。

因此编号冲突被转化为:

1
serialization through one coordinator

代价也很明显:

1
2
3
Coordinator
=
Single Administrative Bottleneck

在几十篇 RFC、少量作者的规模下完全可接受。

如果这个系统一天产生几百万份文档,这种人工中心化方案当然无法扩展。

这就是典型的:

在当时规模下,选择最简单的足够方案,而不是提前构建全球分布式 ID 服务。

Failure Path 3:联系人地址过期怎么办

RFC 10 没有自动服务发现。

它的解决方法非常朴素:

1
2
3
公布当前已知地址
+
请参与者纠正

这本质上是:

1
Manually Maintained Directory

只要目录错误:

1
Document Routing

就可能失败。

RFC 16、24、27、30 后来持续修改分发名单,正说明这个状态是动态的。

Failure Path 4:一个粗糙想法被误认为正式标准怎么办

RFC 10 的主要防御不是加一个:

1
DRAFT=true

字段。

而是通过文化和命名降低误解:

1
Request for Comments

再明确声明:

1
2
3
不成熟的想法也允许
问题可以没有答案
最短只有一句话

这相当于告诉所有读者:

1
2
3
RFC Number

Approval

但这种机制依赖参与者理解共同文化。

随着规模扩大,它不够了。

所以现代 RFC 体系增加:

  • Internet-Draft 与 RFC 的明确区分;
  • Stream;
  • Status;
  • Working Group Review;
  • IETF / IESG Review;
  • RFC Production;
  • 明确的 Updates / Obsoletes 元数据。

也就是说,早期靠文化解决的问题,后来逐渐被制度和机器可读元数据解决。

重点概念与术语

Network Working Group

**Network Working Group(NWG,网络工作组)**在 RFC 10 中仍然是一个相当非正式的协作群体。

RFC 10 甚至仍然使用:

1
seems to consist of

这种非常松的表达。

它不是今天 IETF 中拥有 Charter、Chair、Milestone 和正式流程的 Working Group。

读到 Working Group 时不能把现代组织结构倒灌回 1969 年。

Request for Comments

**Request for Comments(请求评论)**在 RFC 10 的语境里是真的字面意思。

这些 Note 的目标首先是:

1
2
3
让别人看
让别人评论
让讨论继续

而不是:

1
保存一个已经完成的最终标准。

RFC 8700 后来明确回顾,最早的 RFC 目标是启动对话,而不是创建标准或最佳实践的永久档案。

NWG Note

RFC 10 中的 RFC 本质上仍然被描述为:

1
NWG Note

它可以是:

  • 哲学观点;
  • 实现技巧;
  • 明确问题;
  • 很短的意见。

所以不能把 NWG Note 直接等同于今天发布完成的 Standards Track RFC。

Serial Number

**Serial Number(连续编号)**是整个系列的稳定 Identity。

它解决:

1
2
3
4
标题重复
引用歧义
历史追踪
版本关系

RFC 10 中由 Steve Crocker / UCLA 分配。

Authoritative

RFC 10 中 **authoritative(权威性的)**是一个很核心的词。

作者担心:

1
Document exists

被误解成:

1
Document is official

所以 RFC 制度有意降低早期文档的权威外观。

Affiliation

作者不仅要写名字,还要写:

1
affiliation

因为当时协议设计高度依赖:

1
2
3
哪个站点
哪套 Host
哪个实现团队

这个上下文。

今天技术讨论中公司、项目或 Working Group 仍可能重要,但 RFC 作者身份模型已经不再等同于这份 1969 年站点名录。

Distribution

这里的 **Distribution(分发)**不是网络层 Multicast。

它指文档物理副本怎样传到各个研究站点。

Reproduction

**Reproduction(复制)**指各站点自己复制更多文档副本。

它让跨站点分发与站点内部分发解耦。

Legacy Stream

这是现代 RFC Editor 给早期文档使用的历史分类。

它提醒读者:

1
2
不要给 1969 年 RFC
强行套现代 IETF Standards Process。

Obsoletes / Updated by

这些是今天 RFC Editor 为历史文档整理出的演化关系。

对于 RFC 10:

1
2
3
Obsoletes RFC 3
Obsoleted by RFC 16
Updated by RFC 24 / 27 / 30

不要把它理解成现代软件包里干净的:

1
v1.0 → v1.1 → v2.0

早期 RFC 的修订关系更像一系列增量工作笔记。

需要特别注意的点

RFC 10 不是一篇新的协议规范,而是 RFC 3 的修订版

它最核心的内容哲学几乎没有改变。

真正的变化集中在:

1
2
3
4

编号负责人
分发点
地址

所以如果把 RFC 10 写成“RFC 文档格式包含四个字段”,就会错过它为什么需要存在。

它本质上是:

协作系统扩容后的运行配置更新。

SHOULD 不能套 RFC 2119 的现代规范性语义

RFC 10 写:

1
Every NWG note should bear...

但 RFC 2119 是 1997 年才发布的。

RFC 8174 又在 2017 年进一步说明规范性关键词的使用方式。

因此 RFC 10 的 should 只是当时普通英文语境下的规定性表达,不能机械解释成现代:

1
SHOULD = 有充分理由时才可违反

那种精确定义。

“任何人都可以写”不是“今天任何人都可以直接发布 RFC”

RFC 10 的:

1
any site by anybody

是在一个很小的 ARPANET 研究共同体中说的。

今天仍然可以开放参与 IETF,也可以公开提交 Internet-Draft,但正式 RFC 的产生流程已经不同。

RFC Editor 当前明确说明:

1
2
3
4
5
6
7
RFC 通常从 Internet-Draft 开始
→ 讨论
→ 评审
→ 修订
→ 批准
→ RFC Production
→ 分配 RFC Number

所以:

1
开放参与

并不等于:

1
任何上传的文本自动成为 RFC。

“Timely rather than polished”今天更像 Internet-Draft / Draft PR,而不是最终 RFC

Steve Crocker 在 RFC 8700 中明确指出,今天早期、未成熟想法通常通过:

1
2
Email / Mailing List
Internet-Draft

交流。

正式 RFC 则已经变成:

1
2
3
4
polished
reviewed
edited
approved

的出版物。

因此不能用 RFC 10 给今天的最终标准文档质量低下找借口。

RFC 16 “Obsoletes RFC 10”非常反直觉

RFC Editor 当前元数据明确:

1
2
RFC 16
Obsoletes RFC 10

但 RFC 16 正文只有一个非常具体的变化:

MIT 现在也应该接收所有 Network Working Group memos,并给出 Abhai Bhushan 的地址和电话。

从内容看,它更像:

1
Distribution List Update

而不是重新定义 RFC 10 的全部 Documentation Conventions。

这正说明早期 RFC 的 Obsoletes 关系不能完全按现代“大版本替换全部规范”理解。

后来的 RFC 24 又明确说:

1
This note is a revision of NWG/RFC 10 and 16.

把两者重新合并成一份完整规则。

“Updated by RFC 24、27、30”与“Obsoleted by RFC 16”同时存在,不是数据库错误就能简单解释掉

按现代线性版本思维,很容易觉得:

1
2
RFC 10 已经被 RFC 16 废弃
为什么 RFC 24、27、30 还会 Update RFC 10?

因为这些后续文档明确把多个旧 Note 一起列为修订基础。

RFC 27:

1
revision of NWG/RFC 10, 16, and 24

RFC 30:

1
revision of NWG/RFC 10, 16, 24, and 27

所以正确的历史理解不是:

1
每篇只继承上一版

而是:

1
2
新文档不断把多个相关旧规则
重新汇总、修订和发布。

RFC 10 没有定义共识机制

它告诉你:

1
2
3
谁能写
怎么编号
怎么发

却没有告诉你:

1
2
3
4
两篇冲突 RFC 谁赢?
什么时候算达成共识?
谁有否决权?
怎样批准?

这不是一个小缺口。

它说明 1969 年的 RFC 机制主要是:

1
Communication Infrastructure

还不是完整的:

1
Standards Governance Process

RFC 10 没有可靠交付协议

分发规则是:

1
send one copy

但没有:

  • ACK;
  • Delivery Receipt;
  • Retry;
  • Timeout;
  • Duplicate Detection。

如果某份纸质材料没送到,它没有协议层恢复机制。

这说明:

RFC 10 定义的是社会/组织流程,不是计算机可靠消息协议。

联系地址直接写进 RFC 今天已经明显过时

RFC 10 公开列出:

  • 个人办公地址;
  • 电话号码;
  • 分机。

这是当时分发系统必须依赖的数据。

今天这些信息大多由:

1
2
3
4
5
组织目录
邮件列表
Datatracker
账号系统
Web

维护。

把易变化的运行时通讯录直接固化进长期技术文档,会带来明显的陈旧问题。

RFC 16、24、27、30 不断改名单,已经证明了这一点。

RFC 10 没有现代安全和身份认证机制

如果从现代威胁模型看,会马上问:

1
2
3
4
谁能证明一份 RFC 真是某作者写的?
编号请求能否伪造?
分发副本能否被修改?
联系人目录能否被冒充?

RFC 10 没有数字签名、PKI 或身份验证机制。

不能据此批评 1969 年设计“没有安全意识”,因为它运行在规模很小、机构明确的研究共同体里。

但这确实属于:

1
Historical Trust Assumption

而不是今天可以原样复制的安全模型。

从今天的视角重新看这篇 RFC

今天仍然成立的设计思想

最值得保留的第一点,是:

早期讨论和最终标准应该是两个不同阶段。

RFC 10 通过降低 Note 门槛解决这个问题。

现代流程则通过:

1
2
Internet-Draft
→ Published RFC

把两个阶段显式分开。

第二点是:

稳定 Identity 比漂亮标题重要。

RFC Number 作为不可混淆的编号,直到今天仍然是整个 RFC Series 最核心的引用方式。

第三点是:

开放参与与受控命名空间可以同时存在。

任何人可以提出设计,不代表任何人可以随意制造一个已占用的 RFC Number。

第四点是:

历史版本不应被静默覆盖。

RFC 3 没有因为 RFC 10 出现就消失。

RFC 10 也没有因为 RFC 24 出现就被修改成另一份内容。

旧文档保留下来,新文档显式描述关系。

对于架构决策记录,这仍然是非常优秀的原则。

已经发生变化的部分

最大的变化是:

1
2
“RFC”本身从早期讨论载体
变成了成熟的正式出版物。

RFC 8700 对这个演化说得很清楚:

早期 RFC 的主要目标是:

1
start conversations

而不是:

1
create an archival record of a standard

今天,RFC Editor 明确说明 RFC 通常从 Internet-Draft 开始,经过不同 Stream 的讨论、评审和批准,再由 RFC Production Center 编辑并正式发布。

所以现代结构更像:

flowchart LR
    A[Idea]
    B[Mailing List / Discussion]
    C[Internet-Draft]
    D[Review / Revision]
    E[Stream Approval]
    F[RFC Production Center]
    G[RFC Number]
    H[Published RFC]

    A --> B --> C --> D --> E --> F --> G --> H

RFC 10 把:

1
early idea

和:

1
numbered RFC

放得很近。

今天它们已经被清楚拆开。

另一个变化是编号机制。

RFC 10:

1
Steve Crocker 人工分配 Serial Number

今天 RFC Number 是在文档被批准并进入正式出版流程后,由 RFC Production 体系分配。

再有就是分发。

RFC 10:

1
2
3
一份纸质/离线副本
→ 站点联系人
→ 本地复制

今天:

1
2
canonical online publication
→ 全球直接访问

分发问题已经从:

1
“怎样把副本送到每个站点”

变成:

1
2
3
4
长期存档
格式兼容
全球可访问
机器可读元数据

已经过时的历史设计

RFC 10 中最明显已经过时的是固定人名分发列表。

它把系统路由写成:

1
2
3
4
Steve
Ron
Elmer
...

这种模式规模一大就会出现:

1
2
3
4
人员流动
名单过期
中心联系人过载
组织结构变化

RFC 24 已经开始显示这个问题。

它不再像 RFC 10 那样用具体姓名定义 Network Working Group,而改成:

1
2
interested people from
existing or potential ARPA network sites

也就是说:

1
Member List

开始让位于:

1
Membership Rule

这是一种重要的扩展性改进。

固定电话和邮寄地址同样属于历史实现细节。

人工单点编号在当时规模足够简单,但今天如果用于互联网级文档生产也明显不可扩展。

最重要的过时点则是:

1
RFC Number 本身不表达成熟度。

今天已经通过更完整的文档生命周期和元数据解决这个问题。

现代工程中的对应物

现代软件组织里的内部 RFC Process,通常和 RFC 10 有非常强的结构相似性:

1
2
3
4
5
6
7
8
9
10
11
作者提交设计草案

获得稳定文档 ID

明确作者与时间

团队公开评论

形成后续 revision

旧决定保留历史

GitHub Issue / Pull Request 也有类似结构:

1
2
3
4
5
6
7
8
9
10
11
Title
可以重复

Issue Number
唯一

任何贡献者
可以发起

是否 Merge
由后续评审决定

Architecture Decision Record(ADR)也经常采用:

1
2
ADR-001
ADR-002

作为稳定 ID,并通过:

1
Superseded by ADR-xxx

保留历史演化。

这些现代实践并不一定直接“源自 RFC 10”。

更准确的说法是:

它们在解决同一类协作系统问题,因此自然出现了类似设计:开放产生内容、稳定标识、显式版本关系和可追踪历史。

这篇 RFC 带来的影响

RFC 10 最直接的影响不是某个网络协议字段,而是它本身形成了一条清晰的 Documentation Conventions 演化链

直接协议影响:RFC 文档规则持续扩容

从 RFC Editor 和后续原文可以得到这条链:

flowchart LR
    R3[RFC 3<br/>April 1969<br/>Initial Conventions]
    R10[RFC 10<br/>July 1969<br/>Revision]
    R16[RFC 16<br/>Aug 1969<br/>MIT Added]
    R24[RFC 24<br/>Nov 1969<br/>Consolidated Revision]
    R27[RFC 27<br/>Dec 1969<br/>Distribution Update]
    R30[RFC 30<br/>Feb 1970<br/>Further Expansion]

    R3 --> R10
    R10 --> R16
    R10 --> R24
    R16 --> R24
    R24 --> R27
    R10 --> R27
    R16 --> R27
    R27 --> R30

RFC 10 相比 RFC 3:

1
2
3
4
5
6
7
8
9
10
分发点:
6 → 9

Serial Number 分配:
Bill Duvall / SRI

Steve Crocker / UCLA

增加:
完整地址簿

RFC 16 又加入:

1
MIT / Abhai Bhushan

作为 NWG Memo 接收点。

RFC 24 把参与者定义从具体姓名升级为:

1
2
interested people from
existing or potential ARPA network sites

并把分发名单扩展到:

1
11 个入口

RFC 27 进一步增加到:

1
12 个

RFC 30 则达到:

1
14 个

其中已经出现:

  • Carnegie-Mellon;
  • Raytheon;
  • Stanford;

等更多机构。

这个增长链非常具体地说明:

Documentation Conventions 并不是一次写完的“格式规范”,而是在随着网络社区扩张持续调整自己的分发拓扑。

直接影响:稳定编号最终成为整个 RFC Series 的核心引用机制

RFC 10 没有发明 RFC Number——RFC 3 已经规定了 Serial Number。

但 RFC 10 继续确认并运行了这个机制。

后来无论 RFC 制度怎样变化:

1
2
3
4
RFC 793
RFC 2616
RFC 8446
RFC 9110

稳定编号始终是核心引用方式。

今天 RFC 的标题可能:

  • 被复用;
  • 被修改;
  • 非常长;
  • 在不同文档中相似。

但:

1
RFC 9110

永远准确指向一个确定的历史出版物。

这就是一个非常成功的 Identity Design。

思想影响:开放性留下来了,但“低门槛”迁移到了 Draft 阶段

RFC 8700 对五十年演化的回顾非常重要。

它明确指出:

早期 RFC:

1
真正是 requests for comments

目标是:

1
start conversations

今天 RFC:

1
2
3
4
fully polished
reviewed
edited
approved

而那些尚未成熟的技术想法,则更多通过:

1
2
Internet-Drafts
Mailing Lists

流动。

也就是说,RFC 10 的核心思想没有完全消失,而是发生了分层迁移

1
2
3
4
5
6
1969:
RFC = Draft + Discussion + Numbered Note

今天:
Internet-Draft = Early Discussion
RFC = Approved Archival Publication

这是一个很重要的制度演化。

它没有否定 RFC 10 的:

1
timely rather than polished

而是把它放到了更合适的生命周期阶段。

思想影响:开放参与从“小组文化”变成正式流程原则

RFC 10 写:

1
Membership is not closed.

今天 RFC Editor 对 IETF 流程的说明仍然强调:

1
free and open to participation

不要求参与者必须属于某家公司或机构。

当然,中间经过了几十年的组织和流程演化,不能把今天 IETF 的开放治理简单说成“RFC 10 直接定义的”。

但可以可靠地说:

早期 NWG 就已经把非封闭参与作为明确规则,而开放参与后来一直是互联网标准协作文化的重要组成部分。

思想影响:技术文档开始成为工程过程本身,而不是项目结束后的说明书

RFC 10 的世界里:

1
2
3
4
5
Idea
→ Write Note
→ Distribute
→ Discuss
→ New Note

文档不是:

1
2
工程完成后
补一份说明书

而是:

1
工程设计过程中的活动对象。

这和今天:

  • Design RFC;
  • ADR;
  • Proposal;
  • Internet-Draft;
  • Pull Request Review;

有非常强的共通结构。

更重要的是,这种做法留下了完整的“失败设计”历史。

如果早期工程师只保存最终 NCP 或 TCP/IP,我们今天就无法看到:

1
2
3
哪些假设曾经被认真提出
哪些规则后来扩展失败
协议为什么被重构

RFC 10 本身就是一个很好的例子:

它不是一份今天仍有效的规则,却精确记录了:

1969 年 7 月,一个快速扩张的技术共同体是怎样管理自己的知识流动的。

总结

RFC 10 当时真正解决的,不是“Markdown 应该怎么写”这种格式问题。

它面对的是一个更基础的协作系统问题:

当网络协议不再由同一个房间里的几个人讨论,而开始跨多个站点、多个机构并行推进时,怎样让不成熟的技术意见仍然能够快速进入讨论,同时又保证它们可识别、可引用、可分发?

它给出的答案非常简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
内容生产保持开放

不要要求想法先变得完美

用 Serial Number 建立稳定 Identity

作者、机构、日期、标题形成最小元数据

由一个中心协调全局编号

作者向各站点入口各发送一份

站点内部自行复制

地址发生变化就继续修订分发规则

RFC 10 最关键的设计思想不是“所有 RFC 都应该粗糙”。

而是:

早期技术讨论必须有足够低的进入成本,但低门槛不能以失去身份、引用和传播能力为代价。

这也是它最聪明的地方。

它同时选择了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
开放作者
+
集中编号

非正式内容
+
正式身份

标题可重复
+
编号必须唯一

跨站点单副本
+
站点内本地复制

历史文档保留
+
新 RFC 显式修订

这些组合让一个很松散的研究群体拥有了一套最低限度、但真正可以运行的协作协议。

当然,RFC 10 本身也暴露了时代限制。

它依赖:

1
2
3
4
5
固定联系人
纸质/人工分发
电话和邮寄地址
人工编号
小型信任共同体

规模一扩大,名单就不断过期,于是很快出现:

1
2
3
4
RFC 16
RFC 24
RFC 27
RFC 30

持续更新分发系统。

后来更大的变化则是:

1
早期讨论

与:

1
正式 RFC 出版

被拆成两个不同阶段。

今天的设计逻辑已经演化为:

1
2
3
4
5
6
7
8
9
10
11
12
13
技术问题

开放讨论

Internet-Draft

评审与修订

批准

RFC Number

永久出版与归档

但如果把这些现代组织和工具全部拿掉,底层逻辑仍然和 RFC 10 非常接近:

1
2
3
4
5
6
7
8
9
10
11
12
13
问题

让想法尽早公开

给它稳定身份

让相关人都能拿到

允许别人反驳和修订

保留历史

让下一版明确说明自己改变了什么

今天的软件工程师仍然值得读 RFC 10,原因并不是它能教你写现代 RFC。

而是它展示了一个非常容易被忽略的事实:

大型技术系统不仅需要机器之间的协议,也需要设计这些机器协议的人之间有一套协议。

RFC 10 写的,正是后者。


RFC 10:Documentation Conventions——当技术讨论开始扩容,RFC 如何成为一套可运行的协作协议
https://allendericdalexander.github.io/2026/08/24/rfc/rfc00010-documentation-conventions/
作者
AtLuoFu
发布于
2026年8月24日
许可协议