Answers review of 14. Framing only. Four of the six reverse something
14 asserted, and a green protocol gate would not have caught any of
them.
**"BESIDE `Present`/`PanelPointer`" WAS POSITIONALLY DANGEROUS.**
"Beside" reads as adjacent, and adjacent insertion shifts every
discriminant below it --- the exact hazard the appended-only rule
exists for. Appended means LAST: `PresentMapped` after `Absent`,
`PanelPointerMapped` after `TextInput`, with a diagram so the next
reader cannot re-derive it wrongly. Field order is stated exactly,
`mapping_generation` is a `u64`, ZERO IS INVALID --- it is what a
default-constructed or half-initialised sender produces, so accepting
it would let a peer opt out of the check by sending nothing --- and the
gate reads `PANEL_MAPPING_MIN_VERSION = 25` rather than a literal.
**BLANKET REFUSAL STOPPED THE WHEEL AFTER ONE TICK.** The first
effective document wheel changes `view_top`, which advances the key, so
the next already-queued tick carries the old generation and is refused:
the panel scrolls once and goes dead until the frontend observes the
new frame. Local terminal scrollback has the same shape.
The discriminator is whether the gesture USES its coordinate.
Coordinate-free gestures --- the document wheel, non-reporting terminal
scrollback --- cannot be mis-aimed by a stale mapping and are EXEMPT.
A child-reported wheel is the opposite case: SGR carries row and
column, so a stale one aims an application action at a cell the user
never pointed at, and it keeps the check. Two-tick witnesses added,
because without them a blanket-refusal implementation passes every
single-event row in the matrix.
**CANCELLATION WAS REACTIVE AND LOSES A RACE.** If the replacement
mapped frame reaches the frontend before the physical `Up`, the
producer resets `pointer_held` and SUPPRESSES THE VERY EVENT that would
have cancelled --- so the daemon is never told, the selection stays
armed, and the child keeps holding its button. It is now PROACTIVE,
triggered by the authoritative key advancing while a gesture is
accepted, and the producer must emit a cancellation tail or retain the
latch rather than clearing first.
That needs state 14 assumed and never specified: an ACCEPTED-GESTURE
LATCH recording whether the `Down` was accepted, whether it reached the
child, and the coordinate, button and encoding a release must match.
Two rules fall out and are ruled here --- a stale `Up` with no accepted
`Down` is INERT, and cancellation NEVER reclaims a controller another
frontend has since taken, because a stale gesture must not steal a live
one's terminal.
**THE EXISTING SCREEN GENERATION CANNOT BE THE TERMINAL KEY.**
`Screen::changed()` bumps from 39 call sites including `SetStyle`,
`Bell`, the tab-stop operations, cursor-only motion and `SetTitle`.
None of those change what a coordinate denotes, so keying on it would
cancel a drag every time the child recoloured a character. A dedicated
terminal mapping revision is defined over projected cell identity,
retained-row identity and the per-view scroll anchor --- with those
five events as explicit STABLE CONTROLS, so a reader who later reaches
for the convenient counter fails a test instead of shipping a cancelled
drag.
**G5'S EFFECTS ARE NOT PROVABLE ON THIS BRANCH**, and 14 claimed them.
`gesture_last_content_cell` and the document/terminal replay exist only
on `panel-pointer-replay` (`pmacs-gpu/src/main.rs:2143` there); the
same struct here is at `:2124` with no such field. The obligations are
split in a table. G5a --- that the key advancing RAISES cancellation
--- stays here on purpose: the trigger is this slice's rule, and moving
the whole row out would leave the proactive ruling with no witness in
the slice that introduces it.
P2s: mutation legs split (wrap vs gutter, terminal content vs
scrollback, G5a-c, G8a/b, G9a/b); G7 given a positive-path mutation;
G11 expanded --- exhaustion must publish `Absent`, clear input
authority, cancel any accepted gesture and LATCH, or a stale panel
stays painted and permanently inert; the v26 correction finished at the
gate and old-peer cells (`:573`); and the SS20 impact statement added
--- hardens an existing panel island, no journey grade changes, no
config, no background work.
**And the pin correction is mine to make: it EXISTS**, at
`src/protocol.rs:1975`, in the ROOT crate's test module rather than
under `pmacs-protocol/` or `tests/` --- which is exactly where I
searched. `message.rs:524` was right and the doubt was wrong; the
contrary claim is removed from both records.
Gates: all eleven green under `env -u TMPDIR` with `--protocol`,
log 20260814T180105Z.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai