Originally published in French on blog.saifallah.dev


A code assistant surfaces every change as a text diff: red lines, green lines, and a human who approves or rejects. That mechanism is what makes Claude Code or Codex workable on a real repository. It's also their ceiling. You're approving lines. Not behavior.

The text diff answers "what changed in the file." It doesn't answer "who calls whom, in what order, and what happens when it fails." Nobody asks that question anymore, because code arrives faster than anyone can read it.

The diagram is the contract. Nothing gets coded before it's approved.

This piece proposes a simple shift: apply to design the same mechanism that already works on code. The assistant proposes a diagram. The human sees what changed in that diagram, in color, like a diff. They approve it. Only then does the assistant write code, and the diagram regenerated from that code is compared, visually, against the one that was approved. The name for this practice is Design-Gated Development (DGD). The key word is gated: what matters isn't the diagram. It's the gate placed in front of implementation.


The Problem: Comprehension Debt

The term vibe coding comes from an Andrej Karpathy post in February 2025. It describes a specific practice: accepting model-generated code without reading it, re-prompting on the next error, and iterating until the thing runs. On a throwaway prototype, that's rational. On a system that will live two years, it's a loan. Original post

Comprehension debt is the gap between what a system does and what the team can explain. It compounds silently, because each generated increment builds on the previous one without anyone having reviewed the structure. And it comes due all at once, on the day you have to reason about the system without the model: an incident, an audit, a handoff to another team.

The bottleneck isn't code production. It's reading. No reviewer keeps up with a model that generates, and the post-hoc code review inherited from human-to-human workflows doesn't scale when the author is a machine. A sequence diagram, on the other hand, takes two minutes to read, and it says what matters: participants, calls, their order, error paths. That's where human validation becomes viable again. The gate needs to move: off the code, onto the design.

The Idea: Reading Design Like a Diff

With a code assistant today, you look at two things: code and text diffs. The proposal is to add a third view, at the same level: diagrams and diagram diffs.

A diagram is text (Mermaid), so the assistant can produce it, modify it, and compare it. But you don't read it like text. You read it rendered, and the diff too: additions appear in green, removals in red, structural changes in orange, highlighted directly on the diagram. A missing error path shows up as an absent arrow. A misplaced responsibility shows up as an arrow leaving from the wrong participant.

Here's what that diff looks like on an order processing flow, between the diagram proposed by the assistant and the one corrected by the human before approval. It is a merged view: a single diagram where every element carries its status.

flowchart TD
    A[Order received] --> B[Pre-trade check]
    B --> C[Pricing]
    C --> D[Execution]
    D --> E[Booking]
    B -. reject .-> R[Rejection notification]
    C -. timeout .-> T[Retry queue]
    E --> F[Reconciliation]

    classDef added fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
    classDef removed fill:#fee2e2,stroke:#dc2626,stroke-width:2px,stroke-dasharray:5 5,color:#7f1d1d
    classDef changed fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f

    class R,T added
    class F removed
    class B changed

Three human corrections are visible without reading a single line of code: two error paths added (pre-trade rejection, pricing timeout), one step removed from the increment's scope (reconciliation), and one check whose contract changed. None of this is coded yet. It's the cheapest moment to make these decisions.

Nothing exotic here: Mermaid supports node coloring by class (edges are colored by index, which is less convenient). A naive structural diff, over sets of nodes and edges, is simple; detecting a rename or a moved responsibility takes more work. What's missing isn't the tooling, it's the convention. Mermaid classes and styles

The Method in Five Steps

Step Who produces Artifact Exit criteria
1. Intent Human The requirement in three sentences + external contracts Inputs, outputs, invariants named
2. Design Assistant Sequence diagram, class diagram if state warrants it, signatures No function bodies
3. Gate Human The diagram diff, corrected and approved Written, dated sign-off
4. Implementation Assistant Tests first, then code, one diagram node at a time Each test cites an arrow from the diagram
5. Anti-drift Assistant Diagram regenerated from code, visual diff against approved version Empty diff, or back to step 3

Intent. Three sentences: what the system receives, what it returns, what must stay true in between. External contracts are defined here, as signatures, because that's what the human knows better than the model.

Design. The assistant responds with a sequence diagram, and a class diagram when shared state warrants it. Every arrow has a sender, a receiver, a payload, and a rank. Signatures live in the design file, not in the source code. Error paths are either in the diagram or they don't exist. No function bodies.

Gate. The human reads the diagram diff, not the whole diagram. They rename things, remove an arrow, add one for the failure case, move a responsibility. Then they sign off, in writing, in a file with their name and the date. An assistant that wrote code before this approval has violated the contract, even if the code is correct.

Implementation. Each increment maps to one node in the approved diagram. Tests come first and derive from the diagram: an expected message becomes an assertion, an error path becomes a test case. Code follows, constrained by the approved signatures and topology.

Anti-drift. A hand-maintained diagram dies in two sprints. So the diagram isn't maintained. It's regenerated from code, canonicalized (deterministic participant and arrow ordering, stable names), then compared against the approved diagram using the same color rendering as the gate. A non-empty diff has two readings: the code drifted and needs to be fixed, or the design evolved and the gate needs to be revisited. The human decides.

sequenceDiagram
    participant H as Human
    participant A as Assistant
    participant R as Repository

    H->>A: 1. Intent (3 sentences + external contracts)
    A->>H: 2. Design (diagrams + signatures, zero code)
    loop 3. Gate: diagram diff
        H->>A: corrections (arrows added, removed, moved)
        A->>H: revised diagram, changes highlighted
    end
    H->>R: written sign-off (name, date, commit)
    A->>R: 4. Tests derived from arrows, then code
    A->>A: 5. Diagram regenerated and canonicalized
    A->>H: visual diff (regenerated vs. approved)
    alt empty diff
        H->>R: merge
    else drift
        H->>A: fix code, or back to step 3
    end

What This Requires from the Tooling

The method is a convention. It runs on top of an existing code assistant, with no new product, given three conditions.

A design file per increment, versioned alongside the code, containing the intent, the diagrams, and an approval block. As long as that block is empty, the assistant refuses to write to source files. That's a skill rule or a system instruction, not a feature.

A diagram diff. Both diagrams are put into canonical form, compared as sets of nodes and edges, and the result is rendered as a single Mermaid diagram using the color classes shown above. The assistant displays it at the gate and at step 5.

Honest regeneration. When orchestration is declarative (an agent graph, a state machine, a task catalog), the diagram regenerates mechanically and the diff is exact. When the code is imperative, the assistant reconstructs the diagram by reading the code, and the diff is over that reconstruction. That's weaker, and it should be stated plainly: step 5 is a proof on declarative systems, and an assisted check on everything else. On imperative code, the main safeguard remains step 4: the tests derived from the arrows.

Where This Fits

TDD and BDD established that the contract is written before the code. DGD moves that contract up one level, to the interaction between components, and tests derive from it afterward. Spec-driven development makes the same bet, using a prose specification before letting the assistant code. The difference is in the medium and the feedback loop. A prose spec can be read diagonally; you're validating intent. A sequence diagram doesn't allow vagueness: every arrow is a commitment. And a spec isn't regenerated from code; the diagram is, which gives the contract a verifiable expiration date. GitHub Spec Kit

What This Isn't

Not waterfall. There's a gate per increment, and an increment is measured in hours. The approved diagram covers the increment, not the system.

Not exhaustive modeling. One sequence diagram, one class diagram if state warrants it, scoped to the increment. Cross-cutting properties (idempotence, concurrency, latency) don't surface on a sequence diagram and keep their own tests.

Not a replacement for code review. Code is still read, but against an approved diagram. You're verifying conformance, not reconstructing intent.

Not a universal method. A throwaway script, a one-line fix, an exploratory spike you'll discard: the gate has a fixed cost these cases don't justify. It applies whenever an increment touches an interface, a shared state, or an error path.

In a financial system, the approved design file has one more use. It says what the component does, who approved it, and at which commit. That's what first-level control looks like when the code is written by a machine, and it exists before the code rather than being reconstructed after the fact.

What Comes Next

The method fits on one page. The implementation fits in one skill: a design file per increment, an assistant that refuses to write code until the approval block is filled, a diagram diff rendered in color at the gate and at step 5. A prototype Claude Code skill exists as an unpublished draft; the same convention applies to Codex. The day you look at a highlighted diagram with the same reflex as a text diff, the gate is in place.