# Coding Standards

## Python

### Type System
- All functions have type annotations — parameters and return types
- `mypy --strict` must pass
- No `Any` types — use `Protocol`, `TypeVar`, generics
- Pydantic v2 models for all data structures crossing module boundaries

### File Organization
- 300-line file limit — split proactively
- One public class or related group of functions per file
- Imports sorted by Ruff (isort rules)
- No circular imports — if needed, restructure

### Naming
- `snake_case` for functions, variables, modules
- `PascalCase` for classes
- `UPPER_CASE` for constants
- Private functions prefixed with `_`

### Paths
- `pathlib.Path` everywhere — never `os.path`
- Resolve paths early, pass `Path` objects to functions

### Logging
- `structlog` for library code — never `print()`
- `print()` allowed ONLY in `cli.py` (via Rich)

### Error Handling
- Raise specific exceptions with clear messages
- Never catch and ignore (`except: pass`)
- Let unexpected errors propagate — don't over-catch

### Testing
- `pytest` with `tmp_path` for filesystem tests
- Mock external calls (subprocess, network)
- Meaningful assertions — test values, not just existence
- Tests ship in the same wave as the code they test
- Coverage >= 80%

## Jinja2 Templates

### Conventions
- `.j2` extension
- Context variables documented in a comment block at the top
- No complex logic — Python computes the context, templates render
- Use Jinja2 whitespace control (`{%- -%}`) for clean output
- Test every template renders without errors

### Generated File Quality
- Generated YAML must be valid (parseable)
- Generated JSON must be valid (parseable)
- Generated Markdown must be well-formed
- Generated Python must pass basic syntax checks

## CLI

### Commands
- Typer for command definitions
- Rich for output formatting
- CLI is thin — no business logic
- Exit codes: 0 = success, 1 = user error, 2 = system error
