Stop Writing CLAUDE.md From Scratch
Every agentic codebase starts with an empty CLAUDE.md and fills it with hallucinations. Here's the six-file harness signum scaffolds for you.
A month ago I wrote about spec drift — what happens when an agent reads a stale project.intent.md and treats wrong facts as ground truth. The fix was a reverse diff: derive what the spec should say from the code, compare it to what it says, classify drift section by section.
That post answers: the spec exists and rotted, what now?
The question that bugged me afterwards: what about projects where the spec doesn’t exist yet?
Open any new repo started with Claude Code in the last six months and you will find the same artifact: a CLAUDE.md (or AGENTS.md, or .cursor/rules, or .github/copilot-instructions.md) with three lines that read like a placeholder. “This is a Python project. Use type hints. Run pytest.” The agent dutifully reads it, fills the gaps with assumptions, and ships a feature based on what a generic Python project usually looks like — not what this project actually is.
This is not spec drift. This is spec absence. And it shapes the agent’s first 50 commits.
Why one file isn’t enough
When you only have CLAUDE.md, every question the agent asks ends up there. What’s the architecture? What can break? What’s the merge bar? Who owns what? The file becomes either a 4000-word kitchen sink that no one updates, or a 200-word stub that answers none of them.
I watched this pattern in five of my own projects. The CLAUDE.md said “the architecture is event-driven” and the agent confidently designed a new feature around an event bus. There was no event bus. The phrase had been copy-pasted from a template six months earlier.
The deeper issue: agents need typed inputs. A reviewer agent asking “is this safe to merge?” needs different context than a contractor agent asking “what’s in scope?” Cramming both into one file means each ends up with a partial answer. The agent fills the rest from training-data priors.
The six-file harness
/signum init --harness generates six harness documents, each answering one specific question that an agent will ask:
| File | Question it answers |
|---|---|
AGENTS.md | Where do I read first? What rules override defaults? |
ARCHITECTURE.md | What is this codebase actually shaped like? |
docs/PLANS.md | What’s in flight right now? |
docs/RELIABILITY.md | What must keep working? How do I know it broke? |
docs/SECURITY.md | What’s the threat model? What can’t I touch? |
docs/QUALITY_SCORE.md | What’s the bar for “done”? |
Six files, each with frontmatter (status: draft, owner: TODO, last_reviewed: <date>, review_cadence: quarterly), each with a fixed set of sections that map to a real agent decision.
The frontmatter matters. last_reviewed is the freshness signal: when an agent reads RELIABILITY.md two quarters after creation and sees last_reviewed: 2026-01-15, it knows the doc is past cadence and should be sanity-checked rather than trusted blindly. This is the same insight from the spec-drift post — verified-on date beats edited-on date — applied at bootstrap.
What deterministic actually means here
The scaffold is generated by a bash script (lib/init-harness-scaffold.sh) reading from checked-in templates (lib/templates/init-harness/*.tmpl) — not by a model. Same project root, same date, same output. No LLM creativity in the scaffold step.
This is a deliberate split. The structure (sections, frontmatter, table headers) is deterministic and template-driven. The content (what goes in each section) is LLM-assisted in a follow-up step or written by hand. By separating them, the scaffold itself never drifts: every project gets identical headings, identical section order, identical evidence pattern. Diffs across projects become comparable.
In v4.21 we extracted the templates from inline heredocs into checked-in .tmpl files. Boring change, but it means the templates are code-reviewable as their own surface — golden tests assert byte-for-byte parity.
Brownfield-safe by default
The fear with any “init” command is that it stomps on real work. init --harness doesn’t:
- If
project.intent.mdexists, it is preserved. - If
project.glossary.jsonexists, it is preserved. - If any of the six harness files already exist, they are preserved.
- Only files actually missing get scaffolded.
- Only
--forcebypasses these checks.
The behavior is brownfield-first. If you ran init --harness on a four-year-old codebase that already has half the docs, you get drafts only for the missing half. The existing docs stay untouched, even if they are stale or wrong. Spec drift is init --actualize’s job, not init --harness’s.
What the scaffold gives you (and what it doesn’t)
A scaffolded RELIABILITY.md looks like this:
---
status: draft
owner: TODO
last_reviewed: 2026-04-27
review_cadence: quarterly
---
# myproject -- Reliability
## Critical User Journeys
- TODO: List the flows that must keep working for the product to be viable.
- TODO: Link tests, smoke checks, or dashboards that cover each flow.
## Service Levels
- TODO: Define availability / latency / throughput goals if they exist.
- TODO: Record error budgets or acceptable degradation rules.
## Failure Modes and Recovery
- TODO: Top known failure modes.
- TODO: Detection signal for each failure mode.
- TODO: Recovery / rollback procedure for each failure mode.
It is not finished documentation. It is a typed prompt for the human (or a follow-up agent) to fill in. The TODOs are pinpointed: not “describe reliability” but “list the flows that must keep working.” Every prompt forces you to put a fact, not a paragraph of mood.
The structure also makes the gap visible. If you scaffold RELIABILITY.md and three months later the section “Failure Modes and Recovery” is still all TODOs, that is a real signal — your team has no documented failure modes, and an agent shipping changes to that surface is doing it without context.
Why six and not three (or twelve)
Six is the smallest set that doesn’t collapse two unrelated agent questions into one file. I tried smaller. Combining RELIABILITY.md and SECURITY.md into a single OPS.md pushed the doc past the point where an agent could find a specific failure mode without scanning the whole file. Combining PLANS.md into AGENTS.md made the latter rot weekly.
I also tried larger. Splitting ARCHITECTURE.md into DATAFLOW.md + MODULES.md + BOUNDARIES.md produced three half-empty files. Most projects don’t have enough architecture to justify three docs, but they do have enough to justify one.
The split that survived: one file per agent decision, never one file per topic. That is the design contract.
What it doesn’t replace
init --harness does not generate project.intent.md. That file is the contract surface for Signum’s pipeline — used by the contractor agent to derive scope and acceptance criteria — and it has its own bootstrap path (signum init plain) that uses the code scanner, not the harness templates.
Harness docs are human-and-reviewer surfaces: they shape how a reviewer agent thinks about merge gates, how a contractor frames non-goals, how an engineer agent decides whether a change crosses a reliability boundary. They are not the contract itself.
The two interlock. project.intent.md says “what this project does.” The harness says “how this project is run.”
Try it
claude plugin install signum@emporium
cd your-project/
claude "/signum init --harness"
You’ll see six draft files. Review them, fill the TODOs, commit. If you already have one of them, it is preserved — only missing files get scaffolded.
If your existing harness has drifted, that’s init --actualize’s job from the earlier post. Different surface, same underlying logic: derive what the doc should say from the code, classify the gap, write only what you accept.
Most agentic projects fail their first month not because the agent makes bad code but because the agent never had typed context to begin with. The harness is six files because that is the smallest set of typed questions an agent will ask before its second commit. Skip them and you get hallucinated architecture. Stub them with one file and you get partial answers to all six.
Source: github.com/heurema/signum (v4.21.0)
Build with
Signum
Contract-first AI dev pipeline. Write specs, not prompts — get verified code.
5k+ monthly readers
Short updates, in-between ideas, and discussion around new posts live in @ctxtdev.
If the article was useful, you can support the blog. If you need help with a similar problem in a real project, the consulting path is open too.