Skip to main content
Traducción. Autoritativo: ../../modules/README.md.
El modelo está tomado prestado, no inventado: una propuesta numerada y versionada con estructura obligatoria, un estado de ciclo de vida y un registro del release que la implementó — el mecanismo que Kubernetes usa para los KEP, IETF para los RFC y Python para los PEP. Lo que agregamos es la lección de Backstage: si la trazabilidad vive en prosa, nadie la consulta. La nuestra vive en frontmatter validado.

1. Diccionario

Dos trampas de vocabulario que vale la pena nombrar:
  • Spec de módulo ≠ Feature Spec. El spec de módulo es un mapa de lo que existe y se edita libremente. Un Feature Spec es un contrato para un cambio y se congela al aprobarse.
  • FS ≠ TS. El FS dice qué construir y cómo sabremos que está listo. El TS dice cómo construirlo. Una feature chica no necesita TS — el FS lleva una sección Ejecución en su lugar.

2. La cadena

Cada eslabón es verificable. Un FS que cita un DEC inexistente falla CI; un FS marcado implemented sin PR registrado falla CI; una tabla del spec de módulo que ningún FS reclama se reporta como sin cobertura.

3. Identificadores

FS-{MODULE}-{NNNN} — cuatro dígitos, para que un módulo pueda tener hasta 9999 feature specs sin renumerar. Códigos de módulo: Ejemplos: FS-LOY-0002, FS-CORE-0014. La numeración es por módulo — los módulos crecen a ritmos distintos y una secuencia global obligaría a coordinar para nada. Los números nunca se reutilizan, ni siquiera después de retirar un spec. Una feature que genuinamente cruza módulos pertenece a core, o son dos feature specs con un depends_on entre ellos. Nunca es un FS archivado bajo dos módulos.

4. Versionado

Dos esquemas distintos, deliberadamente: Un spec parte en 0.1.0 en draft. Llega a 1.0.0 en el momento en que se approved — eso es lo que significa aprobar: el contrato ya es lo bastante estable como para construir contra él.

5. Ciclo de vida

Las dos reglas que hacen de esto un sistema y no una carpeta

R-S1 — No se mergea código de una feature cuyo FS no esté approved. El PR declara su id de FS; CI lee el estado de ese spec y bloquea si no.
R-S2 — Un FS approved es inmutable en sus secciones normativas. Cambiarlo no es editarlo: subir la versión y agregar una fila de changelog con qué cambió y por qué. Si el cambio revierte un DEC o un ADR, ese ADR se escribe primero.
Las secciones normativas son: Alcance, Fuera de alcance, Comportamiento, Datos, API, Eventos y Criterios de aceptación. Contexto, Notas y Preguntas abiertas se pueden editar libremente en cualquier estado.

6. Frontmatter — el contrato máquina-legible

Todo FS lo lleva. Los validadores lo leen; nada acá es decoración.
tables, events y endpoints son lo que usa el validador de cobertura: cada entidad de un spec de módulo debe estar reclamada por exactamente un FS. Así descubrimos que algo se diseñó y nunca se asignó a una entrega. La sección Registro de entrega del cuerpo se genera desde implementation. Nunca se escribe a mano — la misma disciplina que un modelo de datos generado.

