A project framework for Claude Code that enforces engineering discipline, prevents common AI agent failure modes, and builds continuous improvement into your workflow.
A complete set of templates for configuring Claude Code as a rigorous engineering partner rather than a compliant assistant. Includes:
- CLAUDE.md template — Project rules, architecture constraints, agent behavior rules with auto-generated section markers
- Skills — 20 slash commands: 15 core (
/build,/test,/review,/check-sizes,/retro,/commit,/create-pr,/create-ticket,/create-skill,/document-bug,/session-mode,/diagnose,/fix-issue,/smoke-test) + 5 Linear integration (/linear-sync,/linear-create,/linear-triage,/linear-sprint,/linear-update) - Hooks — 6 automated enforcement hooks + optional tdd-guard TDD enforcement (file size limits, scope warnings, pre-commit verification, rule persistence through context compression)
- Rules — 11 modular, path-scoped rule files (anti-sycophancy, scope guardrails, feedback loops, anti-patterns, canary strategy, trust levels, complexity budget, public-facing writing)
- Agents — 6 specialized subagents with persistent memory (code reviewer, docs reviewer, planner, QA tester, domain expert, Linear PM)
- Ticket system — Persistent task tracking across sessions with structured templates
- Issue tracking — Linear as single source of truth with local snapshot cache (
docs/LINEAR_SNAPSHOT.md) - Setup tooling — Automated setup and update scripts, comment stripping for production,
.claudeignoretemplate
Every rule in this framework exists because of a specific failure mode observed in production use of AI coding agents. These are not theoretical — they address real categories of problems that occur when LLM agents operate without structured constraints.
| Rule | Failure Mode It Prevents |
|---|---|
| File size limits | Large files exhaust context windows, degrading reasoning quality and causing hallucinations |
| Anti-sycophancy rules | Agent agrees with incorrect approaches instead of pushing back, compounding errors |
| Evidence-based claims | Agent asserts code exists or behaves a certain way without verification, wasting debugging time |
| Max fix attempts | Unbounded fix-retry loops where each attempt introduces new regressions |
| Scope guardrails | Uncontrolled scope expansion — a single bug fix becomes a multi-file refactor with cascading breakage |
| Feedback loop | Hard-won knowledge is lost between sessions, causing the same mistakes to be repeated |
| PreCompact hook | Critical rules are dropped during context compression, effectively removing constraints mid-session |
| Diagnosis rules | Speculative fixes applied without evidence, masking root causes or introducing new failures |
| Session modes | Behavioral constraints stated early in a session are forgotten as context grows |
| Pre-commit hook | Code committed without build or test verification, shipping broken artifacts |
| Public-writing rule | Public text drafted from the agent's session reads as a narrative of its own work, and leaks private data into artifacts that cannot be un-published |
| Public-text hook | Real values and identifiers reach commit messages and release notes, where a forward fix cannot remove them |
| Docs reviewer | The author cannot see session narrative in their own text — they have the context that makes it feel earned |
# Clone this repo
git clone https://github.com/opmau/claude-code-framework.git
# Option A: Automated setup (recommended)
bash claude-code-framework/bin/setup.sh /path/to/your-project
# Option A2: Auto-calibrate file-size limits for your language in one shot
bash claude-code-framework/bin/setup.sh /path/to/your-project --language python
# Supported: python, cpp, typescript, rust, go, none
# (Writes the limits into .claude/project.conf AND updates the CLAUDE.md
# File Size Limits table to match. Omit the flag to keep the C++ defaults.)
# Option B: Manual copy
cp -r claude-code-framework/templates/.claude your-project/.claude
cp claude-code-framework/templates/CLAUDE.md your-project/CLAUDE.md
cp claude-code-framework/templates/.claudeignore your-project/.claudeignore
cp -r claude-code-framework/templates/docs your-project/docs
mv your-project/.claude/project.conf.example your-project/.claude/project.confPrerequisites (for hooks): bash, jq. On Windows, use Git Bash or WSL. See Platform Notes.
jq is required, not optional — the hooks parse their input and build their output with it, and without it they exit silently having enforced nothing. setup.sh refuses to install hooks if jq is missing; pass --no-hooks to install everything else.
Updating an existing project:
# Pull latest framework changes without overwriting your CLAUDE.md, docs/, or tickets/
bash claude-code-framework/bin/update.sh /path/to/your-project
# Preview what would change first
bash claude-code-framework/bin/update.sh /path/to/your-project --dry-runOpen Claude Code in your project and paste:
I'm setting up a new project with a CLAUDE.md framework. The template is
already in place at CLAUDE.md. Your job is to POPULATE it, not redesign it.
PROJECT CONTEXT:
- Project name: [your project name]
- Language: [e.g., Python 3.11, TypeScript, C++17]
- Build command: [e.g., npm run build]
- Test command: [e.g., pytest, npm test]
Read CLAUDE.md and replace [BRACKETED] placeholders with my project values.
DO NOT change the section order or remove any agent behavior rules.
Show me the changes before writing.
Read CLAUDE.md and answer:
1. If I proposed a fix and you thought it was wrong, what would you do?
2. If a file hit 450 lines, what would you do?
3. If your second fix attempt failed, what would you do?
See PROJECT_SETUP.md for the full 11-step setup guide.
When the framework gets new skills, bug fixes, or rule improvements, update your project:
# Preview what would change
bash claude-code-framework/bin/update.sh /path/to/your-project --dry-run
# Apply updates
bash claude-code-framework/bin/update.sh /path/to/your-project
# Also delete files that no longer exist in the templates (off by default,
# because it removes skills/rules/agents your project wrote too)
bash claude-code-framework/bin/update.sh /path/to/your-project --pruneThe update script overwrites framework files only (skills, rules, hooks, agents) and never touches your project-specific files (CLAUDE.md, docs/, .linear.toml, .claude/project.conf).
Project-owned files are protected:
| File | Behavior on update |
|---|---|
.claude/project.conf |
Never touched. This is where you customize the framework. |
.claude/settings.local.json |
Installed if missing; once you edit it, left alone (it holds your hook wiring and permissions). |
.claudeignore |
Same — installed if missing, preserved once edited. |
.claude/tickets/, .claude/tdd-guard/ |
Seeded on first install, then yours. ticket-list.md accumulates real state and the tdd-guard reporter is meant to be customized, so neither is refreshed. |
| Skills/rules/hooks/agents you wrote yourself | Kept and reported as [extra]. Pass --prune to delete anything absent from the templates. |
When a preserved file has upstream changes you want, the script prints the diff command to review them.
Customize in
.claude/project.conf, never by editing.claude/hooks/. The updater copies hooks over wholesale, so edits made directly to a hook script are silently reverted on the next update.
bin/
├── setup.sh # Automated project setup script
├── update.sh # Update framework files in existing projects
└── strip-comments.sh # Strip coaching comments for production
templates/
├── CLAUDE.md # Main agent rules template
├── .claudeignore # Files Claude should skip
├── docs/
│ ├── CURRENT_SPRINT.md # Sprint state template
│ └── LINEAR_SNAPSHOT.md # Auto-generated Linear cache
└── .claude/
├── settings.local.json # Hook registration (pre-configured)
├── project.conf.example # Per-project hook config; never overwritten by update.sh
├── skills/
│ ├── build/SKILL.md # /build — compile and report
│ ├── test/SKILL.md # /test — run tests, parse results
│ ├── review/SKILL.md # /review — pre-commit code review
│ ├── check-sizes/SKILL.md # /check-sizes — audit file sizes
│ ├── retro/SKILL.md # /retro — session retrospective
│ ├── commit/SKILL.md # /commit — conventional commit generation
│ ├── create-pr/SKILL.md # /create-pr — structured PR creation
│ ├── create-skill/SKILL.md # /create-skill — generate new skills
│ ├── document-bug/SKILL.md # /document-bug — log bugs in Linear
│ ├── session-mode/SKILL.md # /session-mode — set session constraints
│ ├── diagnose/SKILL.md # /diagnose — structured bug investigation
│ ├── prfaq/SKILL.md # /prfaq — interview to shared understanding on a PRFAQ
│ ├── fix-issue/SKILL.md # /fix-issue — fix tracked Linear issues
│ ├── smoke-test/SKILL.md # /smoke-test — integration test log triage
│ ├── create-ticket/SKILL.md # /create-ticket — local task tracking
│ ├── linear-create/SKILL.md # /linear-create — create Linear issues
│ ├── linear-sync/SKILL.md # /linear-sync — generate local snapshot
│ ├── linear-triage/SKILL.md # /linear-triage — triage and groom issues
│ ├── linear-sprint/SKILL.md # /linear-sprint — sprint/cycle management
│ └── linear-update/SKILL.md # /linear-update — update issue status
├── hooks/
│ ├── check-file-size.sh # Warns when files exceed size limits
│ ├── check-scope.sh # Warns when editing out-of-scope files + session mode
│ ├── pre-commit-check.sh # Warns when committing without build/test
│ ├── check-public-text.sh # Scans text about to be published for private data
│ ├── inject-critical-rules.sh # Preserves rules through context compression
│ └── session-check.sh # Periodic feedback loop reminder
│ # + tdd-guard hooks (optional, pre-configured in settings.local.json)
├── tdd-guard/ # TDD enforcement templates (optional)
│ ├── data/instructions.md # Project-specific test instructions
│ └── reporters/generic-reporter.sh # Test output → TDD Guard JSON
├── rules/
│ ├── agent-behavior.md # Anti-sycophancy, evidence rules
│ ├── scope-guardrails.md # Change scope limits
│ ├── file-size-limits.md # Size limits (path-scoped to src/)
│ ├── testing-protocol.md # Test mapping, bug handling
│ ├── linear-workflow.md # Linear integration rules
│ ├── feedback-loop.md # Post-session review triggers
│ ├── anti-patterns.md # Explicit "don't do this" registry
│ ├── canary-strategy.md # De-risk cross-cutting changes
│ ├── trust-levels.md # Progressive autonomy by module risk
│ ├── complexity-budget.md # Code health thresholds
│ └── public-writing.md # Voice and private-data rules for public artifacts
├── agents/
│ ├── code-reviewer.md # Pre-commit reviewer with memory
│ ├── docs-reviewer.md # Cold reviewer for public-facing text
│ ├── planner.md # Task planning and breakdown
│ ├── qa-tester.md # Test writing and QA
│ ├── domain-expert.md # Domain specialist with memory
│ └── linear-pm.md # Linear PM — sprint planning, health checks
└── tickets/
├── README.md # Ticket system guide
├── ticket-list.md # Centralized task index
└── TICKET-000-template.md # Ticket template
Claude's default is to agree with users. In engineering, this creates blind spots. The framework explicitly instructs Claude to:
- Push back when it disagrees ("I'd push back on this because...")
- Propose better alternatives even when not asked
- Never agree just to be agreeable
- Re-check evidence when challenged instead of immediately conceding
- Follow user-provided log evidence before proposing its own theories
- Test multiple hypotheses before concluding on a root cause
Lock sessions into specific operating modes to prevent drift:
/session-mode debug— focused bug fixing, no refactoring/session-mode refactor— restructure code, document bugs found but don't fix them/session-mode feature— build new functionality with a plan
Complete lifecycle from discovery to fix:
/document-bug— log bugs as Linear issues without touching source code, recording what was expected and whether the cause is confirmed/diagnose— structured differential diagnosis with multiple hypotheses; records the confirmed root cause on the issue/fix-issue— pick a tracked bug, reproduce it, agree the acceptance criteria, then fix it test-first and update issue tracking
An issue carries its root cause as UNCONFIRMED or CONFIRMED. /diagnose is the
only transition between them, and /fix-issue refuses to fix an unconfirmed cause
or a failure it cannot reproduce — a tracked issue is a lead, not a specification.
/smoke-test— analyze integration test logs, classify failures by severity, batch-create issues
Rules aren't just documented — they're enforced automatically:
- PostToolUse hook checks file size after every edit
- PreToolUse hook warns about out-of-scope changes and enforces session mode constraints
- PreToolUse hook warns when committing without running build/tests
- PreToolUse hook scans text about to be published — commit messages, PR bodies, release notes, staged docs — for private data and session narrative
- PreCompact hook re-injects critical rules (including diagnosis rules) before context compression
- Stop hook periodically reminds about documentation updates
- Optional: tdd-guard hooks enforce TDD discipline automatically — blocks implementation code without failing tests, supports mid-session toggle (
tdd-guard on/tdd-guard off). Pre-configured insettings.local.json; install withnpm install -g tdd-guard
Built-in slash commands for clean git workflows:
/commit— generates conventional commit messages from staged changes/create-pr— creates PRs with structured summary, changes list, and test plan/create-ticket— tracks tasks persistently across sessions/create-skill— meta-skill to generate new custom skills/linear-sync,/linear-create,/linear-triage,/linear-sprint,/linear-update— full Linear issue tracking integration
- CLAUDE.md includes an Integration Testing section template for documenting smoke test commands and log interpretation
/smoke-testskill analyzes integration test logs, diagnoses failures against source code, and batch-creates issues- Integration test results feed into the structured bug workflow (
/document-bug→/fix-issue)
Agents draft commit messages, PR bodies and release notes from their own working session, because that is what is salient to them. The result reads as a narrative of the agent's work rather than a description of the change, and it is how real values and identifiers end up in artifacts that cannot be un-published.
A rule alone does not fix this — it governs what not to write, while the problem is what the text is drafted from. The framework addresses it with three mechanisms:
rules/public-writing.md— defines the reader (a technical lead integrating the project) and the three questions every sentence must servehooks/check-public-text.sh— scans commit messages, PR bodies, release notes and staged docs before the publishing command runsdocs-revieweragent — reviews the text with no session context, so anything that only makes sense to someone who watched the work reads as unmotivated
Six agents with persistent memory for different roles:
- code-reviewer — pre-commit review against CLAUDE.md rules (Opus)
- docs-reviewer — cold review of public-facing text, given only the artifact and the diff (Opus)
- planner — breaks down complex tasks before implementation (Opus)
- qa-tester — writes tests, validates coverage, investigates failures (Opus)
- domain-expert — deep expertise for domain-specific debugging (Opus) — supports splitting into multiple domain experts
- linear-pm — sprint planning, velocity analysis, project health, release readiness (Opus)
The framework builds continuous improvement into every session:
- Post-session retrospectives via
/retro - Living documentation rules (Claude proposes updates to CLAUDE.md)
- Retrospective triggers for bugs, failed fixes, and incidents
- Agent memory persistence (all agents learn over time)
File limits aren't just code quality — they're agent performance optimization:
- Smaller files = more context window for reasoning
- Smaller files = fewer ambiguous string matches for edits
- Smaller files = smaller blast radius from mistakes
- Language-specific calibration table included
All per-project framework configuration lives in .claude/project.conf, created
by bin/setup.sh and never touched by bin/update.sh. The hooks source it
at runtime and fall back to the framework defaults for anything left unset, so
the framework itself stays generic while each project overrides what it needs.
# This project's source lives in lib/ and cmd/, not src/
ALLOWED_DIRS="lib/ cmd/ tests/ docs/ .claude/"
# Extend the built-in always-editable file list rather than replacing it
ALLOWED_FILES_EXTRA="requirements.txt Dockerfile"
# Python calibration (or run: setup.sh <project> --language python)
HEADER_LIMIT=300
IMPL_LIMIT=300Every setting is optional and falls back to the framework default. Setting a
list to "" means "match nothing" — comment the line out to restore the
default instead.
Editing the hook scripts directly does not survive an update — the updater
copies them over wholesale. project.conf is the supported seam.
Pass --language <name> to bin/setup.sh and the script writes the limits into
.claude/project.conf and updates the CLAUDE.md File Size Limits table to match.
The values used are below. Omit the flag to keep the template's C++ defaults;
pass --language none to be explicit about opting out.
| Language | Header/Interface | Implementation | Total |
|---|---|---|---|
| C/C++ | 150 | 400 | 500 |
| TypeScript | 100 | 300 | 400 |
| Python | N/A | 300 | 300 |
| Rust | N/A | 400 | 400 |
| Go | N/A | 400 | 400 |
Not every project needs every section. Safe to remove:
- Production Protection — if no production environment
- File Header Template — if your language/project doesn't use them
Never remove:
- Agent Behavior Rules — these prevent the most common AI failures
- Feedback Loop — this is how the system improves
- Scope Guardrails — this prevents Claude from making sweeping changes
Reduce CLAUDE.md from ~850 lines to ~400 lines after setup:
bash bin/strip-comments.sh CLAUDE.md --dry-run # preview
bash bin/strip-comments.sh CLAUDE.md # stripPlus .claudeignore prevents Claude from reading build artifacts, dependencies, and binary files.
If you use this framework and discover improvements:
- New steering phrases that work well for Claude Code
- Hook scripts for additional enforcement
- Skills for common workflows
- Rules for specific languages/frameworks
- Gotcha patterns that apply across projects
Open a PR or issue.
MIT