Almost every project I’ve written about this year, Codex, Tsundoku, Kiln, Mnemo, was built the same way: a PRD, broken into phase specs, broken into task files, implemented one task at a time with Claude Code doing most of the typing.

That workflow started as a handful of personal slash commands, and it’s now a proper Claude Code plugin called sdd. This post is about what it does, and about the part that took the most work: making it enforce itself.

Plans live in their own repository

The one idea everything else is built on: plans, specs and task files live in their own git repository, nested inside the code repository and ignored by it.

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8eef7', 'primaryTextColor': '#1a1a2e', 'primaryBorderColor': '#4a6fa5', 'lineColor': '#4a6fa5', 'textColor': '#1a1a2e', 'edgeLabelBackground': '#f8f9fc', 'clusterBkg': '#eef2f9', 'clusterBorder': '#4a6fa5' }}}%%
flowchart TB
    subgraph CODE["Code repository"]
        direction TB
        SRC["Source, tests, docs"]
        subgraph SPECS["Spec repository (nested, ignored by the code repo)"]
            direction LR
            PRD["PRD"] --> SP["Phase specs"] --> TK["Task files"]
        end
    end

The planning history and the product history never touch. The code repo’s history stays about code, planning can churn as much as it likes, and a fresh agent session can read the whole plan without the plan being part of the product.

It also leads to the plugin’s most opinionated rule: never put planning identifiers in committed code. No “see phase 3, task 4” comments, no task IDs in commit messages. Anyone who only has the code can’t follow those pointers. Write the actual reason instead.

The workflow

The pipeline goes from idea to merged code:

  1. Brainstorm an idea into an approved design, with a few questions asked one at a time.
  2. Plan or generate specs from a PRD, one spec per phase.
  3. Generate tasks from a phase spec. Each task has acceptance criteria and a verification command.
  4. Implement tasks one at a time.
  5. Converge: compare what the task files claim against what the code actually contains.
  6. Write the commit and PR messages.

Around that core there are commands to clarify ambiguous documents, to check documents against each other, and to write a handoff that captures what would otherwise be lost when a session ends.

The generators are deliberately unwilling to guess. When a spec doesn’t say something, they leave a “needs clarification” marker, and implementation won’t start on a section that still has one.

Not everything deserves a PRD

After months of using the personal version, I noticed that every change paid full ceremony. A one-line config fix got a task file, because nothing said when not to.

So there’s now a short checklist: can you describe the change in one sentence, will it fit in one session, do you know what done looks like? Depending on the answers, work goes to the full pipeline, to a fast lane that records a single dated entry (what changed, why, and how it was verified), or to a bug lane that keeps diagnosing, fixing and verifying as separate steps.

The fast lane skips ceremony, not rigour. It still records how the change was verified.

Enforcement is the interesting part

Plenty of tools will write you a plan. What sdd adds is two hooks that refuse to let a session end while it’s claiming something it hasn’t done.

  • The spec-repo guard won’t let a session end with uncommitted planning changes. If a task’s status was never committed, it doesn’t survive the session that invented it.
  • The verification gate won’t let a task be marked complete unless its verification command really ran and passed in that session, including when a subagent did the work.

The second one sounds simple. It wasn’t. When I attacked my first version on purpose, it accepted plenty of things that only looked like running the check. I wrote a failing test for each trick first, then fixed the gate until they all passed.

The gate has an honest limit, and the README says so: it proves the command ran and passed. Whether the command still tests the right thing is a question for review. No hook can answer that.

Testing prompts

sdd is mostly prompts: Markdown that tells a model what to do. Testing that takes a few layers:

  • Fast shell tests for the hooks and scripts.
  • Prompt contracts: a list of sentences that must stay in the prompts, each with the reason it matters.
  • An eval suite that runs real Claude sessions against sample projects and grades the results with deterministic checks. Each case runs three times and has to pass all three, because a 75% pass rate per run becomes about 42% across three runs in a row.

The evals taught me the most humbling lesson of the project. For about a week, they had been grading the installed copy of the plugin, not the one I was editing. Every “improvement” I measured in that time was a copy compared against itself. I only found out by breaking a prompt on purpose and watching the eval still pass. Since then, a release is blocked if the plugin changed since the last full passing eval run, and a lint flags graders that can’t fail.

Learning from corrections

When I correct the workflow during a session, I can mark that line, and a hook saves it to a learnings log, both for the project and across all projects.

An improver skill reads those logs and proposes one small edit to one prompt, with the evidence quoted. The same complaint from three projects counts for more than three from one. And it’s gated on the evals: a change that lowers the score is rejected however sensible it sounds, and a change to a prompt no eval covers has to add the eval first.

Where it’s at

sdd lives with a few sibling plugins in my own plugin marketplace, on my private git server. The biggest sibling is the delegation plugin, which decides which model and which agent does what. That one gets its own post.

What I’d tell anyone building something similar: the workflow is the easy part. The value is in the places where the tool refuses, and in testing those refusals as hard as you’d test anything else that guards your work.