Skip to content

fix(render,network,handoff): port the litclock-dev#640/#642/#644/#645/#646 train - #55

Merged
kapoorankush merged 1 commit into
masterfrom
fix/port-render-dispatcher-handoff-train
Aug 16, 2026
Merged

fix(render,network,handoff): port the litclock-dev#640/#642/#644/#645/#646 train#55
kapoorankush merged 1 commit into
masterfrom
fix/port-render-dispatcher-handoff-train

Conversation

@kapoorankush

Copy link
Copy Markdown
Owner

Second of two port PRs for v0.224.0. Ports litclock-dev#640, #642, #644, #645, #646.

Merge order matters. This is stacked on fix/port-hotspot-password-and-clone-warning (#54) because both PRs touch CHANGELOG.md and separate branches would guarantee a conflict. Merge #54 first, and retarget this PR's base to master before you do — merging #54 with --delete-branch while this points at it will close this PR.

What changes

  • litclock-dev#640 — handoff splash row clamps. Long values ran off the glass, and collided with the right column well before that.
  • litclock-dev#642 — cross-file string parity enforced in CI. Strings that must match across files (handoff completion triggers, dispatcher 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.
  • litclock-dev#645 — record the LAN IP before the handoff gate. The dispatcher's marker write sat behind .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.
  • litclock-dev#646 — attribute the handoff completion to the path that actually did it, making the "verify all three completion paths" QA step answerable for the first time.

Port notes

  • 51 bare dev#NNN refs requalified to litclock-dev#NNN.
  • Two new files here: tests/test_cross_file_string_parity.py, 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 #645 actually changed) and kept the qualified ref.
  • The #646 CHANGELOG hunk re-added #649's entry, which feat(wifi): persist the setup hotspot password per device; let the clone warning print #54 already ported. Dropped the duplicate; #649 appears exactly once.
  • Verified nothing was dropped: of every line the five upstream commits added, the only absentees were superseded within the same series (#644 replaced #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

Review 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 the exit 0, so every dhcp4-change at a 169.254.x address 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.

…/#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
kapoorankush force-pushed the fix/port-render-dispatcher-handoff-train branch from 3d7b2a2 to bd955ae Compare August 16, 2026 17:03
@kapoorankush
kapoorankush changed the base branch from fix/port-hotspot-password-and-clone-warning to master August 16, 2026 17:03
@kapoorankush kapoorankush reopened this Aug 16, 2026
@kapoorankush
kapoorankush merged commit 5d01301 into master Aug 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant