Skip to content

cnx-ios: after a redial the shown browser tab keeps its video; terminals follow a Mac restart - #22419

Closed
azooz2003-bit wants to merge 19 commits into
feat-cnx-ios-hybrid-linkfrom
feat-cnx-ios-redial-video
Closed

azooz2003-bit wants to merge 19 commits into
feat-cnx-ios-hybrid-linkfrom
feat-cnx-ios-redial-video

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes the redial defects a fresh verifier found (cnx-ios/verify/transport-verify-20261019.md on feat-cnx-ios-transportverify), on top of the hybrid link (#22337).

What changed

  • Defect 7 (high): the browser tab you're looking at keeps its video after a transport switch or a cnx-hostd restart.
    • The phone reopens only the tab on screen. Hidden tabs open when they are shown.
    • Tabs of workspaces closed on the Mac are dropped when the Mac's workspace list arrives.
    • The tab on screen tells the Mac with rb.visibility. cnx-hostd gives it back the media lane, starting at a keyframe. This works on WireGuard RTP, the WebRTC media session (hybrid) and WebRTC-only.
    • cnx-hostd's host limit now stops idle hosts first, then hidden tabs, then the tab on screen. It closes the stopped tab with evicted instead of replaced.
    • A page cnx-hostd stopped reopens at its current address. It does this twice at most, then shows a Reopen button.
    • New browser workspaces keep their page when the Mac assigns the real tab id.
  • Defect 2 (medium): a terminal reattach looks up its terminal by terminal_id with resolve-terminal before it attaches. If the Mac's daemon restarted, the surface number has changed and the reattach follows it.
    • If the Mac no longer has the terminal, the terminal says so in one line.
    • A terminal the daemon is still restoring is retried.
    • When retries run out, the terminal says so, and the next keystroke tries again.
  • Defect 4 (low): Settings shows "UDP blocked" only for WireGuard.

Details, tests and live numbers: cnx-ios/verify/redial-video.md. Contract: PROTOCOL.md browser.

Tests

  • The failing tests were committed before the fixes.
  • Swift on mini-cmux11s: CnxLive, CnxBrowserStream, CnxModel, CnxTransport, CnxShell and CnxWorkspaces, 426 tests passing.
  • Rust on rbx: cargo test --workspace and clippy -D warnings, both green.
    • The new lane tests fail without the fix on all three carriers and pass with it.

Review

Two fresh review subagents checked correctness: one after the first fix, one after the live fixes. Every finding and how it was handled is in redial-video.md. Two items are still open:

  • The shown tab's rb.visibility reminder and a hidden tab's open travel on different channels, so they can arrive at hostd out of order. Fixing this needs visibility inside rb.open, which is a hostd change.
  • A renamed placeholder's Mac host stays until the host limit stops it.

Live check (real link, mini-cmuxs-mac-mini-3)

The phone opens two browser workspaces, the Mac closes one, and the other stays on screen. Then cnx-hostd is killed, or the transport is switched in Settings. This ran on WireGuard-only, hybrid and WebRTC-only.

  • Every row came back on the right carrier: wg-rtp on WireGuard-only, track on hybrid and WebRTC-only.
  • The overlay showed 25 to 48 fps, and the bench measured 27 to 33 fps with glass-to-glass p50 of 60 to 82 ms.
  • After each event hostd saw one browser open (the verifier saw 3 to 5) and stopped no host.

Terminal: the Mac app was quit, killed, and killed together with its daemon (surfaces renumbered from 269 to 394). Each time, a command typed on the phone reached the same terminal, with no [unknown surface].

Several bugs were found and fixed during the live check:

  • A page reopened after a cnx-hostd restart came back blank.
  • A page stayed hidden on the Mac after the next link opened it.
  • A new browser workspace lost its page when the Mac named the tab.
  • A page could be marked hidden while it was on screen.
  • resolve-terminal answered terminal_not_found for a moment after a Mac app restart, which ended a live terminal.

Changelog

none (cnx-ios is unreleased)

🤖 Generated with Claude Code

azooz2003-bit and others added 15 commits October 19, 2026 22:37
transport-verify-20261019.md defects 7 and 4: only the shown tab reopens
after a redial, closed workspaces' tabs are dropped, the shown tab takes
the media lane back (WireGuard RTP, media session, WebRTC), the host limit
stops hidden tabs first and says evicted, and Block UDP is not shown for
WebRTC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
transport-verify-20261019.md defect 7 (high) and 4 (low).

- Phone: on a new link only the shown tab opens again; hidden tabs open
  when shown. Tabs the Mac no longer lists are dropped when the tree
  arrives. The shown state goes to the Mac as rb.visibility. A page the
  Mac stopped (evicted) reopens at its current address while shown (twice,
  then a Reopen button); one another viewer took offers Reopen.
- cnx-hostd: rb.visibility true takes the media lane back for the shown
  tab (fresh track bridge, keyframe), on WireGuard RTP, the media session
  and WebRTC alike. The host limit stops idle, then hidden, then shown
  hosts, and says evicted instead of replaced.
- cnx-ffi: a tab whose video came on the channel restarts its lane frames
  at a keyframe.
- Settings: Block UDP is shown only for WireGuard (WebRTC ignores it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s surfaces

transport-verify-20261019.md defect 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…enumbers surfaces

transport-verify-20261019.md defect 2 (medium). A Mac daemon that
restarted numbers its surfaces again, so the phone's open terminal kept
asking for its old number ('[unknown surface 15]', stuck Reattaching).
A reattach now asks resolve-terminal for the terminal's surface first and
follows it; a terminal the Mac no longer has ends with a clear line; a
reattach that ran out of retries says so and the next keystroke tries
again. Sessions whose terminal moved to another surface reattach on a new
link. Older daemons without resolve-terminal attach by number as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shown tab's stream also opens when the app becomes active (a link
that came up in the background). Adds verify/e2e/redial_video.py (browser
kill/switch rows with a workspace closed on the Mac, and Mac app restart
with an open terminal) on the verifier's transport_verify.py rig.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…redial-video.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d, restoring terminals waited for

- A hidden page does not open on layout; a stream that opened hidden makes
  the shown tab say rb.visibility true again (it takes the lane back).
- The reopen count is forgiven only after 20 s live, so two viewers
  evicting each other stop after two rounds.
- A reopen at the page's current address only after the Mac stopped the
  page; otherwise the tab's own address (a tab id reused after a restart).
- resolve-terminal with a null surface (daemon still adopting) retries
  instead of ending the terminal; a reattach that gave up shows no spinner
  and restarts its backoff from the shortest delay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or typing on the phone)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t too

Live check: a hostd kill stops every browser host; reopening at the tab's
first address showed a blank page. The current address goes on every
reopen (the tab-id-reuse case after a daemon restart stays open).
Rig: every row relaunches the phone with its environment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live check (switch row): the page hidden when the person left for
Settings stayed hidden under the next link's viewer (the host keeps the
last rb.visibility), so the reopened tab showed a blank page at 2 fps.
Every stream now sends its visibility right after rb.open.
Rig: terminal 'daemon' row kills the app and its daemon (surfaces renumbered).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live check (switch row): a browser workspace made on the phone streams
under its placeholder tab id (new-<id>-t1); once the Mac confirms, the
tab is s<N>, and the redial opened s<N>'s own blank host. The creation now
reports the placeholder-to-real tab, and the streamed model moves to it
(the open stream keeps going; the next open uses the real id at the
page's current address).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live check: reopening under the real tab id started a new host whose
page was blank (the model's address had followed an about:blank report).
The phone finds the page under the real id, and it reopens the same host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e page's Back); drop noisy logs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@blacksmith-sh

blacksmith-sh Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Found 14 test failures on Blacksmith runners:

Failures

Test View Logs
cnx-ios-testflight.yml job testflight never runs scripts/
select-ci-xcode.sh, so it builds with the image's default Xcode
View Logs
GitHub-hosted runner label: .github/workflows/
pr-red-checks-comment.yml:16: runs-on: ubuntu-24.04
View Logs
GitHub-hosted runner label: .github/workflows/
pr-red-checks-comment.yml:16: runs-on: ubuntu-24.04
View Logs
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='cmux-scheme-compile')/
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='cmux-scheme-compile')
View Logs
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='daemon-test')/
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='daemon-test')
View Logs
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='generated-files')/
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='generated-files')
View Logs
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='release-compile')/
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='release-compile')
View Logs
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='swift-test')/
test_every_mac_job_reads_the_placement (main.CmuxNextWiring.test_every_mac_job_read
s_the_placement) (job='swift-test')
View Logs
test_every_shadow_job_is_compare_only (main.ShadowJobTests.test_every_shadow_job_is
_compare_only) (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-runtime-x86_64')
/test_every_shadow_job_is_compare_only (main.ShadowJobTests.test_every_shadow_job_i
s_compare_only) (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-runtime-x86_64'
)
View Logs
test_every_shadow_job_is_compare_only (main.ShadowJobTests.test_every_shadow_job_is
_compare_only) (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-shadow')/
test_every_shadow_job_is_compare_only (main.ShadowJobTests.test_every_shadow_job_is
_compare_only) (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-shadow')
View Logs

...and 4 more test failures. View all on Blacksmith

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

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

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

Probably yours: CI fast guards failed: a guard step failed, FAIL 0.2s workflow-guard-tests / ci: Validate macOS jobs select a pinned Xcode.

CI failed on 28dc1a66b7 (run 39402321318 attempt 1): 3 code, 5 unknown.
macOS jobs did not run: compile and app tests were skipped: Fast static checks failure.

Job Verdict Why
CI fast guards code a guard step failed
Fast static checks code a static check failed
guards / workflow-guard-history unknown no known signature; failed step: Validate SwiftPM lockfile policy
guards / workflow-guard-tests / release-tooling unknown no known signature; failed step: Validate retried Ghostty Zig package fetches
guards / workflow-guard-tests / app-host-cache unknown no known signature; failed step: Validate iOS video recording failures
guards / workflow-guard-tests / quality-determinism code a Python test failed
guards / workflow-guard-tests / release-ios unknown no known signature; failed step: Validate iOS simulator build-once contract
guards / workflow-guard-tests / preflight unknown no known signature; failed step: Validate macOS runner guards
Matched log lines
CI fast guards: FAIL    0.2s  workflow-guard-tests / ci: Validate macOS jobs select a pinned Xcode
Fast static checks: FAILED localization (1.08s)
guards / workflow-guard-tests / quality-determinism: FAIL: test_scans_only_test_sources (__main__.CommandLine.test_scans_only_test_sources)

Not re-run automatically: CI fast guards, Fast static checks, guards / workflow-guard-history, guards / workflow-guard-tests / release-tooling, guards / workflow-guard-tests / app-host-cache are not machine failures.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

CI fast guards failed on 28dc1a66b7 (https://github.com/manaflow-ai/cmux/actions/runs/39402321318). It does not block the merge; a red guard merged into main breaks it for every open PR.

Validate macOS jobs select a pinned Xcode

Test: python3 tests/test_ci_macos_xcode_selection.py

cnx-ios-testflight.yml job testflight never runs scripts/select-ci-xcode.sh, so it builds with the image's default Xcode

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate macOS jobs select a pinned Xcode'

Check that push and pull_request path filters agree

Test: python3 tests/test_ci_workflow_path_filter_parity.py

Traceback (most recent call last):
  File "/home/runner/_work/cmux/cmux/tests/test_ci_workflow_path_filter_parity.py", line 245, in <module>
    test_push_and_pull_request_filter_the_same_files()
  File "/home/runner/_work/cmux/cmux/tests/test_ci_workflow_path_filter_parity.py", line 156, in test_push_and_pull_request_filter_the_same_files
    assert not drifted, (
           ^^^^^^^^^^^
AssertionError: Every workflow that filters both events must filter them identically, or declare the difference in EXEMPTIONS or PUSH_ONLY_PATTERNS with a reason.
backend.yml: push and pull_request filter different files
  paths: guarded on push, not on pull requests: scripts/cmux-next/release/prod-promote.ts, scripts/cmux-next/release/production-approvals.json

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Check that push and pull_request path filters agree'

Validate local hook trust boundary

Test: python3 tests/test_preflight_trust.py

  • PreflightTrustTests.test_annotated_tag_push_does_not_execute_candidate_code
subprocess.CalledProcessError: Command '['bash', 'scripts/install-git-hooks.sh']' returned non-zero exit status 1.
  • PreflightTrustTests.test_hook_installation_has_no_candidate_code_runner
subprocess.CalledProcessError: Command '['bash', 'scripts/install-git-hooks.sh']' returned non-zero exit status 1.
  • PreflightTrustTests.test_push_does_not_execute_candidate_check_through_unchanged_wrapper
subprocess.CalledProcessError: Command '['bash', 'scripts/install-git-hooks.sh']' returned non-zero exit status 1.
  • PreflightTrustTests.test_push_does_not_execute_candidate_runner
subprocess.CalledProcessError: Command '['bash', 'scripts/install-git-hooks.sh']' returned non-zero exit status 1.

... and 1 more failing tests in the run log.
Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate local hook trust boundary'

Run canonical CMUX CI guard profile

GitHub-hosted runner label: .github/workflows/pr-red-checks-comment.yml:16:    runs-on: ubuntu-24.04

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Run canonical CMUX CI guard profile'

Validate package test selection

Test: python3 tests/test_ci_select_package_tests.py

    result, count = run_package_step("CmuxUpdater", [(startup, 1), (passed, 0)])
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/runner/_work/cmux/cmux/tests/test_ci_select_package_tests.py", line 102, in run_package_step
    count = int((root / "calls").read_text())
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/pathlib.py", line 1029, in read_text
    with self.open(mode='r', encoding=encoding, errors=errors) as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/pathlib.py", line 1015, in open
    return io.open(self, mode, buffering, encoding, errors, newline)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpqc2l03re/calls'

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate package test selection'

Lint every workflow

/tmp/guard-steps-i6wey9tm/runner_temp/actionlint.tar.gz: OK
/tmp/guard-steps-i6wey9tm/runner_temp/actionlint
.github/workflows/cmux-next-defaults-guard.yml:94:28: expected scalar node for string value but found alias node with "" tag [syntax-check]
   |
94 |           sparse-checkout: *defaults-paths
   |                            ^~~~~~~~~~~~~~~
.github/workflows/nightly.yml:34:3: maximum number of inputs for "workflow_dispatch" event is 10 but 15 inputs are provided. see https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#providing-inputs [events]
   |
34 |   workflow_dispatch:
   |   ^~~~~~~~~~~~~~~~~~

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Lint every workflow'

Validate side-lane placement onto idle owned runners

  • CmuxNextWiring.test_every_mac_job_reads_the_placement (job='cmux-scheme-compile')
AssertionError: False is not true : ${{ !(github.event_name == 'pull_request' && github.base_ref == 'feat-cmux-next') && (!cancelled() && ((inputs.same_tree_sha == '' && needs.path_route.outputs.scheme == 'true' && needs.push-head-preflight.outputs.current == 'true' && needs.path_route.outputs.tree_state == 'ready' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/feat-cmux-next' || startsWith(github.ref, 'refs/heads/next-batch/'))) || (inputs.same_tree_sha != '' && inputs.same_tree_state == 'ready' && contains(inputs.same_tree_tiers, 'scheme')))) }}
  • CmuxNextWiring.test_every_mac_job_reads_the_placement (job='release-compile')
AssertionError: False is not true : ${{ !(github.event_name == 'pull_request' && github.base_ref == 'feat-cmux-next') && (!cancelled() && needs.path_route.outputs.native == 'true' && needs.push-head-preflight.outputs.current == 'true' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/feat-cmux-next' || startsWith(github.ref, 'refs/heads/next-batch/'))) }}
  • CmuxNextWiring.test_every_mac_job_reads_the_placement (job='swift-test')
AssertionError: False is not true : ${{ !(github.event_name == 'push' && github.ref == 'refs/heads/feat-cmux-next') && (!cancelled() && needs.path_route.outputs.swift == 'true' && needs.push-head-preflight.outputs.current == 'true' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/feat-cmux-next' || startsWith(github.ref, 'refs/heads/next-batch/'))) }}
  • CmuxNextWiring.test_every_mac_job_reads_the_placement (job='daemon-test')
AssertionError: False is not true : ${{ !((github.event_name == 'push' && github.ref == 'refs/heads/feat-cmux-next') || (github.event_name == 'pull_request' && github.base_ref == 'feat-cmux-next')) && inputs.same_tree_origin != 'push' && (!cancelled() && ((inputs.same_tree_sha == '' && needs.path_route.outputs.daemon == 'true' && needs.push-head-preflight.outputs.current == 'true' && needs.path_route.outputs.tree_state == 'ready' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/feat-cmux-next' || startsWith(github.ref, 'refs/heads/next-batch/'))) || (inputs.same_tree_sha != '' && inputs.same_tree_state == 'ready' && contains(inputs.same_tree_tiers, 'daemon')))) }}

... and 1 more failing tests in the run log.
Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate side-lane placement onto idle owned runners'

Validate every workflow guard is wired

Test: python3 tests/test_ci_workflow_guards_are_wired.py

Traceback (most recent call last):
  File "/home/runner/_work/cmux/cmux/tests/test_ci_workflow_guards_are_wired.py", line 110, in <module>
    test_every_workflow_guard_is_run_by_a_workflow()
  File "/home/runner/_work/cmux/cmux/tests/test_ci_workflow_guards_are_wired.py", line 89, in test_every_workflow_guard_is_run_by_a_workflow
    assert not unwired, (
           ^^^^^^^^^^^
AssertionError: these tests read .github/workflows/ but no workflow runs them, so the invariants they assert are not enforced:
  tests/test_cmux_tui_republish_same_commit.py
Add a step to .github/workflows/ci-guards.yml, or add an entry to UNWIRED in this file explaining why not.

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate every workflow guard is wired'

Validate notification semantics gates

Test: python3 tests/test_ci_notification_semantics.py

  • NotificationSemanticsTests.test_a_failing_package_does_not_hide_later_packages
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpijptul7q/calls.jsonl'
  • NotificationSemanticsTests.test_packages_prebuild_in_parallel_then_test_serially
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpuf_s5fsl/calls.jsonl'

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate notification semantics gates'

Validate the macOS cross-compile shadow jobs stay compare-only

  • ShadowJobTests.test_every_shadow_job_is_compare_only (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-shadow')
AssertionError: Lists differ: ['notify-unpublished-tree'] != []

First list contains 1 additional elements.
First extra element 0:
'notify-unpublished-tree'

- ['notify-unpublished-tree']
+ [] : cmux-tui-artifacts.yml: ['notify-unpublished-tree'] must not need macos-cross-shadow
  • ShadowJobTests.test_every_shadow_job_is_compare_only (workflow='cmux-tui-artifacts.yml', shadow='macos-cross-runtime-x86_64')
AssertionError: Lists differ: ['notify-unpublished-tree'] != []

First list contains 1 additional elements.
First extra element 0:
'notify-unpublished-tree'

- ['notify-unpublished-tree']
+ [] : cmux-tui-artifacts.yml: ['notify-unpublished-tree'] must not need macos-cross-runtime-x86_64

Fix: the assertion above names what the guard expects; change the tree to match it.
Reproduce in seconds, no build: scripts/ci/guards-local.sh --step 'Validate the macOS cross-compile shadow jobs stay compare-only'

... and 2 more failed steps in the run log.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

azooz2003-bit and others added 4 commits October 20, 2026 02:03
Live check: after a simulator reboot the scene stayed inactive, so the
shown page told the Mac it was hidden (it stopped painting) and did not
reopen on a new link. Only the background hides streamed pages now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…retried first

Live check (Mac app killed, daemon alive): resolve-terminal answered
terminal_not_found for a moment after the restart, and the session
ended a live terminal. A terminal now ends only when it is still missing
after the reattach retries. The session asks with terminal_resource_id
(term_...), which a daemon restart keeps; terminal_id is the host id,
which it does not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A renumbered terminal reattaches on a new link (match the public id).
- A page counts the views showing it, and starts hidden: a tab's new view
  appearing before its old one disappears keeps it shown, and a page laid
  out ahead never opens.
- Only a browser workspace's opening tab is renamed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erminal rows pass)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

Correctness review (two fresh subagents): findings and resolutions are in the Reviews section of cnx-ios/verify/redial-video.md.

First review: both must-fix items are fixed (a restoring terminal was ended; two viewers could evict each other forever). Of the should-fix items, four are fixed and two are accepted with the reason recorded.

Second review: the must-fix is fixed (a renumbered terminal did not reattach on a new link), and so are two should-fix items and one nice-to-have. Two should-fix items are still open:

  • the rb.visibility reminder and a hidden tab's open can reach hostd out of order across channels (fixing it needs hostd to take visibility in rb.open);
  • a renamed placeholder's host stays until the host limit stops it.

Not done (nice-to-have): a late channel frame in the cnx-ffi viewer costs one extra keyframe.

@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

Superseded by #22555, which merged this branch's head into feat-cmux-next (merge commit f3842ff) together with #22260, #22354, #22355, #22337, #22419, #22387 and #22574. Closing as folded in; the branch is kept.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant