Capítulo 09 de 10 · 10 min de lectura
Cambiar requisitos sin romper nada
Un requisito nuevo no se añade al código. Se añade a la spec, y desde ahí se ve, antes de tocar nada, qué tests y qué ficheros va a arrastrar.
El cambio empieza en la spec
acorta nació sin autenticación a propósito. Fue la cuarta pregunta de la entrevista del capítulo 3, y la spec lo dejó escrito en «Fuera de la v1»: será la primera ampliación tras la v1, como spec nueva. Este capítulo es esa ampliación, hecha el 3 de octubre de 2026 con el mismo método que todo lo demás, y es el único de los diez que cambia un proyecto que ya funciona.
El encargo fue una palabra: «Autenticación». Y como manda la regla 10, antes de escribir nada hubo cuatro preguntas con opciones y recomendación:
| # | Pregunta | Respuesta |
|---|---|---|
| 1 | ¿Qué operaciones pasan a exigir autenticación? | Crear y borrar. Listar y redirigir, públicos |
| 2 | ¿Qué forma tiene la credencial? | Un token de API único, configurado al arrancar el servidor |
| 3 | ¿Qué pasa si el servidor arranca sin token? | Se niega a arrancar |
| 4 | ¿Cómo se autentica la interfaz web? | Pide el token una vez y lo guarda en el navegador |
Con las respuestas se escribió la spec 008: trece criterios, AUT-01 a AUT-13, repartidos entre la API, la CLI y la web, y una lista de trece decisiones tomadas por defecto para revisar. Y se tocaron cinco specs que ya existían, en total treinta y tres líneas: el contrato de Handler gana un parámetro, la sinopsis de serve gana un flag, WEB-04 lista el 401, la autenticación deja de estar fuera, y la tabla de fases gana tres filas.
Todo eso antes de una sola línea de código. No es un trámite: es el momento en que el cambio se puede leer entero y decidir si es el que se quería.
Qué arrastra una frase
Con la spec escrita, la pregunta «¿qué toca este cambio?» tiene respuesta antes de tocarlo. Esta es la demo: la spec del cambio a la izquierda, y lo que cada frase ilumina a la derecha, calculado sobre el repositorio real entre el commit anterior al cambio y el que lo cierra.
- 13criterios nuevos
- 82tests nuevos
- 22ficheros tocados
- 11commits
La spec: pulsa una frase
Spec 008, nueva
Specs que ya existían
AUT-01POST /api/links sin cabecera Authorization responde 401 con {"errors":["falta el token de API"]} y la cabecera WWW-Authenticate: Bearer. No se crea nada.
Tests que lo nombran (1)
- serverTestAUT01_CrearSinToken
Ficheros tocados por el cambio (8 de 22 se iluminan)
- testcmd/acorta/auth_test.go+304
−0 - códigocmd/acorta/main.go+29
−3 - testcmd/acorta/main_test.go+22
−1 - códigoserver/api.go+5
−1 - testserver/api_test.go+1
−1 - códigoserver/auth.go+37
−0 - testserver/auth_test.go+259
−0 - testserver/helpers_test.go+8
−12 - códigoserver/respond.go+7
−0 - códigoserver/server.go+6
−3 - testserver/static_test.go+1
−1 - specspecs/000-especificacion.md+1
−1 - specspecs/004-api.md+6
−5 - specspecs/005-cli.md+3
−2 - specspecs/006-web.md+5
−4 - specspecs/007-fases.md+5
−1 - specspecs/008-autenticacion.md+65
−0 - testweb/src/App.test.js+247
−3 - códigoweb/src/App.vue+16
−3 - códigoweb/src/api.js+41
−8 - códigoweb/src/components/LinkForm.vue+3
−1 - códigoweb/src/components/TokenField.vue+52
−0
Dónde fueron las líneas
Sin tocar: linkstoreshortener. Bitácora aparte: +618 líneas, los encargos y los informes tal cual.
Datos de acorta entre los commits 15125e2 y 2f95878: los tests son los que existen después y no antes.
Tres cosas que mirar:
- Cada criterio nuevo ilumina sus tests y los ficheros de su paquete.
AUT-05, el que dice que el token se comprueba antes de leer el cuerpo, tiene cuatro tests enservery no toca nada fuera deserver/. Los trece criterios juntos iluminan los 82 tests nuevos: no hay ninguno que no nazca de una frase de la spec. - Las frases de las specs viejas también arrastran. El parámetro nuevo de
Handlertoca cinco ficheros, tres de ellos tests que solo tuvieron que cambiar la llamada. La autenticación «fuera de la v1» tachada no toca ninguno: es historia, y conviene que quede escrita. - Lo que no se ilumina nunca.
link,storeyshortenerno cambiaron una línea. Un cambio de requisitos bien acotado en la spec se queda en los paquetes que la spec nombra.
Y la proporción de las barras de abajo: 85 líneas de spec, 842 de tests, 196 de código. El código es la parte pequeña. Lo que un requisito nuevo cuesta de verdad es decidirlo y comprobarlo.
Los tests viejos también cambian
Aquí está la diferencia con añadir una funcionalidad a un proyecto vacío. Un cambio de requisitos contradice tests que ya existen y están en verde, y hay que decidir qué hacer con ellos.
En acorta pasó tres veces, y las tres las avisó el agente del paso rojo antes de que pasara. Los tests de la API creaban enlaces sin cabecera y esperaban 201; en cuanto el servidor comprobase el token, darían 401. Los tests de serve arrancaban sin token. Y la sinopsis de serve que comprobaban los tests de la ayuda era la vieja. El agente del servidor lo dijo así:
Conviene que el encargo del paso verde lo autorice explícitamente, porque la regla 3 de AGENTS.md («no modifiques un test para que pase») podría frenarlo.
Tenía razón en el diagnóstico y no en el remedio. La solución no fue autorizar tocar tests en el verde, sino hacerlo en el rojo: la spec 008 dice ahora que los tests de la spec 004 que crean o borran envían el token correcto, y que solo los de la 008 controlan la cabecera; el ajuste se hizo en el paso rojo, con la spec delante, y el commit en rojo lo lleva. Igual con los de serve y con la sinopsis. Resultado: los tres commits en verde del cambio no tocan un solo fichero de tests, exactamente como los seis de la v1.
La regla, entonces, es esta: cuando un requisito nuevo invalida un test viejo, el test cambia con la spec, en el paso rojo y nombrando el criterio nuevo que lo justifica. Nunca en el verde, que es donde cambiar un test es la trampa del capítulo anterior.
Hubo una cuarta vez, y es la que mejor enseña. Los tests de WEB-04 buscaban «la región aria-live del documento» y daban por hecho que había una sola; con el campo del token encima del formulario, había dos. El agente de la web no tocó el test: dejó la región del token sin persistir, lo anotó en un comentario y lo contó en el informe como un compromiso de accesibilidad. El orquestador corrigió los tres tests en un commit propio, y al hacerlo se equivocó una vez (buscó la región dentro del formulario, y está al lado): lo cazaron los propios tests antes de confirmar.
El rojo volvió a revisar la spec
Entre los tres agentes, el paso rojo dejó quince avisos sobre una spec que ya había pasado una revisión. Doce acabaron escritos en la spec antes de implementar: si la cabecera Authorization se recorta o no (no: Bearer con dos espacios es incorrecto), si un token de solo espacios es «falta el token» o «demasiado corto», si el token se comprueba antes o después de abrir la base de datos, si Enter en el campo del token guarda igual que el botón, si el estado «Token guardado» va en una región aria-live, si WEB-04 debía listar el 401.
Ninguno de los doce lo habría encontrado una lectura. Las encuentra quien tiene que escribir el test y necesita el valor exacto. Es la misma lección del capítulo 2, y con un cambio de requisitos vale el doble, porque los huecos están en las costuras con lo que ya existía.
Lo que no cambió
«Sin romper nada» no es una esperanza: son los 284 tests de la v1, que siguen ahí y siguen en verde. Los de la API envían ahora el token, pero comprueban lo mismo que antes. add, list y rm no cambian porque no pasan por la API, y lo dice la spec. Las rutas públicas no miran la cabecera, y lo vigila un criterio propio, AUT-06, con catorce casos que piden cada ruta sin token, con token bueno y con token malo, y comparan las tres respuestas.
La verificación final repitió la de la v1 con el binario compilado, con curl y con un navegador real: los 401 con su cabecera y su cuerpo, el 405 que sigue ganando al token, serve que se niega a arrancar, y el recorrido entero de la interfaz con el token guardado, borrado y equivocado.
Cuánto costó
Once commits, de las 00:55 a las 01:16 del mismo día: tres de spec, tres en rojo, tres en verde, un arreglo de tests y el cierre. Tres agentes, dos de ellos en paralelo. Y diez encargos con sus diez informes en la bitácora, tal cual.
Lo que viene
Queda una pregunta abierta desde el capítulo 5: un criterio con un test no es un criterio bien probado. El último capítulo rompe el código a propósito para ver si los tests se enteran, y cierra el método con lo que se ejecuta en cada cambio sin que nadie tenga que acordarse.