Home / Articles

An Eight-Layer Claude Code Setup: CLAUDE.md, Memory, Hooks and Guardrails

How eight configuration layers, from scoped CLAUDE.md files and hooks to device verification and reversibility rules, make a Claude Code workflow trustworthy.

Publisher: REACTAPP.TOP9 min read1996 words

This article is published in English.

Sources: I Don’t Trust AI Coding Agents by Default — Here’s the 8-Layer Claude Code Setup That Earns It 🛠️

The setup decides how far to trust the answer

Anyone can type a prompt into Claude Code, yet the configuration around it decides whether the output earns trust. What follows is a layer-by-layer tour of a realistic setup for serious engineering work, along with the reasoning for each layer. It's no feature list and no marketing version. Eight layers together make something closer to a well-configured engineering tool than a chat window that happens to write code.

Layer 1: CLAUDE.md at two scopes

Claude Code reads CLAUDE.md files at several scopes, and the split between them matters more than most people expect. A personal file at ~/.claude/CLAUDE.md applies in every project, whichever repository is open. Each project also gets its own CLAUDE.md committed to version control, so the entire team reads the same instructions through source control.

A simple rule keeps the two apart. Anything about how a person works, regardless of codebase, goes in the global file: tool-usage rules such as preferring a code-intelligence lookup over a raw grep pass, communication preferences and conventions meant to apply everywhere. Anything about one specific codebase goes in the per-repo file: build commands, architecture decisions, naming conventions and bug classes that have already bitten that project. In any other project those items are noise that eats context for nothing.

The trigger for writing something down is concrete. Imagine a bug pattern that appears twice in the same area of a project. The fix looks right and passes a casual glance, yet it reintroduces the identical problem because the underlying constraint was never recorded anywhere the agent could see. The first time, the constraint gets explained in conversation and everyone moves on. The second time, the same mistake brings the same explanation. That's the signal. A rule belongs in CLAUDE.md not because it might be useful someday but because it cost the same conversation twice. Once it's a concrete, checkable rule and not a vague warning, the problem stops recurring.

One practical detail: CLAUDE.md content is delivered as a user message and isn't baked into the system prompt, so specificity beats length. A file under 200 lines of checkable rules outperforms a long file of vague ones.

Layer 2: auto memory

CLAUDE.md is what the developer tells the agent, and memory is what the agent works out alone. They do different jobs and shouldn't be conflated. Claude Code has a second system, auto memory, that builds up per project and is stored outside the repository, and it's the agent that writes to it. It keeps four kinds of notes: the developer's role and working preferences, corrections and feedback already given, ongoing project state that can't be derived from the code, and external references pointing to information that lives outside the codebase. A lightweight MEMORY.md file indexes everything.

The distinction is that CLAUDE.md holds instructions written on purpose, while memory holds context gathered from working together session after session, never formally documented. One is a rulebook. The other resembles the institutional knowledge a long-tenured teammate carries without any onboarding doc. Three examples show what changes:

  • A one-time correction such as "don't touch this file without asking first" carries into the next session and doesn't need repeating each time a conversation opens.
  • Project state invisible in the code gets remembered: a migration in progress, a deliberately deferred decision, or an architecture that looks wrong on purpose because of a constraint no diff shows.
  • Pointers to where answers live survive, such as which dashboard, which external document or which system holds what the codebase can't tell you.

None of that belongs in CLAUDE.md, since none of it is a rule being enforced. It's context that would disappear the moment a session closed.

Layer 3: hooks as deliberate friction

Friction picked deliberately is nothing like friction you're merely stuck with. Hooks run deterministically, as genuine shell commands at fixed moments in the lifecycle, and that's a firmer guarantee than hoping the model usually remembers. A PreToolUse hook triggers ahead of any tool call and can stop it completely. A Stop hook triggers when Claude ends its reply and can push it to continue if some condition still isn't met.

The most useful pattern is a PreToolUse hook limited to file edits. Before the edit proceeds, it requires a written account of the facts: which modules import the file, what might break and what the request actually was. It acts as a purposeful brake on careless changes, and the friction pays for itself because it bites exactly where caution is right. Unlike human attention, a hook doesn't flag or hurry through the fortieth edit of a long session.

A second hook handles output discipline by keeping responses terse, trimming the reflexive fluff and hedging that creeps into longer sessions. That's less about safety and more about not wasting reading time on filler. A third watches context health, nudging toward compaction at a natural boundary and not an arbitrary one. A PreCompact or SessionStart hook tied to compaction events can prompt a summary when the conversation has really reached a stopping point, so it isn't cut off mid-thought.

Does the friction pay off? For the file-edit guardrail, absolutely, because it has stopped real mistakes before they grew into real problems. The terseness and context hooks are comfort tuning more than protection, but they help once set up properly.

