Keyboard resize rules in Rust: cmux-layout-reducer shown_resize over the app FFI, proven equal to Swift on a 3,203-case corpus (step A)

Merged
LA
1d ago
+5020-119

Summary

Move 2 of the swift-logic plan (lead order after 18:00Z; PL-motion-core did not take STATUS 12205): the keyboard resize rules of ShownResizeRange move to cmux-layout-reducer (shown_resize), called through cmux-layout-reducer-ffi (cmux_shown_resize_*). This is step A of the repo's two-step app FFI move (as #34982, #33660): the Rust rules, the C ABI and the parity proof land now; the app keeps calling the Swift rules until the CCmuxAppFFI release that carries the new symbols is pinned. Step B (branch swift-logic/shown-resize-range-ffi-switch, head b83c6bd8cfe8, ready) then switches Swift to the C calls and deletes the Swift rule copy.

Owner: PL-motion-core (pane geometry, OWNERS.md "Layout motion"); you may take this over.

What changes:

  • ShownResizeRange+Rules.swift: the five rules (ratioRule, columnWidthRule, dockWidthRule, tradeRule, rowHeightsRule) over the values they read from the geometry, the former method bodies with the reads replaced by inputs, same order of operations. ShownResizeRange.swift keeps its API and call sites, gathers the inputs and calls them; the trade's placement check (movesOnlyTheDivider, a ScreenGeometry.compute) stays in Swift. No behavior change.
  • ShownResizeRangeCorpusTests: a seeded corpus (3,203 inputs: 403 ratio, 300 width, 400 dock, 1,200 trade, 900 rows; each kind with at least 152 answers that move) and its answers recorded from the Swift rules on the fleet, floats as IEEE-754 bit patterns, in cmux-tui/crates/cmux-layout-reducer/tests/data/shown_resize_corpus.txt.
  • cmux-layout-reducer/src/shown_resize.rs: the rules in Rust, ported one operation at a time (Swift's min/max on a tie and NaN, rounded() as half away from zero, the column width through f32 as the daemon keeps it), with unit tests per rule.
  • cmux-layout-reducer-ffi/src/shown_resize.rs and the header: five typed C calls, no handle, no JSON, no allocation (catch_unwind, null checks, ERR_NULL/ERR_PANIC with nothing written).

Numbers

swift-logic-lines.py (swift_logic_lines):

  • base feat 2d102f877445: 415,764
  • this head (step A): 415,870 (+106: the split adds the gather code; the rules count until step B)
  • step B head b83c6bd8cfe8 (stacked, not in this PR): 415,581. The Swift rules become C calls; the table rows follow rule (c): ShownResizeRange+Rules PLATFORM (each rule one cmux_shown_resize_* call), ShownResizeRange MIXED 15 (its placement check stays Swift). -183 against the base; the row stays red (+363 at this base) because new feat code rose since 15:38Z.

Changelog

none

Observed / Not run

Observed (fleet):

  • Corpus recorded from the Swift rules: step 6f6123fc3742bbec3124c9f6 (aws-m4pro-3) at f0f3cd09a164 (branch fix/shown-resize-record-nomerge, this tree with record = true; never lands): recordCorpus passed; artifact sha256 5a487a0ca811, the committed fixture.
  • Swift parity at this head 9c0844ac2e97: step b6711b8b1458475196017b2f (aws-m4pro-8): ShownResizeRangeCorpusTests and all 17 KeyboardResize* suites, 46 tests, passed.
  • Rust at 4bc90e627348 (branch test/shown-resize-ffi-proof-never-merge: this head plus the FFI crate in the cmux-tui workspace, as the R-INPUT S1a proof did; never lands): cmux-tui-rust-check.sh test shown_resize step 2e06bda6c1cd76f246f6eda1: 15 of 15 passed, both corpus tests included (Rust and C calls, bit for bit); clippy step 2546fc85bfe70b8cbe220ea6: green; fmt step a7216178c64c: red only on base files (cmux-app-manifest, cmux-tui-core, cmux-tui link/sync_cli), none in this PR.
  • python3 scripts/cmux-next/prepush-gate.py: no new violations.

Not run:

  • No perf bench: ShownResizeRange has no // perf-hot mark and no row in perf-hot-benches.json; it runs once per resize key press, not per frame. The step B C calls do no allocation on the Rust side; the Swift side builds two small arrays per row press, as today.
  • The app compile of step B waits for the new CCmuxAppFFI pin (it imports the new symbols).

Display fleet run (gui-session-v1)

  • cmux-ci run --class light --display --script scripts/ci/package-test-lane.sh --arg suite --arg Packages/macOS/CmuxNext --arg <18 suites> --ref 9c0844ac2e973b88020c27b8582fda6008efc9ef (the command of S4's display step 538dccf3f6002506fb3b7549, with the suites that exist at this head): step 777a3be61b678960b38cbaef on cmux14.local, display worker, console session: "All 18 suites passed.", exit 0.
  • Suites (Swift Testing tests executed): KeyResizeCoalescedPressesKeepEveryStepTests 2, KeyResizeFirstTickPinTests 2, KeyResizeKeyTurnSurfaceTests 2, KeyResizeReduceMotionKeyTurnTests 1, KeyboardResizeArrowDirectionTests 20, KeyboardResizeContentHoldTests 2, KeyboardResizeFirstFrameTests 1, KeyboardResizeHoldLifetimeTests 4, KeyboardResizeHoldTakeoverTests 2, KeyboardResizeOneGridReportTests 2, KeyboardResizeReflowAfterLandingTests 2, KeyboardResizeRowsEdgeCasesTests 5, KeyboardResizeRowsFollowupTests 3, KeyboardResizeRowsPixelFloorTests 1, KeyboardResizeRowsTests 2, KeyboardResizeShownLimitTests 2, TerminalFrameOwnerMainThreadTests 1, TerminalSurfaceCommitSizeTests 5 (each N > 0; 59 in total).
  • An earlier display step, 16be4bd35823cbdf60ca1ff7, failed only on its filter: TerminalKeyResizeFrameTests exists on #35470's branch, not at this head, so it ran 0 tests and the execution guard failed it; its other two suites passed.