diff --git a/CONTEXT.md b/CONTEXT.md index 80cbcc5..56dfee8 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -7,7 +7,26 @@ > > Ask Claude Code: "Please update CONTEXT.md with what we did today" -Last updated: 2026-10-15 (v0.315.0 — one app page with four tabs, the catalog guide, no Pi badge) +Last updated: 2026-10-15 (v0.316.x — the app page in one column; a version number is pushed once) + +> **2026-10-15 (late evening) — v0.316.0/.1/.2 built and on demo-hp; .3 committed, NOT built.** +> **Measured before fixing:** the tabs rendered unstyled through the public address because of a +> CACHE, not the box — the stylesheet URL was `?v={{.Version}}`, identical across three different +> 0.315.0 builds; the origin sends NO ETag and NO Last-Modified, so a copy can only expire; and +> Cloudflare caches it while rewriting the browser TTL to four hours. Evidence and its caveat: +> `audits/app-page-2026-10-15b/P0/VERDICT.md`. +> **Two mechanisms now:** `build.sh` refuses a second push of a version (a registry it cannot reach +> is a refusal too), and every shell's stylesheet address is a per-build tag. +> **The app page is the approved one-column mockup**: one width, hairline sections, underlined tabs, +> and a box only for „the app is waiting for you" (blue) or „this is risky" (amber). The +> auto-update SUCCESS banner is now meta text. +> **THE LESSON OF THE EVENING, and it cost a bad push:** I put the guard in `controller/build.sh`, +> but the release runbook runs `build/felhom-controller/build.sh` — a SEPARATE COPY from +> 2026-07-18. Proving the refusal against a real tag therefore re-pushed 0.315.0 a fourth time +> (R-1081). The build directory's script is a symlink now. A guard in a script nobody runs is not a +> guard. The same shape bit twice more in one evening: the asset tag shipped dead because only one +> of TWO render paths set it, and both times a BROWSER found what the suite could not. +> Not yet validated: the operator's own look; 0.316.3's two cosmetic fixes. > **2026-10-15 (evening) — v0.315.0, ONE APP PAGE WITH FOUR TABS.** An app was six pages and every „Vissza" went to the > app LIST; it is now `/apps/{slug}/{settings,data,guide,logs}` plus `/apps/{slug}/install`, one shared header and one diff --git a/REPORT.md b/REPORT.md index ee50266..ae8f7e4 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,280 +1,177 @@ -# REPORT — v0.315.0: one app page with four tabs (2026-10-15) +# REPORT — v0.316.x: the app page as one column; one image per version number (2026-10-15) ## 1. Baselines | Repo | `main` at start | Version | → | |---|---|---|---| -| felhom-controller | `85f65c7` | v0.314.0 | **v0.315.0** | -| felhom.eu | `06e7cf8c` (the task said `3263bb2`; it had moved — two other sessions are pushing) | docs only | — | -| app-catalog-felhom.eu | `e67aad4` | read only | — | +| felhom-controller | `8339206` | v0.315.0 | **v0.316.0 → .1 → .2 built; .3 committed, NOT built (§6)** | +| felhom.eu | `340804f9` (docs only) | — | — | -Architecture read before any claim: `02-controller-module-map.md` (`web/`, the R-571 alert-placement -rule), `10-localisation.md` §7, `15-media-library.md` (the Plex claim path), and the controller's -`CLAUDE.md`, `REUSE.md` and `.claude/rules/{ui-hungarian,gates,unprompted-work}.md`. +Architecture read first: `02-controller-module-map.md` „The app page", `09-update-architecture.md`, +the `felhom-ui-design` skill, and the controller's `CLAUDE.md` + `.claude/rules/*`. -**Where the work ran.** Edited on the Windows workstation; **built and tested on DooPlex** in an -isolated scratch clone (`/mnt/5_hdd/felhom.eu/scratch/cc-apptabs`) so the shared DooPlex checkout — -which two other sessions are using tonight — was never dirtied. The sync normalises line endings to -LF and restores any file it did not mean to touch, because this checkout has `core.autocrlf=true` -while six files (`.gitignore`, `Dockerfile`, `Makefile`, the three infra templates) are stored in git -WITH CRLF; a blanket normalisation rewrote all six on the first attempt. +Built and tested on DooPlex in an isolated scratch clone; edited on the Windows workstation. The +browser work is on the workstation, which is the reason CC runs here. -## 2. Files created / modified +## 2. PART 0 — the diagnosis, before any fix -**Created (11)** -`controller/internal/web/app_page.go` · `after_start.go` · `app_page_test.go` · `guide_render_test.go` · -`controller/internal/stacks/guide_test.go` · -`templates/app_shell.html` · `app_settings.html` · `app_data.html` · `app_guide.html` · `app_logs.html` · `app_fields.html` +**Verdict: (a) a cache.** Full evidence: `felhom.eu/documentation/audits/app-page-2026-10-15b/P0/VERDICT.md`. -**Deleted (4 templates)** `templates/app_info.html` · `logs.html` · `app_export.html` · `tier2_config.html` -— with the three page handlers that rendered them (`logsHandler`, `exportPageHandler`, -`tier2ConfigPageHandler`). The POST handlers beside them (`tier2ConfigSaveHandler`, -`appEmailToggleHandler`) stay, with their URLs. +**(b) is ruled out.** Exactly one guest ran 0.315.0 — demo-hp 9201 — on digest +`sha256:8887343011d6…`, identical to the registry's 0.315.0 at the time of measuring. The **global +floor is 0.314.0** (read from the hub's `/configuration`), so no box could have taken 0.315.0 by +itself. demo-hp 9202 and felhom-pve (N100) 9201 are both on 0.314.0; Tester 1 (`c11-appliance`) was +unreachable and, by the floor, cannot be on 0.315.0. -**Modified (main ones)** `web/server.go` (routes + the GET-only redirects) · `web/handlers.go` -(`appDetailHandler` → `appCommonData`; `deployHandler` → `deployPageData` + a thin renderer) · -`web/media_events.go` (`applyPlexClaim` extracted) · `web/tier2_config_handler.go` (redirect targets) · -`templates/deploy.html` (install-only; 1197 → 544 lines) · `stacks.html`, `dashboard.html`, -`backups_apps.html`, `app_import.html` (links) · `stacks/metadata.go`, `metadata_i18n.go`, -`appinfo_address.go`, `manager.go` (the guide) · both locale files · `scripts/template_id_gate.py`, -`scripts/test_gate_decoys.py`, `scripts/i18n_go_keys.json`. +**The mechanism, in four measured facts:** -## 3. Commits on `main` +1. `layout.html` asked for `/static/style.css?v={{.Version}}` → `?v=0.315.0` for **all three** + different 0.315.0 builds (`e66d466`, `fe0228c`, `db52f5a`); the first had no `.app-tabs` rules. +2. The origin sends **no validator**: measured on the box, `ETag present = 0`, + `Last-Modified present = 0`. A cached copy cannot be revalidated — only expire. +3. Cloudflare caches that URL (`cf-cache-status: HIT`, `age: 99 → 100` over three requests) and + **rewrites the browser TTL from the origin's `max-age=3600` to `max-age=14400`** — four hours. +4. The session's first request returned **`cf-cache-status: EXPIRED`**, which only happens when the + edge holds an entry that has aged past its TTL. + +**What is true now, and the caveat stated rather than glossed:** origin, edge and box agree +byte-for-byte (`sha256 c1774f63…` both sides) and all carry the rules; the page itself is never +cached (`DYNAMIC`). The specific stale object is **no longer observable** — the first probe forced +its revalidation, which is what `EXPIRED` records — so I cannot show a `HIT` whose body lacks +`.app-tabs`. What is shown is every precondition, the proof an aged entry existed, and the +elimination of the only other candidate. No cache was purged by hand. + +## 3. Boxes on 0.315.0, with digests + +| Box | tag | digest | now | +|---|---|---|---| +| demo-hp 9201 | 0.315.0 | `8887343011d6` | **0.316.2** | +| demo-hp 9202 | 0.314.0 | — | unchanged | +| felhom-pve (N100) 9201 | 0.314.0 | — | unchanged | +| Tester 1 (`c11-appliance`) | unreachable | — | cannot be on 0.315.0 (floor 0.314.0) | + +## 4. Files changed, commits on `main` | Commit | What | |---|---| -| `e66d466` | v0.315.0 — the slice: tabs, routes, the after-start registry, the guide, the Pi removal, the fixtures. One commit, because the template split, the routes and the fixtures cannot be green apart | -| `fe0228c` | style the tab bar; reuse the hero classes that already have rules (**found in a browser**) | -| `db52f5a` | close the log tab's `` from `app_logs.html` again | `TestAppPage_ScriptTagsAreBalanced` FAILS: "logs: 3 `