Saltar al contenido
team banzai

demo técnica · software · legado

Reconstruir la documentación de un software leyendo su código, con examen incluido

Le dimos a un sistema el código fuente de DOOM, cambiamos cuatro cifras a sus espaldas y le pedimos que documentara cómo funciona. Cazó las cuatro: reportó el valor cambiado, con la línea exacta como prueba, mientras la documentación que humanos han escrito de DOOM durante treinta años sigue diciendo lo viejo.

Y para que no te fíes de nuestra palabra, el juego corre aquí mismo, en tu navegador, compilado desde esa misma copia cambiada. Abres una puerta y un cronómetro mide cuánto espera antes de cerrarse: 3 segundos, los que dijo la doc, no los 4,3 de siempre. La prueba deja de leerse y se ejecuta.

Elige un sistema del que dependa tu empresa: el ERP que se instaló en 1998, el programa que calcula las nóminas, el que decide qué pedidos pasan. Funciona. Pero la persona que lo escribió se fue hace años, el manual que hay dentro de un cajón describe una versión de hace tres reformas, y nadie se atreve a tocarlo porque nadie sabe del todo qué hace por dentro. El conocimiento no está perdido: está escrito, línea por línea, en el código. Solo que nadie lo lee.

La capacidad que probamos aquí es esa: reconstruir cómo funciona un sistema a partir del código, no de sus manuales, y demostrar que no se lo inventa. Lo enseñamos con DOOM porque su código es público, está bajo licencia libre y cualquiera puede comprobar lo que decimos. El caso es DOOM; el patrón sirve para tu ERP.

Y como documentar no es una cosa sola, generamos cuatro documentaciones desde la misma lectura del código, cada una en el formato que usa un equipo distinto: la técnica para quien va a mantenerlo, la funcional para el analista de negocio, un backlog ágil con historias de usuario para un equipo Scrum, y un manual llano para quien solo lo usa. Las cuatro están justo debajo del juego, y se pueden abrir y descargar.

El mismo código, corriendo: cronometra el gazapo

No enseñamos el código por un lado y el juego por otro: el motor de aquí abajo está compilado desde el código que documentamos. Arráncalo, abre una puerta con la barra espaciadora y mira el cronómetro de arriba a la derecha. No está pintado: mide el reloj real del motor (35 pasos por segundo) entre que la puerta acaba de abrir y empieza a cerrarse. Cambia entre la copia de siempre y la nuestra con el botón, y verás cambiar la cuenta.

motor GPL · webassembly

DOOM, desde nuestra copia

El motor corre en tu navegador, compilado desde el código con los cuatro cambios. Se descarga solo cuando le des a arrancar (unos 30 MB), nada pesado se carga antes.

copia monitor
150 tics = 4,29 s: lo que dice la Doom Wiki y el código público de id Software para la espera de una puerta normal.
105 tics = 3,00 s: lo que dijo nuestra doc leyendo el código cambiado. El reloj, con esa copia cargada, mide justo eso.
Motor de DOOM de id Software (GPL-2.0), compilado a WebAssembly desde nuestra copia con las cuatro mutaciones. Recursos del juego: Freedoom Phase 1 (licencia BSD). Carga diferida, solo al arrancar. En móvil salen controles táctiles; el teclado va al canvas al tocarlo.

Las cuatro documentaciones: una para cada equipo

Esto es lo que produjo el sistema, y es el objeto de la demo: la misma lectura del código, contada de cuatro formas, cada una en el formato que un equipo distinto ya usa. La técnica para quien mantiene el código, la funcional para negocio y QA, el backlog ágil para un equipo Scrum, y el manual para quien solo juega. La tesis es esa: el mismo conocimiento, en el formato que tu equipo use.

Cada afirmación con número trae su archivo y su línea: pincha cualquiera y abres el código público de id Software en esa línea exacta. Verás el valor de siempre (150, no 105), porque GitHub tiene el código público y aquí documentamos nuestra copia con las cuatro cifras cambiadas. Esa diferencia es justo el experimento, y más abajo te contamos cómo lo montamos.

El ciclo de una puerta, generado leyendo el código a la vista. Cada número lleva su línea y su grado de confianza; no se afirma ningún valor que no esté en una línea leída.

Constantes de tiempo y velocidad

VDOORSPEED = FRACUNIT*3 p_spec.h:364. Con FRACUNIT = 65536, son 3 unidades de mapa por tic para la puerta normal. · confianza alta

VDOORWAIT = 105 tics p_spec.h:365. A 35 tics por segundo doomdef.h:122, son 105/35 = 3,00 segundos de espera arriba. · confianza alta

Nota de método: VDOORWAIT y VDOORSPEED no se comprueban con la Doom Wiki (que puede reflejar otra versión); se comprueban leyendo p_spec.h en este árbol y, si se quiere, cronometrando la puerta en el binario compilado desde este código. Eso es justo lo que hace el cronómetro de arriba.

Estructura de estado: vldoor_t

Definida en p_spec.h:343-360. El campo direction vale 1 (sube), 0 (espera arriba) o -1 (baja); al llegar arriba, una puerta normal pasa a direction = 0 y arranca el contador topcountdown = topwait p_doors.c:182.

Máquina de estados: T_VerticalDoor

El "thinker" que corre una vez por tic p_doors.c:63 ramifica por direction: subiendo mueve el plano hacia el techo p_doors.c:168; esperando decrementa el contador y, al llegar a cero, manda cerrar y suena el cierre p_doors.c:81; bajando, si algo la cruza, se reabre en lugar de aplastar p_doors.c:151.

Constantes fuera de la puerta (parte del examen)

Daño de bala: damage = 7*(P_Random()%3+1) p_pspr.c:633, es decir 7, 14 o 21 por impacto. Cargador: clipammo[am_clip] = 15 p_inter.c:59, un cargador da 15 balas (tope 200).

Puntos seguros de cambio

Quiero cambiar…Toco…Radio de impacto
Espera de la puerta arribaVDOORWAIT p_spec.h:365todas las puertas con topwait = VDOORWAIT
Velocidad de la puertaVDOORSPEED p_spec.h:364puerta normal; las rápidas usan VDOORSPEED*4 y se escalan también
Daño de balamultiplicador en p_pspr.c:633pistola y ametralladora, ambas vía P_GunShot
Balas por cargadorclipammo[0] p_inter.c:59recogida de cargadores y munición inicial

Incertidumbre declarada

Cuánto sube una puerta en unidades absolutas depende de la geometría del nivel, no de una constante: no se puede afirmar una altura fija sin un mapa concreto. Solo la espera arriba (VDOORWAIT) es un tiempo fijo y citable en segundos.

las cuatro documentaciones, en pdf · en el formato que tu equipo ya conoce
Técnica plantilla arc42, el estándar de documentación de arquitectura de software. Para quien lo mantiene. Descargar PDF · 256 KB
Funcional especificación de requisitos ISO/IEC/IEEE 29148 con criterios de aceptación en Gherkin. Para negocio y QA. Descargar PDF · 164 KB
Backlog ágil historias de usuario con criterios Gherkin y prioridad MoSCoW. CSV importable a Jira + PDF. Para un equipo Scrum. Descargar CSV · Jira Descargar PDF · 170 KB
Manual estilo Microsoft Manual of Style, el de los manuales de usuario. Para quien lo usa. Descargar PDF · 104 KB

Cómo lo hacemos: le cambiamos el examen sin avisar

Aquí hay una trampa que resolver antes de empezar: DOOM es probablemente el programa más diseccionado de la historia. Hay libros enteros sobre él, y cualquier IA moderna se lo sabe de memoria. Así que pedirle "documenta DOOM" no prueba nada: te lo recita. La pregunta buena no es si lo conoce, es si documenta el código que tiene delante o recita lo que pone en la Doom Wiki.

