ci: point the feat-cmux-next acpmux channel at each daemon-tested tree
Merge held for Leo's OK on trust and security. This adds point-feat-channel to the jobs that get the R2 credentials (the artifacts environment allowlist in tests/test_ci_production_secrets_protected_env.py), and Linux fleet hosts run the build that this channel names (acpmux host self-update, #24232). Codex xhigh review: SHIP at 94897124 (the first, at 0e002721, blocked on a malformed channel file being overwritten without a compare; fixed).
Summary
Leo: "BRO CANT YOU JUST LIKE SUSPEND SHIT AFTER A TOOL CALL/TURN THEN JUST GO AND AUTOUPDATE OUR TEAMMATES NEED ACPMUX UPDATING TOO..."
Leo: "how do we get cmux next users (esp just the team rn) to update to the latest acpmux daemon!?"
Split out of #24232 to keep that PR under the size limit and to review the trust change on its own. #24232's self-update reads this channel; until this lands it finds no channel and changes nothing.
- After a feat-cmux-next push whose cmux-tui tree is published and daemon-tested, the new
point-feat-channeljob incmux-tui-artifacts.ymlpointscmux-tui/channels/feat-cmux-next.jsonat that tree. The file holds the tree key, the commit and the sha256 of eachcmux-tui-acpmux-<target>.- Runs only in
manaflow-ai/cmuxonpushtorefs/heads/feat-cmux-next, inenvironment: artifacts, withpermissions: contents: readandpersist-credentials: false.
- Runs only in
scripts/ci/cmux-tui-point-channel.shmoves the pointer only forward:- it writes when the GitHub compare status from the named commit to this one is exactly
ahead, or when there is no channel file yet; - it leaves the pointer and exits 0 on
behind,identical,diverged, a failed compare, a non-JSON compare answer, a failed channel read, a channel file that names no valid commit (not JSON, no or a malformedcommit), or a tree without thedaemon-tests.jsonmarker; - it writes with a compare-and-swap on the bytes it compared (
upload-r2-object.py --replace-sha256, or--write-oncefor the first file). If another run wrote first, it reads and compares again, up to 5 times.
- it writes when the GitHub compare status from the named commit to this one is exactly
- No concurrency group: GitHub keeps one pending job per group and replaces it with whichever queues next, which can be an older push's. The compare-and-swap makes overlapping runs safe instead.
Leo-ask: ask-48bbaec1d4
Leo-ask: ask-061e3574a6
Leo-ask: ask-98502f19a4
Changelog
- Internal: CI publishes a feat-cmux-next channel file that Linux hosts read to keep their acpmux daemon on the newest daemon-tested build.
Tests
tests/test_cmux_tui_point_channel.pyruns the real script with a fakecurland a fake uploader: first write, forward move, every refusal above, and three race orders. Against the old script from #24232's first head, 15 of its checks fail, including "older run loses the race and moves the pointer back" and a downgrade on a failed compare. Registered aslinux-guard, with a step inci-guards.yml.tests/test_ci_production_secrets_protected_env.pylists the new artifacts job and checks it gets only the R2 upload secrets.
Observed / Not run
- Observed:
test_cmux_tui_point_channel.py,test_ci_production_secrets_protected_env.pyandvalidate_test_execution_registry.pypass on this branch. - Not run: the job itself, which runs only on a feat-cmux-next push.
No capture: CI only.
Agent session: Air-Blue
š¤ Generated with Claude Code