Thanks for your interest. This document covers dev setup, the quality gate every commit must pass, and what we expect from changes. Architecture context lives in docs/ARCHITECTURE.md; full environment setup in docs/SETUP.md.
- Prerequisites: Python 3.12, PostgreSQL 16 with
pgvector+pg_trgm, Node 20+ (frontend). Or skip all of this withdocker compose upfrom the repo root — see the README's "Running it" section. - Backend:
cd src/backend python -m venv .venv && source .venv/bin/activate # .venv\Scripts\activate on Windows pip install -e ".[dev]" cp ../../.env.example .env # then edit DATABASE_URL / DATA_ROOT alembic upgrade head python -m scripts.doctor # preflight check python -m scripts.restore_seed # loads the committed seed dataset
- Data:
restore_seed.pyloads the committed seed dataset (40 tables, 240k rows) in seconds. For the full, real dataset from public sources instead, see docs/INGESTION_RUNBOOK.md. - Frontend:
cd src/frontend && npm install && npm run dev.
Install the hooks once — they run black + ruff + mypy --strict on every commit:
pip install pre-commit && pre-commit install
pre-commit run --all-files # must be green before you pushRules that will bite you if you skip reading them:
- black is the sole formatter and owns line length (100). ruff lints only.
- Complexity cap: ruff C90 enforces
max-complexity=10onapp/business logic. If a function hits the limit, decompose it — do not raise the threshold or add# noqa: C901without a justifying comment.scripts/andmigrations/are exempt by policy. - mypy
--strictruns in the pre-commit hook's isolated env, which is not your venv — verify against the hook, not just your localmypy.
cd src/backend
pytest # full suite
pytest tests/test_data_invariants.py -v # data contracts (must always pass)
pytest tests/test_performance.py -m slow # P95 latency thresholds (ADR-007)- Data invariants are tests, not comments (
tests/test_data_invariants.py). If your change touches ingestion or derived tables, run them. - The hard data-model rules (E0/E1/E2 semantics, the Beta = E1 + 0.5×E2
coefficient, tier separation, N≥5 privacy suppression, …) are documented in
docs/domain-model.md and
CLAUDE.md. They are contracts — changes that "optimise around" them will be declined. - Performance changes need measurements: run
pytest -m slowand checkGET /api/v1/admin/slow-queriesbefore and after. Don't guess.
Docs drift from code silently. Two layers guard against it:
-
check_docs.py(pre-commit + CI) — structural: broken internal links and orphaned docs. -
scripts/check_content_drift.py(the Content drift CI job) — content: asserts machine-checkable claims inREADME.md/CLAUDE.mdstill match the code (the canonical row total, frontend routes, endpoint/test/table counts). Structural drift (a route moved, the two docs citing different row totals) fails CI — fix the doc in the same PR as the code change. Volatile-count mismatches (a new endpoint or test) are warnings, not failures. Run it locally:cd src/backend && python -m scripts.check_content_drift # exit 1 on drift cd src/backend && python -m scripts.check_content_drift --report # list everything
-
Weekly doc-drift review (P6) — a scheduled, review-only routine runs the content checker plus an LLM pass over the week's commits vs the docs, and opens a GitHub issue flagging likely-stale prose. It never edits docs; a human accepts or dismisses each item.
If you add an endpoint, page/route, model, or data source, update the relevant
README.md / CLAUDE.md claims in the same PR — the content-drift job will tell
you which ones.
Code is MIT (LICENSE); the data compilation is CC-BY-4.0
(DATA_LICENSE) with per-source attribution in NOTICE.
Every source is registered in signal_source_registry with a
redistribution_ok flag, and scripts/check_redistribution.py gates what may
ship. A new data source must be registered there with its licence verified —
citation-only sources can inform analysis but never enter a published output.
See docs/data-sources.md.
feat(FR-X): ... fix(FR-X): ... test(FR-X): ...
refactor: ... docs: ... chore: ...
Small, focused PRs against master. Include tests for behaviour changes, and
update the docs listed in CLAUDE.md §Key Reference Docs when your change makes
them stale.