Skip to content

Swift calls cmux-focus-core's focus rules; the Swift copies go (A12 step B, carried from #31835; R-INPUT S2) - #34685

Merged
lawrencecchen merged 15 commits into
feat-cmux-nextfrom
fix/r-input-s2-a12-focus-rules
Nov 4, 2026
Merged

lawrencecchen merged 15 commits into
feat-cmux-nextfrom
fix/r-input-s2-a12-focus-rules

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

#34641 and its re-pin (#34995) are on feat, so this can land. This is step B of the FFI two-step rule (STATUS 5388). It carries #31835 by @lawrencecchen, which REWRITE R-INPUT took over (lead decision, 2026-11-04; notice: #31835 (comment)). #31835 stays open for a person to close. The work is @lawrencecchen's: its commits are kept as they are, and each new commit credits him. It is the first PR of R-INPUT stage S2: one handle for focus and input.

Summary

The macOS app's focus rules leave Swift and are called from cmux-focus-core over the app FFI (rust-migration backlog A12; layer-ownership.md: Rust owns rules and input routing decisions). Step A (#31921) already landed the Rust half, and the app's pin (cmux-app-ffi-d3d3f420820f) already has every C function and reply field that this Swift half calls (checked against the pinned header: 18 functions, 30 CmuxFocusReply fields).

Swift (deleted, or a thin call) Rust
CmuxNextDesignTokens/CloseFocus/FocusAfterClose.swift tab, openerFamily, liveOpeners, workspace close_focus::{tab, opener_family, live_openers, workspace}
CmuxNextFocus/PaneCloseAim.swift close_aim::PaneCloseAim
CmuxNextFocus/OmnibarFocusMemory.swift omnibar_memory::OmnibarFocusMemory
CmuxNextFocus/InputInvariants.swift, InputInvariants+World.swift invariants::{model, transition, step, world, expected_responder}
FocusState+TypingTab.swift (typingTab), FocusState+GhosttyAgreement.swift FocusState::typing_tab (from the reply), Resolved::ghostty_mismatch

Behavior: no change, with the one difference #31835 named. Past its 64-tab bound, the address bar memory drops the oldest tab; the Swift Set.removeFirst() dropped one in hash order.

The feat merge (1721 commits) and why this waits for #34641

scripts/merge-main.sh --base feat-cmux-next (git 2.47) merged feat 44365e0. 0d4e198 records how each conflict was resolved:

Takes back #31265: the input invariants it moved into CmuxNextFocus (InputInvariants+World.swift, InputInvariants.swift) now run in cmux-focus-core. The Swift code becomes calls, which is the A12 move this PR carries.
Takes back #32769: its rule in InputInvariants+World.swift (a window waiting for another tab is unsettled) moves to the Rust world check in #34641, which lands first, and its FocusMachine and FocusState changes stay (ff7d600).

#31835's 12 red checks, compared with the base

All ran on its old head 151151d (2026-11-02):

  • cmux-next/compile, cmux-next fleet Release compile, cmux-next swift test, cmux-next fast tier, cmux-next generated files (shared build), cmux-next daemon tests (same-tree): its own. The Swift half called cmux_focus_pane_moved and cmux_focus_frame_presented, which its pin at that time (8b62425, from before step A landed) did not have. The pin on feat has them now, so the merge removes this cause. The new head's compile is on this PR's CI and the fleet.
  • cmux-next checks, part "Check the app FFI pin": its own (the branch carried the Rust half). Gone: cmux-tui equals feat.
  • risk evidence: its own: it took back base red: arch app_lines, move the input invariants out of CmuxNextApp into CmuxNextFocus (margin) #31265's change with no reason. The Takes back lines above clear it.
  • tooling-tests, nightly-guards / Guard status, nightly-guards / workflow-guard-tests / release-notary: base findings (test_download_prints_the_active_profile_only: "no ACTIVE profile named 'cmux NEXT Developer ID'").
  • next-autoland / verdict: a wrapper over the others.

Line accounting

python3 -I scripts/cmux-next/swift-logic-lines.py --repo . --rev REV --json:

Rev CmuxNextFocus logic / mirror CmuxNextDesignTokens logic / mirror
base 44365e0 519 / 378 1839 / 1936
head ff7d600 67 / 382 1839 / 1820
change -452 / +4 0 / -116

