Simon Martinelli has been a Java consultant in Switzerland for 17 years, working with insurance companies, wholesale, retail, and government. He works on ERP systems with thousands of database tables, not demo apps.
In a talk at a recent Java community event, Martinelli shared what happened when he took spec-driven development (SDD) into six customer engagements. Not experiments. Not side projects. Production modernization work for the largest wholesale company in Switzerland, the Swiss parliament, and multiple insurance firms.
His conclusion: specs fix the one thing that breaks AI-assisted development at scale. But only if you rethink three things first: your architecture, your team structure, and what you put in your system prompt.
The full talk is available here: Lessons Learned from Spec-Driven Development.
The Problem With Vibe Coding at Enterprise Scale
Martinelli started the same way many developers do. Someone at his sports club asked him to build a volunteer management system. He used an AI agent (Windsurf), and it was fast. By fall 2024, he had a working application.
Then another club wanted the same thing, with different features. And he realized he had no idea what he had built. The code existed, but the intent behind it was gone. There was no specification to modify. Changing features meant reverse-engineering his own AI-generated code.
This is the core failure of what Andrej Karpathy called "vibe coding" in February 2025. It works for isolated tasks. It breaks the moment someone asks "can you also make it do X?" and you cannot answer because you never wrote down what it does now.
According to an analysis by DevToolLab, three failure modes appear consistently once teams scale AI-assisted coding beyond toy projects:
- Intent drift: The model picks reasonable defaults that differ from what the team wanted. Nobody catches it because the code looks correct.
- Hallucinated interfaces: The agent invents an API method or database column that does not exist. It compiles. It fails at runtime.
- Context collapse: On tasks spanning multiple sessions or files, the agent loses track of earlier decisions and contradicts itself.
The spec-driven development movement says the fix is not better prompts. The fix is writing down what you want before you let the agent touch code. Early adopters report 3-10x higher first-pass success rates from AI agents on non-trivial tasks using this approach, according to DevToolLab's June 2026 analysis.
Why Use Cases, Not User Stories
Most agile teams work with user stories. Martinelli argues this is a problem for AI-assisted development.
User stories are too small and too informal. "As a user, I want to search for veterinarians so I can book an appointment" tells the AI almost nothing. Which fields? What happens when the search returns zero results? What is the sort order? The agent will guess. Sometimes the guesses are wrong.
Martinelli went back to use cases. The original concept invented by Ivar Jacobson in 1987, later formalized in UML.
Martinelli credits an article on Tessl's AI-native development site (ainative.dev) and a piece by Simon Maple for introducing him to spec-driven development with AI. At the time, the concept was new enough that he had to figure out what "specs" meant for business applications himself.
A use case has a defined structure:
- Preconditions: What must be true before the use case can execute
- Main success scenario: The happy path, step by step
- Alternative flows: What happens when things deviate
- Postconditions: What must be true after successful execution (these double as acceptance criteria)
Here is the key insight: AI already knows how to write use cases. The format has existed for nearly 40 years. Every major language model trained on software engineering data has seen thousands of use case examples. You do not need to teach the format. You just need to fill in the content.
Martinelli demonstrated this using the Spring Pet Clinic, the standard demo application for the Spring Framework. He reverse-engineered the existing application into use case diagrams and entity models, then asked the AI to regenerate the implementation. The result was working code, produced in about 90 seconds.
Martinelli is doing this on real ERP systems. The same approach works on applications with hundreds of tables and dozens of modules, because the use case structure scales.
Use cases define behavior. But behavior operates on data. Martinelli pairs every use case with an entity model (effectively a domain model) that defines the data structures. The use case says "list all veterinarians with their specialties." The entity model says a Veterinarian has a first name, last name, and a list of Specialties. Together, these two artifacts form the specification, and the AI generates code from both.
This is where Martinelli's approach diverges from tools like GitHub Spec Kit or Amazon Kiro. Those tools follow a multi-phase pipeline: product requirements document to plan to tasks to implementation. Martinelli skips the intermediate steps. He goes directly from use case plus entity model to code.
The order of code and test generation depends on the type of system. For APIs, Martinelli uses test-driven development: tests first, then let the tests drive code generation. For full-stack applications with a UI, TDD is impractical because you first need to figure out what the UI looks like before you can write tests for it. In those cases, code comes first, tests second.
Self-Contained Systems: The Architecture That Makes AI Work
Martinelli argues that your architecture determines whether AI-assisted development works or fails. And most enterprises have the wrong architecture.
Here is the problem. Over the past 15 years, teams built microservices. Many went overboard. Martinelli cites one insurance company with approximately 500 microservices and 500 corresponding micro frontends. That is an N-to-M relationship between frontends and backends.
When you want to use AI on part of that system, you need context. The AI needs to see all the relevant code in one place. With 500 microservices scattered across repositories, gathering that context is a nightmare. You spend more time feeding context to the agent than it spends generating code.
On the other end, a massive monolith is equally bad. Martinelli's ERP modernization project has thousands of database tables. The context is too large for any agent to work with effectively.
His recommendation is an architecture called Self-Contained Systems (SCS). Created around the same time as microservices but far less known, SCS splits an application into vertical slices. Each slice has its own UI, business logic, and database in one repository. You can find the formal definition at scs-architecture.org.
The sweet spot for AI-assisted development is a self-contained system small enough that the AI can see all the relevant code in its context window. Martinelli's teams work on one SCS at a time, with technology stacks that can vary per slice. The inventory module might use Vaadin and Spring Boot. The order management module might use React and Spring Boot. Each has its own skills and guidelines.
Stop Stuffing Everything Into CLAUDE.md
Martinelli has a strong opinion about how teams configure AI agents. Most developers put all their project rules, conventions, and documentation into a single large file. Claude Code uses CLAUDE.md. Other tools use AGENTS.md or similar.
Martinelli says this is wrong, and he cited a study from ETH Zurich claiming that the larger the system prompt, the more hallucinations the model produces. (The specific paper was not named in the talk.) Martinelli's conclusion: it may be better to have no instruction file at all than a bloated one.
Instead, he uses skills. Skills are modular, focused instructions that the agent loads only when relevant. A skill for generating Spring Boot REST controllers. A skill for Vaadin UI patterns. A skill for Liquibase migrations. Each skill is small, specific, and iterated on over time.
He also uses MCP (Model Context Protocol) servers for large documentation. Instead of stuffing framework docs into the prompt, an MCP server lets the agent search the documentation on demand. This keeps the context small while still giving the agent access to the information it needs.
For project scaffolding, Martinelli is blunt: never let AI create the project. Use the official tools. For Spring, that means start.spring.io. For other frameworks, use their CLIs. AI-generated project scaffolding wastes tokens and often produces outdated configurations. Set up the project yourself, then let the AI work within it.
Brownfield Modernization: Reverse Engineering Specs From Code
Most of Martinelli's work is not greenfield development. He modernizes existing systems. COBOL applications, legacy Java monoliths, ERP systems running for decades.
His approach works like this. Instead of trying to translate code directly from one technology to another (which he says has never worked, despite 30 years of attempts), he reverse-engineers specifications from the existing system.
The process:
- Extract use cases and entity models from the existing code, tests, and documentation (Confluence, Jira, whatever exists)
- Review and revise the specifications with business stakeholders
- Generate new code from the revised specifications
This has a side effect. Because the team goes through the specification phase, they can integrate new features that were not in the original system. The modernization becomes more than a technology swap. It becomes a chance to rethink how users interact with the software.
Martinelli notes that the initial guideline for his current ERP modernization was explicit: "we want the exact same system in new technology, no new features, because we do not want to introduce bugs." With the spec-driven approach, they can finally add improvements because they are changing the specification, not the code directly.
How Teams Change
His teams have dropped from 5-7 developers per module to 1-2 developers per self-contained system. He prefers two for knowledge sharing, but the work is now small enough that one developer with strong AI tooling can handle a system.
They no longer run Scrum sprints. The two-week sprint cycle does not make sense when implementation takes minutes instead of weeks. Instead, they use continuous flow with a Kanban-style board tracking use cases. The specification phase still takes weeks, but the implementation phase that follows is dramatically shorter.
Martinelli describes the shift: "We need maybe two weeks to do the specification, but we do not need two weeks to create the software." The work has shifted left, toward requirements engineering and specification.
He also mentions that they have stopped doing pull requests in these projects. Instead, they use trunk-based development with continuous peer review. Two developers work together, explain what they built, and review each other's work in real time.
Risk-Based Review
If the AI writes code in 90 seconds, can a human review it fast enough? Martinelli's answer is risk-based review. In his ERP system, the inventory module failing means workers take a coffee break. The order management module failing means the company loses money. The amount of human review should match the risk. This is not different from manual development, just risk management applied to a new context.
The Tools Landscape
Martinelli's process-centric approach exists alongside several tool-driven approaches to spec-driven development:
| Tool | Approach | Key Detail |
|---|---|---|
| AI Unified Process (Martinelli) | Process-centric, enterprise-focused | Use cases + entity models, skips plan/task phase |
| GitHub Spec Kit | Tool-driven, open-source | 123,000+ GitHub stars as of July 2026 (source) |
| AWS Kiro | IDE-integrated, SDD-native | Launched internationally May 2026, uses EARS notation for requirements |
| BMAD Method | Framework-driven | Community-driven, agent-agnostic |
An arXiv paper published in January 2026 formalized the field, identifying three levels of specification rigor: spec-first, spec-anchored, and spec-as-source. Martinelli's approach sits firmly in the spec-as-source category, where the specification is the primary artifact and code is generated from it.
What This Means
Martinelli's talk is not about a tool. It is about discipline: writing down what you want before you generate code, keeping system prompts small, choosing architectures that give AI enough context without overwhelming it, and rethinking team structures for a world where implementation is no longer the bottleneck.
There is a forward-looking angle here too. If your specification exists independently of your code, you can regenerate the same application in different technologies. Today it is Spring Boot and Vaadin. Tomorrow it could be React and Quarkus. The use cases and entity models stay the same. Martinelli even speculates about a future where the specification generates a chat interface instead of a traditional web UI. That is speculative, but the underlying principle is sound: when the spec is the source of truth, code becomes a choice rather than a constraint.
The teams that figure this out will ship faster. The teams that do not will keep debugging AI-generated code they do not understand.
Sources:
- Simon Martinelli, "Lessons Learned from Spec-Driven Development" talk: https://youtu.be/odbNXv9xXjc
- Tessl, AI-native development: https://ainative.dev
- GitHub Spec Kit repository (123,235 stars as of July 22, 2026): https://github.com/github/spec-kit
- Piskala, D. B. (2026). "Spec-Driven Development: From Code to Contract in the Age of AI Coding Assistants." arXiv:2602.00180: https://arxiv.org/abs/2602.00180
- Self-Contained Systems architecture: https://scs-architecture.org/
- DevToolLab, "Spec-Driven Development in 2026" (June 25, 2026): https://devtoollab.com/blog/spec-driven-development-ai-agents
- AWS Kiro: https://kiro.dev/
- Ivar Jacobson, use case origin (1987): https://www.ivarjacobson.com/sites/default/files/2018-06/OOSE.pdf
Top comments (1)
Spec-driven AI works best when the spec is treated as an operating boundary, not a prompt appendix. The model can move faster, but the team still needs a stable source of truth for scope and acceptance.