← Back to list

Why the Future of Software Starts with a Contract

Before a single line of code is written, the agreement between humans and AI sets the rules of the game.

Enrico Piovesan in Mastering Software Architecture for the AI Era · 2025-08-14 04:10 · 51 claps · 12.9 min read
#contract-first #ai-readable #contract-driven #software-architecture #semantic-versioning
Open on Medium ↗
Wiki topics: 🏛️ · Architecture

Why the Future of Software Starts with a Contract

Before a single line of code is written, the agreement between humans and AI sets the rules of the game.

Mastering Software Architecture for the AI Era* Part 13*

In 1793, Parisian scientists and lawmakers gathered to define the meter and kilogram, replacing hundreds of local measures with a single standard a moment of precision and unity that mirrors today’s push for AI-readable contracts in software development.

In 1793, Parisian scientists and lawmakers gathered to define the meter and kilogram, replacing hundreds of local measures with a single standard a moment of precision and unity that mirrors today’s push for AI-readable contracts in software development.

Paris, 1793. The city still echoed with the aftermath of the Revolution. Following the political upheaval, scientists and lawmakers convened at the French Academy of Sciences, not to discuss philosophy, but to focus on a more practical matter: how to measure the world.

Until then, France consisted of over 250,000 local units of measure. A foot in Bordeaux was not the same as a foot in Lyon. Grain was sold in baskets of varying sizes, and wine by barrels of different volumes. Trade was a constant negotiation, involving ongoing recalculations, and cheating was nearly impossible to detect.

The National Convention, aiming to unify the country and modernize its economy, commissioned scientists to develop a single, rational system. They looked to nature for truth, defining the meter as one ten-millionth of the distance from the equator to the North Pole, and the kilogram as the weight of a cubic decimeter of pure water. Bronze bars and platinum cylinders were cast as physical standards, stored in Paris, and replicas were sent across the country.

For merchants, it meant no more haggling over the weight of a pound. For engineers, it meant designing bridges and machines with confidence that parts would fit, regardless of where they were manufactured. For citizens, it offered a glimpse of a world where human agreement was not just written on paper, but embedded in the way reality was measured.

Software is approaching its own measurement milestone. Today, AI relies on a complex mix of formats, scattered documentation, inconsistent type systems, and business rules hidden in code. Asking it to implement a feature is like asking an 18th-century merchant to trade using six different measuring tapes, each with a different mark.

Contracts can alter that. Not legal agreements, but structured, semantically versioned definitions of capabilities, requirements, use cases, owners, and states a standard, AI-readable measure for software. The aim is not to make code more attractive for developers but to provide AI with the same foundation the metric system gave to industry: a single, trusted source of truth that removes guesswork and allows for precision at scale.

The Metric Moment for Software

In late 18th-century France, standardization was not just an abstract idea; it was a crucial survival tool. Trade conflicts, engineering mistakes, and even tax collection issues were hindered by the lack of a shared reference. The metric system addressed this problem by offering a universal, physical standard for measurement: a platinum-iridium bar in Paris that defined the meter, a cylinder that defined the kilogram, and a set of rules that made them consistent and unambiguous.

Modern software, especially in the AI era, remains pre-metric. Each team, framework, and platform defines capabilities in its own language, resulting in incomplete documentation, inconsistent API specifications, and hidden assumptions in source code. AI agents responsible for implementation must translate between these “local units” without a shared reference, leading to wasted effort, fragile integrations, and risky assumptions.

An AI-readable contract format is like the meter and kilogram in software. It captures key facts, capabilities, requirements, use cases, ownership, and open questions in a single, reliable form that both humans and machines can trust. Once the contract exists, AI agents no longer need to guess intent or reverse-engineer meaning from code. They can build, validate, and improve systems based on a standard that stays consistent even as the implementation changes.

Two parallel histories, one for physical trade and one for software development, both moving from fragmented local definitions to a unified, trusted standard.

Two parallel histories, one for physical trade and one for software development, both moving from fragmented local definitions to a unified, trusted standard.

Without this standard, AI-assisted development risks repeating the chaos of pre-metric France: inconsistent measures, constant translation, and the inability to trust results without extensive manual verification. With it, we move toward a world where generating a service, integrating a capability, or validating a change is as simple as measuring a beam with a meter stick.

