fix(render,network,handoff): port the litclock-dev#640/#642/#644/#645/#646 train - #55
Merged
Merged
Conversation
…/#646 train Second of two port PRs for v0.224.0. Stacked on the PR1 branch because both touch CHANGELOG.md; see the merge-order note in the PR body. litclock-dev#640 — handoff splash row clamps. Long values ran off the glass, and long before that they collided with the right column. The clamp is now derived from the actual text budget rather than the panel width. litclock-dev#642 — cross-file string parity is enforced in CI. Strings that must match across files (the handoff completion triggers, the dispatcher's markers) had no mechanical check, so a rename in one file silently broke a grep contract in another. litclock-dev#644 — QR screen clamps, and ONE derivation of the text budget. The bound that applies is the 760px text budget, not the 800px panel, and having two surfaces derive it independently is how they drift. litclock-dev#645 — record the LAN IP before the handoff gate, not after. The nm-dispatcher's marker write sat behind the .handoff-complete gate, so on a fresh provision it was skipped entirely and /run/litclock/last-rendered-ip stayed absent for a whole DHCP lease — far past the 300s settling grace. Every clock coming out of first boot therefore showed "Network: Connection issue" with a blank LAN IP. The write is now un-gated. The dispatcher still refuses to record the setup hotspot's own gateway or a 169.254 link-local, so the true "never acquired an IP" alarm keeps working in both directions. litclock-dev#646 — attribute the handoff completion to the path that actually did it. The journal named a cause it had not established, which made the long-standing "verify all three completion paths separately" QA step unanswerable. The fallback timer uses the same phrasing, so a rescued device is greppable too. Port notes: - 51 bare dev#NNN references requalified to litclock-dev#NNN. - Two new files on this repo: tests/test_cross_file_string_parity.py and tests/test_nm_dispatcher_behavior.py. - One conflict, in the _anomalies.py docstring: this repo already carried the requalified litclock-dev#596 ref while the incoming commit rewrote the sentence around it. Took the newer wording (it describes what litclock-dev#645 actually changed) and kept the qualified ref. - The litclock-dev#646 CHANGELOG hunk also re-added litclock-dev#649's entry, which PR1 already ported. Dropped the duplicate; #649 appears exactly once. - Verified nothing was dropped: of every line the five upstream commits added, the only ones absent here were superseded within the same series (litclock-dev#644 replaced litclock-dev#640's `max_w` with PANEL_TEXT_BUDGET and reformatted nine assertion f-strings). tests/test_eink_wrap.py is byte-identical to dev; src/eink_display.py differs only by this repo's existing bare-#NNN requalifications. Testing: - ruff + shellcheck clean - pytest: 3360 passed, 62 skipped (was 3252 on PR1 — the 108 new tests are the ported ones; all 62 skips pre-existing and in untouched files) - npm run test:js: 191 passed
kapoorankush
force-pushed
the
fix/port-render-dispatcher-handoff-train
branch
from
August 16, 2026 17:03
3d7b2a2 to
bd955ae
Compare
kapoorankush
changed the base branch from
fix/port-hotspot-password-and-clone-warning
to
master
August 16, 2026 17:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second of two port PRs for v0.224.0. Ports litclock-dev#640, #642, #644, #645, #646.
What changes
.handoff-complete, so on a fresh provision it was skipped entirely and the marker stayed absent for a whole DHCP lease, far past the 300s settling grace. Every clock coming out of first boot showed "Network: Connection issue" with a blank LAN IP.Port notes
dev#NNNrefs requalified tolitclock-dev#NNN.tests/test_cross_file_string_parity.py,tests/test_nm_dispatcher_behavior.py._anomalies.pydocstring: this repo already carried the requalifiedlitclock-dev#596ref while the incoming commit rewrote the sentence around it. Took the newer wording (it describes what #645 actually changed) and kept the qualified ref.max_wwithPANEL_TEXT_BUDGETand reformatted nine assertion f-strings).tests/test_eink_wrap.pyis byte-identical to dev;src/eink_display.pydiffers only by this repo's existing bare-#NNNrequalifications.Testing
pytest: 3360 passed, 62 skipped (was 3252 on feat(wifi): persist the setup hotspot password per device; let the clone warning print #54 — the 108 new tests are the ported ones; all skips pre-existing, in untouched files)npm run test:js: 191 passedReview found a pre-RC defect in the ported code — filed, not patched here
Adversarial review found that litclock-dev#645's link-local blanking disables the same-IP short-circuit:
CURRENT_IP=""fails the[ -n "${CURRENT_IP:-}" ]gate that guards theexit 0, so everydhcp4-changeat a169.254.xaddress falls through to a full e-ink render. Measured three renders from three identical events where a real address produces one. That reinstates the unbounded-render / SPI-contention failure the #309 A4 guard was written to prevent, on a device with a finite panel-cycle budget.It is present identically on dev, so it is fixed upstream and ported rather than patched here — patching only this repo adds to the forward divergence litclock-dev#657 already tracks. Filed as litclock-dev#667, scoped pre-RC alongside litclock-dev#660, with three smaller findings from the same review.