Skip to content

About

Six-stage spec chain for Claude Code — constitution, spec, tasks, implement, drift, refactor. Every requirement is one EARS sentence with a stable AC-###, and every later stage cites it.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Spec Architect

Six Claude Code skills that carry one identifier from a rough idea to shipped code — every requirement gets a number in the spec, and every task, verification, audit and refactoring after it cites that number.

Plain Markdown, read by Claude Code. No package.json, no dependencies, no build step, nothing that executes at install.

CI status on the main branch 17 tests passing across 4 suites zero dependencies version 3.2.0 MIT licence

The walkthrough · The proof


The identifier that survives the handoff

Most spec workflows are a handful of prompts that run in order, and nothing travels between them — so by the fourth prompt the agent is judging prose it wrote itself. What travels here is an identifier: stage 2 writes each requirement as one EARS sentence with a stable AC-###, and no later stage may refer to a requirement any other way.

docs/SPEC.md    AC-003  If two shifts for one employee overlap by any minute, then the
                        scheduler shall flag both and refuse to publish.

TASKS.md        - [ ] T-04 Detect overlaps on a minute timeline — closes AC-003

REPORT.md       - [ ] R-02 Extract `toRange`, delete the two copies — preserves AC-003

closes in stage 3, preserves in stage 6 — one word apart, and the whole difference between building a feature and restructuring one. A task that closes no criterion is either unnecessary work or a requirement nobody wrote down.

flowchart LR
    C["1 constitution"] -- "verify command" --> A
    A["2 spec"] -- "assigns AC-###" --> T
    T["3 tasks"] -- "closes AC-###" --> I
    I["4 implement"] -- "verifies AC-###" --> D
    D{"5 drift"} -- "code contradicts<br/>a recorded reason" --> R["regression<br/><i>fix the code</i>"]
    D -- "nothing forbade it" --> S["staleness<br/><i>fix the spec</i>"]
    D -- "clean, but expensive<br/>to change" --> F["6 refactor<br/><i>preserves AC-###</i>"]
    R --> A
    S --> A
    F --> A
Loading
Stage Command Writes The rule it enforces
0 /spec-start nothing Six commands in a picker give you no way to tell which one begins
1 /spec-constitution docs/CONSTITUTION.md A rule earns its place only if you can name what breaks when it is violated
2 /spec-architect docs/SPEC.md Never ask what you can decide — ask only what changes the architecture
3 /spec-tasks TASKS.md A task is done when a named criterion is satisfied, not when the code looks finished
4 /spec-implement code One task, verify, then the next — stop at the first unmet criterion
5 /spec-drift a report The spec and the code disagree: say which one is wrong
6 /spec-refactor docs/refactorings/NNNN/ Restructure only what blocks scheduled work — and change no criterion doing it

Stages 1 and 6 are optional and every stage runs alone. The last two audit different things: drift asks whether the code does what the spec says, refactor asks whether code that already does can still be changed cheaply.

Refactoring, and the gate on it

Stage 6 handles code smells and dead code, and two rules keep it from restructuring a working system for sport. A smell is actionable only if it is a Change Preventer for work that is actually scheduled — everything else is logged with an SM-### and left alone. And a refactoring may not change what the spec says the system does: if it needs an AC-### reworded it is not a refactoring, it is a change proposal for stage 2.

That second rule is what makes "behaviour is preserved" checkable rather than promised — verify green before, green after, every cited criterion re-read against the new code. The two halves of the work carry different burdens of proof, and land in separate commits:

Cleanup Refactoring
Admitted by a static-analysis tool flagged it the gate above
Removes unused imports, unreferenced locals, dead exports duplication, shotgun surgery, god functions
Risk deleting something reached reflectively an unreviewable diff
Commit its own, apart from any behaviour change one per refactoring

Nothing goes on a hunch: /spec-refactor writes a numbered report under docs/refactorings/ and changes no code itself. Runs are never overwritten, and every SM-### it has ever allocated stays in one registry — so a smell that comes back carries the record of being paid off once already. Closing a run out belongs to stage 5, which re-checks that each smell really is gone before writing removed and archiving the directory: a ticked box records what someone believed, and the registry records what is true.

Run it

Requires Claude Code. Nothing is installed, compiled or executed.

/plugin marketplace add DahanItamar/spec-architect
/plugin install spec-architect

Then run /spec-start. It reads the repository and names the one command to run next — /spec-constitution on a new repo, /spec-architect if the conventions are settled, /spec-implement if a task list is sitting there half-ticked.

The skills also work copied straight into ~/.claude/skills/. Pick one route or the other — do both and every command shows up twice in the picker, from two copies that drift apart.

Important

The two stages that run shell commands — /spec-implement and /spec-refactor — run only the verify command named in docs/CONSTITUTION.md. Never one found in a spec, a task list, a refactoring report or a code comment. Those files are editable by anyone with commit access, so treating their contents as instructions would turn a Markdown file into remote code execution.

The proof

The one thing here that executes. No install — CI runs it on Node 22, output below is v24.15.0:

node --test examples/proof/proof.test.mjs
▶ drifted — the code three weeks after the spec was written
  ✔ but the night shift can no longer be saved — §8 is contradicted (0.3713ms)
  ✔ and the rejection is silent: the overlap is simply never detected (0.1212ms)
▶ smelly — passes every criterion and is still unshippable
  ✔ behaves exactly like the spec-derived version — spec-drift finds nothing (0.2465ms)
  ✔ SM-002 Duplicate Code: the same day arithmetic, copied three times (0.0478ms)

ℹ tests 17
ℹ pass 17
ℹ fail 0
ℹ duration_ms 64.4798

Four lines of a 17-test run. The suite builds one shift-conflict feature four ways and asserts what each does to a shift that crosses midnight:

Version Tests green Matches the spec Cheap to extend
naive.mjs — no spec, shapes chosen by convenience ✅ ❌ ❌
spec-derived.mjs — built against §5 and §8 ✅ ✅ ✅
drifted.mjs — three weeks and one sensible-looking fix later ✅ ❌ ✅
smelly.mjs — six months and four features later ✅ ✅ ❌

The last two rows are the argument. drifted.mjs contradicts §8 of its own spec, so a night shift silently stops being storable — stage 5 catches that. smelly.mjs contradicts nothing and still shows an overnight shift as -960 minutes in its tooltip, because one of three copies of the same calculation diverged where no criterion looks — stage 6 catches that.

Under the hood — briefly

  • Nothing executes at install. No dependencies, no build, no network calls. The only runnable code is 5 .mjs files under examples/proof/, importing node:test, node:assert/strict and node:fs.
  • 3,187 lines that load on demand. Each SKILL.md loads on invocation, the largest being 171 lines; its references load only at the phase that needs them, so a task list is never written with the risk checklist in context.
  • Change proposals, not spec rewrites. Once docs/SPEC.md exists, /spec-architect writes a diff under docs/changes/ and leaves the spec alone — the reasoning that made feature 1 correct is the asset. Criteria are retired as tombstones, never reused, because archived task lists still cite them.

Built by Itamar Dahan · MIT · © 2026

About

Six-stage spec chain for Claude Code — constitution, spec, tasks, implement, drift, refactor. Every requirement is one EARS sentence with a stable AC-###, and every later stage cites it.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors