SparkyFitness onboarding record (Part C: bench + 9202 measured, six rows open — R-786; licence non-commercial — R-784); CHANGELOG/CONTEXT/REPORT for the R-753 catalog work
gates / gates (push) Successful in 2s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-01 22:16:21 +02:00
parent ca144ea841
commit de0a9bd29f
4 changed files with 109 additions and 17 deletions
+18
View File
@@ -1,3 +1,21 @@
## The visitor's address (R-753) — 19 router resets, BookStack per visitor, checklist 3.10; SparkyFitness's record (2026-10-01, night)
- **19 apps that read the LEFTMOST `X-Forwarded-For`** carry a router middleware removing the chain (`<router>-xff`,
defined on the router's own container): adventurelog, audiobookshelf, code-server, docmost, emby, ghost, gokapi, komga,
mealie, opengist, outline, paperless-ngx, papra, plant-it, rallly, romm, seerr, sparkyfitness, uptime-kuma (one commit
each, `04e9516`..`50e4fb4`). Pushed BEFORE controller v0.286 made traefik keep the tunnel's chain, whose leftmost entry a
stranger writes. Measured: such a router hands the app NO X-Forwarded-For (9202); docmost on demo-hp's real tunnel still
throttles a rotating forger at try 11. Sweep of all 56 (+Grimmory, MeTube) read in source:
`felhom.eu/documentation/audits/visitors-2026-10-01/A/sweep/`.
- **bookstack:** `APP_PROXIES=172.16.0.0/12` (`ca144ea`) — the login throttle per visitor. 3.6 re-measured on 9202:
before, a stranger's 5 wrong tries throttled the household from another address too; after, only the stranger.
(`09` decision 59 said "no gain" while every tunnel visitor shared one address — that is what R-753 changed.)
- **Checklist 3.10** (since 2026-10-02, `9b3b859`): the visitor's address — read from the right, never the leftmost; the
REUSE pattern, and the switches that must never be turned on. 61 checks.
- **`onboarding/sparkyfitness.md`** — the exempt app's record (the brief's Part C): bench (rebuilt 9401, destroyed) and
9202. Six rows open (R-786). **Its licence is non-commercial only — an operator decision (R-784).**
- Found, filed: `scripts/test_gate_decoys.py` fails 4 of its own "genuine" onboarding cases on the untouched tree (R-781).
## Grimmory — tested, NOT published; fixture added (2026-10-01, night)
- Grimmory (the BookLore successor) passed the checklist on the bench and 9202 except one finding that needs the
+4
View File
@@ -2,6 +2,10 @@
> Created with the REUSE.md rollout (2026-07-03). History: `CHANGELOG.md`; format spec: `README.md`.
- **2026-10-01 (night, later) — the visitor's address (R-753, controller v0.286.1):** traefik now keeps the tunnel's
X-Forwarded-For chain; readers take it from the RIGHT. Leftmost readers carry `<router>-xff` (19 apps); a right-walking
reader gets `172.16.0.0/12` (bookstack done; kimai, zipline, vikunja, nextcloud open — R-776). Checklist 3.10. SparkyFitness
record added; its licence is non-commercial only (R-784, operator). Licence sweep of the catalog owed (R-787).
- **2026-10-01 (night) — FIRST NEW APPS through the checklist:** Radicale `195129c`, Karakeep `882ac14`, Dawarich `72247a3`
published with complete records; Grimmory tested but held (R-775, operator); Grimoire/MeTube/Pinchflat stopped on the
fit check; Invidious/moonlight-web fit only (`felhom.eu/documentation/audits/new-apps-2026-10-01/FIT.md`).
+13 -17
View File
@@ -1,19 +1,15 @@
# REPORT — the first new apps through the checklist (2026-10-01, night)
# REPORT — the visitor's address in the catalog (R-753); SparkyFitness's record — 2026-10-01 (night)
Full session report: `felhom.eu/REPORT-new-apps-2026-10-01.md`; evidence `felhom.eu/documentation/audits/new-apps-2026-10-01/`
(fit table `FIT.md`).
Session report: `felhom.eu/REPORT-visitors-2026-10-01.md`. Baseline `94477cba435a`.
- **wger hidden** (`lifecycle: hidden`, `55b8c8a`) until R-762 and R-763 are fixed; read back on 9202: not on the app list.
- **Published, each with a complete `onboarding/<app>.md` and its first proven ladder step (bench swap 0 + 9202):**
- **Radicale** (`195129c`) — CalDAV/CardDAV, upstream image; the login file is written on the FIRST start only
(R-765: rewritten at every start, a restore after a remove locked the household out — fixed before publishing).
- **Karakeep** (`882ac14`) — bookmarks + crawler (Chrome) + search; AI off unless the household enters a key; setup gate,
sign-up closed twice; web memory raised to 1536M on measurements.
- **Dawarich** (`72247a3`) — location history, PostGIS 17; the seeded known login replaced by `after_install` behind the
install hold; `SECRET_KEY_BASE` a data_key.
- **Grimmory not published:** a stranger's 5 wrong sign-ins lock every visitor out for 15 min (hard-coded, one address
behind the tunnel) — R-775, the operator's word. Its template waits in the evidence `wip/grimmory/`; its fixture
(`Grimmory`) is in `upgrade_fixtures_box.py`.
- **Not built on the fit check:** Grimoire, MeTube, Pinchflat; Invidious and moonlight-web fit only.
- Fixtures added: `Radicale`, `Karakeep`, `Dawarich`, `Grimmory`. Gates: `catalog_gates.py --fast` OK on every push; the
runtime volume gate CLEAN for each published app (bench).
- **19 router resets** (`04e9516`..`50e4fb4`), one commit per app, each `catalog_gates.py --fast <app>` green. Pushed
before controller v0.286.0/.1 (whose traefik keeps the tunnel's chain). Installed copies on demo-hp (adventurelog,
docmost, opengist, paperless-ngx, romm) and demo-felhom (opengist) restarted through the product after the sync.
Measured: docmost on the real tunnel still throttles a rotating forged address at try 11.
- **bookstack `APP_PROXIES=172.16.0.0/12`** (`ca144ea`) — 3.6 re-measured on 9202, before/after
(`felhom.eu/documentation/audits/visitors-2026-10-01/A/bookstack-3.6.txt`).
- **Checklist 3.10** + REUSE pattern (`9b3b859`).
- **`onboarding/sparkyfitness.md`** — measured: bench 5.1/5.2/1.4/2.1/9.1 (LXC 9401 rebuilt and destroyed), 9202 walk
(gate, sign-up locks, 3.5, 3.6, 3.9, 4.3, 4.4, backup/remove/restore, both removes). Open: 0.1 (licence, R-784), 0.5,
0.7, 1.6, 1.7, 5.4, 8.3 (R-786).
- Not done: settings for kimai, zipline, vikunja, nextcloud, Jellyfin (R-776/R-777) — each needs its own 3.6 re-measure.
+74
View File
@@ -0,0 +1,74 @@
# Onboarding record — sparkyfitness
app: sparkyfitness
opened: 2026-10-01
template_at: ca144ea (sparkyfitness_server + sparkyfitness v0.17.3, postgres:18-alpine; the router reset of R-753)
<!--
An EXEMPT app (published before 2026-10-01): this record is the 2026-10-01 night brief's Part C, measured against the live
template. Bench (LXC 9401, rebuilt and destroyed this session): felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/. Box (scratch 9202, controller 0.286.1, live
catalog): felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt. Earlier proofs reused where they still hold: the PostgreSQL 15 → 18 step on both venues
(felhom.eu/documentation/audits/pg-last-six-2026-09-30/). Open rows are register rows (R-783..R-786).
-->
0.1 | open | the licence is NOT open source: "non-commercial purposes only … may not be used, directly or indirectly, in any product, service … intended for … commercial advantage … without prior written permission" (felhom.eu/documentation/audits/visitors-2026-10-01/C/C0-license.txt) — an operator decision (R-784)
0.2 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/C0-license.txt ; felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt — pushed 2026-10-01; releases through v1.7.3 — the pin v0.17.3 is 11 releases and a major behind (R-785)
0.3 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt — version tags, amd64 + arm64 (docker manifest inspect)
0.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the server's first-start log names no outside host but the box's own name and dotenvx's banner; no telemetry switch read in the env
0.5 | open | not measured whether food search reaches outside providers (OpenFoodFacts and others) at runtime
0.6 | n/a | the frontend serves HTTP on port 80 only; the server and database stay internal
0.7 | open | the phone app's sign-in route was not tried through traefik (the web sign-in is 3.9)
0.8 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — tagline + use_cases
0.9 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/birth/BIRTH/birth.log — runs on the bench; the public URL only builds links
1.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C3-catalog-gates-sparkyfitness.txt — image-pins and image-resolvable exit 0
1.2 | done | felhom.eu/documentation/audits/pg-last-six-2026-09-30/A1/upstream-notes.md — upstream's compose runs PostgreSQL 18; the template moved 15 → 18 on both venues
1.3 | done | app-catalog-felhom.eu/templates/sparkyfitness/docker-compose.yml — postgres:18 mounted at /var/lib/postgresql
1.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/move/evidence/MV-sparkyfitness/verdict.json ; felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/move/evidence/MV-sparkyfitness/migration-lines.txt — v0.17.2 seeded, stepped INTO v0.17.3, the server ran its own migrations, read back; the undo came back in 31.3 s with the data
1.5 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — node (tsx) runs the server; nginx serves the frontend
1.6 | open | the env names the server reads were not listed from its source; the set ones are the two DB passwords, API_ENCRYPTION_KEY, BETTER_AUTH_SECRET
1.7 | open | the image's entrypoint was not read
1.8 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — an unknown page answers the app's own page (200, the SPA), an unknown API 401; no stack trace
1.9 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — API_ENCRYPTION_KEY and BETTER_AUTH_SECRET carry data_key with the reason
2.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C2-volume-persistence-sparkyfitness.txt — volume-persistence gate CLEAN (it notes a benign write under /app/SparkyFitnessServer outside the mounts — not read further)
2.2 | done | app-catalog-felhom.eu/templates/sparkyfitness/docker-compose.yml — three named volumes (NVMe): database, uploads, the app's own backup folder
2.3 | n/a | needs_hdd false: no drive path to classify; the tier-1 unit holds the three volumes
2.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the first start wrote its database and the seeded check-in through the app
2.5 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the night chain's backup, remove keeping backups, the household's restore button (60.8 s), the weight read back with the household's own login
2.6 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — both remove choices delete the three volumes; no drive data exists; the stack folder is the catalog's copy
2.7 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — 69 MB database + 12 KB uploads after the seed; the database is mostly the food catalogue
2.8 | n/a | the household uploads no files in the measured flows; uploads volume holds profile pictures only (not exercised)
3.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — class 4: the first account made through the setup gate as the household (better-auth sign-up 200)
3.2 | n/a | no default login exists; the first visitor signs up (class 4, gated)
3.3 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — gated from the install; a stranger 302 (page) / 401 (API) before the setup; no probe — the household presses "Done"
3.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — after "Done": record open + native_lock applied, SPARKY_FITNESS_DISABLE_SIGNUP=true; a stranger's sign-up 403 at /api/auth/sign-up/email, /API/Auth/Sign-Up/email and //api//auth/sign-up/email; after remove + restore the lock came back (R-773, opened_by restore) and a stranger 403
3.5 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — 77 stranger sign-up tries, one a second from the press until the household's account: 404 then 401, never 200
3.6 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — through the simulated tunnel: 3 wrong sign-ins → 429 for ~10 s for EVERY visitor (better-auth keys on one address behind the router reset); the household from another address was refused 429 at 3 s and 10 s, in at 16 s; a forged leftmost address did not escape (R-783)
3.7 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — add_people: the 15-minute sign-up window (decision 47); the password is changed in the app's own profile
3.8 | n/a | no after_install command; after_setup sets an env value only
3.9 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the browser-shaped sign-in through traefik over https with Origin: right 200, wrong 401
3.10 | done | felhom.eu/documentation/audits/visitors-2026-10-01/A/sweep/sweep-4.md ; felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — better-auth reads the LEFTMOST X-Forwarded-For: the router reset (catalog 460f75e) removes the chain; measured: rotating forged addresses did not escape the limit
4.1 | done | app-catalog-felhom.eu/templates/sparkyfitness/docker-compose.yml — each healthcheck uses the image's own tool (verified by 4.3: all three report healthy)
4.2 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C3-catalog-gates-sparkyfitness.txt — probe-matches-compose OK
4.3 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt ; felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/birth/BIRTH/birth.log — box: all healthy 69 s after the press, 0 restarts; bench: 73.4 s, 184 migrations in ~2 s
4.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the server stopped: the state read degraded within 10 s (the front page still served by nginx, /api/health dead); running again 20 s after start
4.5 | done | app-catalog-felhom.eu/templates/sparkyfitness/docker-compose.yml — container_name sparkyfitness = the stack; sidecars sparkyfitness-server, sparkyfitness-db
5.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/birth/mem-summary.txt ; felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/birth/mem-birth.csv — swap 0, from birth: server 338.9 MiB (33.1 % of 1024M), db 13.9 MiB, frontend 5.1 MiB; 0 kills
5.2 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/move/mem-summary.txt ; felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/move/evidence/MV-sparkyfitness/burst-sparkyfitness.log — 10 min + a 540 s food-diary burst (3 269 foods and entries): server 38.2 %, db 53.3 %, frontend 2.6 % of their limits (anon); 0 kills, 0 restarts
5.3 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — mem_limit 1792M = 512M + 1024M + 256M, the header says the same
5.4 | open | one watch at one limit only (1024M); a second limit not measured
5.5 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — pi_compatible false (the card says so); images amd64 + arm64
6.1 | done | app-catalog-felhom.eu/scripts/upgrade_fixtures_box.py — Sparkyfitness: sign-up, check-in, readback, with a wrong-password and an empty-date control
6.2 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml ; felhom.eu/documentation/audits/pg-last-six-2026-09-30/box/sparkyfitness/box-verdict-sparkyfitness.json — the ladder step postgres 15 → 18, proven on both venues
6.3 | done | felhom.eu/documentation/audits/pg-last-six-2026-09-30/box/sparkyfitness/undo-verdict.json — the undo on 9202
6.4 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/move/evidence/MV-sparkyfitness/verdict.json — files_changed empty, no mark
6.5 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt — plain vX.Y.Z tags for both images
7.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — no mail settings in the template; a fresh install boots and serves (4.3)
8.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C3-catalog-gates-sparkyfitness.txt — copy-i18n OK
8.2 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — the first steps hold on 9202: open the address, sign up (through the gate), set the profile
8.3 | open | felhom.eu/assets/sparkyfitness-logo.svg and -.png and -screenshot-1.webp answer 404
8.4 | done | app-catalog-felhom.eu/templates/sparkyfitness/.felhom.yml — category home, catalog_since 2026-09-30
8.5 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C3-catalog-gates-sparkyfitness.txt — the template count is unchanged by this record
9.1 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/bench/C3-catalog-gates-sparkyfitness.txt — catalog_gates.py sparkyfitness exit 0 (11 gates)
9.2 | done | felhom.eu/documentation/audits/visitors-2026-10-01/C/box/sparky-box.txt — a fresh install on 9202 as the household and as a stranger, start to finish (live catalog, the app is published)
9.3 | done | felhom.eu/documentation/backlog/OPEN-ITEMS.md — the open rows above are register rows R-783..R-786
9.4 | n/a | an exempt app already published; this record is added after the fact