31 lines
4.6 KiB
Markdown
31 lines
4.6 KiB
Markdown
|
|
# RFC:为 RFC 统一一种有门禁保障的文件内格式
|
|||
|
|
|
|||
|
|
Status: implemented
|
|||
|
|
|
|||
|
|
[English](2026-07-05-uniform-rfc-format.md) | 中文
|
|||
|
|
|
|||
|
|
## 问题
|
|||
|
|
|
|||
|
|
RFC 的路径已编码了生命周期与分类,但文件内容仍然混杂着不同的标题风格、状态格式、ADR 模板与提案模板,以及已实施记录中残留的提案时期章节。作者复制手边找到的任何邻居文件作为模板,而生命周期迁移可以跳过必要的改写,因为没有门禁强制执行文件内契约。
|
|||
|
|
|
|||
|
|
## 决策
|
|||
|
|
|
|||
|
|
[README.md § The file format](../../README.md#the-file-format) 即为文件内契约:头部块(`# RFC: <title>` 加上不含日期、与所在文件夹一致的 `Status:` 枚举,其唯一内容是否决原因);按生命周期区分的正文骨架(所有阶段都以 `Problem` 开头;`proposed/` 中使用 `Proposal`/`Acceptance criteria`/`Risks`;`implemented/` 中使用现在时的 `Decision`/`Consequences` 且禁止提案时期标题;`rejected/` 中冻结提案形态);强制的 `Alternatives considered` 章节;以及规范的章节词汇表——在这些固定章节之间,自定义的技术章节保持自由格式。`pnpm run verify-rfc-format`([scripts/verify-rfc-format.ts](../../../../scripts/verify-rfc-format.ts))作为 doc-sync(文档同步门禁)的一环强制执行每一条机械化条款,因此跳过改写的生命周期迁移现在会导致 CI 失败,而非依赖评审者的记忆。
|
|||
|
|
|
|||
|
|
整个语料库在定义格式的同一个变更中完成了规范化——这是预发布阶段的立场:不设过渡期,不容忍双格式并存。唯一的祖父条款针对内容而非格式:替代方案只记录已有的,不凭空编造;因此如果一篇格式定义之前的 RFC 的替代方案无法从记录中重建,它会携带 `rfc-format: alternatives-not-recorded` 注释,门禁仅对日期早于本 RFC 的文件接受该注释。
|
|||
|
|
|
|||
|
|
## 曾考虑的替代方案
|
|||
|
|
|
|||
|
|
- **完全刚性模板**(每个生命周期一套固定章节顺序,所有 RFC 重构以适配):否决。大型设计 RFC 携带八到十五个自定义技术章节(包拓扑、协议格式契约、schema),这些是承重内容而非漂移;刚性顺序会迫使当下进行破坏性改写,并永远与模板对抗。
|
|||
|
|
- **仅规范化头部**(H1 与 Status,正文不动):否决。技术债标记指出的正是*正文*的体裁分裂,让 `Context`/`Decision` 与 `Problem`/`Proposal` 无限期并存什么也解决不了。
|
|||
|
|
- **不设 Status 行**(文件夹本身就是状态;三篇最新的格式定义前 RFC(及其中一篇的中文对侧文件)省略了该行):否决,保留自描述文件。当初促使去掉该行的漂移风险,已被「门禁将该行与文件夹做一致性校验」所消除。
|
|||
|
|
- **带日期的状态**(`Status: implemented (accepted YYYY-MM-DD)`):否决。接受日期属于叙述性历史,写作规则将其排除在文档之外;文件名承载首次提出日期,git 承载其余信息,门禁能检查日期格式但永远无法检查其真实性。
|
|||
|
|
- **裸 `# <title>` H1**:否决。`RFC: ` 前缀是语料库中的多数形式,且在文件脱离目录树阅读时能自描述体裁;索引生成器会剥离它,因此索引行无论哪种写法都一样。
|
|||
|
|
- **`## What we give up` 作为已实施记录的收尾章节**(README 自身用来描述 RFC 所记录内容的措辞):否决。它只命名了代价,而诚实的后果章节同时记录权衡所换来的收益。
|
|||
|
|
- **约定而无门禁**(写下契约,靠评审强制执行):否决。slop checklist 已通过约定禁止在 `implemented/` 中使用规范体措辞,而十九个文件展示了纯靠约定在这里能达到什么效果。
|
|||
|
|
- **独立的 `FORMAT.md` 契约文件**:最初落在此处;在生成索引迁出至 [INDEX.md](../../INDEX.md) 后折入 README.md:表格移走后 README 重新有了空间,一个前门同时承载布局、分类与格式,优于将契约拆分到两个文件。
|
|||
|
|
|
|||
|
|
## 后果
|
|||
|
|
|
|||
|
|
每篇 RFC 现在多了少许结构成本,而强制的 `Alternatives considered` 章节是有意为之的摩擦:一个不记录被否决方案的决策,会招来 RFC 本应防止的反复讨论。格式定义前的 RFC 若其替代方案无法重建,则永久携带祖父条款注释——这是记录上的诚实空白,而非编造的理由。doc-sync 新增一道门禁,在生命周期文件夹之间迁移 RFC 现在是迁移时的实际工作(即迁移本就欠下的正文改写),而非无人追踪的延后清理。三十九个技术债标记已全部消除,由它们等待的模板所解决。
|