Don't Code, Specify: Why Senior Developers Are Getting Worse Results with AI
The methodology I used to build a crypto fintech (13 apps) in 70 days, solo, with AI agents.
I’ve been writing production code for 25+ years. When AI coding tools arrived, I did what every experienced developer does: I jumped in, typed a prompt, and watched Claude generate 500 lines of code in 30 seconds.
It was beautiful. It was fast. And it was completely wrong.
Not syntactically wrong — the code compiled. But wrong in the way that matters: it solved a problem I didn’t fully define, with assumptions I didn’t make, in an architecture I didn’t want.
After months of this cycle — prompt, generate, throw away, reprompt — I realized something uncomfortable:
The problem wasn’t the AI. The problem was me.
I was treating a world-class engineer like a junior dev. “Build me a task system.” “Add authentication.” “Now make it real-time.” Each prompt was a context-free command thrown at a tool that had zero memory of my previous decisions.
That’s when I adopted Spec-Driven Development (SDD) — a methodology that changed how I build software with AI. I used it to build a 13-app monorepo with 3 APIs, 3 databases, and Kubernetes in production. Solo.
Here’s how it works.
The Illusion of Speed
Imagine hiring an extraordinarily fast bricklayer. He builds walls in minutes, installs plumbing in seconds, finishes the roof before lunch.
Now imagine you forgot to give him the blueprint.
The result? A building that stands — but with the bathroom where the kitchen should be, doors that open into walls, and stairs that lead nowhere.
This is exactly what happens with AI-assisted development without specifications.
Claude Code, Cursor, Copilot — they’re that bricklayer. They generate code at a speed that was science fiction five years ago. But speed without direction is just a faster way to arrive at the wrong place.
The real cost shows up in the math:
Without specs: prompt → generate → realize something’s missing → reprompt → break something → fix → reprompt → repeat. Total: 8-12 hours for a feature.
With specs: 2 hours of planning → generate from spec → minor adjustments → done. Total: 3 hours.
Investing time in specifications saves total time. Every single time.
Why Experienced Developers Resist This
If you have 10, 15, 20 years of experience, you’re probably thinking: “I already know what I need to build. Formal specs are bureaucracy.”
I get it. For years, best practices emphasized agility, rapid iteration, “working software over comprehensive documentation.”
But here’s the crucial difference: you’re not coding alone anymore.
When you write code, your brain holds a mental model of the entire system. You know that obscure function in utils.ts is critical because you remember the time it saved the project at 2 AM.
Claude doesn’t have that memory. Every session starts from zero. Every context is limited. The AI is extraordinarily capable, but it operates in an eternal present — no access to the decisions you made yesterday or the lessons you learned last month.
Specifications are the external memory that AI agents need.
The Four Pillars of SDD
SDD stands on four pillars, each with a human approval gate before the next phase begins:
- Requirements (WHAT)
Define what the system must do. Written in business language, focused on observable behaviors, technology-independent.
- Design (HOW)
Define how the system will work. Architectural decisions, technology choices with justifications, data models, API contracts.
- Tasks (HOW MUCH)
Decompose into implementable units. Each task: 2-4 hours, independently testable, with clear dependencies.
- Implementation (EXECUTION)
Code follows the spec. Verification against acceptance criteria. Documentation of implementation decisions.
The gates between phases are non-negotiable. The AI agent cannot advance to the next phase without explicit human approval. This ensures errors are caught before they propagate — and the earlier you catch them, the cheaper they are to fix.
The Anatomy of a Good Spec
The Smart Kid Principle
Imagine explaining your system to a very intelligent 12-year-old. She’s smart, asks good questions, and can understand complex concepts — but doesn’t have your implicit context.
You wouldn’t say: “Do that thing with the tasks.”
You’d say: “When someone creates a task, we need to save the title, check if the person has permission in that workspace, and notify everyone looking at the list that a new task appeared.”
This is exactly the level of clarity your specs need.
Be Specific, Not Generic
Bad: “The system should be fast.”
Good: “The GET /api/v1/tasks endpoint must respond in under 500ms at p95 for lists of up to 1,000 tasks.”
Define Negative Scope
What you explicitly won’t build is as important as what you will:
- This MVP does not support recurring tasks
- No Google Calendar integration (v2)
- No time tracking
- No task dependencies (subtasks only)
This prevents the AI from helpfully adding features you didn’t ask for — which happens constantly.
Use Concrete Examples
Bad: “Validate the task title.”
Good:
- "" → Error: “Title is required”
- “A” → Error: “Minimum 2 characters”
- “Fix bug #123” → Success
- “A” × 501 → Error: “Maximum 500 characters”
- ” ” → Error: “Title is required”
Anticipate Questions
Before the AI asks (or worse, assumes):
- What happens when deleting a task with subtasks? → Cascade delete, confirm with user.
- Who sees archived tasks? → All workspace members, separate tab.
- Default sort order? → Created date (newest first), then priority.
Every question you answer in the spec is a wrong assumption prevented in the code.
The Directory Structure
Before writing any spec, you need clear organization:
project/
├── .claude/
│ ├── commands/ # Slash commands
│ │ ├── spec-new.md
│ │ ├── spec-requirements.md
│ │ └── spec-design.md
│ ├── steering/ # Persistent context
│ │ ├── product.md
│ │ ├── tech-stack.md
│ │ └── conventions.md
│ ├── specs/ # Feature specs
│ │ ├── 001-auth/
│ │ │ ├── requirements.md
│ │ │ ├── design.md
│ │ │ └── tasks.md
│ │ ├── 002-workspaces/
│ │ └── 003-tasks/
│ └── agents/ # Specialized sub-agents
│ ├── architect.md
│ ├── implementer.md
│ └── reviewer.md
└── CLAUDE.md # Entry point (< 300 lines)
The CLAUDE.md file is the entry point — concise, using imports for details. The steering files provide persistent context about the product, tech stack, and conventions. Each feature gets its own spec directory with the three documents: requirements, design, tasks.
The EARS Format for Requirements
EARS (Easy Approach to Requirements Syntax) eliminates ambiguity:
Ubiquitous (always true): The system SHALL validate workspace permissions on all task operations.
Event-driven (when something happens): WHEN a task is marked complete, the system SHALL record timestamp and completing user.
Unwanted behavior (error handling): IF the user attempts to create more than 50 subtasks, the system SHALL display “Subtask limit reached.”
State-driven (based on state): WHILE a task is archived, the system SHALL NOT allow edits.
Conditional: WHERE the workspace has notifications enabled, the system SHALL notify assignees when a task is modified.
Each requirement gets a MoSCoW priority: Must Have, Should Have, Could Have, Won’t Have. This gives the AI — and you — a clear implementation order.
Specialized Sub-Agents
SDD works even better when you define specialized roles:
Architect — Makes technical decisions, designs interfaces, identifies trade-offs. Never writes implementation code.
Implementer — Follows the spec exactly. Writes tests alongside code. Stops when encountering ambiguity instead of assuming.
Reviewer — Checks conventions, types, error handling, test coverage, security vulnerabilities, performance.
Each agent has a markdown file defining its role, responsibilities, and rules. This prevents the AI from context-switching between design thinking and implementation thinking within a single conversation.
What SDD Is NOT
It’s not Waterfall. Specs in SDD are living documents — they evolve, but in a controlled way. You can go back and modify requirements, but changes propagate consciously through design and tasks.
It’s not overkill for everything. Use SDD when the project lasts more than a few days, involves multiple complex features, requires careful architecture, or spans multiple development sessions. For a one-hour script, just prompt and go.
It’s not about documentation for documentation’s sake. Every line in a spec exists to prevent a wrong assumption in the code. If a line doesn’t serve that purpose, delete it.
The Results
I built a complete crypto fintech platform using SDD — payment gateway, OTC exchange engine, OAuth 2.1 auth server, multi-tenant architecture, Kubernetes deployment. 13 apps in a monorepo, 8 shared packages. Solo developer.
The specs were the multiplier. Not the AI — the specs.
Without them, Claude Code is a fast bricklayer without a blueprint. With them, it’s a senior engineer who happens to have perfect recall of every decision you’ve made.
Getting Started
Start small. Pick one feature. Write the three documents:
-
requirements.md — What does it do? For whom? What are the acceptance criteria?
-
design.md — How does it work? Data model, API endpoints, architectural decisions.
-
tasks.md — Break it into 2-4 hour implementable chunks with clear dependencies.
Then hand it to your AI agent and watch what happens.
You’ll never go back to naked prompting.
I’m a practitioner of SDD — not the creator. My authority comes from applying it at scale: 13 apps, 70 days, solo, production.
I’ve trained 30,000+ developers in software engineering and 400+ professionals in AI-augmented workflows. SDD is the methodology I use daily with Claude Code — structured specs as the single source of truth for AI-generated implementations.
If you’re building with AI and fighting the “generate → throw away → reprompt” cycle, try SDD on your next feature. The first spec takes time. The second one takes half as long. By the third, it’s muscle memory.
The code writes itself. The spec doesn’t.
— Felipe