docs: add a developer onboarding guide for the monorepo #98

Merged
admin_emi merged 3 commits from docs/onboarding into dev 2026-07-25 18:34:47 +00:00
Owner

Twelve documents under docs/onboarding/, plus a pointer from the root README.

What's here

Doc Covers
README.md index, reading order, first-day / first-week path
01-orientation the product's actual claim, the domain model in six steps, the estate, the non-negotiable rules, quota discipline
02-setup toolchain, verified run/test recipes for backend, frontend, daemon and the full stack; connectors; the repo's .claude hooks
03-repo-map every domain and directory, and the nine workflows
04-backend roles, the two source ladders, the three storage tiers and their different contracts, the validity token, grading, the HTTP surface, leader election, the Go daemon, the lake
05-frontend the Go service, the content client's four load-bearing properties, static assets, the design system, the image
06-contracts the nine seams that break silently across the FE/BE split, with a pre-PR checklist
07-ci-and-release branch model, who may merge what, all nine workflows and why each is shaped as it is
08-infra-secrets the machines, compose vs Swarm, deploy.sh step by step, the SOPS vault and its two design decisions, ops tooling, backups
09-observability the stack, the prod label trap, the twelve alert rules, deploying an observability change, the known gaps
10-recipes task-shaped walkthroughs: payload fields, SSR pages, visual changes, secrets, background jobs, alerts, two debugging paths, promotion, rollback
11-traps live traps and, separately, which docs in this tree currently describe a system that no longer exists

Verification

Every command in 02-setup was run against this checkout:

  • backend/make test429 passed, 8 skipped in 11.57s
  • frontend/server: go vet ./... clean, go test ./... → all 7 packages ok
  • backend booted from a venv: /healthz{"status":"ok","role":"all"}, /thermograph/api/version{"backend_version":"2","min_frontend":"1","payload_ver":"p2"}
  • Go frontend built and booted: /healthz{"status":"ok"}

All relative links in the doc set resolve; the workflow count and the 14-code Fahrenheit set were checked programmatically.

Two findings recorded along the way

static/units.js's F_REGIONS is guarded by no test. Comments in backend/api/content_payloads.py, frontend/format.py and frontend/server/internal/format/format.go all claim "a test asserts all three stay identical". The only assertion is format_test.go::TestFCountriesMatchesBackend, which re-parses the backend's Python and compares the Go copy — nothing reads units.js. All four copies are currently identical (verified, 14 codes). Extending that Go test to parse units.js would close it.

The test-compose files still point at retired image paths. backend/docker-compose.test.yml and frontend/docker-compose.test.yml default BACKEND_IMAGE_PATH to emi/thermograph-backend/app, and the frontend harness pins THERMOGRAPH_BACKEND_TEST_TAG to the split-era v0.0.2-split-ci. make smoke is unaffected (it builds :local); make backend-up does pull, so it depends on those packages not having been GC'd yet.

Neither is fixed here — this PR is documentation only, and both are noted in 11-traps with workarounds.

Scope note

This covers working in this repo. Cross-cutting ADRs and operator runbooks stay in thermograph-docs; the set links out rather than duplicating. Where a fact is owned by a CLAUDE.md, that file stays the source of truth.

https://claude.ai/code/session_01AfXqHrxCJLs2D7hpQkiUiJ

