pmacs/tests
Levi Neuwirth 70e5781420
feat(discovery): M-x rows carry descriptions — protocol v22 -> v23
`Command.description` has always been required and has always been
rendered by `help.list-commands`. It was missing at the one moment it
would change a decision: the M-x row. This carries it there.

COHERENCE.md §5's clause "M-x rows are still bare names", per
docs/discovery-stage2-framing.md revision 3.

## The wire half is additive, and the old variant is FROZEN

postcard is not self-describing: enum variants encode by index and
fields by position. Widening `MinibufferPrompt.candidates` in place
would make every v12–v22 peer MIS-DECODE the bytes rather than ignore
them — and gating the widened form at `>= 23` would not rescue them
either, because with only one variant to gate they would receive no
minibuffer message at all. Compatibility requires the old shape to
still exist AND still be sent.

So `MinibufferPrompt` is retained unchanged for `12..=22`, and
`MinibufferPromptRows { prompt, input, cursor, rows, selected, total }`
is APPENDED as the final variant, carrying `MinibufferRow { label,
detail: Option<String> }`. A new row type, not `CompletionPopupRow`,
whose `kind` is an LSP `CompletionItemKind` code with no honest value
for a command (Q#D2-1).

Exactly one of the two reaches any peer, ever. The producer selects on
the session's negotiated version, so the CLOSE necessarily uses the
same family as the OPEN — a rows session closed by a legacy clear
leaves the dropdown on screen forever. The daemon's write loop gates
both directions again, with the legacy gate written as a RANGE
(`12..MINIBUFFER_ROWS_MIN_VERSION`) rather than a floor, so a v23 peer
cannot receive both and double-render.

`ADVERTISED_PROTOCOL_VERSION` stays 20, untouched.

## The TUI half involves no wire at all

`src/editor.rs` contains zero references to `MinibufferPrompt`:
`paint_minibuffer` reads `core.minibuffer` directly. So it reads
`Command.description` from the registry in-process, which is why this
half is independent of the bump.

Clipping is three ORDERED steps (§3.4), and the guarantee is "never a
PARTIAL name", not "the name always survives" — the prompt and typed
input consume the budget first, so the remainder can be too small even
for the bare name. If the whole name does not fit, the suffix is
omitted entirely; only once it fits is a description attempted; a
description that does not fit whole is dropped, leaving today's
`[name]`. No ellipsis stub, and no prefix of a name is ever emitted.

## Verification

`src/protocol.rs` gains this repo's FIRST literal postcard byte
fixtures: `minibuffer_prompt_v12_wire_bytes_are_frozen`, open and
cleared. A round-trip freezes nothing — it encodes and decodes with
the same types, so a field addition leaves it passing while every
shipped peer breaks. Bite-verified: reordering two fields of
`MinibufferPrompt` leaves `minibuffer_prompt_round_trips_through_postcard`
green and fails the fixture.

`line_wrap_facts_encoding_is_unchanged_by_the_v23_build` pins the
PREVIOUS final variant, per the handoff §4 rule that an appended
variant's own round-trip cannot detect a discriminant shift.

`tests/discovery_stage2_acceptance.rs` runs ONE daemon serving a v22
and a v23 session simultaneously, through the real M-x key path, and
asserts each receives its own variant AND ONLY its own — open and
close alike — by collecting every minibuffer message rather than
filtering for the expected one.

No cross-version cache test, deliberately (§3.2):
`SemanticRenderState::for_peer` bakes the negotiated version in at
attach and is dropped at detach, so a cache cannot span two versions.
A test for an impossible condition passes forever while teaching the
next reader that the hazard is real.

Five version assertions updated, each read before editing:
`src/protocol.rs` (the `PROTOCOL_VERSION` tripwire, renamed; and the
v6-floor ladder's accepted/rejected ranges),
`tests/statusline_segments_acceptance.rs`,
`tests/bottom_panel_stage2b_gpu_acceptance.rs`,
`tests/vterm_stage3_acceptance.rs`. No `ADVERTISED_PROTOCOL_VERSION`
assertion fired.

Gates: `scripts/gate --protocol --acceptance discovery_stage2_acceptance`
— all ten green, including the strengthened two-configuration sweep.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
2026-08-10 13:52:32 +02:00
..
common test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
fixtures V0.2-prerequisite pull-forward + M10.11 clean audit round 2026-05-18 10:31:31 -04:00
support docs: record the pipe-masking gate trap in the handoff 2026-07-29 12:25:29 -04:00
acceptance.rs Collapse if-let nests into let-chains (MSRV-1.95 collapsible_if sweep) 2026-05-18 14:29:36 -04:00
ambient_isolation_acceptance.rs fix(isolation): the isolation suite must not itself be ambient 2026-07-31 19:46:18 -04:00
auto_indent_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
auto_indent_crdt_acceptance.rs fix(lint): make the crdt targets pass clippy for the first time 2026-08-01 09:38:36 -04:00
auto_pair_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
auto_pair_crdt_acceptance.rs feat(edit): auto-pairing (Arc 2) 2026-07-11 17:11:56 +01:00
autosave_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
bottom_panel_stage1_acceptance.rs test(panel): pin that the OMITTED default degrades on a pre-panel frontend 2026-08-03 11:16:08 -04:00
bottom_panel_stage2a_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
bottom_panel_stage2b_daemon_acceptance.rs fix(tests): eight version assertions the v22 bump broke, five of them defects 2026-08-07 20:15:33 +02:00
bottom_panel_stage2b_gpu_acceptance.rs feat(discovery): M-x rows carry descriptions — protocol v22 -> v23 2026-08-10 13:52:32 +02:00
bottom_panel_stage2b_protocol_acceptance.rs fix(tests): eight version assertions the v22 bump broke, five of them defects 2026-08-07 20:15:33 +02:00
comment_toggle_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
compile_mode_acceptance.rs feat(view): horizontal scroll, text and decorations together 2026-08-07 22:43:17 +02:00
compile_mode_crdt_acceptance.rs review round 1: the crdt suite Stage 3 missed, and two stale explanations 2026-08-04 12:08:28 +02:00
completion_popup_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
config_registry_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
cua_region_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
desktop_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
dired_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
discovery_acceptance.rs fix(help): forwarders must work programmatically, not only from M-x 2026-07-31 20:31:00 -04:00
discovery_stage2_acceptance.rs feat(discovery): M-x rows carry descriptions — protocol v22 -> v23 2026-08-10 13:52:32 +02:00
editops_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
find_file_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
folding_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
folding_stage2_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
full_grid_resync_acceptance.rs fix(frontend): honor full_grid — the flag existed and nothing read it 2026-08-06 15:05:59 +02:00
gate_script_acceptance.rs test(gate): assert the real plan's (name, command) pair, not one half 2026-08-09 18:02:36 +02:00
gpu_font_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
gpu_initial_target_acceptance.rs Implement session-scoped GPU initial targets 2026-07-23 19:03:25 -04:00
gpu_invocation_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
gui_zoom_acceptance.rs docs(zoom): the ties both round up, they do not oppose 2026-08-06 17:50:03 +02:00
horizontal_scroll_acceptance.rs docs(test): five adopters, four of them decorator families 2026-08-07 22:49:59 +02:00
injection_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
journey_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
kill_ring_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
lean4_server_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
lean4_stage1_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
lean_input_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
line_wrap_acceptance.rs fix(editor): the renderer never got the mode everything else was reading 2026-08-07 18:48:11 +02:00
listview_acceptance.rs feat(view): horizontal scroll, text and decorations together 2026-08-07 22:43:17 +02:00
long_line_readable_acceptance.rs feat(view): horizontal scroll, text and decorations together 2026-08-07 22:43:17 +02:00
lsp_dispatch_seams_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
lsp_latex_acceptance.rs fix(lsp): a `/` search boundary no longer disables the LaTeX marker walk 2026-08-10 10:48:49 +02:00
lsp_multi_root_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
lsp_spawn_guidance_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m3_acceptance.rs
m4_acceptance.rs fix(tests): bound the LSP fixture's project detection — retires R8 (#226) 2026-08-09 08:54:06 +00:00
m5_5_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m5_6_acceptance.rs
m5_7_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m5_8_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m5_perf_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m6_4_repl_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m6_5_repl_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m6_7_scrollback_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m6_8_multi_repl_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m6_perf_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m7_3_acceptance.rs
m7_5_acceptance.rs fix(packages): basename-collision reject, SHA-256 cache key, timeout thread join, commit→revision, dead-code (F-005/F-009–F-012) 2026-07-03 18:47:23 -04:00
m7_6_acceptance.rs fix(packages): basename-collision reject, SHA-256 cache key, timeout thread join, commit→revision, dead-code (F-005/F-009–F-012) 2026-07-03 18:47:23 -04:00
m7_7_acceptance.rs
m7_8_acceptance.rs
m7_9_acceptance.rs
m7_10_acceptance.rs fix(packages): basename-collision reject, SHA-256 cache key, timeout thread join, commit→revision, dead-code (F-005/F-009–F-012) 2026-07-03 18:47:23 -04:00
m7_11_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m7_review_acceptance.rs
m8_1_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_1c_acceptance.rs
m8_1d_acceptance.rs
m8_2_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_3_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_5_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_6_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_7_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_9_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m8_10_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_1_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_2_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_3_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_4_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_5_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_6_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_7_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m9_8_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
m10_2_perf.rs M10.10 ship gate 2026-05-13 16:28:46 -04:00
m10_10_perf.rs M10.10 ship gate 2026-05-13 16:28:46 -04:00
m10_10_postcard_unknown_variant.rs M10.10 ship gate 2026-05-13 16:28:46 -04:00
m10_11_acceptance.rs M11.1: semantic-frontend protocol scaffolding (wire + capability) 2026-05-18 19:39:07 -04:00
m10_11_perf.rs M10.11: adversarial two-laptop acceptance + jitter; the M10 arc verified 2026-05-15 20:51:00 -04:00
m11_5_semantic_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
mode_system_wiring_acceptance.rs Keep the v21 panel wire dark for v20 clients 2026-07-28 14:08:17 -04:00
overlay_reattach_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
persistence_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
query_replace_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
resource_reconciliation_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
save_clobber_guard_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
statusline_segments_acceptance.rs feat(discovery): M-x rows carry descriptions — protocol v22 -> v23 2026-08-10 13:52:32 +02:00
tab_width_acceptance.rs feat(view): horizontal scroll, text and decorations together 2026-08-07 22:43:17 +02:00
terminal_config_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
terminal_copy_mode_acceptance.rs feat(view): horizontal scroll, text and decorations together 2026-08-07 22:43:17 +02:00
theme_faces_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
typed_edit_chain_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
vterm_stage1_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00
vterm_stage2_acceptance.rs fix(test): retire R2 and R4 — two readiness predicates weaker than their assertions 2026-08-05 13:41:05 +02:00
vterm_stage3_acceptance.rs feat(discovery): M-x rows carry descriptions — protocol v22 -> v23 2026-08-10 13:52:32 +02:00
worker_shutdown_acceptance.rs test(isolation): migrate the corpus off the ambient roots 2026-07-31 18:48:45 -04:00