Tests

The Swift tests of these types became the Rust corpus in step A (cmux-tui/crates/cmux-focus-core/tests/focus_rules, filter ported::). OmnibarFocusMemoryTests and PaneCloseAimTests are deleted here, because their cases are in that corpus.

Fleet compile check at ff7d600 (cmux-ci compile-check --app --package CmuxNext, job 616c5c6bc8b330bcf99270d9): passed. CmuxNext, the app and cmux-tui are ok: true, with 0 errors. It compiles against the current pin, because every C call is already pinned; only the INVERSE-KEY world rule's behavior waits for #34641.

After #34641's re-pin (#34995, cmux-app-ffi-2e0b6acc3593) merged, this branch merged feat with it (3d46ef9, scripts/merge-main.sh, no conflict):

  • Fleet compile check at 3d46ef9 (cmux-ci compile-check --app --package CmuxNext, job ae88d00b33d75f1fc7ce369d): CmuxNext passed (375 s), the app passed (91 s).
  • The 11 Swift suites that exercise these rules, on a fleet Mac (step 2fd742f616994eca487f554b, aws-m4pro-1): all passed, 47 tests: FocusAfterCloseOpenerTests 10, BrowserTabOpenersCloseFocusTests 5, GhosttyFocusAgreementTests 2, ChromiumPageFocusInvariantTests 2, FocusWaitLeavesPageTests 2, CloseTabKeepsPaneTests 5, CmdWEmptiedSplitPaneLeavesInItsTurnTests 4, ClosedPendingSplitFocusTests 2, RapidCloseTabTests 2, OmnibarFocusParityTests 9, OmnibarFocusClickSelectionTests 4. The step ran without a display.
  • The four suites that read typingTab (the reviewer asked for them), step 6e31c3cebe1932c775e178aa on aws-m4pro-8: all passed, 23 tests: CreationInputHoldTests 11, HomePendingTerminalFocusTests 4, CmdNThenCreateKeysTests 2, CloseThenTypeKeysTests 6.
  • Independent review: SHIP at 3d46ef9 (Swift calls cmux-focus-core's focus rules; the Swift copies go (A12 step B, carried from #31835; R-INPUT S2) #34685 (comment)). Its non-blocking points: FocusMachine.swift is 477 lines (cap 400, warn ceiling 480), so the four close-aim calls move to FocusMachine+CloseAim.swift in a follow-up; a wire-shape mismatch would make the debug world check report every window unsettled without a reason (the pin check prevents a mismatch).

Observed / Not run

Changelog

none

No capture: no visible change; the focus rules move from Swift to Rust with the same behavior.

Co-authored-by: Lawrence Chen 54008264+lawrencecchen@users.noreply.github.com

lawrencecchen and others added 14 commits November 2, 2026 04:37
…t rules (failing)

cmux-focus-core gets the home of the focus rules the macOS app keeps in
Swift beside it (rust-migration backlog A12), with their Swift tests
ported as the Rust corpus (tests/focus_rules, filter `ported::`):

- close successors of every kind (FocusAfterClose): the opener tests
  (FocusAfterCloseOpenerTests), the exhaustive model check of the deleted
  FocusAfterCloseModelCheckTests (panes both policies with its 7 mutants,
  tabs with its 2 mutants, workspaces), and the focus cases of
  closefocus.tla (the strip, strip-recent and list configurations with
  SuccessorRule, C1-C3, and its "history" mutant);
- the Close Tab aim (PaneCloseAimTests);
- the per-tab address bar memory (OmnibarFocusMemoryTests);
- the input invariants (ChromiumPageFocusInvariantTests, plus one case per
  F, T and W rule and the app's InputObservation JSON).

The pane rule is generic over the id type now (the model check runs it on
integers); its behavior does not change and its cases pass. The tab,
workspace and opener rules, the aim, the memory, the invariants, the
Ghostty check, the typing tab and the closeFocus config parse are stubs
here: their tests fail until the rules move in the next commit.
…cklog A12)

The rules of the macOS app's Swift focus copies, moved as they are, with
one rule set beside the existing pane rule:

- close_focus: the tab successor (opener family first in Chrome's order,
  then next-else-previous shown tab), live opener relations (Chrome's
  FixOpeners) and the workspace successor (drawn row orders first), from
  CmuxNextDesignTokens FocusAfterClose; generic over the id type.
- close_aim: PaneCloseAim, which pane a Close Tab press is aimed at after
  a close emptied a pane (presented frame and key repeat decide).
- omnibar_memory: OmnibarFocusMemory, Chrome's per-tab address bar focus.
  One refinement: past the 64-tab bound the oldest tab goes; the Swift Set
  dropped an arbitrary one (hash order).
- invariants: InputInvariants' model (F), transition (T) and world (W)
  checks over the app's FocusState read view and InputObservation JSON
  shapes, the expected responder table, and debug.focus's Ghostty check.
  Violation details are diagnostics; the invariant ids and windows are the
  Swift ones.
- state: Resolved pane/tab/kind/isTextInput, FocusState typing_tab and
  terminal_tab (FocusState+TypingTab), CloseFocusPolicy::from_config_value.
- wire: JSON requests for focus_input_world, focus_input_step and
  focus_debug_window.

No behavior change; the Swift copies go in PR 2, after the app FFI re-pin.
…lose and per press)

