370a4ffdc1
ERA5 lake: bucket-hosted history primary + SQL indexer service ( #15 )
secrets-guard / encrypted (push) Successful in 10s
Deploy backend to LAN dev server / build (push) Successful in 1m13s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 1m39s
Deploy backend to LAN dev server / deploy (push) Successful in 34s
2026-07-23 21:20:35 +00:00
Emi Griffith
6086b40fe6
Add off-box encrypted backups to Contabo Object Storage
...
secrets-guard / encrypted (pull_request) Successful in 7s
PR build (required check) / changes (pull_request) Successful in 8s
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 3s
Prod DB dumps and Forgejo (db + data volume) are now copied off-box to the
era5-thermograph S3 bucket, age-encrypted to the vault recipient so the host
age key at /etc/thermograph/age.key decrypts them for restore. Nothing plaintext
leaves the box; no local intermediate (streamed via age | rclone rcat).
ops-cron: the prod pg_dump job gains an off-box push; a new forgejo-backup job
dumps Forgejo's Postgres + tars its data volume on beta (the git host had NO
backup at all). 30-day off-box retention on both. S3 creds are Forgejo Actions
secrets (S3_ENDPOINT/BUCKET/ACCESS_KEY/SECRET_KEY), mirrored into the SOPS vault
(prod.yaml/beta.yaml) for host-side use. Contabo needs path-style addressing.
Adds deploy/backup/README.md with the DR restore runbook.
2026-07-23 13:42:09 -07:00
ebf5efadfb
Merge pull request 'Reconcile: merge main back into dev' ( #13 ) from main into dev
secrets-guard / encrypted (push) Successful in 7s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 58s
Deploy backend to LAN dev server / build (push) Successful in 1m7s
Deploy backend to LAN dev server / deploy (push) Successful in 17s
2026-07-23 16:22:20 +00:00
0b574c88ed
Merge pull request 'Promote dev -> main (deploy beta): Open-Meteo migration (Phases 0-4)' ( #9 ) from dev into main
secrets-guard / encrypted (push) Successful in 10s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 1m3s
Deploy backend to beta VPS / deploy (push) Successful in 2m7s
secrets-guard / encrypted (pull_request) Successful in 6s
PR build (required check) / changes (pull_request) Successful in 9s
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) / build-backend (pull_request) Successful in 45s
PR build (required check) / gate (pull_request) Successful in 1s
2026-07-23 14:58:42 +00:00
790b6bf0dc
Migrate off the Open-Meteo weather API (Phases 0-4)
...
secrets-guard / encrypted (push) Successful in 8s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 1m4s
Deploy backend to LAN dev server / build (push) Successful in 1m12s
Deploy backend to LAN dev server / deploy (push) Successful in 17s
PR build (required check) / changes (pull_request) Successful in 7s
secrets-guard / encrypted (pull_request) Successful in 6s
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) / build-backend (pull_request) Successful in 54s
PR build (required check) / gate (pull_request) Successful in 3s
Steady-state usage of the Open-Meteo API is removed; it remains only as a dormant fallback. Geocoding -> local GeoNames + Nominatim; wind gusts -> Meteostat; history -> NASA POWER (curated cells seeded with keyless ERA5); recent+forecast -> NASA range + MET Norway. Plus a drift-check tool comparing NASA vs Open-Meteo. All keyless, no new infra. Backend suite green in-image (gate).
2026-07-23 14:34:51 +00:00
6ac59a55ff
Merge pull request 'Promote dev to main (tag-keying remainder)' ( #7 ) from dev into main
secrets-guard / encrypted (push) Successful in 5s
secrets-guard / encrypted (pull_request) Successful in 6s
2026-07-23 14:00:26 +00:00
af839c6cd0
Finish the domain-sha tag keying: three deploy workflows were missed ( #6 )
secrets-guard / encrypted (push) Successful in 6s
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
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) / build-backend (pull_request) Successful in 42s
PR build (required check) / gate (pull_request) Successful in 3s
2026-07-23 13:58:57 +00:00
424930619a
Merge pull request 'Promote dev to main (domain-sha tag keying)' ( #4 ) from dev into main
secrets-guard / encrypted (push) Successful in 7s
secrets-guard / encrypted (pull_request) Successful in 7s
2026-07-23 13:44:00 +00:00
0b46844cf5
Key image tags to the last domain-touching commit, not the branch tip ( #3 )
secrets-guard / encrypted (push) Successful in 5s
secrets-guard / encrypted (pull_request) Successful in 6s
PR build (required check) / changes (pull_request) Successful in 9s
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) / build-backend (pull_request) Successful in 54s
PR build (required check) / gate (pull_request) Successful in 3s
2026-07-23 13:42:28 +00:00
Emi Griffith
0ed7e89401
stack: fix bind-mount paths for the monorepo host layout
...
Sync infra to hosts / sync-beta (push) Successful in 6s
Sync infra to hosts / sync-prod (push) Successful in 5s
secrets-guard / encrypted (push) Successful in 8s
The cutover moved the host checkout's deploy tree to /opt/thermograph/infra/deploy/,
but the stack file's absolute bind sources (db init, env-entrypoint.sh, autoscale.sh)
still pointed at the old /opt/thermograph/deploy/ -- a service update kept the stale
mounts and new tasks failed with 'bind source path does not exist'.
2026-07-23 03:34:25 -07:00
Emi Griffith
e5a4b25f71
backend: monorepo cutover marker (path-filter probe)
Deploy backend to beta VPS / deploy (push) Failing after 10s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 34s
secrets-guard / encrypted (push) Successful in 5s
Deploy backend to prod VPS / deploy (push) Failing after 5m35s
2026-07-23 03:18:03 -07:00
Emi Griffith
f21f553d49
build.yml: run the hermetic suite inside the built image (promote dev's port to main, matching the split repos' dev->main promotion)
secrets-guard / encrypted (push) Successful in 7s
2026-07-22 22:37:43 -07:00
Emi Griffith
303ab24938
Subtree-sync frontend to split main 510d94d (dev->main promotion: reconciled hardening, two-tier suite); subtree workflow copy stays deleted (CI lives at root)
2026-07-22 22:37:29 -07:00
Emi Griffith
303134479d
Subtree-sync backend to split main a4d7fcd (dev->main promotion: reconciled bot + hardening, in-image CI); subtree workflow copies stay deleted (CI lives at root)
2026-07-22 22:37:21 -07:00
510d94df96
Merge pull request 'Promote dev to main (reconciled bot + hardening merge, test harness, in-image CI)' ( #7 ) from dev into main
2026-07-23 05:35:11 +00:00
a4d7fcd1d7
Merge pull request 'Promote dev to main (reconciled bot + hardening merge, test harness, in-image CI)' ( #15 ) from dev into main
2026-07-23 05:35:07 +00:00
Emi Griffith
67e4d651f5
Merge branch 'worktree-mono-assembly' into dev
secrets-guard / encrypted (push) Successful in 6s
2026-07-22 22:27:09 -07:00
Emi Griffith
31b969039a
docs: record the 2026-07-22 branch-migration sweep in cutover notes
2026-07-22 22:27:09 -07:00
Emi Griffith
a9ceb8f03f
CI: port the dev-branch in-image test step into the reusable build check
...
Backend runs its full hermetic suite, frontend its unit tier, inside the
just-built image -- the dev-only feature both app repos carried in their own
build.yml (deleted here in favor of the root workflow).
2026-07-22 22:24:31 -07:00
Emi Griffith
2b775abe6f
Subtree-merge thermograph-frontend origin/dev into frontend/ (two-tier test suite; CI workflow ported to root)
...
# Conflicts:
# frontend/.forgejo/workflows/build.yml
2026-07-22 22:23:50 -07:00
Emi Griffith
6bee541d66
Subtree-merge thermograph-backend origin/dev into backend/ (CI-in-image feature; workflows ported to root)
...
# Conflicts:
# backend/.forgejo/workflows/build.yml
# backend/.forgejo/workflows/deploy.yml
2026-07-22 22:23:50 -07:00
Emi Griffith
210627f040
docs: monorepo README, cutover runbook, root agent instructions
2026-07-22 22:11:33 -07:00
Emi Griffith
2e753f2c6f
deploy: adapt scripts + compose to the monorepo host checkout
...
/opt/thermograph becomes a monorepo checkout: deploy.sh gains INFRA_DIR (git
ops at the root, compose work cd'd into infra/), lock/tags/render paths move
under infra/deploy/, image-path defaults become emi/thermograph/backend|
frontend across compose, stack, and the tag-prune. docker-compose.yml pins
name: thermograph -- without it compose run from .../infra derives project
"infra" and recreates the whole stack beside the running one;
deploy-dev.sh pins COMPOSE_PROJECT_NAME=thermograph-dev (env wins over the
file key) to keep LAN dev's separate project.
2026-07-22 22:11:33 -07:00
Emi Griffith
7b2db07722
CI: port the split repos' workflows to per-domain path-filtered monorepo pipelines
...
One root workflow set replaces the four repos' copies (deleted -- root-only
is where Forgejo reads them, and dead copies are a trap): per-domain
build-push with explicit image paths (emi/thermograph/backend|frontend; the
old github.repository-derived path collides in a monorepo), path-filtered
per-domain beta/prod/dev deploys, a domain-input reusable build check, a
single always-reporting PR gate (path-filtered required checks deadlock
auto-merge), a new infra-sync pipeline (host checkout + secrets render on
infra/** pushes), and ports of secrets-guard / ops-cron /
observability-validate to monorepo paths.
2026-07-22 22:11:33 -07:00
f0e87b78ba
Merge pull request 'Merge main into dev: absorb responsiveness hardening; migrate its new tests to the unit tier' ( #6 ) from reconcile-dev-with-main into dev
2026-07-23 05:07:43 +00:00
017997a656
Merge pull request 'Merge main into dev: absorb hardening line + resolve the duplicate bot port' ( #11 ) from reconcile-dev-with-main into dev
2026-07-23 05:07:40 +00:00
Emi Griffith
f2fd8f6835
Subtree-merge thermograph-observability (origin/main) into observability/
...
git-subtree-dir: observability
git-subtree-mainline: ae1d9bb534
git-subtree-split: 19e74af9ca
2026-07-22 22:01:11 -07:00
Emi Griffith
ae1d9bb534
Subtree-merge thermograph-infra (origin/main) into infra/
...
git-subtree-dir: infra
git-subtree-mainline: d6df04eab2
git-subtree-split: 99b4b3f78d
2026-07-22 22:01:11 -07:00
Emi Griffith
d6df04eab2
Subtree-merge thermograph-frontend (origin/main) into frontend/
...
git-subtree-dir: frontend
git-subtree-mainline: a4be7066e5
git-subtree-split: 3a98146da4
2026-07-22 22:01:11 -07:00
Emi Griffith
a4be7066e5
Subtree-merge thermograph-backend (origin/main) into backend/
...
git-subtree-dir: backend
git-subtree-mainline: 6723fc0326
git-subtree-split: 83c2e05b96
2026-07-22 22:01:11 -07:00
Emi Griffith
6723fc0326
Monorepo root: reunify the split app repos (docs stays separate)
2026-07-22 22:01:11 -07:00
Emi Griffith
9afc19eb2f
Merge main into dev: absorb responsiveness hardening ( #4 )
...
# Conflicts:
# tests/test_content.py
2026-07-22 21:56:11 -07:00
Emi Griffith
6c3d7b8215
Merge main into dev: absorb notifier/PG hardening + the hardened bot port
...
main received the perf hardening line (#5 , #8 ) and its own landing of the
Discord gateway bot (#7 ) while dev carried a parallel port of the same bot
(#3 ). The two implementations are near-identical ports of the same archived
source; main's includes one extra hardening (grading calls moved off the
gateway event loop via asyncio.to_thread) and broader tests, so bot files
resolve wholesale to main's side. dev keeps its test-runner/smoke tooling and
the run-tests-in-image CI, which main lacks.
# Conflicts:
# notifications/discord_bot.py
# tests/notifications/test_discord_bot.py
# web/app.py
2026-07-22 21:54:18 -07:00
99b4b3f78d
Mail docs: stack-mode gateway + postfix umbrella-unit gotcha ( #12 )
2026-07-23 04:45:15 +00:00
6f75762c89
Document THERMOGRAPH_DISCORD_BOT (gateway-bot enable flag) in env example + key-gaps ( #11 )
2026-07-23 04:41:49 +00:00
3a98146da4
Harden top pages against backend blips, pool the content-API client ( #4 )
2026-07-23 04:41:43 +00:00
83c2e05b96
Land the Discord gateway bot (port + hardening) ( #7 )
2026-07-23 04:41:32 +00:00
215c46cea7
Bound Postgres connections, add rate-limit/timeout guards, move revgeo off the threadpool ( #8 )
2026-07-23 04:41:26 +00:00
d67476ebbf
notifier: bound push/Discord sends, cap pass duration, fix key-gen race ( #5 )
2026-07-23 04:41:19 +00:00
f2270100bb
Stack rehearsal fixes: interpolation, network ownership, plain-CMD images ( #10 )
2026-07-23 04:21:10 +00:00
9cd24387f2
Swarm stack for prod: autoscaled web tier (1-3), worker split, loopback LB ( #9 )
2026-07-23 04:13:12 +00:00
d9d72e4e8d
CI: run the test suite inside the built image ( #3 )
2026-07-23 00:59:06 +00:00
90a7148165
CI: run the test suite inside the built image ( #4 )
2026-07-23 00:59:03 +00:00
b412b7352a
test: self-contained two-tier suite + pull-the-backend-image harness ( #2 )
2026-07-23 00:40:18 +00:00
c2ce93fad6
test: reproducible local runner + image boot-smoke ( #2 )
2026-07-23 00:40:13 +00:00
d02c0f719f
render-secrets: chown rendered env to the deploy user on the sudo-install path ( #7 )
2026-07-23 00:38:15 +00:00
97d0e53d77
Port the Discord gateway bot from the archived app repo (its PR #23 ) ( #3 )
2026-07-22 23:58:49 +00:00
f5b8b26590
thermograph.env.example: document THERMOGRAPH_DISCORD_BOT ( #8 )
2026-07-22 23:58:02 +00:00
e44d1603b6
deploy.sh: serialize concurrent deploys with flock; GC old app-image tags ( #6 )
2026-07-22 23:39:29 +00:00
e929f4606f
Docs pass after the app-repo archive; sync key-gaps skill; add CLAUDE.md ( #5 )
2026-07-22 23:36:21 +00:00