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

donumAI

{ date: “2026-08-08”, statut: “en développement”, modules_stack: 14 }

Moteur par étapes pour le développement logiciel — les agents écrivent, mais rien n'avance tant que vous n'avez pas validé

donumAI est né d'une irritation très précise : les outils qui promettent d'« écrire vos documents de projet avec l'IA » produisent un texte plausible et aucun moyen de savoir s'il est encore vrai. Un document d'architecture généré en mars reste là, aussi convaincant qu'au premier jour, alors qu'en mai les exigences ont changé et que personne ne s'en aperçoit. donumAI part de l'hypothèse inverse : le plus dur n'est pas de générer, c'est de tenir ensemble six documents qui se contredisent dès que le projet bouge. Le produit est un moteur qui accompagne un projet logiciel à travers six étapes — discovery, estimation, domain design, architecture, plan d'implémentation, plan de test — et qui, à chaque passage, met une personne devant ce que les agents ont écrit.

## Les six étapes et le gate

Chaque étape produit un artefact versionné, composé de sections. Les agents l'écrivent, mais ils ne le referment pas : la revue se fait section par section, et pour chacune on peut approuver, commenter ou demander des modifications. Une étape ne débloque la suivante que lorsque son gate est approuvé — ce n'est pas une formalité, c'est un vrai verrou. C'est la différence entre un assistant qui produit et un processus qui avance.

·Discovery : le brief initial, recueilli par un entretien qui se déroule en phases
·Estimation : les chiffres et les hypothèses sur lesquelles ils reposent
·Domain design : le modèle du domaine métier
·Architecture : les décisions verrouillées, avec les alternatives écartées
·Plan d'implémentation : epics, séquencement, jalons, definition of done
·Plan de test : stratégie et répartition des tests

## Quand quelque chose change en amont

Le pari derrière donumAI est étroit et mécanique : versionner chaque document, enregistrer de quelle décision vient chacune de ses parties, et dès qu'une entrée change, marquer comme « périmé » tout ce qui en dépendait en aval. La dérive ne disparaît pas — elle cesse d'être invisible, et c'est finalement l'essentiel du problème. Les trace links ne sont pas inférés par un modèle : ils naissent d'une projection sur les données, car un lien inféré porte un taux d'erreur et, à partir de là, toute la chaîne le porte avec lui.

## Des règles déterministes avant les grilles d'évaluation

Chaque artefact traverse une couche de validation avant d'atteindre le gate. Le principe : toute propriété qui peut être capturée sous forme de champ typé sort du jugement d'un modèle et devient une règle structurelle — présence, cardinalité, type, appartenance à un ensemble fermé. Les règles structurelles ne coûtent aucun appel, ne varient pas d'une exécution à l'autre et ne se laissent pas convaincre par une prose bien écrite. Seul ce qui reste — le jugement sémantique irréductible — va à la grille.

·Pour la seule étape d'architecture : 154 règles déterministes, extraites ligne par ligne des documents de méthode
·Trois niveaux de sévérité qui ne sont jamais fondus en un seul : block arrête le gate, repair déclenche une boucle de correction automatique, warn apparaît au gate sans bloquer
·Des enums fermés copiés mot pour mot depuis les sources, parce que les connaissances antérieures d'un modèle sont souvent périmées
·Des verdicts obligatoires sur les propriétés qui demandent réellement un jugement, mais où l'on peut contraindre le juge à citer ses preuves

## Le markdown n'est jamais une entrée

C'est l'invariant qui soutient tout le reste, et c'est aussi la décision technique à laquelle je tiens le plus. Le worker ne produit pas de texte : il produit des objets typés, via un appel d'outil forcé. Les règles s'exécutent sur les objets. Le markdown est une projection, produite par un renderer pur, et aucun composant en aval ne le lit jamais. Si, dans ce projet, je me surprends à écrire un parseur ou une regex sur de la prose, c'est que je suis parti dans la mauvaise direction. Une couche d'extraction est une inférence avec un taux d'erreur, et toutes les règles en aval hériteraient de cette erreur et cesseraient d'être déterministes. Il y a même un test qui vérifie l'invariant sur l'AST — par type de retour et non par nom de fonction — et qui prouve qu'il n'est pas aveugle en repérant les parseurs hérités restés dans un module plus ancien.

## Les guides de méthode

Derrière chaque étape il y a des documents de méthode, et ces documents se lisent à l'intérieur même du produit : une section d'étude qui explique pourquoi un artefact est fait ainsi, ce qui rend une décision verrouillable et selon quels critères elle sera jugée. Ils sont écrits en italien alors que le reste de l'interface est en anglais, ce qui a fait de la typographie un problème concret : une longue prose italienne n'a ni la même mesure ni le même rythme qu'une interface dense.

## Design et identité visuelle

L'interface est pensée pour des personnes techniques qui y passent des heures : tableaux denses, documents longs, décisions de gate. Densité et lisibilité avant décoration. Le système s'appelle « Slate & Ferrous » et est presque monochrome, avec un seul accent bleu : le noir d'encre marque les actions primaires, le bleu marque l'état — ainsi un tableau plein de cartes reste lisible sans que la couleur fasse deux métiers à la fois.

·Palette en OKLCH, thème clair et thème sombre tous deux conçus, et non l'un l'inverse de l'autre
·Typographie : Bricolage Grotesque pour les titres, Public Sans pour l'interface, JetBrains Mono pour les identifiants, versions et métriques — ce qui est en chasse fixe est par définition une valeur produite par la machine
·Polices auto-hébergées : aucune requête tierce sur les pages publiques, ce qui est aussi la seule façon d'écrire une politique de cookies sans bandeau tout en disant vrai
·La marque est un double hexagone avec un nœud plein sur chacun des six sommets de l'anneau intérieur : un par étape

## Stack technologique

Le projet est un monorepo TypeScript où le control plane et l'execution plane sont volontairement séparés : l'API reçoit les requêtes et détient l'état, tandis qu'un worker distinct exécute les runs, qui peuvent durer plusieurs minutes.

·Control plane et moteur : NestJS avec Prisma et PostgreSQL
·Execution plane : un worker séparé sur BullMQ et Redis
·Web : React 19, Vite, TanStack Router, HeroUI, Tailwind CSS v4
·Contrats partagés : des schémas Zod dans un paquet à part, utilisés par l'API comme par le client
·Client LLM agnostique du fournisseur, isolé dans son propre paquet
·Monorepo géré avec pnpm

donumAI est un projet personnel, développé seul, et il avance dans un ordre que je me suis imposé : d'abord le câblage typé, ensuite l'invocation du juge et la mesure de sa variance, puis tout le reste. Les 154 règles écrites jusqu'ici restent des hypothèses tant qu'elles n'ont pas tourné sur des artefacts réellement générés, et le tableau qui m'intéresse a deux colonnes : les règles qui ne se déclenchent jamais et celles qui se déclenchent toujours. Leurs diagnostics sont opposés et doivent être lus ensemble — une règle qui se déclenche toujours n'est pas une réussite de la couche de validation, c'est le symptôme de quelque chose à corriger plus en amont.

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