What a Contract-First Development Model Looks Like

In traditional development, requirements are spread across tickets, wikis, and source code. The implementation then becomes the main source of truth, meaning anyone, human or AI, who wants to understand the system has to reverse-engineer it. That process is slow, prone to errors, and fragile.

A contract-first model flips this dynamic. Instead of code defining the truth, the contract defines the truth. The contract is written before implementation, kept up-to-date throughout development, and treated as the canonical description of what the system can do, under what conditions, and with which constraints.

A contract-first approach has three defining traits:

  1. Implementation-Agnostic. The contract focuses on what a capability accomplishes, what inputs it takes, and what outputs it provides, not on how it is built.
  2. AI-Readable by Design: It employs a standard schema that is clear, precise, and easily interpretable by machines. This includes requirements, capabilities, states, and questions that AI agents need to address before moving forward.
  3. Lifecycle-Integrated. The contract progresses through states Draft, In Review, Approved, Implemented, and Deprecated, with defined ownership and approval rules. Every code change links back to a contract version, ensuring the connection between business intent and implementation remains traceable.

Hands-On Example: Minimal AI-Readable Contract (YAML)

contract:
  id: payment-service-v1
  version: 1.0.0
  owner: "Payments Team"
  approver: "Head of Engineering"
  state: "approved"
  capabilities:
    - name: "process_payment"
      description: "Processes a payment and returns transaction status"
      inputs:
        - name: "amount"
          type: "decimal"
          constraints: ["min:0.01", "max:10000.00"]
        - name: "currency"
          type: "string"
          constraints: ["ISO-4217"]
      outputs:
        - name: "status"
          type: "string"
          enum: ["success", "failure", "pending"]
  use_cases:
    - "User completes checkout with credit card"
    - "Merchant processes refund"
  open_questions:
    - "Should partial refunds be supported in v1?"

Why this matters for AI:

  • An AI agent can parse this file, understand exactly what the service does, and generate an implementation without guessing about parameters or constraints.
  • If open_questions exists, the AI can halt execution and request clarification instead of hallucinating behavior.

In a contract-first model, the contract defines the work, drives implementation, and remains the authoritative reference throughout the system’s lifecycle.

In a contract-first model, the contract defines the work, drives implementation, and remains the authoritative reference throughout the system’s lifecycle.

Semantic Versioning for Contracts

In a contract-driven model, version numbers are more than just bureaucratic labels. They act as signals to both humans and AI, indicating changes in the system’s intent. Without clear versioning rules, you risk breaking integrations, confusing AI-generated implementations, or misaligning teams on what is actually “current.”

Semantic versioning for contracts works much like semantic versioning for APIs or libraries, but with a crucial twist:

  • The “source” being versioned is the contract, not the code.
  • Implementation changes that do not alter the contract do not change the version.
  • Contract changes, even before code is generated, do change the version

Suggested rules for contract semantic versioning:

  • MAJOR: Breaking changes in capabilities or requirements. Example: removing a capability, changing an output format, or altering constraints in a way that breaks existing consumers.
  • MINOR: Backward-compatible additions. Example: adding a new optional capability, introducing an extra use case, or providing new optional constraints.
  • PATCH: Non-breaking clarifications. Example: refining descriptions, adding more examples, or updating open questions without altering actual behavior.

Hands-On Example: Contract Version Diff

v1.0.0

capabilities:
  - name: "process_payment"
    inputs:
      - name: "amount"
        type: "decimal"
    outputs:
      - name: "status"
        type: "string"
        enum: ["success", "failure"]

v2.0.0 (Major change)

capabilities:
  - name: "process_payment"
    inputs:
      - name: "amount"
        type: "decimal"
        constraints: ["min:0.01", "max:10000.00"]
      - name: "currency"
        type: "string"
        constraints: ["ISO-4217"]
    outputs:
      - name: "status"
        type: "string"
        enum: ["success", "failure", "pending"]

Why this is a major change:

  • Adding currency As a required input, it breaks existing consumers who do not send it.
  • Adding "pending" to status changes the expected output set.

Semantic versioning communicates the impact of a change before implementation, giving both humans and AI agents the context they need to update safely.

