test(window): pin the cross-frontend exception, and fix two ledger counts

panel_commit_dedication_refusal matches on `fid` as well as on the
profile: a nested commit for a DIFFERENT frontend may dedicate that
frontend's own side slot, because resolve_placement consults only the
requesting frontend's panel_capable and its own one side window, so
nothing done to B can change where A's side request lands.

That promise was documented and unpinned. Both revision 9 nesting
tests drive a single frontend, so the comparison is trivially true
throughout them: deleting it, and making any outer "panel" contract
globally restrictive, passed the whole file.

a_nested_commit_for_another_frontend_may_dedicate_its_own_slot runs
two frontends. While an outer "panel" commit for A is in force, a
nested commit for B dedicates B's slot and is ALLOWED --- and B's
slot is asserted really dedicated afterwards, not merely unrefused.
The far side runs in the same test: A's slot stays undedicated and
A's result still lands in A's panel, so the row cannot pass by having
weakened the restriction generally.

This is the suite's only POSITIVE row; every other asserts a refusal,
which is the shape it was thinnest on. An exception only the doc
comment knows about is one review round from being simplified out.

Mutation-checked: deleting `&& contract.destination.frontend == fid`
fails ONLY this test. Both single-frontend nesting tests pass under
it, which is the evidence they are independent of the frontend match
rather than merely looking so. journey_acceptance (47),
dired_acceptance (31) and cargo test --lib (1920) stay green.

Two ledger corrections, both section-local:

* "Eight writes exist; five are reachable" then listed four. The
  fifth is quit_window's QuitAction::Restore --- the site proved
  unreachable and guarded anyway. It now appears in the list that
  justifies it, and the bullet counts what actually matters: all five
  are guarded.
* The revision 9 mutation paragraph had the preservation counts
  REVERSED (journey 31 / dired 47). It is journey 47 / dired 31,
  matching the bullet further up and measured per target. The same
  reversal is in 394fa43's commit message; that is left as written
  rather than rewriting a pushed commit, and the ledger now says so
  where the numbers are, so a reader following the SHA takes the
  corrected pair.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
This commit is contained in:
Levi Neuwirth 2026-08-09 21:28:30 +02:00
parent 5f3f38dfd7
commit 3b8e426f90
No known key found for this signature in database
3 changed files with 184 additions and 23 deletions

View File

