Skip to content

cmux-tui: a new build stamp no longer recompiles cmux-tui-core - #21980

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
feat-cmux-next-tui-stamp-runtime
Oct 20, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
feat-cmux-next-tui-stamp-runtime

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

cmd_server.rs in cmux-tui-core read CMUX_TUI_BUILD_COMMIT, CMUX_MUX_BUILD_COMMIT and CMUX_TUI_GHOSTTY_COMMIT with option_env!. rustc records these in dep-info, so every new build stamp recompiled cmux-tui-core and, through it, cmux-remote.

Now only the binary crate reads the stamp at compile time:

  • cmux-tui-core/src/server/daemon_build.rs: a new BuildStamp in a OnceLock, set by install_build_stamp (first call wins). The stamped_build_commit() and stamped_ghostty_commit() functions read it.
  • cmux-tui/src/main.rs: build_stamp() reads the env values in the same order as before (TUI, then MUX; an empty value counts as no stamp). main() installs it as its first step after the link-token take, before any mode can serve identify or ping. version_string() reads the same build_stamp().
  • A mux that runs without an installed stamp (core tests, embedders) reports null, which is what an unstamped build reported before.

cmux-relay has the same pattern, but it is not in the cmux-tui bin graph (it is only a dev-dependency of cmux-remote), so this PR does not change it.

Proof (Blacksmith Testbox, 32 vCPU, cargo build -v -p cmux-tui --bin cmux-tui --locked)

Stamps A=aaaa… and B=bbbb… (40 hex), ghostty cccc…. The same tree for each pair.

Pool Linux twin settings (CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0, CMUX_TUI_DISTRIBUTION_VERSION and CMUX_GIT_SHORT_SHA follow the stamp), --timings:

stamp change wall cmux-tui-core
before A to B 51.5 s Compiling, 39.0 s
before B to A 52.5 s Compiling, 39.5 s
after A to B 32.9 s Fresh
after B to A 32.5 s Fresh

After the change these units still rebuild for each new stamp: cmux-tui (18.4 s), acpmux (16.7 s, from CMUX_GIT_SHORT_SHA/SOURCE_DATE_EPOCH), cmux-remote (9.6 s, from CMUX_TUI_DISTRIBUTION_VERSION in ssh_bootstrap.rs), and the cmux-build-identity build script. Those are not in this PR.

Incremental dev profile, only the commit and ghostty stamps changed: before, the build compiled cmux-build-identity, cmux-remote, cmux-tui-core and cmux-tui. After, it compiled only cmux-build-identity and cmux-tui, and every library was Fresh.

Readers, after the change, through a real headless daemon socket (identify and ping) and --version. The values are identical to the before-change binary with the same stamp:

after-A --version: cmux 0.1.0 (aaaa…aaaa; ghostty cccc…cccc)
  identify: build_commit=aaaa…aaaa ghostty_commit=cccc…cccc build_id=aaaa…aaaa
  ping:     build_commit=aaaa…aaaa ghostty_commit=cccc…cccc
after-B --version: cmux 0.1.0 (bbbb…bbbb; ghostty cccc…cccc)
  identify: build_commit=bbbb…bbbb ghostty_commit=cccc…cccc build_id=bbbb…bbbb
  ping:     build_commit=bbbb…bbbb ghostty_commit=cccc…cccc

The A and B binaries (after the change) have the same size (1183893440 bytes). Of the 380 differing bytes, 360 are in the 9 stamp strings. The other 20 are the ELF .note.gnu.build-id hash (offset 812-831; section at 0x31c).

Tests

  • cargo fmt --check -p cmux-tui-core -p cmux-tui: ok
  • cargo test -p cmux-tui-core --lib identify_and_ping_return_build_metadata: ok
  • cargo test -p cmux-tui --test resource_cli_v2 --test cli -- startup_help_and_version_use_the_public_command_name machine_agent: 3 ok
  • cargo clippy --locked -p cmux-tui-core -p cmux-tui --all-targets -- -D warnings: ok

No new tests.

🤖 Generated with Claude Code


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


Summary by cubic

Moves build stamp reading out of cmux-tui-core so a new stamp no longer recompiles it. cmd_server.rs previously read CMUX_TUI_BUILD_COMMIT, CMUX_MUX_BUILD_COMMIT, and CMUX_TUI_GHOSTTY_COMMIT with option_env!, which rustc tracked in dep-info and forced cmux-tui-core (and cmux-remote through it) to rebuild on every stamp change. Now only the cmux-tui binary reads the environment at compile time and installs a BuildStamp in core at startup.

  • main() installs the stamp as its first step, before any mode can serve identify or ping; reading order is unchanged, and an empty value still counts as no stamp.
  • A mux without an installed stamp (tests, embedders) reports null, same as an unstamped build.
  • identify_and_ping_return_build_metadata now installs a known stamp and asserts its literal values in identify and ping.
  • A stamp-change build dropped from ~51.5 s to ~32.9 s wall time on the Linux pool, with cmux-tui-core staying Fresh.
  • cmux-relay has the same pattern but sits outside the cmux-tui bin graph, so it is unchanged here.