Semantic versioning communicates the impact of a change before implementation, giving both humans and AI agents the context they need to update safely.

Turning Contracts into Code and Binaries with AI

Once a contract is defined, approved, and versioned, it becomes more than just a reference. It turns into an executable blueprint. AI agents can take this blueprint, generate implementation code, create deployment configurations, and even produce compiled binaries, all without making undocumented assumptions.

This is where the contract stops being documentation and becomes a driver for the entire delivery pipeline.

The AI-Assisted Pipeline

  1. Define the Contract Capture capabilities, requirements, and use cases in the agreed standard format.
  2. Approve the Contract Stakeholders review and resolve all open questions.
  3. Generate the Implementation AI agents transform the contract into application code, tests, and configuration.
  4. Compile or Package Code is built into deployable artifacts (binaries, containers, serverless bundles).
  5. Deploy and Validate Generated services are deployed, tested, and monitored, with validation back against the contract.
  6. Update and Re-Generate Changes to the contract trigger new builds, keeping the implementation aligned with the agreed source of truth.

Hands-On Example: From Contract to Code

Contract (YAML)

contract:
  id: greeting-service-v1
  version: 1.0.0
  owner: "Platform Team"
  state: "approved"
  capabilities:
    - name: "say_hello"
      description: "Returns a greeting for a given name"
      inputs:
        - name: "name"
          type: "string"
          constraints: ["minLength:1"]
      outputs:
        - name: "message"
          type: "string"
  requirements:
    - "Response time < 100ms for 95th percentile"
  use_cases:
    - "User requests greeting via API"
  open_questions: []

AI-Generated Implementation (Python FastAPI)

from fastapi import FastAPI
from pydantic import BaseModel, constr
import time

app = FastAPI()
class GreetingRequest(BaseModel):
    name: constr(min_length=1)
class GreetingResponse(BaseModel):
    message: str
@app.post("/say_hello", response_model=GreetingResponse)
def say_hello(request: GreetingRequest):
    start_time = time.time()
    message = f"Hello, {request.name}!"
    elapsed = (time.time() - start_time) * 1000
    if elapsed > 100:
        # Could log a performance warning here
        pass
    return GreetingResponse(message=message)

This AI-generated service respects:

  • Input constraints from the contract (minLength:1).
  • Output shape (message as a string).
  • Non-functional requirement (measuring response time to enforce < 100ms).

An AI-readable contract is not just a spec; it is the source from which code, tests, and binaries are generated, creating a closed loop between definition, implementation, and validation.

An AI-readable contract is not just a spec; it is the source from which code, tests, and binaries are generated, creating a closed loop between definition, implementation, and validation.

Living Contracts in the Development Lifecycle

A contract-first approach is not a “write it once” task. If the contract is the source of truth, it must be alive and adapt alongside the system it governs. This means the contract is:

  • Active at runtime: validated against real requests and responses.
  • Continuously updated: reflecting new capabilities, requirements, and answers to open questions.
  • A reference for monitoring: defining what “correct” looks like so anomalies can be caught early.

In this model, the contract becomes part of the operational fabric of the system. Rather than a document filed away in a wiki, it is loaded, checked, and enforced while the system is running.

Runtime Enforcement

With an AI-readable contract in place, services can perform automatic runtime validation:

  • Input validation: Ensure requests match the defined constraints.
  • Output validation: Confirm responses match the expected schema and constraints.
  • Performance checks: Monitor SLAs defined in requirements.

This ensures that even as code changes, the system continues to behave in line with the agreed specification.

Hands-On Example: Runtime Validation from Contract

Contract (JSON for runtime consumption)

{
  "capabilities": [
    {
      "name": "say_hello",
      "inputs": [
        { "name": "name", "type": "string", "constraints": ["minLength:1"] }
      ],
      "outputs": [
        { "name": "message", "type": "string" }
      ]
    }
  ]
}

Runtime Validator (Python)

import json
from jsonschema import validate, ValidationError

# Load contract at service startup
with open("contract.json") as f:
    contract = json.load(f)
# Build JSON schema from contract definition
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string", "minLength": 1}
    },
    "required": ["name"]
}
def validate_input(data):
    try:
        validate(instance=data, schema=schema)
        return True
    except ValidationError as e:
        return False