7. Escribir un módulo, paso a paso

  1. PRD. Un documento, desde TEMPLATE-prd.md. Para quién es, qué trabajos hace, no-objetivos explícitos, cómo se mide el éxito, implicancias de pricing, fases. Se escribe una vez, se revisa, y después casi no se toca. Escríbelo antes del diseño técnico — si el PRD cuesta escribirlo, el módulo todavía no se entiende.
  2. Spec de módulo. La forma técnica: entidades e invariantes, eventos emitidos, endpoints con el único permiso que declara cada uno, puntos de extensión. Este queda vivo y se edita cuando la realidad cambia.
  3. Descomponer en features. Cortar por incrementos que se pueden lanzar solos, no por tablas. La prueba: ¿esto se puede lanzar solo y vale algo? Si no, es una sección dentro de otro FS. Registrar la lista resultante en el hub del módulo como tabla de hoja de ruta.
  4. Escribir cada FS desde TEMPLATE-feature-spec.md, en orden de dependencia. Estado draftreview → el owner aprueba → 1.0.0.
  5. Ejecutar. Feature chica: la sección Ejecución del FS basta. Más grande: abrir un TS que declare su arquetipo. El agente trabaja desde el FS aprobado, no desde un prompt de chat — ese es todo el punto del sistema.
  6. Mergear y registrar. El PR agrega una entrada de implementation y mueve el estado a implemented. Después se actualiza el spec de módulo para que refleje lo que ahora existe.

8. Idiomas

La documentación de módulos se entrega en inglés y español, para que cualquier persona pueda leer y revisar un módulo completo.
  • El inglés es autoritativo. modules/{m}/ es la versión normativa: es lo que leen los agentes, lo que valida CI, y lo que manda ante cualquier discrepancia.
  • El español es una traducción fiel, no una variante. Vive en es/modules/{m}/ y refleja el árbol exactamente, archivo por archivo. Una traducción que dice algo distinto del original es un defecto, no una decisión local.
  • Ambas llevan el mismo frontmatter — mismo id, version y status. El validador translation falla cuando divergen, que es lo que impide que una subida de versión deje al español atrás en silencio.
  • Todo archivo traducido abre nombrando su original autoritativo.
El paquete legal va en la dirección contraria: el español es el autoritativo y la traducción al inglés lleva un banner de no vinculante, porque un documento legal en inglés puede terminar firmado como si rigiera.

9. Validación

El modo reporte es el default mientras los módulos se siguen descomponiendo; strict es lo que corre CI. docs:validate:mint corre el CLI del propio Mintlify. Deliberadamente no está pinneado ni es una compuerta de CI: valida contra un producto hosteado que publica varias versiones al día, así que pinnearlo nos verificaría contra un contrato viejo. Córrelo antes de subir documentación; las reglas que ya conocemos están codificadas en links y navigation, que sí son deterministas.

9b. Escribir para Mintlify

Tres restricciones no son obvias, y cada una produjo silenciosamente un 404 en vez de un error.
.md se parsea como MDX. Un < suelto seguido de algo que no es una letra se lee como el inicio de una etiqueta JSX y mata la página. Los presupuestos de latencia son el caso común: escribe p95 &lt;300 ms, no p95 <300 ms. Una { suelta abre una expresión JavaScript — escápala como \{, o pon el token entre backticks. Los comentarios HTML fallan igual: usa {/* ... */}, nunca <!-- ... -->. Dentro de bloques de código y de spans en backticks nada de esto aplica.
Una página nunca puede llamarse README.md. Mintlify omite esos archivos por completo; la navegación queda apuntando a una página que, para el build, no existe. Los overviews de sección son overview.md. El único README.md en docs/internal/ es deliberado: es el archivo que ve GitHub, y es el único lugar donde los enlaces relativos con sufijo .md son correctos.
Los enlaces resuelven desde la raíz de la documentación, no desde el archivo. Un enlace cuyo destino se escribe data.md funciona en GitHub y da 404 en el sitio, y un standards/data pelado también. Todo enlace interno es absoluto y sin extensión: /standards/data.
Los validadores links y navigation hacen cumplir las tres.

10. Índice de módulos

11. Cuándo podar esto

Si en unos meses se están escribiendo specs que nadie lee, el sistema falló y hay que recortarlo en vez de defenderlo. La señal honesta: un FS cuyos criterios de aceptación nunca se contrastaron contra el código mergeado. La ceremonia solo vale su costo porque un agente con un spec aprobado y criterios de aceptación reales produce trabajo mucho más consistente que uno con un prompt — si eso deja de ser cierto, hay que dejar de pagarla.