- cmux_close_focus_tab, cmux_close_focus_workspace and
  cmux_close_focus_live_openers: the close successors over the caller's
  u32 ids, one typed call per close, no handle and no JSON.
- The window focus handle keeps the Close Tab aim (cmux_focus_pane_moved,
  cmux_focus_frame_presented, cmux_focus_pane_emptied,
  cmux_focus_aims_at_emptied_pane) and the address bar memory, which it
  notes on every reduction: the reply's former reserved bytes are
  omnibar_return and returns_to_omnibar (the layout is unchanged), and a
  typing_tab string follows the reply's last field.
- cmux_layout_reducer_json answers focus_input_world, focus_input_step and
  focus_debug_window for the debug monitor, debug.focus and the journal
  replay.

cmux-app-ffi links this crate already, so the next CCmuxAppFFI release
carries the calls; the Swift copies call them in PR 2. The C ABI test
(tests/close_focus_rules.rs) drives each call.
… check

debug.focus's Ghostty check (FocusState.Resolved.ghosttyMismatch) moved
into cmux-focus-core in the previous commits; its Swift test, with the
same texts for each case, is now part of the ported corpus.
The transition arms fold their condition into the match guard (each falls
to the no-op arm, as before), and the Ghostty check picks the key window's
terminal first, then branches: the same rules, clippy -D warnings clean.
… copies go (backlog A12)

The Swift half of the move. It needs CCmuxAppFFI re-pinned to a release
built with this branch's Rust (the pre-merge FFI release, STATUS 5013):
the calls below are not in the pinned release, so it does not compile
against the pin yet.

- FocusAfterClose (tab, liveOpeners, workspace) numbers the caller's ids
  and calls cmux_close_focus_*; the Swift rules, neighbor, resolve and
  openerFamily are gone. Callers are unchanged.
- PaneCloseAim forwards to the window focus machine (cmux_focus_pane_moved
  and siblings); its state and rule are the machine's. PaneCloseAim.Press
  keeps its shape (TabCloseGuard builds it).
- OmnibarFocusMemory is deleted: the machine notes every reduction, and
  FocusCoordinator reads the reply's omnibarReturn and returnsToOmnibar.
- InputInvariants' model, transition and world checks and the expected
  responder table are deleted; reduction, world, expectedResponder and
  debugWindow call focus_input_step, focus_input_world and
  focus_debug_window. A refused call fails loud in debug builds
  (assertionFailure); world then reports every window unsettled.
- FocusState.typingTab is the reply's typing_tab; the Ghostty check calls
  the machine's rule.

