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
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;Versionset inexecuteTemplateLang..shell-langis nowdisplay: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-menurule applies and the dashboard and the shells cannot drift apart.- The div moved to the end of each card: under the footer on
loginandclaim, last in the card onrecovery(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).