AXME Code · 7 min read

Stop Writing CLAUDE.md Files. Write Decisions Instead.

CLAUDE.md is a passive artifact. Decisions are active rules with enforcement levels, supersede chains, and audit history. Here's why I stopped maintaining CLAUDE.md and what I switched to.

This is going to sound deliberately provocative, and it is. Stop writing CLAUDE.md files. They are the wrong tool, and the longer you maintain one, the more maintenance cost you accept for a diminishing return.

I know this is the advised default. I know there’s a reason for it. I know the first thing every Claude Code tutorial tells you is to create a CLAUDE.md. I tried it for three months. Then I tried something different. The difference is significant enough that I think the default advice is wrong for anything beyond a one-week project.

What CLAUDE.md actually is

CLAUDE.md is a prose file at your repo root that gets loaded into the agent’s context at session start. It’s a convention, not a feature: the agent is taught to look for this file and read it if present. You write it by hand. You update it by hand. You check it into the repo.

As an onboarding document, it works. It’s the equivalent of a CONTRIBUTING.md for a human, adapted for an LLM. “Here’s our stack, here’s our deploy flow, here’s what not to do.”

As a living context system, it fails, and it fails for one specific reason: it is a passive artifact. You write it, the agent reads it. Nothing about this loop updates the file based on what happens during the session.

Let me show you what that looks like in practice, over a 30-day timeline.

A 30-day timeline of CLAUDE.md rot

Day 1: You write CLAUDE.md. 10 clean lines. Stack, entry point, deploy command. Commit.

Day 3: Agent generates Joi validation code. You correct it: “use Zod.” Agent apologizes, fixes. You remember this for about 20 minutes, then move on. You do not update CLAUDE.md.

Day 7: Agent uses httpx.Client (sync) inside an async def. You explain that this blocks the event loop. You fix the code together. You do not update CLAUDE.md.

Day 10: You decide to standardize on pnpm after a long Slack thread about npm’s lockfile behavior. Agent is not in the room. You commit the change. You remember to update CLAUDE.md. You add “Use pnpm not npm.” One line.

Day 14: New session. Agent uses npm install. You correct. Agent reads CLAUDE.md. CLAUDE.md says “use pnpm.” Agent apologizes, says “right, you have pnpm documented, I missed it.” You wonder what else it is missing.

Day 21: You realize the Joi→Zod correction from day 3 has happened again in three more sessions. You add “use Zod, not Joi” to CLAUDE.md. You realize your CLAUDE.md is now 30 lines and does not feel comprehensive.

Day 25: Agent runs git push --force-with-lease and clobbers a commit. You add “NEVER FORCE PUSH” in caps to CLAUDE.md. You know the all-caps doesn’t do anything, but it feels right.

Day 30: CLAUDE.md is 80 lines. Some entries contradict each other. You cannot remember which of your corrections have been documented and which have not. You find a three-week-old sentence about a refactor that has since been completed and is now wrong. You don’t delete it because you’re not sure it’s wrong.

This is not a straw man. This is exactly how my CLAUDE.md evolved before I gave up on it.

The structural problem

CLAUDE.md is read-only from the agent’s perspective, writable only by the human, and has no metadata. Those three constraints, taken together, mean:

  1. Corrections during sessions are lost. The agent learns something, the session ends, the learning vanishes. The only way to preserve it is for you to remember and hand-edit later. You won’t.

  2. Contradictions accumulate. Every line you add is independent prose. There’s no notion of “this replaces that.” Two weeks of edits produces a file with overlapping, sometimes conflicting, instructions.

  3. Enforcement is aspirational. Writing “never force push” in CLAUDE.md is a suggestion to the model. It’s not a fence. The model can still decide, in context, that this particular force push is justified.

The pathological form of CLAUDE.md is exactly where most real projects end up after a month: a 150-line document you’re afraid to prune, with important rules buried in the middle, that the agent reads with mild interest at session start and then forgets mid-session.

What decisions fix, specifically

