From 546c0800cce7ee510ecb78b30bd6d0f9e36b5c55 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Sun, 19 Apr 2026 18:35:54 -0600 Subject: [PATCH] =?UTF-8?q?docs:=20CLAUDE.md=20=E2=80=94=20Session=203=20e?= =?UTF-8?q?ntry,=20live-in-prod=20state,=20current=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase moves to "live in production"; last-commit pointer and open-issues list reflect the deploy pipeline and proxy-headers fix. Session 3 summary added; Session 1 rotates off to the wiki (per the "most recent 3" rule). Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 82 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a2501fc..aec8bdf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -47,19 +47,18 @@ then restart. ## Current Project State -* **Phase**: shipped MVP + posting ledger + template-entry edit + - platform-deploy prep (`/healthz`, structured JSON logs). Working - daily-use tool; first production deploy to home-ctr-onyx pending. +* **Phase**: live in production on home-ctr-onyx at + `https://quartermaster.unbiasedgeek.com/`. Every merge to `main` + rolls out automatically via `.forgejo/workflows/deploy.yml`. * **Last worked on**: 2026-04-19 -* **Last commit on main**: `1296258` — chore: silence jsonlogger - deprecation, fix LogQL example (#26, #27) +* **Last commit on main**: `ee6eaae` — fix(docker): enable uvicorn + proxy-headers so url_for works behind Traefik * **Open PRs**: none -* **Open issues**: #28 Dockerfile, #29 compose.yml, #30 Forgejo - Actions deploy workflow (dependency-chained); #31 small cleanups - (non-blocking polish) +* **Open issues**: #23 MCP proposal; #31 small cleanups (non-blocking + polish); #26 and #27 are landed but weren't closed when their work + merged — safe to close. * **Test count**: 148 / 148 passing -* **Migrations**: 5 applied; latest `cc60e7f73a1c` (no schema change - in #26 or #27) +* **Migrations**: 5 applied; latest `cc60e7f73a1c` * **Blocking issues**: none After pulling new work, always: @@ -75,6 +74,47 @@ the live DB. Most recent 3 sessions (full history in the [wiki](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki)). +### Session 3 — 2026-04-19 + +Deploy-pipeline arc: four PRs (#32 Dockerfile, #33 compose.yml, +#34 Forgejo Actions workflow, #35 post-deploy proxy-headers fix) +took Quartermaster from "deploy prep merged" to live on +`https://quartermaster.unbiasedgeek.com/`. All three dependency-chained +issues (#28/#29/#30) closed. + +Key decision, locked mid-flight: the deploy workflow has **no SSH +step**. Initial draft used an SSH-from-runner-to-host pattern with +`DEPLOY_SSH_KEY` + `DEPLOY_KNOWN_HOSTS` secrets. Jeff pushed back — +the `homelab` runner lives on home-ctr-onyx itself with the host's +Docker socket mounted, so `docker compose pull && up -d` runs +directly against the same daemon that hosts production. Dropped +two secrets and the private-key risk surface. Remaining Actions +secrets: `REGISTRY_TOKEN` (archeious PAT, `read:package` + +`write:package`, minted via the Forgejo API using the admin +password exposed by `homelab-IaC/bin/load-ops-secrets`) and +`QUARTERMASTER_SMOKE_PASSWORD` (plaintext basic-auth for the +post-deploy `/healthz` probe). + +Other design points: image tag parameterised via +`QUARTERMASTER_TAG` (workflow writes a per-deploy `.env`), +`COMPOSE_PROJECT_NAME=quartermaster` pinned so the runner's +ephemeral workspace path doesn't confuse compose, smoke step does +`curl -u admin:… https://quartermaster.unbiasedgeek.com/healthz` +to catch TLS + routing + basic-auth regressions in one probe. + +One post-deploy bug: the first rolled image rendered unstyled +because uvicorn was started without `--proxy-headers`, so +Starlette ignored `X-Forwarded-Proto` from Traefik and `url_for()` +generated `http:///static/…` hrefs, which browsers +blocked as mixed content on the `https://` page. Reproduced +locally by curling the pre-fix image with Traefik-style headers; +added `--proxy-headers --forwarded-allow-ips='*'` to +`docker/entrypoint.sh` in #35. Safe to trust all forwarded IPs +because `compose.yml` publishes no host port — only Traefik on +`proxy-net` can reach port 8000. + +Full retro: [Session3](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki/Session3). + ### Session 2 — 2026-04-19 Platform contract intake (#25) filled out and accepted; platform team @@ -105,25 +145,3 @@ Deploy-pipeline work queued as #28 (Dockerfile), #29 (compose.yml), Full retro: [Session2](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki/Session2). -### Session 1 — 2026-04-17 - -Greenfield to working ledger. 10 PRs merged in one sitting: -scaffold (#2) → monthly view with snapshot + deviation (#4) → -backups + CLAUDE.md safety rule (#6) → zero amount header (#8) → -gitignore wiki (#10) → section groups + sinking funds (#12) → -notes field (#14) → month lifecycle Planning / Active / Closed -(#16) → UI redesign in Barlow Condensed with logo (#18) → -posting transaction ledger (#20). - -Key architectural decisions: snapshot-over-mirror for months; -Primary Debt Target is a pointer, not a pre-allocated amount; -nothing auto-sweeps — close requires applied zero at $0; `applied` -is derived from postings only, no column. UI went through three -mockups before settling on Barlow Condensed + cream paper + -burgundy accent sampled from the logo shield. - -One incident: I wiped the live DB several times during early dev -churn before the backup script existed. The script + alembic hook -+ repo-level CLAUDE.md safety rule are the fix. - -Full retro: [Session1](https://forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/wiki/Session1).