Last active
June 8, 2026 15:53
-
-
Save codeninja/0d261024d8a991fb12e21b2c853c18b7 to your computer and use it in GitHub Desktop.
CLAUDE.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # CLAUDE.md | |
| This is a decision guide, not a runbook — how to make choices when writing code here. Commands, setup, architecture, and deployment live in the README. On *running* something, the README wins; on *deciding* something, this file wins. | |
| Full conventions: https://gist.github.com/codeninja/75f94d35911df96b3c931a8f76242332 | |
| --- | |
| ## Philosophy | |
| You are an LLM assisting the Principal Engineer — nothing is impossible or too much work. In systems we don't control, understand them and make the minimal change. In greenfield, set a strong foundation from the start. | |
| Aim for clean, modular, reusable code. Patterns and abstractions are tools, not goals — avoid needless complexity; favor patterns that automate away boilerplate and human error. | |
| - **Explicit > implicit** — no magic, no hidden state, no author-only conventions. | |
| - **Composition > inheritance** — small composable pieces over deep hierarchies. | |
| - **Constraints > convention** — enforce correctness with types, schemas, and tooling, not docs. | |
| - **Deterministic behavior** — same inputs, same outputs; minimize runtime surprises. | |
| - **Tests are non-negotiable** — untested is broken. Every feature ships with tests; target ≥85% coverage. | |
| - **Code is the source of truth** — behavior lives in code and tests, never in comments or docs that drift. | |
| --- | |
| ## Comments: self-documenting code, strictly enforced | |
| Code explains itself through naming, structure, and types. Comments are a last resort: | |
| 1. **Max 2 lines.** Need more? Restructure — extract a named function, rename a variable, split the logic. | |
| 2. **Only non-obvious interactions**, and only about the code directly beneath. "What" comments are forbidden. | |
| 3. **No business logic.** Rules and policies belong in code and tests, where they're executable. A comment of a rule lies silently when the rule changes. | |
| 4. **No third-party knowledge.** Don't document how a library/API behaves — it drifts and misleads. If an external quirk forces odd code, link the upstream issue instead of paraphrasing. | |
| 5. **Don't touch existing comments** when editing nearby code unless the code they describe changed. Never rewrite for tone or style. | |
| 6. **Delete comments that restate the code** when you're already modifying it — the only comment edit needing no justification. | |
| Docstrings on public APIs are fine: signature, purpose, contract only. No essays, tutorials, or change history. | |
| **The test:** before writing a comment, ask "can renaming or restructuring make this unnecessary?" If yes, do that. | |
| --- | |
| ## Writing code | |
| - **Small, focused modules with clear ownership.** No god-objects, no grab-bag `utils`. | |
| - **Business logic lives in services/domain code**, not route handlers, UI components, or scripts. | |
| - **Dependency injection over global state.** Config is explicit and validated at startup. | |
| - **Import from actual modules**, not `__init__.py` re-exports. | |
| - **Prefer auto-discovery over manual registration** (e.g., routers) — fewer parallel-agent merge conflicts. | |
| - **Match the surrounding code** — its idioms, naming, and density. Don't introduce a new pattern when one exists. | |
| - **No speculative flexibility.** Build what the task needs; abstractions earn their place with ≥2 real consumers. | |
| - **Handle errors where they can be acted on.** Don't swallow exceptions or catch-log-continue without reason. | |
| ### Default technology choices | |
| When starting new and the codebase doesn't dictate otherwise: | |
| - Python: `uv` (never pip/poetry), `ruff` lint+format, `pytest`, Pydantic, SQLAlchemy 2.x async. | |
| - JS/TS: `bun` (never npm/yarn/pnpm), Vite, Vitest + Testing Library + MSW. | |
| - Python UI defaults to NiceGUI; React only for standalone/public SPAs. | |
| - UUID primary keys, `created_at`/`updated_at` on every model, JSONB for flexible data. | |
| - Conventional Commits. Merge commits, not squash. | |
| --- | |
| ## Git workflow: worktrees, commits, PRs | |
| All work happens in git worktrees — never directly on `main` or the working checkout. | |
| - **Base every worktree off `main`** (or the branch the user designates). | |
| - **One worktree per unit of work; a fresh worktree per background subagent.** Subagents never share a worktree or write to the primary checkout. | |
| - **Worktrees live in `.claude/worktrees/`** — ensure it's gitignored before the first one. | |
| ```bash | |
| git worktree add .claude/worktrees/<branch-slug> -b feat/<short-slug> main | |
| ``` | |
| - **Commit early and atomically; open a PR before work is done.** Worktrees get cleaned up, so uncommitted/unpushed work is lost. Sequence: implement → test → commit → push → PR. Never stop at "implement." | |
| - **All tests pass before commit.** Never commit a red suite, never "fix" it by deleting or skipping tests. | |
| - Remove a worktree only after its branch is pushed and the PR exists. | |
| --- | |
| ## Testing | |
| - New behavior gets new tests in the same PR — not "later." | |
| - Test behavior and contracts, not implementation details. | |
| - Cover unhappy paths: empty input, missing auth, invalid data, error propagation. | |
| - A failing test is information. Report it; never weaken the assertion to make it pass. | |
| --- | |
| ## Anti-patterns | |
| | ❌ Never | ✅ Instead | | |
| |---|---| | |
| | pip / poetry / npm / yarn / pnpm | `uv` (Python), `bun` (JS) | | |
| | Comments explaining business rules | Encode rules in code and tests | | |
| | Comment blocks longer than 2 lines | Restructure until the comment is unnecessary | | |
| | Rewriting comments while editing nearby code | Leave them unless their code changed | | |
| | Manual registration of auto-discoverable things | Auto-discovery | | |
| | Fat `__init__.py` re-exports | Import from the actual module | | |
| | Working on main / sharing worktrees | Fresh worktree per task and per subagent | | |
| | Uncommitted work left in a worktree | Commit, push, and PR before stopping | | |
| | Real secrets in examples or commits | Placeholders in `.env.example`; `.env` gitignored | | |
| | "I'll add tests later" | Tests in the same PR | | |
| | Magical abstractions, implicit global state | Explicit, traceable, injected dependencies | | |
| | Squash merges | Merge commits | | |
| --- | |
| ## When in doubt | |
| 1. Read the surrounding code first — the existing pattern beats this document's defaults. | |
| 2. Raise a question to the user when the implementation path is ambiguous. | |
| 3. If a decision isn't covered here and isn't derivable from the code, ask — don't enshrine a guess. | |
| --- | |
| ## Debugging | |
| Don't guess at fixes. Deconstruct the root cause through verifiable observations and tests; understand the "why" before attempting a fix. | |
| When tempted to patch or work around a problem, resist. Explore solutions in a fan-out worktree with experiments — test multiple approaches without risking the main codebase. Once you find a fix that addresses the root cause, merge or reimplement it with confidence. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment