RFC 작성 및 유지 관리
이 스킬은 번호가 매겨진 경량 RFC(마크다운 디자인 제안서)를 작성하고 유지 관리합니다. RFC는 설명하는 코드 옆에 리포지토리에 보관되는 설계 문서입니다. RFC는 설계가 구축되기 전에(또는 구축되는 동안) 다음을 포착합니다: 문제, 현재 코드 상태, 근거가 포함된 확정 결정 사항, 그리고 의도적으로 범위를 벗어난 항목. 모든 RFC는 단일 INDEX.md로 추적되어 전체 설계 이력을 하나의 표에서 훑어볼 수 있습니다.
여기서 RFC는 작업 문서일 뿐, 관료주의가 아닙니다. 결정 사항이 맥락 손실에서 살아남고, 다시 집어든 설계가 '단일 작은 PR, 그 이상도 이하도 아닌' 상태가 되며, 기각된 대안이 재론되지 않도록 하기 위해 존재합니다.
이 스킬을 사용해야 하는 경우
- 사용자가 RFC, 설계 문서, 설계 제안, 기술 사양 또는 아키텍처 제안 작성을 요청하는 경우
- 사용자가 구현하기 전에 설계 결정을 기록하거나 확정하고 싶어 하는 경우(대안이나 접근 방식이 기각된 이유 포함)
- 사용자가 RFC 업데이트(상태 변경, 실행 노트, 배포 또는 기각 표시)를 요청하는 경우
- 사용자가
rfcs/(또는rfc/) 디렉토리를 생성, 색인화 또는 재구성하도록 요청하는 경우 - 대규모 기능 논의를 지속 가능한 문서로 포착해야 하는 경우
이 스킬을 사용하지 말아야 하는 경우
- 사용자가 제품 문서, README 또는 사용자 대상 문서를 원하는 경우(설계 제안이 아님)
- 사용자가 이미 확립된 ADR 규칙이 있는 리포지토리에서 ADR을 원하는 경우 — 대신 해당 규칙을 따르세요
- 변경 사항이 커밋 메시지나 PR 설명으로 충분히 전달될 정도로 사소한 경우
디렉토리 및 인덱스
위치. RFC는 리포지토리 루트의 단일 플랫 디렉토리인 rfcs/(기본 권장) 또는 rfc/에 위치합니다. 무엇이든 생성하기 전에 먼저 기존 디렉토리가 있는지 확인하고 따르세요. 둘 다 없으면 rfcs/를 만드세요.
Gitignore는 사용자의 결정에 맡기세요. 일부 프로젝트는 RFC를 커밋하고, 다른 프로젝트는 로컬 작업 노트로 gitignore합니다. 명시적으로 요청하지 않는 한 RFC 디렉토리에 대한 .gitignore 항목을 추가하거나 제거하지 마세요. 디렉토리가 gitignore된 경우 INDEX.md 헤더에 이를 명시하여(템플릿 참조) 독자들이 왜 리포지토리 기록에 없는지 알 수 있도록 하세요.
INDEX.md는 컬렉션의 진실 공급원입니다. 여기에는 세 가지가 포함됩니다:
- 다음 사용 가능 번호 — 명시적으로 명시됩니다. 번호는 병렬로 생성될 때 충돌이 발생하므로 인덱스가 다음 번호를 지정하고 모든 RFC 생성 시 동일한 변경에서 이를 업데이트합니다.
- 인덱스 표:
| # | 제목 | 상태 | 한 줄 요약 |, RFC당 한 행, 번호는 파일에 연결됨. - 상태 범례.
디렉토리가 존재하지만 README.md가 이 역할을 하는 경우, 이를 인덱스로 취급하세요. 새로 설정하라는 요청을 받으면 INDEX.md를 사용하세요 — references/index-template.md를 복사하세요.
번호 매기기 및 파일명
- 번호는 4자리 숫자이며, 앞에 0을 채우고, 단조 증가합니다:
0001,0002, … - 할당 방법:
INDEX.md에서 "다음 사용 가능 번호"를 읽고, 디렉토리ls결과와 교차 검증하여(인덱스가 오래되었을 수 있음) 사용되지 않은 다음 정수를 사용합니다. - 파일명:
NNNN-kebab-case-title.md. 파일명에 번호를 유지하고# RFC NNNN — 제목H1과 동기화하세요 — 그렇지 않으면 둘 사이에 차이가 생기고 링크가 양방향으로 깨집니다. - 기존 RFC의 번호를 다시 매기지 마세요. 번호는 정리할 순서가 아닌 식별자입니다.
상태
- 📝 초안 — 제안됨, 시작되지 않음 ("설계 확정, 수요 게이트" RFC도 여전히 초안)
- 🚧 진행 중 — 부분적으로 배포됨
- ✅ 완료 — 완전히 배포됨
- ❌ 기각 / 철회 — 파일을 유지하세요. 기록된 기각은 재론을 방지합니다.
상태는 일치해야 하는 두 곳에 위치합니다: RFC 헤더의 **상태:** 줄과 인덱스 표의 상태 열. 동일한 변경에서 둘 다 업데이트하세요.
RFC 구조
새 RFC를 작성하기 전에 references/rfc-template.md를 읽고 해당 템플릿에서 시작하세요. 구조는 다음과 같습니다:
헤더 블록 (H1 바로 아래, 모든 섹션 앞의 글머리 기호 목록):
**상태:**— 이모지 + 단어, 선택적으로 주석 추가 ("실행 준비 완료 — 하나의 PR", "설계 확정, 일정 미정")**범위:**— 밀도 있는 단락: 이 RFC가 다루는 내용 과 의도적으로 다루지 않는 내용. 이것은 누군가가 나머지를 읽을지 결정하기 위해 읽는 단락입니다.**관련 항목:**— 수정되는 코드에 대한 링크(리포지토리 내 상대 링크), 다른 RFC, 선행 사례, 외부 참조**논의:**(선택 사항) — 설계가 논의되었거나 논의 중인 곳에 대한 링크(PR, 이슈, 스레드). 동의하지 않는 독자는 문서를 포크하는 대신 그곳으로 갑니다.**출처:**(선택 사항) — 설계가 포팅되거나 일반화된 곳(있는 경우)
번호가 매겨진 섹션. 실질적인 RFC에 대한 전체 세트:
- 요약 — 몇 문장으로 무엇이 배포되는지
- 동기 — 실제 코드베이스의 증거와 함께 문제
- 현재 상태 — 오늘 존재하는 것, 코드에 대해 검증됨, 기억이 아님
- 목표 / 비목표 — 양방향 모두 명시적
- 설계 — 핵심; 작업 스트림 또는 구성 요소별 하위 섹션, 설계를 고정시키는 실제 시그니처/스키마/코드 블록 포함. 선택이 논쟁이 되었던 곳에서는 기각된 대안과 왜 기각되었는지 유지하세요 — 사소한 호출의 경우 한 문장, 선택이 설계를 형성한 경우
### 고려된 대안하위 섹션 사용. - 테스트 — 설계가 어떻게 검증되는지
- 문서 — 어떤 문서가 함께 제공되는지
- 범위 밖 — 이름이 지정되고 이유가 설명됨: 각 항목은 왜 제외되었고 무엇이 그것을 바꿀 수 있는지 말함
- 위험 — 문서가 오독될 위험을 포함한 정직한 실패 모드
- 미해결 질문 — 설계가 확정된 것으로 간주되기 전에 해결되어야 할 것 vs. 구현이 자유롭게 해결할 수 있는 것; 알려지지 않은 것을 명명하는 것이 빌드 중간에 조용히 해결하는 것보다 나음
- 결정 사항 — 확정된 결정의 번호가 매겨진 표; 이것이 픽업을 저렴하게 하고 재론을 불필요하게 만드는 요소임. 결정이 미래를 명확하지 않게 제약하는 경우, 행이 이를 말함 — 한 결정의 결과는 다음 결정의 맥락임
- 단계화 — 무엇이 먼저 배포되고, 무엇이 무엇에 의존하는지
RFC의 무게에 맞게 조정하세요. 작은 설계 확정 RFC는 헤더 블록, 설계, 비목표 및 결정 표만 있으면 됩니다. 2페이지 RFC를 12개 섹션으로 채우지 마세요. 시스템 전체 제안을 세 개로 축소하지 마세요. 사용되는 어떤 하위 집합에 대해서도 섹션 번호가 연속되도록 유지하세요.
작성 스타일
- 모든 주장을 코드에 근거하세요. "현재 상태"와 "동기"는 파일, 라인 수준 사실 및 측정된 숫자를 인용하고 상대 경로로 연결하세요. 기억에 의존하는 RFC는 제목만 있는 허구입니다.
- 결정을 '왜'와 '비용'과 함께 기록하세요. 결정 표는 계약입니다. 본문은 추론을 담습니다. 기각된 대안은 왜 기각되었는지 말하는 문장을 얻습니다(절충점과 함께 기록된 대안은 기각된 상태로 유지됩니다. 단순히 "기각"으로만 기록된 대안은 재제안됩니다). 나중에 문을 닫는 결정은 해당 행에서 이를 명시합니다.
- 시의적절함이 세련됨보다 낫습니다. 존재하는 거친 RFC가 존재하지 않는 완벽한 RFC보다 낫습니다(Oxide의 RFD 규칙: "세련됨보다 시의적절함"). 초안 문장은 거칠 수 있습니다. 범위 단락과 결정 표는 그렇지 않을 수 있습니다.
- 한계에 대해 정직하세요. 메커니즘이 연기되었거나, 게이트되었거나, 불완전한 것으로 알려진 경우, 독자가 발견하게 두지 말고 RFC에 명시하세요. 닫힘-실패 표현("거부", "발생", "의도적으로 미일정")이 낙관적인 모호함보다 낫습니다.
- 밀도가 길이보다 낫습니다. 세 개의 얇은 단락보다 하나의 하중을 지탱하는 단락을 선호하세요. 특히 인덱스 한 줄 요약: 독자가 RFC를 건너뛸 수 있을 만큼 자급자족해야 합니다.
워크플로우
번호 할당, 템플릿에서 파일 생성, 인덱스 행 및 다음 사용 가능 번호 업데이트, 차이 감지와 같은 부기 작업은 기계적이며, scripts/rfc_index.py는 수동 할당이 생성하는 충돌 없이 수행합니다:
python3 scripts/rfc_index.py check # 인덱스 vs 파일, H1 vs 파일명, 상태, 다음 사용 가능
python3 scripts/rfc_index.py next # 다음 사용 가능 번호
python3 scripts/rfc_index.py new "제목" # 할당 + 템플릿 인스턴스화 + 인덱스 행 + 번호 증가
python3 scripts/rfc_index.py new "제목" --number 42 # 예약된 번호 또는 삭제된 RFC 재생성
(경로는 이 스킬의 디렉토리를 기준으로 합니다. 리포지토리 루트에서 스크립트는 skills/rfc-writer/scripts/rfc_index.py에 있습니다. new를 제외하고 읽기 전용입니다. 리포지토리가 현재 작업 디렉토리가 아닌 경우 --root DIR을 서브커맨드 앞이나 뒤에 추가하세요.) 사고 — 설계가 무엇을 말하는지, 한 줄 요약이 무엇을 주장하는지, 상태가 언제 변경되는지 — 는 당신의 몫입니다.
A — 새 RFC 생성
- RFC 디렉토리(
rfcs/또는rfc/)를 찾습니다. 없으면 먼저 워크플로우 D를 실행합니다. - 다음 번호를 할당하고 파일을 인스턴스화합니다:
rfc_index.py new "제목"— 번호를 생성하고, 템플릿을 작성하고, 인덱스 행을 추가하고, 다음 사용 가능 번호를 증가시킵니다. 3단계와 4단계는 여전히 당신의 몫입니다: 템플릿을 채우지 않은 상태로 두고 인덱스에 리터럴TODO: 한 줄 요약을 작성합니다. 수동으로: 인덱스에서 다음 사용 가능 번호를 읽고ls와 교차 검증합니다 — 번호는 병렬로 생성될 때 충돌합니다. references/rfc-template.md의 구조에서 설계의 무게에 맞게 조정하여 파일을 채웁니다. "현재 상태"를 작성하기 전에 실제 코드를 조사하세요 — 이것이 대부분의 작업입니다.- 인덱스의 플레이스홀더 한 줄 요약을 밀도 있고 자급자족하는 요약으로 바꿉니다.
B — 기존 RFC 업데이트
- 작업이 부분적으로 또는 완전히 배포되면
**상태:**줄을 업데이트하고 — 무엇이 언제 배포되었는지 주석을 추가합니다("2026-06-29 배포: …; P5만 남음"). - 실행이 설계와 달라진 경우, RFC에 차이를 기록합니다(상태 노트 또는 관련 섹션의 수정 사항) — 기록을 조용히 다시 쓰지 마세요. 결정 로그는 추가 전용으로 유지됩니다.
- 상태(및 모양이 변경된 경우 한 줄 요약)를 인덱스 표에 반영합니다.
- 기각된 설계는 ❌를 받고 디렉토리에 남습니다.
C — 인덱스 유지 관리
rfc_index.py check를 실행합니다 — 인덱스 행이 없는 파일과 그 반대, H1-파일명 불일치, 헤더-표 상태 불일치, 중복 번호, 그리고 사용 가능하지 않은 다음 사용 가능 번호를 보고합니다. 보고된 항목을 수정하고(수정은 판단: 어떤 상태가 참인지, 한 줄 요약이 무엇이어야 하는지), 다시 실행하여 깨끗해질 때까지 반복합니다. 무엇이 동기화되지 않았는지 보고합니다.
D — RFC 디렉토리 초기화
rfcs/를 생성합니다(사용자가rfc/를 원하거나 이미 존재하지 않는 경우).references/index-template.md에서INDEX.md를 생성하고, 프로젝트 이름을 채우고 다음 사용 가능 번호를0001로 설정합니다..gitignore는 건드리지 마세요 — 디렉토리를 커밋할지 무시할지는 사용자의 선택이라고 언급합니다.
참조
references/rfc-template.md— 섹션별 지침이 있는 RFC 골격; 새 RFC를 작성하기 전에 읽으세요.references/index-template.md— INDEX.md 골격; 디렉토리 초기화 시 사용하세요.
관련 스킬
altitude-docs— 설계 후 배포되는 사용자 대상 문서; RFC의 문서 섹션이 이를 가리킵니다.self-audit— RFC를 실행한 브랜치에 대한 병합 전 적대적 검토.keep-a-changelog— 배포된 것을 기록합니다; RFC는 왜 그렇게 구축되었는지 기록합니다.