~/progetti/donumai/README.md
~/progetti/donumai/README.md

donumAI

{ fecha: “2026-08-08”, estado: “en desarrollo”, módulos_stack: 14 }

Motor por etapas para el desarrollo de software — los agentes escriben, pero nada avanza hasta que tú lo apruebas

donumAI nace de una molestia muy concreta: las herramientas que prometen «escribir los documentos de proyecto con IA» producen texto plausible y ninguna forma de saber si sigue siendo cierto. Un documento de arquitectura generado en marzo se queda ahí, tan convincente como el primer día, mientras en mayo los requisitos han cambiado y nadie se da cuenta. donumAI parte del supuesto contrario: la parte difícil no es generar, es mantener unidos seis documentos que se contradicen entre sí en cuanto el proyecto se mueve. El producto es un motor que acompaña a un proyecto de software a través de seis etapas — discovery, estimación, domain design, arquitectura, plan de implementación, plan de pruebas — y en cada paso pone a una persona delante de lo que han escrito los agentes.

## Las seis etapas y el gate

Cada etapa produce un artefacto versionado, formado por secciones. Los agentes lo escriben, pero no lo cierran: la revisión ocurre sección por sección, y en cada una se puede aprobar, comentar o pedir cambios. Una etapa desbloquea la siguiente solo cuando su gate está aprobado — no es una formalidad, es un candado de verdad. Es la diferencia entre un asistente que produce y un proceso que avanza.

·Discovery: el briefing inicial, recogido con una entrevista que avanza por fases
·Estimación: los números y los supuestos sobre los que se apoyan
·Domain design: el modelo del dominio de negocio
·Arquitectura: las decisiones bloqueadas, junto con las alternativas descartadas
·Plan de implementación: épicas, secuenciación, hitos, definition of done
·Plan de pruebas: estrategia y distribución de los tests

## Cuando algo cambia aguas arriba

La apuesta detrás de donumAI es estrecha y mecánica: versionar cada documento, registrar de qué decisión viene cada una de sus partes y, en el momento en que un input cambia, marcar como «obsoleto» todo lo que aguas abajo dependía de él. La deriva no desaparece — deja de ser invisible, y a fin de cuentas esa es la mayor parte del problema. Los trace links no los infiere un modelo: nacen por proyección sobre los datos, porque un enlace inferido tiene una tasa de error y, a partir de ahí, se la lleva consigo toda la cadena.

## Reglas deterministas antes que rúbricas

Cada artefacto pasa por una capa de validación antes de llegar al gate. El principio es que cualquier propiedad que pueda capturarse como campo tipado sale del juicio de un modelo y entra en una regla estructural: presencia, cardinalidad, tipo, pertenencia a un conjunto cerrado. Las reglas estructurales cuestan cero llamadas, no cambian de una ejecución a otra y no se dejan convencer por una prosa bien escrita. Solo lo que queda — el juicio semántico irreducible — va a la rúbrica.

·Solo para la etapa de arquitectura: 154 reglas deterministas, extraídas línea por línea de los documentos de método
·Tres severidades que nunca se colapsan en una: block detiene el gate, repair dispara un ciclo de corrección automática, warn aparece en el gate sin bloquear
·Enums cerrados copiados literalmente de las fuentes, porque el conocimiento previo de un modelo suele estar desactualizado
·Veredictos obligatorios sobre las propiedades que sí requieren juicio, pero en las que se puede obligar al juez a citar sus evidencias

## El markdown nunca es un input

Es la invariante que sostiene todo lo demás, y también la decisión técnica a la que más apego tengo. El worker no produce texto: produce objetos tipados, mediante una tool call forzada. Las reglas se ejecutan sobre los objetos. El markdown es una proyección, producida por un renderer puro, y ningún componente aguas abajo lo lee jamás. Si en este proyecto me sorprendo escribiendo un parser o una regex sobre prosa, es que he ido en la dirección equivocada. Una capa de extracción es una inferencia con una tasa de error, y todas las reglas aguas abajo heredarían ese error y dejarían de ser deterministas. Hay incluso un test que verifica la invariante sobre el AST — por tipo de retorno y no por nombre de función — y que demuestra no estar ciego al detectar los parsers heredados que quedan en un módulo más antiguo.

## Las guías de método

Detrás de cada etapa hay documentos de método, y esos documentos se pueden leer dentro del propio producto: una sección de estudio que explica por qué un artefacto es como es, qué hace que una decisión sea bloqueable y con qué criterios se la juzgará. Están escritos en italiano mientras el resto de la interfaz está en inglés, lo que convirtió la tipografía en un problema real: la prosa larga en italiano tiene una medida de línea y un ritmo distintos de los de una interfaz densa.

## Diseño e identidad visual

La interfaz está pensada para personas técnicas que pasan horas dentro: tablas densas, documentos largos, decisiones de gate. Densidad y legibilidad antes que decoración. El sistema se llama «Slate & Ferrous» y es casi monocromático, con un único acento azul: el negro tinta marca las acciones primarias, el azul marca el estado — así un tablero lleno de tarjetas sigue siendo legible sin que el color haga dos trabajos a la vez.

·Paleta en OKLCH, tema claro y tema oscuro ambos diseñados y no uno el inverso del otro
·Tipografía: Bricolage Grotesque para los títulos, Public Sans para la interfaz, JetBrains Mono para identificadores, versiones y métricas — si está en monoespaciada, por definición es un valor producido por la máquina
·Fuentes self-hosted: ninguna petición a terceros en las páginas públicas, que además es la única manera de escribir una política de cookies sin banner y decir la verdad
·El logotipo es un doble hexágono con un nodo relleno en cada uno de los seis vértices del anillo interior: uno por etapa

## Stack tecnológico

El proyecto es un monorepo TypeScript en el que el control plane y el execution plane se mantienen separados a propósito: la API recibe las peticiones y es dueña del estado, mientras que un worker aparte ejecuta los runs, que pueden durar minutos.

·Control plane y motor: NestJS con Prisma y PostgreSQL
·Execution plane: un worker separado sobre BullMQ y Redis
·Web: React 19, Vite, TanStack Router, HeroUI, Tailwind CSS v4
·Contratos compartidos: esquemas Zod en un paquete aparte, usados tanto por la API como por el cliente
·Cliente LLM agnóstico del proveedor, aislado en su propio paquete
·Monorepo gestionado con pnpm

donumAI es un proyecto personal, desarrollado en solitario, y avanza en un orden que me he impuesto: primero el cableado tipado, luego la invocación del juez y la medición de su varianza, después todo lo demás. Las 154 reglas escritas hasta ahora siguen siendo hipótesis mientras no se ejecuten sobre artefactos generados de verdad, y la tabla que me interesa tiene dos columnas: las reglas que no saltan nunca y las que saltan siempre. Sus diagnósticos son opuestos y hay que leerlos juntos — una regla que salta siempre no es un éxito de la capa de validación, es el síntoma de algo que hay que corregir más arriba.

// stack
[nestjs”, prisma”, postgres”, redis”, bullmq”, react”, vite”, tanstack-router”, typescript”, tailwind”, zod”, llm”, monorepo”, sdlc”, ]