跳至主要内容

RFC 撰寫指南

RFC(Request for Comments)是對 AppFuse 框架 API 或行為的變更提案。 本指南定義 RFC 的生命週期、品質標準、檔案格式,為 docs-web/rfcs/docs-server/rfcs/ 的具體 RFC 提供單一事實來源。

定位:本頁是規範(methodology),具體 RFC 實例放在 docs-web/rfcs/docs-server/rfcs/(web / server 框架範疇決定)。


RFC 與 ADR 的區別

RFCADR
時機變更發生前決策達成後
目的提案、徵求意見、審議記錄已定案的架構決策
作者任何團隊(含外部應用團隊)框架維護者
生命週期proposed → accepted/rejectedaccepted(預設)
被拒絕的版本保留(含理由)不存在
編號日期式(YYYY-MM-DD-slug流水號(NNN-slug

一個 RFC 被接受後,大部分情況不會產生對應 ADR——RFC 本身已是完整歷史紀錄。 僅當接受的變更涉及「重大架構決策」時才衍生 ADR(例:變更了整體分層、引入新機制)。 此時在 RFC 的 related_adr frontmatter 欄位指向對應 ADR。


何時使用 RFC

情境需要 RFC說明
新增框架層的 API(元件 prop、公開函式、API 端點)跨應用共用的介面變更
既有框架 API 的破壞性變更影響所有消費端
既有框架 API 的非破壞性增強視情況小幅增強可直接 PR;影響多模組才需 RFC
框架內部重構(不影響公開 API)直接 PR,必要時寫 ADR
Bug 修正直接 PR
應用專案自身的需求變更/us 變更流程處理

判斷原則:變更是否會影響多個應用團隊、且不能用單純的 PR 描述承載論述,就寫 RFC。


生命週期

draft(應用端,尚未提交)
↓ /rfc submit(脫敏 + 打包)
proposed(已提交到 appfuse-docs)
↓ 框架維護者審議
├─→ accepted → implemented(實作並發佈後)
├─→ rejected (保留紀錄,含拒絕理由)
├─→ deferred (保留紀錄,含重新評估條件)
└─→ superseded (被新 RFC 取代)
狀態意義寫入時機
draft應用端撰寫中,未提交/rfc draft 產出
proposed已提交框架端,待審議/rfc submit 脫敏後產出;/rfc-intake intake 入站
accepted框架維護者接受,待實作/rfc-intake decide 標記為接受
rejected框架維護者拒絕/rfc-intake decide 標記為拒絕,必填理由
deferred暫緩,未來重新評估/rfc-intake decide 標記為延後,必填重新評估條件
implemented已實作並發佈實作完成後手動或工具更新
superseded被新 RFC 取代新 RFC 提出時連動更新,frontmatter superseded_by 指向新 RFC

Frontmatter 規範

每份 RFC 都必須包含以下 frontmatter:

---
sidebar_position: 1 # Docusaurus 用

# 識別
id: 2026-04-24-media-input-mark-index
title: {標題}
scope: web # web | server(決定 intake 目的地)
component: lib/components/data-input/media-input # 可選,影響的元件/模組路徑

# 生命週期
status: proposed # proposed | accepted | rejected | deferred | implemented | superseded
created: 2026-04-24

# 決策(accepted/rejected/deferred 時填)
decided_at: # YYYY-MM-DD
decided_by: # 決策者標識
target_version: # accepted 專用,預計納入版本
superseded_by: # superseded 專用,指向新 RFC id

# 關聯
related_adr: [] # 對應 ADR 路徑(若有)
related_rfcs: [] # 相關 RFC id
depends_on: [] # 依照 m-depends-on 規範

# 來源(脫敏後僅保留類別,不含客戶/專案名)
origin:
project_type: {類別} # 如 ecommerce、pos、erp
submitted_at: 2026-04-24

# 僅應用端版本使用,指向框架端已發佈的 URL
# upstream: https://appfuse.leandev.io/web/rfcs/2026-04-24-media-input-mark-index
---

7 維度品質檢核

RFC 必須通過以下 7 維度檢核才可提交。每個維度有三種狀態:Clear(充分論述)、Partial(有提及但不完整)、Missing(完全未提及)。

#維度Clear 的條件
1動機明確有具體 use case(非空想)、描述現況痛點、可感受的好處
2現況分析說明目前如何繞道(hack)、列出現有限制、提供舉證(程式片段 / 錯誤訊息 / 行為描述)
3API 設計提供 TypeScript / Java 型別定義、預設值、命名論證、與既有 API 風格的對齊
4相容性明確標示 breaking / non-breaking、列出受影響的消費端情境、提供遷移路徑
5替代方案列出至少一個替代方案 + 選擇理由
6範圍界定明確「out of scope」區段,避免範圍蔓延
7測試/驗證提出測試策略(unit / visual / accessibility 視情況)

提交門檻

  • 所有 7 維度至少 Partial
  • 關鍵 3 維度必須 Clear:動機明確(#1)、API 設計(#3)、相容性(#4)

未達標者,/rfc checklist 會列出需要補強的項目;/rfc submit 在未達標時拒絕打包。

把關界線

由 AI 把關由框架維護者把關
論述完整性(7 維度是否寫了)價值判斷(API 設計好不好、要不要接受)

AI 替框架維護者決定接受/拒絕——那是框架維護者在 /rfc-intake decide 時的工作。

嚴格模式(多 AI 檢核)

單一 AI 跑 7 維度檢核可能評估過寬(這在實踐中已驗證——某 AI 評全 Clear,但 3 個 AI 並行重審後修正為部分 Partial)。對於設計取捨複雜的 RFC,建議啟動嚴格模式:

階段啟動方式適用
應用端撰寫/rfc checklist {rfcId} --strict提案者自我把關前的最後一道
框架端決策/rfc-intake decide {rfcId} 的 Step 4.3多候選方案、破壞性變更、跨多元件的 RFC

嚴格模式會並行啟動 claude / codex / gemini 三個 AI,跑同一份檢核或審議,主 session AI 對各方意見做 defense(對每個 AI 意見表態),最終由人綜合判斷。實作細節見 /rfc/rfc-intake skill 文件。

何時應該嚴格

  • RFC 列出多個候選方案(A/B/C...)且論述偏向某一案
  • 提案是破壞性變更(影響既有消費端)
  • 跨多個框架元件 / 模組
  • 提案者自承「未來可能演進為 X」之類的字眼(暗示 API 邊界未拍板)

Decision Log 規範

每份 RFC 末尾必須有 ## Decision Log 區段,按時間倒序(最新在上)記錄所有狀態轉換。

## Decision Log

### {YYYY-MM-DD} — Accepted
- **決策者**: {identifier}
- **理由**: {為何接受的簡要說明}
- **實作**: 預計納入 {framework}@{version}
- **相關 ADR**: {若有,列出 ADR 檔案路徑;否則填「無」}

### {YYYY-MM-DD} — Under Review
- {審議過程中的關鍵討論紀錄,可多條}

### {YYYY-MM-DD} — Proposed
- **提案者**: {脫敏後的來源識別,如「ecommerce 專案團隊」}
- **來源**: {project_type}

各狀態必填資訊

狀態必填欄位
Proposed提案者、來源
Accepted決策者、理由、target_version、相關 ADR(無則填「無」)
Rejected決策者、拒絕理由、替代建議(指向現有 API 或其他 RFC)
Deferred決策者、延後理由、重新評估條件(例:「等 Design Token 系統落地後重新評估」)
Superseded決策者、取代理由、新 RFC id

多 AI 審議結論的記錄

若決策過程啟動了嚴格模式(見「7 維度品質檢核 / 嚴格模式」),Decision Log 應記錄結論與投票分布,不必詳列各 AI 的完整意見:

### YYYY-MM-DD — Deferred

- **決策者**: {identifier}
- **三 AI 審議結論**:
- Gemini:建議 A 微調
- Codex:建議 C(render prop / slot),堅持 A/B 則 reject
- Claude sub-agent:建議 C + A 便利糖
- **投票 2:1 傾向 C**
- **延後理由**: ...
- **重新評估條件**: ...

完整子 AI 意見保留在 skill 執行時的 console 輸出(不版控進 git)。Decision Log 的價值在於「為何決策」,不是「過程記錄」。


脫敏原則

應用團隊提交 RFC 時,原始版留在應用端 repo{app-docs}/docs/rfcs/),脫敏版提交到框架端docs-web/rfcs/docs-server/rfcs/)。

必須脫敏的內容

類別範例脫敏後
客戶 / 專案名florist-flora花店ecommerce 專案商品管理
內部人名、email、帳號jason@example.com移除或泛化為「團隊」
商業數字具體單價、折扣率、營收用示意值或抽象描述
私有 API endpoint/api/internal/foo移除或泛化
業務流程細節特定商業邏輯抽象為通用模式或移除

可保留的內容

  • 框架範疇內的 prop / API 設計
  • 公開文檔中已有的 API / 元件名稱
  • 技術限制與實作細節
  • 通用的 use case 描述

驗證雙關

  • 第一關(應用端 /rfc submit):AI 掃描並列出疑似敏感項,互動式確認替換
  • 第二關(框架端 /rfc-intake):AI 再獨立掃一次,若仍抓到敏感項則拒絕入站、退回修訂

檔名規則

{YYYY-MM-DD}-{kebab-slug}.md
  • 日期為 RFC 首次建立日期(created frontmatter)
  • slug 用 kebab-case,描述核心變更
  • 同日多個 RFC 用後綴 -a-b 區分(極少發生)

範例

  • 2026-04-24-media-input-mark-index.md
  • 2026-05-10-form-partial-update-api.md
  • 2026-06-01-auth-token-rotation.md

儲存位置

位置內容存取方式
{app-docs}/docs/rfcs/應用端原始版(含專案上下文)應用團隊自己的 repo
appfuse-docs/docs-web/rfcs/框架端脫敏版(web 範疇)發佈到 /web/rfcs/
appfuse-docs/docs-server/rfcs/框架端脫敏版(server 範疇)發佈到 /server/rfcs/

雙向同步靠 frontmatter 欄位:

  • 應用端版 upstream 指向框架端 URL
  • 框架端版 origin 僅保留 project_type 類別(不暴露客戶身份)

工具對應

Skill執行位置職責
/rfc draft應用端對話式撰寫 RFC
/rfc checklist應用端跑 7 維度品質檢核
/rfc submit應用端脫敏 + 產出交付檔
/rfc list應用端列出本專案提過的 RFC
/rfc-intake intake框架端收檔、分類到 docs-web/docs-server、更新 sidebar / llms.txt
/rfc-intake decide框架端記錄 accepted / rejected / deferred + 更新 Decision Log
/rfc-intake list框架端列出所有 RFC(可過濾 status、scope)

RFC 撰寫範本

請以 RFC 範本 為起點。

範本涵蓋 7 維度要求的所有區段:摘要、動機(使用場景 + 現況限制)、建議設計(API + 行為)、相容性、替代方案、範圍界定、測試策略、Decision Log。


相關文檔


最後更新: 2026-04-24