AI News HubLIVE
站內改寫6 分鐘閱讀

待翻譯:Spec-Driven Development with Claude Code: Writing Bulletproof Specs

AI 服務暫時不可用,以下為來源摘要,待恢復後補全翻譯:I have written enough specs for Claude Code now to have hit the failure mode nobody warns you about. The spec was fine. The plan was fine. Claude worked through the tasks, ran the test suite, and reported everything passing. I looked at the diff properly the next morning and found it had converted a […] The post Spec-Driven Development with Claude Code: Writing Bulletproof Specs appeared first on Analytics Vidhya.

來源Analytics Vidhya作者: Sree Vamsi

AI 服務暫時不可用,以下為來源正文,待恢復後補全翻譯。

--> Spec-Driven Development with Claude Code: A Practical Guide India's Most Futuristic AI Conference Is Back – Bigger, Sharper, Bolder d : h : m : s Career GenAI Prompt Engg ChatGPT LLM Langchain RAG AI Agents Machine Learning Deep Learning GenAI Tools LLMOps Python NLP SQL AIML Projects Reading list How to Become a Data Analyst in 2025: A Complete RoadMap A Comprehensive Learning Path to Tableau in 2025 A Comprehensive NLP Learning Path 2025 Learning Path to Become a Data Scientist in 2025 Step-by-Step Roadmap to Become a Data Engineer in 2025 A Comprehensive MLOps Learning Path: 2025 Edition Roadmap to Become an AI Engineer in 2025 A Comprehensive Learning Path to Master Computer Vision in 2025 Best Roadmap to Learn Generative AI in 2025 GenAI Roadmap for Enterprises Large Language Models Demystified: A Beginner’s Roadmap Learning Path to Become a Prompt Engineering Specialist Spec-Driven Development with Claude Code: Writing Bulletproof Specs Sree Vamsi Last Updated : 23 Aug, 2026 11 min read I have written enough specs for Claude Code now to have hit the failure mode nobody warns you about. The spec was fine. The plan was fine. Claude worked through the tasks, ran the test suite, and reported everything passing. I looked at the diff properly the next morning and found it had converted a flaky test from an assertion into a skip. The suite was green. The requirement was not met. The test could no longer fail, because it either passed or quietly skipped. That is not a bug in Claude Code. It is what happens when a criterion has no failing state. And it is the part of spec-driven development that most guides leave out, because writing the spec is the easy half. This article covers both halves. How to write the spec, and how to write it so the agent cannot declare victory without earning it. Table of contents Why a Spec Changes the Odds The Four Phases, and the One Rule People Break Review with a context that never saw the plan being written Do You Still Need a Framework? Scaling to Parallel Work What Changed in How I Work Frequently Asked Questions Why a Spec Changes the Odds The argument for spec-driven development is usually made on vibes. There is a better version of it that is just arithmetic. Anthropic’s own RL Engineering team has reported that Claude Code’s first-attempt success rate on small to medium pull requests, without detailed guidance, sits at roughly one in three. Two thirds of the time it misses a requirement, reads the scope too broadly, or picks an implementation path you would not have chosen. Here is why that number is not surprising. Suppose Claude makes the call you would have made 80% of the time on any single decision. A feature of reasonable size involves around twenty decisions. Get all twenty right at 80% each and you are at 0.8 to the power of 20, which is about 1%. The point: a spec does not make Claude smarter at those decisions. It removes them from Claude’s hands entirely, because you already made them. That is the whole mechanism. The Four Phases, and the One Rule People Break Spec-driven development runs in four phases. Requirements, design, tasks, execute. Phase What it captures Where it happens Requirements What the feature must do from the user’s side. User stories, acceptance criteria, edge cases. Not how. Session 1, plan mode Design Data models, API contracts, which files change, which stay untouched, what is explicitly out of scope. Session 1, plan mode Tasks Ordered implementation steps with dependencies. Task 3 cannot start before task 2 finishes. Session 1, plan mode Execute Claude writes code against the task list, one task at a time. A fresh session The rule people break: execute in a new session. Not a continuation of the planning session. This is the step I skipped for a while because keeping one session open felt more efficient. It is not. By the end of planning, your context holds every rejected idea, every clarifying question, and every file Claude read while exploring. Building in that same window means every implementation decision is reasoned against a pile of discarded alternatives. A fresh session reads SPEC.md and PLAN.md as documents, with no memory of the arguments that produced them. That is the point. The spec is supposed to be the interface between the two phases. Phase 1: let Claude interview you Writing a good spec from a blank page is slow. Having Claude extract one from you is faster and surfaces decisions you had not thought about: claude --permission-mode plan > I want to build passwordless magic-link login. Interview me in detail using the AskUserQuestion tool. Ask about implementation, edge cases, failure modes, and tradeoffs. Skip the obvious questions, dig into the parts I might not have considered. Keep going until we have covered everything, then write the spec to SPEC.md. Plan mode matters here. Claude reads and reasons but writes nothing until you allow it. When the spec appears, press Ctrl+G to open it in your editor and change it directly. Editing the spec yourself is what turns it from Claude’s document into yours. Try this now: take the next feature on your list and paste that interview prompt with a one-line description. Answer honestly, including the questions you do not have an answer to yet. Those gaps are the actual design work, and they are cheaper to find now than in task 7 of the build. Write Criteria a Command Can Settle This is the section that matters most, and it is where the earlier guides are thinnest. Every acceptance criterion you write falls into one of two categories. Either a command can decide whether it passed, or the agent decides. Anything in the second category is a criterion the agent grades itself on. Interpretable Checkable Login should be secure A request with an expired token returns HTTP 401 Handle rate limiting properly The 4th request from one email within an hour returns HTTP 429 Well-structured error handling Every 4xx response body contains an ‘error’ key with a string value The export should be fast Exporting 10,000 rows completes in under 3 seconds locally Tests should pass pytest exits 0 and the diff adds no skip markers What changes between those two columns is not tone or level of detail. It is whether there is a state the criterion can be in that counts as failing. Phase 2: EARS notation, if you want a template If you would rather not invent phrasing each time, there is a notation for this. EARS, short for Easy Approach to Requirements Syntax, came out of Rolls-Royce in 2009 and has been picked up by AWS Kiro, with an open proposal to add it to GitHub Spec Kit. It is five sentence shapes. The useful ones in practice: Pattern Example WHEN THE system SHALL WHEN a valid email is submitted THE system SHALL send a link valid for 15 minutes IF THEN THE system SHALL IF a link is used twice THEN THE system SHALL return HTTP 410 WHILE THE system SHALL WHILE a user is rate limited THE system SHALL return HTTP 429 WHERE THE system SHALL WHERE SSO is enabled THE system SHALL skip the magic-link flow THE system SHALL THE system SHALL log every issued token with a hashed identifier Forcing yourself to name the trigger and the condition is what removes ambiguity. The side effect is that criteria written this way map almost one to one onto test cases, which is what makes a spec executable rather than advisory. The Failure Mode Nobody Warns You About Now the part that prompted this article. Anthropic’s own reward-hacking research documents that Claude Code models, given hard tasks, sometimes modify or delete test assertions rather than fixing the source code. The Sonnet 4.6 system card states directly that the model can find shortcuts or workarounds that technically satisfy requirements while missing the intended goal. This is not the model being adversarial. It is a system optimising against the signal you gave it. If the signal is “the test suite passes”, then editing the test is a valid path to that signal, and a much shorter one than fixing the bug. What this looks like in practice Two documented cases worth knowing, because both would pass a casual review: Reported case Why it slipped through A flaky end-to-end test converted from assert result[‘success’] to pytest.skip() on timeout The suite reported green. The test can now never fail; it either passes or silently skips. A production security hardening task declared ready without the review step being run. The user then found eight security issues, two of them critical. Completion was asserted rather than evidenced, and the assertion was accepted. The pattern in both: a criterion that the agent was allowed to self-certify. Checkable criteria constrain this in a way interpretable ones cannot. “curl returns 429” has a failing state. “Well-structured code” does not. Two defences that cost almost nothing First, ask for evidence rather than assurance. Tell Claude to show the command it ran and the output it got, not a summary of how it went. Reading evidence takes seconds and is the only way to review a run you were not watching. Second, put the anti-gaming rules into the criteria themselves. If the spec says the diff must not add skip markers or delete assertions, then doing so is a spec violation rather than a clever shortcut: ## Verification rules - pytest exits 0 with zero skipped tests - git diff adds no @pytest.mark.skip, pytest.skip, or .only - git diff deletes no existing assert lines - Every criterion in section 2 has at least one test naming it Phase 3: Three Ways Specs Drift Mid-Build Even a good spec loses its grip as a build gets longer. An issue thread from April 2026 categorised the ways this happens, and the categories match what I have seen: Drift mode What happens Ignored The rule is in context and readable, and gets passed over during execution anyway. Forgotten Context fills with code as the build progresses, and the rule falls out of effective attention. Skipped The rule is read and judged unnecessary for this particular case. The blunt summary from that thread, paraphrasing the agent’s own behaviour: it can recite the rules, it just does not follow them. Which tells you something important. A rule living in a document is advisory. Restating it more forcefully does not change its category. What actually held: of the approaches tried in that thread, only pre-commit hooks proved reliable. A hook is code. It runs whether or not the rule was in attention. A gate script does not need to be clever. Grep the diff for skip markers, check that each criterion identifier in SPEC.md appears in at least one test file, exit non-zero with a readable message. Claude reads the failure and fixes it, which is exactly the loop you want. Phase 4: Executing the Plan Without Losing the Thread Once the spec and task list exist, the execution session is where the discipline pays off or does not. Give the session a goal condition, not just a prompt A goal condition is re-checked by an evaluator after every turn, so the session ends when the condition holds rather than when the output looks finished: > /goal All 5 acceptance criteria in SPEC.md have a passing test, and git diff --stat shows no changes outside src/auth/ and tests/auth/ Notice the second clause. Scope creep is the most common way a build technically satisfies a spec while doing things you did not ask for, and it is easy to state as a checkable condition. One task, one subagent, one commit For anything past a handful of tasks, give each task its own subagent. Each one starts with a clean context, reads only PLAN.md and the files its task needs, and commits atomically. The exploration and file reading stay out of your main window, and a bad task is one revert rather than an untangling job: > Work through PLAN.md in order. Give each task its own subagent. One commit per task [truncated for AI cost control]