# Example usage
print(validate_input({"name": "Alice"}))  # True
print(validate_input({"name": ""}))       # False

This method ensures the contract guides both compile-time creation and runtime behavior, minimizing drift between intent and actual execution.

Why a Standard Format is Non-Negotiable

Without a standard, contract-driven development will split into countless variations. Each team might define “AI-readable" differently, leading to chaos similar to pre-metric measurement confusion. AI agents would require translators for every project, undermining the goal of a single source of truth.

A standard contract format solves three critical problems:

  1. Interoperability AI agents, developer tools, CI/CD pipelines, and monitoring systems can all consume the same contract without custom parsing logic.
  2. Portability A contract created in one organization or project can be reused elsewhere without reformatting or semantic loss.
  3. Trust Stakeholders can rely on the fact that the meaning of a contract field or structure is consistent everywhere it is used.

Minimal Standard Contract Example (JSON Schema)

The standard should be validated by machines. JSON Schema is a good choice because it is widely supported and can be extended for custom requirements.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "AI-Readable Contract",
  "type": "object",
  "required": ["id", "version", "capabilities"],
  "properties": {
    "id": { "type": "string" },
    "version": { "type": "string" },
    "capabilities": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "inputs", "outputs"],
        "properties": {
          "name": { "type": "string" },
          "inputs": { "type": "array" },
          "outputs": { "type": "array" }
        }
      }
    }
  }
}

This schema isn't the complete standard, but it illustrates how a core definition can be checked by a machine. AI agents can verify any given contract against it before trying to generate or integrate.

Cross-Team Example

  • Team A builds a payment processing service with a contract in the standard format.
  • Team B builds a checkout flow and imports Team A’s contract directly into their build process.
  • An AI assistant for Team B generates integration code directly from Team A’s contract without a single meeting or manual re-specification.

This works only because both teams adhere to the same contract schema and semantics.

A standard contract format allows AI-assisted development to cross team and organizational boundaries without translation overhead.

A standard contract format allows AI-assisted development to cross team and organizational boundaries without translation overhead.

From Developer Comfort to AI Clarity

Most existing abstractions, such as classes, types, and well-documented APIs, were designed with developers as the main audience. They prioritize human readability over machine precision. The assumption was that a human would always be there to interpret intent, resolve ambiguity, and bridge the gap between specification and implementation.

In an AI-native development model, the main user of your architecture is often not another developer, but an AI agent. This necessitates a shift in priorities:

  • Clarity over cleverness: Explicit constraints beat elegant but ambiguous abstractions.
  • Machine parseability over prose: A human-friendly README is nice, but a machine-validated contract prevents errors.
  • Disambiguation before implementation: Every open question must be resolved or stored in the contract for later clarification, rather than left to be discovered during coding.

Example: Same Intent, Two Different Representations

Developer-Optimized API Spec (human-friendly)

# process_payment(amount, currency)
# Returns: status

A developer might infer parameter types, valid values, and potential outputs from domain knowledge, but an AI cannot do so reliably without guessing or hallucinating.

AI-Optimized Contract Snippet (machine-friendly)

capabilities:
  - name: "process_payment"
    inputs:
      - name: "amount"
        type: "decimal"
        constraints: ["min:0.01", "max:10000.00"]
      - name: "currency"
        type: "string"
        constraints: ["ISO-4217"]
    outputs:
      - name: "status"
        type: "string"
        enum: ["success", "failure", "pending"]

The contract leaves nothing for the AI to guess. Every constraint and option is explicit.

Shifting from developer comfort to AI clarity means treating the contract as the primary architectural artifact, with both humans and AI working from the same unambiguous blueprint.

Shifting from developer comfort to AI clarity means treating the contract as the primary architectural artifact, with both humans and AI working from the same unambiguous blueprint.

Cultural Shift in Practice

  • Before: Developers write code, then documentation follows.
  • After: Teams define and approve the contract first, then the implementation is generated or written to match.
  • Before: Ambiguity is acceptable if it saves a few lines.
  • After: Ambiguity is a defect because it forces AI to make assumptions.

