# Onboarding — becoming a full contributor to Thermograph This is the developer onboarding path for the `emi/thermograph` monorepo: what the product is, how the code is shaped, how to run it, what will break silently if you get it wrong, and how a change actually travels from your editor to `thermograph.org`. **Scope.** This covers *working in this repo*. Cross-cutting architecture decision records and operator runbooks live in the separate `thermograph-docs` repo (reachable through Centralis's `docs_search`) — this set links out rather than duplicating them. Where a fact is owned by a `CLAUDE.md`, that file stays the source of truth and this set explains the context around it. ## Reading order | # | Doc | Read it when | |---|-----|--------------| | 1 | [Orientation](01-orientation.md) | First. What the product actually claims, the estate, the four non-negotiable rules. | | 2 | [Local setup](02-setup.md) | Before you touch anything. Toolchain, verified run/test recipes for every service. | | 3 | [Repo map](03-repo-map.md) | To find things. Every domain and directory, and which files matter. | | 4 | [Backend deep dive](04-backend.md) | Before your first backend change. Data pipeline, grading, caching, roles, daemon. | | 5 | [Frontend deep dive](05-frontend.md) | Before your first frontend change. The Go SSR service, static assets, design system. | | 6 | [Cross-service contracts](06-contracts.md) | **Before any change that touches both.** These break silently and in production. | | 7 | [CI and release](07-ci-and-release.md) | Before you open a PR. Nine workflows, three branches, three environments. | | 8 | [Infra and secrets](08-infra-secrets.md) | Before you touch deploy, compose, or a secret. | | 9 | [Observability](09-observability.md) | When something is wrong and you need to see it. | | 10 | [Recipes](10-recipes.md) | Task-shaped walkthroughs for the things you'll actually do. | | 11 | [Traps and stale docs](11-traps.md) | **Skim early, re-read often.** Which docs in this repo currently lie, and why. | ## The short version Thermograph grades how unusual today's weather is at any point on Earth against ~45 years of that exact location's own history. Percentiles, never thermometer readings. - **`backend/`** — Python 3.12 / FastAPI. Owns all climate data, grading, the API, accounts, notifications, plus a Go daemon (`backend/daemon/`) that owns the Discord gateway and recurring timers. Ships as `emi/thermograph/backend`. - **`frontend/`** — **Go** SSR service (`frontend/server/`) plus every static asset. No climate data, no database, no compute. Ships as `emi/thermograph/frontend`. (The Python implementation at `frontend/*.py` is the superseded original — see [traps](11-traps.md).) - **`infra/`** — compose and Swarm files, deploy scripts, the SOPS secrets vault, Terraform, ops query tooling. - **`observability/`** — Loki + Grafana on vps1, an Alloy agent per node. Branches stage environments: PR → `dev` (vps1, mesh-only) → `main` (beta, vps2) → `release` (prod, vps2). The two app domains build and deploy **independently** — that independence is the whole reason the split-then-reunify history exists, and [contracts](06-contracts.md) is the list of things that keep it safe. ## Your first day 1. Read [Orientation](01-orientation.md) and [Traps](11-traps.md). 2. Work through [Local setup](02-setup.md) until `make test` is green in both `backend/` and `frontend/server/`. 3. Read [Repo map](03-repo-map.md) with the tree open beside it. 4. Pick something small in the domain you're least afraid of, and follow [Recipes](10-recipes.md) end to end — including opening the PR. ## Your first week - Read [Contracts](06-contracts.md) properly. Every item on that list has already cost someone a production incident somewhere in this project's history; that's why each one is written down. - Get Centralis wired up (see [Local setup](02-setup.md)) and ask it `fleet_status`, `logs_overview`, `deployed_version`. You cannot debug this estate blind, and the boxes are not reachable from a laptop off the WireGuard mesh. - Read the `CLAUDE.md` for each domain. They are terse, current, and binding.