CLAUDE.MD
stableThe project's DNA, in text.
The file Claude reads every time it opens the project. It is not a README. README is for the human cloning the repo. CLAUDE.md is a briefing for an agent: what the project IS, the voice, the hard constraints, the dangerous commands, the safe shortcuts.
Keep it short. No narration. Point to detailed docs instead of duplicating them. If Claude keeps making the same mistake over and over, a line is missing here.
Concrete tip: start with the monorepo map, the non-negotiable conventions, and the shortcuts that keep you from wiping production. Everything else becomes a link.
# CLAUDE.md (repo root)
## Stack
- Next.js 16 + Convex backend
- Turbo monorepo, main app in apps/sapiens/
## Don'ts
- Never run `npx convex *` from the root, only inside apps/sapiens/
- No em-dash in .md files (a hook blocks it)
## Safe shortcuts
- npm run dev (starts sapiens + aitag + decks)
- npm run convex:deploy (prod deploy)
Related: CONVENTIONS.MD · DECISIONS.MD · HOOKS
HOOKS
stableShell triggers the harness runs for you.
A hook is a script that runs on an event: PreToolUse, PostToolUse, SessionStart, Stop. Think middleware. Useful for blocking edits on sensitive files, running lint after a save, firing a notification when a long session ends.
Configured in settings.json. Do not confuse it with Claude's memory. A hook is deterministic, it always runs, without depending on the agent remembering.
In Sapiens, a hook warns whenever an em-dash shows up in a .md file, because the house DNA forbids it. A rule that becomes code, not a preference that becomes wishful thinking.
// .claude/settings.json
{
"hooks": {
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "node hooks/check-emdash.mjs"
}]
}]
}
}Related: PERMISSIONS · CLAUDE.MD · CONVENTIONS.MD
PERMISSIONS
stableWhich tools run without asking.
Every tool (Bash, Edit, Write, MCP) can be allowed, denied or asked. Defined by command pattern. E.g. Bash(git status:*) frees only status, not push.
Move to user settings what is universally safe (ls, git diff, npm test). Move to project settings what is repo-specific (npm run convex:deploy only in this project).
Never free the whole Bash(*). You lose the seat belt and still feel comfortable.
// .claude/settings.local.json
{
"permissions": {
"allow": [
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(npm test:*)",
"Read(*)"
],
"deny": [
"Bash(rm -rf:*)",
"Bash(git push --force:*)"
]
}
}Related: HOOKS · MCP SERVERS
GIT COMMITS
stableCommit early, commit small.
Before every experiment or big change, commit. It becomes a checkpoint you can revert to painlessly.
Direct messages: fix, feat, chore, refactor. No process narration in the body. The diff tells the story.
When Claude is iterating fast on a feature, commit at every green step. If the next attempt breaks, you run git restore with confidence.
# Before every experiment:
git add -A && git commit -m "checkpoint: pre-refactor"
# Iterating fast:
git add src/feature.tsx
git commit -m "feat: add foo step 1"
# ... next green step
git commit -m "feat: foo step 2"
# Something broke? Roll back painlessly:
git restore src/feature.tsx
Related: VERIFY WORK · STOP EARLY · WORKTREES
CONVENTIONS.MD
stableSmall technical rules, in one place.
Things like: named exports not default, Tailwind before CSS Modules, dates in ISO 8601, no console.log in the final commit.
CLAUDE.md points here. It exists so you do not repeat the same correction 5 times across 5 different sessions.
When you catch yourself saying the same thing for the second time in the same week, open the file and write it down.
# conventions.md
## Code
- Named exports, not default
- Tailwind before CSS Modules
- Dates in ISO 8601
- No console.log in the final commit
## Naming
- Component: PascalCase
- Hook: useFoo
- Util file: kebab-case.ts
## Imports
- @/ for absolute paths
- Order: react > next > third-party > @/
Related: CLAUDE.MD · DECISIONS.MD
DECISIONS.MD
stableWhy I chose this, in one line.
A lean ADR. Format: swapped X for Y on DD/MM because Z.
When Claude (or you) tries to revert something three months from now, this file prevents the classic well, there must be a reason, leave it there.
Only write the entry when the decision is non-obvious. Do not document the trivial.
# decisions.md
## 2026-05-18 · Hash → canonical URL in /aprenda-claude
Reason: per-item OG image needs a real route,
not just a hash. Hash routing loses the share.
## 2026-04-22 · Convex Auth instead of Clerk
Reason: one backend only, no identity bridge,
costs half on the free plan.
Related: CONVENTIONS.MD · CLAUDE.MD