Repository navigation
cnx-ios: terminal fixes from the 2026-10-19 full verify (round 13) - #22387
azooz2003-bit wants to merge 25 commits into
Conversation
…one batch (r13 D1) Red on mini-cmux11s: TerminalOutputBurstTests 5 tests, 11 issues (the pacer feeds the first chunk of a burst alone). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A program that writes a row and then redraws its live area under it (Codex, stream20) reaches the phone as two chunks a fraction of a millisecond apart. The pump fed the first chunk at once and the second on the next display frame, so Ghostty drew one frame with the row and no live area: the page jumped a row and back (46 times in 66 s, keyboard up). The pump now waits until the output has been quiet for 3 ms, or the oldest chunk has waited 8 ms (a flood still goes once per frame). A backlog over the frame budget goes on the next frame without a new wait. -CnxNoBurstHold turns it off for A/B on the rig. Green on mini-cmux11s: TerminalOutputBurstTests + TerminalOutputQueueTests, 9 tests passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ffline state, stale input and TUI reattach (D2, D4, D5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… once when the Mac's host is back, honest offline state, never send stale input (D2, D4, D5) - LinkMachine: presence offline no longer closes a connected link; it is probed (1.5 s) and kept when it answers (T-LIFE-17). A presence frame for the linked Mac (its signaling socket back, e.g. hostd restarted) probes the link now instead of at the 15 s heartbeat, and ends a backoff (T-LIFE-12). A dead link to an offline Mac waits for presence. - Terminals show '<Mac> is offline' (pill: 'Mac offline') at once when presence says so, or after 4 s of no link; last frame kept (T-LIFE-13). - DaemonTerminalSession: typed keys wait at most 2 s for the terminal; older ones are dropped with an inputNotSent event, never sent at the reattach (T-INPUT-17). The composer keeps its text, marked not sent, while the terminal is not attached. - A reattach goes straight to the replay's alternate screen state: a TUI reattach no longer flips the page to the empty primary screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…poser says connecting vs reconnecting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… a close asks at once from programs read when the grid opened, or shows a pending question (D7) D6 (T-TABS-01): the active card was a snapshot taken once at grid open. While the grid is visible and not scrolling, TerminalCardLiveRefresh retakes a streaming page's card every 0.5 s (copied on the main thread, composed off it) and reads the Mac's screen every 1 s for a terminal whose page is off screen. D7 (T-TABS-08): the grid reads each terminal's process-info when it opens and every 2.5 s (TabProgramCache, 5 s max age). A close of a tab known to be busy asks at once; otherwise the Mac is asked and, after 250 ms with no answer, the question shows as pending and the answer fills it in or closes an idle shell. Tests: TerminalCardLiveRefreshTests, TerminalCardFresherTextTests, TabClosePromptPlanTests (mini-cmux11s, 30 tests green; red at the two test commits). iOS: xcodebuild -scheme CnxShell generic iOS Simulator BUILD SUCCEEDED. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… state before its rows (no guess at attach); deterministic tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed (r13 D3) The pill was the text view's edit menu: a tap on the focused, empty composer shows it, and its only item was AutoFill. Text traits do not control it (textContentType nil already). ComposerUITextView now removes the AutoFill menu in buildMenu. Red/green: verify/termqa/afprobe (a one-view simulator app with the composer's traits, tapped with axe): plain UITextView shows the pill, with the removal nothing shows (verify/termfix-r13/d3-autofill-before-after.png). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto feat-cnx-ios-termfix-r13
…l in flight (r13 D2b) Red on mini-cmux11s: macSignalingBackRestartsADialInFlight, 2 issues. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…13 D2b) After a cnx-hostd kill the host was back on signaling in 1.6 s, but the phone's redial had sent its offer while the host was down and waited out the 25 s dial timeout: the link came back 26.7 s after the kill. A presence frame for the linked Mac (sent only when its socket connects, closes or it is renamed) now abandons a dial in flight and dials again; the abandoned dial's late result is ignored by generation, and a link it still brings up is closed. Green on mini-cmux11s: LinkMachineTests + LinkControllerTests, 18 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…grid controls out of a page's accessibility tree, D7 T-TABS-14; Close All asks first) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…timing) The verifier's 5.59 s from + to a prompt included about 2.9 s between the + menu appearing (0.9 s in life-c-newtab.mp4) and the rig's New Terminal pick (about 3.85 s); pick to prompt was about 1.05 s in the recording. This line lets the next round split the Mac's part from the page's attach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… deadline (r13 D2b) Red on rbx: webrtc_dial_gives_up_on_an_unanswered_offer_at_its_answer_deadline gave up after 20.0 s (the whole dial's timeout). answer_timeout is added to DialOptions but not enforced yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (G-08, G-09) -CnxTermProbe turns on TerminalDevProbe for every terminal screen: - echo probe (M-ECHO): each printable byte sent is matched with its echo in the session output (TerminalEchoMatcher) and stamped at the first frame presented after Ghostty parsed it; samples go to Documents/termprobe/echo.jsonl and the termprobe log; - text export (M-INTEG): the Darwin notification dev.cmux.cnx.termprobe.export writes each open terminal's whole text (soft wraps joined) to Documents/termprobe/<title>.txt. verify/termqa/termprobe.py reads both (echo percentiles, export, crcgen check). Not compiled into Production. Green on mini-cmux11s: TerminalEchoMatcherTests, TerminalTextExportTests, TerminalScreenRowsTests (10 tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto feat-cnx-ios-termfix-r13
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Found 14 test failures on Blacksmith runners: Failures
...and 4 more test failures. View all on Blacksmith
|
…r13 D2b) An offer sent while the Mac's host was down or restarting is never answered; the dial waited out the whole 25 s dial timeout. The dial side now gives up 8 s after the offer without an answer (DialOptions. answer_timeout), so the phone's next dial reaches the restarted host. The Mac's answer side is unchanged. Green on rbx: cargo fmt --check, clippy --all-targets -D warnings, cargo test (loopback 20 passed incl. the new test; roaming 9 passed, its wireguard_roam_takes_a_fresh_turn_allocation, flaky once, passed 3/3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The screen logs 'replay done bytes=N ms=M' when a reset's replay is parsed; verify/termqa/sizelog.py counts resizes and resets by cause and replays from a simulator's unified log. Resize and reset lines already carry cause=. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Probably yours: CI failed on
Matched log linesNot re-run automatically: Written by
|
From the correctness review (subagent): - D5: input expiry is all-or-nothing and only for keys queued while the terminal was detached; after a drop, input is refused until the next attach, so the last 2 s of a command (mp\r of ls -la /tmp\r) can never run alone. Keys typed on a slow live link never expire. Keys still queued when the link drops are dated from when they were typed. noFragmentOfACommandRunsAfterAnOutage: red on the old session (3 issues), green now. - D5: a Send while a new tab's first attach is under way goes to the session's short hold instead of being refused. - D2b: a presence frame sends .macSignaled only when retarget() did not just dial, so a Mac back from offline gets one dial, not two. - D4: a first dial is called offline after 8 s instead of never (a redial after a lost link can last its whole timeout); the coordinator re-checks at that bound. - D1: the burst restarts when the queue drains on an alternate screen step; the wake work item runs main-actor isolated. - D6: an unchanged Mac screen text is re-dated without redrawing the card. - cnx-link: a dial that hits the answer deadline closes its peer connection. Green: mini-cmux11s 51 tests in 9 suites (DaemonTerminalSession, LinkMachine, LinkController, ComposerSendGate, TerminalOutputBurst, TerminalFeedPacerDrain, TerminalCardLiveRefresh, TerminalCardFresherText); rbx fmt, clippy -p cnx-link -D warnings, loopback 20 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Correctness review (fresh review subagent) and resolutionReviewed the diff 3e6a2b5..e6d43df read-only. Findings and what was done (fixes in 43c6ef8):
Checks after the fixes: mini-cmux11s |
Re-run: plain UITextView shows the AutoFill pill (1447 bright pixels in the band above the field), with the fix none (0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ectly Live re-run of the verifier's scenarios on 43c6ef8 (phone simulator and hidden Mac rig on mini-cmux11s, real WebRTC link): D1, D2, D3, D5, D6 and most of D7 fixed with numbers; D4 not verified (a second Mac on the account took the link; terminals' offline state follows the link's phase). Analyser json and scenario logs in verify/termfix-r13/live/. termprobe.py export armed its wait for the app's reply after posting the request and missed it; it now arms the waiter first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…3 D4, live rig) The live rig quit the Mac app with a second Mac online on the account: the link moved to that Mac and read connected, so the quit Mac's tab said Reattaching... for 60 s. Each terminal session now records its Mac; it is offline when the link's phase says so for the linked Mac, and at once when the link serves another Mac (LinkMachine.terminalOffline). Green on mini-cmux11s: CnxLiveTests 191 tests (incl. TerminalOfflinePerMacTests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Graceful Mac quit with stream20 running: 'Mac offline' at 0.45 s (was never), last frame kept, composer Send kept unsent, typed keys dropped with a notice, nothing ran after the relaunch, tab live 3.88 s after the launch call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Addendum to the review: the live rig found one more D4 gap after the review (offline state followed the single link, which had moved to the account's other Mac). Fixed in 64dbc81 (per-terminal Mac, |
Summary
Fixes the terminal defects the fresh verifier found on build 3e6a2b5 (
cnx-ios/verify/full-verify-terminal-20261019.mdonfeat-cnx-ios-fullverify-terminal), againstcnx-ios/verify/design/terminal/ACCEPTANCE.md.TerminalFeedPacer: a feed waits for 3 ms of quiet or 8 ms max (a flood still goes once per frame);-CnxNoBurstHoldfor A/BTerminalOutputBurstTests(11 issues → 6 pass),TerminalFeedPacerDrainTeststopvt-statesets the alternate screen before its rowsLinkMachineTests.presenceOfflineKeepsAConnectedLinkAndProbesIt,DaemonTerminalSessionTests.aReattachToATUIStaysOnTheAlternateScreenDialOptions.answer_timeout)macSignalingBackRestartsADialInFlight(2 issues → pass); Rustwebrtc_dial_gives_up_on_an_unanswered_offer_at_its_answer_deadline(20.0 s → < 4 s)ComposerUITextView.buildMenuremoves.autoFillverify/termqa/afprobesimulator probe: pill before, none after (verify/termfix-r13/d3-autofill-before-after.png)TerminalConnectionState.offlineper terminal's own Mac: at once when presence says offline or the link serves another Mac, after 4 s of failed dials (8 s for a first dial); last frame kept and readableterminalsShowOfflineWithinABoundedTime,aDroppedSessionShowsOfflineWhileTheMacIsGonestaleInputIsNeverSentAfterAReattach,noFragmentOfACommandRunsAfterAnOutage,ComposerSendGateTestsTerminalCardLiveRefreshTests,TerminalCardFresherTextTestsfeat-cmux-next-tabs-kit8ef7a76, byte-identical here)TabClosePromptPlanTests; TabsKit 55 tests; AX dumpsNot fixed in code: D7 New Terminal (5.6 s) and first grid→tab switch (0.76 s) — the recording attributes most of both to the rig's tap timing (pick → prompt ≈ 1.05 s); a
tabslog line now splits the Mac's create time. The grid "+" inner unlabeled button is a SwiftUI menu artifact; the menu itself is labeled.Rig tools added (DEBUG only):
-CnxTermProbereal-link echo probe (G-08) and text export (G-09) withverify/termqa/termprobe.py;replay done bytes= ms=sizing line andverify/termqa/sizelog.py(G-07).Coordination: the
feat-cnx-ios-redial-videoagent owns browser video after a redial and the Mac APP restart "[unknown surface N]" case; this PR only changes link and terminal reattach timing..offlinetouches the pill text andTerminalTabPage/GhosttyTerminalTabContentnear that work.Verification
-D warnings, all suites green.cnx-e2e-e6d43df7, both on mini-cmux11s because the laptop CoreSimulator was wedged; settings viaopen --envonly). Full table:cnx-ios/verify/termfix-r13/live-results.md.topBlocked or not scored: first grid→tab switch at the 0.15 s bar (needs an in-app timing log; no first-switch penalty seen), the grid "+" label (rig matches an inner SwiftUI button), two-host link latency.
Changelog
none
🤖 Generated with Claude Code