Dieser Blogpost ist auch auf Deutsch verfügbar

TL;DR

  • Agentic Spec-Driven Development speeds up implementation, but intensifies architecture drift across system landscapes.
  • Spec-Driven Architecture turns implicit conventions into versioned, agent-readable contracts that can be enforced.
  • Domain, architecture, ops, and security contracts define boundaries, invariants, and allowed dependencies.
  • A gatekeeper skill provides contract context upfront and validates results after each workflow step.
  • Automated contract checks turn governance into a property of the process and not a guard duty.

Agentic development is currently shifting where the real bottleneck in software development sits. Anyone working today with tools like BMAD, Claude Code, or Cursor—and using structured specifications as the foundation—experiences this firsthand: implementation becomes fast, cheap, and scalable. A new service, a refactor, an additional feature unit: hours instead of weeks.

But implementation speed doesn’t solve an architecture problem. It amplifies it.

The Problem: Implicit Architecture and Distributed Systems

Imagine you’re developing a new application spec-driven with an agentic workflow. The specification is clear, the agent delivers cleanly, the tests are green. Then comes the moment when this application needs to be integrated into an existing enterprise landscape, and suddenly questions arise that aren’t in any spec: Which logging format applies here? Which auth infrastructure is used? Is this service allowed to write directly into a neighboring system’s database? Which events must it publish so other systems learn what’s happening?

These questions aren’t implementation details. They’re architecture decisions that apply system-wide and must be collectively adhered to across a distributed system. As long as you’re building a standalone application, you can gloss over them. The moment you operate in a distributed system landscape, they become mandatory.

This is exactly where the real problem begins. In most projects, architecture lives implicitly: in ADRs that nobody reads anymore, in Confluence pages that weren’t updated in the last sprint, in framework conventions that are taken for granted—until an agent doesn’t know them. The problem isn’t that this architecture is wrong. The problem is that it isn’t enforceable. No build fails because a domain boundary was crossed. No CI job reports that a forbidden dependency was introduced. Drift emerges quietly and only becomes visible when it’s expensive.

In agentic setups, the effect multiplies. Every autonomously generated unit is a new point where an architecture convention can be violated silently—not out of malice, but because the agent simply can’t know if the knowledge isn’t explicitly documented anywhere.

Spec-Driven Architecture

Spec-Driven Development is the approach of treating the specification as the primary artifact from which implementation and tests are derived. SDD describes how a system is correctly implemented. It doesn’t describe how a portfolio of systems stays coherent.

That gap is exactly what Spec-Driven Architecture (SDA) addresses.

SDA transfers SDD’s core principle to the architecture level: architecture isn’t diagrams or ADRs—it’s versioned, agent-optimized contracts. In a distributed system developed with agentic workflows, they operate on multiple levels at once:

  • Development process: Contracts for architecture, operations, or security define guardrails within which agents may implement autonomously.

  • Between systems: Architecture contracts can define permitted dependencies and communication patterns across system boundaries.

  • Within a system: Contracts for domain design can make a domain’s semantics, invariants, and interfaces binding.

SDA doesn’t replace existing governance. It automates it. What’s discussed today in architecture review boards, documented in ADRs, and corrected in retrospectives becomes, in SDA, a verifiable artifact—one that can’t be forgotten next sprint.

Contracts: Boundaries and Guarantees for Agents and Teams

A contract in SDA isn’t an abstract idea. It’s an explicit, verifiable statement about expectations, guarantees, and boundaries between domains, services, teams, and agents—an artifact treated like source code: versioned, reviewed, part of the pipeline.

Here, the term means something different from API or consumer-driven contracts like Pact. While those govern behavior between two services at the implementation level, SDA contracts operate at the architecture, governance, and domain levels. They don’t define how two services talk to each other; they define what is allowed in a system at all.

Which contracts a system needs depends on its specific requirements. There’s no definitive list. The following examples are typical for distributed systems.

Domain contracts describe a domain’s business semantics outward: which terms it defines, which invariants it guarantees, and through which API or event interfaces it may be consumed. A domain contract protects the integrity of the domain—not only against other teams, but also against agents that autonomously generate new implementations. It defines what must remain stable so consumers can rely on it. Domain contracts formalize concepts from DDD: they delineate a domain’s ubiquitous language outward and define which terms and invariants are relevant and stable for other domains—and what remains internal. What used to live in event-storming boards and in people’s heads becomes, in SDA, a versioned artifact.