The replacement I landed on is a decision log. Not a prose file, a structured store. Each decision is its own file with fixed fields:

id: D-042
title: Never force push to any branch
enforce: required
decision: >
  The agent must never run git push --force, git push --force-with-lease,
  or any variant that rewrites remote history.
reasoning: >
  We lost a commit on 2026-03-14 to a --force-with-lease under stale lease
  conditions. The agent had a plausible reason every time it ran it.
  Enforcement at the pre-tool-use hook is the only layer that holds.
date: 2026-03-15
source: session-6f1ac3
supersedes: null

Four things this structure gives you that CLAUDE.md cannot:

1. Enforcement level

enforce: required vs enforce: advisory is a first-class field. A pre-tool-use hook reads all required decisions and uses them to filter commands. The agent cannot run a command that violates a required decision, because the hook blocks it before execution.

advisory decisions are suggestions. They get loaded into context like preferences. The agent should follow them but is allowed to deviate with reason.

CLAUDE.md cannot distinguish these. Every line is the same strength.

2. Supersede chain

When a decision changes, you don’t delete the old one and write a new line. You create a new decision that supersedes the old one:

id: D-089
title: Allow force push on personal feature branches
enforce: advisory
decision: >
  Force push is permitted on branches matching feat/*, as long as no one
  else is collaborating on that branch. Protected branches remain blocked.
supersedes: D-042

Now the history is preserved. You can see that force push was once fully blocked, then softened for feature branches, and why. In CLAUDE.md, you would just edit the old line and lose the history.

3. Automatic extraction

Decisions can be written by the audit agent at session close, not by you at session-end-plus-ten-minutes. If I say “let’s always use Zod going forward” in a session, the audit agent reads the transcript, identifies this as a decision, proposes it, and writes the file. I approve or adjust. Zero hand-editing.

I have never convinced myself to hand-write a decision file. Every decision in my store came from an audit of a session where I said something commitment-shaped, and the audit caught it.

4. Conflict detection at session start

When a new session starts, the agent loads decisions. If I say something in the new session that contradicts an existing required decision, the agent flags it before running anything. “You said to use Joi here, but decision D-021 requires Zod. Confirm?” This catches my own mistakes.

In a CLAUDE.md world, the agent just reads the document and hopes you meant what you said.

The honest objection

“But decisions are a lot of infrastructure for what is basically a text file.”

Yes. Decisions are more infrastructure. A decision log requires:

  • A data format (I use markdown files with YAML frontmatter)
  • A store (a directory, one file per decision)
  • A loader (code that reads the store on session start and injects into agent context)
  • An audit agent (code that reads transcripts and extracts candidate decisions)
  • A pre-tool-use hook (for enforcement)

That is more code than CLAUDE.md. The reason it is worth it is that every one of those pieces is a wall against a failure mode I have actually hit. Without the audit agent, decisions don’t get written. Without enforcement, required rules don’t hold. Without supersede, history gets lost.

You don’t need to write all of this yourself. AXME Code is an MCP plugin that provides all of it as a drop-in. But even if you build your own, the shape is the same: stop writing prose and start writing structured decisions with enforcement metadata.

What to do today

If you have a CLAUDE.md you are still maintaining, try this experiment for one week:

  1. Create a decisions/ directory in your repo.
  2. For every rule in CLAUDE.md that is actually a commitment, convert it to a decision file with enforce: required or advisory.
  3. Delete those lines from CLAUDE.md.
  4. Write the remaining CLAUDE.md as the simplest possible “project facts” file: stack, entry point, test command. No rules, no preferences, no history.
  5. At the end of the week, look at which file you updated more often. Note how many of your “updates” to CLAUDE.md were additions vs edits.

I predict: you stop touching CLAUDE.md entirely after day 2, because everything interesting is in decisions/, and decisions/ starts growing the way a real system of record should.

That is the point. CLAUDE.md was trying to be your system of record, and it could not hold the shape.

More on AXME Code