Twelve documents under `docs/onboarding/`, plus a pointer from the root README. ## What's here | Doc | Covers | |---|---| | `README.md` | index, reading order, first-day / first-week path | | `01-orientation` | the product's actual claim, the domain model in six steps, the estate, the non-negotiable rules, quota discipline | | `02-setup` | toolchain, **verified** run/test recipes for backend, frontend, daemon and the full stack; connectors; the repo's `.claude` hooks | | `03-repo-map` | every domain and directory, and the nine workflows | | `04-backend` | roles, the two source ladders, the three storage tiers and their different contracts, the validity token, grading, the HTTP surface, leader election, the Go daemon, the lake | | `05-frontend` | the Go service, the content client's four load-bearing properties, static assets, the design system, the image | | `06-contracts` | the nine seams that break silently across the FE/BE split, with a pre-PR checklist | | `07-ci-and-release` | branch model, who may merge what, all nine workflows and why each is shaped as it is | | `08-infra-secrets` | the machines, compose vs Swarm, `deploy.sh` step by step, the SOPS vault and its two design decisions, ops tooling, backups | | `09-observability` | the stack, the prod label trap, the twelve alert rules, deploying an observability change, the known gaps | | `10-recipes` | task-shaped walkthroughs: payload fields, SSR pages, visual changes, secrets, background jobs, alerts, two debugging paths, promotion, rollback | | `11-traps` | live traps and, separately, which docs in this tree currently describe a system that no longer exists | ## Verification Every command in `02-setup` was run against this checkout: - `backend/make test` → **429 passed, 8 skipped in 11.57s** - `frontend/server`: `go vet ./...` clean, `go test ./...` → all 7 packages ok - backend booted from a venv: `/healthz` → `{"status":"ok","role":"all"}`, `/thermograph/api/version` → `{"backend_version":"2","min_frontend":"1","payload_ver":"p2"}` - Go frontend built and booted: `/healthz` → `{"status":"ok"}` All relative links in the doc set resolve; the workflow count and the 14-code Fahrenheit set were checked programmatically. ## Two findings recorded along the way **`static/units.js`'s `F_REGIONS` is guarded by no test.** Comments in `backend/api/content_payloads.py`, `frontend/format.py` and `frontend/server/internal/format/format.go` all claim "a test asserts all three stay identical". The only assertion is `format_test.go::TestFCountriesMatchesBackend`, which re-parses the backend's Python and compares the **Go** copy — nothing reads `units.js`. All four copies are currently identical (verified, 14 codes). Extending that Go test to parse `units.js` would close it. **The test-compose files still point at retired image paths.** `backend/docker-compose.test.yml` and `frontend/docker-compose.test.yml` default `BACKEND_IMAGE_PATH` to `emi/thermograph-backend/app`, and the frontend harness pins `THERMOGRAPH_BACKEND_TEST_TAG` to the split-era `v0.0.2-split-ci`. `make smoke` is unaffected (it builds `:local`); `make backend-up` does pull, so it depends on those packages not having been GC'd yet. Neither is fixed here — this PR is documentation only, and both are noted in `11-traps` with workarounds. ## Scope note This covers *working in this repo*. Cross-cutting ADRs and operator runbooks stay in `thermograph-docs`; the set links out rather than duplicating. Where a fact is owned by a `CLAUDE.md`, that file stays the source of truth. https://claude.ai/code/session_01AfXqHrxCJLs2D7hpQkiUiJ
admin_emi added 2 commits 2026-07-25 18:26:37 +00:00
Merge pull request 'promote: dev → main (CI consolidation, 15 workflows → 9)' (#90) from dev into main
All checks were successful
shell-lint / shellcheck (pull_request) Successful in 9s
Build + push images (Forgejo registry) / build-push (frontend) (push) Successful in 6s
Deploy / deploy (frontend) (push) Successful in 12s
Sync infra to hosts / sync-beta (push) Successful in 12s
Sync infra to hosts / sync-prod (push) Successful in 9s
secrets-guard / encrypted (push) Successful in 13s
Deploy / deploy (backend) (push) Successful in 50s
shell-lint / shellcheck (push) Successful in 14s
Build + push images (Forgejo registry) / build-push (backend) (push) Successful in 46s
secrets-guard / encrypted (pull_request) Successful in 7s
aa4ee7f4c4
docs: add a developer onboarding guide for the monorepo
All checks were successful
PR build (required check) / changes (pull_request) Successful in 7s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / validate-observability (pull_request) Successful in 19s
shell-lint / shellcheck (pull_request) Successful in 6s
PR build (required check) / build-backend (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 2s
9c755e72f6
Twelve documents under docs/onboarding/ covering orientation, local setup,
the repo map, per-domain deep dives, the cross-service contracts, CI and the
release flow, infra and secrets, observability, task recipes, and a list of
which docs in this tree are currently stale.

Every command in the setup guide was run against this checkout: the backend
suite (429 passed, 8 skipped), the frontend Go suite, a venv boot of the
backend, and a build+boot of the Go frontend.

Two findings recorded along the way:

- static/units.js's F_REGIONS is guarded by no test, despite three source
  comments claiming "a test asserts all three stay identical". The Go test
  only cross-checks the Go copy against the backend's Python. All four copies
  are currently identical.
- backend/ and frontend/docker-compose.test.yml still default to the retired
  emi/thermograph-backend/app image path, and the frontend harness pins the
  split-era v0.0.2-split-ci tag.

Claude-Session: https://claude.ai/code/session_01AfXqHrxCJLs2D7hpQkiUiJ
admin_emi added 1 commit 2026-07-25 18:34:25 +00:00
Merge branch 'dev' into docs/onboarding
All checks were successful
secrets-guard / encrypted (pull_request) Successful in 8s
PR build (required check) / changes (pull_request) Successful in 9s
shell-lint / shellcheck (pull_request) Successful in 6s
PR build (required check) / build-backend (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 2s
edf00cf9e2
admin_emi merged commit 12441be0c1 into dev 2026-07-25 18:34:47 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Jinemi/thermograph#98
No description provided.