Local-First Claude Code: CLAUDE.md & a Secure CLI
Every new Claude Code session starts the same way: you re-explain that the project uses pnpm not npm, that tests run with Vitest, that the API layer lives under src/server and must never import from src/ui. You're paying — in tokens and in your own time — to re-teach the same facts daily, and the one session where you forget is the one where the agent runs npm install and rewrites your lockfile. The local agent needs a standing memory and a hard boundary. Both are configuration, not prompting.
Core Architectural Concepts & Trade-offs
CLAUDE.md is the agent's standing system prompt for a workspace. It loads automatically at the start of every session, so any fact you put there is amortized to near-zero cost (Lesson 9 — it caches) instead of re-paid per conversation. It resolves in a hierarchy: a global ~/.claude/CLAUDE.md for cross-project rules, a project CLAUDE.md checked into the repo for team conventions, and local overrides — merged, with the more specific file winning. This is the difference between an agent that re-learns your project every morning and one that already knows it.
The discipline is that a CLAUDE.md is a context-window resident, so it is subject to the same budget physics as everything else. A bloated one — every edge case, a wall of history, duplicated docs — is dead weight re-sent on every turn, and worse, it buries the load-bearing rules in noise the model skims past. Treat it like API design: terse, imperative, the few invariants that actually change behavior. "Use pnpm. Tests: pnpm test. Never edit dist/." beats three paragraphs of prose every time.
The second pillar is the permission boundary. The agent can run shell commands, and the model is an untrusted planner (Lesson 4) — so the CLI is an execution surface that needs an explicit allowlist, not blanket trust. Claude Code gates tool use behind a permission model: read-only and safe commands can be pre-approved, while destructive or outward-facing operations require confirmation. Encoding that allowlist in settings turns "hope it doesn't" into "it can't" — the agent physically cannot run git push --force if it isn't permitted.
The two pillars reinforce each other. CLAUDE.md tells the agent what to do and the conventions to honor; the permission layer enforces what it may never do regardless of what it plans. Hooks close the loop with determinism — a pre-commit hook or a command-blocking hook is a guardrail the model can't talk its way past, which (Lesson 10) is the only kind of guardrail that survives an adversarial input. Configuration over correction: the cheapest mistake is the one the runtime makes impossible.
An Optimized CLAUDE.md
Terse, imperative, only the invariants that change behavior. Every line earns its place in the window.
# Project: shop-api
## Stack
- Package manager: **pnpm** (never npm/yarn — it breaks the lockfile).
- Tests: `pnpm test` (Vitest). Typecheck: `pnpm typecheck`.
- Run all three before reporting any change done.
## Architecture (hard boundaries)
- API + business logic: `src/server/**`
- UI: `src/ui/**`
- **`src/server` must never import from `src/ui`** (enforced by eslint
boundary rule — do not disable it).
- DB access only through `src/server/db/repo.ts`. No inline SQL elsewhere.
## Conventions
- Validate all external input with Zod at the route boundary.
- No new files unless asked; prefer editing existing ones.
- `dist/` and `*.lock` are generated — never hand-edit.
## Don't
- Don't add dependencies without asking.
- Don't write comments that restate the code.Pair it with a permission allowlist in .claude/settings.json so safe commands run uninterrupted while anything destructive needs an explicit yes.
{
"permissions": {
"allow": [
"Bash(pnpm test)",
"Bash(pnpm typecheck)",
"Bash(git status)",
"Bash(git diff:*)"
],
"deny": [
"Bash(git push --force:*)",
"Bash(rm -rf:*)",
"Bash(pnpm publish:*)"
]
}
}Layered Context & the Permission Gate
A configured workspace is the launchpad for reusable automation. Next, turn a repeated workflow into a first-class capability: building custom Claude Skills. Or browse the full roadmap.