**The P1 was real and my previous fix only did half of it.** Arming and
completing a `TypedEditRecord` are separate steps: `typed_edit_complete`
is called from `insert_char` / `insert_char_over_region` and NOWHERE
else, so routing the single-scalar branch through the generic
`insert_text_input` left the arm holding `None`. `this_command` rotated
correctly and `buffer.after-edit` saw no record --- auto-pairing stayed
broken while the command side looked right, which is the failure mode
that hides longest.
The single-scalar branch now goes through `insert_char_over_region(ch)`,
which handles the no-region case itself by delegating to `insert_char`.
`insert_text_input` is documented as the MULTI-scalar path only, with
the trap named at the definition rather than left for the next caller
to rediscover.
**The witness consumes the record rather than inspecting
`this_command`**, per the review. `single_scalar_text_input_produces_a_consumable_typed_edit_record`
takes it through the same `pmacs.pair._last_record` seam `pair.lua`
uses, and `single_scalar_text_input_auto_pairs_like_a_keypress` states
the same fact in the terms a user would notice: typing `(` must produce
`()`. **Mutation M-1a-1 reverts the fix and both rows fail**; the four
others stay green, so they are discriminating rather than duplicated.
**A ceiling tripwire proved less than it claimed.** The discovery
acceptance looped `6..=23` and then rejected `PROTOCOL_VERSION + 1`, so
a supported set that ENDED at 23 would have passed while
`PROTOCOL_VERSION` was 24 --- the accepted half said nothing about the
version the constant names. It runs to `PROTOCOL_VERSION` now.
**The public protocol history stopped at v23 while both constants
already included 24.** The rustdoc above `PROTOCOL_VERSION` and
`SUPPORTED_PROTOCOL_VERSIONS` now carries the v24 bump, and states the
thing that makes it unlike its predecessors: **it is the first
FRONTEND->INSTANCE extension needing a gate in BOTH directions**,
because the producer withholding is not enough when a peer compiled from
this same crate can encode the variant whatever it negotiated.
Three typed-edit doc sites said the arm is set by "the dispatch fallback
only" or named two producers; there are three now, and the single-scalar
`TextInput` path is one. `typed_edit_arm`'s own doc gains the warning
that arming is only half.
Also 1a's suite: A6 (one commit, one edit, one undo unit), A7 (a prompt
accumulates scalars in order), and A9's boundary row --- a payload
exactly at the cap lands intact, the complement of the rejection that is
enforced where a test can reach it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai