pmacs/pmacs-gpu
Levi Neuwirth a8a996c446
feat(panel): the wheel exemption, exhaustion, and mapped coalescing
Three rows that share a shape: each is a gate this slice owns whose
downstream EFFECT belongs to the rebased replay lane.

G10b --- ordering, and a carve-out. `panel_mapping_is_current` now takes
the event kind. Zero is refused FIRST, then coordinate-free wheels skip
the freshness comparison. The order is the row: run the carve-out first
and a sender emitting zeroed wheels faces no check at all, which is an
inbound opt-out through the exempt path. The exemption exists because a
tick changes `view_top` and so advances the key --- the next tick already
queued behind it echoes the previous generation, and without the
carve-out the panel scrolls once per frame and appears dead. It returns
before the read, so a wheel does not advance the key either; advancing
would make a wheel invalidate the press after it.

The framing's carve-out-to-the-carve-out, re-imposing the check for
CHILD-REPORTED terminal wheels where SGR carries row and column, is
replay's. Whether a wheel is forwarded is decided by the reporting mode,
and no panel pointer coordinate is consumed on this base at all.

G11a --- exhaustion fails CLOSED. `saturating_add` froze the key at the
ceiling while the mapping kept moving underneath it: the stale-gesture
hole the key exists to close, with the check still appearing to pass.
Now `checked_add`, and overflow publishes `Absent`, clears input
authority, and latches for the session.

G13a/G13b --- `PanelPointerMapped` fell through `coalesce_kind` to
`None`, so pixel-rate mapped motion was lossless and filled the bounded
outbox. Two tags of its own; tail-replacement takes the whole event, so
coordinate and generation advance together and a collapsed run can never
pair a new coordinate with a stale one. Press, release and every wheel
kind stay lossless.

Mutation results, including two that changed the design:

  - exemption before the nonzero check -> G10b(zero) alone
  - no wheel exemption -> G10b(exemption) alone
  - saturating instead of checked add -> G11a alone
  - no exhaustion latch -> G11a, but only AFTER the row was extended.
    The first version of G11a did not bite: the latch had no proven
    job, because the overflow path already returns before storing the
    ceiling snapshot, so the next read re-takes the changed arm anyway.
    Measured, the two are ALTERNATIVES --- either alone keeps the band
    down; only removing both resurrects it. The latch is kept as the
    primary because it has a job the ordering does not: `peek` now
    honours it, so the peek and the authoritative read agree that an
    exhausted session has no key rather than reporting the ceiling.
    The source comment says this, rather than the "second half" claim
    it made before the measurement.
  - mapped variants untagged / one tag for all kinds / sharing the
    legacy tags -> the mapped coalescing row alone, three times

Witness-shape note: the two G10b rows call the predicate directly, and
say why. A wheel has no dispatcher-visible effect on this base --- a
document panel focuses on `Down` only --- so asserting focus for a wheel
would prove nothing. Each row carries a press leg, which does have an
effect, to show the predicate is wired into the production arm.

Verified: `cargo fmt --check`; `cargo clippy --workspace --all-targets
-- -D warnings`; `cargo test --lib` (1959); `cargo test -p pmacs-gpu
--bins` (275); both `bottom_panel_stage2b_*` suites (39); `git diff
--check`. `composition_overhead_under_ten_percent` red once during this
work and green in isolation --- a second occurrence of a signature the
lane ledger already carries, now recorded there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
2026-08-20 17:55:21 +02:00
..
fonts feat(math): bundle Latin Modern Math and read its MATH constants 2026-07-24 18:27:34 -04:00
src feat(panel): the wheel exemption, exhaustion, and mapped coalescing 2026-08-20 17:55:21 +02:00
Cargo.toml feat(release): binaries on tag — Distribution Stage 1 2026-08-01 14:40:47 -04:00