Build journal
ARCHITECTUREArchitecture 5 min read

CLAUDE.md & the Dev Workflow

Published Jul 11, 2026

A single operating manual encodes the hard-won rules, traps, and conventions so mistakes don't get re-made.

Every codebase accumulates tribal knowledge: the deploy step that must not have a trailing slash, the config flag that wipes the database, the layout bug that keeps coming back. Usually that knowledge lives in senior engineers' heads and Slack scrollback. Praxis924 puts it in one file — CLAUDE.md — that is read first, every session, by both the humans and the AI assistants working the repo. It is institutional memory as code: every rule maps to a real incident, so the same mistake is never made twice.

The problem

The naive approach is to trust that people (and AI agents) will "just know" the traps. They don't. A new contributor rebuilds the Nginx config and reintroduces a trailing slash in proxy_pass — every /api/v1/* call 404s and /learn goes dark. An assistant hand-rolls a fixed inset-0 overlay inside a backdrop-blur bar, and the drawer peeks from a corner instead of covering the screen — a bug that shipped roughly seventeen times. Someone runs docker compose down -v to "reset" and drops the volume holding every learner's progress.

These are not exotic failures. They are the same failures, recurring, because the knowledge that would prevent them isn't where the work happens. Documentation in a wiki nobody opens has zero enforcement. Convention-by-code-review only catches what a reviewer remembers that day.

The design

CLAUDE.md is a plain-Markdown operating manual at the repo root, loaded into context at the start of every AI session and read first by humans. Its authority is explicit: the instructions override default behavior. It is organized so a reader can act, not just admire — what the project is, how to run it, the domain model, key flows, and then the load-bearing sections: Gotchas / conventions and Don't nuke prod.

The core rule is that every entry earns its place by pointing at a real incident. A convention with no scar tissue behind it is noise; a convention that says "this exact miss broke the notes drawer" is a rule you obey.

markdown
1- Nginx `/api` trailing-slash trap: proxy_pass http://127.0.0.1:8000; — NO
2  trailing slash. A trailing slash rewrites /api/v1/* → /v1/* and every API
3  call 404s (this caused the /learn "Not Found" outage). It lives on the host,
4  so a server rebuild can silently reintroduce it — re-copy the committed file.
5
6- Overlays: reuse the primitives, don't hand-roll. A hand-built fixed inset-0
7  overlay shipped the same layout bug ~17 times. New overlays use <SidePanel> /
8  <Modal>, which bake in the portal-to-body that a backdrop-blur ancestor breaks.
Powered by AI

Paired with the manual are slash commands in .claude/commands/ — executable shortcuts for the routines the manual describes: rebuild (rebuild + health-check the stack), logs (tail backend logs), db-reset (the destructive one, clearly flagged dev-only), and verify-generation (an end-to-end smoke test of the lesson pipeline). The manual tells you the rule; the command lets you follow it without re-deriving the invocation.

bash
1# The manual documents the flow; the command encodes it.
2/rebuild backend          # up -d --build backend, then health-check
3/verify-generation        # admin login → create → generate → assert `generated`
Powered by AI

Finally, OpenSpec enforces a verify-first, decide-before-you-build culture: agree on what to build (a proposal + delta specs + tasks) before writing code, then implement against it. The manual's sharpest cultural rule is that a green build is not proof of correctness.

Warning: next build type-checks; it says nothing about layout. "The build passes" is not "it works." For anything visual, reason through a 375px width or drive the running app.

The gotchas

The manual's own gotcha table is the model — each row is a trap, its consequence, and the fix.

TrapWhat it breaksThe fix
Trailing slash in proxy_passEvery /api/v1/* 404s; /learn outageRe-copy the committed Nginx config; no trailing slash
docker compose down -v on the serverDrops the volume → wipes learner progressDev-only; never on prod
Hand-rolled fixed inset-0 overlayDrawer peeks from a corner (shipped ~17×)Use <SidePanel> / <Modal> primitives
flex-col scroll child without min-h-0Sticky footer pushed off-screenflex-1 min-h-0 overflow-y-auto on the body
Altering a table via create_allSchema drift; migration crashes mid-deployNew tables auto-create; alters use Alembic

Build it yourself

The minimal version is one Markdown file and a discipline:

  1. Create CLAUDE.md at the repo root. State up front that it is authoritative and read first.
  2. Write only three things well: what the project is, how to run it, and the gotchas. Keep the gotchas section fed by incidents — after any "we shipped that bug again," add a rule that names the incident.
  3. Add a .claude/commands/ folder with one file per routine you type more than twice (rebuild, logs).
  4. Make the destructive commands loud. A db-reset that drops volumes gets a warning banner, not a quiet mention.

What changes at scale

As the team and repo grow, split the monolith into scoped CLAUDE.md files per package so context stays relevant. Add a lint or CI check that fails when a model changes without a matching Alembic migration — Praxis924 already gates this with a migration-drift check and a CD preflight that aborts on an unstamped database rather than crashing mid-deploy. Promote the "verify-first" rule from prose into tooling: a verify skill that drives the running app, and OpenSpec proposals that force a design decision to exist before code does. The file stays the front door; the enforcement moves into the pipeline.

Published in build journal