Repository navigation
ci: app-host rerun holds the product's canonical root - #14417
Merged
Merged
Conversation
The rerun job hard-coded /private/tmp/cmux-ci, rm -rf'd that root's DerivedData and never took the root, so on an owned Mac with two roots it could replace a tree another job was using, and it rebuilt a root-2 product at root-1 paths. It now unpacks the products beside the job, reads the producer's root from the receipt (falling back to CMUX_CI_CANONICAL_ROOT, then /private/tmp/cmux-ci), holds it with glaeda-canonical-root take, and only then replaces that root's DerivedData. CMUX_CI_CANONICAL_ROOT is exported so canonical-resolve builds in the same root. Blacksmith keeps /private/tmp/cmux-ci and has no helper to call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (3)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
rustybret
pushed a commit
to rustybret/bmux
that referenced
this pull request
Sep 25, 2026
8409047 ci: run the suites that mention an app-source change (manaflow-ai#14418) cbebee8 fix(homebrew): generate the symbol form of depends_on macos (manaflow-ai#14424) e9bb38a ci(ios): only pick simulators the active Xcode SDK can target (manaflow-ai#14422) 5b2533c fix(ios): stop calling a mutating method inside #expect (manaflow-ai#14421) 4ab2739 ci: pick the pool with the least expected wait, bounded by every run's peak (manaflow-ai#14410) 26292a4 ci(nightly): warn instead of failing when GitHub refuses the tag move (manaflow-ai#14425) f4b331d Merge pull request manaflow-ai#14090 from manaflow-ai/14078-cloud-codex-restore-garble 193f5d9 test: restore AppDelegate.shared after every XCTest case (manaflow-ai#14379) 31588d6 ci: run a tart-* pick as auto while the Tart VMs are offline (manaflow-ai#14416) 2d844cb ci: app-host rerun holds the product's canonical root (manaflow-ai#14417) d0f485e Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble a855dbf test: fix the dead-key crash and sidebar AX walk failing on main (manaflow-ai#14406) 066f300 Merge pull request manaflow-ai#13938 from manaflow-ai/13893-desktop-click-ownership 0c2bb9d Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership 9670d83 Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble cb88a4b Merge branch 'main' of https://github.com/manaflow-ai/cmux into 13893-desktop-click-ownership 86504fb fix: import Cloud package for team picker 885a39c test: import CmuxCloud in the Desktop navigation tests 75070d9 Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership 3dfcfb9 Merge branch 'main' of https://github.com/manaflow-ai/cmux into 13893-desktop-click-ownership 52020d3 Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 9cafdf5 test: register cloud preview during materialization bc09ec8 test: scope desktop registration hook to the preview resource ea4242c Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 1be4c92 fix: count retained cloud previews as planned 4f98bd3 fix: align Xcode iroh package requirement 4a0bd3a chore: update Xcode package lockfile 8cda030 Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble ddeb03d fix: pin published iroh Swift release 1d9082a chore: update iroh package lockfiles fc2b529 fix: pin attested iroh Swift artifact revision 4c33353 test: import surface catalog models in cloud actions 25c64f2 Merge branch 'main' of https://github.com/manaflow-ai/cmux into 13893-desktop-click-ownership 4bd5808 test: import shared surface catalog models 59eddd9 Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership a157f5c Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble cbc0118 ci: pin GhosttyKit for replay fix 4a48e3d Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 4784eb2 fix: preserve Cloud replay trailing rows d081368 Merge origin/main and fix replay API visibility 7202960 Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership a846dfd Merge branch 'main' of https://github.com/manaflow-ai/cmux into 14078-cloud-codex-restore-garble 96d5686 fix: delimit replay rows when scrollback exists 6ac603e fix: use terminal history boundary for replay 054dc50 style: apply hosted replay formatting 90fa111 fix: preserve replay history and protect tagged resources d2d6aa3 fix: refresh Cloud renderer after replay application 91601b8 revert: remove speculative Cloud replay grid overrides cb2dc58 test: reproduce Cloud replay shifting sparse screens with history c78ffdc fix: keep replay sizing helpers in app target 1e6f928 fix: preserve Cloud sizing intent across replay e568942 fix: keep Cloud replay geometry transient c094d63 Merge remote-tracking branch 'origin/14078-cloud-codex-restore-garble' into 14078-cloud-codex-restore-garble 8ed24b2 fix: align Cloud replay with remote grid bbc466c test: cover Cloud replay grid alignment cba191e test: cover self-registered Desktop materialization 105f24f fix: keep a Cloud Desktop pane that registers itself while materializing 9397594 Revert "fix: retain local Desktop projection provenance" dc9e8af fix: retain authored colors when Cloud replay omits sidecar 58d4105 test: preserve authored Cloud colors across sidecar-free replay a5af809 Merge remote-tracking branch 'origin/main' into issue-14078-cloud-codex-restore-garble 781a063 Merge origin/main into desktop click ownership 82b100a test: cover legacy applied resize responses a9f6a92 Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 9d90d5e fix: clear Cloud ownership after replay confirms peer loss 6a36349 fix: defer cross-client Cloud loss until replay state 9bd3588 fix: ignore no-op Cloud resize acknowledgements 99329a1 fix: retain pending Cloud claims through handshake 4c0fa87 fix: demote Cloud mirror after cross-client rejection 509b984 fix: preserve explicit Cloud claim intent dce99b4 fix: distinguish passive Cloud lease outcomes 5de372f test: allow automatic restore claim response f7a3bc7 fix: wait for Cloud resize outcome before claiming 2fdaef3 fix: block rejected cross-client Cloud sizing claims 4804326 fix: stop passive Cloud mirror claim oscillation 223eb67 fix: restore debug title formatter linkage 68fb24d test: keep replay reset marker in restore fixture 674248c Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 1a11606 fix: reset Cloud VT state for replacement replays 2a2e092 test: reproduce stale Cloud replay cells after restore 15ba7c4 fix: preserve restore intent before process probing a900e91 test: cover click Desktop graph reconciliation ff2694f refactor: isolate workspace title debug formatting 53dd942 Read matchingObservation after it is declared in the restore liveness check 1b288aa Merge remote-tracking branch 'origin/main' into 14078-cloud-codex-restore-garble 8b8c669 test: fence passive Cloud claims with protocol traffic 62532fc fix: remove duplicate Cloud restore test registration 827d859 chore: sync Cloud restore test wiring 22a187b fix: import workspace liveness in Codex restore policy 92126bd test: assert restored Cloud resize dimensions b7e457f fix: retain Cloud geometry claim policy across hidden restores 5dccec0 test: reproduce lost Cloud geometry eligibility after hidden restore 97c4673 test: preserve Cloud replay state across hidden restore geometry e0d44a0 fix: retain local Desktop projection provenance 31f698b fix: preserve committed routes while proxy connects b976180 fix: preserve preview provenance and committed Cloud routes 80f7087 fix: retain explicit Desktop placement provenance 3ee2ece fix: preserve Cloud Desktop panes during reconciliation 39b61fc test: keep Cloud Desktop previews during reconciliation 4ce4f4f fix: let activated Cloud browsers own route navigation 519bf26 test: reproduce desktop navigation without a mounted view 7d2b58a Merge origin/main and preserve per-run E2E cleanup 1b1feb8 test: use lifecycle-safe workspace creation in Desktop fixture a722c20 ci: restore E2E products inside the owned runner temp root 903513c test: enforce E2E DerivedData cleanup ownership c0f96a2 test: keep Desktop placement fixture windows hidden e8a34f4 Merge main after Desktop ownership fix landed fb9955b fix: keep Desktop view opens on the captured destination 1e696af test: give Desktop placement fixtures a complete native window route 9d3e2d8 fix: capture the Desktop view destination before scheduling f327329 Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership 6dc7d9f test: establish mouse event context for the Desktop regression baseline 7cdeac6 Merge remote-tracking branch 'origin/main' into 13893-desktop-click-ownership 1f9c925 fix: retain the Desktop click destination across queued work b4f17f6 test: reproduce queued Desktop click targeting another Cloud workspace # Conflicts: # .github/workflows/app-host-test-rerun.yml # .github/workflows/ci-guards.yml # .github/workflows/ci.yml # .github/workflows/nightly.yml # .github/workflows/test-e2e.yml # .github/workflows/test-ios.yml # .github/workflows/update-homebrew.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
glaeda's review found that
app-host-test-rerun.yml'srerunjob hard-codes/private/tmp/cmux-ci, rm -rfs that root'sderived-data-compile-admission, and never callsglaeda-canonical-root take. On an owned Mac with two roots it could replace a tree another job is using. It also rebuilt a product compiled in/private/tmp/cmux-ci-2at root-1 paths, which its swiftmodules do not match.scripts/ci/take-product-canonical-root.sh(new) reads the producer's root from the product receipt'sderived, the same wayrestore-app-host-test-product.shdoes. If the receipt has no canonical root, it usesCMUX_CI_CANONICAL_ROOT, then/private/tmp/cmux-ci. It rejects anything that is not/private/tmp/cmux-cior/private/tmp/cmux-ci-<n>, holds the root withglaeda-canonical-root take <root> --wait 1800when the helper exists, and prints the root.$RUNNER_TEMP/rerun-productsfirst. It takes the root, and only after that replaces<root>/derived-data-compile-admission(with amv). It exportsCMUX_CI_CANONICAL_ROOT,CANONICAL_ROOTandCOMPILE_DERIVED_DATAto$GITHUB_ENV. The job-level hard-codedCANONICAL_ROOT/COMPILE_DERIVED_DATAenv is gone. ExportingCMUX_CI_CANONICAL_ROOTalso fixes a latent mismatch:canonical-resolveread that variable while the rest of the job used the hard-coded root.$RUNNER_TEMP/cmux-derived-data-rerun, a DerivedData of the job's own, the same way the shard jobs do./private/tmp/cmux-ci, and there is no helper to call.Why the rebuild stays in
<root>/derived-data-compile-admissionand not a fresh directory: the cmuxTests bundle is compiled against the producer's swiftmodules, which carry absolute paths into that DerivedData and into<root>/src. In a different directory, those paths would point at whatever the root holds, possibly another revision's build. Taking the root first makes that directory this job's own until the job ends.test-e2e.ymlowns the same path the same way.glaeda follow-up (not in this PR): the hook still classifies
rerunas an unknown job, which means compile, pinned to root 1. It holds root 1 from job start, so the take is a no-op for root-1 products and exits 2 ("one root per job") for a root-2 product. The rerun fails loudly in that case and no longer builds at the wrong paths. Adding("app-host-test-rerun.yml", "rerun"): "gui"toWORKFLOW_JOB_CLASSESlets it take the producer's root like other consumers. It runs the app-host tests in the console session, so it needs the gui token.Tests
python3 tests/test_app_host_test_rerun.py: 47 tests OK. The newCanonicalRootTestscheck that:/private/tmp/cmux-ci; the fallback lives only in the helperrm -rf "$COMPILE_DERIVED_DATA"./tests/test_ci_self_hosted_guard.sh: 38 checks pass.python3 tests/test_ci_canonical_build_root.py: OK.tests/test_ci_change_areas.py::test_app_host_rerun_runs_on_the_products_pool: OK.actionlint .github/workflows/app-host-test-rerun.yml: clean.The existing test file is already wired into
ci-guards.yml(app-host-execution group) andtests/test-execution.toml(linux-guard), so no new wiring is needed.release-build audit
Scope: the
release-buildjob inci-macos.ymland the scripts it runs.Paths it writes or deletes
build-universal/is the Release DerivedData, plusCompilationCache.noindex. It is deleted at job start by "Reclaim release runner disk" and never cleaned at job end..spm-cache/holds the SwiftPM checkouts and.package-cache. It is also deleted at start.GhosttyKit.xcframeworkis deleted and re-extracted bydownload-prebuilt-ghosttykit.sh.ghostty-cli-helper/is a downloaded artifact..git/index.lockand.git/modules/**/*.lockare cleared by the first step.$RUNNER_TEMP: the cmux-tui manifests,cmux-release-product.tar.gz, and the reuse receipt.$TMPDIR/mktemp: scratch dirs fromtest_thin_app_bundle.sh,test_install_cmux_tui_client.sh,download-prebuilt-ghosttykit.shandbuild-cmux-cua.sh, all removed by traps.$HOME, shared by every job on the mini:~/.cargoand~/.rustup:install-rust-ci.shmay run rustup-init,rustup default stable,rustup target add, and install the DiffSidecar toolchain.~/Library/Caches/cmux/cmux-tui-client:install-cmux-tui-client.sh.~/Library/Caches/cmux/cmux-cua:build-cmux-cua.sh, which runs as an Xcode build phase.~/Library/Caches/go-buildand~/go/pkg/mod, from the wireguard-go/tunnel build phase.$RUNNER_TOOL_CACHE, from actions/setup-go.select-ci-xcode.shrunsxcode-select -s(sudo -n fallback) unlessCMUX_CI_SKIP_XCODE_SELECT=1. It only reads/Applicationsto choose an Xcode./private/tmp/cmux-ci*(no canonical root),/Users/Shared/cmux-build-fleet(owned build state),/Applicationswrites, launchd,defaults.Signing and secrets
CODE_SIGNING_ALLOWED=NO. The only signatures are ad hoc (codesign --sign -) on cmux-cua and its helper app, pluscodesign --verify. These do not use the keychain.github.tokenwith read scopes (actions, attestations, contents). It is used forgh attestation verify, artifact download, and product restore.GUI session: not needed. No app launch, no XCTest, and no
run-in-console-session.sh.Safe on a persistent owned mini that runs other jobs? Yes, with these caveats:
xcode-select -sis host-global. It is harmless while every job on the mini selects the same Xcode. Otherwise, setCMUX_CI_SKIP_XCODE_SELECT=1for this job; it already pinsDEVELOPER_DIR.~/Library/Caches/cmuxwrites are shared$HOMEstate. Every other job writes it the same way, but two concurrent rustup installs can race on first use.build-universal/(several GB) stays in each runner instance's workspace until that instance's next release-build.runs-onisvars.MACOS_RUNNER_26, not the owned-pool picker, so it needs a routing change to reach a mini at all.Recommended glaeda class:
isolated(2 units, no root, no gui):compilewould take a root and the persistent-dd token for nothing.product.gui.The hook would treat it as an unknown job today (compile, pinned to root 1), so it needs an explicit
"release-build": "isolated"entry inJOB_CLASSESbefore it is routed to minis.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
The
rerunjob now holds the product's canonical build root before rebuilding against it, so it no longer replaces trees another job is using and rebuilds at the paths the product was compiled at.Bug Fixes
scripts/ci/take-product-canonical-root.shreads the producer's root from the product receipt'sderived, falls back toCMUX_CI_CANONICAL_ROOTthen/private/tmp/cmux-ci, and takes the root withglaeda-canonical-root takewhen the helper exists.$RUNNER_TEMP/rerun-productsand moved into the root only after the take succeeds.CMUX_CI_CANONICAL_ROOT,CANONICAL_ROOT, andCOMPILE_DERIVED_DATAare exported, fixing the mismatch wherecanonical-resolvereadCMUX_CI_CANONICAL_ROOTwhile the job used a hard-coded root./private/tmp/cmux-ciand there is no helper to call.Written for commit 723aced. Summary will update on new commits.
Summary by CodeRabbit