ADR 0046 — Los documentos se publican con Starlight
This content is not available in your language yet.
Estado: aceptado · Fecha: 2026-10-23
Contexto
Sección titulada «Contexto»La web del proyecto ya publica los documentos, pero lo hace con una app React/Vite propia:
docs/**/*.mdse importa entero conimport.meta.glob(..., { eager: true });- el título y la descripción se adivinan del primer
#y del primer párrafo; - el orden del producto está en una lista
PRODUCTOdentro del código; - los ADR, sus changelogs y la guía dependen de convenciones de nombre;
- la web es una SPA: hay un
index.htmly el router pinta el documento. No hay un HTML por documento, SEO real ni búsqueda; - añadir una sección puede obligar a tocar el código de la web.
Hay 99 documentos. La documentación va a crecer y tiene que seguir siendo revisable en PR, con historial y sin un backend que mantener. La pregunta no es «Markdown sí o no»: Markdown es el mejor formato para escribir prosa. Lo que falta es un modelo de contenido y un build que lo valide.
Decisión
Sección titulada «Decisión»1. Astro + Starlight para la documentación
Sección titulada «1. Astro + Starlight para la documentación»La web de documentos pasa a Astro con Starlight. Cada documento se genera como HTML estático en su ruta, con:
- sidebar generada desde el contenido;
- búsqueda Pagefind en el build;
- índice de la página y navegación anterior/siguiente;
- sitemap y metadatos por documento;
- contenido Markdown/MDX con frontmatter validado.
La portada y la guía pueden seguir siendo páginas propias (Astro, o un componente React montado como isla) para conservar la identidad visual. No se obliga a que todo el sitio sea Starlight.
2. docs/ sigue siendo la fuente de verdad
Sección titulada «2. docs/ sigue siendo la fuente de verdad»No se copia el contenido a apps/site ni se mantiene un espejo a mano. El proyecto define una
colección docs con un loader glob que lee ./docs y genera ids con el prefijo docs/:
docs: defineCollection({ loader: glob({ base: "./docs", pattern: "**/*.md", generateId: ({ entry }) => `docs/${entry.replace(/\.md$/, "")}` }), schema: docsSchema({ extend: ... })})Así una carpeta de docs/ sigue siendo una ruta del sitio (docs/model.md → /docs/model/) y
los ADR/changelogs se revisan donde siempre. Si una versión futura de Starlight no permite leer
fuera de src/content/docs, se generará un espejo en el build, nunca a mano.
La guía no entra en esa colección: tiene la suya, sobre docs/guideline/entradas/ (apartado 5).
3. El frontmatter es obligatorio y validado
Sección titulada «3. El frontmatter es obligatorio y validado»Cada documento declara lo que el sitio necesita:
---title: El modelodescription: Qué es un cc.json y qué garantiza.section: producto # producto | adr | guiaorder: 20status: aceptado # en los ADRdate: "2026-10-23"adr: adr/0041-0050/0045-... # en un changelogchangelog: true # en un changelogtags: [modelo, checksum]---El esquema extiende docsSchema() con Zod. Si falta title, el section no es válido o un
changelog no apunta a su ADR, el build falla. No hay metadatos adivinados.
La primera línea # del documento se elimina del cuerpo: Starlight pinta el título con el
frontmatter. La descripción no se calcula del primer párrafo.
4. Las URLs actuales se conservan
Sección titulada «4. Las URLs actuales se conservan»/docs/<ruta>/para los documentos./guia/para la guía./para la portada.
Las rutas no cambian, así que no hacen falta redirecciones. Los enlaces internos del Markdown se validan en el build; una ruta rota no se publica.
5. La guía deja de ser un bloque parseado a mano
Sección titulada «5. La guía deja de ser un bloque parseado a mano»Cada idea es un fichero en docs/guideline/entradas/:
entradas/2026-10-21-01-el-registro-publico-de-plugins.md---title: El registro público de pluginsdate: "2026-10-21"category: featureverdict: idea---Las normas son normas.md; las entradas viven en entradas/. La página /guia/ agrupa las
entradas por día y categoría, como antes, pero sin partir un único Markdown con expresiones
regulares. Añadir una idea es añadir un fichero, no tocar el parser.
6. Búsqueda, SEO y publicación
Sección titulada «6. Búsqueda, SEO y publicación»Pagefind genera el índice de búsqueda en el build y Starlight genera el sitemap. El workflow
web.yml construye y publica en GitHub Pages cuando cambia apps/site/docs/ o apps/site/. Añadir un
documento con su frontmatter es suficiente: aparece en su ruta, en la sidebar y en la búsqueda.
No se usa una base de datos como fuente: GitHub Pages es estático y la documentación tiene que poder revisarse en un PR. SQLite/FTS5 (M24) sigue siendo un índice derivado para CLI/MCP, no la fuente del sitio.
7. La cabecera del sitio, también en los documentos
Sección titulada «7. La cabecera del sitio, también en los documentos»Starlight conserva su cabecera (búsqueda, tema y GitHub) y se le añaden los enlaces Inicio,
Guía y Documentos con un override de Header. Los documentos no pierden la navegación del
resto del sitio; en móvil, el título lleva a Inicio y la barra lateral a la guía.
8. Idiomas, con dos
Sección titulada «8. Idiomas, con dos»El idioma por defecto es el español; el inglés vive en /en/. Starlight resuelve la traducción de
los documentos con su propio locales, Astro la de las rutas y la interfaz con i18n, y la portada
y la guía se sirven desde las mismas islas de React con lang. Añadir contenido es:
- Crear
docs/<idioma>/con el mismoslugy el frontmatter traducido; lo que falte cae al español y Starlight lo avisa en la página. - Servir las rutas con un parámetro de descanso (
[...lang]): una sola página genera/,/guia/…y sus versiones/en/…. Una vista, un fichero; el idioma es un dato. - Añadir las cadenas a
src/content/i18n/<idioma>.json: una entrada por idioma con todas las claves, que es la coleccióni18nde Starlight.src/lib/i18n.tslas tipa para las islas de React y los componentes de Starlight las leen conAstro.locals.t.
El selector de los documentos lo pone Starlight en su cabecera; el del sitio cambia el prefijo de la
ruta. La cabecera y los documentos usan Astro.locals.t; las islas de React reciben lang y usan
t(lang, clave), y las fechas, categorías y veredictos de la guía se formatean en ese idioma. La guía se traduce entera —cada entrada lleva su
pareja inglesa y un test lo comprueba— y sus enlaces llevan al documento en /en/docs/. No se
generan traducciones automáticas: una página en inglés es una página revisada.
Consecuencias
Sección titulada «Consecuencias»- La documentación gana HTML por página, SEO, búsqueda, sitemap y navegación automática.
- El contenido sigue en
docs/, versionado y revisable; no se muda a una base de datos ni a PHP. - Hay una migración única: añadir frontmatter a 99 documentos y quitar su
#inicial. - Starlight trae su propio layout; la portada y la guía se adaptan para conservar la identidad.
- El bundle deja de cargar todo el markdown de golpe: cada página lleva su contenido.
- El CI valida el esquema, los enlaces y el build; un documento mal formado no se publica.
Alternativas descartadas
Sección titulada «Alternativas descartadas»- Base de datos como fuente: GitHub Pages no ejecuta consultas; haría falta un backend, auth y perderíamos el diff/PR de la documentación.
- PHP: necesita un servidor; no encaja con Pages ni con el repo.
- XML: sirve para datos, no para prosa; el diff y la escritura son peores que Markdown.
- CMS externo: solo si se quiere editar sin tocar git; añade dependencia, coste y secretos.
- Docusaurus: también válido, pero más pesado y con más trabajo para conservar el diseño actual.
- Capa de contenido sobre la web React/Vite actual: menos migración, pero tendríamos que construir prerender, búsqueda, sitemap y SEO; más mantenimiento a largo plazo.
Hoja de ruta
Sección titulada «Hoja de ruta»M29 — Los documentos con Starlight
Sección titulada «M29 — Los documentos con Starlight»- Crear
apps/sitecon Astro + Starlight y el loader que leedocs/. - Definir el esquema de frontmatter y migrar los 99 documentos (título, descripción, sección, orden, estado, fecha, ADR/changelog).
- Conservar
/docs/,/guia/y/y validar los enlaces internos (las rutas no cambian, así que no hacen falta redirecciones). - Migrar la guía a entradas estructuradas; la portada ya está adaptada.
- Activar Pagefind, sitemap y búsqueda; un documento nuevo entra solo en la sidebar.
- Actualizar
web.yml,READMEyAGENTS.md; retirar la app React/Vite de docs. - Validar el build y la publicación en GitHub Pages (
web.ymlconstruye y publica con Node 24).
M29 queda cerrada: los documentos y la guía se publican desde el markdown del repo.
M31 — El sitio en dos idiomas
Sección titulada «M31 — El sitio en dos idiomas»Estado: cerrada.
- Selector de idioma en la portada, la guía y los documentos.
- Rutas inglesas:
/en/,/en/guia/,/en/guia/AAAA-MM-DD/,/en/guia/futuro/y/en/guia/normas/. - Diccionario ES/EN completo en
src/content/i18n/(la coleccióni18nde Starlight): la interfaz no deja cadenas sin traducir. - Fechas, categorías y veredictos de la guía localizados.
- Una sola ruta por vista con
[...lang]: los dos idiomas comparten fichero y cambian el prefijo. - Documentos de producto traducidos en
docs/en/: índice, modelo, reglas, MCP, migración y mapa, más el índice de ADR y la hoja de ruta. - La guía entera en inglés: sus entradas y las normas, con el mismo nombre de fichero y un test que exige la pareja.
- Los ADR se quedan en español, con su aviso de caída: son documentos de construcción y el producto ya tiene su documentación traducida. Traducir 103 ADR envejecidos no aporta lo que cuesta mantenerlos en dos idiomas.
La infraestructura, los documentos de producto y la guía están completos; los ADR se leen en español, con su aviso de caída.