Módulo 7: Documentación que sobrevive
Docs-as-code
Descripción
La lección anterior estableció el principio: la doc que sobrevive es la que vive pegada al código, porque la proximidad es lo único que la mantiene sincronizada. Pero un principio no se ejecuta solo —"mantén la doc cerca del código" es un buen consejo que se olvida el primer día ocupado—. Esta lección instala la práctica concreta que convierte ese principio en un mecanismo que no depende de la buena voluntad: docs-as-code, tratar la documentación exactamente como tratamos el código. Eso significa cuatro cosas que van juntas: la doc vive en el repo (no en una wiki aparte); está escrita en texto plano (Markdown para la prosa, PlantUML o Mermaid para los diagramas, de modo que se versione y se compare línea por línea); pasa por review en los mismos PRs que el código (el mismo cambio que toca payments toca su doc, y el revisor ve las dos cosas juntas); y —lo más potente— se valida en CI, como los tests, de modo que si la doc se desincroniza del código, el build falla.
Ese cuarto punto es el que transforma la disciplina en garantía. En la lección 2 vimos que la wiki se pudre porque la desincronización es invisible: nadie audita si la doc quedó al día, así que el residuo se acumula en silencio hasta que la doc está podrida. Docs-as-code hace lo contrario: convierte la desincronización en un test que rompe el build. Si un ADR referencia un módulo billing que ya se renombró a payments, un validador en CI lo detecta y falla, igual que fallaría un test roto. "La doc se pudrió" deja de ser un problema que se descubre meses después, cuando un dev nuevo confía en algo falso, y se convierte en un semáforo rojo que salta en el PR que introdujo la desincronización —cuando todavía es barato arreglarlo—. Esta lección ejecuta ese validador sobre la documentación de Mercado y ve el build fallar.
Conexión con el módulo. Es la continuación directa de la lección 2. Aquella enseñó por qué la proximidad mantiene viva la doc (el principio: living documentation); esta enseña cómo forzar esa proximidad de modo que no dependa de que alguien se acuerde (la práctica: docs-as-code). Con la analogía del módulo: la lección 2 explicó que la etiqueta tiene que estar pegada a la máquina; esta instala la regla del taller que lo garantiza —"no se cierra la orden de mantenimiento sin actualizar la etiqueta", verificada por un supervisor—. Frontera con el resto: aquí no re-enseñamos a dibujar el C4 (M3) ni a redactar un ADR (architecture-decisions); aquí ponemos esos artefactos en el repo y los validamos. El validador que construimos no juzga si el C4 está bien dibujado; verifica que no referencie módulos que ya no existen.
Una analogía: la enmienda que ambas partes firman en el mismo acto
Piensa en un contrato entre dos empresas, y en dos maneras de manejar los cambios que se le van haciendo con el tiempo.
La carpeta de correos sueltos. El contrato original está firmado y archivado. Con los meses, las partes acuerdan cambios —un precio nuevo, un plazo distinto, una cláusula extra— y cada cambio se manda por correo, se habla por teléfono, se anota en una minuta. Cada acuerdo es real, pero vive suelto: en la bandeja de entrada de alguien, en una nota, en la memoria de quien estuvo en la llamada. Un año después, nadie sabe con certeza cuál es el contrato vigente: el documento firmado dice una cosa, los correos dicen otra, y hay un cambio que solo recuerda una persona que ya no trabaja ahí. Cuando surge una disputa, no hay una fuente de verdad —hay un documento oficial desactualizado y un enjambre de cambios sueltos que lo contradicen—. El contrato "existe", pero no se puede confiar en él, porque los cambios nunca se integraron a él.
La enmienda firmada en el mismo acto. Las mismas dos empresas, con otra disciplina: cada vez que acuerdan un cambio, redactan una enmienda que se integra al contrato, y ambas partes la firman en el mismo acto en que acuerdan el cambio —no "después", no "cuando haya tiempo"—. La enmienda queda en el mismo expediente que el contrato, numerada, versionada. En cualquier momento, el contrato vigente es el original más todas sus enmiendas firmadas, y no hay ambigüedad: si un cambio no está firmado e integrado, no es vigente. El cambio y su registro ocurren juntos, ante las mismas dos firmas, en el mismo expediente. Un año después, el contrato dice exactamente lo que las partes acordaron, porque cada acuerdo se integró en el momento y pasó por las dos firmas.
Aquí está docs-as-code: el cambio al sistema y el cambio a su documentación ocurren en el mismo acto, en el mismo expediente, ante la misma revisión. El PR es el "acto": el cambio al código de payments y el cambio a su doc viajan en el mismo PR, y el revisor —las "dos firmas"— aprueba las dos cosas juntas o ninguna. El repo es el "expediente": la doc vive ahí, versionada, junto al código, no en una bandeja de correos suelta (la wiki). Y el validador en CI es la regla notarial que rechaza una enmienda mal hecha: si la doc referencia algo que ya no existe, el "acto" no se cierra —el build falla— hasta que se corrija. La carpeta de correos sueltos es la wiki de la lección 2: cambios reales que nunca se integraron al documento oficial, hasta que el documento oficial ya no dice la verdad. Docs-as-code es la enmienda firmada: el documento siempre dice lo que el sistema hace, porque cambiarlos es el mismo acto revisado.
Ejemplo trabajado: el validador que rompe el build
Vamos a construir la pieza que hace de docs-as-code una garantía y no un buen deseo: el validador de doc desincronizada, el equivalente a un test que corre en CI. La idea es simple y poderosa: la fuente de verdad es el código —el conjunto de módulos que de verdad existen—; la documentación afirma cosas sobre esos módulos (un ADR habla de ciertos módulos, un diagrama C4 dibuja ciertas cajas, el README menciona ciertas piezas). El validador cruza lo que la doc afirma contra lo que el código tiene, y detecta dos tipos de desincronización: referencias rotas (la doc apunta a un módulo que ya no existe —se renombró o se borró—) y módulos sin documentar (el código tiene un módulo que ninguna doc menciona).
En Mercado, el código tiene seis módulos. Y hay dos desincronizaciones plantadas que un equipo real acumula sin darse cuenta: un ADR viejo habla de billing, que se renombró a payments hace tiempo; y un diagrama C4 dibuja notifications, un módulo que se borró. Además, platform existe en el código pero ninguna doc lo menciona. El validador los caza:
# Docs-as-code: la doc vive en el REPO, junto al codigo, y se revisa en los PRs.
# Eso permite VALIDARLA en CI, como al codigo. Aqui un validador que detecta doc
# DESINCRONIZADA: un ADR o un diagrama C4 que referencia un modulo que ya no existe
# (se renombro o se borro), y modulos del codigo que nadie documento.
# Estado real del codigo hoy (la fuente de verdad):
CODE_MODULES = {"catalog", "orders", "payments", "shipping", "platform", "search"}
# Lo que la documentacion AFIRMA que existe (referencias en ADRs y diagramas):
DOC_REFERENCES = {
"ADR-014": {"orders", "billing"}, # 'billing' se renombro a 'payments'
"ADR-021": {"catalog", "search"},
"C4-container": {"catalog", "orders", "payments", "shipping", "notifications"},
"README": {"catalog", "orders", "payments"}, # 'notifications' no existe
}
# 1) Referencias rotas: la doc apunta a modulos que el codigo ya no tiene.
print("== Referencias rotas (doc -> modulo inexistente) ==")
broken = 0
for doc, refs in DOC_REFERENCES.items():
for mod in sorted(refs - CODE_MODULES):
broken += 1
print(f" {doc}: referencia '{mod}', que no existe en el codigo")
print(f" total de referencias rotas: {broken}")
print()
# 2) Modulos sin documentar: el codigo los tiene, ninguna doc los menciona.
documented = set().union(*DOC_REFERENCES.values())
undocumented = CODE_MODULES - documented
print("== Modulos sin documentar (codigo -> sin doc) ==")
for mod in sorted(undocumented):
print(f" '{mod}' existe en el codigo y ninguna doc lo menciona")
print(f" total sin documentar: {len(undocumented)}")
print()
exit_code = 0 if (broken == 0 and not undocumented) else 1
print(f"CI: {'PASA' if exit_code == 0 else 'FALLA'} (exit {exit_code})")
print("Docs-as-code convierte 'la doc se pudrio' en un test que ROMPE el build.")
Qué esperar. Al correr el archivo, la salida es exactamente esta:
== Referencias rotas (doc -> modulo inexistente) ==
ADR-014: referencia 'billing', que no existe en el codigo
C4-container: referencia 'notifications', que no existe en el codigo
total de referencias rotas: 2
== Modulos sin documentar (codigo -> sin doc) ==
'platform' existe en el codigo y ninguna doc lo menciona
total sin documentar: 1
CI: FALLA (exit 1)
Docs-as-code convierte 'la doc se pudrio' en un test que ROMPE el build.
Lee la salida como lo que es: la salida de un test, roja, en un PR.
Las dos referencias rotas son doc que miente. El validador encontró que ADR-014 habla de un módulo billing que ya no existe —se renombró a payments hace tiempo, pero el ADR viejo se quedó con el nombre muerto—, y que el diagrama C4-container dibuja un módulo notifications que se borró. Estas son exactamente las desincronizaciones que en una wiki serían invisibles: nadie audita el ADR viejo, nadie revisa que el diagrama siga cuadrando con el código, así que ahí se quedan, mintiéndole a quien las lea. Un dev nuevo que lea el ADR-014 buscará un módulo billing en el código, no lo encontrará, y perderá media hora confundido antes de descubrir que se llama payments —o peor, creerá que hay un módulo que no está—. El validador convierte esa media hora futura de confusión en un renglón rojo hoy, en el PR.
El módulo sin documentar es un hueco. El validador también detectó que platform existe en el código pero ninguna doc lo menciona —ni un ADR, ni el diagrama, ni el README—. Ese es el otro tipo de desincronización: no doc que miente, sino sistema que nadie describió. platform podría ser justo la pieza que un dev nuevo necesita entender, y no hay ni una línea sobre ella. Detectarlo automáticamente convierte "ups, nunca documentamos platform" —que normalmente se descubre cuando alguien la necesita y no encuentra nada— en un aviso explícito.
Y el corazón: CI: FALLA (exit 1). Esto es lo que cambia todo. El validador no imprime un reporte que alguien leerá algún día; devuelve un exit code distinto de cero, que es el lenguaje universal de "el build falla". En un pipeline de CI, un exit 1 detiene el merge: el PR queda bloqueado, en rojo, hasta que se arregle la desincronización. Piensa en lo que eso significa: es imposible que la doc de Mercado se desincronice sin que alguien lo note, porque el build no deja pasar un cambio que rompa una referencia o deje un módulo sin documentar. La putrefacción silenciosa de la wiki —el residuo que se acumula release tras release hasta el 20% de exactitud de la lección 2— se vuelve imposible, porque cada release tiene que pasar por este semáforo. La doc no se puede pudrir en silencio si su sincronización es un test.
Como flujo, docs-as-code se ve así:
El PR que cambia el codigo cambia tambien su doc, y CI valida las dos:
dev abre PR ─┬─ cambia codigo (renombra billing -> payments)
└─ cambia doc (ADR, C4, README)
│
▼
CI corre los tests ──┬── tests de codigo: pasan
└── VALIDADOR DE DOC: ¿referencias rotas?
│
┌───────────────────────────┴───────────────────────┐
todo verde exit 1: rojo
merge permitido merge BLOQUEADO hasta
(codigo Y doc al dia) arreglar la desincronizacion
Profundización: qué hace docs-as-code, y qué no
El validador del ejemplo es deliberadamente simple —cruza dos conjuntos de nombres— pero encarna la idea entera de docs-as-code, y vale la pena desmenuzar por qué funciona y dónde están sus límites.
Lo que hace docs-as-code, en el fondo, es aplicarle a la documentación las cuatro cosas que ya hacemos con el código y que sabemos que funcionan. Versión: la doc está en git, así que puedes ver quién cambió qué y cuándo, volver a una versión anterior, comparar dos estados —imposible con una wiki donde el historial es un lío—. Texto plano: la doc en Markdown y los diagramas en PlantUML/Mermaid se comparan línea por línea en el PR, así que un revisor ve exactamente qué cambió en la doc, no un blob binario ni una página que se sobrescribió. Review: la doc pasa por la misma aprobación que el código, así que un cambio a la doc lo revisa otra persona —y un cambio al código que debería tocar la doc y no la toca es visible en el PR—. Y validación: la doc se testea en CI, así que su corrección no depende de que alguien la audite a mano. Ninguna de estas cuatro es sobre "escribir mejor"; todas son sobre poner la doc dentro del mismo sistema de garantías que el código, donde la calidad no depende de la disciplina individual sino de la maquinaria.
El punto más sutil es el de la revisión en el mismo PR, porque ataca la causa raíz de la putrefacción. En la lección 2 vimos que la wiki se pudre porque actualizarla es un acto aparte que se pospone. Docs-as-code elimina el "aparte": como la doc de payments vive en el repo junto al código de payments, el PR que cambia payments naturalmente incluye su doc, y si no la incluye, el revisor lo nota —"cambiaste el comportamiento de payments pero no tocaste su ADR, ¿sigue vigente?"—. La proximidad no solo hace posible actualizar la doc en el momento; hace visible cuando no se actualizó. Esa visibilidad es lo que convierte la buena intención en costumbre: no es que la gente sea más disciplinada, es que el sistema hace evidente el hueco.
Ahora, los límites honestos, porque docs-as-code no es magia. El validador solo puede verificar lo que es mecánicamente comprobable. Puede verificar que un ADR no referencie un módulo inexistente, que un diagrama no dibuje una caja borrada, que cada módulo del código tenga alguna doc, que los links no estén rotos, que los ejemplos de código en la doc compilen. Lo que no puede verificar es si el contenido es correcto en su juicio: no puede saber si el ADR explica bien el porqué, si el diagrama está al nivel correcto para su audiencia, si la decisión que documenta sigue siendo sensata. Eso lo verifica el review humano —la otra pata de docs-as-code—, no el validador. La división es clara: el validador (CI) atrapa la desincronización mecánica (referencias, links, existencia); el revisor (humano) juzga la calidad (claridad, nivel, vigencia). Docs-as-code necesita las dos; el validador no reemplaza al revisor, le quita de encima el trabajo aburrido y mecánico para que se concentre en el juicio.
Y un matiz sobre qué validar, que conecta con lecciones futuras. El validador es más valioso cuanto más estable es lo que verifica. Verificar que los nombres de módulos en los ADRs existan es valioso porque los nombres de módulos cambian poco y una referencia rota es un error claro. Intentar validar mecánicamente cosas muy volátiles —que la doc liste exactamente los mismos endpoints que el código en cada momento— es posible pero a menudo ruidoso, y ahí la mejor respuesta no es validar la doc escrita a mano sino generarla desde el código (living documentation, lección 2) para que no pueda desincronizarse. La regla: valida a mano lo estable (referencias, existencia, estructura), genera lo volátil. Esto anticipa la lección 5 —documentar lo estable, no lo volátil—: docs-as-code funciona mejor sobre doc estable, que es justo la que vale la pena mantener a mano.
Errores comunes
La wiki "oficial" fuera del repo (el peor de todos, y el más común). Qué pasa: el equipo mantiene la doc en Confluence/Notion/Docs "porque es más lindo para escribir y compartir", y el código en el repo. Las dos viven separadas, así que no hay forma de revisarlas juntas ni de validar una contra la otra, y la doc se pudre exactamente como en la lección 2. Por qué pasa: las herramientas de wiki son más cómodas para escribir (editor visual, comentarios, compartir un link), y esa comodidad de escritura oculta el costo enorme de la desincronización. Cómo detectarlo: si tu doc no está en el mismo repo que el código, no puedes hacer docs-as-code, punto —la separación imposibilita el review conjunto y la validación—. Cómo corregirlo: mover la doc de arquitectura que debe sobrevivir (ADRs, diagramas, README, la doc de límites) al repo, en Markdown y PlantUML/Mermaid; dejar la wiki, si acaso, para lo efímero (notas de reunión, borradores) que no pretende sobrevivir.
Poner la doc en el repo pero no validarla (docs-as-code a medias). Qué pasa: el equipo mueve la doc al repo —bien— pero no añade ningún validador en CI, así que la doc puede desincronizarse igual, solo que ahora en el repo. Se gana la versión y el review, pero se pierde la garantía automática. Por qué pasa: escribir el validador cuesta un rato y parece opcional ("total, el review humano lo atrapa"). Cómo detectarlo: si tu doc está en el repo pero nada en CI verifica su sincronización, tienes docs-as-code sin la "code": texto plano versionado que aún depende de que un humano note cada desincronización. Cómo corregirlo: añadir validadores para lo mecánico —referencias a módulos, links, existencia de doc por módulo, ejemplos que compilen—; empezar con uno simple (como el del ejemplo) y crecer. La validación es lo que convierte la disciplina en garantía; sin ella, docs-as-code es solo "docs cerca del código", que ayuda pero no garantiza.
Validar de más y ahogar en ruido. Qué pasa: el equipo, entusiasmado, escribe validadores tan estrictos que fallan por cualquier cosa —cada vez que la doc y el código difieren en un detalle volátil—, y el build empieza a fallar tanto por doc que la gente desactiva el validador o lo ignora. Por qué pasa: se intenta validar mecánicamente cosas volátiles que cambian todo el tiempo, generando falsos positivos constantes. Cómo detectarlo: si el validador de doc falla seguido por cosas que no importan, o si la gente lo saltea con --skip, se volvió ruido. Cómo corregirlo: validar solo lo estable y claramente comprobable (referencias a módulos, links rotos, doc faltante por módulo), y para lo volátil generar la doc desde el código en vez de validar la escrita a mano. Un validador debe fallar solo cuando hay una desincronización real que importa; si falla por ruido, pierde su poder —la gente aprende a ignorar el rojo, y entonces no atrapa ni las desincronizaciones reales—.
Ejercicios
Ejercicio 1 — Por qué el exit code lo cambia todo. El validador del ejemplo termina con CI: FALLA (exit 1). Un ingeniero dice: "podríamos hacer lo mismo con un reporte semanal que liste las desincronizaciones y lo mandamos por correo; ¿para qué romper el build?". Explica por qué el exit 1 que rompe el build es cualitativamente distinto —y más efectivo— que un reporte que alguien leerá.
Ver solución
El exit 1 que rompe el build es cualitativamente distinto porque bloquea el merge en el momento y en el lugar donde se introdujo el problema, mientras que un reporte semanal solo informa de un problema que ya ocurrió y que alguien tendrá que arreglar después —si es que alguien lee el reporte y decide priorizarlo—. Con el reporte, la desincronización entra al repo, vive ahí una semana (o para siempre, si nadie actúa sobre el reporte), y se acumula con las demás; es exactamente el mecanismo de la wiki que se pudre, solo que con un correo semanal que nadie lee. Con el build roto, la desincronización no puede entrar: el PR que la introdujo queda bloqueado hasta arreglarla, así que el problema se corrige cuando es más barato —en el contexto del cambio que lo causó, por la persona que lo causó, que tiene todo fresco en la cabeza—.
Hay una diferencia de incentivos también. Un reporte semanal crea una tarea aparte, sin dueño claro, que compite con todo lo demás y casi siempre pierde ("ya lo arreglo la semana que viene"). Un build roto crea una barrera concreta para esta persona ahora: no puede hacer merge hasta arreglarlo, así que lo arregla. El reporte depende de la disciplina y la priorización colectiva (que falla); el build roto no depende de nadie —es una compuerta mecánica—. Es la misma lección de docs-as-code entera: no confíes en que alguien se acuerde o priorice; pon la garantía en la maquinaria. Un reporte es información; un build roto es una garantía.
Ejercicio 2 — Los dos tipos de desincronización. El validador detecta dos cosas distintas: referencias rotas (doc que apunta a un módulo inexistente) y módulos sin documentar (código sin doc). Para cada uno, explica qué daño concreto causa a un dev nuevo de Mercado si no se detecta, y por qué los dos son formas de que la doc "no sobreviva".
Ver solución
Referencia rota (doc que apunta a algo inexistente). El daño concreto: un dev nuevo lee el ADR-014, que habla de un módulo billing, y lo busca en el código. No lo encuentra —porque se renombró a payments—. En el mejor caso pierde tiempo confundido hasta que alguien le explica que billing es el viejo nombre de payments; en el peor caso concluye que hay un módulo que en realidad no existe, o desconfía de todo el ADR ("si esto está mal, ¿qué más estará mal?") y deja de usarlo. Es doc que miente: dice que algo existe cuando no, y manda al lector por un camino falso. Es una forma de no sobrevivir porque la doc quedó atrás del código —el código evolucionó (renombró), la doc se quedó con el nombre muerto—.
Módulo sin documentar (código sin doc). El daño concreto: el dev nuevo necesita entender platform —quizás es donde tiene que hacer su primer cambio— y no encuentra ni una línea: ni un ADR que explique por qué existe, ni una caja en el diagrama, ni una mención en el README. Tiene que reconstruir el propósito y los límites de platform leyendo el código a ciegas, o preguntándole a quien sepa (bajando el bus factor a depender de esa persona). Es doc que falta: el sistema tiene una pieza que nadie describió. Es una forma de no sobrevivir porque el conocimiento de esa pieza nunca se capturó —vive solo en cabezas, y cuando esas cabezas se van, se va con ellas—.
Los dos son caras de la misma moneda: la doc y el código tienen que corresponderse. La referencia rota es doc que sobra (apunta a algo que ya no está); el módulo sin documentar es doc que falta (algo que está no tiene doc). El validador exige la correspondencia en las dos direcciones —nada en la doc sin respaldo en el código, nada en el código sin mención en la doc— y así garantiza que la doc siga siendo un mapa fiel del territorio, que es lo que la hace sobrevivir.
Ejercicio 3 — Qué valida CI y qué valida el humano. El texto insiste en que el validador atrapa la desincronización mecánica y el revisor humano juzga la calidad. Clasifica cada una de estas cinco verificaciones en "la hace el validador de CI" o "la hace el revisor humano", y explica el criterio: (a) el ADR-014 referencia un módulo que no existe; (b) el ADR explica de forma clara y convincente por qué se tomó la decisión; (c) los links del README no están rotos; (d) el diagrama C4 está al nivel correcto para su audiencia; (e) cada módulo del código tiene al menos un documento que lo menciona.
Ver solución
- (a) Referencia a módulo inexistente → validador de CI. Es mecánicamente comprobable: se cruza el conjunto de referencias contra el conjunto de módulos del código. No requiere juicio; es verdadero o falso. Lo hace la máquina.
- (b) El ADR explica de forma clara y convincente el porqué → revisor humano. Requiere juicio: "claro" y "convincente" no son comprobables mecánicamente; una máquina puede verificar que el ADR tiene una sección de contexto, pero no si esa sección convence. Lo juzga una persona en el review.
- (c) Links del README no rotos → validador de CI. Mecánicamente comprobable: se intenta resolver cada link y se verifica que exista. Lo hace la máquina.
- (d) El diagrama C4 está al nivel correcto para su audiencia → revisor humano. Requiere juicio sobre la audiencia y el nivel de abstracción —justo lo que se enseñó en el módulo 3—; una máquina puede contar cajas (y avisar si son demasiadas, higiene mecánica), pero no puede juzgar si el Container es el nivel correcto para el VP. Lo juzga una persona.
- (e) Cada módulo del código tiene doc que lo menciona → validador de CI. Mecánicamente comprobable: se cruza el conjunto de módulos contra el conjunto de módulos documentados y se reportan los huecos. Lo hace la máquina.
El criterio: el validador de CI hace todo lo que es una comprobación objetiva de correspondencia —existencia, referencias, links, cobertura— sin necesidad de juicio; el revisor humano hace todo lo que requiere juicio sobre la calidad—claridad, nivel, vigencia, si la decisión sigue siendo sensata—. Docs-as-code necesita los dos: el validador le quita al humano el trabajo mecánico y aburrido (que la máquina hace mejor y sin cansarse), para que el humano gaste su atención en lo único que la máquina no puede hacer —juzgar si la doc, además de estar sincronizada, es buena—. Poner el juicio en la máquina la ahogaría en falsos positivos; poner lo mecánico en el humano lo cansaría hasta que dejara de mirar. Cada quien lo suyo.
Resumen y siguiente paso
En esta lección convertiste el principio de la lección 2 —la proximidad mantiene viva la doc— en una práctica concreta: docs-as-code. La doc vive en el repo, en texto plano (Markdown, PlantUML/Mermaid), pasa por review en los mismos PRs que el código, y —lo decisivo— se valida en CI. Viste, con la enmienda firmada en el mismo acto contra la carpeta de correos sueltos, que el punto es que el cambio al sistema y el cambio a su doc ocurran en el mismo acto revisado, en el mismo expediente. Y lo ejecutaste: un validador que cruza lo que la doc afirma contra lo que el código tiene, detecta las referencias rotas (billing renombrado, notifications borrado) y los módulos sin documentar (platform), y devuelve exit 1 —rompe el build—. Con eso, "la doc se pudrió" deja de ser un problema invisible que se descubre meses después y se convierte en un test rojo en el PR. Entendiste también los límites: el validador atrapa la desincronización mecánica, el revisor humano juzga la calidad, y para lo volátil es mejor generar que validar.
Antes de avanzar deberías poder: nombrar las cuatro patas de docs-as-code (repo, texto plano, review en PR, validación en CI); explicar por qué el exit 1 que rompe el build es más efectivo que un reporte; y clasificar qué verifica la máquina y qué el humano.
La lección 4 sube un nivel: ya sabes dónde poner la doc (en el repo) y cómo mantenerla sincronizada (docs-as-code); ahora vemos qué piezas componen una documentación de arquitectura completa, y cómo se ensamblan en un sistema. Vas a ver el combo C4 + ADR + arc42 —el diagrama que muestra la estructura, el ADR que guarda el porqué, y arc42 como el esqueleto que los organiza y cubre lo que falta— y a medir por qué ninguna pieza sola alcanza: cada una responde solo una fracción de las preguntas que un dev nuevo o un auditor hacen, y solo el combo las responde todas. La doc que sobrevive no es un artefacto; es un sistema, y la próxima lección lo arma.
Recursos
- Write the Docs — "Docs as Code" — la referencia canónica de la práctica: doc en el repo, en texto plano, revisada en PRs, construida y validada con las mismas herramientas que el código. La base de esta lección. En inglés.
- Cyrille Martraire, Living Documentation (Addison-Wesley, 2019), caps. sobre automated documentation — el paso de "doc cerca del código" a "doc validada y generada desde el código", que es el corazón del validador de esta lección. En inglés.
- Michael Nygard — "Documenting Architecture Decisions" y adr.github.io — los ADRs como archivos de texto plano en el repo, versionados con el código: el ejemplo por excelencia de docs-as-code aplicado a las decisiones. Su mecánica es la guía hermana
architecture-decisions. En inglés. - PlantUML y Mermaid — herramientas para escribir diagramas como texto plano (que se versiona y se compara en PRs), en vez de imágenes binarias que no se pueden diffear. Lo que hace diffeable un diagrama C4. En inglés.
- Andrew Hunt y David Thomas, The Pragmatic Programmer, 20th Anniversary Edition (Addison-Wesley, 2019), temas sobre automatización y "Don't Repeat Yourself" — por qué toda verificación que dependa de la memoria humana termina fallando, y la solución es ponerla en la maquinaria. En inglés.