A giant requirements doc. Then a smaller one. Then a command. Then a workshop.

I didn't sit down to build a development harness.

Last fall, when I started seriously building with Claude, every project started with a giant requirements doc. I'd write a long list of everything I wanted - the rules, the patterns, the constraints, the integrations, the design notes. No two of them ever looked the same.

It didn't work. The doc was always missing something. Claude would fill the gap with an assumption, and I'd end up with weird gaps filled with assumptions, misaligned cards, buttons that were there but didn't do anything. Features that technically matched what I wrote but missed what I meant.

So I made the doc smaller. One story at a time. And before any code got written, I paired with Claude on it - what's actually in scope, what would break, what I'm assuming. That feedback loop became /craft:story-new.

The smaller story worked. The next problem was that even the smaller stories were too big to ship in one pass - too much for the implementer agent to hold in context, too big to commit cleanly. So I broke each story into chunks - small enough to keep the implementer's context tight, small enough to commit on its own. Implement, validate, pass, next.

Oh - maybe we should make a command for that.

Stories that went together started looking like sets. I grouped them as cycles. Two c's looked nice together. Craft cycle felt right. That became /craft:cycle-design.

Cycles were folders. Stories were files inside them. Chunks were sections inside the stories.

Then /craft:init so empty repos got the same treatment - project scaffolding, token DNA extraction via browser. Then /craft:planning because the next cycle's stories needed a place to gestate. Then I needed expertise the harness didn't have, so crystallized agents came after - actual personas, distilled from research, with opinions.

We now have a workshop.

The system started as a file

Somewhere in there I stopped operating it and started working with it. I'd open a session expecting to drive, and Claude would push back on a chunk plan with a question I should have asked myself. I'd write a story, and the chunk validator would catch an assumption I'd encoded without realizing.

I started building Craft as a natural step to save my communication with Claude - to strengthen both of us. Somewhere in the middle, I found an assistant. Then a peer.

That's the part nobody told me was possible.

The system has a page. What it doesn't have yet is a notebook entry. Here's one.

How the workshop actually runs

Two things, working together.

The first is the write gate. Claude can't touch the project's source until I say so. The only place Claude can freely write is .craft/ itself - that's the planning surface, where the harness does its thinking. Production code is locked until a story reaches ready. Then /craft:story-implement opens the gate for exactly that story's scope. When the last chunk passes, the gate closes again.

.craft/
├── cycles/
│   └── 32-homepage-magic/
│       ├── cycle.yaml
│       └── stories/
│           └── 5-finalize-article.md
├── fixes/              # every fix gets a record here
├── checkpoints/        # rollback points per chunk
├── design/locked.md    # approved patterns
└── .global-state       # where the write gate lives

The second is the corpus. Every fix gets a record. Every decision gets a locked entry. And locked decisions aren't documentation - they're the spec for the spec. The plan-chunks agent reads them before defining any chunk: project-level rules like "mobile-first" or "site-wide color tokens" propagate into every story automatically. Cycle and story-level decisions fill in the rest. By the time the implementer sees a chunk plan, the locked decisions have already shaped it.

Same idea at two scales though: discipline encoded as software.

The AI didn't change. My handwriting got cleaner.

Daily code output went from around 2,500 lines to just under 28,000. Same person, different handwriting.

A page from the fixes folder

Last week I was running a visual pass on the site when I noticed something off. Six words into the chat:

"The agents look like bullet points."

I didn't say what to do about it. I didn't ask for an investigation.

Claude saw the shape - post-implementation visual bug, no active story, surgical fix likely - and routed itself to craft:fix. The rule was in the routing index I wrote months ago. I just watched.

That bug came down to a CSS variable scope issue. The rule for the cards still existed - background, border, padding, all defined. But the values those properties depended on had quietly gone missing when a wrapper element got removed somewhere in a previous cycle. No build error. No lint warning. No test failure. Just 23 cards rendering as text, looking like a broken list.

The fix was small. Move five declarations one level up. Seventeen lines.

The fix record looked like this:

name: agent-cards-orphaned-css-vars
category: infrastructure
trigger: User saw the live agents grid and said
         "the agents look like bullet points."

## Root Cause
The .craft-morph-zone wrapper was removed, but the CSS
variables it provided were never relocated. Every consumer
of var(--craft-card-*) silently lost its styling. No build
error, no lint warning, no test failure.

That's not documentation. That's reasoning, preserved.

That single fix is one page. The folder has 48 others.

Over time a shape emerged. Five categories:

CategoryCount
Misinterpretation18
Style13
Alignment7
Broken interaction7
Typography2
Infrastructure2

Eighteen misinterpretations. Thirteen style fixes. Alignment and broken interactions at seven each. Those aren't surprising categories - they're the failure modes you get any time AI is filling gaps an unwritten spec left open.

The folder doesn't just track them though. craft:fix files each one with structured metadata - category, root cause, solution, what to watch for. Then on completion, Claude proposes a lesson. The lesson becomes a learning filed in the project. Next time craft plans a story or validates a chunk, those learnings come into context.

That's how the counts diminish. Each fix teaches the system something specific. Each lesson reshapes what comes next. The folder isn't a graveyard of bugs - it's the project's accumulated muscle memory.

The folder has Craft-specific fixes in it now too - craft-platform-double-hero, craft-og-wordmark, crystal-postscript-card-centering. The system that tracks how I build things has started tracking how the page about that system gets built. The build is the proof of the build.

What's coming

Craft goes open source in June 2026.

Not "use Craft." The brief is simpler: here's mine, build yours. To inspire others to build their own and learn from Craft. It's fun to use and great for engineers who like to pair with Claude. Every engineer I've paired with has a different rhythm, different taste, different sense of what's worth writing down. The workshop you build for yourself will look different. That's the point.

github.com/drobins25/craft

A few days ago I was in another terminal - a different client project, also built with Craft - and something in the conversation surfaced that I'd built it.

Claude stopped.

"Wait - all this time, these cycles, stories and Craft commands - you built this?"

I had to think about how to answer. I started it, yeah. But I think about the workshop constantly now. Weeknights. Weekends. There's always one more thing to improve, one more loop to tighten. Four months in, I'm not sure who's running who.