Swift tests: PaneCloseAimTests and OmnibarFocusMemoryTests are deleted
(their rules moved; the cases are cmux-focus-core's ported:: corpus).
FocusAfterCloseOpenerTests, GhosttyFocusAgreementTests,
ChromiumPageFocusInvariantTests, CloseTabKeepsPaneTests,
PaneCloseControllerTests and BrowserTabOpenersCloseFocusTests stay and
now run the Rust rules.
…rted:: filter

One test-name filter (ported::) now selects the crate's ported rule tests
and their C ABI tests, so one fleet step proves both.
contains_key instead of get().is_some(), and the mutant builder's closure
type (the pane rule's own signature) is allowed as complex.
… tests used

The app's settings layer parses layout.closeFocus (CloseFocusSetting,
CloseFocusPolicy.init(configValue:)), like its other settings; the Rust
copy had no caller. The settings parse moves with the settings (backlog D).
swift-logic-classes.tsv: the rows of the deleted rules (InputInvariants+World,
OmnibarFocusMemory) go; FocusAfterClose, PaneCloseAim, InputInvariants and the
Ghostty check are thin FFI glue now (PLATFORM), and the new IDNumbering glue
has its row. FocusEvent.Responder.pane had no caller left and is deleted.
…s over #31835)

The branch was 1721 feat commits behind (its last base merge: b6b550e).
Conflicts, resolved this way:
- The six Rust paths (cmux-focus-core lib.rs, wire.rs,
  tests/focus_rules/ported/input_invariants.rs; cmux-layout-reducer-ffi lib.rs,
  include/cmux_layout_reducer_ffi.h, tests/close_focus_rules.rs): feat's side.
  Step A (#31921, 80d716d) already landed every Rust change of this branch,
  and feat has moved on since then (agent cursor visibility, the scroll and
  hover reducers, the R-INPUT router), so cmux-tui now equals feat's tree.
- FocusState+TypingTab.swift: the branch drops the computed `typingTab` (now
  `FocusState.typingTab`, the Rust machine's rule from its reply). Feat's
  `awaitableContent` (REOPEN-F4) and `awaitsOtherTab` (P0 INVERSE-KEY) stay.
- InputInvariants+World.swift: deleted, as the branch intends; the world
  checks run in cmux-focus-core. INVERSE-KEY's rule in that file ("a window
  whose focus is on its way to another tab is unsettled", 5fe33a3) is not
  in the Rust world check yet: it moves into cmux-focus-core in #34641 (A12
  step A of the FFI two-step rule), which lands and is re-pinned before this
  Swift half lands.

Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
…changed, effects, omnibar flags)

A semantic conflict of the feat merge: the A12 move widened
FocusMachine.send's result to Reduction (changed, effects, omnibarReturn,
returnsToOmnibar), and P0 INVERSE-KEY (5fe33a3) added
reapplyingOnWaitChange, which took and returned the old (changed, effects)
pair. It now takes and returns a Reduction: on a wait change with no
responder move it marks the reduction changed and appends the
moveResponder, as before, and the omnibar flags pass through unchanged.

Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
Merge-main commit by scripts/merge-main.sh.
Merged by scripts/merge-main.sh: origin/feat-cmux-next at 4a17e97.

Merge-main-previous-head: ff7d600
Merge-main-base: 4a17e97
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 3d46ef9: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr34685 -f ref=fix/r-input-s2-a12-focus-rules -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Base-red classifier (per test) (+1 more) is not red on the base 4a17e97; do not merge until green; see lane-rules

Shipped in:

@blacksmith-sh

blacksmith-sh Bot commented Nov 4, 2026

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpqqe8_6ph/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpx6mux49x/summary-missing.json (live):/summary-missing.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Review (independent subagent, correctness first): SHIP at 3d46ef9
perf claim: none
R9: pass

Scope: the PR's own diff against its merge base 4a17e97 (18 files, +293/-709, no Rust file), the merge 3d46ef9, ff7d600 against 5fe33a3 and fc12029, the fleet evidence and the checks on this head. Read only. I did not build or run anything.

Behavior equality (Swift copy against cmux-focus-core)

