v0.151.0 — the Megosztás page stops reloading, and says how to connect
S-1: /sharing/status coerced idle->running on the PHASE channel, so the first poll of every steady-state page load reported a terminal job that never ran and the client's repaint-reload fired ~1.2s apart, forever. The coercion's real duty (liveness must never be contradicted) belongs to the 'running' LEVEL field beside it, and is now pinned by its own regression test. S-4 core: a terminal 'running' is served exactly once, so a REAL bring-up cannot re-arm the reload on the page it just caused. failed/needs_password/in-flight are never consumed. Unified async-job feedback stays the ROADMAP item. S-2/S-5: new connect card with the Windows form, the Mac form and the direct smb://<IP>, read from the SAMBA container's netns (the controller is on a docker bridge and would answer 172.x). Derived per render, cached nowhere - the address is a DHCP lease. Underivable => the line is omitted. sharing.html's <script> block is byte-identical to v0.150.0. Red-proofed three ways. 23/23 packages green.
This commit is contained in:
@@ -1,5 +1,50 @@
|
||||
## Changelog
|
||||
|
||||
### v0.151.0 — the Megosztás page stops reloading, and says how to connect (2026-07-20)
|
||||
|
||||
Closes **S-1**, **S-2**, **S-5** and the core of **S-4** from
|
||||
`felhom.eu/documentation/audits/DIAG-sharing-2026-07-20.md`.
|
||||
|
||||
**S-1 — `/sharing` reload-looped about once a second, for every customer with sharing enabled.**
|
||||
`GET /sharing/status` carries two things that mean different things to the client: `phase` (the
|
||||
ensure JOB — the page answers a terminal `running` with a one-shot `location.reload()`, because the
|
||||
„Állapot" badge is server-rendered) and `running` (the service LEVEL, straight from the liveness
|
||||
probe). v0.147.0 coerced `idle`→`running` on the PHASE channel so that a missing job could never
|
||||
contradict a live container. That duty was real, but it belongs to — and was already discharged by —
|
||||
the `running` field beside it; on the phase channel the same value reads as a fresh success edge. The
|
||||
poll's `tick()` runs synchronously at script end, so the FIRST poll of every steady-state page load
|
||||
reported a terminal job that had never run, scheduled a reload 1.2s later, and the new page did it
|
||||
again. The coercion is gone: no job, no edge. The defensive intent it was written for is now pinned
|
||||
by its own named regression test on the `running` field.
|
||||
|
||||
**S-4 (core) — a REAL bring-up is now reported exactly once.** Without this the loop would return
|
||||
after every future image update: the finished job outlives the reload it triggered, so the next page
|
||||
load found `phase:"running"` waiting for it. `consumeIfRunning` serves a terminal `running` once and
|
||||
clears it — and only while the single-flight slot is free, since the job goroutine sets the phase
|
||||
before its deferred `release()` and eating it in that window would lose the success the customer is
|
||||
waiting on. `failed` and `needs_password` stay sticky (their client path stops the timer and shows a
|
||||
card with NO reload, so stickiness is informative and cannot loop), and in-flight phases are never
|
||||
consumed. Accepted cost, stated rather than hidden: with two tabs open during a bring-up only the
|
||||
first gets the success banner — both still show the true state, which comes from the level channel.
|
||||
The unified async-job feedback layer remains the ROADMAP item; this is the minimal contract fix.
|
||||
|
||||
**S-2 + S-5 — the page now names both ways in.** It had only ever shown the configured NetBIOS name,
|
||||
so a customer whose network fails to resolve it had no fallback but a guess — and the guess that
|
||||
produced the diagnosis was the Proxmox HOST's address, which never ran smbd. New
|
||||
„Csatlakozás a megosztáshoz" card: the Windows form, the Mac form, and the direct `smb://<IP>`.
|
||||
The address comes from `stacks.SambaLANAddress()`, which reads the guest's netns through the SAMBA
|
||||
container (`network_mode: host`) — the controller is on a docker bridge and would answer `172.x`,
|
||||
the same trap `setup.DetectLocalIPs` needs `HOST_IP` for. Reading it there also makes it the right
|
||||
kind of true: it is the address smbd is bound to, not merely one the box owns. **Derived per render
|
||||
and cached nowhere** — the guest holds it by DHCP, so a stored copy eventually misdirects people
|
||||
(S-5) — and an underivable address omits the line, because no address beats a wrong address.
|
||||
|
||||
`sharing.html`'s `<script>` block is byte-identical to v0.150.0: both fixes are server-side, so the
|
||||
client contract is proven fixed rather than papered over. `infra.SambaHostInterface` replaces the
|
||||
third `eth0` literal (smb.conf, `FELHOM_IFACE`, and now the address read must name the same nic).
|
||||
Red-proofed three ways — reinstating the coercion, deleting the serve-once clear, and memoizing the
|
||||
derived address each turn the corresponding test red. 23/23 packages green.
|
||||
|
||||
### v0.150.0 — green gate restored + the export link stops leaking the CSRF token (2026-07-20)
|
||||
|
||||
**F7 / R-53 — `app_export.html` built the app's public URL from the CSRF token.** The line read
|
||||
|
||||
Reference in New Issue
Block a user