Declare, Don't Instruct

A methodology for maintaining architectural control when AI agents build your software.

GitHub: https://github.com/vanis14/declarative-system-spec/


There's a failure mode in AI-assisted development that nobody talks about enough, probably because it's boring. It's not hallucination. It's not wrong code. It's the slow, invisible drift that happens when you build a system across dozens of agent sessions, and each session starts from zero.

Session 14 doesn't know what session 3 decided about the database schema. Session 22 doesn't know why session 8 put the validation logic in the API layer instead of the service layer. Every session makes locally reasonable decisions that are globally incoherent, because no single session has the full architectural picture. You end up with a codebase that works but has no structural integrity — business logic scattered across layers, component boundaries violated, invariants that hold in some places and not others.

The usual solution is to re-explain the system every session. Paste in context. Summarize what's been built. Remind the agent about constraints. This works for small projects. It doesn't scale. And it puts the human in the position of being a context-transfer bottleneck — the one person who holds the full picture in their head and has to translate it into agent-digestible form every time.

I ran into this problem building two things simultaneously: a personal AI system called Spark, and production AWS infrastructure at work. Both involved hundreds of agent sessions over months. Both started coherent and drifted. And both forced me to develop a solution that I've since extracted into something general enough to share.

The Core Idea

A Declarative System Spec is a document that describes what a system is — not how to build it. It declares states, invariants, component contracts, behaviors, and acceptance criteria. An implementing agent reads the spec and derives architecture, data models, and service boundaries from the declarations.

The analogy that makes this click: Terraform declares desired infrastructure state, and the engine figures out how to reach that state. A Declarative System Spec declares desired system behavior and structure, and the implementing agent figures out how to build it. The human describes WHAT. The agent handles HOW.

This is different from traditional documentation in a specific way that matters for agents. Traditional docs are written for humans who accumulate understanding over time — they can be partial, they can reference shared context, they can assume you've read the README and attended the architecture review. Agents don't accumulate. They receive context fresh every session. A Declarative System Spec is written for cold start — every term defined, every relationship explicit, every constraint stated rather than implied.

What Goes In One

The structure is deliberate. A spec starts with System Identity — what the system is, why it exists, and critically, what it is not. That last part matters more than people expect. Agents are completion machines. Without explicit boundaries, an agent implementing a monitoring system will add dashboard features. A notification system will grow message composition. A data pipeline will sprout analytics. The "is NOT" section is the primary defense against scope creep.

Then Core Abstractions — every entity the system manages, its state, and invariants that must hold. Not "emails should be unique" but "a User's email MUST be unique across all Users, enforced at the persistence layer, not just the application layer." Strong invariants tell the agent not just what must be true but where the enforcement lives.

Then Component Contracts with negative boundaries. "The interface adapter translates formats. It MUST NOT filter content." "Capabilities gather data. They MUST NOT interpret results." Without negative contracts, agents put logic wherever they happen to be working, regardless of whether it belongs there. This is the most common implementation failure in agentic engineering, and negative contracts are the fix.

Then Design Principles with rationale, Acceptance Criteria that are binary and testable, and Open Questions — the things you haven't decided yet, explicitly marked so agents flag them instead of guessing.

What I Learned Using It

I've been building with this methodology for a few months now, across a personal project and production infrastructure. A few things surfaced that I didn't anticipate.

First, the spec gets stale during implementation. This is expected, not a failure — but the v1.0 of this standard didn't address it explicitly enough. Implementation reveals things the spec author couldn't anticipate: edge cases, performance constraints, abstractions that are awkward in practice. The v1.1 update adds a section on the implementation feedback loop — how to reconcile the spec with what you learn while building, without letting silent divergence destroy the spec's value.

Second, the collaborative authoring workflow matters. The human writes System Identity and Design Principles — these encode judgment and values that come from the human. The AI helps formalize Core Abstractions and drafts Behaviors and Contracts. The human reviews and corrects. This split works because it puts each party where they're strongest.

Third, the spec is genuinely useful as a thinking tool even before any code is written. The act of declaring invariants, drawing component boundaries, and writing negative contracts forces you to resolve ambiguities you didn't know existed. I caught several architectural mistakes in Spark during the spec-writing phase that would have been expensive to fix during implementation.

An Honest Assessment

This methodology has limitations I should name.

It takes significant effort to write a good spec. If your project is small enough to finish in one or two sessions, this is overkill. The investment pays off proportionally to how many times agents will need to re-ground on the system. If the answer is "many times over months," it's worth it. If the answer is "once," probably not.

It also assumes the human has enough architectural clarity to declare the system's structure upfront. If you're still prototyping and the design isn't stable, writing a spec too early will just produce a document that needs to be rewritten. Write it after the design stabilizes, not before.

And the feedback loop problem — specs getting stale during implementation — is real and requires discipline. The spec only works as a single source of truth if you actually keep it current. Silent divergence is the failure mode, and it's easy to fall into when you're in flow and just want to keep building.

Why I'm Publishing This Now

The agentic engineering space is in a phase where people are actively building with AI agents and actively struggling with context loss, architectural drift, and scope creep. Most of the solutions I've seen are either "just give the agent more context" (doesn't scale) or "use a framework" (adds complexity without solving the structural problem).

The Declarative System Spec is neither. It's a document methodology — a way of writing down what your system is so that any agent, in any session, can derive what it needs without conversation history. It's low-tech, framework-independent, and works with any agent or coding tool. The full standard — including the template, anti-patterns, and a worked example — is linked at the top of this post.


This started as a practical necessity — I was losing architectural coherence across agent sessions and needed a fix. The methodology emerged from the fix. The standard emerged from noticing the methodology was general enough to apply beyond my own projects. Whether it's useful to others is something I'll find out by publishing it. If you've been building with agents and hitting the same walls, I'd be curious to hear whether this framing resonates or where it breaks down for your use case.