Files
felhom-controller/REPORT.md
T
admin 8fb2f9ef9d
gates / gates (push) Successful in 23s
v0.255.0 — the globe on the sign-in-flow pages: styled, and inside the card
Two defects in v0.254.0's globe, both plain on a browser and neither catchable by anything
that existed — every test read the MARKUP, and the fault was in which CSS file the browser
fetched.

The shells requested /static/style.css with NO ?v=, while layout.html has carried one since
v0.166.0. A browser holding a copy from before v0.254.0 kept serving CSS with no .lang-globe
rules, so the globe came out as a bare unstyled <details> — a stray triangle and two plain
words at the edge of the window. It was FIVE shells, not the three named: both guest share
pages have the same fault for any CSS change, and their visitor is the likeliest of all to be
holding an old copy. And .Version was missing from three of those five data maps, which is
exactly how the next one would be forgotten — it is now filled at the one choke point every
shell renders through.

The globe also floated outside the card, pinned to the corner of the VIEWPORT, reading as part
of the browser rather than the page. It now sits inside the card, centred under the footer, with
the menu opening upward via the shared rule — so the dashboard and the shells cannot drift.

AND A THIRD, caught by a test that already existed: putting the version on the guest share pages
would have printed the controller build onto a page a stranger with a capability URL can open.
TestShareGuest_HeadersTilesNoAdminChrome refused it. Those two now take an opaque per-build tag
— same cache-busting, no disclosure. The fill is ONE function shared with the parity harness,
because a fixture rendered through a different data path is a picture of a page nobody serves,
which the previous release got wrong twice.

15 shell fixtures re-captured; 91 identical, every dashboard page among them.

MinAgent: 0.131.0 (unchanged). No hub release needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-18 15:07:49 +02:00

4.4 KiB

REPORT — the globe on the sign-in-flow pages, fixed (controller v0.255.0)

2026-09-18 · base 2e9d402 (v0.254.0) · MinAgent 0.131.0, unchanged · no hub release. Architecture named: felhom.eu/documentation/architecture/10-localisation.md §3 (who picks the language, and where the switch lives).

1. Claims in the prompt that live source disproved — named first

the prompt said source says
"only the three shells lack ?v=" FIVE do: login, claim, recovery, and both guest share pages (launcher_shared, launcher_share_password). The share pages carry no globe, but the stale-stylesheet fault is the same for any CSS change and their visitor is the likeliest to hold an old copy. All five fixed — which is why 3 fixtures outside the named three changed, against the prompt's "zero re-captures outside the three shells". (8 first-boot wizard templates also lack it; out of scope, R-554 deletes them.)
".Version is already in their data" Only in two. login (auth.go:343) and claim (claim.go:289) set it; recovery and both share pages did not. Rather than add it three times, it is set once in executeTemplateLang — the choke point every shell renders through — so the next shell cannot miss it.
"login.html L11 … style.css L3683-3684" Confirmed, line for line.

2. What was wrong, and why no test saw it

The globe rendered unstyled for anyone whose browser had style.css cached from before v0.254.0: the shells requested it with no ?v=, so the cached copy — which has no .lang-globe rules — kept being served. The markup was correct, which is why every existing test passed: they all read the HTML, and the fault was in which CSS file the browser fetched. It took a screenshot to see it.

And the globe floated outside the card, pinned to the corner of the viewport, reading as a stray browser control rather than part of the page.

3. The fix

  • ?v={{.Version}} on all five shells; Version set in executeTemplateLang.
  • .shell-lang is now display:flex; justify-content:center; margin-top:1.5rem — a plain block inside the card. The absolute positioning and the menu-direction override are deleted, so the shared .lang-globe-menu rule applies and the dashboard and the shells cannot drift apart.
  • The div moved to the end of each card: under the footer on login and claim, last in the card on recovery (which has no footer paragraph).

3b. A third defect, caught by an existing test

Putting the version on the guest share pages would have printed the controller build onto a page a stranger with a capability URL can open. TestShareGuest_HeadersTilesNoAdminChrome already refused that, and refused it here — a good test earning its keep. Those two pages now take an opaque per-build tag instead (AssetTag): same cache-busting, no disclosure.

The fill is one function, addShellAssetData, called by executeTemplateLang and by the parity harness. Slice 2 release C got the fixture/production split wrong twice; sharing the function is what makes a third time impossible rather than merely unlikely.

4. Tests, red-proofed

TestGlobeOnAnonymousShells gained: the stylesheet carries a non-empty ?v=; the globe is inside the card; the globe is below the footer where one exists. Each was red-proofed by restoring the defect's exact shape — the unversioned link (convicts, naming the stylesheet) and the globe put back before the card (convicts, "floats outside it").

testServer gained version: "test": an empty ?v= busts a cache exactly once and never again, and baking that into a fixture would have hidden it. The test now refuses an empty one.

5. Parity

15 fixtures re-captured — 1 login, 4 claim, 7 recovery, 3 guest share — and 91 identical, including every dashboard page. Four change shapes: the three shells gained the moved globe AND the buster; the two guest pages gained only the buster, as an opaque tag. The whole diff is the ?v= attribute and the moved block, nothing else: felhom.eu/documentation/audits/i18n-slice2-2026-09-18/D/parity-diff.txt.

6. Green gate

go build ./... && go vet ./... && go test ./... green; all controller gates OK.

7. Row

R-579 — the cache-buster gap: found, fixed and closed in this session, with the general form recorded (a template that loads a versioned asset without the version is invisible to every test that reads markup).