diff --git a/.claude/rules/frontend.md b/.claude/rules/frontend.md
index 692e6a7..ae9933a 100644
--- a/.claude/rules/frontend.md
+++ b/.claude/rules/frontend.md
@@ -4,31 +4,32 @@ globs: ["**/*.{js,jsx,ts,tsx,vue,svelte}"]
# Frontend Rules
+> Loaded automatically when Claude opens any frontend source file. Each rule has a "why" so you can override it intentionally.
+
## Components
-- Functional components only (no class components)
-- One component per file
-- Reusable components in `components/` directory
-- Page components in `pages/` or `views/` directory
-- Props interface/type defined at top of file
+- Functional components only (no class components) — *hooks API is the supported path since React 16.8 (2019); class lifecycle methods are not first-class with Suspense / concurrent rendering*
+- One component per file — *grep-by-filename works; circular-import risk drops*
+- Reusable components in `components/`, page components in `pages/` or `views/` — *next.js / nuxt convention; routing tools depend on it*
+- Props interface/type defined at top of file (TS) or `propTypes` defined at bottom (JS) — *contract is visible without scrolling; LSP autocomplete works for consumers*
## State Management
-- Local state for component-specific data
-- Global store for shared application state
-- API calls through dedicated service layer (not inside components)
-- Loading and error states for all async operations
+- Local state for component-specific data (`useState`, `useReducer`) — *keep blast radius small; don't pollute global store with form input state*
+- Global store (Zustand / Redux / Pinia) for shared application state only — *anything passed through more than 2 prop layers is a candidate; below that, prop drilling is fine*
+- API calls through a dedicated service layer (`services/` or `api/`), not inside components — *one place to swap fetch for axios, add retries, mock in tests*
+- Loading and error states for all async operations — *the "spinner-then-blank" UX is a regression magnet; always render `if (error) ... if (loading) ... return data`*
## Styling
-- Follow existing project conventions (CSS modules / Tailwind / styled-components)
-- Responsive design — mobile-first approach
-- No inline styles beyond trivial cases
+- Follow the project's existing convention (CSS modules / Tailwind / styled-components / vanilla-extract) — *do not introduce a second styling system; the bundle size and cognitive cost is real*
+- Responsive design — mobile-first (`min-width` queries, not `max-width`) — *progressive enhancement; default styles work on the smallest target*
+- No inline styles beyond trivial cases (one-off `style={{ width: dynamicPx }}`) — *inline styles bypass the design system, can't be themed, and hurt CSP*
## Error Handling
-- Error boundaries for user-facing components
-- User-friendly error messages (no raw error objects)
-- Graceful degradation when API is unavailable
+- Error boundaries for user-facing component trees — *uncaught render errors otherwise unmount the entire React tree (white screen)*
+- User-friendly error messages, no raw `error.toString()` — *expose stack traces only in dev; production users see a sentence and a retry button*
+- Graceful degradation when API is unavailable — *show cached data + "offline" indicator rather than a hard error*
## Testing
-- Unit tests for utility functions
-- Component tests for user interactions
-- Mock API responses in tests
-- Test accessibility (semantic HTML, ARIA labels)
+- Unit tests for utility functions (Vitest / Jest) — *fastest feedback loop; pure functions deserve 100% coverage*
+- Component tests for user interactions (Testing Library: `getByRole`, `userEvent.click`) — *test the user contract, not implementation details; avoid `getByTestId` unless nothing semantic exists*
+- Mock API responses in tests (MSW preferred over `jest.mock`) — *MSW intercepts at the network layer, so the same mocks work in Storybook and Playwright*
+- Test accessibility (semantic HTML, ARIA labels, `getByRole` queries) — *if Testing Library can find your button, so can a screen reader*
diff --git a/.claude/rules/python-backend.md b/.claude/rules/python-backend.md
index 879f82c..a306d7b 100644
--- a/.claude/rules/python-backend.md
+++ b/.claude/rules/python-backend.md
@@ -4,30 +4,32 @@ globs: ["**/*.py"]
# Python Backend Rules
+> Loaded automatically when Claude opens any `*.py` file. Each rule has a "why" so you can override it intentionally rather than blindly.
+
## Code Style
-- Type hints on ALL function signatures (parameters and return types)
-- Docstrings on all public functions and classes (Google style)
-- Use `pathlib.Path` instead of `os.path`
-- Prefer f-strings over `.format()` or `%`
-- Use `logging` module, never `print()` for non-debug output
-- Constants in UPPER_SNAKE_CASE at module level
+- Type hints on ALL function signatures (parameters and return types) — *enables `mypy --strict` and IDE autocomplete; required by FastAPI/Pydantic v2 for response_model inference*
+- Docstrings on all public functions and classes (Google style) — *parsed by Sphinx/mkdocstrings; downstream callers see hover hints*
+- Use `pathlib.Path` instead of `os.path` — *cross-platform paths, chainable API, `.exists()`/`.read_text()` without import gymnastics*
+- Prefer f-strings over `.format()` or `%` — *fastest path on CPython 3.12+; lower cognitive load*
+- Use `logging` module, never `print()` for non-debug output — *level filtering, structured handlers, captured by pytest's `caplog` fixture*
+- Constants in UPPER_SNAKE_CASE at module level — *grep-friendly, distinguishable from runtime values*
## Error Handling
-- Handle exceptions explicitly — never use bare `except:`
-- Use custom exception classes for domain errors
-- Always log exceptions with traceback: `logger.exception("message")`
-- Return meaningful error messages to API callers
+- Handle exceptions explicitly — never use bare `except:` — *bare except swallows `KeyboardInterrupt` and `SystemExit`, hides real bugs*
+- Use custom exception classes for domain errors — *callers can `except DomainError` without coupling to library-specific exception types*
+- Always log exceptions with traceback: `logger.exception("message")` — *not `logger.error(str(e))` which loses the stack*
+- Return meaningful error messages to API callers — *FastAPI: prefer `HTTPException(status_code, detail)` over generic 500*
## Architecture
-- Use Pydantic models for request/response validation
-- Async endpoints where I/O is involved
-- Dependency injection for testability
-- Repository pattern for database access
-- Service layer between routes and repositories
+- Use Pydantic v2 models for request/response validation — *catches malformed input at the boundary; auto-generates OpenAPI*
+- Async endpoints where I/O is involved (`await db.execute(...)`, `await http.get(...)`) — *sync handlers block the event loop and serialise the entire app*
+- Dependency injection (FastAPI `Depends`) for testability — *swap real DB session for in-memory in tests without monkey-patching*
+- Repository pattern for database access — *isolates SQL/ORM details from business logic; one place to add caching*
+- Service layer between routes and repositories — *route handlers stay thin (parse → call service → serialise); business logic is unit-testable without HTTP*
## Testing
-- Use pytest with fixtures
-- Mock external services (API calls, database) in unit tests
-- Use factories for test data (not hardcoded dictionaries)
-- Async tests with `pytest-asyncio`
-- Each test function tests ONE thing
+- Use pytest with fixtures (not `unittest.TestCase`) — *first-class parametrize, smaller boilerplate, plugin ecosystem (`pytest-asyncio`, `pytest-mock`, `pytest-cov`)*
+- Mock external services (API calls, database) in unit tests — *unit tests must run in <1 s each; integration tests live in a separate folder*
+- Use factories for test data (`factory_boy`, `polyfactory`), not hardcoded dictionaries — *changes to a model don't break 50 unrelated tests*
+- Async tests with `pytest-asyncio` and `@pytest.mark.asyncio` — *required for `async def` tests; otherwise pytest treats them as coroutines and skips silently*
+- Each test function tests ONE thing — *failure message names exactly what regressed; no shotgun debugging*
diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml
new file mode 100644
index 0000000..410b464
--- /dev/null
+++ b/.github/workflows/validate.yml
@@ -0,0 +1,73 @@
+name: Validate
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Validate settings.json is well-formed JSON
+ run: |
+ python -c "import json,sys; json.load(open('.claude/settings.json'))"
+ echo "settings.json: OK"
+
+ - name: Validate every agent has a YAML frontmatter name field
+ run: |
+ set -e
+ fail=0
+ for f in .claude/agents/*.md; do
+ if ! awk '/^---$/{f++; next} f==1' "$f" | grep -qE '^name:[[:space:]]*[A-Za-z0-9_-]+'; then
+ echo "::error file=$f::missing or invalid 'name:' field in YAML frontmatter"
+ fail=1
+ fi
+ if ! awk '/^---$/{f++; next} f==1' "$f" | grep -qE '^description:'; then
+ echo "::error file=$f::missing 'description:' field in YAML frontmatter"
+ fail=1
+ fi
+ if ! awk '/^---$/{f++; next} f==1' "$f" | grep -qE '^tools:'; then
+ echo "::error file=$f::missing 'tools:' field in YAML frontmatter"
+ fail=1
+ fi
+ done
+ exit $fail
+
+ - name: Validate every rule has a globs frontmatter
+ run: |
+ set -e
+ fail=0
+ for f in .claude/rules/*.md; do
+ if ! awk '/^---$/{f++; next} f==1' "$f" | grep -qE '^globs:'; then
+ echo "::error file=$f::missing 'globs:' field in YAML frontmatter"
+ fail=1
+ fi
+ done
+ exit $fail
+
+ - name: CHANGELOG.md exists and is non-empty
+ run: |
+ test -s CHANGELOG.md || (echo "CHANGELOG.md missing or empty" && exit 1)
+
+ - name: All Markdown internal links resolve
+ run: |
+ set -e
+ fail=0
+ while IFS= read -r line; do
+ file="${line%%:*}"
+ rest="${line#*:}"
+ target=$(echo "$rest" | grep -oE '\]\([^)#]+' | sed 's/](//' | head -1)
+ [ -z "$target" ] && continue
+ case "$target" in
+ http*|mailto:*|\#*) continue ;;
+ esac
+ base="$(dirname "$file")"
+ resolved="$base/$target"
+ if [ ! -e "$resolved" ] && [ ! -e "$target" ]; then
+ echo "::warning file=$file::broken internal link → $target"
+ fi
+ done < <(grep -rEn '\]\([^)]+\)' README.md CHANGELOG.md CONTRIBUTING.md docs/*.md 2>/dev/null || true)
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..580a758
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,41 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · [SemVer](https://semver.org/spec/v2.0.0.html).
+
+## [0.2.0] — 2026-04-30
+
+### Added
+- Mermaid diagram of the four-layer defence model in `README.md`
+- `Limitations & honest disclaimers` section covering compaction, subagent isolation, shell portability, slow suites, push-vs-commit gate, `/clear` behaviour, advisory nature of rules
+- `Tech stack & component map` table mapping each file to a concrete role
+- `Configuration notes` section explaining `permissions.allow` semantics and stack-specific test-command swap-ins
+- `CHANGELOG.md` (this file)
+- `CONTRIBUTING.md` with priority list for community submissions
+- `.github/workflows/validate.yml` — validates `settings.json` is well-formed JSON and every agent file has a YAML frontmatter `name:` field
+- "Featured on Habr / dev.to / Claude Code Opus 4.7" badges
+- Inline `CRITICAL RULES` block in `README.md` so the value proposition is visible without opening the template
+- "Why" rationale comments on rules in `.claude/rules/python-backend.md` and `.claude/rules/frontend.md`
+- Author signature with full name and direct links to Habr / dev.to profiles
+
+### Changed
+- README hero rewritten: leads with social proof (Habr top-5, 20K reads, Технотекст 8) and Opus 4.7 / 1M context positioning
+- "The Problem" section replaced with the post-1M-context narrative — regressions are a discipline problem, not a memory problem
+- Project structure tree annotated with concrete responsibilities per file
+- `Recommended stack` table extended with "Why" column
+
+### Notes on `settings.json`
+- `Bash(pip install*)` remains in `permissions.allow` for compatibility with the original community template, but is now flagged in README as a candidate for removal in security-sensitive projects
+- The hook's `pytest` command is unchanged; README now documents the npm / cargo / go variants
+
+## [0.1.0] — 2026-03-05
+
+### Added
+- Initial release accompanying the [Habr article](https://habr.com/ru/articles/1013330/) (top-5 day, 20K reads, Технотекст 8 entry) and the [dev.to article](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
+- `CLAUDE.md.template` with `CRITICAL RULES`, `Working Style`, `Agents`, `Known Patterns`, `Gotchas` sections
+- `.claude/settings.json` with `PreToolUse` commit-blocking `pytest` hook and `PostToolUse` edit reminder
+- Three subagents: `planner` (research-only, no `Write` tool), `tester` (full-suite runner with regression check), `code-reviewer` (severity-tagged review)
+- Two glob-scoped rules: `python-backend.md` (`**/*.py`), `frontend.md` (`**/*.{js,jsx,ts,tsx,vue,svelte}`)
+- `docs/WORKFLOW.md` daily playbook with emergency recovery and cheat sheet
+- `docs/MCP-SETUP.md` for Playwright, GitHub, Postgres, Context7
+- `LICENSE` (MIT)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..d122896
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,39 @@
+# Contributing
+
+Thanks for considering a contribution. This repo is intentionally small — its job is to be a clean, copy-paste starter for Claude Code anti-regression configs. PRs that add real, battle-tested artifacts are very welcome.
+
+## Priorities (highest impact first)
+
+1. **Sister rules for new languages** — `.claude/rules/go-backend.md`, `rust-backend.md`, `typescript-node.md`, `kotlin.md`, etc. Follow the existing `python-backend.md` shape (frontmatter `globs:` + sections + a one-line "why" per rule).
+2. **Framework-specific subagents** — `django-tester.md`, `nextjs-reviewer.md`, `rails-planner.md`. Constrain `tools:` to the minimum set needed and document the output format.
+3. **Additional `PreToolUse` hooks** — examples that would fit:
+ - **Lint gate** on `git commit*` (`ruff check` / `eslint` / `golangci-lint`)
+ - **Secret-scanning gate** on `git commit*` (`gitleaks detect --staged`)
+ - **Migration-safety gate** on writes to `migrations/` directory
+4. **Stack-specific test-command swap-ins** for the README's `Configuration notes` section (Maven, Gradle, sbt, mix, etc.).
+5. **Recording assets** — better demo GIF / asciinema cast than the placeholder.
+
+## What we will not merge
+
+- "Best practices" essays without code artifacts.
+- Vendor-specific rules that lock the user into a single editor or shell beyond what the existing setup already does.
+- Hooks that silently weaken the commit gate (e.g. `pytest --pass-with-no-tests` without a clear opt-in note).
+- Generic linter configs that already have canonical homes elsewhere (just link to them in `docs/MCP-SETUP.md` style).
+
+## Pull request checklist
+
+- [ ] New rule file has frontmatter `globs:` and at least one "why" rationale per bullet
+- [ ] New subagent has `name:`, `description:`, `tools:` frontmatter and an explicit output format
+- [ ] New hook has a stated **timeout**, a stated **shell** (bash / pwsh / cross-platform), and a tested failure path
+- [ ] `README.md` and `CHANGELOG.md` updated when surface area changes
+- [ ] `validate.yml` workflow still passes (it checks `settings.json` is valid JSON and every `.claude/agents/*.md` has a `name:` frontmatter field)
+
+## Style
+
+- Prefer concrete commands and version numbers over abstract advice.
+- One sentence per rule. If you need a paragraph, you are explaining the wrong thing.
+- Cite the source of any "best practice" you import (Anthropic docs, SFEIR Institute, real incident).
+
+## Author / maintainer
+
+[@CreatmanCEO](https://github.com/CreatmanCEO) — Nick Podolyak. Open an issue first for anything larger than a single rule or subagent.
diff --git a/README.md b/README.md
index 99aaf03..6cfb80a 100644
--- a/README.md
+++ b/README.md
@@ -1,136 +1,229 @@
# Claude Code Anti-Regression Setup
-> Stop Claude Code from breaking your projects. Ready-to-use configs, agents, hooks, and templates.
+[](LICENSE)
+[](https://github.com/CreatmanCEO/claude-code-antiregression-setup/actions/workflows/validate.yml)
+[](https://habr.com/ru/articles/1013330/)
+[](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
+[](https://code.claude.com)
-## The Problem
+🇬🇧 English · [🇷🇺 Русский](README.ru.md)
-Claude Code progressively breaks projects during long sessions due to **context window exhaustion** (~200K tokens). At 90% utilization, it forgets earlier decisions and introduces regressions. 80% of context gets consumed by file reads and tool results — not your conversation.
+**The exact CLAUDE.md + subagents + hooks setup that got me into Habr's daily top-5 (20K reads, Технотекст 8 entry). Survives Claude's 1M context window — because regressions aren't a memory problem, they're a discipline problem.**
-The community calls this **"context drift"** and it's the #1 source of AI-introduced regressions.
+> Companion articles: [Habr (RU) — Как я перестал бояться Claude Code](https://habr.com/ru/articles/1013330/) · [dev.to (EN) — I Stopped Claude Code From Breaking My Projects](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
-## The Solution
+
-This repo provides a battle-tested anti-regression setup through four layers:
+> Want a real terminal recording instead of this rendered SVG? Run `bash docs/setup-demo-project.sh` and follow [docs/RECORDING-DEMO.md](docs/RECORDING-DEMO.md).
-1. **CLAUDE.md** — Persistent project rules that survive context compaction
-2. **Subagents** — Isolated AI specialists (planner, tester, reviewer) with separate context windows
-3. **Hooks** — Automated test gates that block broken commits
-4. **Rules** — Modular, glob-scoped coding standards
+---
-## What's Inside
+## Why this exists
+A million-token context window does not eliminate regressions — Anthropic itself reports only a 15% drop in compaction events with Opus 4.7 (April 2026). Even a developer with perfect memory will introduce bugs without process discipline. Claude with 1M tokens **remembers more, but still happily "improves" your working function or "optimizes" the test that guards an important edge case.**
+
+The root cause is not "the model is dumb." It is the absence of a project constitution that survives context compaction, a separation between research and implementation contexts, and an automated gate that refuses broken commits. This repo gives you all three.
+
+> Per SFEIR Institute, **60% of Claude Code support tickets** come from the *ghost context* anti-pattern — working without a `CLAUDE.md`. **A simple `CLAUDE.md` resolves the issue in 90% of cases.**
+
+## How it works — four layers of defence
+
+```mermaid
+graph TB
+ User["You (prompt)"]
+ Claude["Claude Code main session"]
+ CLAUDE["CLAUDE.md persistent rules · survives /compact"]
+ Rules[".claude/rules/ glob-scoped standards"]
+ Subs[".claude/agents/ planner · tester · reviewer"]
+ Hooks[".claude/settings.json PreToolUse · PostToolUse"]
+ Repo[("Your repo code · tests")]
+
+ User --> Claude
+ CLAUDE -->|"injected before every turn"| Claude
+ Rules -->|"loaded only on matching files"| Claude
+ Claude -->|"delegate research / tests / review"| Subs
+ Subs -->|"summary only — separate context"| Claude
+ Claude -->|"git commit attempt"| Hooks
+ Hooks -->|"pytest fails → block"| Claude
+ Hooks -->|"pytest passes → allow"| Repo
+
+ classDef gate fill:#fee,stroke:#c44
+ class Hooks gate
```
-├── CLAUDE.md.template # Project constitution — fill in your details
+
+| Layer | What it does | Why it works |
+|---|---|---|
+| **CLAUDE.md** | Project constitution: stack, commands, CRITICAL RULES | Re-read from disk after every `/compact` — no rule can be "forgotten" |
+| **Subagents** | `planner` (research), `tester` (full suite), `code-reviewer` (regression check) | Each runs in isolated context; only summary returns to main session |
+| **Hooks** | `PreToolUse` on `git commit` runs `pytest` and blocks if anything fails | Hard gate — Claude literally cannot bypass it without you editing `settings.json` |
+| **Rules** | `glob`-scoped per-language standards in `.claude/rules/` | Loaded only when Claude opens matching files; saves context |
+
+## What you actually get
+
+```
+├── CLAUDE.md.template # Project constitution — copy and fill
├── .claude/
-│ ├── settings.json # Hooks: auto-test reminders, commit blocking
+│ ├── settings.json # Hooks: commit-blocking pytest + post-edit reminders
│ ├── agents/
-│ │ ├── planner.md # Research and planning (never writes code)
-│ │ ├── tester.md # Full test suite runner + regression checker
-│ │ └── code-reviewer.md # Quality, security and regression reviewer
+│ │ ├── planner.md # Research codebase, write plan to ./plans/, NEVER write code
+│ │ ├── tester.md # Run FULL suite (catches regressions), report root cause
+│ │ └── code-reviewer.md # Severity-rated review with file:line references
│ └── rules/
-│ ├── python-backend.md # Python-specific rules (glob-scoped)
-│ └── frontend.md # Frontend-specific rules (glob-scoped)
-├── plans/
-│ └── .gitkeep # Planner agent saves implementation plans here
-└── docs/
- ├── WORKFLOW.md # Daily anti-regression workflow guide
- └── MCP-SETUP.md # MCP server installation instructions
+│ ├── python-backend.md # globs: **/*.py — type hints, Pydantic, async I/O, no bare except
+│ └── frontend.md # globs: **/*.{js,jsx,ts,tsx,vue,svelte} — functional, error boundaries
+├── plans/ # planner agent saves implementation plans here
+├── docs/
+│ ├── WORKFLOW.md # Daily anti-regression workflow + emergency recovery
+│ └── MCP-SETUP.md # Playwright / GitHub / Postgres / Context7 install
+├── .github/workflows/validate.yml # CI: validates settings.json + agent frontmatter
+├── CHANGELOG.md # Versioned for Claude Code releases (Opus 4.6 → 4.7 → ...)
+└── CONTRIBUTING.md # Priorities for community contributions
+```
+
+## The `CRITICAL RULES` block (this is the product)
+
+This is the section of `CLAUDE.md.template` that does the heavy lifting. Claude follows these rules with high consistency *because they are injected before every turn — no compaction can erase them.*
+
+```markdown
+## CRITICAL RULES — MUST FOLLOW
+- **NEVER** delete or rewrite working tests without explicit request
+- **NEVER** delete files without asking for confirmation
+- **NEVER** make multiple unrelated changes in one step
+- **ALWAYS** run tests after any code change
+- **ALWAYS** do `git add -A && git commit` checkpoint before large refactors
+- **ALWAYS** preserve backward compatibility when refactoring
+- If unsure about anything — **ASK**, don't guess
+- One task at a time. Complete and verify before moving to next
```
## Quick Start (15 minutes)
-### 1. Copy configs to your project
+### 1. Copy configs into your project
```bash
git clone https://github.com/CreatmanCEO/claude-code-antiregression-setup.git
-cp -r claude-code-antiregression-setup/.claude /path/to/your/project/
-cp claude-code-antiregression-setup/CLAUDE.md.template /path/to/your/project/CLAUDE.md
+cd claude-code-antiregression-setup
+
+cp -r .claude /path/to/your/project/
+cp CLAUDE.md.template /path/to/your/project/CLAUDE.md
mkdir -p /path/to/your/project/plans
```
-### 2. Fill in CLAUDE.md
+### 2. Fill in `CLAUDE.md`
+
+Open `CLAUDE.md` in your project root and replace every `[placeholder]` with your stack, commands, and known gotchas.
-Open `CLAUDE.md` in your project root and replace all `[placeholders]` with your project's actual data.
+### 3. Adapt the test command in hooks
-### 3. Start Claude Code
+Edit `.claude/settings.json` and replace `python -m pytest tests/` with whatever your test runner is (`npm test`, `cargo test`, `make test`, etc.). The default 120-second timeout is enough for ~500 unit tests; raise it if your suite is heavier.
+
+### 4. Start Claude Code
```bash
claude
```
-Claude reads `CLAUDE.md` automatically. Try:
+Claude reads `CLAUDE.md` automatically. First useful prompt:
```
-> Use the planner agent to analyze our codebase and create a plan for [your task]
+> Use the planner agent to read this codebase and produce
+> a plan for [your task]. Do NOT write any code yet.
```
-### 4. Adapt hooks
+## Tech stack & component map
-Edit `.claude/settings.json` — replace `python -m pytest tests/` with your project's test command.
+| Component | File | What it does |
+|---|---|---|
+| Project constitution | `CLAUDE.md.template` | Persistent rules · survives `/compact` |
+| Commit gate | `.claude/settings.json` → `PreToolUse` | Runs `pytest -x --timeout=60` before every `git commit*` |
+| Edit reminder | `.claude/settings.json` → `PostToolUse` | Echoes "remember to run tests" after every `Write`/`Edit` |
+| Research agent | `.claude/agents/planner.md` | Tools: `Read · Grep · Glob · LS` (no `Write`) — cannot accidentally code |
+| QA agent | `.claude/agents/tester.md` | Tools: `Read · Write · Bash · Grep · Glob` — runs full suite, reports regressions |
+| Review agent | `.claude/agents/code-reviewer.md` | Tools: `Read · Grep · Glob` — severity-tagged review |
+| Python rules | `.claude/rules/python-backend.md` | `globs: **/*.py` — loaded only when Claude opens Python |
+| Frontend rules | `.claude/rules/frontend.md` | `globs: **/*.{js,jsx,ts,tsx,vue,svelte}` — loaded for frontend |
+| MCP integration | `docs/MCP-SETUP.md` | Playwright (browser) · GitHub · Postgres · Context7 |
-## How It Works
+## Recommended stack
-### CLAUDE.md — The Most Important File
+| Component | Tool | Cost | Why |
+|---|---|---|---|
+| IDE | [Google Antigravity](https://antigravity.google) | Free | Agent-first VS Code fork, built-in Gemini 3 Pro browser agent |
+| AI coding agent | Claude Code (Max) | $100/mo | 1M context on Opus 4.7, full subagent + hook ecosystem |
+| Visual UI testing | Gemini 3 Pro (in Antigravity) | Free | Autonomous browser navigation — no Playwright setup needed for casual checks |
+| Browser automation in code | [Playwright MCP](docs/MCP-SETUP.md) | Free | When you need scripted, repeatable tests |
-Claude reads this at the start of **every** session. It survives compaction. Your CRITICAL RULES live here.
+## Recommended workflow
-**Key stat**: 60% of Claude Code support tickets come from the "ghost context" anti-pattern — working without CLAUDE.md. A simple CLAUDE.md resolves 90% of cases.
+See [docs/WORKFLOW.md](docs/WORKFLOW.md) for the full daily playbook. The short version:
-### Subagents — Isolated Context Windows
+1. **Plan first** — `Use planner agent` → review the plan in `./plans/` → approve
+2. **Small diffs** — one file → tests → next file
+3. **Monitor context** — `/cost` periodically; `/compact` at 60–70%, even on Opus 4.7
+4. **Checkpoint** — `git commit -m "checkpoint: before X"` before risky changes
+5. **Review & test before final commit** — `Use code-reviewer` then `Use tester`
+6. **Rewind if broken** — `Esc + Esc` → restore code only (Claude's checkpoint), or `git reset --hard HEAD`
-| Agent | Purpose | Why Isolated? |
-|---|---|---|
-| `planner` | Research codebase, create plans | Research reads many files — would bloat main context |
-| `tester` | Run full test suite, catch regressions | Test output is verbose — stays out of working memory |
-| `code-reviewer` | Review for quality, security, patterns | Fresh perspective without implementation bias |
+## Configuration notes
-### Hooks — Automated Safety Nets
+### About the `permissions.allow` list in `settings.json`
-Commit-blocking hook prevents Claude from committing code that breaks tests. Zero exceptions.
+The list contains `Bash(git commit*)`, `Bash(npm test*)`, etc. **This does not weaken safety** — it only suppresses the per-command approval prompt for routine commands. The actual gate on `git commit` is the **hook**, which runs `pytest` and refuses the commit on failure.
-### Rules — Scoped Standards
+> ⚠️ The default config keeps `Bash(pip install*)` in `allow`. If you work with untrusted repos or want to require manual approval before any dependency change, **move `pip install*` out of `allow`** so Claude Code prompts you each time.
-Files in `.claude/rules/` load only when Claude works with matching file patterns — saves context.
+### About the hook's test command
-## Recommended Workflow
+The default is `python -m pytest tests/ -x --timeout=60`. Adjust to your stack:
-See [docs/WORKFLOW.md](docs/WORKFLOW.md) for the complete daily workflow.
+```jsonc
+// JS / TS project
+"command": "npm test --silent || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
-1. **Plan first**: `Use planner agent` → review → approve
-2. **Small diffs**: One step → tests → next step
-3. **Monitor context**: `/compact` at 60-70%
-4. **Checkpoint**: `git commit` before risky changes
-5. **Review**: `Use code-reviewer` before final commit
-6. **Rewind if broken**: `Esc + Esc` → restore code only
+// Rust project
+"command": "cargo test --quiet || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
-## Recommended Stack
+// Go project
+"command": "go test ./... || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
+```
-| Component | Tool | Cost |
-|---|---|---|
-| IDE | [Google Antigravity](https://antigravity.google) | Free |
-| AI Coding Agent | Claude Code (Max subscription) | $100/mo |
-| UI Testing | Gemini 3 Pro (built into Antigravity) | Free |
-| Browser Automation | Playwright MCP | Free |
+If your suite takes longer than 120 seconds, raise the `timeout` value in `settings.json` accordingly. Slower suites are still fine — the hook just needs enough time to finish.
+
+## Limitations & honest disclaimers
+
+This is not a magic shield. Concrete cases where the setup is *not enough*:
+
+- **Compaction still loses mid-conversation detail.** `CLAUDE.md` and disk files survive; the chat history between rule-loads does not. Important interim decisions belong in `./plans/` or a checkpoint commit, not in chat.
+- **Subagents do not share memory.** `tester` cannot see `planner`'s reasoning unless `planner` saved it to `./plans/`. The plan file is the medium of communication.
+- **Hooks are shell-dependent.** The default command uses bash syntax (`||`, `1>&2`, `2>&1`). On native Windows PowerShell you may need to rewrite the command or run Claude Code from WSL/Git Bash. Tested on macOS bash, Linux bash, Windows Git Bash.
+- **Slow test suites need tuning.** A 10-minute integration suite will time out at 120 s. Either raise the timeout, or split into a fast unit hook (gate) and a separate full-suite agent step (manual).
+- **Hooks gate `git commit`, not `git push`.** A determined misconfiguration can still push a broken commit. If you want a push gate, add a second `PreToolUse` matcher on `Bash(git push*)`.
+- **`/clear` reloads `CLAUDE.md` but loses `./plans/` context.** Re-feed the relevant plan filename to the next session.
+- **Rules are advisory, not enforced.** A `globs:` block tells Claude to *consider* a rule when editing matching files; it does not refuse to write non-conforming code. Pair rules with a real linter (ruff, eslint) in CI for hard enforcement.
+
+## What's new in this version
-See [docs/MCP-SETUP.md](docs/MCP-SETUP.md) for MCP server installation.
+See [CHANGELOG.md](CHANGELOG.md) for the full history. Latest: **0.2.0 (2026-04-30)** — updated for Opus 4.7 / 1M context, added Mermaid diagram, added validate-CI, added Limitations section.
## Contributing
-PRs welcome! Priority: language-specific rules, framework-specific agents, additional hooks.
+PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) — current priorities: sister rules for Go/Rust/TypeScript backends, framework-specific subagents (Django, Rails, Next.js), additional `PreToolUse` hooks (lint gate, secret scanning).
## Resources
-- [awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) — Curated list of skills, hooks, agents
-- [claude-code-workflows](https://github.com/shinpr/claude-code-workflows) — Production-ready workflow plugins
-- [Claude Code Docs: Best Practices](https://code.claude.com/docs/en/best-practices) — Official recommendations
+- [awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) — Curated skills, hooks, agents
+- [claude-code-workflows](https://github.com/shinpr/claude-code-workflows) — Production workflow plugins
+- [Claude Code Docs: Best Practices](https://code.claude.com/docs/en/best-practices) — Official guidance
+- Companion read on context engineering: [Habr article](https://habr.com/ru/articles/1013330/) · [dev.to article](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
## Author
-**Nick** — Python developer and digital architect at **CREATMAN**
+**Nick Podolyak** — Python developer and digital architect at [CREATMAN](https://creatman.site)
- GitHub: [@CreatmanCEO](https://github.com/CreatmanCEO)
-- Website: [creatman.site](https://creatman.site)
+- Habr: [creatman](https://habr.com/ru/users/creatman/)
+- dev.to: [@creatman](https://dev.to/creatman)
## License
-MIT
+[MIT](LICENSE) · Nick Podolyak
diff --git a/README.ru.md b/README.ru.md
new file mode 100644
index 0000000..74f42db
--- /dev/null
+++ b/README.ru.md
@@ -0,0 +1,229 @@
+# Claude Code Anti-Regression Setup
+
+[](LICENSE)
+[](https://github.com/CreatmanCEO/claude-code-antiregression-setup/actions/workflows/validate.yml)
+[](https://habr.com/ru/articles/1013330/)
+[](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
+[](https://code.claude.com)
+
+🇷🇺 Русский · [🇬🇧 English](README.md)
+
+**Готовый набор `CLAUDE.md` + субагентов + хуков, с которым моя статья попала в топ-5 дня на Хабре (20K чтений, заявка на «Технотекст 8»). Работает с миллионным окном Claude — потому что регрессии — это не проблема памяти, а проблема дисциплины.**
+
+> Статьи-сопровождения: [Habr (RU) — Как я перестал бояться Claude Code](https://habr.com/ru/articles/1013330/) · [dev.to (EN) — I Stopped Claude Code From Breaking My Projects](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
+
+
+
+> Хочешь реальную запись терминала вместо отрендеренного SVG? Запусти `bash docs/setup-demo-project.sh` и следуй [docs/RECORDING-DEMO.md](docs/RECORDING-DEMO.md).
+
+---
+
+## Зачем это нужно
+
+Контекстное окно в миллион токенов **не отменяет регрессии** — Anthropic сообщает лишь о 15% снижении событий compaction'а в Opus 4.7 (апрель 2026). Даже разработчик с идеальной памятью допустит баги, если у него нет процесса. Claude с 1M токенов **помнит больше, но всё ещё может «оптимизировать» вашу рабочую функцию или «улучшить» тест, охранявший важный edge case.**
+
+Корень не в том, что «модель тупая». Корень в отсутствии трёх вещей: конституции проекта, переживающей `/compact`; разделения исследовательского и реализационного контекстов; автоматического шлюза, который отказывается коммитить сломанный код. Этот репозиторий даёт всё три.
+
+> По данным SFEIR Institute, **60% обращений в поддержку Claude Code** вызваны паттерном *ghost context* — работой без `CLAUDE.md`. **Простой `CLAUDE.md` решает проблему в 90% случаев.**
+
+## Как это работает — четыре уровня защиты
+
+```mermaid
+graph TB
+ User["Вы (промпт)"]
+ Claude["Claude Code основная сессия"]
+ CLAUDE["CLAUDE.md правила · переживают /compact"]
+ Rules[".claude/rules/ стандарты по glob-паттерну"]
+ Subs[".claude/agents/ planner · tester · reviewer"]
+ Hooks[".claude/settings.json PreToolUse · PostToolUse"]
+ Repo[("Ваш репозиторий код · тесты")]
+
+ User --> Claude
+ CLAUDE -->|"инжектируется до каждого хода"| Claude
+ Rules -->|"загружается только при работе с подходящими файлами"| Claude
+ Claude -->|"делегирует исследование / тесты / ревью"| Subs
+ Subs -->|"возвращает только summary — отдельный контекст"| Claude
+ Claude -->|"попытка git commit"| Hooks
+ Hooks -->|"pytest упал → блок"| Claude
+ Hooks -->|"pytest ОК → разрешено"| Repo
+
+ classDef gate fill:#fee,stroke:#c44
+ class Hooks gate
+```
+
+| Уровень | Что делает | Почему это работает |
+|---|---|---|
+| **CLAUDE.md** | Конституция проекта: стек, команды, CRITICAL RULES | Перечитывается с диска после каждого `/compact` — ни одно правило не «забывается» |
+| **Субагенты** | `planner` (исследование), `tester` (полный прогон), `code-reviewer` (поиск регрессий) | Каждый работает в отдельном контексте; в основную сессию возвращается только summary |
+| **Хуки** | `PreToolUse` на `git commit` запускает `pytest` и блокирует, если что-то упало | Жёсткий шлюз — Claude физически не может его обойти, не редактируя `settings.json` |
+| **Правила** | Скоупированные по glob стандарты в `.claude/rules/` | Загружаются только когда Claude открывает соответствующий файл; экономят контекст |
+
+## Что внутри
+
+```
+├── CLAUDE.md.template # Конституция проекта — копируй и заполни
+├── .claude/
+│ ├── settings.json # Хуки: блокировка коммита по pytest + reminder после правки
+│ ├── agents/
+│ │ ├── planner.md # Исследует код, пишет план в ./plans/, НЕ КОДИТ
+│ │ ├── tester.md # Прогоняет ПОЛНЫЙ test-suite (ловит регрессии)
+│ │ └── code-reviewer.md # Ревью с severity (CRITICAL/WARNING/GOOD), file:line
+│ └── rules/
+│ ├── python-backend.md # globs: **/*.py — type hints, Pydantic, async I/O
+│ └── frontend.md # globs: **/*.{js,jsx,ts,tsx,vue,svelte}
+├── plans/ # planner сохраняет планы реализации сюда
+├── docs/
+│ ├── WORKFLOW.md # Дневной workflow + emergency recovery
+│ └── MCP-SETUP.md # Установка Playwright / GitHub / Postgres / Context7
+├── .github/workflows/validate.yml # CI: валидирует settings.json и frontmatter
+├── CHANGELOG.md # Версионирование под релизы Claude Code (4.6 → 4.7 → ...)
+└── CONTRIBUTING.md # Приоритеты для PR
+```
+
+## Блок `CRITICAL RULES` (это и есть продукт)
+
+Эта секция `CLAUDE.md.template` — главная рабочая лошадка. Claude следует этим правилам с высокой консистентностью **именно потому, что они инжектируются перед каждым ходом — никакой compaction их не сотрёт.**
+
+```markdown
+## CRITICAL RULES — MUST FOLLOW
+- **NEVER** удалять или переписывать рабочие тесты без явного запроса
+- **NEVER** удалять файлы без подтверждения
+- **NEVER** делать несколько несвязанных изменений за один шаг
+- **ALWAYS** запускать тесты после любого изменения кода
+- **ALWAYS** делать `git add -A && git commit` checkpoint перед крупными рефакторингами
+- **ALWAYS** сохранять обратную совместимость при рефакторинге
+- Если не уверен — **СПРОСИ**, не угадывай
+- Одна задача за раз. Закончи и проверь, прежде чем переходить к следующей
+```
+
+## Quick Start (15 минут)
+
+### 1. Скопировать конфиги в свой проект
+
+```bash
+git clone https://github.com/CreatmanCEO/claude-code-antiregression-setup.git
+cd claude-code-antiregression-setup
+
+cp -r .claude /path/to/your/project/
+cp CLAUDE.md.template /path/to/your/project/CLAUDE.md
+mkdir -p /path/to/your/project/plans
+```
+
+### 2. Заполнить `CLAUDE.md`
+
+Открой `CLAUDE.md` в корне своего проекта и замени все `[placeholder]` на реальный стек, команды и known gotchas.
+
+### 3. Адаптировать команду тестов в хуке
+
+Открой `.claude/settings.json` и замени `python -m pytest tests/` на свою команду (`npm test`, `cargo test`, `make test`). Дефолтный таймаут 120 секунд хватает на ~500 unit-тестов; если у тебя медленнее — увеличь.
+
+### 4. Запустить Claude Code
+
+```bash
+claude
+```
+
+Claude автоматически прочитает `CLAUDE.md`. Первый полезный промпт:
+
+```
+> Use the planner agent to read this codebase and produce
+> a plan for [твоя задача]. Do NOT write any code yet.
+```
+
+## Карта стека и компонентов
+
+| Компонент | Файл | Что делает |
+|---|---|---|
+| Конституция проекта | `CLAUDE.md.template` | Постоянные правила · переживают `/compact` |
+| Шлюз коммита | `.claude/settings.json` → `PreToolUse` | Запускает `pytest -x --timeout=60` перед каждым `git commit*` |
+| Reminder после правки | `.claude/settings.json` → `PostToolUse` | Напоминает запустить тесты после `Write`/`Edit` |
+| Исследовательский агент | `.claude/agents/planner.md` | Tools: `Read · Grep · Glob · LS` (нет `Write`) — не может случайно закодить |
+| QA-агент | `.claude/agents/tester.md` | Tools: `Read · Write · Bash · Grep · Glob` — полный прогон, отчёт по регрессиям |
+| Reviewer-агент | `.claude/agents/code-reviewer.md` | Tools: `Read · Grep · Glob` — ревью с severity-рейтингом |
+| Python-правила | `.claude/rules/python-backend.md` | `globs: **/*.py` — грузятся только при работе с Python |
+| Frontend-правила | `.claude/rules/frontend.md` | `globs: **/*.{js,jsx,ts,tsx,vue,svelte}` |
+| MCP-интеграция | `docs/MCP-SETUP.md` | Playwright (браузер) · GitHub · Postgres · Context7 |
+
+## Рекомендуемый стек
+
+| Компонент | Инструмент | Стоимость | Почему |
+|---|---|---|---|
+| IDE | [Google Antigravity](https://antigravity.google) | Бесплатно | Agent-first форк VS Code, встроенный browser-агент Gemini 3 Pro |
+| AI-агент | Claude Code (Max) | $100/мес | 1M контекст на Opus 4.7, полная экосистема субагентов и хуков |
+| Визуальные UI-тесты | Gemini 3 Pro (в Antigravity) | Бесплатно | Автономно навигирует браузер — Playwright не нужен для casual проверок |
+| Browser-автоматизация в коде | [Playwright MCP](docs/MCP-SETUP.md) | Бесплатно | Когда нужны воспроизводимые тесты |
+
+## Рекомендуемый workflow
+
+Полный playbook — [docs/WORKFLOW.md](docs/WORKFLOW.md). Короткая версия:
+
+1. **Сначала план** — `Use planner agent` → ревью плана в `./plans/` → утвердить
+2. **Маленькие диффы** — один файл → тесты → следующий файл
+3. **Следить за контекстом** — `/cost` периодически; `/compact` при 60–70%, даже на Opus 4.7
+4. **Checkpoint** — `git commit -m "checkpoint: before X"` перед рискованными изменениями
+5. **Ревью и тесты перед финальным коммитом** — `Use code-reviewer` затем `Use tester`
+6. **Откат если сломалось** — `Esc + Esc` → restore code only (чекпоинт Claude'а), либо `git reset --hard HEAD`
+
+## Заметки по конфигурации
+
+### О списке `permissions.allow` в `settings.json`
+
+В списке лежат `Bash(git commit*)`, `Bash(npm test*)` и т.д. **Это не ослабляет безопасность** — лишь убирает per-command подтверждение для рутинных команд. Реальный шлюз на `git commit` — это **хук**, который запускает `pytest` и отказывает при падении.
+
+> ⚠️ В дефолтном конфиге `Bash(pip install*)` лежит в `allow`. Если работаешь с непроверенными репо или хочешь ручное подтверждение перед каждой установкой зависимости — **убери `pip install*` из `allow`**, и Claude Code будет запрашивать разрешение каждый раз.
+
+### О команде в хуке
+
+По умолчанию: `python -m pytest tests/ -x --timeout=60`. Под другие стеки:
+
+```jsonc
+// JS / TS
+"command": "npm test --silent || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
+
+// Rust
+"command": "cargo test --quiet || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
+
+// Go
+"command": "go test ./... || (echo '{\"block\":true,\"message\":\"Tests failing.\"}' 1>&2 && exit 2)"
+```
+
+Если test-suite дольше 120 секунд — увеличь `timeout` в `settings.json`.
+
+## Ограничения и честные оговорки
+
+Это не серебряная пуля. Конкретные случаи, когда сетапа **недостаточно**:
+
+- **Compaction всё ещё теряет детали середины разговора.** `CLAUDE.md` и файлы на диске переживают; история чата между перечитываниями правил — нет. Важные промежуточные решения должны идти в `./plans/` или checkpoint-коммит, не в чат.
+- **Субагенты не делятся памятью.** `tester` не видит рассуждений `planner`'а, если тот не сохранил их в `./plans/`. Файл плана — это медиум коммуникации.
+- **Хуки зависят от шелла.** Команда по умолчанию использует bash-синтаксис (`||`, `1>&2`, `2>&1`). На нативном Windows PowerShell может потребоваться переписать команду или запускать Claude Code из WSL/Git Bash. Протестировано на macOS bash, Linux bash, Windows Git Bash.
+- **Медленные test-suite требуют тюнинга.** 10-минутный integration-suite таймаутнется на 120 с. Либо подними таймаут, либо раздели на быстрый unit-хук (шлюз) и отдельный шаг полного прогона через агента (вручную).
+- **Хуки шлюзуют `git commit`, не `git push`.** Целеустремлённая мисконфигурация всё ещё может запушить сломанный коммит. Для шлюза на push добавь второй `PreToolUse` matcher на `Bash(git push*)`.
+- **`/clear` перечитывает `CLAUDE.md`, но теряет контекст из `./plans/`.** Передай нужное имя файла плана в новую сессию.
+- **Правила — рекомендация, не enforcement.** Блок `globs:` говорит Claude *учитывать* правило; он не отказывается писать код, нарушающий его. Парь правила с реальным линтером (ruff, eslint) в CI.
+
+## Что нового
+
+Полная история — [CHANGELOG.md](CHANGELOG.md). Последняя: **0.2.0 (2026-04-30)** — обновлено под Opus 4.7 / 1M контекст, добавлена Mermaid-диаграмма, validate-CI, секция Limitations.
+
+## Контрибьют
+
+PR приветствуются. См. [CONTRIBUTING.md](CONTRIBUTING.md) — текущие приоритеты: правила для Go/Rust/TypeScript-бэкендов, framework-specific субагенты (Django, Rails, Next.js), дополнительные `PreToolUse` хуки (lint gate, secret scanning).
+
+## Ресурсы
+
+- [awesome-claude-code](https://github.com/hesreallyhim/awesome-claude-code) — Кураторская подборка skills, hooks, agents
+- [claude-code-workflows](https://github.com/shinpr/claude-code-workflows) — Production workflow-плагины
+- [Claude Code Docs: Best Practices](https://code.claude.com/docs/en/best-practices) — Официальные рекомендации
+- Сопровождающий материал: [статья на Хабре](https://habr.com/ru/articles/1013330/) · [статья на dev.to](https://dev.to/creatman/i-stopped-claude-code-from-breaking-my-projects-heres-the-exact-setup-1agi)
+
+## Автор
+
+**Николай Подоляк (Nick Podolyak)** — Python-разработчик и цифровой архитектор в [CREATMAN](https://creatman.site)
+
+- GitHub: [@CreatmanCEO](https://github.com/CreatmanCEO)
+- Habr: [creatman](https://habr.com/ru/users/creatman/)
+- dev.to: [@creatman](https://dev.to/creatman)
+
+## Лицензия
+
+[MIT](LICENSE) · Николай Подоляк
diff --git a/docs/RECORDING-DEMO.md b/docs/RECORDING-DEMO.md
new file mode 100644
index 0000000..aa5233b
--- /dev/null
+++ b/docs/RECORDING-DEMO.md
@@ -0,0 +1,68 @@
+# Recording the demo GIF
+
+The README's hero GIF is a placeholder (`docs/screenshots/hook-blocks-commit.gif` does not yet exist). Replace it with a real recording of the commit-blocking hook in action — that single demo carries the value proposition more than the rest of the README combined.
+
+## Bootstrap a clean demo project
+
+Run [`docs/setup-demo-project.sh`](setup-demo-project.sh) — it creates `/tmp/cc-demo/` with a 5-file Python project containing one passing test, one failing test, the configs from this repo, and a one-commit `git log`. Everything is ready for recording.
+
+```bash
+bash docs/setup-demo-project.sh
+cd /tmp/cc-demo
+```
+
+The script also prints the exact prompts to feed Claude during the recording.
+
+## What the recording must show
+
+A 6–12 second loop of:
+
+1. Claude Code running `git commit -m "..."` at the user's prompt
+2. The `[HOOK] Running tests before commit...` line appearing
+3. `pytest` failing on a deliberately broken test
+4. The hook printing `Tests are failing. Fix all test failures before committing.` and Claude refusing to proceed
+5. (Optional) Claude reading the failure, fixing the test, retrying — second commit succeeds
+
+## Recommended tool: asciinema → agg
+
+`asciinema` records the terminal as plain text with timing metadata (small file, perfect resolution, terminal-native). `agg` converts it to GIF.
+
+```bash
+# install
+brew install asciinema agg # macOS
+sudo apt install asciinema && cargo install --git https://github.com/asciinema/agg
+
+# record
+asciinema rec hook-demo.cast
+# ... do the demo in this terminal ...
+# Ctrl-D to stop
+
+# convert to GIF
+agg --theme monokai --rows 24 --cols 100 hook-demo.cast docs/screenshots/hook-blocks-commit.gif
+```
+
+## Alternative: OBS Studio + ffmpeg
+
+If you want a fancier demo with cursor highlights and zoom, record the screen with [OBS](https://obsproject.com/), then convert:
+
+```bash
+ffmpeg -i recording.mkv -vf "fps=12,scale=900:-1:flags=lanczos,palettegen" palette.png
+ffmpeg -i recording.mkv -i palette.png -filter_complex "fps=12,scale=900:-1:flags=lanczos[x];[x][1:v]paletteuse" docs/screenshots/hook-blocks-commit.gif
+```
+
+## Constraints
+
+- **Keep it under 1 MB.** GitHub renders larger GIFs poorly on slow connections.
+- **Loop seamlessly.** First and last frames should be visually identical (empty prompt).
+- **No personal paths in view.** Run the demo from `/tmp/demo-project` or similar.
+- **Use a fresh repo with two commits** so the `git log` shown is short and readable.
+
+## Replacing the file
+
+```bash
+cp /path/to/your.gif docs/screenshots/hook-blocks-commit.gif
+git add docs/screenshots/hook-blocks-commit.gif
+git commit -m "Add hook-blocks-commit demo GIF"
+```
+
+The README already references this exact path — no Markdown edits needed once the file exists.
diff --git a/docs/screenshots/hook-blocks-commit.svg b/docs/screenshots/hook-blocks-commit.svg
new file mode 100644
index 0000000..396e44c
--- /dev/null
+++ b/docs/screenshots/hook-blocks-commit.svg
@@ -0,0 +1,59 @@
+
+
diff --git a/docs/setup-demo-project.sh b/docs/setup-demo-project.sh
new file mode 100644
index 0000000..e89b2e7
--- /dev/null
+++ b/docs/setup-demo-project.sh
@@ -0,0 +1,119 @@
+#!/usr/bin/env bash
+#
+# Bootstraps a tiny demo project ready to record the hero GIF.
+# Run from the root of claude-code-antiregression-setup.
+#
+# Usage:
+# bash docs/setup-demo-project.sh
+# cd /tmp/cc-demo
+# asciinema rec hook-demo.cast
+# # ... record the demo (instructions below) ...
+#
+# Recording script (paste these prompts/commands one at a time):
+# 1. claude
+# 2. > Read CLAUDE.md and tell me what this project does in one sentence.
+# 3. > Now run: git add -A && git commit -m "feat: add divide function"
+# Claude will execute the git commit. The PreToolUse hook will run
+# pytest, see test_divide_by_zero fail, and BLOCK the commit.
+# 4. > Look at the failure, fix the divide function to handle zero,
+# and try the commit again.
+# 5. Claude fixes calculator.py, retries the commit, hook passes, commit succeeds.
+#
+# Total recording length: ~25 seconds. Trim to ~12 seconds in the GIF.
+
+set -euo pipefail
+
+DEMO_DIR="${DEMO_DIR:-/tmp/cc-demo}"
+REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+
+if [ -e "$DEMO_DIR" ]; then
+ echo "ERROR: $DEMO_DIR already exists. Remove it first or set DEMO_DIR=/some/other/path." >&2
+ exit 1
+fi
+
+mkdir -p "$DEMO_DIR"
+cd "$DEMO_DIR"
+
+# Copy the anti-regression configs in
+cp -r "$REPO_ROOT/.claude" .
+cp "$REPO_ROOT/CLAUDE.md.template" CLAUDE.md
+mkdir -p plans tests
+
+# Fill in CLAUDE.md with demo-project specifics
+cat > CLAUDE.md <<'CLAUDE_EOF'
+# Calculator Demo
+
+## Architecture
+- **Language**: Python 3.12
+- **Tests**: pytest
+
+## Key Commands
+- `python -m pytest tests/` — Run test suite
+
+## CRITICAL RULES — MUST FOLLOW
+- **NEVER** delete or rewrite working tests without explicit request
+- **ALWAYS** run tests after any code change
+- One task at a time. Complete and verify before moving to next
+CLAUDE_EOF
+
+# A working module
+cat > calculator.py <<'CALC_EOF'
+def add(a: float, b: float) -> float:
+ return a + b
+
+
+def divide(a: float, b: float) -> float:
+ return a / b
+CALC_EOF
+
+# A passing test and a deliberately failing test
+cat > tests/test_calculator.py <<'TEST_EOF'
+import pytest
+from calculator import add, divide
+
+
+def test_add():
+ assert add(2, 3) == 5
+
+
+def test_divide():
+ assert divide(10, 2) == 5
+
+
+def test_divide_by_zero():
+ """divide(x, 0) must raise ValueError, not ZeroDivisionError."""
+ with pytest.raises(ValueError, match="cannot divide by zero"):
+ divide(10, 0)
+TEST_EOF
+
+# Initial git state — important so `git log` is short during recording
+git init --quiet
+git add -A
+git commit --quiet -m "Initial calculator with one failing test"
+
+cat < Run: git add -A && git commit -m "stub: ship divide function"
+ # (hook blocks → claude fixes calculator.py → commits again → passes)
+ # press Ctrl-D to stop recording
+
+Convert to GIF:
+ agg --theme monokai --rows 24 --cols 100 hook-demo.cast \\
+ $REPO_ROOT/docs/screenshots/hook-blocks-commit.gif
+
+Then commit the GIF:
+ cd $REPO_ROOT
+ git add docs/screenshots/hook-blocks-commit.gif
+ git commit -m "Add hero GIF: hook blocking a failing commit"
+ git push
+
+Tip: keep the GIF under 1 MB. If too large:
+ agg --rows 22 --cols 90 --speed 1.4 hook-demo.cast ...
+MSG