Desarrollo spec-first: acordad la intención antes de que la IA escriba el código
Cuando el código sale barato, el cuello de botella es la intención. Un flujo práctico guiado por especificaciones con OpenSpec, escenarios para revisar antes de programar y consejos para implantarlo en un equipo.
Durante treinta años, lo escaso era el código. Los agentes de programación con IA lo han abaratado, y eso desplaza el cuello de botella hacia algo más difícil de comprar: saber exactamente qué querías construir. Aquí va el cambio de mentalidad, un flujo de trabajo que aguanta el uso diario y la parte humana de conseguir que un equipo lo adopte.
Todos estaban adivinando
Un fallo conocido suele ir así. Sale un cambio, y solo en la revisión, o peor, en producción, el equipo se da cuenta de que el resultado no es lo que nadie pretendía. Los requisitos estaban repartidos entre un hilo de chat, un comentario en un ticket y la cabeza de unas cuantas personas, y cada fuente decía algo ligeramente distinto.
En concreto, alguien coge una tarea cuyos requisitos son:
- el título de un ticket en una línea,
- un hilo de Slack que se quedó en nada,
- y una suposición que todos creían compartida, pero no lo era.
Lo construye. La revisión pilla parte del desajuste y deja pasar el resto, porque quien revisa solo ve un diff y tiene que ir del código hacia atrás hasta una suposición sobre lo que se quería. Es justo la dirección equivocada. Tras el lanzamiento, el único registro de lo que debe hacer la funcionalidad es el código, más lo que el equipo todavía recuerde.
Ese último punto es el que hace el daño silencioso. El contexto se evapora en cuanto termina la conversación. Medio año después nadie, ni persona ni agente, sabe decir cuál debía ser el comportamiento, solo lo que el código hace por casualidad.
Por qué los agentes cambian las cuentas
Los agentes dieron la vuelta a la economía de la noche a la mañana. Durante décadas escribir código fue el paso caro y cuidadoso, y todos los procesos se construyeron a su alrededor. Un agente, en cambio, es un adivino rápido y seguro de sí mismo. Dale un prompt vago y en segundos te devuelve código plausible, bien estructurado y completamente equivocado. Generar ahora es casi gratis. Decidir qué es correcto es todo el trabajo.
Así que el artefacto duradero y escaso pasa a ser una declaración precisa y compartida de la intención: una especificación. No como papeleo, sino como aquello en lo que las personas se ponen de acuerdo y el contexto que les das a los agentes. El experimento, entonces, es escribir primero la especificación, acordarla y que personas y agentes construyan a partir de ella.
Qué significa el desarrollo guiado por especificaciones
La idea: antes de implementar un cambio, plasma su comportamiento previsto en una especificación estructurada que otros puedan revisar, y consigue que haya acuerdo. Después, la especificación vive en el repositorio junto al código y deja constancia de qué hace el sistema y por qué.
Enseguida surgen tres objeciones, así que esto es lo que no es:
- No es cascada. Una especificación solo tiene que ser lo bastante buena para empezar, y la vas editando a medida que aprendes. Piensa en un documento vivo, no en una carpeta de requisitos firmada.
- No es pesado. A los cambios pequeños les basta un delta de especificación de diez líneas dentro de un único pull request. El esfuerzo solo crece cuando crece el cambio.
- No es un documento de diseño. Los documentos de diseño argumentan por qué se eligió un enfoque, mientras que una especificación describe lo que el sistema hace hoy. Esa frontera tiene su propia sección más abajo.
La recompensa es sencilla: fija primero el objetivo, luego dedica el esfuerzo a acertarlo y conserva ese acuerdo cuando el chat ya esté olvidado.
Tu descripción del puesto cambia
Todo lo demás se apoya en un único cambio de mentalidad. Tu responsabilidad principal ahora es escribir buenas especificaciones, revisarlas y editar código a mano solo en los casos en los que la IA no consigue hacerlo bien.
Eso invierte aquello para lo que se formó la mayoría de los desarrolladores. Antes el trabajo era escribir código. Ahora es lo que menos haces. Tu trabajo real, por orden de importancia, empieza por la especificación y su revisión, y solo después llega el código escrito a mano.
Seis principios que vale la pena repetir
Cuando alguien pregunta cuánta especificación es suficiente, salen siempre las mismas respuestas:
- Acordar primero. Escribe o actualiza la especificación, consigue una revisión rápida y solo entonces implementa.
- Mantener las especificaciones junto al código. Están en el repositorio, se revisan en el mismo cambio y pertenecen a quienes son dueños de ese código.
- Mejor deltas pequeños que grandes reescrituras. Cada cambio indica qué se añade, qué cambia o qué se elimina en lugar de volver a contar el mundo entero.
- Escribir el comportamiento como escenarios verificables. Donde algo se pueda probar, usa given/when/then en lugar de prosa.
- Mantenerse flexible. Si la realidad se aleja de la especificación, actualiza la especificación en vez de dejar que se pudra.
- Dar a cada capacidad una única fuente de verdad, un único lugar donde vive su comportamiento actual.
El ciclo diario
El enfoque no depende de herramientas. Bastan archivos Markdown normales en una carpeta specs/. Aun así, un poco de tooling reduce la fricción, y OpenSpec es un flujo de especificaciones de código abierto que se conecta a los agentes de programación con IA y ofrece comandos slash que encajan con el ciclo:
- Explorar, opcional. Cuando la forma de un cambio no está clara, deja que el agente lea el código, sopese opciones y esboce un plan antes de comprometerte.
- Proponer. Da una descripción de una línea y la herramienta genera una propuesta, una breve nota de diseño, una lista de tareas y un delta de especificación, la pieza que más importa porque muestra cómo cambiará la especificación viva.
- Revisar primero la especificación. Aquí está todo el juego. La propuesta y el delta se revisan antes de que exista código, porque cambiar una frase sale barato y cambiar una implementación ya desplegada no.
- Aplicar. Construye según la especificación acordada, tú mismo o con un agente.
- Verificar. Ejecuta las comprobaciones, idealmente con escenarios de aceptación que se traducen directamente en tests.
- Archivar. Integra el delta en la especificación viva para que siempre describa el presente, y pasa la propuesta al historial.
Si solo te quedas con un paso, que sea el tercero: revisar la especificación antes que el código.
Configurar OpenSpec con un agente de programación
Los agentes actuales, como Claude Code, pueden aprender este flujo y llevarlo contigo, así que no tienes que ir narrando cada movimiento. OpenSpec empaqueta ese conocimiento como skills del agente y comandos slash. Dos comandos lo conectan a tu repositorio y a tu agente:
# install the CLI (drives everything below)
npm install -g @fission-ai/openspec@latest
# scaffold the spec structure AND generate agent skills + slash commands
openspec init --tools claude
El paso init hace dos cosas. Primero, crea el sitio para las especificaciones: una carpeta specs/ para las especificaciones vivas, una carpeta changes/ para las propuestas en curso y una pequeña configuración donde anotas tu stack y tus convenciones. Segundo, instala las skills del agente. Para Claude eso significa archivos de skills más los comandos /opsx:*, en concreto explore, propose, apply, archive y sync. Las skills enseñan al agente a redactar una propuesta, generar un delta de especificación, implementar a partir de él e integrar el resultado de vuelta en la especificación viva.
Cómo es un cambio
Imagina un job en segundo plano que necesita un timeout configurable. Un job que supere su límite debe cancelarse y marcarse como timed_out.
Empieza su vida como un delta de especificación, es decir, un diff contra la especificación viva que muestra con precisión qué se va a mover:
### Requirement: Job timeout
- The system SHALL run a job to completion.
+ The system SHALL cancel a job that exceeds a configurable timeout
+ (default 30s) and record the outcome as `timed_out`.+ #### Scenario: Job exceeds the configured timeout
+ - GIVEN a job configured with a 5s timeout
+ - WHEN the job has run for 5s without completing
+ - THEN the system cancels the job
+ - AND sets its status to `timed_out`
+ - AND emits a `JobTimedOut` event with the job id
Ese diff es lo que revisa la gente, antes de que exista ninguna implementación. Un compañero puede cuestionar el valor por defecto, el nombre del estado o el evento mientras todavía es solo una frase. Cuando todos están de acuerdo, la construcción tiene un objetivo inequívoco y el escenario se convierte en un test.
Una vez desplegado, el archivado integra ese requisito en la especificación viva como una afirmación simple de cómo se comporta el sistema ahora, sin marcas de más o menos sobrantes. Quien toque este código después, persona o agente, lo lee y no tiene que adivinar.
Especificación o documento de diseño
La gente los confunde, y eso provoca duplicación y lío. Una división que ha funcionado:
- Un documento de diseño explica una decisión: por qué este enfoque, cuáles fueron los compromisos. Es una foto de un momento y se espera que se quede desfasado, porque es un registro histórico.
- Una especificación describe el comportamiento actual, es decir, lo que el sistema hace ahora mismo. Está viva y nunca debe quedarse desfasada, porque funciona como contrato.
En la práctica, explora opciones y toma la decisión en un documento de diseño, recoge el comportamiento duradero en la especificación y enlaza ambos en lugar de duplicar. Si el mismo comportamiento se mantiene en los dos sitios, reduce el documento de diseño a un enlace.
Implantarlo en un equipo
Ayuda una lista breve. Para tu próximo cambio: descríbelo y genera la propuesta y el delta de especificación, manda la especificación a revisión antes de escribir código, implementa y haz pasar los escenarios una vez aprobada, y luego archiva para que la especificación viva coincida con la realidad.
Para el equipo: confirma que los repositorios tienen el tooling configurado, añade una nota corta de contexto con el stack y las convenciones para que los agentes escriban mejores especificaciones, y especifica primero tus dos o tres capacidades principales.
No intentes especificar de entrada todo el sistema existente. Escribe especificaciones a medida que tocas cosas, y la cobertura crecerá donde ocurre el trabajo.
Pruébalo en el próximo cambio
No hace falta una gran iniciativa ni una orden de arriba. En tu próximo cambio no trivial, escribe antes de programar lo que debe hacer en forma de unos cuantos escenarios given/when/then. Pide a un compañero que mire esos escenarios antes que nada. Después constrúyelo, haz pasar los escenarios y sube la especificación junto con el código.
Eso es todo. Hazlo unas cuantas veces, deja que tus pull requests mejoren sin hacer ruido, y tu equipo empezará a preguntarte dónde está la especificación.
Durante décadas, el código se trató como la última palabra sobre el comportamiento, ya que una persona había escrito y entendido cada línea. Eso ya no es así. El código generado es barato y desechable, y el artefacto duradero, propiedad de las personas, es la especificación. Los equipos que lo asimilen sacarán más que los que siguen revisando diffs con la esperanza de que la intención haya sobrevivido. Acordad qué vais a construir antes de construirlo. En este nuevo paradigma eso no es burocracia. Es el trabajo.