Spec-driven development: si la regla vive en Slack, la IA la inventa.
Las reglas de negocio que viven en Slack, en la cabeza del PM o en código implícito no las ve nadie. Cómo escribir specs que tu codebase, tu IA y tu próximo dev consuman como contexto.
Le pediste a Claude Code que agregue un endpoint para cancelar una suscripción. Te devuelve código. Pasa los tests. Lo mandás a prod. Dos días después abren un ticket: "cancelamos un usuario Platinum y perdió el acceso al instante. Eso solo tendría que pasar con Free." La IA no sabía esa regla. La inventó.
El problema no es la IA. La regla vivía en un thread de Slack del año pasado, en la cabeza del PM, y en 14 líneas implícitas de código que nadie marcó como "acá está la lógica de tiers". Para la IA, esa regla nunca existió.
Lo mismo le pasa al dev nuevo del equipo. Y al futuro vos a los 3 meses.
Specs como contexto, no como documentación
La forma vieja de pensar specs: documentación que escribís después del código, para que alguien futuro entienda qué hace. Vive en Confluence, Notion, Wiki. Nadie la lee. Cuando hace falta, está desactualizada.
La forma nueva: specs son contexto compartido entre humanos y IA, viven en specs/ del repo, versionados con el código. La IA los lee al razonar sobre un cambio. El dev los lee al onboardearse. Los tests pueden referenciarlos. Cualquier consumidor del sistema, humano o no, parte de la misma fuente.
El formato
Un spec por bounded context, en markdown, frontmatter para que sea filtrable. Las invariantes y reglas se escriben en imperativos absolutos: MUST, CANNOT, ALWAYS, NEVER. Los casos borde, explícitos.
---
title: Order Management
bounded-context: orders
status: active
last-reviewed: 2026-04-20
---
## Invariants
Reglas que SIEMPRE deben valer. Código que las viole es un bug.
- An order MUST have at least 1 line item.
- Order total MUST equal sum(line_item.price × quantity) − discounts + tax.
- An order in SHIPPED status CANNOT be cancelled, use the return flow.
- A customer CANNOT have more than 3 pending orders simultaneously.
## Status Transitions
DRAFT → PLACED → PROCESSING → SHIPPED → DELIVERED
↓
CANCELLED RETURNED
- Only DRAFT and PLACED can be cancelled directly.
- Cancellation after PROCESSING requires manager approval.
- DELIVERED → RETURNED has a 30-day window.
## Edge cases
- A 50% discount on a $1 item rounds to $0.50, not $0.49.
- Orders over $500 require manager approval.
Con specs/domain/orders.md en el repo, cuando le pedís a Claude Code que agregue un endpoint de cancelación, lee el spec, ve que SHIPPED no se puede cancelar, y devuelve código que respeta la regla en vez de inventar una. El próximo dev también, sin pedirle a nadie que le explique. Y vos a los 3 meses.
Quién lee el spec
Backend code que lo implementa, tests que lo verifican, IA que lo razona, dev nuevo que lo onboardea. Una sola fuente de verdad para todos los consumidores.
Las dos reglas
-
Si una regla importante no está en un archivo del repo, asumí que la IA la va a inventar. Y que el dev nuevo va a inventar otra distinta. Y que vos en 6 meses vas a inventar una tercera. Slack y memoria humana no son storage durable.
-
Escribí en imperativos absolutos. "Large orders need approval" es ambiguo. "Orders over $500 require manager approval" es ejecutable. La precisión sale del lenguaje, no del contexto que vos tenés en la cabeza.
El cambio de mindset
Antes: documentás después del código, si te queda tiempo.
Ahora: el spec es un input al código, no un output. Lo escribís antes de pedirle a la IA que implemente, así la IA tiene contexto. Y queda como artefacto que el próximo cambio puede leer también. Specs sobreviven a las conversaciones; un thread de Slack desaparece, un spec en specs/ queda con su historia de cambios durante años.