¿Qué hace Creación y Mantenimiento de RFCs?
Esta habilidad crea y mantiene RFCs ligeros — propuestas de diseño numeradas en Markdown que viven en el repositorio junto al código que describen. Un RFC captura un diseño antes (o mientras) se construye: el problema, el estado actual del código, las decisiones tomadas con su justificación, y lo que está deliberadamente fuera del alcance. La colección se rastrea mediante un solo INDEX.md para que todo el historial de diseño sea escaneable en una tabla.
Los RFCs aquí son documentos de trabajo, no burocracia: existen para que las decisiones sobrevivan a la pérdida de contexto, para que un diseño retomado sea "un solo PR pequeño, nada más", y para que las alternativas rechazadas no se vuelvan a litigar.
Usa esta habilidad cuando
- El usuario pide escribir un RFC, documento de diseño, propuesta de diseño, especificación técnica o propuesta de arquitectura
- El usuario quiere registrar o fijar una decisión de diseño — con las alternativas que venció, o por qué un enfoque fue rechazado — antes de implementarlo
- El usuario pide actualizar un RFC (cambio de estado, notas de ejecución, marcarlo como enviado o rechazado)
- El usuario pide crear, indexar o reorganizar un directorio
rfcs/(orfc/) - Una discusión sobre una funcionalidad grande debería capturarse como un documento duradero
No uses esta habilidad cuando
- El usuario quiere documentación de producto, un README o documentación orientada al usuario (no es una propuesta de diseño)
- El usuario quiere un ADR en un repositorio que ya tiene una convención ADR establecida — sigue esa convención en su lugar
- El cambio es lo suficientemente trivial como para que lo lleve un mensaje de commit o la descripción de un PR
Directorio e índice
Ubicación. Los RFCs viven en un único directorio plano en la raíz del repositorio: rfcs/ (valor predeterminado preferido) o rfc/. Antes de crear cualquier cosa, busca un directorio existente con cualquiera de los dos nombres y síguelo. Si no existe ninguno, crea rfcs/.
El gitignore es decisión del usuario, no tuya. Algunos proyectos commitean los RFCs; otros los ignoran (gitignore) como notas de trabajo locales. Nunca agregues ni elimines una entrada de .gitignore para el directorio de RFCs a menos que se te pida explícitamente. Si el directorio está en gitignore, el encabezado de INDEX.md debe indicarlo (ver la plantilla) para que los lectores sepan por qué no está en el historial del repositorio.
INDEX.md es la fuente de verdad de la colección. Contiene tres cosas:
- El próximo número libre, indicado explícitamente — los números chocan cuando se crean en paralelo, así que el índice nombra el siguiente y cada creación de RFC lo actualiza en el mismo cambio.
- La tabla del índice:
| # | Título | Estado | Resumen |, una fila por RFC, número enlazado al archivo. - La leyenda de estados.
Si el directorio existe pero tiene un README.md en este rol, trátalo como el índice. Si se pide configurar desde cero, usa INDEX.md — copia references/index-template.md.
Numeración y nombres de archivo
- Los números son de 4 dígitos, rellenos con ceros a la izquierda, monótonamente crecientes:
0001,0002, … - Para asignar: lee el "próximo número libre" de
INDEX.md, verifica contralsdel directorio (el índice puede estar desactualizado) y toma el siguiente entero no utilizado. - Nombre de archivo:
NNNN-título-en-kebab-case.md. Mantén el número en el nombre del archivo y el título# RFC NNNN — TítuloH1 sincronizados — de lo contrario se desvían, y los enlaces se rompen en ambos sentidos. - Nunca renumeres RFCs existentes. Los números son identificadores, no un orden que deba ordenarse.
Estados
- 📝 Borrador — propuesto, no iniciado (un RFC "diseño fijado, demanda pendiente" sigue siendo Borrador)
- 🚧 En progreso — parcialmente enviado
- ✅ Completado — completamente enviado
- ❌ Rechazado / retirado — conserva el archivo; un rechazo registrado evita volver a litigar
El estado vive en dos lugares que deben coincidir: la línea **Estado:** en el encabezado del RFC y la columna Estado de la tabla del índice. Actualiza ambos en el mismo cambio.
Anatomía de un RFC
Lee references/rfc-template.md antes de escribir un nuevo RFC y comienza desde ahí. La estructura:
Bloque de encabezado (lista con viñetas directamente debajo del H1, antes de cualquier sección):
**Estado:**— emoji + palabra, opcionalmente anotado ("listo para ejecución — un PR", "diseño fijado, no programado")**Alcance:**— un párrafo denso: qué cubre este RFC y qué no cubre deliberadamente. Este es el párrafo que alguien lee para decidir si leer el resto.**Relacionado:**— enlaces al código que se está modificando (enlaces relativos dentro del repositorio), otros RFCs, trabajo previo, referencias externas**Discusión:**(opcional) — enlace a dónde se debatió o se está debatiendo el diseño (PR, issue, hilo); un lector que no esté de acuerdo va allí en lugar de bifurcar el documento**Origen:**(opcional) — de dónde se portó o generalizó el diseño, si aplica
Secciones numeradas. El conjunto completo, para un RFC sustancial:
- Resumen — qué se envía, en pocas oraciones
- Motivación — el problema, con evidencia del código real
- Estado actual — qué existe hoy, verificado contra el código, no de memoria
- Objetivos / No objetivos — explícito en ambos sentidos
- Diseño — el núcleo; subsecciones por flujo de trabajo o componente, con firmas/esquemas/bloques de código reales donde fijan el diseño. Donde una elección fue controvertida, conserva la alternativa rechazada y por qué perdió — una oración para decisiones menores, una subsección
### Alternativas consideradascuando la elección moldeó el diseño - Pruebas — cómo se verifica el diseño
- Documentación — qué documentación se envía con él
- Fuera del alcance — nombrado y justificado: cada elemento dice por qué está excluido y qué cambiaría eso
- Riesgos — modos de falla honestos, incluidos los riesgos de que el documento sea malinterpretado
- Preguntas no resueltas — qué debe resolverse antes de que el diseño cuente como fijado, frente a qué la implementación es libre de resolver; nombrar una incógnita es mejor que resolverla en silencio a mitad de la construcción
- Decisiones — una tabla numerada de decisiones tomadas; esto es lo que hace que retomar sea barato y que volver a litigar sea innecesario. Donde una decisión restringe el futuro de manera no obvia, la fila lo dice — las consecuencias de una decisión son el contexto de la siguiente
- Fases — qué llega primero, qué depende de qué
Escala según el peso del RFC. Un RFC pequeño de fijación de diseño solo necesita el bloque de encabezado, Diseño, No objetivos y la tabla de Decisiones. No rellenes un RFC de dos páginas hasta doce secciones; no colapses una propuesta de todo el sistema en tres. Mantén la numeración de secciones contigua para el subconjunto que se use.
Estilo de escritura
- Fundamenta cada afirmación en el código. "Estado actual" y "Motivación" citan archivos, hechos a nivel de línea y números medidos — enlázalos con rutas relativas. Un RFC que argumenta desde la memoria es una ficción con encabezados.
- Registra las decisiones con su porqué — y su costo. La tabla de decisiones es el contrato; el cuerpo lleva el razonamiento. Las alternativas rechazadas reciben una oración que dice por qué perdieron (una alternativa registrada con su compensación se mantiene rechazada; una registrada meramente como "rechazada" se vuelve a proponer). Una decisión que cierra una puerta lo dice en su fila.
- Oportuno sobre pulido. Un RFC tosco que existe es mejor que uno perfecto que no existe (regla de RFD de Oxide: "oportuno más que pulido"). El texto del borrador puede ser tosco; el párrafo de Alcance y la tabla de decisiones quizás no.
- Sé honesto sobre los límites. Si un mecanismo se difiere, se condiciona o se sabe incompleto, dilo en el RFC en lugar de dejar que el lector lo descubra. El lenguaje de cierre ante fallo ("rechazado", "genera", "deliberadamente no programado") es mejor que la vaguedad optimista.
- Denso sobre largo. Prefiere un párrafo con carga semántica sobre tres delgados. El resumen de una línea del índice especialmente: debe ser lo suficientemente autónomo para que un lector pueda saltarse el RFC.
Flujos de trabajo
El trabajo administrativo — asignación de números, creación de archivos a partir de la plantilla, actualizaciones de fila del índice y del próximo número libre, detección de desincronizaciones — es mecánico, y scripts/rfc_index.py lo hace sin las colisiones que produce la asignación manual:
python3 scripts/rfc_index.py check # índice vs archivos, H1 vs nombre de archivo, estados, próximo libre
python3 scripts/rfc_index.py next # próximo número libre
python3 scripts/rfc_index.py new "Título" # asigna + instancia plantilla + fila del índice + incrementa
python3 scripts/rfc_index.py new "Título" --number 42 # un número reservado, o recrear un RFC eliminado
(Las rutas son relativas al directorio de esta habilidad; desde la raíz del repositorio el script está en skills/rfc-writer/scripts/rfc_index.py. Solo lectura excepto new; añade --root DIR — antes o después del subcomando — si el repositorio no es el directorio de trabajo actual.) El pensamiento — qué dice el diseño, qué afirma el resumen de una línea, cuándo cambia un estado — es tuyo.
A — Crear un nuevo RFC
- Localiza el directorio de RFCs (
rfcs/orfc/); si no existe ninguno, ejecuta primero el Flujo de trabajo D. - Asigna el siguiente número e instancia el archivo:
rfc_index.py new "Título"— crea el número, escribe la plantilla, añade la fila del índice e incrementa la reclamación del próximo libre. Los pasos 3 y 4 siguen siendo tuyos: deja la plantilla sin rellenar y escribe un literalTODO: resumen de una líneaen el índice. A mano: lee el próximo número libre del índice y verifica contrals— los números chocan cuando se crean en paralelo. - Rellena el archivo a partir de la estructura de
references/rfc-template.md, escalada al peso del diseño. Investiga el código real antes de escribir "Estado actual" — esto es la mayor parte del trabajo. - Reemplaza el resumen de una línea del índice con un resumen denso y autónomo.
B — Actualizar un RFC existente
- Cuando el trabajo se envía parcial o completamente, actualiza la línea
**Estado:**— y anótala con lo que se envió y cuándo ("Enviado 2026-06-29: …; solo queda P5"). - Si la ejecución se desvió del diseño, registra la desviación en el RFC (una nota de estado o una enmienda en la sección relevante) — no reescribas la historia en silencio; el registro de decisiones se mantiene solo de añadido.
- Refleja el estado (y, si la estructura cambió, el resumen de una línea) en la tabla del índice.
- Los diseños rechazados reciben ❌ y permanecen en el directorio.
C — Mantener el índice
Ejecuta rfc_index.py check — informa de cada archivo sin fila en el índice y viceversa, discrepancias entre H1 y nombre de archivo, desacuerdos de estado entre encabezado y tabla, números duplicados y un próximo número libre que no está libre. Corrige lo que nombra (las correcciones son juicio: qué estado es verdadero, qué debería decir el resumen de una línea), luego vuelve a ejecutar hasta que esté en verde. Informa qué estaba desincronizado.
D — Inicializar un directorio de RFCs
- Crea
rfcs/(a menos que el usuario quierarfc/o ya exista uno). - Crea
INDEX.mda partir dereferences/index-template.md, completando el nombre del proyecto y estableciendo el próximo número libre en0001. - No toques
.gitignore— menciona que commitar vs. ignorar el directorio es decisión del usuario.
Referencias
references/rfc-template.md— esqueleto de RFC con orientación por sección; léelo antes de escribir cualquier nuevo RFCreferences/index-template.md— esqueleto de INDEX.md; úsalo al inicializar un directorio
Habilidades relacionadas
altitude-docs— la documentación orientada al usuario que se envía después del diseño; la sección de Documentación del RFC la referenciaself-audit— revisión adversarial de la rama que ejecutó un RFC, antes de fusionarkeep-a-changelog— registra lo que se envió; el RFC registra por qué se construyó de esa manera