Layer 4: a code knowledge graph beats grep

Grep reveals where a string occurs, but not what calls it, what it calls or what breaks when it changes. Classic exploration is a loop: search a term, open the file, search what that file imports, open that one too, and continue until a picture forms. It works, but slowly, and it spends many tool calls rebuilding a mental model made of structural facts that shouldn't need rediscovering by brute force in every session.

A pre-indexed knowledge graph shifts the economics. One query hands back the relevant source along with real call paths: who calls it, what it calls and how far the dependency chain runs. That arrives in a single pass instead of many lookups, so there are fewer round trips and a fuller picture from the start, since call-path details grep would never produce simply come with the result. The official documentation for Claude Code argues something similar for code intelligence plugins, noting that large typed codebases gain heavily from structure-aware queries compared with text matching, where repeated search-and-read cycles get expensive fast.

Layer 5: verifying on a real device

What matters is whether a change works on the device or merely compiled, which are two different claims. For Flutter, this layer is the one used most often. Rebuilding from scratch to check a small UI tweak is wasteful when a connection to an app running on real hardware is available, and that connection fills a gap code generation can't reach. It supports screenshots, tapping through flows and inspecting the live UI tree. Claude Code now supports this properly, offering iOS simulator access and computer-use features that can validate a native build, reproduce a layout bug or run a simulator flow against what's rendered.

Hooking into the Dart VM for hot reload and hot restart reshapes the loop from guess, rebuild, wait, check to guess, reload, check. That's faster, and it also avoids a frequent trap: treating a clean compile as proof the fix works. A build that compiles and a build that behaves correctly on hardware are separate claims, and a rebuild-only habit can't distinguish them. Running it on the device answers the question outright.

Layer 6: load tools only when needed

Every tool sitting in context, used or not, taxes every turn and not just the turns that use it. So not everything loads by default, and that's a deliberate design choice. Specialized tools, such as browser automation, less common MCP servers and anything used occasionally, load on demand and don't occupy context for the whole session.

The effect compounds over a long session, since each tool definition costs tokens on every turn whether or not that turn uses it. Claude Code's MCP tool search exists to scale past this problem. Servers can register for on-demand discovery in place of front-loading every definition at session start, which keeps a multi-hour session efficient and not weighed down by dead context that is never used and never stops costing.

Layer 7: use the packaged workflows you really need

Claude Code ships with a big ecosystem of packaged workflows, including code review, security review, framework-specific reviewers, and planning and execution agents. Each can be invoked explicitly, so the same ad hoc logic isn't rebuilt every session. A large library means little if only three entries ever get used, so an honest tally of actual usage beats a list of the full catalog.

Three get regular use. A general code-review pass runs before anything meaningful merges. A security-focused reviewer covers anything touching authentication or data handling. A dedicated planning subagent handles any task big enough that jumping straight to implementation would skip real architectural thought. Those three account for nearly all explicit invocations.

Most framework-specific reviewers for stacks not in use go untouched, as do the more exotic subagent patterns designed for big parallel research jobs. They aren't poor tools. Daily work just doesn't call for that scale of investigation, and grabbing heavier tooling than the problem needs is a waste of its own. The value comes from knowing the three or four things worth using reliably, without feeling obliged to use the rest simply because they exist.

Layer 8: confirmation by reversibility

Speed counts as a win only while the result stays trustworthy, and once trust slips, speed is what causes the harm. Even with every layer active, certain actions always need explicit confirmation: destructive git operations, pushes and anything truly irreversible. No degree of automation earns a pass across that line, because a mistake there doesn't mean redoing work. It means repairing damage that may not be repairable.

The balance hinges on how reversible the particular action is, not on how risky the task feels. A big refactor over dozens of files takes a lot of effort yet remains fully reversible through version control, so it can run with lighter supervision. One git push --force takes almost no effort and may be permanently unrecoverable, so it gets a hard stop however routine it seems. Effort and risk sit on different axes, and blending them is how sweeping autonomy gets handed to the wrong kind of action.

Choosing between acting immediately and asking first doesn't come down to one dial. It's a per-action-type decision, settled once in advance, and never reopened in the moment when exhaustion makes the confirmation prompt feel like an irritating obstacle.

What the layers add up to

None of the eight layers stands out by itself. CLAUDE.md is a plain text file, and a hook is a shell command that fires at the right moment. Together they turn Claude Code from a fast typist lacking persistent context and any sense of reversibility into a tool with memory, guardrails, structural knowledge of the codebase and real device verification.

The setup itself isn't the interesting part, and the reasoning behind each layer is. Anyone running Claude Code with none of this configured shouldn't try to add all eight at once. Start with a real CLAUDE.md built around mistakes that have already happened twice, then grow outward.