@ -335,10 +335,15 @@ form:
`register_frontend_view` has callers only in `daemon.rs` and core `register_frontend_view` has callers only in `daemon.rs` and core
unit tests. unit tests.
- **Eight writes to `dedicated` exist** (`rg 'params\.dedicated\s*=' - **Eight writes to `dedicated` exist** (`rg 'params\.dedicated\s*='
src/`); **five are reachable**: `apply_placement`'s `Side` created / src/`); **four are reachable and a fifth is guarded defensively**
replacing / non-replacing arms, and `set_params`. Two `Ordinary` arms `apply_placement`'s `Side` created / replacing / non-replacing arms
are harmless (their target is never a side window; one only ever and `set_params` are the reachable four, and `quit_window`'s
clears the flag) and one is a unit test. `QuitAction::Restore` is the fifth, proved unreachable below and
guarded anyway. **All five are guarded**, which is the count that
matters; listing four under the word "five" is what an earlier version
of this bullet did. Two `Ordinary` arms are harmless (their target is
never a side window; one only ever clears the flag) and one is a unit
test.
- **The guards are sited where the property converges, not per caller.** - **The guards are sited where the property converges, not per caller.**
All three `Side` arms are reached through `apply_placement`, which has All three `Side` arms are reached through `apply_placement`, which has
**exactly one caller** — so one guard in `display_buffer` covers every **exactly one caller** — so one guard in `display_buffer` covers every
@ -383,10 +388,11 @@ authoritative tip** — the ref, not a SHA. Recover with
(`pmacs.window.capture_destination()`, the `ViewDestination` rename, (`pmacs.window.capture_destination()`, the `ViewDestination` rename,
the profile argument); `d5a6170` is the profile argument); `d5a6170` is
`tests/destination_capture_acceptance.rs`; `469d5c8` is the `tests/destination_capture_acceptance.rs`; `469d5c8` is the
revision-8 panel-profile correction plus the invalid-UTF-8 hole; the revision-8 panel-profile correction plus the invalid-UTF-8 hole;
commit below is revision 9's contract stack. **14 pins**, and both `394fa43` is revision 9's contract stack and the commit below adds its
preservation suites pass **unchanged** (journey 47, dired 31) — §7's cross-frontend pin. **15 pins**, and both preservation suites pass
stop signal not firing rather than being suppressed. **unchanged** (journey 47, dired 31) — §7's stop signal not firing
rather than being suppressed.
- **HOW THE PANEL PROFILE IS ENFORCED, in one sentence so no earlier - **HOW THE PANEL PROFILE IS ENFORCED, in one sentence so no earlier
revision gets reinstated by someone reading only that document:** the revision gets reinstated by someone reading only that document:** the
preflight stays exactly where it was, and the mutations that would preflight stays exactly where it was, and the mutations that would
@ -413,10 +419,17 @@ authoritative tip** — the ref, not a SHA. Recover with
so a nested scope rightly replaces them; a contract is a so a nested scope rightly replaces them; a contract is a
*restriction*, and replacing one suspends it. The guard stores a *restriction*, and replacing one suspends it. The guard stores a
depth and truncates back to it, so an inner exit removes exactly the depth and truncates back to it, so an inner exit removes exactly the
contract it added and leaves every enclosing one in force. Matching contract it added and leaves every enclosing one in force.
is per **frontend**: a nested commit for a different frontend may - **Matching is per FRONTEND as well as per profile, and that is a
dedicate *its* side slot, which cannot change where this frontend's deliberate exception with its own positive pin.** A nested commit for
side request lands. a different frontend may dedicate *its* side slot: `resolve_placement`
consults only the requesting frontend's `panel_capable` and its own
one side window, so nothing done to B can change where A's side
request lands. Pinned by
`a_nested_commit_for_another_frontend_may_dedicate_its_own_slot`,
which is the file's only row asserting that something is **allowed**
— every other asserts a refusal, and an exception only the doc
comment knows about is one review round from being simplified out.
- **Prohibiting nested `commit_to` was the other candidate and was - **Prohibiting nested `commit_to` was the other candidate and was
rejected.** It closes the hole by forbidding a construction no rule rejected.** It closes the hole by forbidding a construction no rule
objects to — `commit_to` is public Lua API for saying where a objects to — `commit_to` is public Lua API for saying where a
@ -516,17 +529,35 @@ authoritative tip** — the ref, not a SHA. Recover with
And reverting the byte comparison to `to_str()?` fails the And reverting the byte comparison to `to_str()?` fails the
`invalid utf-8` row with mlua's conversion error, on content. `invalid utf-8` row with mlua's conversion error, on content.
**Revision 9's, run across all three suites and the lib:** restore **Revision 9's two, each isolating a different half of the rule:**
`panel_commit_dedication_refusal` to reading only the innermost 1. restore `panel_commit_dedication_refusal` to reading only the
contract (`.last()`, which is exactly revision 8's swapped slot) → innermost contract (`.last()`, which is exactly revision 8's
**only** `a_nested_commit_cannot_mask_an_outer_panel_restriction` swapped slot) → **only**
fails. The other 13 pins, `journey_acceptance` (31), `a_nested_commit_cannot_mask_an_outer_panel_restriction` fails.
`dired_acceptance` (47) and `cargo test --lib` (1920) all stay green, Note the ordinary-nesting pin deliberately survives this — it
which is what makes the new test the pin for this defect and not a exists to fail the *other* candidate fix (prohibit nesting), so the
restatement of the depth-1 one. Note the ordinary-nesting pin two are a pair rather than one test written twice.
deliberately survives that mutation — it exists to fail the *other* 2. delete `&& contract.destination.frontend == fid` from the same
candidate fix (prohibit nesting), so the two are a pair rather than scan, making any outer `"panel"` contract **globally** restrictive
one test written twice. → **only**
`a_nested_commit_for_another_frontend_may_dedicate_its_own_slot`
fails. Both single-frontend nesting tests pass under it, which is
the evidence they are independent of the frontend match rather than
merely looking so; the cross-frontend exception had no pin at all
before this row, since every other test in the file drives one
frontend.
Both were run across all three acceptance suites and the lib: in each
case `journey_acceptance` (47), `dired_acceptance` (31) and
`cargo test --lib` (1920) stay green, along with every other pin in
this file.
**The counts above are journey 47 / dired 31**, matching the bullet
further up. The mutation paragraph committed at `394fa43` had them
**reversed** in both the ledger and that commit's message; the ledger
is corrected here and the message is left as written, since rewriting
a pushed commit is worse than a footnote. A reader following that SHA
should take these numbers, not those.
- **The public API #227 adopts against (Q#DC-5), pinned so it is a - **The public API #227 adopts against (Q#DC-5), pinned so it is a
contract rather than an intention:** contract rather than an intention:**
`pmacs.window.commit_to(dest, body [, profile])`. Profile is an `pmacs.window.commit_to(dest, body [, profile])`. Profile is an

View File

@ -719,6 +719,21 @@ incidental: no arguments is what keeps capture profile-blind.
force after the nested commit returns** (popped, not cleared), and force after the nested commit returns** (popped, not cleared), and
**outside every commit dedication is ordinary again**, so the fix **outside every commit dedication is ordinary again**, so the fix
leaked no permanent restriction onto the editor. leaked no permanent restriction onto the editor.
- **THE CROSS-FRONTEND EXCEPTION IS PINNED POSITIVELY**, over **two**
frontends: while an outer `"panel"` commit for A is in force, a nested
commit for **B** dedicates **B's** side slot and is **allowed** — and
B's slot is asserted really dedicated afterwards, not merely
unrefused. The far side runs in the same test: A's slot is still
undedicated and A's result still lands in A's panel, so this cannot
pass by having weakened the restriction generally. **This is the one
row asserting that something is permitted**; every other in the suite
asserts a refusal, and without it, deleting the `fid` comparison —
making any outer panel contract *globally* restrictive — passes the
whole file, because both nesting rows above drive a single frontend.
The exception is real and not a convenience: `resolve_placement`
consults only the requesting frontend's `panel_capable` and its own
one side window, so nothing done to B can change where A's side
request lands.
- **A `"panel"` commit that really lands in the panel still skips - **A `"panel"` commit that really lands in the panel still skips
checks 24** — otherwise the fix has quietly collapsed the two checks 24** — otherwise the fix has quietly collapsed the two
profiles into one and the parameterization buys nothing. profiles into one and the parameterization buys nothing.

