3 · The six layers¶
Part I — The Idea · ← Loops, not prompts · Contents · Next: Context →
A Claude Code setup is easy to describe as a pile of files and hard to describe as a system. The mental model that makes this repository navigable is six layers, each answering exactly one question:
| # | Layer | Question it answers | Where it lives | Chapter |
|---|---|---|---|---|
| 1 | Context | What must it always know? | project/**/CLAUDE.md (19 files), global/rules/, global/references/ |
4 |
| 2 | Skills | How is this kind of task done here? | project/.claude/skills/ (71), global/commands/ (53) |
5 |
| 3 | Agents | Who does it — and who checks it? | project/.claude/agents/ (23), global/agents/ (8) |
6 |
| 4 | Hooks | What must never happen, whatever the model thinks? | project/.claude/hooks/ (34 scripts, 28 wired across 8 lifecycle events) |
7 |
| 5 | Connectors | What real systems can it touch? | project/.mcp.json, plugin + permission config in the two settings.json |
8 |
| 6 | State | What survives the session ending? | global/memory/ (172 files), PM epics/PRDs, examples/epic-walkthrough/ |
9 |
The order is deliberate. It runs from softest to hardest: context and skills are suggestions the model reads and follows; agents add structure; hooks are mechanical and non-negotiable; connectors and their permission gates define the outer boundary of what is physically possible; and state is what makes the whole thing cumulative rather than Groundhog Day. When a rule matters, it tends to appear at more than one layer — you saw the "never merge" rule enforced at four layers in chapter 2, and that redundancy is a pattern, not an accident.
One request through all six layers¶
Drawn in the order the layers act — which is not the order they are usually listed. Hexagons are mechanical: the model does not get a vote. Rectangles are advisory — read, then decided upon:
flowchart LR
user(["“the invoice list is showing<br/>deleted rows — fix it”"])
subgraph before["before the first token"]
direction TB
hooks1{{"4 · Hooks — SessionStart<br/>git synced · Docker checked<br/>PRs + triage inbox loaded"}}
ctx["1 · Context — resident<br/>use Nx, never bare jest;<br/>confirm destructive commands"]
end
route["2 · Skills — bug-fix<br/>reproduce → failing test → fix"]
work["3 · Agents<br/>mikroorm-expert advises;<br/>adversarial-reviewer grades the diff"]
guard{{"4 · Hooks — every tool call<br/>auto-format · validate · block<br/>Stop: affected tests must run"}}
check["5 · Connectors<br/>query the real schema via MCP,<br/>within permission bounds"]
mem[("6 · State<br/>the durable lesson →<br/>memory + index")]
user --> before --> route --> work --> guard --> check --> mem
mem -.->|"next session starts<br/>already knowing"| ctx
The cylinder is what makes tomorrow's session start further along than today's did —
without it, the loop back to Context never closes and every month repeats the last one.
In prose, the same trip. Suppose the user types: "the invoice list is showing deleted rows — fix it."
Before the first token, layer 4 has already acted: SessionStart hooks synced git,
verified the Node version, checked Docker, loaded open PRs and issues into context, and
ran the worktree doctor. Layer 1 is resident: the root CLAUDE.md has told the model
this is an Nx monorepo where tests run as nx test, never bare jest, and that
destructive commands require explicit confirmation.
Choosing the approach is layer 2. The request pattern-matches the bug-fix skill,
which prescribes this project's shape for a fix: reproduce first, write the failing
test, then make it pass — not whatever generic strategy the model would improvise.
Doing the work engages layer 3. The skill may pull in the mikroorm-expert agent
(the ORM's soft-delete filters are exactly its territory), and when the fix is drafted,
a different agent — adversarial-reviewer, which receives only the diff and no
project context — tries to tear it apart. Maker ≠ checker, staffed.
Every tool call passes layer 4 again. The edit is auto-formatted on write; if the
fix had touched a Helm chart it would have been schema-validated on save; if the model
tried git push --force to main it would be blocked, no matter how sure it was. When
the turn ends, the Stop hook runs the affected tests — a quality gate the model cannot
skip by simply declaring victory.
Verifying against reality is layer 5. The model checks the actual database through
the custom acme-mcp server rather than guessing at column names, within permission
bounds that make credentials unreadable and PR-merging impossible.
And afterwards, layer 6 remembers. If the bug revealed something durable — say,
that a forked EntityManager silently bypasses the global tenant filter — it becomes a
memory file, indexed in MEMORY.md, and every future session starts knowing it. The
fix was a day's work; the memory is permanent.
Six layers, one bug fix. Remove any one of them and something specific degrades: without context the model re-derives conventions and gets them subtly wrong; without skills every fix takes its own improvised path; without a separate checker the fix is graded by its author; without hooks the guardrails depend on the model's mood; without connectors the "verification" is a guess; without state next month's session steps on the same rake.
The map of the repository¶
The two configuration trees mirror Claude Code's own two scopes, frozen at their original paths — what you see is where these files actually lived:
project/ repo-scoped config, exactly as it sits in the monorepo
.claude/
skills/ 71 skills — procedure, not prose
agents/ 23 domain + review agents, tool-scoped
hooks/ 34 hook scripts, 28 wired — the rules the model can't argue with
commands/ 7 project slash-commands
references/ checklists and templates loaded on demand
settings.json hook wiring, permissions, model + effort
**/CLAUDE.md 19 nested instruction files, at their original paths
.mcp.json MCP servers
global/ machine-scoped config (the ~/.claude equivalent)
rules/ 8 always-resident rules
references/ 16 on-demand references, pulled in by a routing table
commands/pm/ 45 PM ceremony commands (see the attribution appendix)
agents/ 8 review + analysis agents
memory/ 172 durable facts — sanitized real history, not synthetic
settings.json model, permissions deny-list, plugins
book/ ← you are here: the guided reading of all of the above
docs/architecture/ the system this setup was used to build (Part IV)
examples/ one epic end-to-end, artefact by artefact (chapter 11)
A useful way to hold the split: global/ is who the engineer is — their standing
rules, their ceremony, their accumulated memory, on every project. project/ is what
this codebase demands — its skills, its guards, its experts. When you install any of
this yourself (Appendix A), the same split applies: global
config is yours to carry between machines; project config belongs to the repo it
governs and should diverge per project.
What Part II does with this¶
Each of the next six chapters takes one layer, opens with what it is for, shows how this setup implements it — with excerpts from the real files, not paraphrase — and closes with pointers to the primary sources. The layers are presented softest-first, same order as the table, because that is also the order in which each layer's failures motivated the next: instructions that were ignored became skills, skills that were rationalized away became hooks, and everything that was learned the hard way became memory.
Next: layer one — the 19-file
CLAUDE.mdhierarchy, the eight resident rules, and the routing table that keeps 16 reference documents out of context until the moment they're needed. Chapter 4 — Context: what it always knows →