flmnt → case studies → marilou

A gate compared what the specs claimed against what the model declared. It disagreed 33 times.

Marilou was built end to end with the workflow. The gate that caught the drift could only run because two written artifacts both traced to the same record of what the team had decided — and because that record could say which version was current. This is what it caught, and what the record underneath it did.

The build, in figures

Measured by the gates, not estimated afterwards.

161

spec files, each stating what the work promised and exactly what it was allowed to change

authored before the build

827

tests, generated from those specs rather than inferred from the code that was produced

green at merge

15

gates enforced in CI, each one a condition the work had to satisfy to merge

all passing

33

discrepancies found by the model-conformance gate, comparing what the specs asserted against what the domain model declared

flagged for review

24

of those were real drift — the design and the specs had quietly diverged during the build

fixed, then gated

The gate that mattered

The tests said the code worked. The gate asked a different question.

Every one of the 827 tests answered "does this code do what its spec says?" That is the question testing has always answered, and it is not the question that costs teams money when agents write the code.

The model-conformance gate asked: does what the specs claim still match what the domain model declares? Both are written down. Both are machine-readable. Over the course of a build they drift apart — someone adjusts the design, someone else writes a spec against the version they remembered, and nothing in a test suite notices, because each spec is internally consistent and each test passes.

Twenty-four of the disagreements were real: the specs had been written against a design that had since moved. Every one of them would have merged as correct-looking, fully tested code built on a decision that was no longer current.

The nine that weren't drift

The remaining nine were the gate being wrong: legitimate differences it flagged anyway. A conformance gate that never produces a false positive is usually a gate that isn't comparing anything, and these nine are what calibrated the comparison.

Why 24 is the number to look at

161 specs and 827 tests describe effort. The 24 describe a class of error ordinary review does not catch: not "is this code correct" but "is this code answering a question we stopped asking." A reviewer reading a diff has no way to see it. A gate comparing two written artifacts sees all of it, every time, in CI.

Once the gate was enforced, that class of error stopped being possible to merge.

What made the comparison possible

two written artifacts

A domain design that declares behavior explicitly, and specs that state their promise and their blast radius. Neither is prose, so a machine can compare them. A gate like this needs both.

Why a machine could settle it

one record, both artifacts

Both artifacts trace to the same decisions. So when the gate flagged a difference, resolving it was a lookup rather than an argument.

How the build ranDecisions recorded as they were made, the domain modeled with time in it, the design verified before any code existed, specs authored and agreed by a person before the build, then proved against the delivered work. The workflow, stage by stage →

What this is and isn'tOur own delivery, reported from the gate output. It is a single build, and the figures are what these gates measured on it — not a controlled study, and not a claim about what your build would produce.

The layer underneath

A gate can only compare two artifacts if something knows which decision each one is answering.

That is flmnt's part of this build. Not a stage in the workflow — the thing every stage read from and wrote back to.

before any code

The design was built from decisions, not from a document. The domain model was authored against what the team had actually settled, with the reasoning attached. Nobody reconstructed the intent from a ticket.

during design

Questions the design raised went back in. Modeling a domain surfaces decisions nobody made explicitly. Each answer entered the record at the moment it was decided, so the next artifact was written against it rather than around it.

at the gate

Every one of the 24 had a resolvable answer. When the gate flagged a real difference, "which of these two is current?" was a lookup. Without that, each of the 24 is a conversation, and some of them get the answer wrong.

throughout

Changed decisions retired the versions they replaced. When something was settled differently mid-build, the old version stopped being served to anything while staying readable as history — so specs re-agreed against the new one, not against whichever was found first.

at review

The decision history arrived on the pull request. A CI worker posted the decisions each change rested on as a comment, beside the code, where the reviewer already was.

after delivery

It outlived the build. The record is not project state that ends at delivery. What was decided, why, and what it replaced is still there — which is what makes a build like this auditable a year later rather than only reviewable at the time.

The dependency runs one wayDomain modeling, design verification and specification each need something that knows what the team decided and which version is current. The record works without any of them. None of them works well without it. How the record works →

The same gates, on your build

Start with the record. The gates come later.

Every comparison on this page was possible because one layer knew what the team had decided, and which version was current.