thermograph/CLAUDE.md
emi e84b1f7937
Some checks failed
shell-lint / shellcheck (push) Has been cancelled
secrets-guard / encrypted (push) Has been cancelled
Validate observability stack / validate (push) Successful in 33s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 3m5s
Deploy frontend to LAN dev server / build (push) Successful in 3m21s
Build + push frontend image (Forgejo registry) / build-push (push) Successful in 3m27s
Deploy backend to LAN dev server / build (push) Successful in 4m16s
Deploy frontend to LAN dev server / deploy (push) Successful in 31s
Deploy backend to LAN dev server / deploy (push) Successful in 1m19s
docs: rewrite the agent context layer to match the live system (#81)
2026-07-25 07:08:54 +00:00

3.8 KiB

thermograph monorepo — agent instructions

One repo, four domains: backend/, frontend/, infra/, observability/. Reunified 2026-07-22 from four split repos, with history, via subtree merges. thermograph-docs is deliberately a separate repo — cross-cutting decision records and operator runbooks go there, not here.

Rule for this file and every domain CLAUDE.md: only statements that would break CI if they became false, or that name a file that exists. Background, history and rationale belong in thermograph-docs. These files are read before every change, so a stale one is a correctness bug, not a documentation bug.

Branches and environments

Branch Deploys to Workflow
feature branch nothing PR into dev
dev LAN dev *-deploy-dev.ymlcurrently inert, see below
main beta (beta.thermograph.org) *-deploy.yml
release prod (thermograph.org) *-deploy-prod.yml

dev, main and release are protected: everything is a PR, for humans and agents alike. Promotion is one PR per hop, devmainrelease.

The two *-deploy-dev.yml workflows are inert — the LAN box's ~/thermograph-dev is still a split-era thermograph-infra checkout, so the monorepo path they call does not exist there. Use infra/'s make dev-up locally instead.

The deploy contract

One entry point, two modes, one contract:

SERVICE=backend|frontend|all  BACKEND_IMAGE_TAG=sha-<12hex>  FRONTEND_IMAGE_TAG=sha-<12hex> \
  /opt/thermograph/infra/deploy/deploy.sh

deploy.sh resets the host checkout, renders secrets from the SOPS vault, then either rolls compose services or — if /etc/thermograph/deploy-mode contains stack — execs infra/deploy/stack/deploy-stack.sh.

  • prod runs Swarm. Its stack is infra/deploy/stack/thermograph-stack.yml (db, web, worker, lake, daemon, frontend, autoscaler, autoscaler-lake). deploy-stack.sh also offers STACK_TEST=1: a full parallel rehearsal on throwaway volumes and ports that cannot touch live data.
  • beta and LAN dev run compose, from infra/docker-compose.yml (db, backend, lake, daemon, frontend).
  • Each service's live tag is persisted host-side, so a single-service roll never disturbs the sibling's running tag.

Images are emi/thermograph/backend and emi/thermograph/frontend, tagged sha-<12hex> on every push and by semver on v*.*.* tags. They build and deploy independently — a backend change ships without a frontend deploy and vice versa. That independence is the point of the FE/BE split and survived reunification.

Rules that bind across domains

  • CI lives only in root .forgejo/workflows/, path-filtered per domain. Never add workflows under a domain's own .forgejo/ — they are inert there and become a trap.
  • Secrets only via the SOPS vault (infra/deploy/secrets/). Never hand-edit /etc/thermograph.env on a host — it is a rendered artifact. secrets-guard CI rejects plaintext. seed-from-live.sh reads production secrets and is explicitly not for an agent to run.
  • FE and BE ship out of lockstep, so the /api/version contract and PAYLOAD_VER discipline are load-bearing — see backend/CLAUDE.md.
  • Anything named "prefetch" must never spend the Open-Meteo quota. Nominatim ≤ 1 req/s.
  • The compose project name is pinned (name: thermograph in infra/docker-compose.yml); LAN dev overrides with COMPOSE_PROJECT_NAME=thermograph-dev. Don't remove either half — the pinned name is what makes the Swarm stack's external volume names line up.
  • CUTOVER-NOTES.md is the source of truth for what is and isn't live yet.

Commits & PRs

Describe only the substance of the change; concise and technical. Never mention AI, Claude, assistants or automated authorship anywhere — no trailers, co-authors, emoji, or "as requested" narration.