Architecture contracts govern the structure of the overall system: which dependencies between modules are allowed, which communication patterns apply, where layer boundaries run. They translate implicit conventions like “we never call directly into another domain’s database” into verifiable rules that a linter or CI job can validate automatically.

Ops contracts define operational requirements that apply to every unit: metrics, tracing, logging standards. Especially when new services pop up quickly, they prevent observability from turning into a cleanup project after the fact.

Security contracts define which data classifications a service may process, which auth mechanisms are mandatory, and which compliance rules apply. This sounds like classic security overhead, but in an agentic context it becomes genuinely critical. An agent that autonomously creates a new service processing customer data has no basis—without an explicit security contract—for knowing that this data must be stored encrypted, transmitted only over internal networks, and never written to generic log output. A security contract turns exactly these requirements into a build artifact that can be checked—not a checklist someone fills out after deployment. Tools like Open Policy Agent (OPA) show this isn’t theoretical; it’s production-ready today.

Depending on context, others may be added: test contracts that define which quality gates apply to a domain, or deployment contracts that govern infrastructure requirements. The principle is always the same: implicit architectural knowledge is made explicit, versionable, and automatically verifiable—so agents and teams alike know where the boundaries are.

What Does a Contract Look Like in Practice?

The simplest way to get started is a Markdown file in the repository. No special format, no tool lock-in—just explicit, versioned knowledge that’s equally readable for humans and agents. A domain contract for an ordering domain might look like this:

### Domain Contract: Ordering


#### Owner

Team Checkout, [email protected]

#### Ubiquitous Language

- **Order**: A confirmed purchase intent by a customer, containing at least one item.
- **OrderItem**: A single product line with quantity and price fixed at the time of ordering.
- **OrderStatus**: Enum — PENDING, CONFIRMED, SHIPPED, CANCELLED

#### Invariants

- An Order always contains at least one OrderItem.
- The total price is frozen at the time of order creation and never changes retroactively.
- A CANCELLED Order cannot be reactivated.

#### Published Interface

- REST API: `POST /orders`, `GET /orders/{id}`
- Events: `OrderConfirmed`, `OrderCancelled` (schema see /contracts/events/ordering.json)

#### What this domain does NOT own

- Payment processing (→ Payment Domain)
- Inventory management (→ Inventory Domain)

#### Consumption Rules

- Direct database access is not permitted.
- Status changes only via the API — never through direct event manipulation.

This isn’t documentation in the classic sense—it’s a contract. An agent implementing a new service in the ordering domain gets this contract as context and therefore knows: which terms are binding, which invariants must be upheld, which interfaces exist, and where the domain’s boundaries lie. That’s the difference between an agent that guesses and an agent that operates within clear guardrails.

The same principle works for architecture contracts as YAML policies, for security contracts as OPA rule files, for ops contracts as part of a platform configuration. The format follows the context; the property stays the same: versioned, verifiable, part of the pipeline.

From Markdown to a Contract System

Markdown in the repository is a pragmatic start, but not the end state. When contracts grow across many domains, teams, and systems, the management question comes up: How do contracts stay consistent? How do dependencies between contracts become visible? How do agents get the right contract context at runtime?

A natural next step is a dedicated contract repository: a central place where all contracts are maintained under version control, checked for consistency, and linked to the affected domains. Changes to a contract trigger automated checks: Which consumers are affected? Which agent workflows need to be revalidated?

The next step is actively delivering contracts to agents at runtime. Instead of loading contracts statically into an agent’s context, a contract server could be provided as a tool or resource via the Model Context Protocol (MCP). The agent actively requests the valid domain contract for the ordering domain before generating an implementation. It retrieves the current security contract for customer data before generating database access. Contracts thus become not only governance artifacts, but an active part of the agentic development process: dynamic, context-dependent, and always up to date.

That’s still future work. But it’s a future whose foundation you can lay today—with a Markdown file in the repository.

Contracts in Agentic Development: The Gatekeeper

A contract in the repository is a good start. But an agent that doesn’t know that contract won’t follow it either. So the key question isn’t where contracts live, but when and how they enter the agentic workflow.

The most straightforward answer: as a skill.

A gatekeeper skill is a specialized agent that knows the relevant contracts and plays a dual role in the workflow. It is advisor and auditor at the same time. Before an implementation agent starts a task, it can consult the gatekeeper: Which terms must I adhere to in this domain? Which dependencies are forbidden? Which interfaces am I allowed to consume? The gatekeeper responds with the relevant contract context, and the implementation agent builds within the guardrails from the beginning.

At the end of each workflow step, the gatekeeper switches roles. It takes the result and validates it against the contracts: Are the domain’s invariants upheld? Does the new dependency violate the architecture contracts? Is the tracing missing that the ops contract requires? Only when the gatekeeper gives the green light does the workflow continue. Otherwise, it returns concrete feedback to the implementation agent.

---

name: contract-gatekeeper

description: Use this skill to validate implementation decisions against active

  domain, architecture, ops, and security contracts. Invoke before any

  non-trivial implementation step and after each workflow step completes.

---


### Contract Gatekeeper


You are the contract gatekeeper for this system.
You know all active Domain Contracts, Architecture Contracts, Ops Contracts,
and Security Contracts.

#### When consulted (pre-implementation)


An agent asks whether a planned approach is contract-compliant.

1. Identify which contracts are relevant to the request.
2. Respond with the relevant contract sections.
3. Return a clear assessment:
   - **green**: compliant, proceed.
   - **yellow**: risk identified, document justification before proceeding.
   - **red**: violation, do not proceed without contract change.

#### When reviewing (post-step)


An agent submits an implementation result for review.

1. Check the result against all relevant contracts.
2. Return structured feedback:
   - which contracts were checked
   - what is compliant
   - what is not compliant, with specific reference to the violated rule

#### Contracts


[Embed relevant contracts here or retrieve via MCP at runtime]

The workflow agent, in turn, is instructed so it cannot bypass the gatekeeper. It knows: before every non-trivial implementation step, I ask the gatekeeper. After every step, I have the result checked. This isn’t a recommendation; it’s part of the workflow structure.

### Implementation Agent — Workflow Instructions (excerpt)


#### Contract Compliance


Before any implementation decision that touches a domain boundary, a dependency,
or an interface: consult the contract-gatekeeper skill.

Provide: what you intend to implement, in which domain, and which resources
you plan to use.

After completing each step: submit the result to the contract-gatekeeper for review.
Do not proceed until the gatekeeper returns green, or a justified yellow
is documented.

This pattern solves both problems at once. The agent gets contract context at the right time—not somewhere as an attachment, but actively embedded in the workflow. And enforcement doesn’t happen only at the end; it’s continuous—early enough to prevent bad decisions before they’re cast into code.

The same logic works in a classic CI/CD pipeline, even if the development workflow isn’t agentic yet. A dedicated pipeline step calls an agent that checks every commit against the relevant contracts. Existing CI/CD tools only need an additional step.

That makes contracts a pragmatic entry point. Teams that haven’t switched to agentic workflows yet can still introduce contracts and immediately benefit from automated validation. The contract linter in a CI job and the gatekeeper skill in an agentic workflow are two expressions of the same principle. If you start with the CI step, you’ve already laid the foundation for the move to SDD workflows.

Governance Without Constant Objections

In most projects, governance is a role someone has to play. Someone who keeps the overview in the architecture review board. Someone who comments on the PR: “But did we actually check whether this violates our layering rules?” Someone who asks after the sprint why the new service has no tracing. That person isn’t malicious. They’re necessary because otherwise the knowledge exists nowhere.

SDA fundamentally changes this role. People who previously had to demand governance during review now get a tool that acts earlier: contracts that apply from the first commit—not only once everything is built. The responsibility stays the same. What changes is when it takes effect. When architecture decisions live in versioned contracts, when the gatekeeper skill checks every workflow step against those contracts, when the CI job validates on every commit: governance is simply there—not as control exercised by someone, but as a property of the process.

Meetings and architecture review boards don’t disappear. They regain their real purpose: making decisions, formulating contracts, consciously setting boundaries. What goes away is the constant overhead of repeatedly enforcing and explaining those decisions in every context. The architecture review board decides what applies. The rest of the process ensures that it applies.

SDA is not a framework, not a tool, not a replacement for DDD or microservice patterns. It’s a governance principle for a world in which implementation has become cheap—and architecture is the last thing keeping systems coherent.