test(panel): P2 asserts real focus, and the ledger stops overstating

Answers review of 9028e1b.

P2 recorded `active_frontend`, which is which FRONTEND is current, not
which window has focus. Focus is `views[&fid].active` and `focus_window`
moves it, so the row would have watched a panel steal focus without
noticing. It now records the focused window, and asserts up front that
the panel does not already hold it --- otherwise "focus did not move to
the panel" asserts nothing.

P2's refusal lever also changed, because the old one could not exercise
what the row claims. An out-of-grid cell with the row bound removed
becomes `on_chrome`, so the press classifies Consumed and still reaches
no target: the row bit on its own precondition while focus was never
touched. A foreign buffer at an in-content cell is the refusal whose
mis-gating actually yields Accepted.

And the row now says what is falsifiable about it. Removing the buffer
check makes the press Accepted and P2 fails --- but on the precondition,
which fires first, so the focus, controller and byte assertions cannot
fail under that mutation and no other mutation reaches them: the daemon
applies only on Accepted, and the disposition enum gives Refused no
target to apply. They are defence in depth against a future refactor,
labelled as such rather than presented as coverage.

The ledger claimed every row reads a target effect and never the latch
alone. That was false. P9 and P10 read the LATCH, and correctly so ---
the defect they fence is a record existing for a gesture that never
began, so the record is the artifact, and an effect assertion would not
distinguish their mutations. The line now separates effect rows from
arming-gate rows and names P2's third case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
This commit is contained in:
Levi Neuwirth 2026-08-20 23:06:30 +02:00
parent 9028e1b172
commit 557ea6dfac
No known key found for this signature in database
2 changed files with 58 additions and 16 deletions

View File

@ -307,10 +307,21 @@ from #171 and #215 — the correction the 1b lane missed, honoured here.
carrying a target — stayed representable inside `editor.rs`. Now
`Refused` holds no target at all.
- **Witnesses: G5k(a)–(d), P1, P2, P3 both legs, P4, P5, P7, P8, P9,
P10, P11, P12.** Each reads a TARGET EFFECT — the child's byte
stream (**exact bytes**, not a count), the terminal drag state, the
document selection, or focus and controller ownership — never the
latch alone. Each bites its own mutation, including G5k's verbatim.
P10, P11, P12**, each biting its own mutation, including G5k's
verbatim. **They do NOT all read a target effect, and an earlier
version of this line said they did.** Two kinds:
- **Effect rows** — G5k(a)–(d), P1, P3 both legs, P4, P5, P7, P8,
P11, P12 — read the child's byte stream (**exact bytes**, not a
count), the terminal drag state, or the document selection.
- **Arming-gate rows** — **P9 and P10** — read the LATCH, and that
is correct for them: the defect they fence is a record existing
for a gesture that never began, so the record IS the artifact.
Manufacturing an effect assertion for them would not distinguish
their mutations.
**P2 is a third case**: its falsifiable claim is the
classification; its focus, controller and byte assertions are
defence in depth, because the precondition asserting `Refused`
fires first under the only mutation that would reach them.
- **Every fixture asserts its own precondition** (the disposition is
`Accepted`, or is `Refused`) because four rows in these rounds
passed vacuously: cells that were out of grid, or that clamped to

View File

@ -8520,6 +8520,16 @@ mod tests {
/// P2, effect half — a REFUSED press reaches no target at all.
///
/// **What is falsifiable here is the CLASSIFICATION.** Removing the
/// buffer check makes this press `Accepted`, and the row fails. The
/// focus, controller and byte assertions cannot fail under that
/// same mutation, because the precondition asserting `Refused`
/// fires first — and no other mutation reaches them, since the
/// daemon calls `apply_panel_pointer` only on `Accepted` and the
/// disposition enum gives `Refused` no target to apply. They are
/// **defence in depth against a future refactor**, kept and
/// labelled rather than presented as witnessed coverage.
///
/// §5b's four `g5_substrate_a_refused_*` rows read the latch and the
/// cancellation count; none of them reads the target. A refusal that
/// armed nothing while still sending the child a press, or starting
@ -8531,20 +8541,41 @@ mod tests {
terminal_panel_session(fid, true);
let press = pmacs_protocol::MouseKind::Down(pmacs_protocol::MouseButton::Left);
let none = pmacs_protocol::Modifiers::default();
let outside = {
let core = editor.core.borrow();
let grid = core.panel_grid_size(fid).expect("grid");
pmacs_protocol::CellCoord::new(grid.rows, 0)
};
// THE REFUSAL LEVER IS A WRONG BUFFER, at an IN-CONTENT cell.
//
// An out-of-grid cell cannot serve here: with the row bound
// removed it becomes `on_chrome`, so the press classifies
// `Consumed` and still reaches no target. The row would "bite"
// on its own precondition while never exercising focus at all.
// A foreign buffer at a content cell is the refusal whose
// mis-gating yields `Accepted`, which is the misclassification
// these assertions are written against.
let foreign_buffer = editor
.core
.borrow()
.registry
.borrow_mut()
.create("*not-the-panel*");
let in_content = pmacs_protocol::CellCoord::new(1, 2);
let key = crate::terminal::view::TerminalViewKey::new(fid, panel, buffer_id);
let active_before = editor.core.borrow().active_frontend;
// FOCUS is `views[&fid].active`, not `active_frontend`: the
// latter says which frontend is current, and `focus_window`
// moves the former. An earlier version of this row recorded the
// wrong one and would have watched a panel steal focus without
// noticing.
let focused_before = editor.core.borrow().views[&fid].active;
assert_ne!(
focused_before, panel,
"fixture: the panel must start PASSIVE, or 'focus did not \
move to the panel' asserts nothing"
);
let controller_before = editor
.terminal_manager
.borrow()
.controller_view_for_frontend(fid);
assert_eq!(
editor
.classify_panel_pointer(fid, buffer_id, outside, press)
.classify_panel_pointer(fid, foreign_buffer, in_content, press)
.outcome(),
crate::editor::PanelPointerOutcome::Refused,
"fixture: this press really is refused --- asserted, because \
@ -8557,8 +8588,8 @@ mod tests {
&mut render,
fid,
epochs,
buffer_id,
outside,
foreign_buffer,
in_content,
press,
none,
);
@ -8569,9 +8600,9 @@ mod tests {
receives is one it will expect a release for"
);
assert_eq!(
editor.core.borrow().active_frontend,
active_before,
"and it must not ACTIVATE the panel: a misclassified press \
editor.core.borrow().views[&fid].active,
focused_before,
"and it must not FOCUS the panel: a misclassified press
focuses before its out-of-range anchor fails, so byte and \
latch assertions alone stay green while focus has moved"
);