AIwave
Anatomy of the Most Upvoted CLAUDE.md File on the Internet

Anatomy of the Most Upvoted CLAUDE.md File on the Internet

Someone posted a CLAUDE.md file to r/ClaudeAI and nearly 1,800 engineers upvoted it. That’s not a fluke — that’s a signal. Most CLAUDE.md files do almost nothing. They’re a graveyard of vague notes that Claude politely reads and then ignores in practice. The viral one is different, and after reading every line of it, I can tell you exactly why.

Three structural patterns explain most of its upvotes. I’ll break each one down, show you what it’s doing under the hood, and then build a minimal production-ready template you can steal.

What you need

You need Claude Code installed and a project to drop a CLAUDE.md into. Familiarity with how Claude Code reads context from your working directory helps, but isn’t required — I’ll cover the relevant mechanics as we go.


Pattern 1: Role + constraint framing at the very top

The first thing the viral file does is frame Claude’s role before any task description. Not a generic instruction about being helpful — something tighter:

# Project Context

You are a backend engineer working in this repository. You write Go.
You do not suggest rewrites in other languages. You do not add dependencies
without being asked. When in doubt, do less and ask.

This block does two things. First, it anchors Claude’s persona to the specific project — not to a general capability set. Second, and more importantly, it leads with negations. Telling Claude what not to do is consistently more reliable than telling it what to do, because constraint space is smaller than possibility space.

Claude Code reads CLAUDE.md as persistent project-level context that survives across sessions and across tool calls. It’s not a one-shot system prompt — it’s closer to a standing work agreement. The role block makes that agreement explicit before the model ever sees a user message.

Pattern 2: Explicit tool permission and denial lists

The second pattern is the one most CLAUDE.md files skip entirely: a tool scope section.

## Tool Use

Allowed:
- Read any file in this repository
- Write to files under src/ and tests/
- Run `make test` and `make lint`
- Search the web for documentation

Not allowed:
- Deleting files
- Running git commands (ask me first)
- Installing packages (ask me first)
- Modifying .env or any file matching *.secrets.*

Claude Code operates a tool-calling loop. On each step, it decides which tools to invoke based on the task at hand — and by default, it’ll use whatever’s available. The permission list doesn’t add new restrictions at the API level; what it does is give Claude a clear prior about what actions are in-scope before it starts planning.

The denial list is the key piece. Without it, Claude will occasionally reach for a tool that’s technically available but contextually inappropriate — deleting files, installing packages, running git commands you didn’t want touched. The denial list front-loads that judgment rather than relying on the model to figure it out mid-task.

Two parallel conveyor belts side by side — one running freely with objects tumbling off the end, the other gated at intervals by precise mechanical stops, rendered in cool industrial light

Pattern 3: Project-scoped memory anchors

The third pattern is what I’d call memory anchors — the “always remember” and “never do” blocks that appear throughout the file, co-located with the code sections they apply to.

## Architecture

This service uses an event-sourcing pattern. All state changes
go through the event bus in pkg/events.

Always remember:
- Commands are in pkg/commands, handlers in pkg/handlers
- The DB is append-only — never issue UPDATE or DELETE queries
- All new handlers must have a corresponding test in tests/integration

Never do:
- Direct DB writes outside of the event handler
- Skipping the validation layer in pkg/validation
- Adding logging inside hot paths without a feature flag

Why does this outperform a generic system prompt? Because it’s scoped. The instruction “never issue UPDATE queries” is meaningful only in the context of an append-only event store — detached from that context, it’s just a weird constraint. By embedding these anchors next to the architectural description that explains why, you give the model the reasoning chain, not just the rule.

This pattern of co-locating capabilities with their constraints generalizes across tooling contexts — you’ll find the same approach reflected in MCP server documentation as well. Repeat it for each major subsystem in your file.


A minimal production-ready template

Here’s a CLAUDE.md you can drop into any project and fill in. Every line earns its place.

# [Project Name] — Claude Work Agreement

## Role

You are a [role, e.g. "backend engineer"] working in this repository.
Primary language: [language].
When unsure, do less and ask.

## Tool Use

Allowed:
- Read any file in the repo
- Write to [specify safe dirs, e.g. src/, tests/]
- Run [specify safe commands, e.g. make test, make lint]

Not allowed:
- Deleting files without confirmation
- Running git commands (ask first)
- Installing or removing packages (ask first)
- Modifying [specify sensitive files, e.g. .env, *.secrets.*]

## Architecture

[2-4 sentences describing the core structure of the project.]

Always remember:
- [Key invariant 1]
- [Key invariant 2]

Never do:
- [Anti-pattern 1]
- [Anti-pattern 2]

## Failure Modes

If you are blocked, say so immediately rather than guessing.
If a task would require a "not allowed" action, stop and ask.
Prefer a short correct answer over a long uncertain one.

The “Failure Modes” section is worth calling out specifically. It tells Claude how to handle ambiguity rather than letting it improvise — and for new contributors who inherit a project with a CLAUDE.md already in place, it’s the section that most directly shapes day-one behavior.


Where this breaks

Vague instructions are the most common failure. Generic directives about code quality or best practices do almost nothing — Claude already attempts these things. Specificity is the entire value of the file. Every line should communicate something Claude couldn’t infer from the codebase alone.

The second failure mode is missing tool scope. Without an explicit list of what’s allowed and what isn’t, Claude has to improvise permission boundaries mid-task — and it will sometimes get them wrong in ways that are hard to predict. The viral file’s tool section isn’t elaborate; it’s just present.

The third failure mode is skipping the failure modes section entirely. Files that describe what to do but not what to do when things go sideways leave Claude to guess. That’s where the unpredictable behavior shows up — not in the happy path, but in the edges.


Next steps

Put CLAUDE.md at the repository root. In a monorepo, you can have a root-level file for global constraints and subdirectory files for service-specific ones — Claude Code will read both. Version the file alongside your code; diffs to CLAUDE.md are worth reviewing in PRs the same way configuration changes are.

The viral file earned its upvotes by being specific, scoped, and honest about failure modes. That’s the whole template. Start with the three blocks above, fill in the blanks for your project, and iterate from real sessions rather than from imagination.


← Back to blog

Get new posts in your inbox

New posts plus the occasional curated note on what's working with Claude and the agent stack.

No spam. Unsubscribe anytime.

Comments