Ir al contenido
CodArchel mapa vivo de la arquitectura
ESEN

ADR 0046 — Los documentos se publican con Starlight

Estado: aceptado · Fecha: 2026-10-23

La web del proyecto ya publica los documentos, pero lo hace con una app React/Vite propia:

  • docs/**/*.md se importa entero con import.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 PRODUCTO dentro del código;
  • los ADR, sus changelogs y la guía dependen de convenciones de nombre;
  • la web es una SPA: hay un index.html y 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.

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.

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).

Cada documento declara lo que el sitio necesita:

---
title: El modelo
description: Qué es un cc.json y qué garantiza.
section: producto # producto | adr | guia
order: 20
status: aceptado # en los ADR
date: "2026-10-23"
adr: adr/0041-0050/0045-... # en un changelog
changelog: true # en un changelog
tags: [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.

  • /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 plugins
date: "2026-10-21"
category: feature
verdict: 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.

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.

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:

  1. Crear docs/<idioma>/ con el mismo slug y el frontmatter traducido; lo que falte cae al español y Starlight lo avisa en la página.
  2. 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.
  3. Añadir las cadenas a src/content/i18n/<idioma>.json: una entrada por idioma con todas las claves, que es la colección i18n de Starlight. src/lib/i18n.ts las tipa para las islas de React y los componentes de Starlight las leen con Astro.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.

  • 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.
  • 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.
  • Crear apps/site con Astro + Starlight y el loader que lee docs/.
  • 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, README y AGENTS.md; retirar la app React/Vite de docs.
  • Validar el build y la publicación en GitHub Pages (web.yml construye y publica con Node 24).

M29 queda cerrada: los documentos y la guía se publican desde el markdown del repo.

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ón i18n de 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.