v0.254.0 — the saved notes follow the language, and the switch becomes a globe (R-557 slice 2 release C; SLICE 2 CLOSED)
gates / gates (push) Successful in 23s
gates / gates (push) Successful in 23s
The notes a background run SAVES — last night's backup line, the last error, the proof result, the restore outcome — are written in the BOX's language at the moment they are written. A household that switches sees the previous run's note in the old language until the next run rewrites it: the operator's §16 option 1, stated rather than hidden. EndRestoreOp no longer receives a Hungarian literal from anywhere. The language switch is a globe. Two text links wrapped in the sidebar footer and asked the reader to recognise "Magyar"/"English" as links; a globe is the one symbol every web user already reads as "language", so nobody has to read Hungarian to escape Hungarian. It is <details>/<summary> — a menu with no script, drawn inline because the icon sprite lives only in layout.html and the visitor pages have their own shell. Those visitor pages get the same globe, and a visitor's choice stays theirs: a display-only felhom_lang cookie that langFor reads ONLY when there is no session. A signed-in household can never inherit a language a previous visitor picked in the same browser. POST /lang is CSRF-exempt for a narrow reason written at the exemption — its only achievable effect is the language of the page the victim's own browser shows them — and safeBackPath refuses //evil.example as well as https://, because "starts with /" alone is not the test. §16 taken: a successful claim carries the cookie into the household's setting. TWO PARITY EXCEPTIONS, MEASURED: 106 fixtures compared with a real diff — exactly two change shapes (the dashboard footer, the globe in the shells) and 5 byte-identical, which are the three pages that must not change. I INTRODUCED A DEADLOCK AND THE SUITE CAUGHT IT BY HANGING. UpdateOffboxStatus holds the settings write lock while running its callback; boxLang() wants the read lock; sync.RWMutex is not reentrant. On a real box an off-site run would have hung forever HOLDING the settings lock. Fixed by resolving the language before the callback, and guarded by a test that names the file and line in a second instead of hanging for 25 minutes. 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
This commit is contained in:
@@ -1,3 +1,64 @@
|
||||
## v0.254.0 — The saved notes follow the language, and the switch becomes a globe (2026-09-18, R-557 slice 2 release C — SLICE 2 CLOSED)
|
||||
|
||||
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing on the wire moved.
|
||||
**Hungarian changes in exactly TWO places, both declared and both measured** — the sidebar footer of
|
||||
every dashboard page, and the three pages a visitor meets. Everything else is byte-identical.
|
||||
|
||||
**1. The notes a background run SAVES now follow the language.** The line under last night's backup,
|
||||
the last error, the proof result, the restore outcome — written in the BOX's language at the moment
|
||||
they are written (`util.Text(lang, key, …)`, `m.note`/`s.note`). The consequence, stated rather than
|
||||
hidden: **a household that switches sees the note from the run before in the old language until the
|
||||
next run rewrites it.** That is the operator's §16 option 1; storing a code and rendering live would
|
||||
need a dozen new persisted fields and a legacy path for each — the R-570 shape a dozen times over.
|
||||
Converted: the off-site failure classes and quota notes, the tier-2 reasons and warnings, the undo
|
||||
phrases, the reconstitute hold, the restore record, and the whole restore-outcome family.
|
||||
**`EndRestoreOp` no longer receives a Hungarian literal from anywhere.**
|
||||
|
||||
**2. The language switch is a globe.** Two text links wrapped in the sidebar footer and asked the
|
||||
reader to recognise „Magyar"/„English" as links; a globe is the one symbol every web user already
|
||||
reads as "language", so nobody has to read Hungarian to find their way out of Hungarian. It is
|
||||
`<details>`/`<summary>` — a menu with no script, which opens on click and on Enter and which a screen
|
||||
reader announces. Language names inside are shown in their own language and are never translated.
|
||||
|
||||
**3. The sign-in, claim and recovery pages get the same globe — and a visitor's choice stays theirs.**
|
||||
Those pages are met by someone who has not signed in. They have no setting to read, and they must not
|
||||
write the household's: a box's sign-in page is reachable by anyone who can reach the box. So the
|
||||
choice lives in the visitor's own browser (`felhom_lang`, display-only, one of two values), and
|
||||
`langFor` reads it **only when there is no session** — a signed-in household can never inherit a
|
||||
language a previous visitor picked in the same browser.
|
||||
|
||||
`POST /lang` is exempt from CSRF for a narrow, checkable reason, written down where it is made: the
|
||||
only thing a forged request can achieve is to change the language of the page the victim's own browser
|
||||
shows them. It writes one cookie, reads nothing, touches no setting, and `safeBackPath` keeps its
|
||||
redirect on this box (a protocol-relative `//evil.example` is refused — "starts with /" alone is not
|
||||
the test). **If that handler ever gains a second effect, it needs CSRF that day.**
|
||||
|
||||
**§16, the operator's default, taken: a claim CARRIES the visitor's language.** Someone who switched
|
||||
the claim page to English and then claimed the box chose English deliberately. Only on success, and
|
||||
only there — the one moment an anonymous visitor becomes the household.
|
||||
|
||||
**No globe on the guest share pages or the not-found page.** A share visitor is a stranger and the
|
||||
household's setting is the wrong default for them; that is a promise about the share feature and an
|
||||
operator decision (**R-577**). Pinned by `TestGuestSharePagesHaveNoGlobe` so it stays a decision.
|
||||
|
||||
**The two parity exceptions, measured rather than asserted.** 106 fixtures rendered and compared with
|
||||
a real (LCS) diff — **exactly two change shapes**: the dashboard footer (89 fixtures) and the globe in
|
||||
the shells (12), with 5 byte-identical, which are precisely the three pages that must not change. The
|
||||
whole diff is in `felhom.eu/documentation/audits/i18n-slice2-2026-09-18/C/parity-exception-diff.txt`.
|
||||
|
||||
**Two defects this release found in its own measurement, recorded rather than tidied away:**
|
||||
|
||||
- The parity HARNESS rendered the three visitor shells through the DASHBOARD path, so the fixture
|
||||
would have baked a globe posting to `/settings/language` with a CSRF field — a form the real page
|
||||
never serves. Caught by reading the diff before re-capturing. The harness now branches on
|
||||
`i18nDirectTemplates`.
|
||||
- The first "is the change only the two blocks?" measurement compared LINE BY INDEX. An insertion
|
||||
shifts every line below it, so it reported 60 520 changed lines and measured nothing. **A
|
||||
line-index compare is not a diff.**
|
||||
|
||||
`R-575` folded in where it was one call (`tier2NoTargetReason` now returns a note in the box's
|
||||
language); the soft memory-overcommit warning stays as its row says.
|
||||
|
||||
## v0.253.0 — Errors carry the key of the sentence they are (2026-09-18, R-557 slice 2 release B)
|
||||
|
||||
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Every Hungarian sentence is byte-identical
|
||||
|
||||
Reference in New Issue
Block a user