View File

@ -1062,6 +1062,121 @@ fn an_ordinary_nested_commit_still_runs_and_restores_the_outer_restriction() {
); );
} }
/// **P** — the restriction is scoped to its **frontend**: a nested commit
/// for a *different* frontend may still dedicate that frontend's own side
/// slot (revision 9).
///
/// `panel_commit_dedication_refusal` scans every contract in force, but it
/// matches on `fid` as well as on the profile, and that comparison is a
/// deliberate exception rather than an oversight: frontend B's side slot
/// has no bearing on where **A's** side request lands. `resolve_placement`
/// consults only the requesting frontend's `panel_capable` and its own one
/// side window, so a contract for A cannot be invalidated by anything done
/// to B.
///
/// **This is a POSITIVE pin, which is the shape this suite is thinnest
/// on** — every other row asserts a refusal. Without it, deleting the
/// `fid` comparison and making any outer `"panel"` contract *globally*
/// restrictive passes the whole file: the two nesting tests above use one
/// frontend, so the comparison is trivially true throughout them. An
/// exception that only the doc comment knows about is one review round
/// away from being "simplified" out.
///
/// The far side is still asserted in the same run: A's slot stays
/// undedicated and A's commit still lands in A's panel, so this cannot
/// pass by having weakened the restriction generally.
///
/// *Mutation:* delete `&& contract.destination.frontend == fid` from
/// `panel_commit_dedication_refusal` and only this test fails.
#[test]
fn a_nested_commit_for_another_frontend_may_dedicate_its_own_slot() {
let s = editor();
// Frontend B: its own layout, its own undedicated panel, and a
// destination captured while it is the acting frontend.
attach_frontend(&s, COMPETITOR);
s.core.borrow_mut().active_frontend = COMPETITOR;
exec(
&s,
"pmacs.window.display(pmacs.buffer.create('*b-panel*'),
{ side = 'bottom', select = false })
dest_b = pmacs.window.capture_destination()",
);
let b_panel = s
.core
.borrow()
.side_window_for(COMPETITOR)
.expect("the competitor gets its own side slot");
assert!(
!dedicated(&s, b_panel),
"B's slot must start undedicated, or the row would prove nothing"
);
s.core.borrow_mut().active_frontend = FrontendId::LOCAL;
// Frontend A: an undedicated panel, so its `"panel"` commit takes the
// relaxed preflight and the restriction is really in force.
exec(&s, PANEL_ARRANGED);
let a_panel = s
.core
.borrow()
.side_window_for(FrontendId::LOCAL)
.expect("the arrangement creates A's side slot");
capture(&s);
let doc = local_window(&s);
exec(
&s,
"pmacs.window.switch_buffer(pmacs.buffer.create('*newer*'))",
);
commit_body(
&s,
Some("'panel'"),
&format!(
"b_ok, b_reason = pmacs.window.commit_to(dest_b, function()
pmacs.window.set_params(pmacs.window.panel(), {{ dedicated = true }})
end)
{PANEL_BODY}"
),
);
// 1. THE CROSS-FRONTEND DEDICATION IS ALLOWED.
assert_eq!(
raised(&s),
None,
"dedicating ANOTHER frontend's side slot must not be refused -- it cannot change \
where this frontend's side request lands"
);
assert!(
eval::<bool>(&s, "return b_ok == true"),
"the nested commit for B must be accepted: {}",
eval::<String>(&s, "return tostring(b_reason)")
);
assert!(
dedicated(&s, b_panel),
"B's slot must really be dedicated -- asserting only that nothing was refused \
would pass on a call that was silently dropped"
);
// 2. AND A'S RESTRICTION IS UNWEAKENED: its slot is untouched and its
// commit still lands in its own panel rather than falling back.
assert!(ok(&s), "A's commit must be accepted: {}", reason(&s));
assert!(
!dedicated(&s, a_panel),
"A's own slot must be untouched -- this row must not pass by having relaxed the \
restriction for everyone"
);
assert_eq!(
name_in(&s, a_panel),
"*result*",
"A's \"panel\" commit still belongs in A's panel"
);
assert_eq!(
name_in(&s, doc),
"*newer*",
"and A's newer document buffer must survive"
);
}
/// **P** — a `"panel"` commit that falls back with a **still-valid** /// **P** — a `"panel"` commit that falls back with a **still-valid**
/// destination lands in the document window, exactly as it does today. /// destination lands in the document window, exactly as it does today.
/// ///