GUI Stage 1-pre. `App::window_event` decided and performed everything
in one 655-line match, and nothing below it could be witnessed without
a display: `ActiveEventLoop` is non-constructible outside a live event
loop, and the arms that matter reach a GPU surface or a socket.
This is the seam, given its shape on the three smallest arms before the
194-line `KeyboardInput` one.
Deciding is `route_event(&WindowEvent) -> Route`, a free function over
the event alone, composing one decision function per family ---
`route_lifecycle` is the first. Performing stays on `App`: the `Resized`
body moves verbatim to `App::apply_resize`.
A route names its LOCAL EFFECT, not merely the family that claims it,
and the harness records routes rather than outbound protocol traffic.
That is deliberate and load-bearing: `CloseRequested` exits and sends
the daemon nothing, so a transcript of daemon traffic alone cannot tell
a handled arm from a dropped one. `RedrawRequested` is the second such
arm and lands next.
The zero-extent clamp moves into the router with the decision. wgpu
rejects a zero-extent surface configuration and a minimize delivers
0x0, so `.max(1)` is a rule rather than defensive padding --- and
deciding it in a pure function is what makes it witnessable with no
surface at all.
No behaviour change. The router is not yet reached for the families
still inline in `window_event`; each subsequent commit moves one, and
when the last goes the match collapses to the router call.
Evidence --- 6 rows, 5 mutations, each failing its own row and no other
beyond a stated dependency:
M1 `CloseRequested` -> no family -> the exit row (+ transcript)
M2 `Resized` -> `Exit` -> both resize rows (+ transcript)
M3 clamp dropped -> the zero-extent row ALONE
M4 harness records outbound only -> the transcript row ALONE
M5 `ModifiersChanged` drops the state -> the modifiers row (+ transcript)
The transcript row is the only one that fails under M4, because the
per-variant rows assert `feed`'s return value; that row alone owns P2,
which is what makes M4 discriminating rather than a blanket failure.
P3 --- that `window_event` DELEGATES rather than deciding for itself
--- is the framing's accepted structural exception, and it was
demonstrated rather than assumed: deleting the whole delegation, which
would leave the GUI unable to close, resize, or track a modifier, left
all six rows green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai