- Create a branch from master.
- Implement focused changes by layer (API -> deps -> service -> repo).
- Add or update tests in the same change.
- Run lint/format/tests before opening PR.
- feature/
- fix/
- chore/
Use concise imperative messages. Examples:
- feat: mount versioned v2 docs app
- fix: whitelist docs CSP in security headers
- docs: align architecture with mounted versioning
uv run ruff check --fix app
uv run ruff format app
uv run mypy app --config-file=pyproject.toml
uv run tach check
uv run bandit -c pyproject.toml -r app
uv run pytestOr run everything at once (matches the CI lint job exactly):
uv run pre-commit run --all-files.secrets.baseline records every secret-shaped string the detect-secrets pre-commit hook (and CI) has already seen and reviewed — anything it finds that isn't in there fails the check.
Pull new or changed findings into the baseline for review:
uv run detect-secrets scan --baseline .secrets.baselineThen step through the unaudited findings interactively, marking each one y (real secret) or n (false positive):
uv run detect-secrets audit .secrets.baselineCommit .secrets.baseline afterward — it only protects anyone else once it's pushed.
Note: for a one-off false positive you can instead add an inline # pragma: allowlist secret comment on that line, and for a whole machine-generated file (whose "secret" is really just something like an embedded commit hash that changes every time it's regenerated) prefer extending the exclude regex on the detect-secrets hook in .pre-commit-config.yaml instead of re-auditing a moving target on every regeneration.
- Endpoints stay thin.
- Deps assemble services and own session boundaries.
- Services hold business rules and raise domain exceptions.
- Repositories perform data access only.
- /v1/docs and /v2/docs are the canonical interactive docs endpoints.
- Root /docs is intentionally disabled.