Written for commit dc61324. Summary will update on new commits.

View guided diff Turn on auto-fix

…amp does not recompile it

cmd_server.rs read CMUX_TUI_BUILD_COMMIT, CMUX_MUX_BUILD_COMMIT and
CMUX_TUI_GHOSTTY_COMMIT with option_env!. rustc tracks them in dep-info,
so every new stamp recompiled cmux-tui-core (18-21 s per stamp in the
Linux build pool). The binary now reads them (as version_string did) and
installs a BuildStamp in core at the top of main; identify and ping read
it. A mux without it (tests, embedders) reports null, as an unstamped
build does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lawrencecchen
lawrencecchen temporarily deployed to cmux-tui-merge-tree October 19, 2026 05:58 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 3087a632-e9cb-485a-9d37-1fbe8b926235

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • 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.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Receipt for dc61324 (this PR's head; a new push replaces it)

  • Visual review: HQ feed card · gallery before/after runs
  • Checks: this head
  • 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=pr21980 -f ref=feat-cmux-next-tui-stamp-runtime -f platform=macos -f backend_mode=local

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Bead cx-887vs created for this PR by the cmux coordinator.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Correctness review (subagent)

Head reviewed: 5e538140. Read-only review. I did not build or run tests. CI cargo check (x86_64-pc-windows-gnu) and the Windows and macOS build jobs are green on this head.

Result: no blocker. Merge is safe after you decide on the should-fix item.

1. Readers of the stamp

  • stamped_build_commit / stamped_ghostty_commit have 3 readers only: cmd_server::identify (cmux-tui-core/src/server/cmd_server.rs:42,45), cmd_server::ping (cmd_server.rs:114-115), and the core unit test (server/tests/detach_and_browser.rs:575-583). No other crate can call them (pub(super)).
  • Only 3 workspace crates depend on cmux-tui-core: cmux-tui, cmux-remote (uses backoff only) and cmux-terminal-client (terminal-host protocol and runtime only). cmux-remote and cmux-terminal-client do not serve identify or ping.
  • acpmux, cmux-server, cmux-browser-host, cmux-app-host, cmux-relay and the FFI crates do not link cmux-tui-core. cmux-relay and cmux-browser-host keep their own option_env! stamps, and this PR does not change them.
  • Every process that serves the control socket enters through cmux_tui::main (crates/cmux-tui/src/main.rs:1637):
    • cmux-tui binary: src/bin/cmux-tui.rs calls cmux_tui::main.
    • Windows thin exe plus DLL: cmux_tui_dll_main (main.rs:1672) calls main. The DLL is the same cmux-tui lib crate, so it gets the same compile-time env as before.
    • acpmux symlink, classic hook mode and __terminal-host re-exec: all of them go through main, and the install is before them.
    • A forked daemon gets the set OnceLock from its parent's memory. A re-exec'd daemon runs main again.
  • cmux-tui-host (Windows per-terminal host) and cmux-tui-hook do not call main. They do not serve identify or ping, so the stamp has no effect on them.

2. Paths that now report null where they reported a value before

Only unit tests that run inside the process. No product path.

  • cmux-tui-core unit tests (for example detach_and_browser.rs:563 identify_and_ping_return_build_metadata): before, build_commit was the compile-time env when the test build had CMUX_TUI_BUILD_COMMIT set. Now it is always null. No test or CI step expects a value there.
  • cmux-tui lib unit tests (main_tests.rs and others) do not call main. None of them reads build_commit.
  • Integration tests under crates/cmux-tui/tests start the real binary, so they get the stamp. The conformance runner (bindings/conformance/raw/runner.py:405,524) expects null from an unstamped binary, as before.
  • Skew and re-bootstrap: SSH bootstrap compares cmux_build_identity::BUILD_IDENTITY (cmux-remote/src/ssh_bootstrap.rs:655) and not build_commit, so this PR has no effect on it. The Swift daemon handoff (DaemonVersionHandoff.swift:110, DaemonLauncher+Build.swift:48, DaemonService.swift:164) reads build_commit from a daemon that is the cmux-tui binary, which installs the stamp. Also, a nil value makes those guards return "no handoff". It does not cause a loop. The nightly probe (nightly.yml:1921) checks build_identity from remote-probe, which this PR does not change.

3. First-call-wins and races

  • There is 1 caller of install_build_stamp: the second statement of main. The first statement, startup_env::take_link_token_from_env, only reads and removes environment variables. It does not start a thread and does not read the stamp. No ctor or static initializer in cmux-tui or cmux-tui-core reads the stamp.
  • A get before the set can occur only in a process that does not call main. This PR documents that case as "reports null".
  • OnceLock::set on a second call is a silent no-op. That is correct for 1 caller.

4. Byte-for-byte output

  • version_string: same expression (TUI.or(MUX).filter(non-empty); ghostty filter(non-empty)), same match, same format!. An empty CMUX_TUI_BUILD_COMMIT together with a set CMUX_MUX_BUILD_COMMIT still gives no commit, as before. The output is the same.
  • identify / ping: same keys, same order, same Option<&'static str> value. version is still core's CARGO_PKG_VERSION. The output is the same for the same stamp.
  • Rebuild tracking: option_env! in the cmux-tui lib crate is tracked by cargo dep-info, so a new stamp still rebuilds the crate that embeds it. The cmux-tui lib crate already read these 3 variables before this PR, so this PR does not add rebuild cost there.

Findings

  • Blocker: none.
  • Should-fix: identify_and_ping_return_build_metadata (cmux-tui-core/src/server/tests/detach_and_browser.rs:575-583) is now a tautology. Both sides read the same empty OnceLock, so the test asserts None == None. No test proves that an installed stamp arrives in identify and ping. Recommendation: in that test, call install_build_stamp(BuildStamp::new(Some("abc"), Some("def"))) and assert the literal values. No other core test reads build_commit, so a process-wide install in that test is safe. As an alternative, add an assertion to an existing binary-level test (for example crates/cmux-tui/tests/cli.rs near line 2502) that ping returns the stamped commit.
  • Nit: build_stamp() (crates/cmux-tui/src/main.rs:968-970) applies .filter(non-empty) to the commit, and BuildStamp::new applies the same filter again. The first filter is necessary only to keep the "empty TUI value hides MUX" behavior. Add a short comment there, or remove the first filter and accept that change in behavior.
  • Nit: the doc on install_build_stamp says "tests, embedders". No embedder exists today. If one is added later (an in-process daemon in an FFI crate), it must call install_build_stamp, or the Swift handoff will see null and will not do the handoff. A note in that doc can prevent that mistake.

@blacksmith-sh

blacksmith-sh Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Found 3 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpfhlsiz1f/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpu7k9_iqk/summary-fail.json (live):/summary-fail.json (live): View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs

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

…e install rule

Review of the build-stamp move: identify_and_ping_return_build_metadata
compared null with null; it now installs a known stamp and checks the
literal values in identify and ping. install_build_stamp says every entry
point that serves identify or ping must call it. build_stamp() says why the
filter runs after the TUI-then-MUX fallback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lawrencecchen
lawrencecchen temporarily deployed to cmux-tui-merge-tree October 19, 2026 06:14 — with GitHub Actions Inactive
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lawrencecchen
lawrencecchen temporarily deployed to cmux-tui-merge-tree October 19, 2026 06:16 — with GitHub Actions Inactive
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 19, 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
lawrencecchen temporarily deployed to cmux-tui-merge-tree October 19, 2026 06:21 — with GitHub Actions Inactive
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Resolution of the review findings

  1. should-fix: identify_and_ping_return_build_metadata compared null with null. Fixed in cf74cad and dc61324. The test now installs a known stamp (0123…4567, ghostty fedc…ba98) and checks these literal values in identify and ping. The result does not depend on test order: the stamp is process-wide and the first install wins, and this is the only test in cmux-tui-core that installs a stamp or reads build_commit/ghostty_commit. I also removed the #[cfg(test)] re-export of stamped_* because no test uses it now.
  2. nit: build_stamp() in cmux-tui/src/main.rs now has a comment. It says that or comes before the filter, so a set but empty CMUX_TUI_BUILD_COMMIT hides CMUX_MUX_BUILD_COMMIT. This is the same as before the move.
  3. nit: The doc of install_build_stamp now says that every entry point that serves identify or ping must call it before it serves. A future embedder (for example an FFI daemon) that does not call it reports build_commit: null, and then the app's daemon handoff does not occur.

f41a71f is a rustfmt order fix only (mod cmd_frontend).

Testbox at dc61324: cargo fmt --check (cmux-tui-core, cmux-tui) ok. cargo test -p cmux-tui-core --lib identify_and_ping_return_build_metadata 1 passed. cargo clippy --all-targets -D warnings (cmux-tui-core, cmux-tui) ok.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

cmux-bot Bot added a commit that referenced this pull request Oct 31, 2026
…#28787)

release::DISTRIBUTION_VERSION read CMUX_TUI_DISTRIBUTION_VERSION with option_env!,
and the Linux pool stamps it per build (0.0.0-r2.sha-<stamp>, macos-cross.sh,
cmux-tui-build-package.yml), so every stamp recompiled cmux-tui-core and everything
above it. #21980 moved core's other stamps to the binary (install_build_stamp);
release.rs came a day later with its own.

Core now reads release::distribution_version(): the value the binary installs at
start (install_distribution_version, next to install_build_stamp), the same filter
(a placeholder stamp is not a release), and the workspace crate version until then
(core's tests, which saw the same value before). The binary keeps its own
DISTRIBUTION_VERSION constant and DISTRIBUTION_STAMP, the one option_env! read.

Test: cargo test -p cmux-tui-core --lib only_a_release_stamp_is_reported_as_the_release


Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f016c499153c1bead46

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

2 inactive deployments
artifacts — dc613248 Deployed Oct 19, 2026 by lawrencecchen
cmux-tui-merge-tree — dc613248 Deployed Oct 19, 2026 by lawrencecchen
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.

2 participants