donumAI
Stage engine for software delivery — the agents write, but nothing moves forward until you say so
donumAI came out of a very specific irritation: tools that promise to 'write your project documents with AI' produce plausible text and no way of knowing whether it is still true. An architecture document generated in March sits there, as convincing as on day one, while in May the requirements have changed and nobody notices. donumAI starts from the opposite assumption: the hard part is not generating, it is holding together six documents that contradict each other the moment the project moves. The product is an engine that walks a software project through six stages — discovery, estimation, domain design, architecture, implementation plan, test plan — and at every handover puts a person in front of what the agents wrote.
## The six stages and the gate
Each stage produces a versioned artifact made of sections. The agents write it, but they do not close it: review happens section by section, and for each one you can approve, comment, or request changes. A stage unlocks the next only when its gate is approved — that is not a formality, it is a real lock. It is the difference between an assistant that produces and a process that advances.
## When something upstream changes
The bet behind donumAI is narrow and mechanical: version every document, record which decision each part came from, and the moment an input changes, mark as stale everything downstream that depended on it. Drift does not go away — it stops being invisible, which turns out to be most of the problem. Trace links are not inferred by a model: they come from a projection over the data, because an inferred link carries an error rate, and from that point on the whole chain carries it too.
## Deterministic rules before rubrics
Every artifact passes through a validation layer before it reaches the gate. The principle: any property that can be captured as a typed field leaves the judgement of a model and becomes a structural rule — presence, cardinality, type, membership of a closed set. Structural rules cost zero calls, do not vary between runs, and cannot be talked round by well-written prose. Only what is left — the irreducibly semantic judgement — goes to the rubric.
## Markdown is never an input
This is the invariant that holds everything else up, and it is also the technical decision I am most attached to. The worker does not produce text: it produces typed objects, through a forced tool call. The rules run on the objects. Markdown is a projection, produced by a pure renderer, and no component downstream ever reads it. If I catch myself writing a parser or a regex over prose in this project, I have gone the wrong way. An extraction layer is an inference with an error rate, and every rule downstream would inherit that error and stop being deterministic. There is even a test that checks the invariant against the AST — by return type, not by function name — and that proves it is not blind by picking up the legacy parsers still sitting in an older module.
## The method guides
Behind each stage there are method documents, and those documents are readable inside the product itself: a study section explaining why an artifact looks the way it does, what makes a decision lockable at all, and the criteria it will be judged against. They are written in Italian while the rest of the interface runs in English, which turned typography into a real problem: long Italian prose has a different measure and a different rhythm from a dense interface.
## Design and visual identity
The interface is built for technical people who spend hours inside it: dense tables, long documents, gate decisions. Density and legibility before decoration. The system is called 'Slate & Ferrous' and is near-monochrome with a single blue accent: near-black marks the primary actions, blue marks state — so a board full of cards stays readable without colour doing two jobs at once.
## Tech stack
The project is a TypeScript monorepo where the control plane and the execution plane are deliberately kept apart: the API takes requests and owns the state, while a separate worker runs the jobs, which can take minutes.
donumAI is a personal project, developed alone, and it follows an order I imposed on myself: first the typed wiring, then invoking the judge and measuring its variance, then everything else. The 154 rules written so far remain hypotheses until they have run on artifacts that were actually generated, and the table I care about has two columns: the rules that never fire and the rules that always fire. Their diagnoses are opposite and have to be read together — a rule that always fires is not a success of the validation layer, it is a symptom of something to fix further upstream.