Skip to content

acpmux tests: socket_owner runs hermetic (base red from #31593) - #32064

Merged
lawrencecchen merged 1 commit into
feat-cmux-nextfrom
base-red-hermetic
Nov 2, 2026
Merged

lawrencecchen merged 1 commit into
feat-cmux-nextfrom
base-red-hermetic

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Base red (priority zero). On feat-cmux-next, acpmux hermetic_daemon_guard::every_test_binary_runs_in_the_hermetic_environment (tests/hermetic_daemon_guard.rs:123) fails: tests/socket_owner.rs does not include tests/support/daemon_env.rs and has no HERMETIC constant. Base job 5472a06e7265dc6ae1ebaa3d.

Culprit: 22f3792 (#31593) added tests/socket_owner.rs without the hermetic include.

Fix (test only): socket_owner.rs includes support/daemon_env.rs and defines const HERMETIC: daemon_env::Process = daemon_env::Process::deny();, as daemon_single_owner.rs does. Before main the binary now starts itself again with the bare environment: no host PATH (no real agent CLI can be found), a scratch HOME, ACPMUX_AGENT_LAUNCH=deny. The test starts no daemon; it calls acpmux::server::bind_unix in a temp home and runs a python3 lock holder, and the hermetic PATH links python3 first. The guard and its rules are unchanged; no allow-list entry.

FYI @teamleaderleo: this is your #31593 test file.

Testing

cmux-ci run --class isolated --os linux --script scripts/ci/cmux-tui-rust-check.sh --ref SHA --arg test --arg FILTER:

  • Red at the base 09a0685c7bad, filter every_test_binary_runs_in_the_hermetic_environment: FAIL, and the message names tests/socket_owner.rs. Step 173ac35ac58ef50eadafe1e2.
  • Green at the head d80d9fce06b, the same filter, 5 of 5 (each 1/1 PASS): steps 576efb89187feea5b9ea187d, 562a791c6dc0b27a936bbfe2, cca7dbe4c5dc90a7fa9a7a3e, e5ad747ad76d92c04554d4c0, a4c888496629d55269f28215.
  • socket_owner's own test at the head, now in the hermetic environment, filter a_bind_that_does_not_hold_the_lock_never_unlinks_the_holders_socket, 2 of 2 PASS: steps 004b83b22853f286fbf018a1, 5a51cd4973f4ec8efb8acade.
  • Panic ratchet (--arg panic) at the head: pass, step e4c0c1bb98809bf02cb59150.

Non-green checks at the head are base findings, not caused by this PR:

Observed / Not run

  • Observed: the fleet step logs above (nextest PASS/FAIL lines); python3 scripts/cmux-next/prepush-gate.py passes at the head.
  • Not run: no local build or test on this VM (fleet only). macOS was not run: the test file is cfg(unix) and the guard reads files only; Linux is the route cmux-tui.yml gates.

Changelog

none

tests/socket_owner.rs (22f3792, #31593) was a test binary without
tests/support/daemon_env.rs and its HERMETIC constant, so it ran with the
host's PATH and HOME, and hermetic_daemon_guard's
every_test_binary_runs_in_the_hermetic_environment was red on
feat-cmux-next. It now includes the helper with Process::deny(), as
daemon_single_owner.rs does: before main the binary starts itself again
with the bare environment (no agent CLI on PATH, scratch HOME, agent
launches denied). Its python3 lock holder still runs: the hermetic PATH
links python3 first.
@lawrencecchen lawrencecchen added the risk:low Risk tier (docs/ci/risk-tiers.md) label Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

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

Review d80d9fc: 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=pr32064 -f ref=base-red-hermetic -f platform=macos -f backend_mode=local

Shipped in:

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Review (subagent, correctness first): SHIP at d80d9fc

Checked (read only, no local build or test):

  • Guard every_test_binary_runs_in_the_hermetic_environment: socket_owner.rs now has #[path = "support/daemon_env.rs"], mod daemon_env; and const HERMETIC: daemon_env::Process. That is all it looks for. The layout is the same as daemon_single_owner.rs.
  • Guard only_the_hermetic_helper_starts_the_acpmux_binary: the file does not name CARGO_BIN_EXE_acpmux or daemon_env::bin(). No allow-list entry was added, and the helper and the guard are not changed. The guard is not weaker.
  • Build: the helper needs libc, tokio, acpmux::cli::entry::WORKER_STACK_BYTES, acpmux::protected_folders and acpmux::cpu_class::ENV. Many other test binaries already use all of them. #![allow(dead_code)] covers the unused helpers. tempfile is a dev-dependency.
  • #![cfg(unix)] on the crate root removes the whole file on Windows, so the helper's #[cfg(windows)] const _: Process = super::HERMETIC; is never compiled. Other unix-only test binaries do the same.
  • Hermetic run: the .init_array / __mod_init_func re-exec runs before main, so #[tokio::test] builds its runtime in the hermetic process.
    • PATH is <tmp>/amx-bin-<pid>-python3:/usr/bin:.... The link points to the real interpreter, which the helper finds before it clears the environment. The pid stays the same after exec, so the link folder stays valid. Command::new("python3") finds it, as in chats.rs and cua_v2_stale_endpoint.rs. The holder script uses only the stdlib (fcntl, os, sys, time).
    • The test uses tempdir_in("/tmp"), so TMPDIR does not change where it works, and the socket path stays short.
    • HOME=<scratch>/home, so config::home() is <scratch>/home/.acpmux. refuse_lost_home(home()) passes because no home is held. socket_held_by_other checks home()/daemon.lock (missing, so no match) and then <socket dir>/daemon.lock, which is the python holder's lock. The bind then fails with the holder's pid, as the test expects. Before this PR, the test read the real ~/.acpmux/daemon.lock of the host. Now it reads only its own scratch files.
  • Feat tip still has socket_owner.rs without the include. No other open or merged PR fixes it.

Findings (they do not block):

  • The PR body's ## Testing section still has the placeholder EVIDENCE. The PR shows no fleet red or green result yet. Add the fleet result for both guard tests and socket_owner, or say on the PR that they were not run.
  • defaults-snapshot is red on this head. This diff changes one Rust test file only, so it cannot cause that check to fail. Look at the base for the cause.

@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 2, 2026
@lawrencecchen
lawrencecchen merged commit 075c08c into feat-cmux-next Nov 2, 2026
278 of 302 checks passed
@lawrencecchen
lawrencecchen deleted the base-red-hermetic branch November 2, 2026 10:13

This branch was previously deployed

3 inactive deployments
ci-routing-agent — d80d9fce Deployed Nov 2, 2026 by github-actions[bot] via cmux-next macOS placement #62286
artifacts — d80d9fce Deployed Nov 2, 2026 by lawrencecchen via publish tree-addressed cmux-tui #100459
sentry-dsyms — d80d9fce Deployed Nov 2, 2026 by lawrencecchen via upload cmux-tui dSYMs to Sentry #100459
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:low Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant