a73x

the session-list→tile diff is written twice: webhub.applyList vs wall_host.planHostDiff

open   by a73x

webhub.zig:155-191 (applyList) and wall_host.zig:186-238 (planHostDiff) implement the same birth/keep/missed-once-grace/vanish rule — same field names, and the same trust-policy comment copy-pasted verbatim. planHostDiff is already the pure, testable planner and its docstring claims to be 'the whole of a host's live sessions are its tiles'; the hub should consume a shared planner rather than re-derive the policy. Needs an ownership decision first: webhub (client row) cannot import wall_host (tui row), so the planner would move down to client or a shared row.

Same neighborhood, smaller: the transport frame-drain + redial ladder is duplicated between webhub.pumpTile and wall_pump (~20 lines each; the one-frame-per-event divergence is now pinned as deliberate by a comment, 2026-09-01). link.zig's awaitFrame doc already claims every hand-rolled poll+readFrame loop is a copy of it — a Link-level drain helper would absorb both. And quic waitReady is written twice (client.zig:729, muxa.zig:497) with subtly different outcome mapping; quic.zig owns Client.pump/isReady and is the natural home.

Found in the 2026-09-01 duplicate-code probe; sites verified.