Date: 2025-12-22
| Metric | Value |
|---|---|
| CLAUDE.md files | 2 (root + analytics) |
| .claude/rules/ | Not used |
| Custom commands | 1 (manual-test-plan) |
| Subagents | 2 (feature-planner, diataxis-docs-expert) |
| @imports | 0 |
| Critical issues | 0 |
| Quick wins | 5 |
| High-value improvements | 4 |
- Comprehensive root CLAUDE.md - Covers commands, architecture, patterns, file locations
- Good subagents - feature-planner and diataxis-docs-expert are well-defined
- Subdirectory memory - analytics/ has its own CLAUDE.md
- Custom command - manual-test-plan is a good example of workflow automation
- Specific instructions - Many instructions are actionable (e.g., exact command syntax)
- No modular rules - Everything in one file, no
.claude/rules/ - No @imports - Not leveraging existing docs (rich docs/ directory unused)
- Handlers not documented -
gyrinx/core/handlers/is a key pattern not mentioned - Some models undocumented - facts.py, battle.py, action.py not mentioned
- No hooks configured -
.claude/settings.jsonhas empty hooks
Category: Quick Win Effort: 5 minutes
The CLAUDE.md duplicates content that exists in docs/. Use @imports instead:
## Additional Documentation
See @docs/developing-gyrinx/testing.md for detailed testing patterns.
See @docs/developing-gyrinx/models-and-database.md for model conventions.
See @docs/fighter-cost-system-reference.md for cost system details.Category: Quick Win Effort: 10 minutes
Add to CLAUDE.md under Common File Locations:
**Handlers:**
- `gyrinx/core/handlers/` - Business logic handlers
- `equipment/` - Equipment-related operations
- `fighter/` - Fighter-related operations
- `list/` - List-related operations
- `campaign_operations.py` - Campaign operations
- `refund.py` - Refund logicCategory: Quick Win Effort: 5 minutes
Add to Key Models Reference:
**Core App (Additional):**
- `Battle` - Campaign battle records
- `Action` - Fighter actions in battles
- `Fact` - Computed facts about fighters/equipmentCategory: Quick Win Effort: 2 minutes
The manage command isn't in PATH without activating the venv. Add note:
**Django:** Use `manage` command (requires activated venv or use `.venv/bin/python scripts/manage.py`)Category: Quick Win Effort: 5 minutes
Create .claude/commands/commit.md:
---
description: Create a well-formatted git commit
---
Create a git commit for the current changes:
1. Run `git status` to see changes
2. Run `git diff --cached` to see staged changes (or `git diff` for unstaged)
3. Analyze the changes and create a descriptive commit message
4. Use conventional commit format if appropriate
5. Include the standard footer:
π€ Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>Category: High Value Effort: 30 minutes
Split CLAUDE.md into focused rule files:
.claude/rules/
βββ testing.md # Testing patterns and pytest usage
βββ templates.md # Template patterns and Bootstrap usage
βββ security.md # Security rules (safe_redirect, etc.)
βββ models.md # Model conventions and AppBase usage
βββ ui-patterns.md # Button classes, layout patterns
Example .claude/rules/testing.md:
---
paths: "**/tests/**/*.py"
---
# Testing Rules
- Use pytest with `@pytest.mark.django_db` decorator
- Test functions at module level, not in classes
- Do not use Django's TestCase or SimpleTestCase
- Use Django test client for view testing
- Run with `pytest -n auto` for parallel executionExample .claude/rules/templates.md:
---
paths: "**/templates/**/*.html"
---
# Template Rules
- Use `{% extends "core/layouts/base.html" %}` for full-page layouts
- Use `{% extends "core/layouts/page.html" %}` for simple content pages
- Back buttons: `{% include "core/includes/back.html" with url=target_url text="Back Text" %}`
- Mobile-first: typically `col-12 col-xl-6`
- Button classes: `btn btn-primary btn-sm`, `btn btn-secondary btn-sm`Category: High Value Effort: 20 minutes
Create commands for common workflows:
.claude/commands/test-fix.md:
---
description: Run tests and fix any failures
---
Run the test suite and fix any failing tests:
1. Run `pytest -n auto -x` to find the first failure
2. Analyze the failure
3. Fix the issue
4. Re-run the failing test to confirm
5. Repeat until all tests pass
6. Run `./scripts/fmt.sh` to format.claude/commands/pr.md:
---
description: Create a pull request for current branch
argument-hint: [pr-title]
---
Create a pull request:
1. Run `./scripts/fmt.sh`
2. Run `pytest -n auto`
3. If tests pass, push the branch
4. Create PR with `gh pr create`
5. Use the provided title or derive from branch name: $1.claude/commands/migration.md:
---
description: Create and check a migration
argument-hint: <app> <name>
---
Create a Django migration:
1. Run `manage makemigrations $1 -n "$2"`
2. Run `./scripts/check_migrations.sh`
3. Review the generated migration file
4. If issues found, suggest fixesCategory: High Value Effort: 15 minutes
Create gyrinx/core/handlers/CLAUDE.md:
# Handlers - CLAUDE.md
Handlers contain business logic separated from views and models.
## Structure
- `equipment/` - Equipment assignment, removal, cost calculations
- `fighter/` - Fighter creation, updates, stat modifications
- `list/` - List operations, copying, archiving
- `campaign_operations.py` - Campaign-specific operations
- `refund.py` - Credit refund logic for campaign mode
## Patterns
- Handlers are pure functions or classes
- They receive model instances and return results
- They don't access request or session directly
- They're designed to be testable in isolation
## When to Use
- Complex business logic that doesn't belong in models
- Operations that span multiple models
- Logic that needs to be reused across viewsCategory: High Value Effort: 15 minutes
Replace duplicated sections with @imports:
## Additional Reference
- Detailed testing guide: @docs/developing-gyrinx/testing.md
- Model conventions: @docs/developing-gyrinx/models-and-database.md
- Frontend patterns: @docs/developing-gyrinx/frontend-development.md
- Cost system: @docs/fighter-cost-system-reference.md
- Security baseline: @docs/security-baseline.md---
description: Review code changes before committing
---
Review the current changes:
1. Run `git diff` to see all changes
2. Check for:
- Security issues (unvalidated redirects, raw SQL, etc.)
- Missing tests for new functionality
- Code style issues
- Missing error handling
3. Suggest improvements
4. Run `bandit -c pyproject.toml -r .` for security scan---
paths: "**/*.py"
---
# Security Rules
- Always validate redirect URLs with `safe_redirect()`
- Never use raw SQL - use Django ORM
- Sanitize user input in templates with `|escape` or `|safe` only when content is trusted
- Check `bandit` output before committing
- Never commit secrets or .env filesCurrently .claude/settings.json has empty hooks. Consider:
{
"hooks": {
"PreToolUse": [
{
"event": "Bash",
"command": "if echo \"$TOOL_INPUT\" | grep -q 'git push.*--force'; then echo 'BLOCK: Force push requires explicit confirmation'; exit 1; fi"
}
]
}
}- Don't over-modularize - The current CLAUDE.md size (~320 lines) is manageable
- Don't add too many subagents - The 2 existing ones are sufficient for now
- Don't duplicate docs content - Use @imports instead
| Priority | Item | Effort |
|---|---|---|
| 1 | Document handlers pattern | 10 min |
| 2 | Add missing models | 5 min |
| 3 | Add /commit command | 5 min |
| 4 | Add @imports to reduce duplication | 15 min |
| 5 | Create .claude/rules/testing.md | 10 min |
| 6 | Create .claude/rules/templates.md | 10 min |
| 7 | Add /pr and /test-fix commands | 15 min |
| 8 | Create handlers/CLAUDE.md | 15 min |
Total estimated effort: ~85 minutes for all improvements
.claude/commands/commit.md.claude/commands/pr.md.claude/commands/test-fix.md.claude/commands/migration.md.claude/rules/testing.md.claude/rules/templates.mdgyrinx/core/handlers/CLAUDE.md
CLAUDE.md- Add handlers to file locations, add missing models, add @imports