pmacs/pmacs-gpu/src
Levi Neuwirth 266bc6e4f3
fix(gpu,daemon): 1a review round 1 --- three P1s, and the version fallout
**A7 AND A8 WERE UNREACHABLE FROM THE REAL PRODUCER.** The intercept
branch sends a truncated `Key` and returns, and TextInput classification
sat below it --- but a modal prompt or a focused terminal is exactly
what makes `daemon_intercepts_keys` true, so the two contracts about
prompts and terminals were reachable only when neither was present. The
selection moves ABOVE the intercept return, where the producer sends the
same `TextInput` in every state and the daemon applies the modal
precedence, which is where it belongs: the frontend cannot see which
shadow is up.

Ordering against the branches below is safe by construction rather than
by luck --- `text_input_payload` returns `None` whenever a command
modifier is held, so Ctrl-V and command chords can never be shadowed.

**A pure `text_input_payload` test cannot catch this**, which is the
lesson worth keeping: the classifier was right the whole time and the
call site was wrong. The witness has to drive `intercept = true` and a
terminal.

**SINGLE-SCALAR PROVENANCE WAS PROMISED IN A COMMENT AND NOT
IMPLEMENTED.** §5 rules that a single-scalar commit is indistinguishable
from a keypress; the code only broke the chain for multi-scalar and
called a generic insert, so `this_command` went stale and no
`TypedEditRecord` was produced. Auto-pairing (Q#AP9) and every other
typed-edit consumer would have silently stopped recognizing GUI input
--- surfacing as "auto-pair stopped working in the GUI", far from its
cause. Now runs the real machinery: `rotate_command("buffer.self-insert")`
-> `typed_edit_arm(ch)` -> the one edit -> `typed_edit_finish` ->
`typed_edit_set_armed` -> `buffer.after-edit` -> clear, which is the
tail `dispatch_key` already runs.

**THE PRODUCER GATE WAS ONLY HALF THE WIRE CONTRACT.** The daemon
accepted `TextInput` from every installed session, so a peer negotiated
at v6-v23 --- compiled from this same crate, and postcard will happily
write the discriminant --- could mutate a buffer through a variant its
own session never declared. Now gated on the AUTHENTICATED session's
negotiated version.

**A4's structural half is implemented, not just its behaviour.**
`apply_keyboard` returns `()`, so `LifecycleRoute::Exit` is the sole
`EventOutcome::Exit` producer and the obsolete keyboard-exit channel is
gone rather than merely unused. The type survives, as ruled: one
producer is not one variant.

Also: `dispatch_text_input`'s rustdoc claimed a boolean return that its
signature does not have.

VERSION FALLOUT, SORTED RATHER THAN RENUMBERED.

Six deliberate tripwires took the conscious edit they exist to force
(protocol.rs, bottom-panel, discovery x2, statusline, and the vterm one
that was missing from my inventory). Two carried the version in their
NAME, so the name moved with the number rather than being left to lie.

Two ceiling assertions --- `!is_supported_protocol_version(24)` ---
now probe `PROTOCOL_VERSION + 1`, so they keep meaning "the set ends at
the current wire" instead of needing a hand-edit every bump.

`m4_6_handshake_accepts_v6_peer` was GENUINELY DEFECTIVE and is the one
real find: its name and the M4.6 contract say **v6 is the floor**, but
its body asserted `is_supported_protocol_version(PROTOCOL_VERSION)` ---
"the current wire accepts itself", a different and far weaker claim that
would have kept passing after v6 was dropped from the supported set,
which is the only regression it exists to catch. Anchored on literal 6.

The M10 pair needed no edit: they already use `PROTOCOL_VERSION`, and
they failed in the first sweep only because it predated the
`SUPPORTED_PROTOCOL_VERSIONS` fix.

`ADVERTISED_PROTOCOL_VERSION == 20` did not fire, as it must not.

Full `--workspace --no-fail-fast` sweep clean under an isolated TMPDIR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
2026-08-12 17:05:55 +02:00
..
attach.rs feat(gpu,protocol): 1a --- A1-A5 and the v24 TextInput variant 2026-08-12 16:35:21 +02:00
main.rs fix(gpu,daemon): 1a review round 1 --- three P1s, and the version fallout 2026-08-12 17:05:55 +02:00
math_layout.rs feat(math): caret-driven suppression, the draw pass, and the slice acceptance 2026-07-24 22:04:35 -04:00
math_parse.rs feat(math): caret-driven suppression, the draw pass, and the slice acceptance 2026-07-24 22:04:35 -04:00
terminal.rs feat(bottom-panel): paint and drive the GPU panel band 2026-07-29 18:40:46 -04:00