Para saberlo, cambiamos cuatro cifras del código a sus espaldas: cuánto espera una puerta antes de cerrarse, a qué velocidad se mueve, cuánto daño hace una bala y cuántas balas trae un cargador. Cuatro números, cambiados en su sitio, sin decírselo. Luego le pedimos que documentara cómo funciona todo eso.

Es el truco del profesor que cambia una cifra del enunciado para ver quién leyó y quién copió del libro. Si dice la cifra nueva, leyó el código. Si dice la del libro, copió. Y lo bonito es que se comprueba solo: cada afirmación de la doc trae su archivo y su línea, y el corrector va a esa línea a ver si el número está ahí.

El resultado, con el truco a la vista: mundo, cambio, doc

Como el público de un mago que sí ve el truco: por cada cifra, tres columnas. Lo que dice el mundo (la Doom Wiki y el código público de id Software), lo que cambiamos nosotros en secreto, y lo que la doc generada acabó diciendo. El ojo salta solo: la doc coincide con lo que cambiamos, no con lo que dice el mundo.

Espera de la puerta arriba p_spec.h:365
mundo150 tics · 4,29 s
cambiamos105 tics · 3,00 s
dijo la doc105 tics · 3,00 s
fiel al código
Velocidad de la puerta p_spec.h:364
mundoFRACUNIT*2 · 2 u/tic
cambiamosFRACUNIT*3 · 3 u/tic
dijo la docFRACUNIT*3 · 3 u/tic
fiel al código
Daño de una bala p_pspr.c:633
mundo5, 10 o 15
cambiamos7, 14 o 21
dijo la doc7, 14 o 21
fiel al código
Balas por cargador p_inter.c:59
mundo10 balas
cambiamos15 balas
dijo la doc15 balas
fiel al código

El código real, con la línea que lo respalda

No hace falta que sepas C. Pincha una afirmación y salta al fichero real de id Software, con la línea exacta que la respalda señalada en ámbar. Es el mismo código público que enlazan las citas: verás ahí el valor de siempre (150, no 105), porque GitHub tiene la copia pública y nosotros documentamos la nuestra cambiada. Esa diferencia es justo el experimento.

linuxdoom-1.10 / p_spec.h p_spec.h:364-365 · ver en GitHub ↗
    int             topwait;
    // (keep in case a door going down is reset)
    // when it reaches 0, start going down
    int             topcountdown;
    
} vldoor_t;



#define VDOORSPEED		FRACUNIT*2
#define VDOORWAIT		150

void
EV_VerticalDoor
( line_t*	line,
  mobj_t*	thing );

Resaltado con Shiki en tiempo de build, sobre el fichero C real. La numeración coincide con la del enlace a GitHub.

las cuentas del corrector salida: evaluacion/resultado.json

4/4

gazapos cazados: reportó el valor cambiado, no el de siempre, en los cuatro

87/87

citas trazables: las 87 referencias archivo:línea de las tres docs apuntan a una línea real

0/4

control negativo: una doc que recita los valores de siempre saca cero, el instrumento sabe suspender

2/3

docs con grados de confianza y sección de incertidumbre (el manual de usuario no la lleva a propósito)

El control negativo es lo que separa una prueba de un truco: le pasamos al corrector una documentación que recita los valores de siempre, y la suspendió en las cuatro. Si el instrumento no supiera dar un cero, aprobar no significaría nada.

Llévatelo: el método, no la palabra

Lo que hemos hecho aquí lo puedes hacer tú con cualquier documentación escrita por una IA. Te dejamos las herramientas: la lista de comprobaciones en llano, el corrector con el que puntuamos, y las cuatro documentaciones ya maquetadas, cada una en el formato estándar de su gremio.

La checklist para auditar doc de IA

Nueve comprobaciones de sentido común, en llano, que convierten "me fío" en "lo miro yo":

  1. Cada afirmación cita su fuente (sin cita, no cuenta).
  2. La fuente sí dice eso (vas y lo compruebas).
  3. Un cambio a escondidas lo caza (el truco del enunciado).
  4. El corrector sabe suspender (si aprueba siempre, no vale).
  5. Declara lo que no sabe · distingue lo fijo de lo variable · separa dato de deducción · habla el idioma de quien lee · se puede reproducir.

El corrector, abierto

El mismo corrige.py que saca las cuentas de esta página: va a cada línea citada, comprueba el número a mano y decide sin criterio propio. Lo publicamos con las mutaciones y el informe reproducible, para que lo corras tú. Es heurístico, no un parser semántico: en los peros están sus dos falsos negativos.

El corrector (repo público)

enlace al repo en cuanto se publique

Los peros

Lo que esta primera versión todavía no prueba.

El modelo conoce DOOM y sabía que se le examinaba. Quien escribió las docs tenía el código cambiado a la vista y además se sabe DOOM. Que reportara los valores nuevos prueba que leyó el código (si hubiera recitado, habría puesto 150), y el corrector lo mide objetivamente. Pero la prueba más fuerte es a ciegas: darle solo el código, sin decirle qué se tocó. Eso es lo siguiente.
Es una parte del código, no el motor entero. Probamos una puerta y tres constantes, no DOOM completo. Suficiente para validar el método; todavía no es "documenta DOOM entero".
El cronómetro mide la copia, no audita el modelo. El reloj de arriba prueba que el binario compilado desde nuestra copia se comporta como dijo la doc (3 s, no 4,3). Es la verificación dinámica que faltaba. Lo que no hace es demostrar que el modelo no supiera ya la respuesta: para eso está el examen a ciegas del primer pero.
El corrector es heurístico, no infalible. Funciona por palabras clave más contexto de contraste, y en su primera versión tuvo dos falsos negativos: contó como "recitó lo viejo" una frase que mencionaba el valor viejo para avisar de que no es ese ("deben ser ~3,0 s, no ~4,3 s"). Se corrigió detectando la negación y se validó con el control negativo, pero un texto rebuscado podría en teoría engañarlo.

¿Y en tu empresa?

Cambia DOOM por lo que te quita el sueño: el ERP que nadie se atreve a migrar, el programa de nóminas que solo entendía quien ya no está, las reglas de negocio enterradas en un procedimiento que nadie ha vuelto a leer. El conocimiento sigue ahí, escrito en el código. Esto lo saca, lo cuenta para quien lo mantiene, para quien decide y para quien lo usa, y deja la línea exacta como prueba de que no se lo ha inventado.

Si esto te suena a un problema tuyo, escríbenos y lo comentamos. Sin rollo: te decimos si se puede o no.

Con qué está hecho. La documentación la escribió un modelo de lenguaje leyendo el código: es la parte que redacta y relaciona. Pero quien decide si aprueba o suspende no es el modelo: es un corrector determinista en Python que va a cada línea citada y comprueba el número a mano, sin criterio propio. El modelo propone; el corrector, que no opina, verifica. Las cuatro mutaciones son parches deterministas sobre el código, reproducibles byte a byte, y las 87 citas se resuelven contra el fichero real. El juego es el motor GPL de id Software compilado a WebAssembly con Emscripten; el cronómetro lee el reloj del propio motor (parche nuestro, publicado con el fork), no lo simula.

Licencias y atribución

Esta demo existe porque id Software liberó el código de DOOM. Gracias.

El motor de DOOM es de id Software, publicado bajo licencia GPL-2.0. El código que mostramos y el que compilamos a WebAssembly salen de github.com/id-Software/DOOM, commit a77dfb9, árbol linuxdoom-1.10, vía el port doomgeneric. Nuestra copia con las cuatro mutaciones y el parche del cronómetro se distribuye también bajo GPL-2.0, como pide esa licencia. Los recursos del juego son Freedoom Phase 1 (licencia BSD). DOOM es una marca de id Software; esto no está avalado por id Software ni por ZeniMax.

¿Puedes usar esto? Nuestros textos y análisis de esta página se publican bajo licencia CC BY 4.0: úsalos citando la fuente, Team Banzai (team-banzai.com). El código de DOOM conserva su licencia GPL-2.0.

← Todas las demos técnicas