Two Loops: Model-Driven Development with Agents
Section titled “Two Loops: Model-Driven Development with Agents”Agents can work away from the keyboard only on what a human approved. A human can approve only what they can read. LLMs write Markdown faster than anyone can read it, so a spec written in prose ends up approved without being read, and agents take it as gospel.
This method puts a model at the center of the spec instead. Business flows, domain models and API contracts are written in structured languages that humans and agents can both read and validate. A human designs the system with them, in a loop with agents. Then agents implement it, in a loop of their own.
Principles
Section titled “Principles”- The model is the spec. Business flows in ZFL, bounded contexts in ZDL, contracts in OpenAPI and AsyncAPI.
- Prose lives inside the model, not around it. Doc comments, business policies and ADRs explain the model. Free-standing documents (PRDs, research notes, generated Markdown specs) feed the design, never the implementation.
- Humans review projections, not prose. Diagrams, state machines, sequence diagrams per branch, API contracts and generated code are all projections of the same model, and they are faster to validate than any document.
- Approved means approved. Agents treat as decided only what is in the approved model baseline.
- Agents challenge the model; they never edit it. When implementation shows the model is wrong, agents stop and propose changes. A human decides.
- Agents make tests pass; they don’t decide what passing means. Expectations come from the model and from test data a human validated.
- Humans review evidence, not code. At the end of an autonomous run the human gets reports, test results and open proposals, not a diff to read line by line.
- Iterative, one batch at a time. Both loops run in parallel on different batches of flows.
- The generator is an accelerator, not the method. Deterministic code generation shrinks what agents have to write. The method works without it.
The cycle at a glance
Section titled “The cycle at a glance”| Stage | Who leads | Produces | Ends when | ZenWave tools |
|---|---|---|---|---|
| Discover | Humans, assisted by agents | PRD, Event Storming findings, first ZFL draft | A flow can be written as ZFL | grill-with-docs, Event Storming |
| Shape (HITL loop) | Humans, assisted by agents | Approved models, ADRs, validated test data, task board | The gate passes | ZFL, ZDL, OpenAPI, AsyncAPI, ZenWave Platform, ZenWave SDK, zfl-to-zdl, zenwave-test-data, zenwave-test-scenarios |
| Implement & Verify (AFK loop) | Agents | Working, tested code; review reports; model-change proposals | The batch exit criteria pass | Orchestrator, implementer and reviewer subagents, zenwave-fill-gaps |
| Navigate | Humans and agents | Understanding of the whole architecture | Never: it runs alongside | zenwave-architecture, ZenWave Platform, MCP |
The stages form a cycle: for an existing system, Navigate is the input to Discover.
Discover
Section titled “Discover”Discovery comes before the loops. Ideally it starts with a PRD, which seeds an interview session with skills like grill-with-docs. It continues with an Event Storming session between technical experts and domain experts. The architect translates the findings into a first ZFL draft of each flow.
Prose is fine here. The PRD and research notes are inputs to the design; agents in the AFK loop never read them.
Ends when a flow can be written as a first ZFL draft.
Shape: the Human-in-the-Loop loop
Section titled “Shape: the Human-in-the-Loop loop”The human drives the design; agents assist. The loop repeats until the gate passes:
- Model. Write the business flow in ZFL and one ZDL per bounded context. The zfl-to-zdl skill drafts the ZDL from the ZFL. API contracts can be derived from the ZDL.
- Project. Explore what the model derives in ZenWave Platform for IntelliJ and VS Code: the EventFlow diagram, sequence diagrams for every alternative branch of a ZFL flow, class diagrams and state machines for each aggregate, commands, domain events, OpenAPI and AsyncAPI.
- Generate. If the stack matches, ZenWave SDK generates services, APIs, event handlers and a full set of tests. Generated code is one more projection. Early on, throw it away and generate again.
- Probe. Generated tests have no proper test data or complete assertions yet. Use them as entry points: start a debug session, or write a few lines by hand, to check that what the model produces covers the requirements.
- Challenge. Agents review the models looking for contradictions, missing outcomes and decisions nobody made. Answers change the model or become ADRs.
- Prepare the handover. Generate test data for each use case and branch of the flow (zenwave-test-data, zenwave-test-scenarios) and validate it. Split the work into tasks.
Task splitting
Section titled “Task splitting”Splitting is a discrete step at the end of Shape, not a loop, though it may take a few iterations. The human splits the work, assisted by an agent that derives a task list from the approved model: from the generated code when there is some, from a blank slate when there isn’t.
The result is a list or a graph of tasks. Each task:
- points at the model lines it implements and the test data that defines done;
- states its difficulty, so it can be routed to a suitable model;
- states its blockers, the tasks it depends on.
Tasks don’t describe behavior in prose; the model already does.
The gate
Section titled “The gate”A batch of flows passes from Shape to Implement & Verify when it is:
- Valid. Models parse and references resolve: every ZFL service exists in a ZDL, every emitted event is declared, every API channel exists. Deterministic, no LLM.
- Reviewed. Agents have no open questions left, and the human has reviewed the projections.
- Covered by test data. Each use case and branch has test data with inputs and expected results, validated by the human.
- Split. The task board is approved.
- Approved. The human commits or tags the model as the baseline.
- Generated (when a generator exists). The last generation run compiles and runs. It becomes the AFK loop’s starting point.
The batch can be a single flow, a module or a whole system.
Implement & Verify: the Away-From-Keyboard loop
Section titled “Implement & Verify: the Away-From-Keyboard loop”Agents implement the batch without a human at the keyboard. They read only the approved models, the ADRs, the validated test data, the task board and the generated code.
- Load. The orchestrator reads the whole approved spec.
- Pick. It takes the next task whose blockers are done.
- Route. It chooses a model according to the task’s difficulty.
- Implement. An implementer subagent works in its own worktree, reads the task and the model lines it points at, and runs only the focused tests for that task.
- Review, per batch. A reviewer subagent runs the entire suite, or the vertical slice of a module in a modular monolith, and checks the changes against the model and the test data. It writes a review report with the reviewed commit range (
from..to). Optionally, it adds regression tests covered by the model. - Integrate. The review report is always committed with the code. On a FIX FIRST verdict, the orchestrator redelivers the affected tasks to implementers.
- Repeat until the board is cleared or every remaining task is blocked.
Only the orchestrator writes to the board. Subagents report back to it.
When the model is wrong
Section titled “When the model is wrong”An implementer or reviewer that finds a gap in the model does not work around it in code and does not edit the model. It:
- marks the task as blocked by the model;
- writes a proposal with one or more solutions, as changes in the modeling language, with the evidence (failing test, code location);
- hands it to the human, while the orchestrator continues with other ready tasks.
The human chooses or adjusts a solution in Shape, updates the model, regenerates and approves a new baseline. The orchestrator reconciles the regenerated code with the code already merged, and the blocked tasks become ready again.
Exit criteria
Section titled “Exit criteria”A batch is done when:
- every task of the approved board is done;
- the batch review is clean (no FIX FIRST);
- the full suite, or the vertical slices, are green;
- structural assertions and approved test data have not changed since the baseline;
- there are no open model-change proposals.
Advanced: once the board is cleared, the reviewer runs the task-list agent again over the result. An empty list means nothing is missing between the model and the code. It can also produce a traceability table: each ZFL step and ZDL operation, the code that implements it, and the test covering each branch.
The human then reviews the evidence: review reports, test results per branch, open proposals and the running application. Code review is by sampling, or for what the model does not cover.
Where the loops meet
Section titled “Where the loops meet”The two loops connect in two places:
- The gate, going forward: an approved batch of models, test data and tasks.
- Model-change proposals, going back: written in the modeling language, so a human can review them in minutes.
Because the method is iterative, both loops run at the same time on different batches. When a later batch changes a shared ZDL, that is a new baseline: regenerate, approve, and let the orchestrator reconcile.
Navigate
Section titled “Navigate”Navigate runs outside the loops. zenwave-architecture builds one graph from all the models and APIs listed in the architecture manifest, and ZenWave Platform and MCP make it explorable by humans and agents. It is how you understand the whole existing architecture and the blast radius of a change, and for an existing system it is where the next Discover begins.
Without a generator
Section titled “Without a generator”The method does not depend on ZenWave SDK. Without a generator:
- Shape still produces models, projections, test data and tasks, minus the generated code;
- the task list starts from a blank slate;
- the gate drops its last check;
- the AFK loop writes all of the code instead of the remaining 20%.
Hard rules and optional practices
Section titled “Hard rules and optional practices”Hard rules:
- the model is the spec;
- agents never edit the model;
- agents never invent expected behavior;
- nothing crosses into the AFK loop without passing the gate.
Optional practices: the code generator, the board backend (a Markdown list, a folder of task files, Jira, GitHub issues, Linear), routing by difficulty, reviewer regression tests, and the advanced exit check.
Further reading
Section titled “Further reading”- Spec-Driven Development Two Loops: Model-Driven Human in the Loop
- Spec-Driven Development Two Loops: Agentic Away from Keyboard Loop
- The skills live in zenwave-sdd. They are still early, extracted from Arcadia Editions, where this method is being tested end to end.