Criação e Manutenção de RFCs
Esta skill cria e mantém RFCs leves — propostas de design numeradas em Markdown que vivem no repositório junto ao código que descrevem. Uma RFC captura um design antes (ou durante) sua construção: o problema, o estado atual do código, as decisões tomadas com sua justificativa e o que está deliberadamente fora do escopo. A coleção é rastreada por um único INDEX.md, permitindo que todo o histórico de design seja verificado em uma única tabela.
As RFCs aqui são documentos de trabalho, não burocracia: elas existem para que as decisões sobrevivam à perda de contexto, para que um design retomado seja "um único PR pequeno, nada mais", e para que alternativas rejeitadas não sejam rediscutidas.
Use esta skill quando
- O usuário pedir para escrever uma RFC, documento de design, proposta de design, especificação técnica ou proposta de arquitetura
- O usuário quiser registrar ou bloquear uma decisão de design — com as alternativas que venceu, ou por que uma abordagem foi rejeitada — antes de implementá-la
- O usuário pedir para atualizar uma RFC (mudança de status, notas de execução, marcando como concluída ou rejeitada)
- O usuário pedir para criar, indexar ou reorganizar um diretório
rfcs/(ourfc/) - Uma discussão sobre um recurso grande precisar ser capturada como um documento durável
Não use esta skill quando
- O usuário quiser documentação de produto, um README ou documentação voltada ao usuário (não é uma proposta de design)
- O usuário quiser um ADR em um repositório que já tenha uma convenção estabelecida de ADRs — siga essa convenção
- A mudança for trivial o suficiente para ser carregada por uma mensagem de commit ou descrição de PR
Diretório e índice
Localização. As RFCs vivem em um único diretório plano na raiz do repositório: rfcs/ (padrão preferido) ou rfc/. Antes de criar qualquer coisa, procure por um diretório existente com qualquer um dos nomes e siga-o. Se nenhum existir, crie rfcs/.
O gitignore é uma decisão do usuário, não sua. Alguns projetos commitam RFCs; outros as ignoram como notas de trabalho locais. Nunca adicione ou remova uma entrada .gitignore para o diretório de RFCs a menos que seja explicitamente solicitado. Se o diretório estiver no gitignore, o cabeçalho do INDEX.md deve indicar isso (veja o template) para que os leitores saibam por que ele não está no histórico do repositório.
INDEX.md é a fonte da verdade para a coleção. Ele carrega três coisas:
- O próximo número livre, declarado explicitamente — números colidem quando emitidos em paralelo, então o índice nomeia o próximo e toda criação de RFC o atualiza na mesma alteração.
- A tabela do índice:
| # | Título | Status | Resumo |, uma linha por RFC, número vinculado ao arquivo. - A legenda de status.
Se o diretório existir mas tiver um README.md nesse papel, trate-o como o índice. Se for solicitado a configurar do zero, use INDEX.md — copie de references/index-template.md.
Numeração e nomes de arquivos
- Os números são de 4 dígitos, preenchidos com zero, monotonicamente crescentes:
0001,0002, … - Para alocar: leia o "próximo número livre" do
INDEX.md, verifique cruzadamente comlsdo diretório (o índice pode estar desatualizado) e pegue o próximo inteiro não utilizado. - Nome do arquivo:
NNNN-título-em-kebab-case.md. Mantenha o número no nome do arquivo e no H1# RFC NNNN — Títulosincronizados — eles divergem caso contrário, e os links quebram em ambos os sentidos. - Nunca renumerere RFCs existentes. Números são identificadores, não uma ordenação a ser arrumada.
Status
- 📝 Rascunho — proposto, não iniciado (uma RFC "design bloqueado, demanda dependente" ainda é Rascunho)
- 🚧 Em andamento — parcialmente implementado
- ✅ Concluído — totalmente implementado
- ❌ Rejeitado / Retirado — mantenha o arquivo; uma rejeição registrada evita rediscussão
O status vive em dois lugares que devem concordar: a linha **Status:** no cabeçalho da RFC e a coluna Status da tabela do índice. Atualize ambos na mesma alteração.
Anatomia da RFC
Leia references/rfc-template.md antes de escrever uma nova RFC e comece a partir dele. A estrutura:
Bloco de cabeçalho (lista de marcadores diretamente abaixo do H1, antes de qualquer seção):
**Status:**— emoji + palavra, opcionalmente anotada ("pronto para execução — um PR", "design bloqueado, não agendado")**Escopo:**— um parágrafo denso: o que esta RFC cobre e o que deliberadamente não cobre. Este é o parágrafo que alguém lê para decidir se deve ler o resto.**Relacionado:**— links para o código sendo modificado (links relativos dentro do repositório), outras RFCs, trabalhos anteriores, referências externas**Discussão:**(opcional) — link para onde o design está ou estava sendo debatido (PR, issue, thread); um leitor que discorda vai lá em vez de bifurcar o documento**Origem:**(opcional) — de onde o design foi portado ou generalizado, se for o caso
Seções numeradas. O conjunto completo, para uma RFC substancial:
- Resumo — o que é entregue, em algumas frases
- Motivação — o problema, com evidências do código real
- Estado atual — o que existe hoje, verificado contra o código, não de memória
- Objetivos / Não objetivos — explícito em ambos os sentidos
- Design — o núcleo; subseções por fluxo de trabalho ou componente, com assinaturas/esquemas/blocos de código reais onde eles fixam o design. Onde uma escolha foi contestada, mantenha a alternativa rejeitada e por que ela perdeu — uma frase para decisões menores, uma subseção
### Alternativas consideradasquando a escolha moldou o design - Testes — como o design é verificado
- Documentação — qual documentação acompanha
- Fora do escopo — nomeado e justificado: cada item diz por que está excluído e o que mudaria isso
- Riscos — modos de falha honestos, incluindo riscos de o documento ser mal interpretado
- Perguntas não resolvidas — o que deve ser resolvido antes que o design conte como bloqueado, vs. o que a implementação é livre para resolver; nomear uma incógnita é melhor do que resolvê-la silenciosamente durante a construção
- Decisões — uma tabela numerada de decisões bloqueadas; isso é o que torna a retomada barata e a rediscussão desnecessária. Onde uma decisão restringe o futuro de forma não óbvia, a linha diz isso — as consequências de uma decisão são o contexto da próxima
- Fases — o que chega primeiro, o que depende do quê
Adapte ao peso da RFC. Uma RFC pequena de bloqueio de design precisa apenas do bloco de cabeçalho, Design, Não objetivos e a tabela de Decisões. Não encha uma RFC de duas páginas com doze seções; não reduza uma proposta de sistema inteiro a três. Mantenha a numeração das seções contígua para o subconjunto usado.
Estilo de escrita
- Fundamente cada afirmação no código. "Estado atual" e "Motivação" citam arquivos, fatos a nível de linha e números medidos — vincule-os com caminhos relativos. Uma RFC que argumenta de memória é uma ficção com cabeçalhos.
- Registre decisões com seu porquê — e seu custo. A tabela de decisões é o contrato; o corpo carrega o raciocínio. Alternativas rejeitadas ganham uma frase dizendo por que perderam (uma alternativa registrada com seu trade-off permanece rejeitada; uma registrada apenas como "rejeitada" é reproposta). Uma decisão que fecha uma porta diz isso em sua linha.
- No tempo certo é melhor que polido. Uma RFC imperfeita que existe vence uma perfeita que não existe (regra RFD da Oxide: "no tempo certo em vez de polido"). A prosa do rascunho pode ser rude; o parágrafo de Escopo e a tabela de decisões, talvez não.
- Seja honesto sobre limites. Se um mecanismo é adiado, dependente ou sabidamente incompleto, diga isso na RFC em vez de deixar o leitor descobrir. Palavras de falha fechada ("recusado", "levanta", "deliberadamente não agendado") vencem a vagueza otimista.
- Denso vence longo. Prefira um parágrafo que sustenta peso a três parágrafos finos. O resumo de uma linha do índice especialmente: ele deve ser autocontido o suficiente para que um leitor pule a RFC.
Fluxos de trabalho
A parte burocrática — alocação de números, criação de arquivo a partir do template, atualizações de linha do índice e próximo número livre, detecção de divergências — é mecânica, e scripts/rfc_index.py a faz sem as colisões que a alocação manual produz:
python3 scripts/rfc_index.py check # índice vs arquivos, H1 vs nome de arquivo, status, próximo livre
python3 scripts/rfc_index.py next # próximo número livre
python3 scripts/rfc_index.py new "Título" # aloca + instancia template + linha do índice + incrementa
python3 scripts/rfc_index.py new "Título" --number 42 # um número reservado, ou recriando uma RFC deletada
(Caminhos relativos ao diretório desta skill; da raiz do repositório o script está em skills/rfc-writer/scripts/rfc_index.py. Somente leitura, exceto new; adicione --root DIR — antes ou depois do subcomando — se o repositório não for o diretório de trabalho atual.) O pensamento — o que o design diz, o que o resumo de uma linha afirma, quando um status muda — é seu.
A — Criar uma nova RFC
- Localize o diretório de RFCs (
rfcs/ourfc/); se nenhum existir, execute o Fluxo D primeiro. - Aloque o próximo número e instancie o arquivo:
rfc_index.py new "Título"— ele gera o número, escreve o template, adiciona a linha do índice e incrementa a reivindicação do próximo livre. Os passos 3 e 4 permanecem seus: ele deixa o template não preenchido e escreve umTODO: resumo de uma linhaliteral no índice. Manualmente: leia o próximo número livre do índice e verifique cruzadamente comls— números colidem quando emitidos em paralelo. - Preencha o arquivo a partir da estrutura de
references/rfc-template.md, adaptado ao peso do design. Investigue o código real antes de escrever "Estado atual" — isto é a maior parte do trabalho. - Substitua o resumo de uma linha placeholder por um resumo denso e autocontido.
B — Atualizar uma RFC existente
- Quando o trabalho for parcial ou totalmente implementado, atualize a linha
**Status:**— e anote com o que foi implementado e quando ("Implementado em 2026-06-29: …; apenas P5 resta"). - Se a execução divergir do design, registre a divergência na RFC (uma nota de status ou uma emenda na seção relevante) — não reescreva a história silenciosamente; o registro de decisões permanece somente para anexação.
- Espelhe o status (e, se a forma mudou, o resumo de uma linha) na tabela do índice.
- Designs rejeitados recebem ❌ e permanecem no diretório.
C — Manter o índice
Execute rfc_index.py check — ele relata todo arquivo sem uma linha no índice e vice-versa, incompatibilidades H1-vs-nome de arquivo, divergências de status cabeçalho-vs-tabela, números duplicados e um próximo número livre que não está livre. Corrija o que ele nomeia (as correções são de julgamento: qual status é verdadeiro, o que o resumo de uma linha deve dizer), então execute novamente até ficar verde. Relate o que estava fora de sincronia.
D — Inicializar um diretório de RFCs
- Crie
rfcs/(a menos que o usuário queirarfc/ou um já exista). - Crie
INDEX.mda partir dereferences/index-template.md, preenchendo o nome do projeto e definindo o próximo número livre como0001. - Não mexa em
.gitignore— mencione que commitar vs. ignorar o diretório é uma escolha do usuário.
Referências
references/rfc-template.md— esqueleto da RFC com orientação por seção; leia antes de escrever qualquer nova RFCreferences/index-template.md— esqueleto do INDEX.md; use ao inicializar um diretório
Skills relacionadas
altitude-docs— a documentação voltada ao usuário que acompanha o design; a seção de Documentação da RFC aponta para elaself-audit— revisão adversarial do branch que executou uma RFC, antes do mergekeep-a-changelog— registra o que foi implementado; a RFC registra por que foi construído dessa forma