Breaking the doom-prompting loop with spec-driven development

Published: (December 2, 2025 at 08:38 AM EST)
5 min read
Source: Dev.to

Source: Dev.to

Bringing software engineering discipline to AI‑assisted coding

Every developer using AI coding tools has experienced the loop: you prompt, the AI generates code, something isn’t quite right, you prompt again, the AI breaks something else while fixing the first issue, you prompt again. An hour later you’re deeper in the hole than when you started, caught in what’s now called doomprompting.

This is the dark side of vibe coding, Andrej Karpathy’s term for fully surrendering to AI‑generated code without really understanding it. Karpathy himself noted it’s “not too bad for throwaway weekend projects.” For anything more substantial, the approach tends to collapse.

I’ve been using spec‑kit, GitHub’s toolkit for spec‑driven development, and it’s changed how I think about AI‑assisted coding. The core insight is simple: catching problems in specifications costs far less than catching them in code.

The shift‑left principle applied to AI coding

Shift‑left testing is the idea that catching defects earlier in development is cheaper than catching them later. Everyone who has debugged a production issue knows this intuitively: finding a problem in requirements costs almost nothing, finding it in code review costs some rework, finding it in production costs a lot more.

Spec‑kit applies this principle to AI‑assisted development, but shifts even further left. Instead of catching issues through testing code, you catch them through reviewing specifications. The four‑phase workflow makes this explicit: Specify → Plan → Tasks → Implement. Each phase has a gate where you review before proceeding.

This feels familiar to anyone who studied software engineering formally. In university projects we often spent weeks on specifications and architecture before writing a line of code. The discipline felt excessive at the time, but the coding phase was remarkably smooth when we finally got there. Spec‑kit brings that same rigor to AI‑assisted development.

What spec‑kit actually provides

The toolkit is agent‑agnostic and works with Claude Code, GitHub Copilot, Cursor, and other AI coding tools. At its core it’s a set of slash commands that guide you through structured phases:

  • /specify – forces you to articulate what you’re building.
  • /plan – generates research and technical direction.
  • /tasks – breaks the plan into discrete implementation steps.
  • /implement – executes those tasks.

Each phase produces Markdown files that serve as both documentation and AI context. The specifications, plans, and task lists persist across sessions, acting as memory that keeps the AI aligned with your intent.

Spec‑kit also introduces a “constitution” (or “principles”) file that establishes cross‑cutting rules for your project: testing approach, coding standards, architectural constraints. These non‑functional requirements apply to everything the AI generates.

How the flow changes day‑to‑day work

My workflow with spec‑kit looks different from the typical AI coding loop. I spend time reviewing and editing the specifications and task list, then let the AI implement the full feature. I treat the AI less like a pair programmer and more like a developer I’m delegating work to. I review the resulting code the way I’d review a pull request from a human team member.

This mental model matters. With pair programming you’re watching every keystroke. With delegation you’re reviewing outcomes against specifications. The latter scales better with AI tools that can implement substantial features autonomously.

The plan phase has become the most valuable. The AI performs research on the technical direction, and I often learn new things from this process. More importantly, I catch misunderstandings early. In one project the plan revealed the AI assumed an IBM Cloud serverless service was deployed on a VPC—a mistake that would have been far costlier to discover later.

I no longer review every single code change. Instead I:

  1. Review specifications carefully.
  2. Let implementation run with auto‑accept enabled.
  3. Do smoke testing.
  4. Review the full changeset.

If issues emerge, I iterate through the full flow (plan → tasks → implementation) rather than jumping straight to code fixes. This keeps the specifications accurate and aligned with what actually got built.

The overhead question

Spec‑kit adds overhead. For simple tasks that overhead may not be worth it.

For larger features, however, the investment pays back. The specifications force me to think through requirements properly. Architectural problems surface during plan review rather than after I’ve invested in code. And I avoid the doom‑prompting loop because ambiguities in my thinking get resolved during specification, not through trial‑and‑error prompting.

The token usage goes up when using spec‑kit—you generate specifications, plans, and task lists before writing code. But these tokens typically pay for themselves by avoiding endless prompting where you might burn through tokens without making progress.

Prompt‑based flows versus coded pipelines

One aspect of spec‑kit’s design surprised me. My initial instinct would have been to implement most of the workflow in a traditional programming language with explicit control flow. Instead, spec‑kit encapsulates the flow in detailed prompts with minimal supporting scripts.

This works well with frontier models. The prompts describe phases in natural language, and the AI follows them reliably. The templating approach with gates provides deterministic outcomes without requiring coded orchestration nodes like those in LangGraph.

I suspect this approach would be less reliable with non‑frontier models, which lack the instruction‑following ability needed for complex, multi‑phase instructions.

Beyond the underlying model, the tools available in each AI assistant matter. The plan phase benefits from web search, codebase search, and other research capabilities. Claude Code includes these out of the box, including deep search for thorough research. Other assistants may lack some of these capabilities, and I’ve seen the most variance in plan quality when research tools are limited.

Configuring MCP tools before running through the flow also improves results. For instance, I configure tools for Terraform module registry search and cloud‑provider documentation lookup, helping the AI generate better‑informed plans.

Adapting for infrastructure as code

When I first used spec‑kit I assumed it would apply directly to infrastructure as code (IaC). As I progressed, I realized IaC has specific characteristics that need different handling:

  • Declarative nature of tools like Terraform.
  • Need to separate cloud‑agnostic requirements from provider‑specific implementations.
  • Governance concerns around security and cost that differ from application code.
  • Validation against actual cloud‑provider APIs and module registries.

To address these, I created iac‑spec‑kit and open‑sourced it. It extends the spec‑kit workflow with IaC‑specific conventions and validation steps, making the approach practical for Terraform, CloudFormation, and similar tools.

Back to Blog

Related posts

Read more »