关于 dev-rfc
面向工程师的文档撰写技能,可用于编写 RFC、架构文档和简短提案。它帮助选择文档结构、梳理项目背景、公平比较方案,并可通过浏览器收集审阅意见。
主要功能
- 01RFC、架构文档与简短提案模板
- 02文档模式选择指引
- 03项目背景梳理清单
- 04图示与设计章节编写指引
- 05可选的浏览器审阅流程
适用场景
- 01在构建系统前协调利益相关者
- 02为新贡献者记录现有系统
- 03用改造前后设计提议系统变更
- 04为小型变更撰写简短提案
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill dev-rfc安装后在 Claude Code 中输入/dev-rfc确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
bun.lockmetadata.jsonpackage.jsonassets/marked.min.jsreview_template.htmlreferences/template.mdscripts/generate_review.pygenerate_review.test.tsgenerate_review.ts详细介绍
Dev RFC 技能
撰写 RFC 和技术提案,实现两个目的:就要构建什么以及为什么达成利益相关者共识(RFC),以及帮助工程师了解系统的工作原理(架构文档)。大多数实际提案会兼顾这两者——此技能可帮助你根据具体情况选择合适的章节。
参考模板
阅读 references/template.md,了解三种结构模板:
- RFC — 用于构建前的共识。侧重摘要、方案(公平比较)、服务 SLA、可观测性和发布计划。
- 架构文档 — 用于记录已构建的系统。侧重图表、源码树、数据流和设计理念。
- 单页文档 — 用于小型更改(少于 1 周)。包含问题、建议的解决方案和发布计划,约 20 行。
步骤 0:选择模式
询问用户(或根据上下文推断)他们属于哪种情况:
| 情况 | 模式 | 文档要回答的关键问题 |
|---|---|---|
| 规划新系统或重大更改 | RFC | “我们应该构建这个系统吗?该如何构建?” |
| 记录现有系统 | 架构文档 | “这个系统如何运作?” |
| 提议更改现有系统 | RFC(在详细设计中加入更改前后的图表) | “我们为什么要更改?更改后的系统会是什么样?” |
| 范围较小的更改(少于 1 周) | 单页文档 | “简要说明要做什么以及为什么?” |
对于现有系统的更改,以 RFC 结构为主干,但要在详细设计章节中加入更改前后的架构图,并在组件上标注 [NEW] 和 [CHANGED]。
文件位置
- 正式提案或 RFC — 主要存放于
docs/rfcs/RFC-NNN-title.md - 整个项目的架构文档 — 仓库根目录下的
ARCHITECTURE.md - 子系统文档 —
docs/design/subsystem-name.md,或放在其所描述的代码旁
如果用户未指定文档的存放位置,请询问。
步骤 1:了解项目
在开始撰写之前,先建立对项目的整体认知。
对于 RFC:
- 与用户明确问题陈述和约束
- 了解利益相关者和审批者
- 询问此方案会与哪些现有系统交互或替换哪些系统
- 确认硬性约束(时间线、预算、兼容性、合规性)
- 询问已考虑或否决过哪些替代方案
对于架构文档:
- 阅读项目的 README、CLAUDE.md 和所有现有文档
- 浏览源码树,识别主要子系统及其边界
- 梳理从输入到输出的主要数据流
- 查看模块间传递的关键类型和接口
- 检查 git 历史,了解架构决策的背景
步骤 2:起草文档
遵循 references/template.md 中适用的结构。应包含哪些章节取决于模式和项目复杂度——模板提供了针对小型、中型和大型项目的扩展指导。
各模式中最重要的章节:
RFC — 审批者最关心的章节:
- 摘要 — 3–5 句的执行摘要。读者应仅凭这部分就能决定是否阅读完整 RFC。
- 方案 — 公平比较所有经过评估的选项。这是 RFC 与规范文档的区别所在。
- 服务 SLA 与可观测性 — 生产就绪性。表明提案考虑了系统在生产环境中的运行方式和监控方式。
架构文档 — 新贡献者最关心的章节:
- 高层架构(附图表)— 一目了然地了解系统。
- 源码树 — “在哪里能找到 X”的索引。
- 关键设计决策 — 解答“为什么要这样设计”。
第 3 步:编写有效内容
并非所有系统都是流水线。 选择与系统相符的图示类型:
- 流水线 — 编译器、数据流水线、ETL。各阶段线性排列,数据依次流经。
- 请求流 — 服务、API。展示请求经过中间件、处理程序和依赖项的路径。
- 事件流 — 事件驱动系统。展示生产者、队列/主题和消费者。
- 分层图 — Web 应用、CRUD。UI → API → 服务 → 数据层。
图示是文档的核心。读者应仅凭图示就能理解系统的整体流程。使用 ASCII 方框图。为各阶段标注模块路径和说明。展示各阶段之间的数据格式。
具体描述,不要抽象概述。 不要写“模块 A 处理输入并传给模块 B”,而要写:“Preprocessor::preprocess() 输出 String(包含行标记的扩展文本),Lexer::tokenize() 接收该结果并生成 Vec<Token>。”对于提案,请使用拟定的类型/接口名称。
方案应提供真正的备选选项,并公平呈现优缺点。 不要贬低其他选项来衬托推荐方案。每个方案都有值得认可的优势。即使审阅者不同意你的建议,也应觉得自己偏好的选项得到了诚实呈现。
目标和非目标应具体且可证伪。 例如(针对“将身份验证迁移到 OAuth2”):
目标:
- 在第三季度末前,所有面向用户的登录流程都使用 OAuth2 授权码流程
- 上线时支持 Google 和 GitHub 作为身份提供商
- 会话令牌存储符合 SOC 2 要求(静态加密,最长有效期为 24h)
非目标:
- 不迁移服务间身份验证(目前继续使用 mTLS)
- 不构建自定义身份提供商——我们将使用 Auth0
- 不支持 SAML(企业 SSO 是单独的第四季度项目)
服务 SLA 应具体明确。 不要说“高可用性”,而要写“正常运行时间为 99.95%”。不要说“低延迟”,而要写“P99 低于 300ms”。说明每个目标的理由。
将决策与理念分开。 关键设计决策是事实性的选择(“我们使用 SSA 形式”)。设计理念则是指导持续决策的原则(“通过表示形式实现关注点分离”)。
第 4 步:审阅清单
RFC:
- 摘要是否足够清晰,让读者能判断是否要阅读完整 RFC?
- 方案部分是否诚实地呈现所有选项及其真实优缺点?
- 推荐方案是否有充分依据——是否说明了需要舍弃什么?
- 服务 SLA 是否具体,包含明确数字,而非含糊表述(“高可用性”)?
- 目标和非目标是否足够具体,便于据此评估提案?
- 是否有包含决策标准的具体回滚计划?
- 是否明确标出需要审批者提供意见的待解决问题?
架构文档:
- 不熟悉该项目的人能否仅凭图示理解流程?
- 数据流中的具体类型和方法名称是否准确?
- 关键设计决策是否涵盖新贡献者最先需要了解的内容?
- 是否包含指向其他文档(README、各模块文档)的交叉引用?
第 5 步:收集反馈并迭代(可选)
编写 RFC 后,主动提出在用户的浏览器中打开审阅 UI。该审阅 UI 会运行一个本地服务,自动保存反馈,支持多轮修订,并允许用户明确批准文档。
路径解析: 在以下命令中,
$SKILL_PATH指向此 SKILL.md 文件的绝对路径。将其解析为包含此文件的目录(例如,如果 SKILL.md 位于/path/to/dev-rfc/SKILL.md,则$(dirname "$SKILL_PATH")为/path/to/dev-rfc)。需要 Bun(或搭配--experimental-strip-types的 Node 22+)。
第一轮
- 将 RFC 保存到目标文件路径。
- 启动评审服务:
这会在bun run "$(dirname "$SKILL_PATH")/scripts/generate_review.ts" <doc-path> --title "<project name>"localhost:3118上启动 HTTP 服务并打开浏览器。用户输入的反馈会自动保存到<doc-dir>/.rfc-review/feedback.json(防抖时间为 800ms)。每次刷新时,服务也会提供最新版本的 Markdown。 - 告诉用户:“我已在浏览器中打开 RFC 评审页面:http://localhost:3118。你可以为任意章节添加反馈,也可以选中文本添加行内评论,然后点击 Submit Feedback(需要修改时)或 Approve(内容没问题时)。反馈会在你输入时自动保存。”
- 用户表示评审完成后,从工作区读取反馈:
cat <doc-dir>/.rfc-review/feedback.json
检查状态
"status": "approved"— 用户已批准 RFC。停止迭代,并告知用户 RFC 已定稿。"status": "needs_revision"— 用户希望修改。开始修订。"status": "draft"— 用户在评审过程中关闭了浏览器。询问用户是想继续评审,还是当前的草稿反馈已足够。
修订指南
修订时,按以下顺序处理反馈(从具体到一般):
- 行内评论(
inline_comments)— 针对特定文本。逐条处理。 - 章节反馈(
sections[].feedback)— 针对各章节的意见。修订相关章节。 - 总体反馈(
overall_feedback)— 整体意见。应用到全文。
章节的反馈为空表示没有问题,可跳过。没有收到反馈的部分不要修改。
后续轮次
修订 RFC 后,开始下一轮评审,并将上一轮的反馈作为只读上下文展示:
bun run "$(dirname "$SKILL_PATH")/scripts/generate_review.ts" <doc-path> --title "<project name>" \
--previous-feedback <doc-dir>/.rfc-review/feedback-history/feedback-round-N.json \
--iteration N+1
服务启动时会自动将上一轮的 feedback.json 归档到 feedback-history/feedback-round-N.json。评审者会在每个章节上方看到其上一轮反馈(只读),以便确认相关问题已得到解决。
重复执行“检查状态 → 修订 → 重新启动”的循环,直到用户批准或选择退出。
结束条件
出现以下任一情况时停止迭代:
- 用户在 UI 中点击 Approve(
"status": "approved") - 用户表示“看起来不错”“可以发布了”“完成了”或类似表述
- 用户明确表示不想再进行更多轮次
静态备用方案
如果服务无法启动(端口冲突、环境问题),则改用静态模式:
bun run "$(dirname "$SKILL_PATH")/scripts/generate_review.ts" <doc-path> --title "<project name>" --static
这会打开一个独立的 HTML 文件。提交时,反馈会以 feedback.json 的形式下载到 ~/Downloads。询问用户文件保存到了哪里。
如果用户希望直接撰写文档而不进行评审,或文档只有一页,则完全跳过此步骤。
步骤 5b:实时撰写模式(可选)
无需先写完整份 RFC 再进行评审,可以使用实时撰写模式:先打开 UI,显示所有计划章节的框架;逐个撰写章节,每个章节会实时显示在浏览器中;用户对每个章节提供反馈后,再撰写下一章节。
何时使用实时模式
- 用户希望在撰写 RFC 的过程中进行协作
- RFC 内容复杂,适合逐个章节反复确认
- 用户明确要求使用“实时”“交互式”或“逐步”模式
启动实时服务
- 根据模板和项目范围,规划 RFC 的章节标题。
- 以实时模式启动服务:
这会打开浏览器,显示包含所有计划章节的框架,每个章节均以待处理卡片呈现。bun run "$(dirname "$SKILL_PATH")/scripts/generate_review.ts" --live --title "<project name>" \ --sections '["Abstract","Motivation","Goals and Non-Goals","Detailed Design","Approaches","Service SLAs","Rollout Plan"]' - 告诉用户:“我已在浏览器中以实时撰写模式打开 RFC:http://localhost:3118。我会逐个撰写章节;在我撰写下一章节之前,你可以批准当前章节或要求修改。”
按章节划分的协议
按顺序处理每个章节:
- 以 Markdown 格式编写章节内容。
- 将其推送到服务端:
该章节会通过 SSE 立即显示在浏览器中。curl -s -X POST http://localhost:3118/api/section/add \ -H 'Content-Type: application/json' \ -d '{"id": "abstract", "heading": "Abstract", "markdown": "## Abstract\n\nYour content here..."}' - 等待用户反馈:
此操作会一直阻塞,直到用户在浏览器中点击“Approve”或“Request Changes”(超时为 5 分钟)。curl -s http://localhost:3118/api/wait-feedback?section=abstract - 处理响应:
{"action": "approve"}— 转到下一章节。{"action": "request_changes", "text": "..."}— 阅读反馈,修改章节,然后推送更新:
然后再次调用curl -s -X POST http://localhost:3118/api/section/update \ -H 'Content-Type: application/json' \ -d '{"id": "abstract", "markdown": "## Abstract\n\nRevised content..."}'/api/wait-feedback?section=abstract。{"timeout": true}— 用户在 5 分钟内未响应。通过 CLI 提示用户或重试。
完成
所有章节获批后,将所有已批准的章节组装成完整的 Markdown,并写入目标文件路径。所有章节获批后,用户也可以在浏览器中点击“Finalize RFC”。
后备方案
如果实时模式遇到问题,则回退到批处理模式(步骤 5):先写入完整的 RFC,再打开标准审核界面。
语气和风格
- 架构文档使用现在时和陈述语气。仅提案使用将来时。
- 简洁——每个词都应发挥作用
- 优先展示(图表、代码、类型签名),而不是叙述
- 段落简短——这是参考资料,不是散文
- Markdown 格式:用粗体强调,用代码块表示类型和路径,用表格进行比较
文档规模
| 变更规模 | 格式 | 章节 |
|---|---|---|
| 小(< 1 周,单个组件) | 单页文档 | 问题、拟议解决方案、推出计划 |
| 中(1-4 周,多个组件) | 标准 RFC | 完整 RFC 或架构文档 |
| 大(> 1 个月,跨团队) | 完整 RFC + 子文档 | 顶层文档 + 指向子系统子文档的链接 |
审核工作流指南
在元数据标题中注明状态:
- 草稿 — 作者仍在撰写。尚未准备好正式审核。
- 审核中 — 已分享给审批人。请注明需要哪些反馈。
- 已批准 — 审批人已签字认可。作为正式计划。
- 已取代 — 更新的 RFC 已取代此 RFC。请链接到替代文档。
- 已弃用 — 系统已不存在,或提案已放弃。