This is not about removing developers from the process. It is about enabling them to work alongside AI without friction, using a common, explicit language that both can process without misinterpretation.

The Next Decade of Contract-Driven Development

Over the next decade, contracts will shift from being a best practice in system design to becoming the central currency in software development. Just as APIs became the primary method for systems to communicate in the 2000s, contracts will become the main way for systems, teams, and AI agents to negotiate capabilities, constraints, and intentions.

What will change:

  • Tooling will speak contracts natively. IDEs, CI/CD pipelines, and observability platforms will parse contracts directly, offering code completion, automated test generation, and live validation against the source of truth.
  • Contracts will be versioned and made discoverable. Teams will publish them to registries much like container images or package libraries today, enabling reuse and integration at the ecosystem scale.
  • AI agents will collaborate through contracts. Multi-agent systems will share and negotiate these artifacts, resolving open questions before generating or modifying code.
  • Compliance and governance will be embedded. Regulatory requirements, security rules, and audit trails will live inside the contract, ensuring every generated implementation is provably compliant.

Early Signs Already Here

  • API specifications like OpenAPI and AsyncAPI are being extended with richer semantics that could evolve into full contracts.
  • Model Context Protocol (MCP) and similar efforts are experimenting with machine-readable capability negotiation.
  • Internal developer platforms are already automating much of the pipeline, once the specification is in place, contracts extend this to the entire lifecycle.

The Long-Term Payoff

A world where contracts are the primary source of truth is one where:

  • AI agents and humans can build together without guesswork.
  • Integration is a matter of sharing a document, not scheduling a meeting.
  • The implementation layer can evolve rapidly without breaking trust in the system’s behavior.

Just as the metric system transformed trade and engineering from negotiations into a predictable science, contract-driven development could turn software from an interpretive art into a precise, collaborative process between humans and machines.

Takeaways

  • Contracts are the metric system of software. They give both humans and AI a single, trusted reference for capabilities, constraints, and intent
  • AI-readable formats eliminate guesswork. By making constraints explicit, contracts allow AI agents to generate, validate, and evolve systems without hallucinating or making unsafe assumptions.
  • Semantic versioning applies to the contract, not the code. This keeps business intent and implementation aligned over time.
  • Contracts can drive the entire delivery lifecycle. From code generation to runtime validation, they provide a continuous link between what is intended and what is deployed.
  • Standardization is non-negotiable. Without a shared format, contract-driven development will fragment and lose its advantage
  • The shift is cultural as well as technical. Designing for AI as a primary consumer means prioritizing clarity, machine-parseability, and disambiguation over traditional developer comfort.
  • The next decade belongs to contracts. Tooling, ecosystems, and AI collaboration will center around them, making them the primary currency of modern software development.

Coming Next:

Living Specifications: How AI Turns Contracts into Continuous Architecture

Contracts extend beyond code generation. In next week’s post, we’ll examine how AI can keep your architecture alive long after deployment by continuously verifying behavior against the contract, detecting drift, and even negotiating changes in real time. We’ll explore runtime enforcement, shadow updates, and AI-driven approval flows that transform contracts from static agreements into active, evolving parts of your system.

[embed]Your Architecture Is Lying to You Living specifications expose the gap between what you designed and what’s really running.medium.com

🧠 Found this valuable? If this post sparked new thinking or gave you something useful to take back to your team, consider hitting the 👏 button. It also helps others discover the series.

🚀 Following along? This article is part of the ongoing series: Mastering Software Architecture for the AI Era: Designing & Building with AI-Driven Architecture Principles

[embed]Mastering Software Architecture for the AI Era This series explores how AI is transforming software architecture, offering practical insights into modular design…medium.com

Each post examines how AI is transforming the way we design, scale, and reason about software systems.


메타데이터
post_id
91b6897715b7
slug
why-the-future-of-software-starts-with-a-contract-91b6897715b7
url
https://medium.com/software-architecture-in-the-age-of-ai/why-the-future-of-software-starts-with-a-contract-91b6897715b7
canonical_url
https://medium.com/software-architecture-in-the-age-of-ai/why-the-future-of-software-starts-with-a-contract-91b6897715b7
author_url
https://medium.com/@enricopiovesan
status
ok
fetched_at
2026-07-30 20:36:18