I compared each deleted or thinned Swift rule with its Rust rule, branch by branch. I found no rule that the Swift copy had and Rust does not have.

  • FocusAfterClose: tab, opener_family, live_openers, workspace and neighbor in close_focus.rs match the deleted Swift line for line. IDNumbering maps nil and out-of-range answers to nil (UInt32.max is the wire's "none"). The deleted neighbor, resolve and openerFamily have no Swift callers left.
  • PaneCloseAim: close_aim.rs pane_moved, presented, pane_emptied and aims_at_emptied_pane match the deleted Swift: the hold, the repeat rule, focused == pane, the from/to filter, and presented_at against press.time. The machine's pane equals the old reduced.pane at each call: paneMoved runs in the drain's defer, and aimsAtEmptiedPane runs reducePendingTopologies() first, as currentState() did. Every caller goes through FocusCoordinator (TabLifecycle.swift:398 included).
  • OmnibarFocusMemory: the Rust is_return events are the same 7 (SelectTab, FocusPane, Topology, Expect, DragEnded, OverlayClosed, WindowKey). The return event is the same (FocusTarget AddressBar Programmatic). set_topology notes the reduction as a return path. take_return runs before the reduction and note after it, as in the coordinator loop before. One change: past 64 tabs, the oldest tab goes (the Swift Set.removeFirst() took one in hash order). The PR body discloses it. It is an improvement.
  • typingTab: Rust FocusState::typing_tab is the old computed rule (the expectation's tab, else the terminal tab). read() refreshes state.typingTab only when changed != 0 || ok == 0. That is safe: the FFI Summary compares the expectation and derived (resolved included), so changed is 1 whenever an input of typing_tab changes. restore() reads cmux_focus_current, which writes changed 1. No code reads typingTab from a state that the machine did not fill. CreationInputCoordinator.swift:301 edits a local copy for a key context only and does not read typingTab.
  • InputInvariants: Rust model, transition, content, expected_responder, key_window (W5: every branch and detail string), overlays (W6), context (W7) and world match the deleted Swift, including the top-page skip and the P0 INVERSE-KEY rule (a window whose focus waits for another tab is unsettled, is_settled). +Routing.step is now reduction (Rust model(new) + transition) + routing, the same sum as before. The base did not emit F8 either.
  • Wire shapes: the Rust Invariant serde names (F1-F6, T1-T3, W1-W8) all exist as Swift InputInvariant raw values. Violation is {invariant, window?, detail} on both sides. The Swift synthesized Codable shapes of FocusEvent (every case), Responder, DragOutcome, Expectation, Target, Resolved, Overlay, FocusTopology and KeyWindow match the Rust serde shapes. Rust uses no deny_unknown_fields, so the extra Swift fields (typingTab, appActive, isDragging and others) do no harm. DebugRequest and DebugWindow match DebugWindowRequest and DebugWindowResponse. The FFI test the_invariant_operations_answer_in_the_apps_shapes pins all three operations.
  • GhosttyAgreement: Resolved::ghostty_mismatch gives the same two strings. GhosttyFocusAgreementTests passed on the fleet.

ff7d600 against 5fe33a3 and fc12029

  • 5fe33a3: reapplyingOnWaitChange has the same rule (no moveResponder yet and awaitsOtherTab changed: changed true, add moveResponder(state.resolved)). The new version keeps omnibarReturn and returnsToOmnibar from the result. waited is still read before read() updates the state. The topology path calls no re-apply, as before. A queued address bar return cannot change awaitsOtherTab (a programmatic focusTarget changes neither the tab nor the expectation), so the omnibar flags and the re-apply do not interact.
  • fc12029 does not touch FocusMachine.swift. Its FocusEvent.isPersonsOwn and FocusCoordinator.personIntents (FocusCoordinator.swift:68 and :81) are intact. Its typingTab read at the capture site now gets the stored value, which follows the same rule.

The merge 3d46ef9

It is clean. Only plans/cmux-next/swift-logic-classes.tsv changed on both sides, and the hunks do not overlap. An automatic re-merge gives the same blob. There is no evil merge: the patch-ids of both sides match. The other 17 files equal ff7d600. I also merged this head into the current feat tip aeca627 with git merge-tree: no conflict.

Evidence

  • Compile check ae88d00b33d75f1fc7ce369d at the exact head: CmuxNext ok (374.8 s), app ok (91.2 s), cmux-tui ok.
  • Suites step 2fd742f616994eca487f554b on aws-m4pro-1 at the exact head: all 11 suites passed, 47 tests, 0 failures. The per-suite counts match the PR body.
  • Perf: no A/B is necessary. frame_presented runs once for each move of the focused pane (FocusCoordinator.swift:93 guard, then paneMoved, then a one-shot CommitBoundary().after with no repeat). It never runs per frame, and Rust ignores a stale or second stamp. The typed C calls run where the Swift code ran (per close, per Close Tab press, per pane move). JSON runs only in debug tooling (the DEBUG monitor 200 ms after input stops, debug.focus, debug.desync, journal replay). For each reduction, the Swift omnibar set work goes, and one optional string decode comes in, only when the reply changed. The key path now reads typingTab as a stored property. The diff touches no perf-hot function. The PR makes no perf claim, so R10 needs no measurement.

Reds on this head

  • cmux-next checks (god files, concurrency, crash safety, l10n): base finding. Its two failing parts are "No fleet host names in gallery fixtures" (webviews/src/agent-session/acpmux/subagents/SubagentTray.gallery.ts:168) and "Base-red classifier (per test)" (tests/test_base_red_excuse.py refuses the if of job portable-placement in .github/workflows/ci-guards.yml). The PR touches neither file. The same two parts fail on the feat-cmux-next push run at 8281fc7 (job 126468750915). The warn-only parts are scrollbars (files outside this PR) and the god-file warning for FocusMachine.swift (nit 1 below).
  • cmux-next fast tier and cmux-next swift test: pending. They do not hold the PR.
  • On the feat tip only: "Check the app FFI pin" is red from R-INPUT S2a: the input router reduces each window's focus as the app's focus handle does (WindowFocus), Rust only #34929 (358a445, Rust-only S2a, waiting for its re-pin). It is not this PR's red. R-INPUT S2a: the input router reduces each window's focus as the app's focus handle does (WindowFocus), Rust only #34929 changes no header, no extern function and no repr(C) field. After the merge, the FFI still fills omnibar_return, returns_to_omnibar and typing_tab, so this Swift half stays valid on the current pin and after the re-pin.

Credit

The 14 commits from #31835 keep lawrencecchen as author (151151d is a cmux-bot merge). The new authored commits 0d4e198 and ff7d600 carry Co-authored-by with his commit email. 3d46ef9 is a merge-main merge with its trailers. #31835 is OPEN. The PR body has the Takes back lines for #31265 and #32769, ### Observed / Not run, ## Changelog none, and a No capture: line. risk:normal is the correct tier.

Nits (none blocks)

  1. FocusMachine.swift grows from 440 to 477 lines (Swift cap 400). The CI god-file step warns, and the file is now 3 lines below the hard ceiling of 480 (slack 20). Fix: move the four close-aim C calls (paneMoved, framePresented, paneEmptied, aimsAtEmptiedPane) into FocusMachine+CloseAim.swift, with handle made internal, or into PaneCloseAim.swift.
  2. Evidence gap: the suites step did not run the creation-hold suites that read typingTab (CreationInputHoldTests, HomePendingTerminalFocusTests, CmdNThenCreateKeysTests, CloseThenTypeKeysTests). The code reading above shows the same behavior. One fleet run of them at this head closes the gap. The pending cmux-next swift test can also cover them.
  3. On an FFI wire mismatch, InputInvariants.world reports every window unsettled. In DEBUG, assertionFailure stops first. A release debug.desync call shows only "unsettled", with no cause. The pin check prevents a mismatch, so this is acceptable. Optional: name the refusal in the result.
  4. The PR is still a draft. Mark it ready before you add ready-to-land.

@lawrencecchen
lawrencecchen marked this pull request as ready for review November 4, 2026 08:47
@cursor

cursor Bot commented Nov 4, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

REWRITE R-INPUT: the red parts of cmux-next checks on head 3d46ef9 are base findings, in files this PR does not touch:

Independent review: SHIP at 3d46ef9 (#34685 (comment)). The 11 focus suites (step 2fd742f616994eca487f554b) and the 4 typingTab suites (step 6e31c3cebe1932c775e178aa) passed on the fleet; the compile check (job ae88d00b33d75f1fc7ce369d) passed.

@lawrencecchen lawrencecchen added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Nov 4, 2026
@lawrencecchen
lawrencecchen merged commit 4bbfb56 into feat-cmux-next Nov 4, 2026
307 of 322 checks passed
@lawrencecchen
lawrencecchen deleted the fix/r-input-s2-a12-focus-rules branch November 4, 2026 09:21

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 3d46ef93 Deployed Nov 4, 2026 by lawrencecchen via namespace autofix #14181
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant