The Rules Are Downstream of the Work
The original was written on day 40. This revision is day 105.
Sediment
Four lines in my CLAUDE.md tell me, in my own voice, not to leave loose ends, not to cross repo boundaries, and not to contaminate ~/Projects with worktrees, which belong inside their own repositories.
I didn't write that file and then start following it. Claude Code wrote it, by writing down how I'd already been talking for forty days.
"Loose ends" shows up in my transcripts twice on April 29, about a hundred seconds apart. It lands in CLAUDE.md on May 18, a twenty-day lag.
"Crossing boundaries" is what I said on May 3, after Claude edited the wrong repo while I was working in another one. The worktree rule that fixed it got written down on May 20, a seventeen-day lag.
"Don't contaminate ~/Projects" was my pushback, word for word, on May 20. The rule landed the same day, reworded. The phrasing changed, but the scar stayed.
The file kept taking on layers. On May 31, the day before I first wrote this, a git worktree move clause got added to that same worktree rule. I said then that the file wasn't finished. It still isn't.
Sixty-five days later it's 208 lines: ten sections, forty-eight bullets. All four of the original lines are still in it, and the worktree rule still carries that move clause.
I didn't decide on these rules and then impose them on the work. They're sediment, laid down a grain at a time by the work itself, over weeks, never in one sitting. That's what the word carries that "downstream" doesn't: sediment takes time. You can't deposit a layer you haven't lived through.
The file looks and reads like a constitution, but nobody wrote it that way. It piled up.
That runs against most of the advice about Claude Code, which says to think hard about your rules and write a careful constitution before you start. I tried that. I still have the failed early CLAUDE.md drafts: vague, wishful, and ignored by the model. It was right to ignore them. I hadn't earned the right to write them yet.
I didn't know what a loose end was until I'd left a hundred of them, and I didn't know what crossing a boundary cost until Claude crossed one and lost me an hour.
What the Next Sixty-Five Days Deposited
The layers since then are dated in the file, because I started dating them.
June 26: warn once, then act. One flag naming the risk and what I plan to do, then the smart default. A flag you already answered never comes back unless the facts changed.
June 28: a secret printing into a local transcript on this machine is not an incident. No rotation theater, no masking machinery, no derail. Git and external exposure stay absolute.
June 30: past 70% of the weekly usage window, talk less. Past 80%, stop fanning out.
July 25: mechanical fan-out runs on cheap models. Session-tier models are reserved for judgment.
Each of those has the same shape as the first four. Something cost me time, I said so in a sentence I wouldn't have thought to write in advance, and it got written down.
Rules That Name an Absence
Then, on August 1, two layers of a different kind.
A gap list handed to me opened with "[medium] No automated tests exist anywhere in the repo." The model made that the headline, reworked the server so it could be tested, and ran a seven-agent workflow that wrote 104 tests across five files. Then it launched a second workflow to revise them. I stopped it mid-run: "Don't be building some huge test suite. I have a command for building out the acceptable level of test suites for these apps. I'm not trying to waste too many expensive tokens on that. Tell the base claude.md this isn't a gap."
The first draft of that rule over-corrected into "no tests," so I corrected the correction: "I didn't say I didn't want tests, but when tests are being added...use my command so it's right sized." The rule isn't anti-test. It's about who sizes the suite.
Same day, different repo, same shape: "this is a prototype. Stop throwing CI/CD on local prototype tools... So when adding the pipelines I should be asked if CI/CD is necessary. If you can infer this is one of my local tools then don't even flagg CI/CD as a gap." I'd already waved off the deploy half of that same audit earlier in the session: "this is a sandbox app, the deployment stutuff shouldn't be considered a gap." That was the signal the model should have turned into a general rule on the spot, and it didn't.
The typos stay in. That's the register the rule was born in.
Both rules say the same thing: the hole is on purpose, and reporting it as a gap is the error.
You can't write that rule in advance. Before the work, "no tests" and "no CI" really do look like gaps to any competent reviewer, which is exactly why an agent keeps finding them. A hole only becomes a deliberate shape once you've lived in it long enough to know you dug it on purpose.
The constitution you write up front can tell an agent what to build. Only sediment can tell it what to leave alone.
Code to Spec
The same thing happened at the tool layer.
On April 28 I wrote a Python script called harvest_cc.py: 1,168 lines that walked ~/.claude/, parsed session JSONL, applied mapping tables, and saved everything to SQLite with idempotent upserts. It worked. Two weeks later, on May 12, I rewrote it as an 84-line slash command.
The slash command has none of the logic in it. It's a spec that tells the agent to do the extraction with the tools it already has.
That move from code to spec is probably the cleanest signal in the whole first window. I couldn't have written the spec first. The spec is what was left after I'd done the work by hand and learned which parts the agent could be trusted with. The 1,168 lines weren't wasted. They were the cost of learning what to hand off.
Two honest updates. The command is still exactly 84 lines. And the script never died. It's still on disk, now 1,238 lines, last touched May 27, two weeks after the spec was supposed to have replaced it. Sediment doesn't delete the layer underneath it.
The same pattern showed up one size larger. Between July 3 and July 5 I wrote nine autonomous cross-repo sweep skills: reconciling WIP, security, licenses, dead links, test backfill, deploy health, config drift, changelogs, brand scrub. Each of the nine turned out to need a ledger, a one-unit-per-iteration loop, a detect-before-act gate, and a resume-safe contract, so the shared engine got pulled out into autonomous-sweep-core, and all nine now cite it.
Same migration, one level up: write the concrete thing nine times, then extract the spec. I couldn't have written autonomous-sweep-core first either.
The Harness, Eating Its Own Tail
Then there's the harness itself, the slash commands, skills, and MCP servers I keep in ~/.claude. As of this morning that's forty-four commands, twenty-two skills, and four agents.
None of it was designed up front. Each command got promoted out of real work, one at a time, and I almost always drafted it away from that work on purpose. When I hit something worth turning into a tool, I back out of the repo I'm in and write the tool from ~/Projects, so building it doesn't muddy the session that needed it.
And the harness is built out of itself.
The first thing I made was prompt-improver, using skill-builder, before I really knew what I was doing. After that, prompt-improver became the tool I drafted almost every later command through. port-collision-scan came from handing prompt-improver the entire generate-port-registry command and asking for the one-shot version. The hardening series borrows its shape from cleanup-repo, front-door-security, and shipit. harness-audit is told, in its own genesis prompt, to reuse lowhangingfruit and cleanup-repo and point them inward.
The newest one closes the circle further than I expected. On July 25 I wrote a skill called preference-recalcification, whose only job is to maintain the sediment. Its instructions name an essay in my docs folder as required reading before it touches the provenance rules. So a tool in the harness now cites a piece of writing about the harness as authority over the harness.
That's what I mean when I say the harness is downstream of itself: a toolchain that bootstrapped on its own output.
Who Wrote This Layer
This is the part I didn't see coming on day 40.
Sediment doesn't check credentials. Anything that settles becomes a layer, and for most of June, whatever was depositing layers into my rules and roadmaps wasn't always me.
An agent proposes a constraint in a plan. I say "y." The constraint gets written into a roadmap. A later session reads the roadmap and cites it back to me as decided. Nobody lied. But three documents repeating one origin aren't three confirmations, and my "y" approved the intent of a plan, not every line inside it.
So the July 25 layer is a rule about layers. Anything the model inferred, as opposed to something I decided, gets a greppable CLAUDE-ORIGIN tag right where it sits. Requirements now carry a provenance class: user-ratified, user-mentioned, bulk-approved, or agent-originated, and the last three never round up to the first. Silence isn't ratification. A "decided, do not relitigate" label only binds if there's a decision entry that actually weighed alternatives, and inheriting a stack isn't deciding one. Those tags now sit in twelve files across five repos, alongside nine ROADMAP.md and nine DECISIONS.md files carrying the same discipline.
The rule has a second half, and it took one more failure to earn. On July 26 the model wrote a paragraph explaining why my new decision superseded a proposal from an old agent packet. It was careful, well-reasoned, and wrong. Arguing against text I never ratified gives it the standing of a live alternative that was weighed and beaten, which is exactly the status it never had. My reply is in the file verbatim: "I literally never cared about the decay layer."
That failure happened inside the document written to obey the rule. It's the most honest thing in my CLAUDE.md, and it's why it stayed in.
The other thing I didn't see coming: a model upgrade is a personnel change nobody announces. Rules written for an earlier model held together because that model filled in the gaps for me. The newer one litigates the letter. In my own words, from the transcript that produced the recalcification skill: "it gets better at litigating, the preference must be calcified by the new litigator in language he will respect."
So on July 25 the enforcing model restated my keystone rules in its own voice, at the rigor it would later hold them to. Each rule's scar is quoted verbatim from the session record, and the file carries a note saying so. From "Close loose ends" through "Agent tangents," the "I" is the model, and I'm in the third person.
My rules are written in someone else's first person. I don't mean that as a metaphor about ownership. It's the only version the enforcer reliably obeys.
Four Layers
So that's four layers with the same basic shape. My coding standards are downstream of my mistakes. My tools are downstream of my scripts. My harness is built out of its own commands, drafted by the first tool I wrote. And my rules about where rules come from are downstream of rules that came from nowhere.
At every level, the thing that looks upstream turns out to be downstream of the work that produced it. And it only matters because I'm not working alone.
Specific Enough to Constrain
This is the part that doesn't carry over cleanly from solo work.
When you write code alone, the constraints can live in your head. The rules you write down are notes to yourself across time. They can be vague, because you're the one reading them and you fill in the missing half.
When you work with an agent, the rules have to live in a file the agent reads, and vague doesn't survive that handoff. A rule has to be specific enough to actually change what the model does.
"Be careful with deletions" does nothing. The model can't act on it, and a new hire probably couldn't either.
"A one-word approval to a multi-option menu is not durable consent" works, because it names the exact shape of a failure I'd already lived through.
You can write the first sentence before the work starts, and it's worth about what you paid for it. You can't write the second until you've lived the failure.
That's why the rules can only be sediment. What makes a rule specific enough to bind an agent is the failure that taught you its shape, and you can't deposit that layer early.
And a rule specific enough to bind one model isn't automatically specific enough to bind the next one. That's a maintenance cost nobody mentions in the guides. The sediment has to be re-cut in the new enforcer's language, or it quietly stops loading.
The Good CLAUDE.md
So write your rules. Just know what they are.
The ones you write before you start are scaffolding: cheap, vague, and disposable. The rules that matter are the ones you write in the third week, in your own annoyed voice, after the model has done the wrong thing for the fifth time in a way you can finally name. The ones that matter most come in the fourteenth week. They're about the rules themselves, and you write them after you find a constraint in your own file that you never actually agreed to.
If you're starting out with Claude Code, you've read the guides, you wrote a careful CLAUDE.md, and the model still does things you don't want, you aren't behind. You're right on time.
The good CLAUDE.md is the one you haven't earned yet. Fifteen weeks in, mine still is.
-- Justin Higgins. Software Engineer, Midwest. A hundred and five days pair-programming with an agent. The failures still write the rules; now the rules say which failures were mine.
Companion pieces: The Work Looks Like Nothing - why the session log is the first place judgment ever got recorded. Everything Looks Like Everything - the instrument that was measuring nothing.
Reactions, disagreements, war stories: jchigg2000.dev@gmail.com