Repository navigation
fix(ci): keep cmux-next minis first through bot retries - #18615
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
|
Found 23 test failures on Blacksmith runners: Failures
...and 13 more test failures. View all on Blacksmith
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 109a9ac. Configure here.
| group: ${{ github.event_name == 'push' && format('cmux-next-push-{0}-swift-test', github.ref) || format('cmux-next-run-{0}-swift-test', github.run_id) }} | ||
| cancel-in-progress: false | ||
| runs-on: ${{ needs.macos-placement.outputs.runner || github.repository_owner != 'manaflow-ai' && 'macos-26' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'blacksmith-6vcpu-macos-26' || vars.CI_PR_POOL_OWNED == '1' && contains(fromJSON('["pull_request","push","workflow_dispatch"]'), github.event_name) && (github.run_attempt <= 2 || github.triggering_actor != 'github-actions[bot]') && vars.CI_SIDE_LANE_RUNNER || vars.MACOS_RUNNER_26 || 'blacksmith-6vcpu-macos-26') }} | ||
| runs-on: ${{ (github.run_attempt <= 3 || github.triggering_actor != 'github-actions[bot]') && needs.macos-placement.outputs.runner || github.repository_owner != 'manaflow-ai' && 'macos-26' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'blacksmith-6vcpu-macos-26' || vars.CI_PR_POOL_OWNED == '1' && contains(fromJSON('["pull_request","push","workflow_dispatch"]'), github.event_name) && (github.run_attempt <= 2 || github.triggering_actor != 'github-actions[bot]') && vars.CI_SIDE_LANE_RUNNER || vars.MACOS_RUNNER_26 || 'blacksmith-6vcpu-macos-26') }} |
There was a problem hiding this comment.
Unwatched retry stays on minis
High Severity
The new run_attempt <= 3 gate keeps a bot retry on needs.macos-placement.outputs.runner through attempt 3, but owned_rerun only watches cmux-next bot retries through attempt 2. The sweeper never adopts that third attempt or creates the attempt 4 Blacksmith overflow, so a refused or queued job can stay on the minis.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 109a9ac. Configure here.
Resolutions: swift-test, daemon-test and generated-files take the placement's gui_runner inside base's minis-first retry gate (#18615): bot attempts up to 3 keep the placed label, attempt 4 overflows to Blacksmith, and the owned-pool fallback is the gui label instead of the generic side label. The compile jobs and the new swift-canary keep the side route. Already on base, so base's copy is kept: the app FFI repin (Package.swift, ci-target-graph.json), the gallery-matrix runner recycle and readiness wait, the icon-picker jump bar and the chief inspector fixture format. The branch's new placement test cases are dropped (no unit tests in cmux-next); base's side-lane placement test now expects the gui label for the three GUI jobs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: screenshot and video tours for cmux-next UI pull requests
A new cmux-next-media workflow builds the head as a tagged dev app on an
owned Mac's gui runner, launches it on a private control socket, drives a
tour through the bundled cmux CLI and captures a screenshot per step plus
frames for a video. The publish job uploads them to pr-media/<pr>/<sha8>/
and keeps one sticky comment on the pull request.
Tours are JSON in scripts/cmux-next/media/tours so other lanes can add
steps. The runner is picked by scripts/ci/cmux_next_media_runner.py and
never falls back to Blacksmith, whose sessions cannot capture.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next resources: fix the Swift 6.2 build (a local shadowed the target function)
ResourceControl.run declares `let target = try await MainActor.run { try
target(...) }`. Swift 6.3 (Xcode 27) resolves the call to the static
function; Swift 6.2 (Xcode 26.3 and 26.6, which the fleet workers use)
resolves it to the local being declared and fails with "generic parameter
'T' could not be inferred", so every fleet build of feat-cmux-next since
3d9c39f failed (fleet job 20ae3ebca821c9f69f0b857f). Call Self.target.
Reproduced and checked with a minimal file under Xcode 26.3 swiftc.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 822db55)
* cmux-next media: probe the capture route, grant screencapture, run pane and tab steps by action id
Run 36903298606: every capture failed with "could not create image from
rect", and pane split-right / tab new-terminal were taken by the daemon
grammar as terminal ids, so those steps run their app actions by id.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next media: publish from the base revision, read the artifact as data, capture through the cua-ssh helper
The publish job holds the pr-media write token, so it checks out its
scripts from the base SHA and validates tour names and shot paths taken
from the artifact. Run 36904395488 showed the gui runner has no Screen
Recording and no passwordless sudo, so the tour also tries an approved
CuaSshScreenCapture.app (main's release-media helper backend), and the
comment says why when nothing could be captured.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next media: address review (cleanup on cancel, window-only capture, inert comment text)
- tour.py: SIGTERM unwinds through cleanup; the app stops before the
recorder; a leftover app or daemon from a cancelled run is stopped
before launch; recording starts once the window is on screen; shots
never fall back to the whole shared display; the probe image is
deleted; the helper runs in the console session; the crop rect is
clamped to the display; the recorder's frame list is locked.
- publish.py: manifest steps are normalized to plain strings and ints,
HTML, Markdown and @mentions are escaped, a bad tour is reported
instead of failing the job, the video has a fixed size, and the head
is checked again right before the comment is written.
- The typing step runs before the new workspace so it lands on screen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next media: a failed upload is reported for its tour instead of failing the publish
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next media: address re-review (newline breakout, frames after the app stops, signal-safe cleanup)
- A newline or CR in manifest text or a command can no longer end the
code span or the table row.
- The recorder stops before the app is killed, so no frame shows what
was behind the window; a window off the display clears the rect.
- Cleanup ignores further signals, and the step execs python so the
runner's cancel signal reaches it.
- The helper's raw desktop image is written outside shots/ and frames/.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next media: write raw captures where the helper can, drop a stale window rect
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next media: start each CI tour from no saved workspaces
The ci-media tag keeps its daemon state in Application Support across
runs, so run 5 launched into run 4's Tour workspace and browser tab.
--fresh-state deletes that tag's state before and after a tour; it is
opt-in so a local run against a developer's tag keeps their workspaces.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next media: stop the tagged daemon before clearing its state; bound ffmpeg
Run 6 still launched into two earlier Tour workspaces: the daemon
outlives the app and keeps its workspaces, so deleting the state
directory under it changed nothing. The tour now ends the tagged
daemon through its socket (server stop --end-terminals) before the
pkill fallback and the state removal. An untagged build's daemon is
the user's and is never stopped.
Run 6's publish job spent its 15 minutes in apt installing ffmpeg.
The install is now capped at 4 minutes and may fail (the comment then
has screenshots and no video), and nothing installs when the base
revision has no publisher.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next media: cap a tour's video at 600 frames
A stuck tour recorded a frame every half second for as long as it ran.
The recorder now stops at five minutes of frames and the publisher's
ffmpeg reads no more than that, so neither the runner nor the publish
job grows with a slow tour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: format staged files before commit (#18808)
* ci: format staged files in the trusted pre-commit hook
* ci: guard formatter scope for staged files
* ci: scope Rust formatter guard to its package
* ci: use direct rustfmt and skip merge formatting
* ci: pass the cmux-tui Rust edition to rustfmt
* ci: check rustfmt on the cmux-tui packages a PR touches (#18800)
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: check rustfmt on the cmux-tui packages a PR touches
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit
The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): leave the relay circuit to its own repair
Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next (#18781)
* ci: add mini-first Swift canary for cmux-next
* ci: remove unit tests from Swift canary change
* cmux-next: repin app FFI to current base release (#18776)
* cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698)
* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree
#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui
Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-next): the newest-published search deepens only this commit's history
A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ci): keep cmux-next minis first through bot retries (#18615)
* docs(cmux-next): map UI parity reference sources (#18561)
* docs(cmux-next): map UI parity reference sources
* docs(cmux-next): add media preview reference source
* docs(cmux-next): define reference freshness checks
* fix(nightly): bound the publish notes step at 10 minutes (#18404)
* test(nightly): the notes step cannot spend the publish budget before the upload (red)
Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(nightly): bound the publish notes step at 10 minutes
The notes take seconds since 0115b26. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622)
* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself
Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): the tree gate watches the base and may pin the tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree
When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a transient wrong binary read must not fail publication
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read a mismatched published binary again before failing
R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): a pull request gate pins a tree its base never builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): a pull request gate pins a tree its base never builds
A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retain base tree dispatch tests
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states (#18901)
* ci(gallery): capture narrow responsive states
* test(gallery): cover workflow matrix changes
* fix(gallery): dedupe equal responsive widths
* ci: shard gallery matrix renders
* ci: retrigger sharded gallery validation
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* test(webviews): keep diff Escape in its document realm Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(webviews): bind diff Escape to its document window Use the panel's owner document for focus and its realm's window for key events. Full webviews tests mount several JSDOM documents concurrently, so ambient globals can otherwise strand the panel's Escape listener on another window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(webviews): regenerate agent pane bundle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate web bundles after base merge * chore(cmux-next): regenerate the agent pane and page bundles * chore(cmux-next): regenerate bundles after base merge * chore(cmux-next): regenerate bundles after base merge * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#18214) * test(cmux-next): queued prompts are numbered rows on the composer box's top edge (red) The queue becomes part of the composer box, numbered, and shows a prompt's full text only when its line is cut off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: queued prompts become compact rows attached to the composer The gray Queued box gives way to numbered one-line rows on the composer's top edge, inset so the box's rounded corners lead into them. The list lies over the transcript's foot instead of taking layout space, so queuing, sending or removing a prompt never moves the composer or the transcript. A prompt shows its full text as a tooltip only when its line is cut off. The gallery gets queued and queued-long variants, with the composer box as a strict anchor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* feat(cmux-next): add project badges and checked state * refactor(cmux-next): share project badges across pickers * test(cmux-next): cover project chooser in gallery * fix(cmux-next): type project chooser gallery props * chore(cmux-next): regenerate the agent pane bundle * chore(cmux-next): regenerate the agent pane bundle after base merge * chore(cmux-next): regenerate the agent pane after latest base merge * gallery: fix project chooser entry imports * style: format project badge * cmux-next project chooser: add keyboard-first project panel Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * gallery: wait for add project panel states * gallery: stabilize add project step plays * gallery: keep add project panel geometry stable * composer: show setup-required project sources * feat(cmux-next): add keyboard-first project panel Add a Base UI command panel for environment, source and folder selection with fixed geometry, keyboard hints, setup-required sources and gallery variants. Existing native project.browse remains the production fallback until a reviewed directory-list host operation exists. * chore(cmux-next): regenerate the agent pane bundle Generated remotely from the exact Add Project panel head. * chore(cmux-next): keep generated bundles at base * ci: retrigger full PR workflows * fix(cmux-next): refresh agent pane string catalog * fix(cmux-next): use semantic project status output * fix(cmux-next): harden add project panel * fix(cmux-next): sync pane strings after base merge * fix(cmux-next): route project shortcuts through ui scope * fix(cmux-next): skip disabled project choices * fix(cmux-next): preserve disabled option semantics * test(next): cover add project menu behavior Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sal (#18287) * test(cmux-next): a Release reload builds acpmux and optchat-chief universal Red: reload.sh lets both default to the host architecture, so the fleet --release build of 0fb1b4b (job f03724be4852) failed in Bundle acpmux: acpmux has architectures arm64, but the app needs arm64 x86_64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): Release reloads build acpmux and optchat-chief universal Release is universal, and the Bundle acpmux and Bundle optchat-chief phases need every app architecture, but reload.sh let both helpers build for the host only. On Release it now asks both for arm64 and x86_64 unless the caller chose. Both caches are keyed by architecture, so the arm64-only copy is not reused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * cmux-next: credential.session answers the backend team of the install token (cx-i6g4) The session answer the Cloud app server shows in cloud.auth.status named the Stack team id (auth.teamID). It now answers the install token's team claim, the backend team the relay bills; nil when no token can be minted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-vm): delete the cmux VM unit tests (cx-034r) Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now"). workers/cmux-vm only. Deleted: - Worker: test/workers ledger, naming, proof-evidence and the quotas case of create-options (they call src directly); test/node entitlements, mesh-acl, mesh-m4-units, service-keys and the refusal cases of mesh-signed-request (the route tests in test/workers prove the same refusals over HTTP: forged, tampered, stale and replayed signatures, bad keys and scopes, unsigned webhooks); - SDK: sdk/test/client.test.ts (fake fetch), its bun test step in cmux-vm-clients.yml, its test script and tsconfig include; - CLI: in-src tests of cmux-vm-codegen normalize; - mesh agent: tests/config.rs. Kept: - every test/workers route test (requests through the Worker's fetch handler with a fake upstream); - the PGlite store and schema-gate tests (the release rails run them against the real migrations: production guard); - upstream-coverage (guard), test/types (compile-time proof misuse); - the golden install-key signature vectors shared with the mesh agent; - cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs (CLI vs openapi.json); - mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979 vectors), tests/loopback.rs (two WireGuard peers over real UDP). Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src + 16 tests/ deleted. * test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20) Ports classic 3fcc2aa, 6802308, b381770, 719e060, 5716dc9, 9423c74, 1872ac1, c7c4bc9, 1d654fc, d841f14 and 3fb6fa8: - page.markdown charges child lists, text, values, URLs, table padding and list and quote indentation to one budget over all frames, reads frames one after another with what the ones before left (at most 100), finds <main> by a charged walk, reads slots one node at a time, and ends a cut page with the read-cut note. Iframe placeholders carry a random mark made in the agent world, so page text cannot spell one, and page NULs become U+FFFD. - searchText reads the text within the budget, contexts at most 1,000 characters a side, matches at most 1,000; extract and dropdownOptions read within it and cut text before they normalize it. Each prints where it stopped. - session.storageState reads localStorage within one budget over at most 100 frames and refuses past it rather than save part of a state. - tabs.content reads text and HTML in the agent world within a 2,000,000 character budget split over the URLs; markdown and snapshot formats use their own budgets. page.exportContent writes page.markdown() under a title cut at 500 characters (the unbounded page-world pageMarkdown goes). - A snapshot header cleans at most 4,000 characters of a title or URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12) Ports classic a02e2b8 and b275d15. iframeHandles walked every element of the parent recursively into each shadow root on every action in a child frame (scrollIntoView of each owner <iframe>). The child now says its place in the parent's window.frames (framePosition, an observe read); the parent checks its light-DOM <iframe> and <frame> elements one at a time from the live collections, and only for a frame in a shadow tree walks its elements iteratively, all within at most 250,000 nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red) The 20,000 nested shadow root cell is replaced: Playwright's own selector engine overflows its stack there before the owner lookup runs, so it could not show the item 12 change. Item 12 is checked by clicks in a light-DOM iframe and in an iframe inside a shadow tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review) Review of the batch 2 port: - tabs.content { format: "html" } read the document in the agent world around frame.observe, so a password field's value attribute came back unmasked. It now calls documentHTML (page.content's read, scrubbed) with the URL's share as its size budget. - session.storageState counted every open frame against its 100-frame bound before it knew the frame's origin, so a session with many ad iframes failed and { urls } did not help. Frames whose origin is out of scope or already read are skipped and not counted. - tabs.content titles are cut as plain text (a cut marker before the reply margin left nothing), and a snapshot-format row names the snapshot's own stop reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* refine agent composer context surface
* show composer controls in the toolbar
* update composer layout assertion
* cover visible access mode label
* format unified composer markup
* test: cover model picker Escape away from search
* fix: close model picker on Escape from any control
* fix: keep unified composer radius tokenized
* test(gallery): cover composer scope row states
* test(gallery): use public composer fixture labels
* plans(projects): daemon-owned project store with source adapters, event-driven resync, merge rules (cx-m0p7 design)
* test(cmux-tui-core): project list reducer merge rules and user edits (red, cx-m0p7)
* feat(cmux-tui-core): project list reducer: sources, user overlay, missing state, refusals (cx-m0p7 slice 1)
* style(cmux-tui-core): rustfmt the project reducer
* style(cmux-tui-core): rustfmt state.rs module list
* feat(cmux-tui-core): project-list-v1 store, ops and spec: project.list/observe/add/update/remove/sync (cx-m0p7 slice 1)
* fix(cmux-tui-core): collapse the project rename check (clippy)
* fix(cmux-tui-core): project store clippy (semicolons; source toggle helpers wait for slice 3)
* fix(cmux-tui-core): semicolon on the project row parse warning
* refactor(cmux-tui-core): request ids move to resource/request_id.rs (move-only) so resource.rs stays under the god-file limit
* test(cmux-tui-core): project list review cases: idempotent observe, null clears, case-insensitive refusals, disk facts from the caller, cap (red, cx-m0p7)
* fix(cmux-tui-core): project store reads no disk for observed paths, null clears, idempotent observe, case-insensitive refusals, cap, disk facts from the app (review, cx-m0p7)
* chore(godfiles): resource.rs meets its budget (row dropped)
* CmuxNext: failing tests, a split shows a provisional pane before the reply (S3 T1, store)
* CmuxNext: a split intent shows a provisional pane beside its target until the daemon's pane with the same public id replaces it (S3 T1, store)
* cmux-layout-reducer: failing test, SplitNew puts a new pane with a new tab beside the target (S3 T3)
* cmux-layout-reducer: SplitNew, a new pane with a new tab beside the target (S3 T3); covered by the random op sequence property test
* S3: the optimistic split matches the Rust reducer's SplitNew vectors (L4 parity: Rust generator with drift check, Swift reader)
* S3 tests: optimistic Cmd+D on a client-keys daemon (T1 app, T2 store frame budget), provisional pane mapping continuity, target gate and typeahead order (T7)
* CmuxNext: Cmd+D shows the new pane before the reply on a split-client-keys-v1 daemon; its terminal view waits for the daemon's terminal and keeps keys typed meanwhile (S3)
* S3: provisional terminal view helpers in their own file; test daemon record as a Sendable box
* S3: TabContentCache within its size limit; the test daemon serves terminal-placement-env-v1
* cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay
* cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe
* cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders)
* S3: drop the unit tests and the reducer op (NO UNIT TESTS rule); verification moves to the tagged app via the debug socket
* cx-m0p7 store: socket-level behavior test on a real daemon replaces the in-process unit tests (NO UNIT TESTS)
* cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS)
* cx-m0p7 store: the socket test picks a non-temporary folder
* cx-m0p7 adapters: the socket test picks a non-temporary folder
* S3: tagged-app proof harness (Cmd+D through debug.key, read-screen) and its results
* S3: the provisional split maps columns and rows instead of indexing them (crash ratchet)
* cx-m0p7 store: keep LocalOperation in resource.rs (boundary check reads it); move encode_hex out for the god-file limit
* S3: SpawnOptions drops unserved fields itself (DaemonConnection stays within its size limit)
* fix(cmux-next): WebKit right and middle buttons: right presses go in as AppKit right-button events, a middle press carries button number 2 on its own Quartz form (DOM button 1), wheel events take the Quartz location AppKit gives the window point, and the web view empties the context menu of a right-click the app did not dispatch, so an agent's right-click opens no native menu (cx-ollo)
* cmux-next: harden the credential relay and the Cloud create approval (cx-t2rz security review)
P2-1: the relay serves only the app cmux/cloud and only cloud.* ops
(credential.app_refused / credential.op_refused otherwise): an install
token with origin user counts as the person on the Worker, so no other app
or op family may borrow it.
P2-2: before feed.answer the app reads integration.approval.get as the
person and requires op cloud.machine.create, state pending and exactly the
params the person confirmed; the feed item must carry the same request
and digest, tool cloud.machine.create, and poster system:cloud:<team>.
Any mismatch answers nothing and shows why. The confirmation shows the
machine size and name.
P3-1: the relay registers only on the app server link path (never with
the legacy default or in release).
P3-2: a create from the progress view's Retry (no gesture origin) asks
the person first; only an action with origin user skips the sheet.
P3-3: the session call for the approval refuses redirects and keeps no
cookies or cache.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): short update titles; the test feed and announcements are notice cards
Chief 2026-10-09 (round 2 of Lawrence's update card ask).
- Update titles are short and the version moves to the detail line:
"Update Available" / "Version 1.0.0-nightly.…", "Update Check Failed",
"Needs macOS 27.0 for …". Before, "cmux 1.0.0-nightly.376…" and
"Couldn't Check for Up…" truncated in a 260 pt sidebar. UpdateNote's
needsNewerMacOS carries the found version. 4 new strings (en + ja,
19 languages needs_review).
- The test-feed notice (Use Real Feed, no x) and the announcements (their
allow-listed Try It, an x that dismisses for good, the next one shows)
are the shared notice card. Order: update status, test feed,
announcement, tip; the "cmux Updated!" card waits while an update
status or a test feed shows.
- The plain R114 card stack is gone (SidebarCard, SidebarCardView,
SidebarCardStackView, SidebarCardStackLayout, SidebarModel.cards and
onCardAction); its hover test goes with it. The footerCards slot stays.
Announcements now show whether or not the sidebar chrome is revealed.
- NO UNIT TESTS (Lawrence 2026-10-10): the unit tests this change breaks are
deleted in this diff (UpdateNoticeTests and its ManualClock copy, from
31d888016eed / d344241b7a88; the stack hover test; two stack-card
asserts). Proof is the tagged app on cmux-lawrence-2 through the debug
socket with screenshots.
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): a check while an update waits shows the waiting update
Lawrence's NIGHTLY (2026-10-09/10): 3797671859401 was downloaded and
waited for a restart; Sparkle skips every check while an update waits
("update check ignored while install is progressing"), so his manual
Check for Updates showed nothing and never saw 3800566557701.
- Check for Updates while an update is staged does not ask Sparkle (it
would ignore the check); it logs and answers with the staged update.
- The staged update card ("cmux X is ready", Restart to Update) shows
after such a check even under updates.notify silent, which otherwise
hides it. Before, a silent install had no answer to a check at all.
Proof: tagged app on cmux-lawrence-2 through the debug socket (staged
update + notify silent: no card; Check for Updates: the card), with
screenshots. No unit tests (Lawrence 2026-10-10).
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(nightly-next): keep the acpmux and OptChat Chief dependency builds between nightlies (cx-g34i)
build-nightly-app compiled every Rust dependency of acpmux (53 s + 46 s, two
arches) and the OptChat Chief (24 s + 24 s) from scratch on each nightly-next
run, on the serial path before the Release build. Swatinem rust-cache on their
target dirs (cmux-tui/target/acpmux-app, optchat-chief/target/app), nightly-next
track only; cargo rebuilds what changed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): drop the hand-written operation and command counts (cx-034r)
Unit-test deletion lane, slice 3 (chief order): every lane that added an
op had to edit 4+ files with a hand-written count (palette hit 211, 212,
213). The generated-from-spec checks (spec inventory, SDK sync, the set
equality of generated commands and the IR) already prove coverage.
Removed, no other assertion changed:
- cmux-tui-core resource_router tests: operations.len() == 213 (2x);
- cmux-tui transport path coverage: cases.len() == 188, catalog 213;
- check-resource-api-boundary test: operations 213;
- conformance runner: TRANSPORTED_OPERATION_COUNT (now: a non-empty
catalog), and its test;
- SDK raw coverage tests: command count 236 and event count 69 in C++,
Go, Java, Python, TypeScript, Zig (src and the watch example);
- spec/resource-operations-v2.md names the JSON catalog, not a number.
Pure assertion deletion: no red test first. 0 tests deleted, 0 added
(test count before == after).
* cmux-next: S3 optimistic Cmd+D off by default (cx-wb5.72)
Keys typed right after Cmd+D lost the tail of the line in 1 of 8 proof
runs. Every daemon now serves split-client-keys-v1, so the capability gate
protects no one. PaneSplitCommand.optimisticSplitEnabled = false sends every
split through the old path; the landing with the ordering fix sets it back.
split-optimistic-proof.py records the path each Cmd+D took and takes an
expected path (optimistic|old) as a gate argument.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): failing tests for automations, runs and bodies in rows (g1)
Head under 100 KB with 100 automations of 20,000-character instructions
and 450 kept runs; bodies stored once with reference counts; keyset
paging for automation.list and run.list stable under inserts; run.get
joins the body; migration of an old JSON head is idempotent on a live
DO and after a rollback refill; disable, delete and a policy deny
cancel every queued run. Deterministic: reads answer without an ok
field, the cancelled-run check uses a sleeping first run, the migration
check binds the object before it reads the head.
Re-applied from orphaned fe31fa1f0ed8 + 467e890d7cb1 (cx-3bi.38).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(scheduler): automations, runs and bodies in rows, keyset paging, live migration (g1)
SchedulerDO moves to row mode (plans/cmux-next/backend.md (g), DO audit
F-1). automation/<id> and run/<id> rows hold the records without their
bodies; body/<sha256> rows hold each distinct body once with a reference
count (automations plus kept runs) adjusted in the same commit; a
finished/<run> index lets prune drop the oldest finished runs past 200
without reading the open ones. A started run keeps its body hash. The
head keeps owner, settings, counters, chains and the counts
automation_count, open_runs, finished_count, row_seq. All four tables
are private, so events and snapshots carry the head only.
One lookup module (domains/scheduler-rows.ts) and one per-op store
(domains/scheduler-store.ts) replace every read of state.automations and
state.runs. New reads run.list and run.get; automation.list pages with
cursor and limit and its first page is unchanged. System op
scheduler.rows_migrate (key carries the head seq) rebuilds the rows from
an old head's maps on bind and drops the maps in one commit; the alarm
path migrates first too.
Re-applied from orphaned 7ab757b458e5 onto feat-cmux-next (cx-3bi.38).
run-policy.test.ts keeps the tip's createWithTeamDown helper (cx-nfts)
and reads next_at from the automation row. Catalog, TS client, Rust
cloud-wire client, app-host ops/scopes/d.ts and the bundled AppPlatform
scopes.json are regenerated with the repo generators, not hand-merged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): failing tests for the g1 review findings
A run pruned while the dispatch loop awaits a create is skipped and
onWake goes on; a refilled head migrates by merge (maps win per id, rows
the maps lack stay with their bodies); reads on a legacy head answer the
retryable owner.migrating; run.list with a sparse filter over more than
200 kept runs scans every step and ends without an empty last page.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(scheduler): g1 review: stale dispatch rows, merge migration, legacy reads, paging
- onWake re-reads each run before it builds the dispatch params: a
disable, delete or deny during an earlier create may have cancelled the
run and prune may have dropped it with its body, which made requireBody
throw and stop the wake. A missing, started or terminal run is skipped.
- scheduler.rows_migrate merges a refilled head instead of replacing the
rows: the maps win per id, rows the maps lack stay with their stored
bodies (dropped only when that body row is gone), and every body
reference count is recounted.
- Reads on a legacy head answer the retryable owner.migrating, the same
as the reducer.
- run.list looks one match ahead, so a page that ends the list has no
cursor to an empty page.
- automation.list keeps automation_count and next_cursor optional while
an old Worker can answer (deploy skew); catalog, TS client, Rust
cloud-wire client and app-host outputs regenerated.
- plans/cmux-next/backend.md (g): roll-forward only, merge semantics,
and the operator recovery when a pre-g1 build meets a migrated head.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): drop the engine-level g1 unit tests (NO UNIT TESTS rule); the SchedulerDO op tests stay as the behavior proof
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* scheduler: regenerate the cloud-wire Rust client and the bundled AppPlatform scopes.json after the rebase
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next: a Cloud create approval must be for the create's own team; the mismatch text stays localized (cx-t2rz review)
The approve step takes the backend team the relay's create bills (the
install token's team claim, captured when the create starts) and requires
the feed item's approval.team to equal it, so an identical create pending
in another team the person belongs to is never approved. The mismatch
reason goes to the log only; the person sees the localized text.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* scheduler (cx-3bi.38): regenerate the cloud-wire Rust client on the tip
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(rd-host): bench sends synthetic upstream frames; upstream loopback check (red: no host sink) (cx-9zn)
cmux-rd bench --upstream mic|camera|screen opens an upstream stream, sends
synthetic frames through cmux-rd-core's UpstreamSender with the host's
feedback, and reports frames sent/acked and an FNV-1a hash.
scripts/upstream-loopback.sh expects a host with --upstream-record DIR to
record every sent frame; red until the host has the recording sink.
* feat(rd-host): --upstream-record DIR development sink for viewer upstream media (cx-9zn)
The desktop host offers up_media only with a sink; it had none (NoSink),
so no viewer could send its microphone, camera or screen anywhere. The new
RecordSink (development only, off by default) writes each upstream stream
to an owner-only file (Annex-B .h264, length-prefixed .opus-packets) and
logs frames, bytes and an FNV-1a hash on close. The sink is chosen per
session; without the flag the host still offers no upstream caps.
* fix(cmux-next): the diff sidecar keeps its pipe readers until end of file
DiffSidecarProcess released the Process at the child's exit, and with it
the Pipes and their read FileHandles. When the exit was handled before the
stdout end-of-file event, the FileHandle closed its descriptor and the EOF
never came: the reply never finished and the caller waited for the request
deadline (130 s; a 60 s hang of writesTheRequestAfterTheReadyMarker... on
the ManualClock, 7 times on 2026-10-09). The invocation now holds both read
ends until each reads EOF, and releases them when the launch fails.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* fix(cmux-next): a cloud edit marks the source degraded before it subscribes
requireEditable started the conversation's subscribe and only then set
degraded. A subscribe that went live in between called recover() on a
source that was not degraded yet, so no .ownerRecovered went out and the
edit waited for a recovery nothing would send (CloudHomeSourceTests
withoutAnEchoTheEditSubscriptionEndsAtTheDeadline, 60 s, once under load).
The flag is now set in the same lock as the target read.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* test(cmux-next): live-daemon suites wait for the daemon's events, not deadlines
The harness connection (and QuitSessionsTests' relaunch connections) send
no client deadline: each request waits for the daemon's reply, so
create-terminal returns when its host is up. The 30 s bound of 57a5a8129382
only moved the line a loaded host crossed at 5 s. TerminalHosts.awaitExit
waits for kernel exit events (one process source per pid) instead of a
50 ms kill(0) poll; its 30 s bound and the suites' .timeLimit are only hang
guards.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* test(cmux-next): the palette benchmark measures the thread's CPU time
The budget read wall time, which counts time the thread waited for a core:
with 32 suite processes on one host the ranking median read 123 ms (54.8 ms
in another run) against 50 ms. The ranking runs synchronously on the calling
thread, so its CPU time is the search cost.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* fix(rd-host): review fixes for the upstream record sink (cx-9zn)
Review subagent should-fix items: the record dir must be a real 0700 dir
owned by this user; a per-session byte limit (--upstream-record-max-mb,
default 1024) and 64-file limit; a sink that cannot start falls back to
NoSink instead of dropping every viewer; unique file names; Drop logs
open streams. Bench uses the welcome's max_datagram. upstream-loopback.sh
counts host lines per run (a failed run no longer shifts later checks),
accepts paced drops, and takes PORT/PORT_NOSINK.
* test(cmux-tui): delete the unit tests of 18 leaf crates (cx-034r)
Unit-test deletion lane, slice 4a (Lawrence 2026-10-10, "Delete all now").
In-src #[cfg(test)] tests and the tests/ files that call library code are
deleted in cmux-motion, cmux-history, cmux-conversation, cmux-chat-index,
cmux-terminal-iface, cmux-terminal-sizing, cmux-tui-cloud-conversations,
cmux-theme-tokens, cmux-agent-pane-policy, cmux-tasks-core, cmux-tasks,
cmux-app-manifest, cmux-chief, cmux-terminal-client, cmux-mobile-core,
cmux-mobile-ffi, cmux-unix-socket and ghostty-vt.
Kept (boundary or cross-language contract):
- ghostty-vt tests/ (bytes in, terminal state out; chief ruling);
- cmux-terminal-client tests/route_e2e.rs and cmux-tasks tests/server.rs
(real sockets end to end);
- shared corpora and fixtures another language replays:
cmux-conversation conformance, cmux-chief corpus, cmux-agent-pane-policy
parity + typescript, cmux-history fixtures, cmux-theme-tokens load,
cmux-mobile-core terminal sizing fixtures, cmux-app-manifest schema
fixtures + samples, cmux-tasks-core catalog (catalog <-> Op guard).
cfg(any(test, feature = "test-support")) narrows to the feature.
cmux-tui.yml: the Windows step drops cmux-chat-index, which has no tests.
Deferred to slice 4b (security and malformed-input cases need a boundary
test first): cmux-local-auth, cmux-relay, cmux-tui-machine-protocol,
cmux-tui-machine-agent-protocol, cmux-transport, cmux-encode, cmux-wg,
cmux-link.
Counts: 327 in-src tests and 189 tests/ tests deleted (516); 55 files deleted.
* cmux-tui: two terminal_host_recovery load flakes made deterministic (cx-2dc4)
pipelined_new_tabs_start_hosts_in_parallel_in_request_order asserted a
wall-clock bound (8 hosts x 400 ms ready delay < 3.2 s), which IO and CPU
load broke (40/40 red on a loaded Testbox). A debug-only host seam,
CMUX_TUI_TEST_HOST_READY_GATE, now holds every host before Ready at a FIFO
the test opens later; all records on disk while the gate is closed prove
the launches overlap, and identify must reply while the creates wait.
host_crash_is_named_with_its_panic_message: the abort seam fired 300 ms
after install, racing the owner's PTY custody (no custody, no replacement,
no host_replaced line), and systemd-coredump of the aborted 1 GB debug host
kept it alive 3-6 s under load. The seam now crashes when the test opens
<marker>.trigger, after wait_for_daemon_custody saw the daemon hold the
master and its custody thread (renamed pty-custody, visible in /proc) end,
and it disables core dumps before abort.
Loaded Testbox runs (32 vCPU; P=8+32 hogs, P=24+96 hogs+8 fsync dd,
P=16+32 hogs+workspace build): before 40/40 and 3/40 red; after 0/120 each.
* cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1
* test(cmux-tui): server-stats write_path counters and the effect intent socket check (red)
Add the optional server-stats section write_path (include-gated, like
resource_projection, so older SDK decoders stay safe): effect receipt
commits carried by journal writer batches, their savepoint failures,
the batches that carried them, effect receipt commits that ran their own
transaction on a request thread, and registry lock acquisitions on a
journal writer thread (counted in release builds, process-wide).
The new socket test drives a headless daemon: terminal creates under
terminal output must commit their effect receipts as writer intents,
with no request-side effect commit and no writer registry lock. Red
today: effect_store still commits each receipt in its own request-side
transaction and fsync (effect_intents stays 0).
Spec: commands.md and sdk-schema.json gain the section; bindings
regenerated.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-tui): effect receipt commits ride the journal writer batch
effect_store commit_resource_effect and commit_resource_effect_patch
become typed writer intents (journal ingress Effect events on the
durable lane). The request thread prepares the intent under the
workspace registry (validation, stored fingerprint, public-fold pruning),
the journal writer applies it inside its batch transaction under a
SAVEPOINT per intent (one shared fsync per batch), and the request
thread finishes it (projection stats, public fold) under the same
registry hold. An intent that fails its checks rolls back to its
savepoint and only its request gets the error; a SQLite failure still
fails the batch, which the writer retries or splits as before.
Lock order is unchanged: workspace registry -> registry connection ->
state. commit_resource_effect_projection drops state and the connection
pin before the receipt wait, keeps the registry (topology writers stay
serialized), and re-locks state to install the revision. The receipt
wait uses the producer deadline and commit fence: a writer error, a
dropped receipt or an expired deadline returns an error and releases
the registry. Prepare and executing transitions stay request-side.
The writer marks its whole loop iteration (batch, commit, retries,
receipt delivery) as the journal writer, so a registry lock there is
asserted in debug and counted in release (server-stats
write_path.writer_registry_locks, checked over the socket). Local commit
fallback (counted as request_effect_commits): writer disabled, stopped,
failed, not running yet, or the calling thread still holds the
connection.
The registry lock, the journal writer iteration and the registry
connection take lock ranks in the lock-rank checker (crate::lock_rank:
workspace.registry > journal.writer > registry.connection > mux.state),
so debug and test builds panic on a registry lock on the writer thread
on every path, in addition to the release counter.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): wait for template terminal adoption after a daemon restart
adopted_template_terminal_is_restored_in_place_after_a_daemon_restart read
the parked terminal's lifecycle once, right after the restart. Adoption
completes asynchronously (the terminal reads "adopting" until its host
handshake lands), so under a loaded gate run the read raced it and saw
"adopting". Wait for "running" with the file's bounded helper.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(browser-parity): snapshot reads beside the walk stay within the page-read budget (cx-2y2 red)
Scenario 41 drives the REPL against hostile pages: a data table judged by
its first 50 rows, an offscreen count past the node budget, a zero-size
link's visible-box check, a link URL longer than the size budget, and
generated content, placeholder, option label and editable text past it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): snapshot reads beside the walk stay within the page-read budget (cx-2y2 items 6, 10, 11)
Ports classic 7f37c374e9f5, eeb6d5105161, 7dfa50c0910b and 84bd76a4e8e7:
- A zero-size link's visible-box check charges each node it looks at.
- Offscreen interactive elements are counted lazily within the node
budget and the clock; past them the viewport note says "at least".
- Layout-table detection reads a sample: 50 children, rows and cells per
row, and 1,000 descendants for a nested table.
- Generated content is read one character at a time, at most as far as
the size budget can use; a placeholder and an option label are cut
before they are normalized; option text and editable text are read
within what the snapshot has left; an ARIA value is cut at 20,000.
- A link URL longer than the size budget has left is not resolved or
parsed (no offsite summary); a URL that fits is parsed once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a snapshot of names that share one huge label stops at the node budget (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): snapshot names read their sources within the page-read budget (cx-2y2 items 8, 9)
Ports classic 7b0f1a7a87a6, bcd5ad8bc5d8, 61b3f78a30d2 and part of
7dfa50c0910b. Before Playwright computes a name, the sources it would read
(aria-labelledby targets, at most 64; labels; own content for roles named
from content; legend, caption, figcaption; shadow content, slotted nodes,
aria-owns targets, name attributes, field values, generated content) are
counted within NAME_NODES 2,000, NAME_CHARS 20,000 and NAME_DEPTH 100, the
nodes outside the element charged to the snapshot's budget. Past the
bounds the name is read directly from the same sources, node by node and
charged. Author names, the select value and elementAt names use the same
bounded reads. A slot's assigned nodes are read one at a time (slotAssigned)
instead of assignedNodes(), which lists them all first.
Scenario 41 adds 1,000 buttons named by one shared 50,000-node label: the
snapshot stops at the node budget at once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): locator reads, allTextContents and page.content of a huge page end where the page-read budget stops (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): locator reads, allTextContents and page.content read within the page-read budget (cx-2y2 item 13)
Ports classic d3d04bf299db. locator textContent, innerText, innerHTML,
getAttribute and inputValue call the page agent's readBounded,
allTextContents and allInnerTexts call readAllBounded (one budget for all
elements; elements past it read ""), and page.content calls documentHTML.
Each reads with the bounded DOM readers (item 3) and answers { value, cut };
a cut value ends with "…" and the runtime prints where it stopped. Before,
these returned whole DOM strings across the evaluate boundary.
frame.observe allows the three new methods (src/observe.rs, the dev driver
and plans/cmux-next/browser-host.md), scrubs sensitive values from their
results like read, gives readBounded of a sensitive field's inputValue or
value attribute the marker at once, scopes readAllBounded to its elements
and documentHTML to the whole frame. The reference host redacts them too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(browser-host): a name past the budget cut never falls back to Playwright's unbounded read (cx-2y2 items 8, 6 review)
Review of the item 8 port: after a node cut the walk still reads the
elements it scheduled, and each one's aria-labelledby list came back empty
(spend failed), so nameFits passed and Playwright read the label whole for
every remaining element (1,000 buttons sharing a 50,000-node label hit the
30 s evaluate timeout). Now a read past a cut, or an aria-labelledby list
with ids left (past 64 or past the budget), takes the bounded name. The
NAME_DEPTH count no longer drifts at a nested <select>, and the visible-box
check of a zero-size link walks iteratively.
Scenario 41 checks generated content, placeholder, option label and
editable text each in its own snapshot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a short secret in a read's HTML is masked; each big value cuts on its own read path (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next: credential.session answers the backend team of the install token (cx-i6g4)
The session answer the Cloud app server shows in cloud.auth.status named
the Stack team id (auth.teamID). It now answers the install token's team
claim, the backend team the relay bills; nil when no token can be minted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(browser-host): frame.observe masks a short secret's value attribute in HTML results (cx-2y2 item 13 review)
A sensitive value of 1-3 characters was replaced only as a whole string,
so innerHTML and documentHTML (page.content, now an observe read) kept it
in value="...". The scrub now also replaces those values in their
attribute form. _printReadCut moves above _raceDialog's comment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release-notes: agent page reads stay within the page-read budget (cx-2y2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(agent-chat, cmux-tui web): delete the unit tests (cx-034r)
Unit-test deletion lane, slice 6 (Lawrence 2026-10-10, "Delete all now").
agent-chat: 63 of 65 test/*.test.ts files deleted (function, adapter,
store and component tests against in-process fakes) plus the fake ACP and
Codex harness scripts only they ran. Kept: listener-auth.test.ts (a real
server process over raw HTTP: token, Host and Origin refusals) and
cmux-chat-argv.test.ts (runs the cmux-chat script: the token never reaches
a child's argv). The manual *.e2e.ts scripts against a running server stay.
The Claude launch environment policy keeps its generator check
(generate-claude-launch-environment-policy.py --check); its unit test and
the workflow_guard_groups.py entry for it go.
cmux-tui/frontends/web: all 37 Vitest/jsdom files and test/setup.ts
deleted; the Vitest config, the test script and the tsconfig test include
go. cmux-tui.yml runs check and build for the web frontend.
Before: 102 test files (about 322 bun test cases plus plain assertion
scripts); after: 2 files.
* ci(cmux-tui artifacts): cmux_next_ daemon tests in one cargo invocation (cx-g34i)
After 5f9ff5c667e8 the separate `-- --list` pass and the real run each built:
the second rebuilt acpmux and cmux-tui for 2m39s (run 38014219284; the first
build was 6m36s, was 11m31s with --workspace). One cargo test run, teed; a run
that passed no test is still red.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(web): drop the agent-session-web job whose tests are gone; vp fmt two kept checks (cmux-next web red) [cx-4g8w]
975d40047a3f deleted webviews/src/agent-session/shared/*.test.ts, so
`bun test webviews/src/agent-session/shared/*.test.ts` matched no file and
agent-session-web-resources failed on every routed push. The job ran only
that command: remove it, its package.json script, its web-status entry and
the CI structure assertions that named it. The same commit left a trailing
blank line in desktopLayer.test.ts and pane-english.test.ts, which vp check
refuses (react-apps-check red).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-vm): delete the cmux VM unit tests (cx-034r)
Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now").
workers/cmux-vm only.
Deleted:
- Worker: test/workers ledger, naming, proof-evidence and the quotas case
of create-options (they call src directly); test/node entitlements,
mesh-acl, mesh-m4-units, service-keys and the refusal cases of
mesh-signed-request (the route tests in test/workers prove the same
refusals over HTTP: forged, tampered, stale and replayed signatures,
bad keys and scopes, unsigned webhooks);
- SDK: sdk/test/client.test.ts (fake fetch), its bun test step in
cmux-vm-clients.yml, its test script and tsconfig include;
- CLI: in-src tests of cmux-vm-codegen normalize;
- mesh agent: tests/config.rs.
Kept:
- every test/workers route test (requests through the Worker's fetch
handler with a fake upstream);
- the PGlite store and schema-gate tests (the release rails run them
against the real migrations: production guard);
- upstream-coverage (guard), test/types (compile-time proof misuse);
- the golden install-key signature vectors shared with the mesh agent;
- cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs
(CLI vs openapi.json);
- mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979
vectors), tests/loopback.rs (two WireGuard peers over real UDP).
Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src +
16 tests/ deleted.
* test(bindings): delete the SDK inventory pin test (cx-034r)
Follow-up to eae755077987, which removed the hand-written command and
event count pins in the SDK tests: test_sdk_inventory_pins.py checked
those pins against the schema and is itself a count-pin test, so it went
red on the tip (cmux-tui-sdks.yml and cmux-tui-spec.yml run the codegen
tests). Deleted; the generated-vs-IR set checks stay.
Pure test deletion: 6 tests deleted, no red test first.
* feat(cmux-next): add signed daily dev channel (#18817)
* feat(cmux-next): add signed daily dev channel
* test(cmux-next): cover daily checksum download path
* fix(cmux-next): publish portable daily checksum
* test(cmux-next): keep rolling release target current
* fix(cmux-next): retarget rolling dev release
* ci(cmux-next): pin publisher Xcode and source workflow
* ci(cmux-next): publish dev builds from producer success
* test(cmux-next): register dev daily contract
* chore(cmux-next): remove unit test coverage from dev daily
* ci: run-webviews-tests.sh works as a fleet step from the checkout root
A cmux-ci step starts at the checkout root, where git ls-files listed 1071
test files from the whole repo and webviews had no node_modules or web
bundles. From outside webviews/ the script now runs ensure-web-bundles.sh
(pinned bun, bundles), bun install --frozen-lockfile in webviews/, and tests
webviews/ only. Run from webviews/ (CI, local dev) it is unchanged. The
per-file re-exec uses the script's absolute path, so it survives the cd.
Bead: cx-tucp
* test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20)
Ports classic 3fcc2aa73fca, 6802308b1a2d, b3817706f600, 719e0608ea10,
5716dc9177df, 9423c7490464, 1872ac1088d9, c7c4bc9c110b, 1d654fc452a7,
d841f14c3997 and 3fb6fa8c6659:
- page.markdown charges child lists, text, values, URLs, table padding and
list and quote indentation to one budget over all frames, reads frames
one after another with what the ones before left (at most 100), finds
<main> by a charged walk, reads slots one node at a time, and ends a cut
page with the read-cut note. Iframe placeholders carry a random mark made
in the agent world, so page text cannot spell one, and page NULs become
U+FFFD.
- searchText reads the text within the budget, contexts at most 1,000
characters a side, matches at most 1,000; extract and dropdownOptions read
within it and cut text before they normalize it. Each prints where it
stopped.
- session.storageState reads localStorage within one budget over at most
100 frames and refuses past it rather than save part of a state.
- tabs.content reads text and HTML in the agent world within a 2,000,000
character budget split over the URLs; markdown and snapshot formats use
their own budgets. page.exportContent writes page.markdown() under a
title cut at 500 characters (the unbounded page-world pageMarkdown goes).
- A snapshot header cleans at most 4,000 characters of a title or URL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12)
Ports classic a02e2b8c3916 and b275d15698d8. iframeHandles walked every
element of the parent recursively into each shadow root on every action
in a child frame (scrollIntoView of each owner <iframe>). The child now
says its place in the parent's window.frames (framePosition, an observe
read); the parent checks its light-DOM <iframe> and <frame> elements one
at a time from the live collections, and only for a frame in a shadow tree
walks its elements iteratively, all within at most 250,000 nodes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red)
The 20,000 nested shadow root cell is replaced: Playwright's own selector
engine overflows its stack there before the owner lookup runs, so it could
not show the item 12 change. Item 12 is checked by clicks in a light-DOM
iframe and in an iframe inside a shadow tree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review)
Review of the batch 2 port:
- tabs.content { format: "html" } read the document in the agent world
around frame.observe, so a password field's value attribute came back
unmasked. It now calls documentHTML (page.content's read, scrubbed) with
the URL's share as its size budget.
- session.storageState counted every open frame against its 100-frame
bound before it knew the frame's origin, so a session with many ad
iframes failed and { urls } did not help. Frames whose origin is out of
scope or already read are skipped and not counted.
- tabs.content titles are cut as plain text (a cut marker before the reply
margin left nothing), and a snapshot-format row names the snapshot's own
stop reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(bindings): delete the SDK unit tests (cx-034r)
Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now").
SDK tests in cmux-tui/bindings before: about 1,243; after: about 507.
Deleted (call SDK code directly, in-memory fake or scripted transports,
net.Pipe, count/shape checks): TypeScript authority, base64, device-kind,
field-compatibility, wire-json, client, resource-api, websocket-transport,
presence; Python consumer, device_kind, events, aio_cleanup, convenience,
schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind,
error_codes, state_handles, public_api and the in-src tests of cmux-sdk
(except the socket ones below), cmux-daemon-client, cmux-sidebar, the two
bootstrap crates and examples/rust-agent-screen-detection; Go
client_zero_progress, resource_api, resource_api_external, socket,
raw/device_kind; go-pane envelope, frame, token, provider, conn,
richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi,
BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig
raw/authority_test and the inline tests of resource.zig, raw/client.zig,
raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no
socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt,
zig raw.zig).
Kept (wire boundary or generated check):
- live daemon tests (*_live.rs), rust mock_server, byte_attachment,
home_conversation, typed_state_ops, dock_field_capability,
local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime
(real Unix sockets), cmux-sdk in-src socket tests in client.rs,
codec.rs, resource/client.rs, socket_hash.rs (UnixListener);
- Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs
schema), package_consumer; TypeScript unix-transport, generated,
package-consumer, resource-package-consumer, code-mode cloud-relay;
Go raw client, ergonomics_external, consumer, url_open (net.Listen);
go-pane listener, websocket, examples/hello main + vectors; Java
GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport,
consumer; C++ generated, macro_collision, unix_transport; Zig provider,
stream_client, wire_presence, generated presence and the socket tests
in transport/client/resource;
- example apps' socket fakes; conformance runner; codegen --check.
Also drops the last hand-written count pins: C++ attach-surface
field_requirements size and the TypeScript emitted-event count.
Release tooling tests (bindings/tests, codegen/tests) are CI tooling and
stay. No Cargo.toml change: dev-dependencies left as they are.
* cmux-next: expose fork in the slash command menu (cx-a7r) (#18836)
* test(cmux-next): cover slash fork availability (red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cmux-next): add fork to the slash command menu
Expose the existing latest-turn fork action through the shared cmux slash command registry. Keep unavailable actions out of the menu and route /fork through the same action as the chat menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* gallery(cmux-next): cover the slash fork command
Add a focused composer gallery variant that types /fork and checks the cmux-owned row alongside harness commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-next): format slash command registry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): make slash fork gallery forkable
Give the focused gallery variant a completed turn sequence so the new /fork row is actually rendered and exercised.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(next): keep slash fork coverage at the webview boundary
Drop added command unit coverage and the obsolete fixed command-list test. Retain the slash-fork gallery interaction.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl]
35a61bd340b7 added enum HomeAppLinks (all-static public surface), which
lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by
making it a struct with an empty public init. URL.isChiefSubagentLink is
the same check on the receiver type; behavior is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt (#18896)
* test(ci): the base autofix regenerates without touching frozen paths (red)
base-autofix.sh copies the Mac job's regenerated files into a checkout,
skipping frozen paths, and adds a missing cmux-tui tree input to both
lists. Red: the script does not exist yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt
After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix
repairs the mechanical reds in one commit on top of it: the generated
files the Mac generated-files job rebuilt (its cmux-next-generated-patch
artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in
cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never
written; the app FFI pin stays with the app-ffi-repin pull request.
The push uses a GitHub App token minted only for the push step and a
plain push that never overwrites a moved base. Dry run until the repo
variable CMUX_NEXT_BASE_AUTOFIX is 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ci): the base autofix never writes a workflow file (red)
The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows
changes. A regenerated workflow file is skipped and reported, and a
missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's
paths) is reported without writing either list. Red: both are written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN
No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the
repair; no ruleset or branch protection applies to feat-cmux-next.
GITHUB_TOKEN cannot push workflow files, so every .github/workflows path
is frozen for the bot, and missing cmux-tui tree inputs (whose second
list is cmux-tui-artifacts.yml's paths) are reported, not written. Its
pushes start no workflow: the next push's cmux-next run verifies the
repair commit. The trigger also checks the run's workflow path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913)
36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and
cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste::
image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only
looked for crate::image_paste under cmux-tui-core, found 9 constants
named CAPABILITY and failed, so release rails is red on every PR and on
nightly-next. A crate:: path whose first segment lib.rs re-exports from
a workspace crate now also names that crate's module file.
No bead (repairs the cx-4l51 guard).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: format staged files before commit (#18808)
* ci: format staged files in the trusted pre-commit hook
* ci: guard formatter scope for staged files
* ci: scope Rust formatter guard to its package
* ci: use direct rustfmt and skip merge formatting
* ci: pass the cmux-tui Rust edition to rustfmt
* ci: check rustfmt on the cmux-tui packages a PR touches (#18800)
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: check rustfmt on the cmux-tui packages a PR touches
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit
The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): leave the relay circuit to its own repair
Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next (#18781)
* ci: add mini-first Swift canary for cmux-next
* ci: remove unit tests from Swift canary change
* cmux-next: repin app FFI to current base release (#18776)
* cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698)
* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree
#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui
Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-next): the newest-published search deepens only this commit's history
A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ci): keep cmux-next minis first through bot retries (#18615)
* docs(cmux-next): map UI parity reference sources (#18561)
* docs(cmux-next): map UI parity reference sources
* docs(cmux-next): add media preview reference source
* docs(cmux-next): define reference freshness checks
* fix(nightly): bound the publish notes step at 10 minutes (#18404)
* test(nightly): the notes step cannot spend the publish budget before the upload (red)
Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(nightly): bound the publish notes step at 10 minutes
The notes take seconds since 0115b2684cf. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622)
* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself
Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): the tree gate watches the base and may pin the tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree
When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a transient wrong binary read must not fail publication
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read a mismatched published binary again before failing
R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): a pull request gate pins a tree its base never builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): a pull request gate pins a tree its base never builds
A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retain base tree dispatch tests
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states (#18901)
* ci(gallery): capture narrow responsive states
* test(gallery): cover workflow matrix changes
* fix(gallery): dedupe equal responsive widths
* ci: shard gallery matrix renders
* ci: retrigger sharded gallery validation
---------
Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: configure shared fleet Rust cache * ci: resolve stable fleet Rust target directories * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * cmux-next: credential.session answers the backend team of the install token (cx-i6g4) The session answer the Cloud app server shows in cloud.auth.status named the Stack team id (auth.teamID). It now answers the install token's team claim, the backend team the relay bills; nil when no token can be minted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-vm): delete the cmux VM unit tests (cx-034r) Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now"). workers/cmux-vm only. Deleted: - Worker: test/workers ledger, naming, proof-evidence and the quotas case of create-options (they call src directly); test/node entitlements, mesh-acl, mesh-m4-units, service-keys and the refusal cases of mesh-signed-request (the route tests in test/workers prove the same refusals over HTTP: forged, tampered, stale and replayed signatures, bad keys and scopes, unsigned webhooks); - SDK: sdk/test/client.test.ts (fake fetch), its bun test step in cmux-vm-clients.yml, its test script and tsconfig include; - CLI: in-src tests of cmux-vm-codegen normalize; - mesh agent: tests/config.rs. Kept: - every test/workers route test (requests through the Worker's fetch handler with a fake upstream); - the PGlite store and schema-gate tests (the release rails run them against the real migrations: production guard); - upstream-coverage (guard), test/types (compile-time proof misuse); - the golden install-key signature vectors shared with the mesh agent; - cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs (CLI vs openapi.json); - mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979 vectors), tests/loopback.rs (two WireGuard peers over real UDP). Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src + 16 tests/ deleted. * test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20) Ports classic 3fcc2aa, 6802308, b381770, 719e060, 5716dc9, 9423c74, 1872ac1, c7c4bc9, 1d654fc, d841f14 and 3fb6fa8: - page.markdown charges child lists, text, values, URLs, table padding and list and quote indentation to one budget over all frames, reads frames one after another with what the ones before left (at most 100), finds <main> by a charged walk, reads slots one node at a time, and ends a cut page with the read-cut note. Iframe placeholders carry a random mark made in the agent world, so page text cannot spell one, and page NULs become U+FFFD. - searchText reads the text within the budget, contexts at most 1,000 characters a side, matches at most 1,000; extract and dropdownOptions read within it and cut text before they normalize it. Each prints where it stopped. - session.storageState reads localStorage within one budget over at most 100 frames and refuses past it rather than save part of a state. - tabs.content reads text and HTML in the agent world within a 2,000,000 character budget split over the URLs; markdown and snapshot formats use their own budgets. page.exportContent writes page.markdown() under a title cut at 500 characters (the unbounded page-world pageMarkdown goes). - A snapshot header cleans at most 4,000 characters of a title or URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12) Ports classic a02e2b8 and b275d15. iframeHandles walked every element of the parent recursively into each shadow root on every action in a child frame (scrollIntoView of each owner <iframe>). The child now says its place in the parent's window.frames (framePosition, an observe read); the parent checks its light-DOM <iframe> and <frame> elements one at a time from the live collections, and only for a frame in a shadow tree walks its elements iteratively, all within at most 250,000 nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red) The 20,000 nested shadow root cell is replaced: Playwright's own selector engine overflows its stack there before the owner lookup runs, so it could not show the item 12 change. Item 12 is checked by clicks in a light-DOM iframe and in an iframe inside a shadow tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review) Review of the batch 2 port: - tabs.content { format: "html" } read the document in the agent world around frame.observe, so a password field's value attribute came back unmasked. It now calls documentHTML (page.content's read, scrubbed) with the URL's share as its size budget. - session.storageState counted every open frame against its 100-frame bound before it knew the frame's origin, so a session with many ad iframes failed and { urls } did not help. Frames whose origin is out of scope or already read are skipped and not counted. - tabs.content titles are cut as plain text (a cut marker before the reply margin left nothing), and a snapshot-format row names the snapshot's own stop reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-next): the Swift exports need a source key Red: scripts/cmux-next/swift-exports-key.py does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): source key of the Swift exports swift-exports-key.py hashes what the export tests compile and read (the packages, plans/cmux-next, the generators and the Xcode pin), minus the exports and the web bundles, so a cache keyed by it can hand the settings schema, MDM manifests, action surfaces, links, daemon capabilities and CI target graph to a job without a Mac build. The checks job runs its tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): pack and install the Swift exports by source key (red) Red: scripts/cmux-next/swift-exports-cache.sh does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): cache the Swift exports of a green push by source key swift-exports-cache.sh packs the exports with their stamp and installs a pack only into a checkout with the same source key, after checking the pack's digest. A Linux job saves the pack after a green feat-cmux-next push, when every tier passed, so a job that only reads the exports (the web bundles read the settings schema) can restore them instead of a Mac build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
… a poster (#18818) * test: red test, a global notification center passed as a center argument fails the lint The lint caught only a literal NotificationCenter.default.post. The off-main notice tests posted through OffMainPost.send() with .default handed in (on: .default, or a NotificationCenter = .default parameter default), and ViewBridge's own didBecomeKey observer trapped the whole swift test run (#18815). Those forms must fail the gate too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the notification-center lint also fails a global center handed to a poster check-test-notification-centers.sh now also fails a process-global center passed as an argument (on: .default, center: NotificationCenter.default, the workspace or distributed center) or as a NotificationCenter parameter's default. The off-main notice tests posted through OffMainPost.send() that way, and ViewBridge's own didBecomeKey observer trapped the whole swift test run (#18815). The 11 existing sites, all deliberate off-main posts that prove an app observer hops to main, carry a reviewed global-notice-allow naming that risk; new ones must inject a center. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* fix(gallery): keep the previous preview through frame swaps * style(gallery): format frame swap stage * fix(gallery): satisfy stage hook dependencies * fix(gallery): retain the displayed frame until ready * fix(gallery): keep frame refs stable during swaps * style(gallery): wrap frame request check * fix(gallery): ignore stale frame readiness * fix gallery frame ref typing * format gallery stage * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…k, not the clock (#17643) * test(cmux-next): palette and terminal deadline tests wait for the work, not the clock Under the full parallel suite (#17601) a replaced palette search had not answered after 100 yields, and the main actor had not started a terminal create within 150 ms, so both failed with no product fault. The palette test waits up to 30 s for the provider to be released; the terminal test gives the create a 5 s start deadline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* feat(gallery): compact the shell controls into a toolbar * fix(gallery): complete the compact control layout * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(cmux-vm): delete the cmux VM unit tests (cx-034r) Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now"). workers/cmux-vm only. Deleted: - Worker: test/workers ledger, naming, proof-evidence and the quotas case of create-options (they call src directly); test/node entitlements, mesh-acl, mesh-m4-units, service-keys and the refusal cases of mesh-signed-request (the route tests in test/workers prove the same refusals over HTTP: forged, tampered, stale and replayed signatures, bad keys and scopes, unsigned webhooks); - SDK: sdk/test/client.test.ts (fake fetch), its bun test step in cmux-vm-clients.yml, its test script and tsconfig include; - CLI: in-src tests of cmux-vm-codegen normalize; - mesh agent: tests/config.rs. Kept: - every test/workers route test (requests through the Worker's fetch handler with a fake upstream); - the PGlite store and schema-gate tests (the release rails run them against the real migrations: production guard); - upstream-coverage (guard), test/types (compile-time proof misuse); - the golden install-key signature vectors shared with the mesh agent; - cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs (CLI vs openapi.json); - mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979 vectors), tests/loopback.rs (two WireGuard peers over real UDP). Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src + 16 tests/ deleted. * test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20) Ports classic 3fcc2aa, 6802308, b381770, 719e060, 5716dc9, 9423c74, 1872ac1, c7c4bc9, 1d654fc, d841f14 and 3fb6fa8: - page.markdown charges child lists, text, values, URLs, table padding and list and quote indentation to one budget over all frames, reads frames one after another with what the ones before left (at most 100), finds <main> by a charged walk, reads slots one node at a time, and ends a cut page with the read-cut note. Iframe placeholders carry a random mark made in the agent world, so page text cannot spell one, and page NULs become U+FFFD. - searchText reads the text within the budget, contexts at most 1,000 characters a side, matches at most 1,000; extract and dropdownOptions read within it and cut text before they normalize it. Each prints where it stopped. - session.storageState reads localStorage within one budget over at most 100 frames and refuses past it rather than save part of a state. - tabs.content reads text and HTML in the agent world within a 2,000,000 character budget split over the URLs; markdown and snapshot formats use their own budgets. page.exportContent writes page.markdown() under a title cut at 500 characters (the unbounded page-world pageMarkdown goes). - A snapshot header cleans at most 4,000 characters of a title or URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12) Ports classic a02e2b8 and b275d15. iframeHandles walked every element of the parent recursively into each shadow root on every action in a child frame (scrollIntoView of each owner <iframe>). The child now says its place in the parent's window.frames (framePosition, an observe read); the parent checks its light-DOM <iframe> and <frame> elements one at a time from the live collections, and only for a frame in a shadow tree walks its elements iteratively, all within at most 250,000 nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red) The 20,000 nested shadow root cell is replaced: Playwright's own selector engine overflows its stack there before the owner lookup runs, so it could not show the item 12 change. Item 12 is checked by clicks in a light-DOM iframe and in an iframe inside a shadow tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review) Review of the batch 2 port: - tabs.content { format: "html" } read the document in the agent world around frame.observe, so a password field's value attribute came back unmasked. It now calls documentHTML (page.content's read, scrubbed) with the URL's share as its size budget. - session.storageState counted every open frame against its 100-frame bound before it knew the frame's origin, so a session with many ad iframes failed and { urls } did not help. Frames whose origin is out of scope or already read are skipped and not counted. - tabs.content titles are cut as plain text (a cut marker before the reply margin left nothing), and a snapshot-format row names the snapshot's own stop reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): reproduce Changes menu keyboard and clipboard focus gaps * fix(cmux-next): share Changes menu focus behavior Migrate file and scope menus to the shared Base UI primitive while preserving selected-scope highlighting and asynchronous clipboard behavior. Add gallery keyboard specimens for both menus. — Ladybug g1 🎯 Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * fix(cmux-next): preserve Changes menu labels Keep accessible names on the migrated Changes popups. — Ladybug g1 🎯 Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * fix(cmux-next): format Changes menu gallery lane Fix the hosted web check formatting failures and keep the scope gallery selection state in the mounted specimen so its Branch play step reaches the selected state. — Ladybug g1 🎯 Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * fix(cmux-next): document palette usage task ownership * fix(web): keep gallery icons semantic without role warning * test(web): refresh layer baseline after changes menu cleanup * chore(webviews): format changes menu lane * fix(cmux-next): refresh generated graph and layer tokens * fix(cmux-next): preserve changes menu focus and stacking * chore(web): format current base tests * test(web): update ui migration debt ledger * fix(ci): follow system scrollbars and lane helper fixtures * test(web): stabilize menu and settings gallery fixtures * test(web): allow palette ranking eval headroom * feat(gallery): make browse contact sheet scannable * fix(changes): keep scope checks on the trailing edge * test(gallery): exercise Codex reasoning picker * docs(parity): refresh reference repository tips * test(gallery): cover session sidebar navigation * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
) * cmux-next: cmux agent message and agent inbox on a durable store Agents can message each other in cmux-next without typing into a terminal. The cmux-tui daemon stores each message before anything tries to reach the recipient (agent.message.send, list, mark on cmux.protocol/2): the agent-rooms envelope with one receipt per recipient, kept in the session registry so it survives a daemon restart. `cmux agent message <agent> <text>` takes a terminal (term_), an agent (agent_) or an acpmux session name. For an acpmux recipient it then prompts the session with the message, using the message id as the acpmux prompt id, so a retry never runs it twice, and records delivered or failed. `cmux agent inbox` lists a recipient's messages and --ack acknowledges them. Hook delivery to terminal agents follows in the next slice. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * agent message: fix clippy and borrow errors Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * agent message: deliver acp backlog oldest first; address review - agent.message.list takes oldest_first; delivery lists queued messages oldest first instead of sorting the newest page. - A failed message is no longer retried on every later send; a send fails only when its own delivery fails. - A receipt another sender recorded first is reported, not fatal. - Take the sent message's receipts from the mark result instead of re-reading up to 1000 messages. - Spec: document that the socket caller is trusted (sender asserted, any caller may list or mark) and the pruning rule. - --reply-to rejects a leading agent instead of folding it into the text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * agent-rooms design: trust model and room for groups and kinds Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * cmux-tui cli: box the agent message plan Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * agent message: use the catalog's agent scope for a missing message resource.not_found allows only catalog scopes. Also build the CLI module on every platform; its acpmux part already has a non-unix stub. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * agent message: keep the app module unix-only; report a failed queue read Adding the agent_message module had moved the cfg(unix) off mod app, which broke the Windows build. A failed read of the recipient's queue after the message is stored is now reported with the message instead of hiding its id. Spec and design text match the no-retry rule for failed messages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * style: order the agent_message module as rustfmt does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui-core): classify agent.message operations for page origin Base's page access match names every catalog operation. A page may not send an agent message (it becomes an agent's input) or list or mark them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): name the app-action failure in agent message problems Base added Failure::AppAction; agent message reports it like the others. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * cmux-next: credential.session answers the backend team of the install token (cx-i6g4) The session answer the Cloud app server shows in cloud.auth.status named the Stack team id (auth.teamID). It now answers the install token's team claim, the backend team the relay bills; nil when no token can be minted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-vm): delete the cmux VM unit tests (cx-034r) Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now"). workers/cmux-vm only. Deleted: - Worker: test/workers ledger, naming, proof-evidence and the quotas case of create-options (they call src directly); test/node entitlements, mesh-acl, mesh-m4-units, service-keys and the refusal cases of mesh-signed-request (the route tests in test/workers prove the same refusals over HTTP: forged, tampered, stale and replayed signatures, bad keys and scopes, unsigned webhooks); - SDK: sdk/test/client.test.ts (fake fetch), its bun test step in cmux-vm-clients.yml, its test script and tsconfig include; - CLI: in-src tests of cmux-vm-codegen normalize; - mesh agent: tests/config.rs. Kept: - every test/workers route test (requests through the Worker's fetch handler with a fake upstream); - the PGlite store and schema-gate tests (the release rails run them against the real migrations: production guard); - upstream-coverage (guard), test/types (compile-time proof misuse); - the golden install-key signature vectors shared with the mesh agent; - cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs (CLI vs openapi.json); - mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979 vectors), tests/loopback.rs (two WireGuard peers over real UDP). Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src + 16 tests/ deleted. * test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20) Ports classic 3fcc2aa, 6802308, b381770, 719e060, 5716dc9, 9423c74, 1872ac1, c7c4bc9, 1d654fc, d841f14 and 3fb6fa8: - page.markdown charges child lists, text, values, URLs, table padding and list and quote indentation to one budget over all frames, reads frames one after another with what the ones before left (at most 100), finds <main> by a charged walk, reads slots one node at a time, and ends a cut page with the read-cut note. Iframe placeholders carry a random mark made in the agent world, so page text cannot spell one, and page NULs become U+FFFD. - searchText reads the text within the budget, contexts at most 1,000 characters a side, matches at most 1,000; extract and dropdownOptions read within it and cut text before they normalize it. Each prints where it stopped. - session.storageState reads localStorage within one budget over at most 100 frames and refuses past it rather than save part of a state. - tabs.content reads text and HTML in the agent world within a 2,000,000 character budget split over the URLs; markdown and snapshot formats use their own budgets. page.exportContent writes page.markdown() under a title cut at 500 characters (the unbounded page-world pageMarkdown goes). - A snapshot header cleans at most 4,000 characters of a title or URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12) Ports classic a02e2b8 and b275d15. iframeHandles walked every element of the parent recursively into each shadow root on every action in a child frame (scrollIntoView of each owner <iframe>). The child now says its place in the parent's window.frames (framePosition, an observe read); the parent checks its light-DOM <iframe> and <frame> elements one at a time from the live collections, and only for a frame in a shadow tree walks its elements iteratively, all within at most 250,000 nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red) The 20,000 nested shadow root cell is replaced: Playwright's own selector engine overflows its stack there before the owner lookup runs, so it could not show the item 12 change. Item 12 is checked by clicks in a light-DOM iframe and in an iframe inside a shadow tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review) Review of the batch 2 port: - tabs.content { format: "html" } read the document in the agent world around frame.observe, so a password field's value attribute came back unmasked. It now calls documentHTML (page.content's read, scrubbed) with the URL's share as its size budget. - session.storageState counted every open frame against its 100-frame bound before it knew the frame's origin, so a session with many ad iframes failed and { urls } did not help. Frames whose origin is out of scope or already read are skipped and not counted. - tabs.content titles are cut as plain text (a cut marker before the reply margin left nothing), and a snapshot-format row names the snapshot's own stop reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* feat(cmux-next): move changes into sources popover Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane bundle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): format sources popover test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): preserve summary focus for changes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane bundle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): type summary focus assertion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): assert summary opener focus Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): keep focus assertion flow-safe Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): match localized summary label Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles * chore(cmux-next): regenerate the agent pane and page bundles * test(cmux-next): restore summary popover DOM harness * chore(cmux-next): regenerate the agent pane and page bundles * test(cmux-next): match summary portal test harness * fix(cmux-next): restore chat header status layout * fix(cmux-next): restore chat header status layout * chore(cmux-next): regenerate the agent pane and page bundles * fix(cmux-next): keep summary popover dismissal controlled * chore(cmux-next): regenerate the agent pane and page bundles * chore(cmux-next): regenerate the agent pane and page bundles * fix(webviews): format gallery strings catalog * chore(cmux-next): regenerate the agent pane and page bundles * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(cmux-vm): delete the cmux VM unit tests (cx-034r) Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now"). workers/cmux-vm only. Deleted: - Worker: test/workers ledger, naming, proof-evidence and the quotas case of create-options (they call src directly); test/node entitlements, mesh-acl, mesh-m4-units, service-keys and the refusal cases of mesh-signed-request (the route tests in test/workers prove the same refusals over HTTP: forged, tampered, stale and replayed signatures, bad keys and scopes, unsigned webhooks); - SDK: sdk/test/client.test.ts (fake fetch), its bun test step in cmux-vm-clients.yml, its test script and tsconfig include; - CLI: in-src tests of cmux-vm-codegen normalize; - mesh agent: tests/config.rs. Kept: - every test/workers route test (requests through the Worker's fetch handler with a fake upstream); - the PGlite store and schema-gate tests (the release rails run them against the real migrations: production guard); - upstream-coverage (guard), test/types (compile-time proof misuse); - the golden install-key signature vectors shared with the mesh agent; - cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs (CLI vs openapi.json); - mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979 vectors), tests/loopback.rs (two WireGuard peers over real UDP). Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src + 16 tests/ deleted. * test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20) Ports classic 3fcc2aa, 6802308, b381770, 719e060, 5716dc9, 9423c74, 1872ac1, c7c4bc9, 1d654fc, d841f14 and 3fb6fa8: - page.markdown charges child lists, text, values, URLs, table padding and list and quote indentation to one budget over all frames, reads frames one after another with what the ones before left (at most 100), finds <main> by a charged walk, reads slots one node at a time, and ends a cut page with the read-cut note. Iframe placeholders carry a random mark made in the agent world, so page text cannot spell one, and page NULs become U+FFFD. - searchText reads the text within the budget, contexts at most 1,000 characters a side, matches at most 1,000; extract and dropdownOptions read within it and cut text before they normalize it. Each prints where it stopped. - session.storageState reads localStorage within one budget over at most 100 frames and refuses past it rather than save part of a state. - tabs.content reads text and HTML in the agent world within a 2,000,000 character budget split over the URLs; markdown and snapshot formats use their own budgets. page.exportContent writes page.markdown() under a title cut at 500 characters (the unbounded page-world pageMarkdown goes). - A snapshot header cleans at most 4,000 characters of a title or URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12) Ports classic a02e2b8 and b275d15. iframeHandles walked every element of the parent recursively into each shadow root on every action in a child frame (scrollIntoView of each owner <iframe>). The child now says its place in the parent's window.frames (framePosition, an observe read); the parent checks its light-DOM <iframe> and <frame> elements one at a time from the live collections, and only for a frame in a shadow tree walks its elements iteratively, all within at most 250,000 nodes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red) The 20,000 nested shadow root cell is replaced: Playwright's own selector engine overflows its stack there before the owner lookup runs, so it could not show the item 12 change. Item 12 is checked by clicks in a light-DOM iframe and in an iframe inside a shadow tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review) Review of the batch 2 port: - tabs.content { format: "html" } read the document in the agent world around frame.observe, so a password field's value attribute came back unmasked. It now calls documentHTML (page.content's read, scrubbed) with the URL's share as its size budget. - session.storageState counted every open frame against its 100-frame bound before it knew the frame's origin, so a session with many ad iframes failed and { urls } did not help. Frames whose origin is out of scope or already read are skipped and not counted. - tabs.content titles are cut as plain text (a cut marker before the reply margin left nothing), and a snapshot-format row names the snapshot's own stop reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* test(cmux-tui): agent chat dock refuses a split
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): refuse a split of the agent chat dock
A split or edge drop that adds a pane to a docked column with role
agent_chat is refused in stage_checked with dock-column-agent-chat, for
every client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): refuse a new pane in the agent chat dock
A split spawns its terminal and attaches the pane outside the staged
plan, so stage_checked never saw it. effect_add_pane now refuses a new
pane in an agent chat dock column before the spawn, and again under the
attach lock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): drop unneeded path qualifications
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read the chat dock guard's state without a new unwrap
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: rerun the same-tree check on the published tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a split column cannot become the agent chat dock
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): a column with more than one pane cannot become the chat dock
set-column-dock and column.update share apply_column_dock, which now
refuses the agent_chat role on a split column (dock-column-agent-chat).
A column that already is the chat dock keeps its role.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: rerun the same-tree check on the published tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* plans(projects): daemon-owned project store with source adapters, event-driven resync, merge rules (cx-m0p7 design)
* test(cmux-tui-core): project list reducer merge rules and user edits (red, cx-m0p7)
* feat(cmux-tui-core): project list reducer: sources, user overlay, missing state, refusals (cx-m0p7 slice 1)
* style(cmux-tui-core): rustfmt the project reducer
* style(cmux-tui-core): rustfmt state.rs module list
* feat(cmux-tui-core): project-list-v1 store, ops and spec: project.list/observe/add/update/remove/sync (cx-m0p7 slice 1)
* fix(cmux-tui-core): collapse the project rename check (clippy)
* fix(cmux-tui-core): project store clippy (semicolons; source toggle helpers wait for slice 3)
* fix(cmux-tui-core): semicolon on the project row parse warning
* refactor(cmux-tui-core): request ids move to resource/request_id.rs (move-only) so resource.rs stays under the god-file limit
* test(cmux-tui-core): project list review cases: idempotent observe, null clears, case-insensitive refusals, disk facts from the caller, cap (red, cx-m0p7)
* fix(cmux-tui-core): project store reads no disk for observed paths, null clears, idempotent observe, case-insensitive refusals, cap, disk facts from the app (review, cx-m0p7)
* chore(godfiles): resource.rs meets its budget (row dropped)
* CmuxNext: failing tests, a split shows a provisional pane before the reply (S3 T1, store)
* CmuxNext: a split intent shows a provisional pane beside its target until the daemon's pane with the same public id replaces it (S3 T1, store)
* cmux-layout-reducer: failing test, SplitNew puts a new pane with a new tab beside the target (S3 T3)
* cmux-layout-reducer: SplitNew, a new pane with a new tab beside the target (S3 T3); covered by the random op sequence property test
* S3: the optimistic split matches the Rust reducer's SplitNew vectors (L4 parity: Rust generator with drift check, Swift reader)
* S3 tests: optimistic Cmd+D on a client-keys daemon (T1 app, T2 store frame budget), provisional pane mapping continuity, target gate and typeahead order (T7)
* CmuxNext: Cmd+D shows the new pane before the reply on a split-client-keys-v1 daemon; its terminal view waits for the daemon's terminal and keeps keys typed meanwhile (S3)
* S3: provisional terminal view helpers in their own file; test daemon record as a Sendable box
* S3: TabContentCache within its size limit; the test daemon serves terminal-placement-env-v1
* cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay
* cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe
* cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders)
* S3: drop the unit tests and the reducer op (NO UNIT TESTS rule); verification moves to the tagged app via the debug socket
* cx-m0p7 store: socket-level behavior test on a real daemon replaces the in-process unit tests (NO UNIT TESTS)
* cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS)
* cx-m0p7 store: the socket test picks a non-temporary folder
* cx-m0p7 adapters: the socket test picks a non-temporary folder
* S3: tagged-app proof harness (Cmd+D through debug.key, read-screen) and its results
* S3: the provisional split maps columns and rows instead of indexing them (crash ratchet)
* cx-m0p7 store: keep LocalOperation in resource.rs (boundary check reads it); move encode_hex out for the god-file limit
* S3: SpawnOptions drops unserved fields itself (DaemonConnection stays within its size limit)
* fix(cmux-next): WebKit right and middle buttons: right presses go in as AppKit right-button events, a middle press carries button number 2 on its own Quartz form (DOM button 1), wheel events take the Quartz location AppKit gives the window point, and the web view empties the context menu of a right-click the app did not dispatch, so an agent's right-click opens no native menu (cx-ollo)
* cmux-next: harden the credential relay and the Cloud create approval (cx-t2rz security review)
P2-1: the relay serves only the app cmux/cloud and only cloud.* ops
(credential.app_refused / credential.op_refused otherwise): an install
token with origin user counts as the person on the Worker, so no other app
or op family may borrow it.
P2-2: before feed.answer the app reads integration.approval.get as the
person and requires op cloud.machine.create, state pending and exactly the
params the person confirmed; the feed item must carry the same request
and digest, tool cloud.machine.create, and poster system:cloud:<team>.
Any mismatch answers nothing and shows why. The confirmation shows the
machine size and name.
P3-1: the relay registers only on the app server link path (never with
the legacy default or in release).
P3-2: a create from the progress view's Retry (no gesture origin) asks
the person first; only an action with origin user skips the sheet.
P3-3: the session call for the approval refuses redirects and keeps no
cookies or cache.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): short update titles; the test feed and announcements are notice cards
Chief 2026-10-09 (round 2 of Lawrence's update card ask).
- Update titles are short and the version moves to the detail line:
"Update Available" / "Version 1.0.0-nightly.…", "Update Check Failed",
"Needs macOS 27.0 for …". Before, "cmux 1.0.0-nightly.376…" and
"Couldn't Check for Up…" truncated in a 260 pt sidebar. UpdateNote's
needsNewerMacOS carries the found version. 4 new strings (en + ja,
19 languages needs_review).
- The test-feed notice (Use Real Feed, no x) and the announcements (their
allow-listed Try It, an x that dismisses for good, the next one shows)
are the shared notice card. Order: update status, test feed,
announcement, tip; the "cmux Updated!" card waits while an update
status or a test feed shows.
- The plain R114 card stack is gone (SidebarCard, SidebarCardView,
SidebarCardStackView, SidebarCardStackLayout, SidebarModel.cards and
onCardAction); its hover test goes with it. The footerCards slot stays.
Announcements now show whether or not the sidebar chrome is revealed.
- NO UNIT TESTS (Lawrence 2026-10-10): the unit tests this change breaks are
deleted in this diff (UpdateNoticeTests and its ManualClock copy, from
31d888016eed / d344241b7a88; the stack hover test; two stack-card
asserts). Proof is the tagged app on cmux-lawrence-2 through the debug
socket with screenshots.
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): a check while an update waits shows the waiting update
Lawrence's NIGHTLY (2026-10-09/10): 3797671859401 was downloaded and
waited for a restart; Sparkle skips every check while an update waits
("update check ignored while install is progressing"), so his manual
Check for Updates showed nothing and never saw 3800566557701.
- Check for Updates while an update is staged does not ask Sparkle (it
would ignore the check); it logs and answers with the staged update.
- The staged update card ("cmux X is ready", Restart to Update) shows
after such a check even under updates.notify silent, which otherwise
hides it. Before, a silent install had no answer to a check at all.
Proof: tagged app on cmux-lawrence-2 through the debug socket (staged
update + notify silent: no card; Check for Updates: the card), with
screenshots. No unit tests (Lawrence 2026-10-10).
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(nightly-next): keep the acpmux and OptChat Chief dependency builds between nightlies (cx-g34i)
build-nightly-app compiled every Rust dependency of acpmux (53 s + 46 s, two
arches) and the OptChat Chief (24 s + 24 s) from scratch on each nightly-next
run, on the serial path before the Release build. Swatinem rust-cache on their
target dirs (cmux-tui/target/acpmux-app, optchat-chief/target/app), nightly-next
track only; cargo rebuilds what changed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): drop the hand-written operation and command counts (cx-034r)
Unit-test deletion lane, slice 3 (chief order): every lane that added an
op had to edit 4+ files with a hand-written count (palette hit 211, 212,
213). The generated-from-spec checks (spec inventory, SDK sync, the set
equality of generated commands and the IR) already prove coverage.
Removed, no other assertion changed:
- cmux-tui-core resource_router tests: operations.len() == 213 (2x);
- cmux-tui transport path coverage: cases.len() == 188, catalog 213;
- check-resource-api-boundary test: operations 213;
- conformance runner: TRANSPORTED_OPERATION_COUNT (now: a non-empty
catalog), and its test;
- SDK raw coverage tests: command count 236 and event count 69 in C++,
Go, Java, Python, TypeScript, Zig (src and the watch example);
- spec/resource-operations-v2.md names the JSON catalog, not a number.
Pure assertion deletion: no red test first. 0 tests deleted, 0 added
(test count before == after).
* cmux-next: S3 optimistic Cmd+D off by default (cx-wb5.72)
Keys typed right after Cmd+D lost the tail of the line in 1 of 8 proof
runs. Every daemon now serves split-client-keys-v1, so the capability gate
protects no one. PaneSplitCommand.optimisticSplitEnabled = false sends every
split through the old path; the landing with the ordering fix sets it back.
split-optimistic-proof.py records the path each Cmd+D took and takes an
expected path (optimistic|old) as a gate argument.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): failing tests for automations, runs and bodies in rows (g1)
Head under 100 KB with 100 automations of 20,000-character instructions
and 450 kept runs; bodies stored once with reference counts; keyset
paging for automation.list and run.list stable under inserts; run.get
joins the body; migration of an old JSON head is idempotent on a live
DO and after a rollback refill; disable, delete and a policy deny
cancel every queued run. Deterministic: reads answer without an ok
field, the cancelled-run check uses a sleeping first run, the migration
check binds the object before it reads the head.
Re-applied from orphaned fe31fa1f0ed8 + 467e890d7cb1 (cx-3bi.38).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(scheduler): automations, runs and bodies in rows, keyset paging, live migration (g1)
SchedulerDO moves to row mode (plans/cmux-next/backend.md (g), DO audit
F-1). automation/<id> and run/<id> rows hold the records without their
bodies; body/<sha256> rows hold each distinct body once with a reference
count (automations plus kept runs) adjusted in the same commit; a
finished/<run> index lets prune drop the oldest finished runs past 200
without reading the open ones. A started run keeps its body hash. The
head keeps owner, settings, counters, chains and the counts
automation_count, open_runs, finished_count, row_seq. All four tables
are private, so events and snapshots carry the head only.
One lookup module (domains/scheduler-rows.ts) and one per-op store
(domains/scheduler-store.ts) replace every read of state.automations and
state.runs. New reads run.list and run.get; automation.list pages with
cursor and limit and its first page is unchanged. System op
scheduler.rows_migrate (key carries the head seq) rebuilds the rows from
an old head's maps on bind and drops the maps in one commit; the alarm
path migrates first too.
Re-applied from orphaned 7ab757b458e5 onto feat-cmux-next (cx-3bi.38).
run-policy.test.ts keeps the tip's createWithTeamDown helper (cx-nfts)
and reads next_at from the automation row. Catalog, TS client, Rust
cloud-wire client, app-host ops/scopes/d.ts and the bundled AppPlatform
scopes.json are regenerated with the repo generators, not hand-merged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): failing tests for the g1 review findings
A run pruned while the dispatch loop awaits a create is skipped and
onWake goes on; a refilled head migrates by merge (maps win per id, rows
the maps lack stay with their bodies); reads on a legacy head answer the
retryable owner.migrating; run.list with a sparse filter over more than
200 kept runs scans every step and ends without an empty last page.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(scheduler): g1 review: stale dispatch rows, merge migration, legacy reads, paging
- onWake re-reads each run before it builds the dispatch params: a
disable, delete or deny during an earlier create may have cancelled the
run and prune may have dropped it with its body, which made requireBody
throw and stop the wake. A missing, started or terminal run is skipped.
- scheduler.rows_migrate merges a refilled head instead of replacing the
rows: the maps win per id, rows the maps lack stay with their stored
bodies (dropped only when that body row is gone), and every body
reference count is recounted.
- Reads on a legacy head answer the retryable owner.migrating, the same
as the reducer.
- run.list looks one match ahead, so a page that ends the list has no
cursor to an empty page.
- automation.list keeps automation_count and next_cursor optional while
an old Worker can answer (deploy skew); catalog, TS client, Rust
cloud-wire client and app-host outputs regenerated.
- plans/cmux-next/backend.md (g): roll-forward only, merge semantics,
and the operator recovery when a pre-g1 build meets a migrated head.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): drop the engine-level g1 unit tests (NO UNIT TESTS rule); the SchedulerDO op tests stay as the behavior proof
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* scheduler: regenerate the cloud-wire Rust client and the bundled AppPlatform scopes.json after the rebase
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* cmux-next: a Cloud create approval must be for the create's own team; the mismatch text stays localized (cx-t2rz review)
The approve step takes the backend team the relay's create bills (the
install token's team claim, captured when the create starts) and requires
the feed item's approval.team to equal it, so an identical create pending
in another team the person belongs to is never approved. The mismatch
reason goes to the log only; the person sees the localized text.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* scheduler (cx-3bi.38): regenerate the cloud-wire Rust client on the tip
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(rd-host): bench sends synthetic upstream frames; upstream loopback check (red: no host sink) (cx-9zn)
cmux-rd bench --upstream mic|camera|screen opens an upstream stream, sends
synthetic frames through cmux-rd-core's UpstreamSender with the host's
feedback, and reports frames sent/acked and an FNV-1a hash.
scripts/upstream-loopback.sh expects a host with --upstream-record DIR to
record every sent frame; red until the host has the recording sink.
* feat(rd-host): --upstream-record DIR development sink for viewer upstream media (cx-9zn)
The desktop host offers up_media only with a sink; it had none (NoSink),
so no viewer could send its microphone, camera or screen anywhere. The new
RecordSink (development only, off by default) writes each upstream stream
to an owner-only file (Annex-B .h264, length-prefixed .opus-packets) and
logs frames, bytes and an FNV-1a hash on close. The sink is chosen per
session; without the flag the host still offers no upstream caps.
* fix(cmux-next): the diff sidecar keeps its pipe readers until end of file
DiffSidecarProcess released the Process at the child's exit, and with it
the Pipes and their read FileHandles. When the exit was handled before the
stdout end-of-file event, the FileHandle closed its descriptor and the EOF
never came: the reply never finished and the caller waited for the request
deadline (130 s; a 60 s hang of writesTheRequestAfterTheReadyMarker... on
the ManualClock, 7 times on 2026-10-09). The invocation now holds both read
ends until each reads EOF, and releases them when the launch fails.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* fix(cmux-next): a cloud edit marks the source degraded before it subscribes
requireEditable started the conversation's subscribe and only then set
degraded. A subscribe that went live in between called recover() on a
source that was not degraded yet, so no .ownerRecovered went out and the
edit waited for a recovery nothing would send (CloudHomeSourceTests
withoutAnEchoTheEditSubscriptionEndsAtTheDeadline, 60 s, once under load).
The flag is now set in the same lock as the target read.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* test(cmux-next): live-daemon suites wait for the daemon's events, not deadlines
The harness connection (and QuitSessionsTests' relaunch connections) send
no client deadline: each request waits for the daemon's reply, so
create-terminal returns when its host is up. The 30 s bound of 57a5a8129382
only moved the line a loaded host crossed at 5 s. TerminalHosts.awaitExit
waits for kernel exit events (one process source per pid) instead of a
50 ms kill(0) poll; its 30 s bound and the suites' .timeLimit are only hang
guards.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* test(cmux-next): the palette benchmark measures the thread's CPU time
The budget read wall time, which counts time the thread waited for a core:
with 32 suite processes on one host the ranking median read 123 ms (54.8 ms
in another run) against 50 ms. The ranking runs synchronously on the calling
thread, so its CPU time is the search cost.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bead: cx-kuxw
* fix(rd-host): review fixes for the upstream record sink (cx-9zn)
Review subagent should-fix items: the record dir must be a real 0700 dir
owned by this user; a per-session byte limit (--upstream-record-max-mb,
default 1024) and 64-file limit; a sink that cannot start falls back to
NoSink instead of dropping every viewer; unique file names; Drop logs
open streams. Bench uses the welcome's max_datagram. upstream-loopback.sh
counts host lines per run (a failed run no longer shifts later checks),
accepts paced drops, and takes PORT/PORT_NOSINK.
* test(cmux-tui): delete the unit tests of 18 leaf crates (cx-034r)
Unit-test deletion lane, slice 4a (Lawrence 2026-10-10, "Delete all now").
In-src #[cfg(test)] tests and the tests/ files that call library code are
deleted in cmux-motion, cmux-history, cmux-conversation, cmux-chat-index,
cmux-terminal-iface, cmux-terminal-sizing, cmux-tui-cloud-conversations,
cmux-theme-tokens, cmux-agent-pane-policy, cmux-tasks-core, cmux-tasks,
cmux-app-manifest, cmux-chief, cmux-terminal-client, cmux-mobile-core,
cmux-mobile-ffi, cmux-unix-socket and ghostty-vt.
Kept (boundary or cross-language contract):
- ghostty-vt tests/ (bytes in, terminal state out; chief ruling);
- cmux-terminal-client tests/route_e2e.rs and cmux-tasks tests/server.rs
(real sockets end to end);
- shared corpora and fixtures another language replays:
cmux-conversation conformance, cmux-chief corpus, cmux-agent-pane-policy
parity + typescript, cmux-history fixtures, cmux-theme-tokens load,
cmux-mobile-core terminal sizing fixtures, cmux-app-manifest schema
fixtures + samples, cmux-tasks-core catalog (catalog <-> Op guard).
cfg(any(test, feature = "test-support")) narrows to the feature.
cmux-tui.yml: the Windows step drops cmux-chat-index, which has no tests.
Deferred to slice 4b (security and malformed-input cases need a boundary
test first): cmux-local-auth, cmux-relay, cmux-tui-machine-protocol,
cmux-tui-machine-agent-protocol, cmux-transport, cmux-encode, cmux-wg,
cmux-link.
Counts: 327 in-src tests and 189 tests/ tests deleted (516); 55 files deleted.
* cmux-tui: two terminal_host_recovery load flakes made deterministic (cx-2dc4)
pipelined_new_tabs_start_hosts_in_parallel_in_request_order asserted a
wall-clock bound (8 hosts x 400 ms ready delay < 3.2 s), which IO and CPU
load broke (40/40 red on a loaded Testbox). A debug-only host seam,
CMUX_TUI_TEST_HOST_READY_GATE, now holds every host before Ready at a FIFO
the test opens later; all records on disk while the gate is closed prove
the launches overlap, and identify must reply while the creates wait.
host_crash_is_named_with_its_panic_message: the abort seam fired 300 ms
after install, racing the owner's PTY custody (no custody, no replacement,
no host_replaced line), and systemd-coredump of the aborted 1 GB debug host
kept it alive 3-6 s under load. The seam now crashes when the test opens
<marker>.trigger, after wait_for_daemon_custody saw the daemon hold the
master and its custody thread (renamed pty-custody, visible in /proc) end,
and it disables core dumps before abort.
Loaded Testbox runs (32 vCPU; P=8+32 hogs, P=24+96 hogs+8 fsync dd,
P=16+32 hogs+workspace build): before 40/40 and 3/40 red; after 0/120 each.
* cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1
* test(cmux-tui): server-stats write_path counters and the effect intent socket check (red)
Add the optional server-stats section write_path (include-gated, like
resource_projection, so older SDK decoders stay safe): effect receipt
commits carried by journal writer batches, their savepoint failures,
the batches that carried them, effect receipt commits that ran their own
transaction on a request thread, and registry lock acquisitions on a
journal writer thread (counted in release builds, process-wide).
The new socket test drives a headless daemon: terminal creates under
terminal output must commit their effect receipts as writer intents,
with no request-side effect commit and no writer registry lock. Red
today: effect_store still commits each receipt in its own request-side
transaction and fsync (effect_intents stays 0).
Spec: commands.md and sdk-schema.json gain the section; bindings
regenerated.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-tui): effect receipt commits ride the journal writer batch
effect_store commit_resource_effect and commit_resource_effect_patch
become typed writer intents (journal ingress Effect events on the
durable lane). The request thread prepares the intent under the
workspace registry (validation, stored fingerprint, public-fold pruning),
the journal writer applies it inside its batch transaction under a
SAVEPOINT per intent (one shared fsync per batch), and the request
thread finishes it (projection stats, public fold) under the same
registry hold. An intent that fails its checks rolls back to its
savepoint and only its request gets the error; a SQLite failure still
fails the batch, which the writer retries or splits as before.
Lock order is unchanged: workspace registry -> registry connection ->
state. commit_resource_effect_projection drops state and the connection
pin before the receipt wait, keeps the registry (topology writers stay
serialized), and re-locks state to install the revision. The receipt
wait uses the producer deadline and commit fence: a writer error, a
dropped receipt or an expired deadline returns an error and releases
the registry. Prepare and executing transitions stay request-side.
The writer marks its whole loop iteration (batch, commit, retries,
receipt delivery) as the journal writer, so a registry lock there is
asserted in debug and counted in release (server-stats
write_path.writer_registry_locks, checked over the socket). Local commit
fallback (counted as request_effect_commits): writer disabled, stopped,
failed, not running yet, or the calling thread still holds the
connection.
The registry lock, the journal writer iteration and the registry
connection take lock ranks in the lock-rank checker (crate::lock_rank:
workspace.registry > journal.writer > registry.connection > mux.state),
so debug and test builds panic on a registry lock on the writer thread
on every path, in addition to the release counter.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): wait for template terminal adoption after a daemon restart
adopted_template_terminal_is_restored_in_place_after_a_daemon_restart read
the parked terminal's lifecycle once, right after the restart. Adoption
completes asynchronously (the terminal reads "adopting" until its host
handshake lands), so under a loaded gate run the read raced it and saw
"adopting". Wait for "running" with the file's bounded helper.
Bead: cx-g1fa.1
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(browser-parity): snapshot reads beside the walk stay within the page-read budget (cx-2y2 red)
Scenario 41 drives the REPL against hostile pages: a data table judged by
its first 50 rows, an offscreen count past the node budget, a zero-size
link's visible-box check, a link URL longer than the size budget, and
generated content, placeholder, option label and editable text past it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): snapshot reads beside the walk stay within the page-read budget (cx-2y2 items 6, 10, 11)
Ports classic 7f37c374e9f5, eeb6d5105161, 7dfa50c0910b and 84bd76a4e8e7:
- A zero-size link's visible-box check charges each node it looks at.
- Offscreen interactive elements are counted lazily within the node
budget and the clock; past them the viewport note says "at least".
- Layout-table detection reads a sample: 50 children, rows and cells per
row, and 1,000 descendants for a nested table.
- Generated content is read one character at a time, at most as far as
the size budget can use; a placeholder and an option label are cut
before they are normalized; option text and editable text are read
within what the snapshot has left; an ARIA value is cut at 20,000.
- A link URL longer than the size budget has left is not resolved or
parsed (no offsite summary); a URL that fits is parsed once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a snapshot of names that share one huge label stops at the node budget (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): snapshot names read their sources within the page-read budget (cx-2y2 items 8, 9)
Ports classic 7b0f1a7a87a6, bcd5ad8bc5d8, 61b3f78a30d2 and part of
7dfa50c0910b. Before Playwright computes a name, the sources it would read
(aria-labelledby targets, at most 64; labels; own content for roles named
from content; legend, caption, figcaption; shadow content, slotted nodes,
aria-owns targets, name attributes, field values, generated content) are
counted within NAME_NODES 2,000, NAME_CHARS 20,000 and NAME_DEPTH 100, the
nodes outside the element charged to the snapshot's budget. Past the
bounds the name is read directly from the same sources, node by node and
charged. Author names, the select value and elementAt names use the same
bounded reads. A slot's assigned nodes are read one at a time (slotAssigned)
instead of assignedNodes(), which lists them all first.
Scenario 41 adds 1,000 buttons named by one shared 50,000-node label: the
snapshot stops at the node budget at once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): locator reads, allTextContents and page.content of a huge page end where the page-read budget stops (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): locator reads, allTextContents and page.content read within the page-read budget (cx-2y2 item 13)
Ports classic d3d04bf299db. locator textContent, innerText, innerHTML,
getAttribute and inputValue call the page agent's readBounded,
allTextContents and allInnerTexts call readAllBounded (one budget for all
elements; elements past it read ""), and page.content calls documentHTML.
Each reads with the bounded DOM readers (item 3) and answers { value, cut };
a cut value ends with "…" and the runtime prints where it stopped. Before,
these returned whole DOM strings across the evaluate boundary.
frame.observe allows the three new methods (src/observe.rs, the dev driver
and plans/cmux-next/browser-host.md), scrubs sensitive values from their
results like read, gives readBounded of a sensitive field's inputValue or
value attribute the marker at once, scopes readAllBounded to its elements
and documentHTML to the whole frame. The reference host redacts them too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(browser-host): a name past the budget cut never falls back to Playwright's unbounded read (cx-2y2 items 8, 6 review)
Review of the item 8 port: after a node cut the walk still reads the
elements it scheduled, and each one's aria-labelledby list came back empty
(spend failed), so nameFits passed and Playwright read the label whole for
every remaining element (1,000 buttons sharing a 50,000-node label hit the
30 s evaluate timeout). Now a read past a cut, or an aria-labelledby list
with ids left (past 64 or past the budget), takes the bounded name. The
NAME_DEPTH count no longer drifts at a nested <select>, and the visible-box
check of a zero-size link walks iteratively.
Scenario 41 checks generated content, placeholder, option label and
editable text each in its own snapshot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a short secret in a read's HTML is masked; each big value cuts on its own read path (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next: credential.session answers the backend team of the install token (cx-i6g4)
The session answer the Cloud app server shows in cloud.auth.status named
the Stack team id (auth.teamID). It now answers the install token's team
claim, the backend team the relay bills; nil when no token can be minted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(browser-host): frame.observe masks a short secret's value attribute in HTML results (cx-2y2 item 13 review)
A sensitive value of 1-3 characters was replaced only as a whole string,
so innerHTML and documentHTML (page.content, now an observe read) kept it
in value="...". The scrub now also replaces those values in their
attribute form. _printReadCut moves above _raceDialog's comment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release-notes: agent page reads stay within the page-read budget (cx-2y2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(agent-chat, cmux-tui web): delete the unit tests (cx-034r)
Unit-test deletion lane, slice 6 (Lawrence 2026-10-10, "Delete all now").
agent-chat: 63 of 65 test/*.test.ts files deleted (function, adapter,
store and component tests against in-process fakes) plus the fake ACP and
Codex harness scripts only they ran. Kept: listener-auth.test.ts (a real
server process over raw HTTP: token, Host and Origin refusals) and
cmux-chat-argv.test.ts (runs the cmux-chat script: the token never reaches
a child's argv). The manual *.e2e.ts scripts against a running server stay.
The Claude launch environment policy keeps its generator check
(generate-claude-launch-environment-policy.py --check); its unit test and
the workflow_guard_groups.py entry for it go.
cmux-tui/frontends/web: all 37 Vitest/jsdom files and test/setup.ts
deleted; the Vitest config, the test script and the tsconfig test include
go. cmux-tui.yml runs check and build for the web frontend.
Before: 102 test files (about 322 bun test cases plus plain assertion
scripts); after: 2 files.
* ci(cmux-tui artifacts): cmux_next_ daemon tests in one cargo invocation (cx-g34i)
After 5f9ff5c667e8 the separate `-- --list` pass and the real run each built:
the second rebuilt acpmux and cmux-tui for 2m39s (run 38014219284; the first
build was 6m36s, was 11m31s with --workspace). One cargo test run, teed; a run
that passed no test is still red.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(web): drop the agent-session-web job whose tests are gone; vp fmt two kept checks (cmux-next web red) [cx-4g8w]
975d40047a3f deleted webviews/src/agent-session/shared/*.test.ts, so
`bun test webviews/src/agent-session/shared/*.test.ts` matched no file and
agent-session-web-resources failed on every routed push. The job ran only
that command: remove it, its package.json script, its web-status entry and
the CI structure assertions that named it. The same commit left a trailing
blank line in desktopLayer.test.ts and pane-english.test.ts, which vp check
refuses (react-apps-check red).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-vm): delete the cmux VM unit tests (cx-034r)
Unit-test deletion lane, slice 7a (Lawrence 2026-10-10, "Delete all now").
workers/cmux-vm only.
Deleted:
- Worker: test/workers ledger, naming, proof-evidence and the quotas case
of create-options (they call src directly); test/node entitlements,
mesh-acl, mesh-m4-units, service-keys and the refusal cases of
mesh-signed-request (the route tests in test/workers prove the same
refusals over HTTP: forged, tampered, stale and replayed signatures,
bad keys and scopes, unsigned webhooks);
- SDK: sdk/test/client.test.ts (fake fetch), its bun test step in
cmux-vm-clients.yml, its test script and tsconfig include;
- CLI: in-src tests of cmux-vm-codegen normalize;
- mesh agent: tests/config.rs.
Kept:
- every test/workers route test (requests through the Worker's fetch
handler with a fake upstream);
- the PGlite store and schema-gate tests (the release rails run them
against the real migrations: production guard);
- upstream-coverage (guard), test/types (compile-time proof misuse);
- the golden install-key signature vectors shared with the mesh agent;
- cmux-vm CLI tests/lifecycle.rs (built binary) and tests/contract.rs
(CLI vs openapi.json);
- mesh agent tests/cli.rs (built binary), tests/install.rs (golden RFC 6979
vectors), tests/loopback.rs (two WireGuard peers over real UDP).
Counts: Worker/SDK TS cases 355 -> 304 (51 deleted); Rust 6 in-src +
16 tests/ deleted.
* test(bindings): delete the SDK inventory pin test (cx-034r)
Follow-up to eae755077987, which removed the hand-written command and
event count pins in the SDK tests: test_sdk_inventory_pins.py checked
those pins against the schema and is itself a count-pin test, so it went
red on the tip (cmux-tui-sdks.yml and cmux-tui-spec.yml run the codegen
tests). Deleted; the generated-vs-IR set checks stay.
Pure test deletion: 6 tests deleted, no red test first.
* feat(cmux-next): add signed daily dev channel (#18817)
* feat(cmux-next): add signed daily dev channel
* test(cmux-next): cover daily checksum download path
* fix(cmux-next): publish portable daily checksum
* test(cmux-next): keep rolling release target current
* fix(cmux-next): retarget rolling dev release
* ci(cmux-next): pin publisher Xcode and source workflow
* ci(cmux-next): publish dev builds from producer success
* test(cmux-next): register dev daily contract
* chore(cmux-next): remove unit test coverage from dev daily
* ci: run-webviews-tests.sh works as a fleet step from the checkout root
A cmux-ci step starts at the checkout root, where git ls-files listed 1071
test files from the whole repo and webviews had no node_modules or web
bundles. From outside webviews/ the script now runs ensure-web-bundles.sh
(pinned bun, bundles), bun install --frozen-lockfile in webviews/, and tests
webviews/ only. Run from webviews/ (CI, local dev) it is unchanged. The
per-file re-exec uses the script's absolute path, so it survives the cd.
Bead: cx-tucp
* test(browser-parity): markdown, searchText, extract, storageState and tabs.content read within the page-read budget (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): page.markdown, searchText, extract, dropdownOptions, storageState, tabs.content and exports read within the page-read budget (cx-2y2 items 14-20)
Ports classic 3fcc2aa73fca, 6802308b1a2d, b3817706f600, 719e0608ea10,
5716dc9177df, 9423c7490464, 1872ac1088d9, c7c4bc9c110b, 1d654fc452a7,
d841f14c3997 and 3fb6fa8c6659:
- page.markdown charges child lists, text, values, URLs, table padding and
list and quote indentation to one budget over all frames, reads frames
one after another with what the ones before left (at most 100), finds
<main> by a charged walk, reads slots one node at a time, and ends a cut
page with the read-cut note. Iframe placeholders carry a random mark made
in the agent world, so page text cannot spell one, and page NULs become
U+FFFD.
- searchText reads the text within the budget, contexts at most 1,000
characters a side, matches at most 1,000; extract and dropdownOptions read
within it and cut text before they normalize it. Each prints where it
stopped.
- session.storageState reads localStorage within one budget over at most
100 frames and refuses past it rather than save part of a state.
- tabs.content reads text and HTML in the agent world within a 2,000,000
character budget split over the URLs; markdown and snapshot formats use
their own budgets. page.exportContent writes page.markdown() under a
title cut at 500 characters (the unbounded page-world pageMarkdown goes).
- A snapshot header cleans at most 4,000 characters of a title or URL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release-notes: markdown and agent tool reads stay within the page-read budget (cx-2y2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): a click in a child frame works beside 20,000 nested shadow roots (cx-2y2 red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(browser-host): a child frame's <iframe> is found by its place in window.frames, within the node budget (cx-2y2 item 12)
Ports classic a02e2b8c3916 and b275d15698d8. iframeHandles walked every
element of the parent recursively into each shadow root on every action
in a child frame (scrollIntoView of each owner <iframe>). The child now
says its place in the parent's window.frames (framePosition, an observe
read); the parent checks its light-DOM <iframe> and <frame> elements one
at a time from the live collections, and only for a frame in a shadow tree
walks its elements iteratively, all within at most 250,000 nodes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(browser-parity): tabs.content HTML masks sensitive values; frame clicks in light and shadow iframes (cx-2y2 red)
The 20,000 nested shadow root cell is replaced: Playwright's own selector
engine overflows its stack there before the owner lookup runs, so it could
not show the item 12 change. Item 12 is checked by clicks in a light-DOM
iframe and in an iframe inside a shadow tree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(browser-host): tabs.content HTML is an observe read; storageState reads each origin once (cx-2y2 items 14, 19 review)
Review of the batch 2 port:
- tabs.content { format: "html" } read the document in the agent world
around frame.observe, so a password field's value attribute came back
unmasked. It now calls documentHTML (page.content's read, scrubbed) with
the URL's share as its size budget.
- session.storageState counted every open frame against its 100-frame
bound before it knew the frame's origin, so a session with many ad
iframes failed and { urls } did not help. Frames whose origin is out of
scope or already read are skipped and not counted.
- tabs.content titles are cut as plain text (a cut marker before the reply
margin left nothing), and a snapshot-format row names the snapshot's own
stop reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(bindings): delete the SDK unit tests (cx-034r)
Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now").
SDK tests in cmux-tui/bindings before: about 1,243; after: about 507.
Deleted (call SDK code directly, in-memory fake or scripted transports,
net.Pipe, count/shape checks): TypeScript authority, base64, device-kind,
field-compatibility, wire-json, client, resource-api, websocket-transport,
presence; Python consumer, device_kind, events, aio_cleanup, convenience,
schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind,
error_codes, state_handles, public_api and the in-src tests of cmux-sdk
(except the socket ones below), cmux-daemon-client, cmux-sidebar, the two
bootstrap crates and examples/rust-agent-screen-detection; Go
client_zero_progress, resource_api, resource_api_external, socket,
raw/device_kind; go-pane envelope, frame, token, provider, conn,
richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi,
BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig
raw/authority_test and the inline tests of resource.zig, raw/client.zig,
raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no
socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt,
zig raw.zig).
Kept (wire boundary or generated check):
- live daemon tests (*_live.rs), rust mock_server, byte_attachment,
home_conversation, typed_state_ops, dock_field_capability,
local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime
(real Unix sockets), cmux-sdk in-src socket tests in client.rs,
codec.rs, resource/client.rs, socket_hash.rs (UnixListener);
- Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs
schema), package_consumer; TypeScript unix-transport, generated,
package-consumer, resource-package-consumer, code-mode cloud-relay;
Go raw client, ergonomics_external, consumer, url_open (net.Listen);
go-pane listener, websocket, examples/hello main + vectors; Java
GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport,
consumer; C++ generated, macro_collision, unix_transport; Zig provider,
stream_client, wire_presence, generated presence and the socket tests
in transport/client/resource;
- example apps' socket fakes; conformance runner; codegen --check.
Also drops the last hand-written count pins: C++ attach-surface
field_requirements size and the TypeScript emitted-event count.
Release tooling tests (bindings/tests, codegen/tests) are CI tooling and
stay. No Cargo.toml change: dev-dependencies left as they are.
* cmux-next: expose fork in the slash command menu (cx-a7r) (#18836)
* test(cmux-next): cover slash fork availability (red)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(cmux-next): add fork to the slash command menu
Expose the existing latest-turn fork action through the shared cmux slash command registry. Keep unavailable actions out of the menu and route /fork through the same action as the chat menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* gallery(cmux-next): cover the slash fork command
Add a focused composer gallery variant that types /fork and checks the cmux-owned row alongside harness commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-next): format slash command registry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): make slash fork gallery forkable
Give the focused gallery variant a completed turn sequence so the new /fork row is actually rendered and exercised.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(next): keep slash fork coverage at the webview boundary
Drop added command unit coverage and the obsolete fixed command-list test. Retain the slash-fork gallery interaction.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl]
35a61bd340b7 added enum HomeAppLinks (all-static public surface), which
lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by
making it a struct with an empty public init. URL.isChiefSubagentLink is
the same check on the receiver type; behavior is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt (#18896)
* test(ci): the base autofix regenerates without touching frozen paths (red)
base-autofix.sh copies the Mac job's regenerated files into a checkout,
skipping frozen paths, and adds a missing cmux-tui tree input to both
lists. Red: the script does not exist yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt
After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix
repairs the mechanical reds in one commit on top of it: the generated
files the Mac generated-files job rebuilt (its cmux-next-generated-patch
artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in
cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never
written; the app FFI pin stays with the app-ffi-repin pull request.
The push uses a GitHub App token minted only for the push step and a
plain push that never overwrites a moved base. Dry run until the repo
variable CMUX_NEXT_BASE_AUTOFIX is 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ci): the base autofix never writes a workflow file (red)
The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows
changes. A regenerated workflow file is skipped and reported, and a
missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's
paths) is reported without writing either list. Red: both are written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN
No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the
repair; no ruleset or branch protection applies to feat-cmux-next.
GITHUB_TOKEN cannot push workflow files, so every .github/workflows path
is frozen for the bot, and missing cmux-tui tree inputs (whose second
list is cmux-tui-artifacts.yml's paths) are reported, not written. Its
pushes start no workflow: the next push's cmux-next run verifies the
repair commit. The trigger also checks the run's workflow path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913)
36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and
cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste::
image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only
looked for crate::image_paste under cmux-tui-core, found 9 constants
named CAPABILITY and failed, so release rails is red on every PR and on
nightly-next. A crate:: path whose first segment lib.rs re-exports from
a workspace crate now also names that crate's module file.
No bead (repairs the cx-4l51 guard).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: format staged files before commit (#18808)
* ci: format staged files in the trusted pre-commit hook
* ci: guard formatter scope for staged files
* ci: scope Rust formatter guard to its package
* ci: use direct rustfmt and skip merge formatting
* ci: pass the cmux-tui Rust edition to rustfmt
* ci: check rustfmt on the cmux-tui packages a PR touches (#18800)
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: check rustfmt on the cmux-tui packages a PR touches
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit
The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): leave the relay circuit to its own repair
Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next (#18781)
* ci: add mini-first Swift canary for cmux-next
* ci: remove unit tests from Swift canary change
* cmux-next: repin app FFI to current base release (#18776)
* cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698)
* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree
#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui
Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-next): the newest-published search deepens only this commit's history
A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ci): keep cmux-next minis first through bot retries (#18615)
* docs(cmux-next): map UI parity reference sources (#18561)
* docs(cmux-next): map UI parity reference sources
* docs(cmux-next): add media preview reference source
* docs(cmux-next): define reference freshness checks
* fix(nightly): bound the publish notes step at 10 minutes (#18404)
* test(nightly): the notes step cannot spend the publish budget before the upload (red)
Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(nightly): bound the publish notes step at 10 minutes
The notes take seconds since 0115b2684cf. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622)
* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself
Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): the tree gate watches the base and may pin the tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree
When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a transient wrong binary read must not fail publication
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read a mismatched published binary again before failing
R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): a pull request gate pins a tree its base never builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): a pull request gate pins a tree its base never builds
A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retain base tree dispatch tests
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states (#18901)
* ci(gallery): capture narrow responsive states
* test(gallery): cover workflow matrix changes
* fix(gallery): dedupe equal responsive widths
* ci: shard gallery matrix renders
* ci: retrigger sharded gallery validation
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* test(cmux-next): appearance change mid-edit keeps the omnibar edit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): cover an empty omnibar through a light/dark switch The placeholder only restarts editing while it shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): edit the omnibar in a key window through a light/dark switch The offscreen harness window cannot become key, and AppKit restarts an edit only in the key window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): keep the omnibar edit through a light/dark switch Setting NSTextField.placeholderAttributedString mid-edit ends and restarts the edit, which ran the focus coordinator inside AppKit's endEditing and overflowed the stack. Write the cell's placeholder while editing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4 got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c8 moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* fix(cmux-next): filter hidden WebViews from scene snapshots * fix(cmux-next): harden scene snapshot validation * fix(cmux-next): reset scene popovers before capture * fix(cmux-next): await scene animations without polling * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b26. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ain actor (cx-t2x.3) (#18398) * test: art shows without a launch flash BackdropLaunchTests pins cx-t2x.3: a backdrop decodes no larger than the screen, its texture renders once into a bitmap (no lazy Core Image rep for the commit to render), every filter keeps the source size, the next launch's first frame shows the snapshot an earlier launch kept and swaps in the full image without a fade, a replaced file is not served from its snapshot, and picking art starts the decode before any window asks. BackdropImageStore takes the new API as stubs that keep today's behavior, so these fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: art shows in the first frame, decoded and textured off the main actor BackdropImageStore decodes a backdrop no larger than the largest screen, runs the texture pass off the main actor into a bitmap (it was a TIFF encode and a lazy Core Image rep rendered in the main actor's commit), and keeps the result as a JPEG snapshot in the app's caches, named for the source file's size and date so a replaced file decodes again. The next launch's first window shows a small copy of that snapshot in its first frame and swaps in the full image in place, without the fade; only art never seen before fades in. ThemeScope starts the decode when settings pick the art, before any window asks. BackdropTextureCache goes: the store caches per source and texture, and its tests moved to BackdropLaunchTests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: drop this PR's unit tests (no-unit-tests rule) Lawrence 2026-10-09: cmux-next changes add no unit tests. BackdropTextureTests keeps only the removal of tests for the deleted cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * CmuxNextDesign: Liquid Glass fallback for macOS 14/15 (cx-s6wi.5) GlassPanelView draws NSGlassEffectView on macOS 26 and an NSVisualEffectView with the same corner radius, tint and hairline before it. Glass.makePanel, makeContainer, the window backdrop (glass frosts at radius 20 like Ghostty.app), overlay surfaces and the glass button bezels/styles go through one switch, Glass.isLiquidGlassAvailable; Debug builds force the old material with CMUX_NEXT_DEBUG_LEGACY_MATERIAL=1. Only CmuxNextDesign calls the native glass API. * CmuxNext: the local Chief Settings panel sets the engine through chief.engine.set, never writes engine.json (cx-opu0, cx-4w47) The brain (optchat-chief) is the one writer of optchat/engine.json and checks each value. The panel read-modify-wrote the file with no lock and no check: lost updates against 'chief engine set', and values the brain refuses were saved and then fell back silently at the next turn. The local panel now sends chief.engine.set on this Mac's Chief owner daemon (it forwards to the brain's tools socket, as for a paired server's brain and chief.stop) and shows the brain's typed refusal. Reads stay a read-only mirror of the files. HomeChiefFiles.setEngine is deleted. * apps: the apps-v1 client replaces the in-app engine (V-8, cx-qbmc; port of PR 16871) Swift mirrors the local daemon's app supervisor and sends intents; no app code, registry, grant table, storage or manifest validator runs in the app. CmuxNextApps: AppsTransport + AppsClient, a confirmed mirror of apps-list written only by replies and apps-changed lists, plus an ordered apps-set intent log (nothing queues while the supervisor is unreachable); scene streams per mount (apps-mount, apps-scene with reset, apps-dispatch with origin user). AppManifest keeps only the fields the UI renders. The App Store pages keep their history and undoable Remove and gain Hide/Show, default-app badges and the unavailable reason. Deleted: AppEngine, AppHost, AppWatchdog, AppGrants, AppEventHub, AppRegistry, AppRegistryFile, AppBundleScanner, AppManifestValidator*, AppPreviewSink, AppStoreCatalog, the bundled JS runtime, schema, fixtures and sample dists. AppScopeTable and AppOperationError move to CmuxNextAppPermissions (their only user). CmuxNextApp: DaemonAppsTransport over the local daemon (availability from the connection, its epoch and apps-v1; apps-* events from store side events that also outlive a tree snapshot). apps-run carries the caller's origin; user only on a verified connection. AppsProviderChannel serves the coderouter and action families over the provider channel with the existing owner handlers, one registration per connection with backoff, answers on the arrival connection, cancels the old connection's calls, and answers apps.disabled while the organization policy turns apps off; it leaves other families (the Cloud credential relay) to their own provider. Sidebar items and sections release their mounts when they leave the layout. The App passes its first-party packages to the daemon as CMUX_APPS_FIRST_PARTY_DIR (hardening: cx-e0cs). Deleted AppOperationRouter, AppStorageStore, AppTopologyReads, AppNetFetch. sync-app-runtime.sh copies scopes, scope classes, whole first-party packages (catalog/ added) and sample manifests and assets only. No unit tests (NO UNIT TESTS rule). Tagged-app preflight runs after the landing (YOLO rule); remains: cx-e0cs/cx-0uo1 (hq-84), cx-kyfd. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-tui): delete the unit tests of 10 networked crates, keep the socket tests (cx-034r) Unit-test deletion lane, slice 4c (Lawrence 2026-10-10, "Delete all now"; chief ruling: in-src tests that open a real socket or spawn a process and assert on what crosses it stay in place). Crates: cmux-remote, chatmux-relay, cmux-server, cmux-server-core, cmux-tui-platform, cmux-tui-cdp, cmux-pane-protocol, cmux-remote-protocol, cmux-cloud-cli, cmux-coderouter. Tests before: 1,268; after: 241 (1,027 deleted). Rule per test: kept when the test or a helper it calls binds or dials a socket, starts a server, or spawns a process, and it does not reach a cfg(test)-only production hook. Everything else goes, with: - the cfg(test)-only production hooks (test barriers, fault injection, counters, *_for_test entry points, test_support modules) and the helpers, fields and imports only deleted tests used; - tests/ files that call library code only (cmux-server access, service; cmux-server-core health, layout_ports, manifest_catalog, pg_macos_ids; cmux-remote-browser-host is not in this slice; cmux-coderouter config). Kept whole as contracts: cmux-pane-protocol tests/conformance.rs (shared vectors), cmux-server-core units_golden.rs, pg_plan.rs (goldens) and pairing.rs (RFC 8032 vectors). Kept tests that relied on deleted test hooks are deleted too (for example cmux-tui-cdp socket_shutdown_disconnects_a_backpressured_event_receiver). CI: cmux-tui.yml macOS steps drop the deleted unix_process_scope, cmux-remote macos_pty_ and server-core layout_ports selectors; cmux-tui-build-package.yml drops "Test release remote sequence rollback" (the cmux-remote unit test it ran is deleted; 367 s on that path). Not in this slice: cmux-rd-host, cmux-remote-browser-host and -testhost (own workspaces, fleet builds), security crates (slice 4b). * CmuxNext: the local Chief Settings panel says this Mac's Chief is not running, not 'the server' (cx-opu0 review) Review of the chief.engine.set move: a local set with no Chief owner connection, or with the brain host down, showed the paired-server text. New case localUnreachable with its own string (en + ja translated, other languages needs_review as the table does). * cmux-next: queued prompts become compact rows attached to the composer (#18214) * test(cmux-next): queued prompts are numbered rows on the composer box's top edge (red) The queue becomes part of the composer box, numbered, and shows a prompt's full text only when its line is cut off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next: queued prompts become compact rows attached to the composer The gray Queued box gives way to numbered one-line rows on the composer's top edge, inset so the box's rounded corners lead into them. The list lies over the transcript's foot instead of taking layout space, so queuing, sending or removing a prompt never moves the composer or the transcript. A prompt shows its full text as a tooltip only when its line is cut off. The gallery gets queued and queued-long variants, with the composer box as a strict anchor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(cmux-next): regenerate the agent pane and page bundles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd340b7 added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b2684cf. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> * ci: size Swift suite and webviews parallelism to the fleet CPU grant (CMUX_CI_CPU_BUDGET) The hq build fleet now admits ci-steps by CPU budget and passes each step the cores it was granted as CMUX_CI_CPU_BUDGET (hq build-fleet internal/cpubudget). run-swift-testing-suites.sh caps CMUX_SWIFT_TEST_SUITE_JOBS at the grant, and run-webviews-tests.sh uses the grant as its default file concurrency, so a step never runs more processes than the cores it holds (2026-10-10: 4 suite steps of 8 suites on a 14-core host ran at load 88). * cmux-next: keyboard-first Add project panel (#18395) * feat(cmux-next): add project badges and checked state * refactor(cmux-next): share project badges across pickers * test(cmux-next): cover project chooser in gallery * fix(cmux-next): type project chooser gallery props * chore(cmux-next): regenerate the agent pane bundle * chore(cmux-next): regenerate the agent pane bundle after base merge * chore(cmux-next): regenerate the agent pane after latest base merge * gallery: fix project chooser entry imports * style: format project badge * cmux-next project chooser: add keyboard-first project panel Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * gallery: wait for add project panel states * gallery: stabilize add project step plays * gallery: keep add project panel geometry stable * composer: show setup-required project sources * feat(cmux-next): add keyboard-first project panel Add a Base UI command panel for environment, source and folder selection with fixed geometry, keyboard hints, setup-required sources and gallery variants. Existing native project.browse remains the production fallback until a reviewed directory-list host operation exists. * chore(cmux-next): regenerate the agent pane bundle Generated remotely from the exact Add Project panel head. * chore(cmux-next): keep generated bundles at base * ci: retrigger full PR workflows * fix(cmux-next): refresh agent pane string catalog * fix(cmux-next): use semantic project status output * fix(cmux-next): harden add project panel * fix(cmux-next): sync pane strings after base merge * fix(cmux-next): route project shortcuts through ui scope * fix(cmux-next): skip disabled project choices * fix(cmux-next): preserve disabled option semantics * test(next): cover add project menu behavior Co-authored-by: Leo Li <cheerleaderleo@outlook.com> * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 adapters: the socket test picks a non-temporary folder * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(bindings): delete the SDK unit tests (cx-034r) Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now"). SDK tests in cmux-tui/bindings before: about 1,243; after: about 507. Deleted (call SDK code directly, in-memory fake or scripted transports, net.Pipe, count/shape checks): TypeScript authority, base64, device-kind, field-compatibility, wire-json, client, resource-api, websocket-transport, presence; Python consumer, device_kind, events, aio_cleanup, convenience, schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind, error_codes, state_handles, public_api and the in-src tests of cmux-sdk (except the socket ones below), cmux-daemon-client, cmux-sidebar, the two bootstrap crates and examples/rust-agent-screen-detection; Go client_zero_progress, resource_api, resource_api_external, socket, raw/device_kind; go-pane envelope, frame, token, provider, conn, richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi, BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig raw/authority_test and the inline tests of resource.zig, raw/client.zig, raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt, zig raw.zig). Kept (wire boundary or generated check): - live daemon tests (*_live.rs), rust mock_server, byte_attachment, home_conversation, typed_state_ops, dock_field_capability, local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime (real Unix sockets), cmux-sdk in-src socket tests in client.rs, codec.rs, resource/client.rs, socket_hash.rs (UnixListener); - Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs schema), package_consumer; TypeScript unix-transport, generated, package-consumer, resource-package-consumer, code-mode cloud-relay; Go raw client, ergonomics_external, consumer, url_open (net.Listen); go-pane listener, websocket, examples/hello main + vectors; Java GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport, consumer; C++ generated, macro_collision, unix_transport; Zig provider, stream_client, wire_presence, generated presence and the socket tests in transport/client/resource; - example apps' socket fakes; conformance runner; codegen --check. Also drops the last hand-written count pins: C++ attach-surface field_requirements size and the TypeScript emitted-event count. Release tooling tests (bindings/tests, codegen/tests) are CI tooling and stay. No Cargo.toml change: dev-dependencies left as they are. * fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl] 35a61bd340b7 added enum HomeAppLinks (all-static public surface), which lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by making it a struct with an empty public init. URL.isChiefSubagentLink is the same check on the receiver type; behavior is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt (#18896) * test(ci): the base autofix regenerates without touching frozen paths (red) base-autofix.sh copies the Mac job's regenerated files into a checkout, skipping frozen paths, and adds a missing cmux-tui tree input to both lists. Red: the script does not exist yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: a base autofix bot commits generated files, tree inputs and fmt After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix repairs the mechanical reds in one commit on top of it: the generated files the Mac generated-files job rebuilt (its cmux-next-generated-patch artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never written; the app FFI pin stays with the app-ffi-repin pull request. The push uses a GitHub App token minted only for the push step and a plain push that never overwrites a moved base. Dry run until the repo variable CMUX_NEXT_BASE_AUTOFIX is 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(ci): the base autofix never writes a workflow file (red) The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows changes. A regenerated workflow file is skipped and reported, and a missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's paths) is reported without writing either list. Red: both are written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the repair; no ruleset or branch protection applies to feat-cmux-next. GITHUB_TOKEN cannot push workflow files, so every .github/workflows path is frozen for the bot, and missing cmux-tui tree inputs (whose second list is cmux-tui-artifacts.yml's paths) are reported, not written. Its pushes start no workflow: the next push's cmux-next run verifies the repair commit. The trigger also checks the run's workflow path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913) 36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste:: image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only looked for crate::image_paste under cmux-tui-core, found 9 constants named CAPABILITY and failed, so release rails is red on every PR and on nightly-next. A crate:: path whose first segment lib.rs re-exports from a workspace crate now also names that crate's module file. No bead (repairs the cx-4l51 guard). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: format staged files before commit (#18808) * ci: format staged files in the trusted pre-commit hook * ci: guard formatter scope for staged files * ci: scope Rust formatter guard to its package * ci: use direct rustfmt and skip merge formatting * ci: pass the cmux-tui Rust edition to rustfmt * ci: check rustfmt on the cmux-tui packages a PR touches (#18800) * test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. These tests pin a helper that runs cargo fmt --check once per touched package, checks every package when a rustfmt config changes or there is no base, and names each unformatted package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: check rustfmt on the cmux-tui packages a PR touches PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml already runs on every PR and push touching cmux-tui/** on hosted Linux; its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed .rs file or Cargo.toml to its nearest tracked package and runs cargo fmt --check on it with the pinned toolchain. No build and no dependency download. A rustfmt config or toolchain change, or no base, checks every package; vendored crates and deleted packages are skipped. A PR compares with its merge commit's first parent, a push with the commit before it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit The new rustfmt job's full run found two base packages that fail cargo fmt --check: acpmux, from #18706's draft tests and their module order, and the Cloudflare relay's circuit.rs. Formatting only, exactly the hosted rustfmt diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style(cmux-tui): leave the relay circuit to its own repair Touching the Cloudflare relay runs its lane, whose npm audit is red on base (sharp and undici advisories through wrangler, fixed only by a wrangler bump outside the stated range). That is the relay's own repair, so this PR keeps acpmux's formatting only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci: add mini-first Swift canary for cmux-next (#18781) * ci: add mini-first Swift canary for cmux-next * ci: remove unit tests from Swift canary change * cmux-next: repin app FFI to current base release (#18776) * cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698) * test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree #16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet same-tree cmux-tui failed them because the base tip's tree was never published (its artifacts run was cancelled). Such a PR should reuse the newest published tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip the tree jobs when none is published, never fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui Path routing records whether the pull request's own diff touches cmux-tui/ or ghostty-next. For one that does not, a merge tree that is not ready no longer fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published tree in the merge's history and reports ready with tree_fetch_key, which the daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with none published it reports skipped. Pushes, dispatches and PRs that change cmux-tui keep the hard check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-next): the newest-published search deepens only this commit's history A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this PR's first run it took path routing past its 5-minute limit (job 113609407061) before the probe's base fallback, which then resolved in under a second. Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep cmux-next minis first through bot retries (#18615) * docs(cmux-next): map UI parity reference sources (#18561) * docs(cmux-next): map UI parity reference sources * docs(cmux-next): add media preview reference source * docs(cmux-next): define reference freshness checks * fix(nightly): bound the publish notes step at 10 minutes (#18404) * test(nightly): the notes step cannot spend the publish budget before the upload (red) Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and was cancelled mid-upload, leaving partial release assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(nightly): bound the publish notes step at 10 minutes The notes take seconds since 0115b2684cf. A regression now fails the step before any asset upload, instead of spending publish-nightly's 30 minutes and being cancelled mid-upload with partial assets left on the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622) * test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself Publisher run 37505519359 failed transiently and its retry was replaced by a newer feat-cmux-next push, so the tree was never published and lanes pushed cmux-tui-pin-* branches by hand to unblock their gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): the tree gate watches the base and may pin the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree When two run checks find no artifacts run that will publish the tree, the gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the artifacts workflow there, once, then keeps waiting. A pull request now watches its base commit (the merge's first parent) instead of no publisher, so it neither waits 45 minutes for a tree nobody builds nor needs a lane to push a pin branch by hand. A superseded push still skips; forks keep a read-only token and no autopin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-tui): a transient wrong binary read must not fail publication Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cmux-tui): read a mismatched published binary again before failing R2 objects are write-once, so a digest mismatch on a binary the run just uploaded is a bad read. Fetch it again from a cache-busting URL up to three times, and name the response headers when it still differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(cmux-next): a pull request gate pins a tree its base never builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): a pull request gate pins a tree its base never builds A pull request that changes cmux-tui has a merge tree no push builds, and the artifacts workflow's pull_request_target trigger has never started a run, so its gate waited 45 minutes with the run check off. With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once and watches that run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci(cmux-next): retain base tree dispatch tests --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * ci(gallery): capture narrow responsive states (#18901) * ci(gallery): capture narrow responsive states * test(gallery): cover workflow matrix changes * fix(gallery): dedupe equal responsive widths * ci: shard gallery matrix renders * ci: retrigger sharded gallery validation --------- Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(gallery): cover composer scope row states (#18590) * refine agent composer context surface * show composer controls in the toolbar * update composer layout assertion * cover visible access mode label * format unified composer markup * test: cover model picker Escape away from search * fix: close model picker on Escape from any control * fix: keep unified composer radius tokenized * test(gallery): cover composer scope row states * test(gallery): use public composer fixture labels * plans(projects): daemon-owned project store with source adapters, event-driven resync, merge rules (cx-m0p7 design) * test(cmux-tui-core): project list reducer merge rules and user edits (red, cx-m0p7) * feat(cmux-tui-core): project list reducer: sources, user overlay, missing state, refusals (cx-m0p7 slice 1) * style(cmux-tui-core): rustfmt the project reducer * style(cmux-tui-core): rustfmt state.rs module list * feat(cmux-tui-core): project-list-v1 store, ops and spec: project.list/observe/add/update/remove/sync (cx-m0p7 slice 1) * fix(cmux-tui-core): collapse the project rename check (clippy) * fix(cmux-tui-core): project store clippy (semicolons; source toggle helpers wait for slice 3) * fix(cmux-tui-core): semicolon on the project row parse warning * refactor(cmux-tui-core): request ids move to resource/request_id.rs (move-only) so resource.rs stays under the god-file limit * test(cmux-tui-core): project list review cases: idempotent observe, null clears, case-insensitive refusals, disk facts from the caller, cap (red, cx-m0p7) * fix(cmux-tui-core): project store reads no disk for observed paths, null clears, idempotent observe, case-insensitive refusals, cap, disk facts from the app (review, cx-m0p7) * chore(godfiles): resource.rs meets its budget (row dropped) * CmuxNext: failing tests, a split shows a provisional pane before the reply (S3 T1, store) * CmuxNext: a split intent shows a provisional pane beside its target until the daemon's pane with the same public id replaces it (S3 T1, store) * cmux-layout-reducer: failing test, SplitNew puts a new pane with a new tab beside the target (S3 T3) * cmux-layout-reducer: SplitNew, a new pane with a new tab beside the target (S3 T3); covered by the random op sequence property test * S3: the optimistic split matches the Rust reducer's SplitNew vectors (L4 parity: Rust generator with drift check, Swift reader) * S3 tests: optimistic Cmd+D on a client-keys daemon (T1 app, T2 store frame budget), provisional pane mapping continuity, target gate and typeahead order (T7) * CmuxNext: Cmd+D shows the new pane before the reply on a split-client-keys-v1 daemon; its terminal view waits for the daemon's terminal and keeps keys typed meanwhile (S3) * S3: provisional terminal view helpers in their own file; test daemon record as a Sendable box * S3: TabContentCache within its size limit; the test daemon serves terminal-placement-env-v1 * cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay * cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe * cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders) * S3: drop the unit tests and the reducer op (NO UNIT TESTS rule); verification moves to the tagged app via the debug socket * cx-m0p7 store: socket-level behavior test on a real daemon replaces the in-process unit tests (NO UNIT TESTS) * cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS) * cx-m0p7 store: the socket test picks a non-temporary folder * cx-m0p7 adapters: the socket test picks a non-temporary folder * S3: tagged-app proof harness (Cmd+D through debug.key, read-screen) and its results * S3: the provisional split maps columns and rows instead of indexing them (crash ratchet) * cx-m0p7 store: keep LocalOperation in resource.rs (boundary check reads it); move encode_hex out for the god-file limit * S3: SpawnOptions drops unserved fields itself (DaemonConnection stays within its size limit) * fix(cmux-next): WebKit right and middle buttons: right presses go in as AppKit right-button events, a middle press carries button number 2 on its own Quartz form (DOM button 1), wheel events take the Quartz location AppKit gives the window point, and the web view empties the context menu of a right-click the app did not dispatch, so an agent's right-click opens no native menu (cx-ollo) * cmux-next: harden the credential relay and the Cloud create approval (cx-t2rz security review) P2-1: the relay serves only the app cmux/cloud and only cloud.* ops (credential.app_refused / credential.op_refused otherwise): an install token with origin user counts as the person on the Worker, so no other app or op family may borrow it. P2-2: before feed.answer the app reads integration.approval.get as the person and requires op cloud.machine.create, state pending and exactly the params the person confirmed; the feed item must carry the same request and digest, tool cloud.machine.create, and poster system:cloud:<team>. Any mismatch answers nothing and shows why. The confirmation shows the machine size and name. P3-1: the relay registers only on the app server link path (never with the legacy default or in release). P3-2: a create from the progress view's Retry (no gesture origin) asks the person first; only an action with origin user skips the sheet. P3-3: the session call for the approval refuses redirects and keeps no cookies or cache. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cmux-next): short update titles; the test feed and announcements are notice cards Chief 2026-10-09 (round 2 of Lawrence's update card ask). - Update titles are short and the version moves to the detail line: "Update Available" / "Version 1.0.0-nightly.…", "Update Check Failed", "Needs macOS 27.0 for …". Before, "cmux 1.0.0-nightly.376…" and "Couldn't Check for Up…" truncated in a 260 pt sidebar. UpdateNote's needsNewerMacOS carries the found version. 4 new strings (en + ja, 19 languages needs_review). - The test-feed notice (Use Real Feed, no x) and the announcements (their allow-listed Try It, an x that dismisses for good, the next one shows) are the shared notice card. Order: update status, test feed, announcement, tip; the "cmux Updated!" card waits while an update status or a test feed shows. - The plain R114 card stack is gone (SidebarCard, SidebarCardView, SidebarCardStackView, SidebarCardStackLayout, SidebarModel.cards and onCardAction); its hover test goes with it. The footerCards slot stays. Announcements now show whether or not the sidebar chrome is revealed. - NO UNIT TESTS (Lawrence 2026-10-10): the unit tests this change breaks are deleted in this diff (UpdateNoticeTests and its ManualClock copy, from 31d888016eed / d344241b7a88; the stack hover test; two stack-card asserts). Proof is the tagged app on cmux-lawrence-2 through the debug socket with screenshots. Bead: cx-t34p Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cmux-next): a check while an update waits shows the waiting update Lawrence's NIGHTLY (2026-10-09/10): 3797671859401 was downloaded and waited for a restart; Sparkle skips every check while an update waits ("update check ignored while install is progressing"), so his manual Check for Updates showed nothing and never saw 3800566557701. - Check for Updates while an update is staged does not ask Sparkle (it would ignore the check); it logs and answers with the staged update. - The staged update card ("cmux X is ready", Restart to Update) shows after such a check even under updates.notify silent, which otherwise hides it. Before, a silent install had no answer to a check at all. Proof: tagged app on cmux-lawrence-2 through the debug socket (staged update + notify silent: no card; Check for Updates: the card), with screenshots. No unit tests (Lawrence 2026-10-10). Bead: cx-t34p Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * ci(nightly-next): keep the acpmux and OptChat Chief dependency builds between nightlies (cx-g34i) build-nightly-app compiled every Rust dependency of acpmux (53 s + 46 s, two arches) and the OptChat Chief (24 s + 24 s) from scratch on each nightly-next run, on the serial path before the Release build. Swatinem rust-cache on their target dirs (cmux-tui/target/acpmux-app, optchat-chief/target/app), nightly-next track only; cargo rebuilds what changed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-tui): drop the hand-written operation and command counts (cx-034r) Unit-test deletion lane, slice 3 (chief order): every lane that added an op had to edit 4+ files with a hand-written count (palette hit 211, 212, 213). The generated-from-spec checks (spec inventory, SDK sync, the set equality of generated commands and the IR) already prove coverage. Removed, no other assertion changed: - cmux-tui-core resource_router tests: operations.len() == 213 (2x); - cmux-tui transport path coverage: cases.len() == 188, catalog 213; - check-resource-api-boundary test: operations 213; - conformance runner: TRANSPORTED_OPERATION_COUNT (now: a non-empty catalog), and its test; - SDK raw coverage tests: command count 236 and event count 69 in C++, Go, Java, Python, TypeScript, Zig (src and the watch example); - spec/resource-operations-v2.md names the JSON catalog, not a number. Pure assertion deletion: no red test first. 0 tests deleted, 0 added (test count before == after). * cmux-next: S3 optimistic Cmd+D off by default (cx-wb5.72) Keys typed right after Cmd+D lost the tail of the line in 1 of 8 proof runs. Every daemon now serves split-client-keys-v1, so the capability gate protects no one. PaneSplitCommand.optimisticSplitEnabled = false sends every split through the old path; the landing with the ordering fix sets it back. split-optimistic-proof.py records the path each Cmd+D took and takes an expected path (optimistic|old) as a gate argument. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(scheduler): failing tests for automations, runs and bodies in rows (g1) Head under 100 KB with 100 automations of 20,000-character instructions and 450 kept runs; bodies stored once with reference counts; keyset paging for automation.list and run.list stable under inserts; run.get joins the body; migration of an old JSON head is idempotent on a live DO and after a rollback refill; disable, delete and a policy deny cancel every queued run. Deterministic: reads answer without an ok field, the cancelled-run check uses a sleeping first run, the migration check binds the object before it reads the head. Re-applied from orphaned fe31fa1f0ed8 + 467e890d7cb1 (cx-3bi.38). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat(scheduler): automations, runs and bodies in rows, keyset paging, live migration (g1) SchedulerDO moves to row mode (plans/cmux-next/backend.md (g), DO audit F-1). automation/<id> and run/<id> rows hold the records without their bodies; body/<sha256> rows hold each distinct body once with a reference count (automations plus kept runs) adjusted in the same commit; a finished/<run> index lets prune drop the oldest finished runs past 200 without reading the open ones. A started run keeps its body hash. The head keeps owner, settings, counters, chains and the counts automation_count, open_runs, finished_count, row_seq. All four tables are private, so events and snapshots carry the head only. One lookup module (domains/scheduler-rows.ts) and one per-op store (domains/scheduler-store.ts) replace every read of state.automations and state.runs. New reads run.list and run.get; automation.list pages with cursor and limit and its first page is unchanged. System op scheduler.rows_migrate (key carries the head seq) rebuilds the rows from an old head's maps on bind and drops the maps in one commit; the alarm path migrates first too. Re-applied from orphaned 7ab757b458e5 onto feat-cmux-next (cx-3bi.38). run-policy.test.ts keeps the tip's createWithTeamDown helper (cx-nfts) and reads next_at from the automation row. Catalog, TS client, Rust cloud-wire client, app-host ops/scopes/d.ts and the bundled AppPlatform scopes.json are regenerated with the repo generators, not hand-merged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(scheduler): failing tests for the g1 review findings A run pruned while the dispatch loop awaits a create is skipped and onWake goes on; a refilled head migrates by merge (maps win per id, rows the maps lack stay with their bodies); reads on a legacy head answer the retryable owner.migrating; run.list with a sparse filter over more than 200 kept runs scans every step and ends without an empty last page. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(scheduler): g1 review: stale dispatch rows, merge migration, legacy reads, paging - onWake re-reads each run before it builds the dispatch params: a disable, delete or deny during an earlier create may have cancelled the run and prune may have dropped it with its body, which made requireBody throw and stop the wake. A missing, started or terminal run is skipped. - scheduler.rows_migrate merges a refilled head instead of replacing the rows: the maps win per id, rows the maps lack stay with their stored bodies (dropped only when that body row is gone), and every body reference count is recounted. - Reads on a legacy head answer the retryable owner.migrating, the same as the reducer. - run.list looks one match ahead, so a page that ends the list has no cursor to an empty page. - automation.list keeps automation_count and next_cursor optional while an old Worker can answer (deploy skew); catalog, TS client, Rust cloud-wire client and app-host outputs regenerated. - plans/cmux-next/backend.md (g): roll-forward only, merge semantics, and the operator recovery when a pre-g1 build meets a migrated head. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(scheduler): drop the engine-level g1 unit tests (NO UNIT TESTS rule); the SchedulerDO op tests stay as the behavior proof Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * scheduler: regenerate the cloud-wire Rust client and the bundled AppPlatform scopes.json after the rebase Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * cmux-next: a Cloud create approval must be for the create's own team; the mismatch text stays localized (cx-t2rz review) The approve step takes the backend team the relay's create bills (the install token's team claim, captured when the create starts) and requires the feed item's approval.team to equal it, so an identical create pending in another team the person belongs to is never approved. The mismatch reason goes to the log only; the person sees the localized text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * scheduler (cx-3bi.38): regenerate the cloud-wire Rust client on the tip Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(rd-host): bench sends synthetic upstream frames; upstream loopback check (red: no host sink) (cx-9zn) cmux-rd bench --upstream mic|camera|screen opens an upstream stream, sends synthetic frames through cmux-rd-core's UpstreamSender with the host's feedback, and reports frames sent/acked and an FNV-1a hash. scripts/upstream-loopback.sh expects a host with --upstream-record DIR to record every sent frame; red until the host has the recording sink. * feat(rd-host): --upstream-record DIR development sink for viewer upstream media (cx-9zn) The desktop host offers up_media only with a sink; it had none (NoSink), so no viewer could send its microphone, camera or screen anywhere. The new RecordSink (development only, off by default) writes each upstream stream to an owner-only file (Annex-B .h264, length-prefixed .opus-packets) and logs frames, bytes and an FNV-1a hash on close. The sink is chosen per session; without the flag the host still offers no upstream caps. * fix(cmux-next): the diff sidecar keeps its pipe readers until end of file DiffSidecarProcess released the Process at the child's exit, and with it the Pipes and their read FileHandles. When the exit was handled before the stdout end-of-file event, the FileHandle closed its descriptor and the EOF never came: the reply never finished and the caller waited for the request deadline (130 s; a 60 s hang of writesTheRequestAfterTheReadyMarker... on the ManualClock, 7 times on 2026-10-09). The invocation now holds both read ends until each reads EOF, and releases them when the launch fails. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Bead: cx-kuxw * fix(cmux-next): a cloud edit marks the source degraded before it subscribes requireEditable started the conversation's subscribe and only then set degraded. A subscribe that went live in between called recover() on a source that was not degraded yet, so no .ownerRecovered went out and the edit waited for a recovery nothing would send (CloudHomeSourceTests withoutAnEchoTheEditSubscriptionEndsAtTheDeadline, 60 s, once under load). The flag is now set in the same lock as the target read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Bead: cx-kuxw * test(cmux-next): live-daemon suites wait for the daemon's events, not deadlines The harness connection (and QuitSessionsTests' relaunch connections) send no client deadline: each request waits for the daemon's reply, so create-terminal returns when its host is up. The 30 s bound of 57a5a8129382 only moved the line a loaded host crossed at 5 s. TerminalHosts.awaitExit waits for kernel exit events (one process source per pid) instead of a 50 ms kill(0) poll; its 30 s bound and the suites' .timeLimit are only hang guards. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Bead: cx-kuxw * test(cmux-next): the palette benchmark measures the thread's CPU time The budget read wall time, which counts time the thread waited for a core: with 32 suite processes on one host the ranking median read 123 ms (54.8 ms in another run) against 50 ms. The ranking runs synchronously on the calling thread, so its CPU time is the search cost. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Bead: cx-kuxw * fix(rd-host): review fixes for the upstream record sink (cx-9zn) Review subagent should-fix items: the record dir must be a real 0700 dir owned by this user; a per-session byte limit (--upstream-record-max-mb, default 1024) and 64-file limit; a sink that cannot start falls back to NoSink instead of dropping every viewer; unique file names; Drop logs open streams. Bench uses the welcome's max_datagram. upstream-loopback.sh counts host lines per run (a failed run no longer shifts later checks), accepts paced drops, and takes PORT/PORT_NOSINK. * test(cmux-tui): delete the unit tests of 18 leaf crates (cx-034r) Unit-test deletion lane, slice 4a (Lawrence 2026-10-10, "Delete all now"). In-src #[cfg(test)] tests and the tests/ files that call library code are deleted in cmux-motion, cmux-history, cmux-conversation, cmux-chat-index, cmux-terminal-iface, cmux-terminal-sizing, cmux-tui-cloud-conversations, cmux-theme-tokens, cmux-agent-pane-policy, cmux-tasks-core, cmux-tasks, cmux-app-manifest, cmux-chief, cmux-terminal-client, cmux-mobile-core, cmux-mobile-ffi, cmux-unix-socket and ghostty-vt. Kept (boundary or cross-language contract): - ghostty-vt tests/ (bytes in, terminal state out; chief ruling); - cmux-terminal-client tests/route_e2e.rs and cmux-tasks tests/server.rs (real sockets end to end); - shared corpora and fixtures another language replays: cmux-conversation conformance, cmux-chief corpus, cmux-agent-pane-policy parity + typescript, cmux-history fixtures, cmux-theme-tokens load, cmux-mobile-core terminal sizing fixtures, cmux-app-manifest schema fixtures + samples, cmux-tasks-core catalog (catalog <-> Op guard). cfg(any(test, feature = "test-support")) narrows to the feature. cmux-tui.yml: the Windows step drops cmux-chat-index, which has no tests. Deferred to slice 4b (security and malformed-input cases need a boundary test first): cmux-local-auth, cmux-relay, cmux-tui-machine-protocol, cmux-tui-machine-agent-protocol, cmux-transport, cmux-encode, cmux-wg, cmux-link. Counts: 327 in-src tests and 189 tests/ tests deleted (516); 55 files deleted. * cmux-tui: two terminal_host_recovery load flakes made deterministic (cx-2dc4) pipelined_new_tabs_start_hosts_in_parallel_in_request_order asserted a wall-clock bound (8 hosts x 400 ms ready delay < 3.2 s), which IO and CPU load broke (40/40 red on a loaded Testbox). A debug-only host seam, CMUX_TUI_TEST_HOST_READY_GATE, now holds every host before Ready at a FIFO the test opens later; all records on disk while the gate is closed prove the launches overlap, and identify must reply while the creates wait. host_crash_is_named_with_its_panic_message: the abort seam fired 300 ms after install, racing the owner's PTY custody (no custody, no replacement, no host_replaced line), and systemd-coredump of the aborted 1 GB debug host kept it alive 3-6 s under load. The seam now crashes when the test opens <marker>.trigger, after wait_for_daemon_custody saw the daemon hold the master and its custody thread (renamed pty-custody, visible in /proc) end, and it disables core dumps before abort. Loaded Testbox runs (32 vCPU; P=8+32 hogs, P=24+96 hogs+8 fsync dd, P=16+32 hogs+workspace build): before 40/40 and 3/40 red; after 0/120 each. * cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1 * test(cmux-tui): server-stats write_path counters and the effect intent socket check (red) Add the optional server-stats section write_path (include-gated, like resource_projection, so older SDK decoders stay safe): effect receipt commits carried by journal writer batches, their savepoint failures, the batches that carried them, effect receipt commits that ran their own transaction on a request thread, and registry lock acquisitions on a journal writer thread (counted in release builds, process-wide). The new socket test drives a headless daemon: terminal creates under terminal output must commit their effect receipts as writer intents, with no request-side effect commit and no writer registry lock. Red today: effect_store still commits each receipt in its own request-side transaction and fsync (effect_intents stays 0). Spec: commands.md and sdk-schema.json gain the section; bindings regenerated. Bead: cx-g1fa.1 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cmux-tui): effect receipt commits ride the journal writer batch effect_store commit_resource_effect and commit_resource_effect_patch become typed writer intents (journal ingress Effect events on the durable lane). The request thread prepares the intent under the workspace registry (validation, stored fingerprint, public-fold pruning), the journal writer applies it inside its batch transaction under a SAVEPOINT per intent (one shared fsync per batch), and the request thread finishes it (projection stats, public fold) under the same registry hold. An intent that fails its checks rolls back to its savepoint and only its request gets the error; a SQLite failure still fails the batch, which the writer retries or splits as before. Lock order is unchanged: workspace registry -> registry connection -> state. commit_resource_effect_projection drops state and the connection pin before the receipt wait, keeps the registry (topology writers stay serialized), and re-locks state to install the revision. The receipt wait uses the producer deadline and commit fence: a writer error, a dropped receipt or an expired deadline returns an error and releases the registry. Prepare and executing transitions stay request-side. The writer marks its whole loop iteration (batch, commit, retries, receipt delivery) as the journal writer, so a registry lock there is asserted in debug and counted in release (server-stats write_path.writer_registry_locks, checked over the socket). Local commit fallback (counted as request_effect_commits): writer disabled, stopped, failed, not running yet, or the calling thread still holds the connection. The registry lock, the journal writer iteration and the registry connection take lock ranks in the lock-rank checker (crate::lock_rank: workspace.registry > journal.writer > registry.connection > mux.state), so debug and test builds panic on a registry lock on the writer thread on every path, in addition to the release counter. Bead: cx-g1fa.1 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(cmux-tui): wait for template terminal adoption after a daemon restart adopted_template_terminal_is_restored_in_place_after_a_daemon_restart read the parked terminal's lifecycle once, right after the restart. Adoption completes asynchronously (the terminal reads "adopting" until its host handshake lands), so under a loaded gate run the read raced it and saw "adopting". Wait for "running" with the file's bounded helper. Bead: cx-g1fa.1 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(browser-parity): snapshot reads beside the walk stay within the page-read budget (cx-2y2 red) Scenario 41 drives the REPL against hostile pages: a data table judged by its first 50 rows, an offscreen count past the node budget, a zero-size link's visible-box check, a link URL longer than the size budget, and generated content, placeholder, option label and editable text past it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): snapshot reads beside the walk stay within the page-read budget (cx-2y2 items 6, 10, 11) Ports classic 7f37c374e9f5, eeb6d5105161, 7dfa50c0910b and 84bd76a4e8e7: - A zero-size link's visible-box check charges each node it looks at. - Offscreen interactive elements are counted lazily within the node budget and the clock; past them the viewport note says "at least". - Layout-table detection reads a sample: 50 children, rows and cells per row, and 1,000 descendants for a nested table. - Generated content is read one character at a time, at most as far as the size budget can use; a placeholder and an option label are cut before they are normalized; option text and editable text are read within what the snapshot has left; an ARIA value is cut at 20,000. - A link URL longer than the size budget has left is not resolved or parsed (no offsite summary); a URL that fits is parsed once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(browser-parity): a snapshot of names that share one huge label stops at the node budget (cx-2y2 red) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(browser-host): snapshot names read their sources within the page-read budget (cx-2y2 items 8, 9) Ports classic 7b0f1a7a87a6, bcd5ad8bc5d8, 61b3f78a30d2 and part of 7dfa50c0910b. Before Playwright computes a name, the sources it would read (aria-labelledby targets, at most 64; labels; own content for roles named from content; legend, caption, figcaption; shadow content, slotted nodes, aria-owns targets, name attributes, field values, generated content) are counted within NAME_NODES 2,000, NAME_CHARS 20,000 and NAME_DEPTH 100, the nodes outside the element charged to the snapshot's budget. Past the bounds the name is read directly from the same sources, node by node and charged. Author names, the select value and elementAt names use the same bounded reads. A slot's assigned nodes are read one at a time (slotAssigned) instead of assignedNodes(), which lists them all first. Scenario 41 adds 1,0…
* test(cmux-tui): cover same-session child process groups
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): clean up all PTY session descendants
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): complete session cleanup host fixtures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): type session process identifiers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): wait for PTY session groups to exit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): ignore exited session members on macOS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): keep recovery test root under god-file limit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(cmux-tui): keep session cleanup out of god file
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(cmux-tui): own session cleanup state in unix helper
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): satisfy session cleanup clippy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): enumerate macOS session members safely
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): preserve session cleanup identity
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): cover adopted session cleanup
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): ignore zombie cleanup probes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): retire bounded cleanup failures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): treat partial session scans as unknown
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): expose cleanup escalation hook
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): use local cleanup module path
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): complete session cleanup refactor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): keep cleanup failure state cross-platform
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): tolerate poisoned session cleanup state
Co-authored-by: Leo Li <cheerleaderleo@outlook.com>
* test(cmux-tui): remove direct cleanup unit tests
Keep the daemon socket recovery coverage as the behavior proof for session cleanup.
Bead: no bead
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): format merged host runtime
Bead: no bead
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* cmux CLI: classic `cmux identify|ping|capabilities` ask the app instead of failing (cx-4w47 D1)
Skills, prompts and agent habits written for both apps run `cmux identify`
(often as `cmux --id-format both identify --json`). The v2 CLI sent it to the
resource grammar, which answered "unknown resource scope" (exit 2), also
inside a Chief turn. These words now run the app's `app identify|ping|
capabilities`: the same system.* methods the classic CLI sends. No new state.
Behavior test: tests/cmux_surface.rs classic_discovery_verbs_ask_the_app runs
the binary as `cmux` against an app socket.
* cmux CLI: `cmux identify --help` and `cmux help identify` print the app help (cx-4w47 D1, review nit)
* fix(cmux-next): Release Notes sits beside Restart to Update; UpdateChangelog is Codable
The staged card's checkbox row truncated both "Automatic Updates" and
"Release Notes" in a 260 pt sidebar (GUI proof job 1009-203236-494e23).
Release Notes now takes its natural width beside Restart to Update.
UpdateChangelog gains Codable so What's New (hq-a3, cx-ncc.45) can persist
the staged changelog across the update relaunch.
Bead: cx-lntk
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(remote): a new terminal from another machine's terminal tab opens on that machine (cx-2s5t)
In a mixed pane (a local workspace that shows an SSH or Cloud machine's
terminal), New Terminal Tab, Cmd-T and the palette opened a terminal on the
pane's own session, in the remote tab's folder path. The new terminal now
runs on the selected tab's machine through RemoteTerminalService.openTerminal;
a machine that is not connected refuses instead of falling back to this Mac.
* cmux-tui: clear-history and Kitty limits no longer wait under pty.runtime; clear-history after set-default-colors succeeds (cx-8q1f)
Same class as cx-j2zd (0293913a99ed). Clear-history and Kitty graphics
limits waited up to CONTROL_RESPONSE_TIMEOUT holding pty.runtime; the
reconnecting reader takes that lock before it reads the new stream, so a
reply on the new connection sat unread and the timeout dropped the
connection. Both now send under the lock (begin_clear_history,
begin_kitty_graphics_limits) and wait after releasing it. Kitty requests
keep their serialization through a new per-surface kitty_limits_request
lock; it and pty.kitty_graphics_limits are now ranked in lock_rank.rs
(mux.state > kitty_limits_request > geometry > term > runtime >
kitty_graphics_limits > taps).
The new boundary test clear_history_right_after_default_colors_succeeds
found a second defect: a clear-history sent just before the defaults'
resync reconnect always failed (240/240 on a loaded Testbox, 'did not
acknowledge ClearHistory', ambiguous delivery), because the abandon
failed ordered waiters. After the abandon, HostFrames now resolves
clear-history acknowledgements itself (queued or arriving); their replay
is moot because the next connection carries the cleared screen (its snapshot, a smart host's ResyncRequired or a legacy host's Output).
After: 0/240. If the stream already ended, abandon fails every waiter at once.
* fix(webviews): the peer-chat test uses the global Bun types, so import.meta.hot keeps Vite's type [cx-e391]
1239e696b4ba added `import type { ServerWebSocket } from "bun"`, the only
module import of "bun" in webviews. It pulls in bun's ImportMeta.hot, whose
on() takes () => void, so every Vite HMR listener with a payload
(src/diff/dev.ts, gallery liveStatus/registry/liveErrors, markdown-viewer
devHost, pages editor/markdown devBridge) failed TS2345. Bun.ServerWebSocket
from the global types needs no import.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(webviews): the gallery's after-host-call snapshots are afterCall, not then [cx-e391]
9097adbf3d87 named the field then, which makes the fixture object thenable
(unicorn/no-thenable warning, so vp check failed). Renamed in format.ts,
the agent pane frame and the queued-send-remove fixture.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(webviews): new raw font sizes use the type scale tokens [cx-c450]
check:type-scale failed: 224eda3199ce added addProject.css with 7 raw sizes,
519b9e7a5790 added 4 font-size: 12px in the gallery shell, and the queued
prompt row added one in acpmux styles.css. They use var(--text-body),
--text-detail, --text-caption and --text-heading now. Visible changes: the
Add project panel's close glyph is 17 px (was 18) and its tag is 11 px (was 10).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* chore(web): regenerate cmux-shortcuts.generated.json; Ctrl-Tab alias is on navigate.next [cx-rn37]
The catalog changed after ba663f26f496 without an export run, so
web/tests/docs-shortcuts.test.ts was red. Output of
bun web/scripts/export-docs-shortcuts.ts (bun 1.4.2 and node 24.11.0 give
byte-identical output). 8a7689bb3c2b (#18813) moved Ctrl-Tab from
nextSurface to navigate.next, so the alias assertion names navigate.next.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-tui): expose cleanup state to shared host startup
Bead: no bead
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test(backend): security-named API cases: route tests, deletions, and route tests slice 5 missed (cx-034r)
Unit-test deletion lane, slice 5b (chief ruling on the 168 security-named
API cases kept by slice 5).
- Re-expressed through the API Worker (worker.fetch), internal version
deleted (12): verified email (user.ensure, four claim shapes), the two
internal install migrations and the team VM owner-action ops (the public
API refuses internal ops), cron trigger refusals and an internal
scheduler op, the internal SSH ops and SSH key shapes (team_vm.ssh_cert),
and the bind refusals (POST /v1/cloud/bind: spent, wrong, expired,
malformed key, non-printable daemon version, no ledger row for a wrong
token).
- Deleted (not reachable by a client request: alarms, provider back-off,
KMS and crypto primitives, mail senders, reducers fed by Stack or Google,
config): about 60 cases, 20 files.
- Deleted 22 DO-internal cases that slice 5 kept by a too-broad helper
match (team VM ledger/registry/create, home inbox paging, VM export).
- Restored 20 route tests that slice 5 deleted by a too-narrow helper
match (multi-line arrow helpers, helpers in support files): cloud idle
backstop, VM revoke, Google stop,
socket expiry, Stack permission read, team VM bind/fence/taint.
- Still kept, listed in .cmux-scratch/nx-unitdel/backend-security-kept.txt
(79): shared vectors (feed vectors, link-token vectors, host relay
frames) and security cases that need a route harness this pass did not
build (agent and VM install tokens, cloud-allowlisted Stack subjects,
wire sockets, code storage).
No deleted test generates or rewrites a checked-in file.
* fix(app-host): regenerate scopes after user.presence_key.list (apps never reach it) [cx-hk0r]
9bdd465eff17 (cx-aocz) added user.presence_key.list to the catalog without
a regen, so gen-cmux-global.ts --check failed. The user family is a NEVER
family for apps (as user.presence_key.revoke already is), so the regen only
adds it to scopes.json never; the AppPlatform copy is synced. The
agent.message.* NEVER rules (528532992c81) stay; the generator keeps them.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* acpmux: behavior test, a Chief outside the app installs its built-in presets without env (red, P0)
Regression from cx-1l61 (8a83261d24ef): the always-on brain and `cmux chief
-p` could no longer install their optchat presets ("a spawn env is
accepted only from the cmux app"). Over the real daemon socket, a plain
client names a built-in preset and sends no env; the stored preset has the
fixed env, cache keys from the name, codex paths from the daemon's own
Chief home, and a subagent's sockets and PATH from the daemon's own
environment. Any env a client sends is still refused without the person.
* ci: package-test-lane.sh records each completed package build (.build/.cmux-ci-built-ref)
run-swift-testing-suites.sh already names the commit it built in
.build/.cmux-ci-built-ref. A fleet worker now keeps a warm .build after a failed
or cancelled step only when that marker was written for the step's commit during
the step (hq build-fleet step_warm.go): 2026-10-10 on aws-m4pro-5, warm steps
cancelled mid-build left a .build that failed to link for three steps in a row.
package-test-lane.sh writes the same marker after a successful prebuild and
suite build, so a test failure after a complete build keeps the warm build.
* acpmux: the Chief's presets are built in; a Chief outside the app installs them without env (P0)
Regression from cx-1l61 (8a83261d24ef), reported by hq-6d: a Chief host
started outside the cmux app (the always-on brain's LaunchAgent, `cmux
chief -p`) is not the person, so acpmux refused its preset env ("a spawn
env is accepted only from the cmux app"); every compactor node failed and
an import never finished.
Chief decision (manaflow-ai/cmux#13742), no caller exemption: the presets
are built in (config/chief_builtins.rs). A client names a built-in preset
(optchat-chief-<id>, optchat-chief-codex-<id>, optchat-compact-<id>-slot-<k>,
optchat-sub-<id>[-claude|-codex]; id 8 hex, k 0..63) and sends no env;
acpmux fills it:
- fixed flags, the literal keys and values optchat-chief used;
- cache keys from the name (optchat-<id>-<role>);
- codex CODEX_HOME / HOME from ACPMUX_CHIEF_MUX_HOME in acpmux's own
environment, the same $MUX_HOME/optchat/... paths optchat-chief's Paths
uses (no state move); CODEX_PATH only the Chief's own codex binary or the
one bundled next to acpmux, never a PATH lookup;
- a subagent's cmux sockets (CMUX_TUI_SOCKET, CMUX_MUX_SOCKET,
CMUX_CHIEF_OWNER_SOCKET, CMUX_BUNDLED_CLI_PATH, CMUX_SOCKET_PATH,
CMUX_APP_DAEMON_SOCKET) only from acpmux's own environment, and PATH =
acpmux's bundle directory first, then its login PATH.
Any env a client sends, a built-in name included, stays the person's
(hub/person.rs), so a changed preset still needs the person key.
optchat-chief: installs by name without env when acpmux's initialize
advertises the feature `chiefBuiltinPresets` (an older daemon gets the env
as before), and gives the acpmux it starts ACPMUX_CHIEF_MUX_HOME. The brain's
install.sh gives the acpmux LaunchAgent ACPMUX_CHIEF_MUX_HOME and the cmux
links the host pins.
Named limits: OPTCHAT_CHIEF_ISOLATE=0 (the non-isolated layout) and
OPTCHAT_CODEX_PATH are not built in; with them a Chief outside the app stays
person-only.
Proof: tests/chief_builtin_presets.rs, the real daemon over its socket (red
at 53a9caed0e61).
* acpmux: the owner socket is a route, not a credential (comment, P0 review)
* acpmux: chats carry their live session's attention and latest reply (cx-xub5) (#18787)
* test(acpmux): add settled history seam regression
* feat(acpmux): expose paged settled chat history
* test(acpmux): keep settled filter receipt independent
* fix(acpmux): route settled history through chat namespace
* test(acpmux): chats carry their live session's attention, red
Activity view (meeting 2026-10-08, AV): a chat in the device index should
carry what its live acpmux session needs from the person and its latest
reply, and a chats watcher should hear every change. The index has
neither yet, so this fails.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(acpmux): chats carry their live session's attention and latest reply
Activity view (meeting 2026-10-08, AV). acpmux owns both the chat index
and the sessions, so it joins them: every chat value gains attention
(needsInput, failed, unread or null) and preview (the live session's
latest reply), taken from the newest session continuing that chat
(profile family + agent session id). A session record that can change
either (status, turn end, permission events) reaches every chats watcher
as chat_changed {kind: activity, key, attention, preview}. It reads no
index, so a scan holding the index lock never delays it, and nothing
polls. The app's chats mirror decodes both fields and applies activity
changes in place; older clients ignore the new kind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(acpmux): rustfmt the composer draft tests
#18706 landed them unformatted, so cargo fmt --check fails on base.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* New Tab: template switcher off by default until styled (cx-7qqu) (#18914)
* test(newtab): the template switcher is off by default; on, a dot switches in place (cx-7qqu)
Gallery play steps on agent-pane.new-tab: switcher-off fails while the
dots render on every New Tab page.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* New Tab: the template switcher is off by default until styled (cx-7qqu)
Debug Settings newTab.templateSwitcher (default off) sends
templateSwitcher: true in the page handshake; only then do the template
dots render. The saved tabs.newTabTemplate applies either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next: background art shows in the first frame, decoded off the main actor (cx-t2x.3) (#18398)
* test: art shows without a launch flash
BackdropLaunchTests pins cx-t2x.3: a backdrop decodes no larger than the
screen, its texture renders once into a bitmap (no lazy Core Image rep
for the commit to render), every filter keeps the source size, the next
launch's first frame shows the snapshot an earlier launch kept and swaps
in the full image without a fade, a replaced file is not served from its
snapshot, and picking art starts the decode before any window asks.
BackdropImageStore takes the new API as stubs that keep today's
behavior, so these fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: art shows in the first frame, decoded and textured off the main actor
BackdropImageStore decodes a backdrop no larger than the largest screen,
runs the texture pass off the main actor into a bitmap (it was a TIFF
encode and a lazy Core Image rep rendered in the main actor's commit),
and keeps the result as a JPEG snapshot in the app's caches, named for the
source file's size and date so a replaced file decodes again.
The next launch's first window shows a small copy of that snapshot in its
first frame and swaps in the full image in place, without the fade; only
art never seen before fades in. ThemeScope starts the decode when settings
pick the art, before any window asks. BackdropTextureCache goes: the store
caches per source and texture, and its tests moved to BackdropLaunchTests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: drop this PR's unit tests (no-unit-tests rule)
Lawrence 2026-10-09: cmux-next changes add no unit tests. BackdropTextureTests keeps only the removal of tests for the deleted cache.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CmuxNextDesign: Liquid Glass fallback for macOS 14/15 (cx-s6wi.5)
GlassPanelView draws NSGlassEffectView on macOS 26 and an NSVisualEffectView
with the same corner radius, tint and hairline before it. Glass.makePanel,
makeContainer, the window backdrop (glass frosts at radius 20 like Ghostty.app),
overlay surfaces and the glass button bezels/styles go through one switch,
Glass.isLiquidGlassAvailable; Debug builds force the old material with
CMUX_NEXT_DEBUG_LEGACY_MATERIAL=1. Only CmuxNextDesign calls the native glass API.
* CmuxNext: the local Chief Settings panel sets the engine through chief.engine.set, never writes engine.json (cx-opu0, cx-4w47)
The brain (optchat-chief) is the one writer of optchat/engine.json and
checks each value. The panel read-modify-wrote the file with no lock and
no check: lost updates against 'chief engine set', and values the brain
refuses were saved and then fell back silently at the next turn. The
local panel now sends chief.engine.set on this Mac's Chief owner daemon
(it forwards to the brain's tools socket, as for a paired server's
brain and chief.stop) and shows the brain's typed refusal. Reads stay a
read-only mirror of the files. HomeChiefFiles.setEngine is deleted.
* apps: the apps-v1 client replaces the in-app engine (V-8, cx-qbmc; port of PR 16871)
Swift mirrors the local daemon's app supervisor and sends intents; no app
code, registry, grant table, storage or manifest validator runs in the app.
CmuxNextApps: AppsTransport + AppsClient, a confirmed mirror of apps-list
written only by replies and apps-changed lists, plus an ordered apps-set intent
log (nothing queues while the supervisor is unreachable); scene streams per
mount (apps-mount, apps-scene with reset, apps-dispatch with origin user).
AppManifest keeps only the fields the UI renders. The App Store pages keep
their history and undoable Remove and gain Hide/Show, default-app badges and
the unavailable reason. Deleted: AppEngine, AppHost, AppWatchdog, AppGrants,
AppEventHub, AppRegistry, AppRegistryFile, AppBundleScanner,
AppManifestValidator*, AppPreviewSink, AppStoreCatalog, the bundled JS
runtime, schema, fixtures and sample dists. AppScopeTable and
AppOperationError move to CmuxNextAppPermissions (their only user).
CmuxNextApp: DaemonAppsTransport over the local daemon (availability from the
connection, its epoch and apps-v1; apps-* events from store side events that
also outlive a tree snapshot). apps-run carries the caller's origin; user only
on a verified connection. AppsProviderChannel serves the coderouter and action
families over the provider channel with the existing owner handlers, one
registration per connection with backoff, answers on the arrival connection,
cancels the old connection's calls, and answers apps.disabled while the
organization policy turns apps off; it leaves other families (the Cloud
credential relay) to their own provider. Sidebar items and sections release
their mounts when they leave the layout. The App passes its first-party
packages to the daemon as CMUX_APPS_FIRST_PARTY_DIR (hardening: cx-e0cs).
Deleted AppOperationRouter, AppStorageStore, AppTopologyReads, AppNetFetch.
sync-app-runtime.sh copies scopes, scope classes, whole first-party packages
(catalog/ added) and sample manifests and assets only.
No unit tests (NO UNIT TESTS rule). Tagged-app preflight runs after the
landing (YOLO rule); remains: cx-e0cs/cx-0uo1 (hq-84), cx-kyfd.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): delete the unit tests of 10 networked crates, keep the socket tests (cx-034r)
Unit-test deletion lane, slice 4c (Lawrence 2026-10-10, "Delete all now";
chief ruling: in-src tests that open a real socket or spawn a process and
assert on what crosses it stay in place).
Crates: cmux-remote, chatmux-relay, cmux-server, cmux-server-core,
cmux-tui-platform, cmux-tui-cdp, cmux-pane-protocol, cmux-remote-protocol,
cmux-cloud-cli, cmux-coderouter. Tests before: 1,268; after: 241
(1,027 deleted).
Rule per test: kept when the test or a helper it calls binds or dials a
socket, starts a server, or spawns a process, and it does not reach a
cfg(test)-only production hook. Everything else goes, with:
- the cfg(test)-only production hooks (test barriers, fault injection,
counters, *_for_test entry points, test_support modules) and the
helpers, fields and imports only deleted tests used;
- tests/ files that call library code only (cmux-server access, service;
cmux-server-core health, layout_ports, manifest_catalog, pg_macos_ids;
cmux-remote-browser-host is not in this slice; cmux-coderouter config).
Kept whole as contracts: cmux-pane-protocol tests/conformance.rs (shared
vectors), cmux-server-core units_golden.rs, pg_plan.rs (goldens) and
pairing.rs (RFC 8032 vectors). Kept tests that relied on deleted test
hooks are deleted too (for example cmux-tui-cdp
socket_shutdown_disconnects_a_backpressured_event_receiver).
CI: cmux-tui.yml macOS steps drop the deleted unix_process_scope,
cmux-remote macos_pty_ and server-core layout_ports selectors;
cmux-tui-build-package.yml drops "Test release remote sequence rollback"
(the cmux-remote unit test it ran is deleted; 367 s on that path).
Not in this slice: cmux-rd-host, cmux-remote-browser-host and -testhost
(own workspaces, fleet builds), security crates (slice 4b).
* CmuxNext: the local Chief Settings panel says this Mac's Chief is not running, not 'the server' (cx-opu0 review)
Review of the chief.engine.set move: a local set with no Chief owner
connection, or with the brain host down, showed the paired-server text.
New case localUnreachable with its own string (en + ja translated, other
languages needs_review as the table does).
* cmux-next: queued prompts become compact rows attached to the composer (#18214)
* test(cmux-next): queued prompts are numbered rows on the composer box's top edge (red)
The queue becomes part of the composer box, numbered, and shows a prompt's
full text only when its line is cut off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* cmux-next: queued prompts become compact rows attached to the composer
The gray Queued box gives way to numbered one-line rows on the composer's top
edge, inset so the box's rounded corners lead into them. The list lies over
the transcript's foot instead of taking layout space, so queuing, sending or
removing a prompt never moves the composer or the transcript. A prompt shows
its full text as a tooltip only when its line is cut off. The gallery gets
queued and queued-long variants, with the composer box as a strict anchor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(cmux-next): regenerate the agent pane and page bundles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(cmux-next): regenerate the agent pane and page bundles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(cmux-next): regenerate the agent pane and page bundles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl]
35a61bd340b7 added enum HomeAppLinks (all-static public surface), which
lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by
making it a struct with an empty public init. URL.isChiefSubagentLink is
the same check on the receiver type; behavior is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt (#18896)
* test(ci): the base autofix regenerates without touching frozen paths (red)
base-autofix.sh copies the Mac job's regenerated files into a checkout,
skipping frozen paths, and adds a missing cmux-tui tree input to both
lists. Red: the script does not exist yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt
After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix
repairs the mechanical reds in one commit on top of it: the generated
files the Mac generated-files job rebuilt (its cmux-next-generated-patch
artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in
cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never
written; the app FFI pin stays with the app-ffi-repin pull request.
The push uses a GitHub App token minted only for the push step and a
plain push that never overwrites a moved base. Dry run until the repo
variable CMUX_NEXT_BASE_AUTOFIX is 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ci): the base autofix never writes a workflow file (red)
The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows
changes. A regenerated workflow file is skipped and reported, and a
missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's
paths) is reported without writing either list. Red: both are written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN
No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the
repair; no ruleset or branch protection applies to feat-cmux-next.
GITHUB_TOKEN cannot push workflow files, so every .github/workflows path
is frozen for the bot, and missing cmux-tui tree inputs (whose second
list is cmux-tui-artifacts.yml's paths) are reported, not written. Its
pushes start no workflow: the next push's cmux-next run verifies the
repair commit. The trigger also checks the run's workflow path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913)
36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and
cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste::
image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only
looked for crate::image_paste under cmux-tui-core, found 9 constants
named CAPABILITY and failed, so release rails is red on every PR and on
nightly-next. A crate:: path whose first segment lib.rs re-exports from
a workspace crate now also names that crate's module file.
No bead (repairs the cx-4l51 guard).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: format staged files before commit (#18808)
* ci: format staged files in the trusted pre-commit hook
* ci: guard formatter scope for staged files
* ci: scope Rust formatter guard to its package
* ci: use direct rustfmt and skip merge formatting
* ci: pass the cmux-tui Rust edition to rustfmt
* ci: check rustfmt on the cmux-tui packages a PR touches (#18800)
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: check rustfmt on the cmux-tui packages a PR touches
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit
The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): leave the relay circuit to its own repair
Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next (#18781)
* ci: add mini-first Swift canary for cmux-next
* ci: remove unit tests from Swift canary change
* cmux-next: repin app FFI to current base release (#18776)
* cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698)
* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree
#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui
Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-next): the newest-published search deepens only this commit's history
A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ci): keep cmux-next minis first through bot retries (#18615)
* docs(cmux-next): map UI parity reference sources (#18561)
* docs(cmux-next): map UI parity reference sources
* docs(cmux-next): add media preview reference source
* docs(cmux-next): define reference freshness checks
* fix(nightly): bound the publish notes step at 10 minutes (#18404)
* test(nightly): the notes step cannot spend the publish budget before the upload (red)
Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(nightly): bound the publish notes step at 10 minutes
The notes take seconds since 0115b2684cf. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622)
* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself
Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): the tree gate watches the base and may pin the tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree
When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a transient wrong binary read must not fail publication
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read a mismatched published binary again before failing
R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): a pull request gate pins a tree its base never builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): a pull request gate pins a tree its base never builds
A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retain base tree dispatch tests
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states (#18901)
* ci(gallery): capture narrow responsive states
* test(gallery): cover workflow matrix changes
* fix(gallery): dedupe equal responsive widths
* ci: shard gallery matrix renders
* ci: retrigger sharded gallery validation
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
* ci: size Swift suite and webviews parallelism to the fleet CPU grant (CMUX_CI_CPU_BUDGET)
The hq build fleet now admits ci-steps by CPU budget and passes each step the
cores it was granted as CMUX_CI_CPU_BUDGET (hq build-fleet internal/cpubudget).
run-swift-testing-suites.sh caps CMUX_SWIFT_TEST_SUITE_JOBS at the grant, and
run-webviews-tests.sh uses the grant as its default file concurrency, so a step
never runs more processes than the cores it holds (2026-10-10: 4 suite steps of
8 suites on a 14-core host ran at load 88).
* cmux-next: keyboard-first Add project panel (#18395)
* feat(cmux-next): add project badges and checked state
* refactor(cmux-next): share project badges across pickers
* test(cmux-next): cover project chooser in gallery
* fix(cmux-next): type project chooser gallery props
* chore(cmux-next): regenerate the agent pane bundle
* chore(cmux-next): regenerate the agent pane bundle after base merge
* chore(cmux-next): regenerate the agent pane after latest base merge
* gallery: fix project chooser entry imports
* style: format project badge
* cmux-next project chooser: add keyboard-first project panel
Co-authored-by: Leo Li <cheerleaderleo@outlook.com>
* gallery: wait for add project panel states
* gallery: stabilize add project step plays
* gallery: keep add project panel geometry stable
* composer: show setup-required project sources
* feat(cmux-next): add keyboard-first project panel
Add a Base UI command panel for environment, source and folder selection with fixed geometry, keyboard hints, setup-required sources and gallery variants. Existing native project.browse remains the production fallback until a reviewed directory-list host operation exists.
* chore(cmux-next): regenerate the agent pane bundle
Generated remotely from the exact Add Project panel head.
* chore(cmux-next): keep generated bundles at base
* ci: retrigger full PR workflows
* fix(cmux-next): refresh agent pane string catalog
* fix(cmux-next): use semantic project status output
* fix(cmux-next): harden add project panel
* fix(cmux-next): sync pane strings after base merge
* fix(cmux-next): route project shortcuts through ui scope
* fix(cmux-next): skip disabled project choices
* fix(cmux-next): preserve disabled option semantics
* test(next): cover add project menu behavior
Co-authored-by: Leo Li <cheerleaderleo@outlook.com>
* cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay
* cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe
* cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders)
* cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS)
* cx-m0p7 adapters: the socket test picks a non-temporary folder
* cx-m0p7 adapters: daemon-capabilities.json lists project-list-v1
* test(bindings): delete the SDK unit tests (cx-034r)
Unit-test deletion lane, slice 8 (Lawrence 2026-10-10, "Delete all now").
SDK tests in cmux-tui/bindings before: about 1,243; after: about 507.
Deleted (call SDK code directly, in-memory fake or scripted transports,
net.Pipe, count/shape checks): TypeScript authority, base64, device-kind,
field-compatibility, wire-json, client, resource-api, websocket-transport,
presence; Python consumer, device_kind, events, aio_cleanup, convenience,
schema_roundtrip; Rust bookmarks_typed, cloud_name_authority, device_kind,
error_codes, state_handles, public_api and the in-src tests of cmux-sdk
(except the socket ones below), cmux-daemon-client, cmux-sidebar, the two
bootstrap crates and examples/rust-agent-screen-detection; Go
client_zero_progress, resource_api, resource_api_external, socket,
raw/device_kind; go-pane envelope, frame, token, provider, conn,
richpane; Java Codec, GeneratedModel, SocketDiscovery, ResourceApi,
BrowserPointerFrame; C++ attachment, base64, json, client, resource; Zig
raw/authority_test and the inline tests of resource.zig, raw/client.zig,
raw/wire.zig, raw/transport.zig and raw/capabilities.zig that open no
socket. Runner lists follow (java scripts/test.sh, cpp CMakeLists.txt,
zig raw.zig).
Kept (wire boundary or generated check):
- live daemon tests (*_live.rs), rust mock_server, byte_attachment,
home_conversation, typed_state_ops, dock_field_capability,
local_socket_windows, rust-daemon-client tests/, rust-sidebar runtime
(real Unix sockets), cmux-sdk in-src socket tests in client.rs,
codec.rs, resource/client.rs, socket_hash.rs (UnixListener);
- Python resource_api, lifecycle (UnixJsonServer), protocol (generated vs
schema), package_consumer; TypeScript unix-transport, generated,
package-consumer, resource-package-consumer, code-mode cloud-relay;
Go raw client, ergonomics_external, consumer, url_open (net.Listen);
go-pane listener, websocket, examples/hello main + vectors; Java
GeneratedCoverage, StreamMode, Lifecycle, Ergonomics, UnixTransport,
consumer; C++ generated, macro_collision, unix_transport; Zig provider,
stream_client, wire_presence, generated presence and the socket tests
in transport/client/resource;
- example apps' socket fakes; conformance runner; codegen --check.
Also drops the last hand-written count pins: C++ attach-surface
field_requirements size and the TypeScript emitted-event count.
Release tooling tests (bindings/tests, codegen/tests) are CI tooling and
stay. No Cargo.toml change: dev-dependencies left as they are.
* fix(messageslab): a Chief subagent link check is a URL property, not a static-only type [cx-94dl]
35a61bd340b7 added enum HomeAppLinks (all-static public surface), which
lint-ios-package-conventions.sh refuses; cdd28b4be39b got past the lint by
making it a struct with an empty public init. URL.isChiefSubagentLink is
the same check on the receiver type; behavior is unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt (#18896)
* test(ci): the base autofix regenerates without touching frozen paths (red)
base-autofix.sh copies the Mac job's regenerated files into a checkout,
skipping frozen paths, and adds a missing cmux-tui tree input to both
lists. Red: the script does not exist yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: a base autofix bot commits generated files, tree inputs and fmt
After each cmux-next run on a feat-cmux-next push, cmux-next-base-autofix
repairs the mechanical reds in one commit on top of it: the generated
files the Mac generated-files job rebuilt (its cmux-next-generated-patch
artifact, so no fleet Mac), missing cmux-tui tree inputs and cargo fmt in
cmux-tui. Frozen paths (base-autofix-frozen.txt) are reported and never
written; the app FFI pin stays with the app-ffi-repin pull request.
The push uses a GitHub App token minted only for the push step and a
plain push that never overwrites a moved base. Dry run until the repo
variable CMUX_NEXT_BASE_AUTOFIX is 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ci): the base autofix never writes a workflow file (red)
The bot pushes with GITHUB_TOKEN, which cannot push .github/workflows
changes. A regenerated workflow file is skipped and reported, and a
missing cmux-tui tree input (its second list is cmux-tui-artifacts.yml's
paths) is reported without writing either list. Red: both are written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: the base autofix pushes as github-actions[bot] with GITHUB_TOKEN
No GitHub App: the job's GITHUB_TOKEN (contents: write) pushes the
repair; no ruleset or branch protection applies to feat-cmux-next.
GITHUB_TOKEN cannot push workflow files, so every .github/workflows path
is frozen for the bot, and missing cmux-tui tree inputs (whose second
list is cmux-tui-artifacts.yml's paths) are reported, not written. Its
pushes start no workflow: the next push's cmux-next run verifies the
repair commit. The trigger also checks the run's workflow path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(release-rails): resolve capabilities re-exported from another cmux-tui crate (#18913)
36c60c86bbba moved the image paste spool into cmux-tui-image-paste, and
cmux-tui-core's lib.rs re-exports it (use cmux_tui_image_paste::
image_paste;). The image staleness guard (8e23f8a61780, cx-4l51) only
looked for crate::image_paste under cmux-tui-core, found 9 constants
named CAPABILITY and failed, so release rails is red on every PR and on
nightly-next. A crate:: path whose first segment lib.rs re-exports from
a workspace crate now also names that crate's module file.
No bead (repairs the cx-4l51 guard).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: format staged files before commit (#18808)
* ci: format staged files in the trusted pre-commit hook
* ci: guard formatter scope for staged files
* ci: scope Rust formatter guard to its package
* ci: use direct rustfmt and skip merge formatting
* ci: pass the cmux-tui Rust edition to rustfmt
* ci: check rustfmt on the cmux-tui packages a PR touches (#18800)
* test(ci): red test, PRs check rustfmt on the cmux-tui packages they touch
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. These tests pin a
helper that runs cargo fmt --check once per touched package, checks
every package when a rustfmt config changes or there is no base, and
names each unformatted package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: check rustfmt on the cmux-tui packages a PR touches
PR CI never runs cmux-tui.yml (dispatch only), so #18706 landed
unformatted Rust and broke base cargo fmt --check. cmux-tui-spec.yml
already runs on every PR and push touching cmux-tui/** on hosted Linux;
its new rustfmt job runs cmux-tui-fmt-changed.py, which maps each changed
.rs file or Cargo.toml to its nearest tracked package and runs cargo fmt
--check on it with the pinned toolchain. No build and no dependency
download. A rustfmt config or toolchain change, or no base, checks every
package; vendored crates and deleted packages are skipped. A PR compares
with its merge commit's first parent, a push with the commit before it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): rustfmt acpmux's draft tests and the relay circuit
The new rustfmt job's full run found two base packages that fail
cargo fmt --check: acpmux, from #18706's draft tests and their module
order, and the Cloudflare relay's circuit.rs. Formatting only, exactly
the hosted rustfmt diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* style(cmux-tui): leave the relay circuit to its own repair
Touching the Cloudflare relay runs its lane, whose npm audit is red on
base (sharp and undici advisories through wrangler, fixed only by a
wrangler bump outside the stated range). That is the relay's own repair,
so this PR keeps acpmux's formatting only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: add mini-first Swift canary for cmux-next (#18781)
* ci: add mini-first Swift canary for cmux-next
* ci: remove unit tests from Swift canary change
* cmux-next: repin app FFI to current base release (#18776)
* cmux-next: same-tree cmux-tui is a hard check only for PRs that change cmux-tui (#18698)
* test(cmux-next): red: a PR that changes no cmux-tui fails same-tree on an unpublished merge tree
#16614, #17551 and #18605 change no cmux-tui or ghostty-next path, yet
same-tree cmux-tui failed them because the base tip's tree was never published
(its artifacts run was cancelled). Such a PR should reuse the newest published
tree in its history (tree_fetch_key, fetched through CMUX_TUI_TREE_KEY), or skip
the tree jobs when none is published, never fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): same-tree cmux-tui is a hard check only for PRs that change cmux-tui
Path routing records whether the pull request's own diff touches cmux-tui/ or
ghostty-next. For one that does not, a merge tree that is not ready no longer
fails: the probe (CMUX_TUI_TREE_BASE_FALLBACK=1) resolves the newest published
tree in the merge's history and reports ready with tree_fetch_key, which the
daemon tests and the Debug scheme compile fetch through CMUX_TUI_TREE_KEY; with
none published it reports skipped. Pushes, dispatches and PRs that change
cmux-tui keep the hard check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-next): the newest-published search deepens only this commit's history
A bare `git fetch --deepen=50 origin` deepens every branch of origin: on this
PR's first run it took path routing past its 5-minute limit (job 113609407061)
before the probe's base fallback, which then resolved in under a second.
Deepening only HEAD takes about 30 s on a depth-2 clone of feat-cmux-next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ci): keep cmux-next minis first through bot retries (#18615)
* docs(cmux-next): map UI parity reference sources (#18561)
* docs(cmux-next): map UI parity reference sources
* docs(cmux-next): add media preview reference source
* docs(cmux-next): define reference freshness checks
* fix(nightly): bound the publish notes step at 10 minutes (#18404)
* test(nightly): the notes step cannot spend the publish budget before the upload (red)
Run 37611677848 spent 29 of publish-nightly's 30 minutes on release notes and
was cancelled mid-upload, leaving partial release assets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(nightly): bound the publish notes step at 10 minutes
The notes take seconds since 0115b2684cf. A regression now fails the step
before any asset upload, instead of spending publish-nightly's 30 minutes and
being cancelled mid-upload with partial assets left on the release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retry bad R2 binary reads and let the tree gate pin itself (#17622)
* test(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree itself
Publisher run 37505519359 failed transiently and its retry was replaced by a
newer feat-cmux-next push, so the tree was never published and lanes pushed
cmux-tui-pin-* branches by hand to unblock their gates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): the tree gate watches the base and may pin the tree
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): the cmux-tui gate pins and dispatches an unpublished tree
When two run checks find no artifacts run that will publish the tree, the
gate creates cmux-tui-pin-<key12> at the publisher commit and dispatches the
artifacts workflow there, once, then keeps waiting. A pull request now
watches its base commit (the merge's first parent) instead of no publisher,
so it neither waits 45 minutes for a tree nobody builds nor needs a lane to
push a pin branch by hand. A superseded push still skips; forks keep a
read-only token and no autopin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-tui): a transient wrong binary read must not fail publication
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(cmux-tui): read a mismatched published binary again before failing
R2 objects are write-once, so a digest mismatch on a binary the run just
uploaded is a bad read. Fetch it again from a cache-busting URL up to
three times, and name the response headers when it still differs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(cmux-next): a pull request gate pins a tree its base never builds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): a pull request gate pins a tree its base never builds
A pull request that changes cmux-tui has a merge tree no push builds,
and the artifacts workflow's pull_request_target trigger has never
started a run, so its gate waited 45 minutes with the run check off.
With CMUX_TUI_TREE_AUTOPIN the gate now pins its own checkout at once
and watches that run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci(cmux-next): retain base tree dispatch tests
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(gallery): capture narrow responsive states (#18901)
* ci(gallery): capture narrow responsive states
* test(gallery): cover workflow matrix changes
* fix(gallery): dedupe equal responsive widths
* ci: shard gallery matrix renders
* ci: retrigger sharded gallery validation
---------
Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(gallery): cover composer scope row states (#18590)
* refine agent composer context surface
* show composer controls in the toolbar
* update composer layout assertion
* cover visible access mode label
* format unified composer markup
* test: cover model picker Escape away from search
* fix: close model picker on Escape from any control
* fix: keep unified composer radius tokenized
* test(gallery): cover composer scope row states
* test(gallery): use public composer fixture labels
* plans(projects): daemon-owned project store with source adapters, event-driven resync, merge rules (cx-m0p7 design)
* test(cmux-tui-core): project list reducer merge rules and user edits (red, cx-m0p7)
* feat(cmux-tui-core): project list reducer: sources, user overlay, missing state, refusals (cx-m0p7 slice 1)
* style(cmux-tui-core): rustfmt the project reducer
* style(cmux-tui-core): rustfmt state.rs module list
* feat(cmux-tui-core): project-list-v1 store, ops and spec: project.list/observe/add/update/remove/sync (cx-m0p7 slice 1)
* fix(cmux-tui-core): collapse the project rename check (clippy)
* fix(cmux-tui-core): project store clippy (semicolons; source toggle helpers wait for slice 3)
* fix(cmux-tui-core): semicolon on the project row parse warning
* refactor(cmux-tui-core): request ids move to resource/request_id.rs (move-only) so resource.rs stays under the god-file limit
* test(cmux-tui-core): project list review cases: idempotent observe, null clears, case-insensitive refusals, disk facts from the caller, cap (red, cx-m0p7)
* fix(cmux-tui-core): project store reads no disk for observed paths, null clears, idempotent observe, case-insensitive refusals, cap, disk facts from the app (review, cx-m0p7)
* chore(godfiles): resource.rs meets its budget (row dropped)
* CmuxNext: failing tests, a split shows a provisional pane before the reply (S3 T1, store)
* CmuxNext: a split intent shows a provisional pane beside its target until the daemon's pane with the same public id replaces it (S3 T1, store)
* cmux-layout-reducer: failing test, SplitNew puts a new pane with a new tab beside the target (S3 T3)
* cmux-layout-reducer: SplitNew, a new pane with a new tab beside the target (S3 T3); covered by the random op sequence property test
* S3: the optimistic split matches the Rust reducer's SplitNew vectors (L4 parity: Rust generator with drift check, Swift reader)
* S3 tests: optimistic Cmd+D on a client-keys daemon (T1 app, T2 store frame budget), provisional pane mapping continuity, target gate and typeahead order (T7)
* CmuxNext: Cmd+D shows the new pane before the reply on a split-client-keys-v1 daemon; its terminal view waits for the daemon's terminal and keeps keys typed meanwhile (S3)
* S3: provisional terminal view helpers in their own file; test daemon record as a Sendable box
* S3: TabContentCache within its size limit; the test daemon serves terminal-placement-env-v1
* cx-m0p7 adapters: red tests for the VS Code family and Zed sources and the chat index relay
* cx-m0p7 adapters: VS Code family and Zed project sources on project.sync; app relays the chat index as project.observe
* cx-m0p7 adapters: review fixes (no partial complete lists from a busy vscdb, a failed Zed row or a scanning chat index; rank-only times; three.js folders)
* S3: drop the unit tests and the reducer op (NO UNIT TESTS rule); verification moves to the tagged app via the debug socket
* cx-m0p7 store: socket-level behavior test on a real daemon replaces the in-process unit tests (NO UNIT TESTS)
* cx-m0p7 adapters: socket-level daemon test for the editor import replaces the unit tests (NO UNIT TESTS)
* cx-m0p7 store: the socket test picks a non-temporary folder
* cx-m0p7 adapters: the socket test picks a non-temporary folder
* S3: tagged-app proof harness (Cmd+D through debug.key, read-screen) and its results
* S3: the provisional split maps columns and rows instead of indexing them (crash ratchet)
* cx-m0p7 store: keep LocalOperation in resource.rs (boundary check reads it); move encode_hex out for the god-file limit
* S3: SpawnOptions drops unserved fields itself (DaemonConnection stays within its size limit)
* fix(cmux-next): WebKit right and middle buttons: right presses go in as AppKit right-button events, a middle press carries button number 2 on its own Quartz form (DOM button 1), wheel events take the Quartz location AppKit gives the window point, and the web view empties the context menu of a right-click the app did not dispatch, so an agent's right-click opens no native menu (cx-ollo)
* cmux-next: harden the credential relay and the Cloud create approval (cx-t2rz security review)
P2-1: the relay serves only the app cmux/cloud and only cloud.* ops
(credential.app_refused / credential.op_refused otherwise): an install
token with origin user counts as the person on the Worker, so no other app
or op family may borrow it.
P2-2: before feed.answer the app reads integration.approval.get as the
person and requires op cloud.machine.create, state pending and exactly the
params the person confirmed; the feed item must carry the same request
and digest, tool cloud.machine.create, and poster system:cloud:<team>.
Any mismatch answers nothing and shows why. The confirmation shows the
machine size and name.
P3-1: the relay registers only on the app server link path (never with
the legacy default or in release).
P3-2: a create from the progress view's Retry (no gesture origin) asks
the person first; only an action with origin user skips the sheet.
P3-3: the session call for the approval refuses redirects and keeps no
cookies or cache.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): short update titles; the test feed and announcements are notice cards
Chief 2026-10-09 (round 2 of Lawrence's update card ask).
- Update titles are short and the version moves to the detail line:
"Update Available" / "Version 1.0.0-nightly.…", "Update Check Failed",
"Needs macOS 27.0 for …". Before, "cmux 1.0.0-nightly.376…" and
"Couldn't Check for Up…" truncated in a 260 pt sidebar. UpdateNote's
needsNewerMacOS carries the found version. 4 new strings (en + ja,
19 languages needs_review).
- The test-feed notice (Use Real Feed, no x) and the announcements (their
allow-listed Try It, an x that dismisses for good, the next one shows)
are the shared notice card. Order: update status, test feed,
announcement, tip; the "cmux Updated!" card waits while an update
status or a test feed shows.
- The plain R114 card stack is gone (SidebarCard, SidebarCardView,
SidebarCardStackView, SidebarCardStackLayout, SidebarModel.cards and
onCardAction); its hover test goes with it. The footerCards slot stays.
Announcements now show whether or not the sidebar chrome is revealed.
- NO UNIT TESTS (Lawrence 2026-10-10): the unit tests this change breaks are
deleted in this diff (UpdateNoticeTests and its ManualClock copy, from
31d888016eed / d344241b7a88; the stack hover test; two stack-card
asserts). Proof is the tagged app on cmux-lawrence-2 through the debug
socket with screenshots.
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(cmux-next): a check while an update waits shows the waiting update
Lawrence's NIGHTLY (2026-10-09/10): 3797671859401 was downloaded and
waited for a restart; Sparkle skips every check while an update waits
("update check ignored while install is progressing"), so his manual
Check for Updates showed nothing and never saw 3800566557701.
- Check for Updates while an update is staged does not ask Sparkle (it
would ignore the check); it logs and answers with the staged update.
- The staged update card ("cmux X is ready", Restart to Update) shows
after such a check even under updates.notify silent, which otherwise
hides it. Before, a silent install had no answer to a check at all.
Proof: tagged app on cmux-lawrence-2 through the debug socket (staged
update + notify silent: no card; Check for Updates: the card), with
screenshots. No unit tests (Lawrence 2026-10-10).
Bead: cx-t34p
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci(nightly-next): keep the acpmux and OptChat Chief dependency builds between nightlies (cx-g34i)
build-nightly-app compiled every Rust dependency of acpmux (53 s + 46 s, two
arches) and the OptChat Chief (24 s + 24 s) from scratch on each nightly-next
run, on the serial path before the Release build. Swatinem rust-cache on their
target dirs (cmux-tui/target/acpmux-app, optchat-chief/target/app), nightly-next
track only; cargo rebuilds what changed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(cmux-tui): drop the hand-written operation and command counts (cx-034r)
Unit-test deletion lane, slice 3 (chief order): every lane that added an
op had to edit 4+ files with a hand-written count (palette hit 211, 212,
213). The generated-from-spec checks (spec inventory, SDK sync, the set
equality of generated commands and the IR) already prove coverage.
Removed, no other assertion changed:
- cmux-tui-core resource_router tests: operations.len() == 213 (2x);
- cmux-tui transport path coverage: cases.len() == 188, catalog 213;
- check-resource-api-boundary test: operations 213;
- conformance runner: TRANSPORTED_OPERATION_COUNT (now: a non-empty
catalog), and its test;
- SDK raw coverage tests: command count 236 and event count 69 in C++,
Go, Java, Python, TypeScript, Zig (src and the watch example);
- spec/resource-operations-v2.md names the JSON catalog, not a number.
Pure assertion deletion: no red test first. 0 tests deleted, 0 added
(test count before == after).
* cmux-next: S3 optimistic Cmd+D off by default (cx-wb5.72)
Keys typed right after Cmd+D lost the tail of the line in 1 of 8 proof
runs. Every daemon now serves split-client-keys-v1, so the capability gate
protects no one. PaneSplitCommand.optimisticSplitEnabled = false sends every
split through the old path; the landing with the ordering fix sets it back.
split-optimistic-proof.py records the path each Cmd+D took and takes an
expected path (optimistic|old) as a gate argument.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test(scheduler): failing tests for automations, runs and bodies in rows (g1)
Head under 100 KB with 100 automations of 20,000-character instructions
and 450 kept runs; bodies stored once with reference counts; keyset
paging for automation.list and run.list stable under inserts; run.get
joins the body; migration of an old JSON head is idempotent on a live
DO and after a rollback refill; disable, delete and a policy deny
cancel every queued run. Deterministic: reads answer without an ok
field, the cancelled-run check uses a sleeping first run, the migration
check binds the object before it reads the head.
Re-applied from orphaned fe31fa1f0ed8 + 467e890d7cb1 (cx-3bi.38).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(scheduler): automations, runs and bodies in rows, keyset paging, live migration (g1)
SchedulerDO moves to row mode (plans/cmux-next/backend.md (g), DO audit
F-1). automation/<id> and run/<id> rows hold the records without their
bodies; body/<sha256> rows hold each distinct body once with a reference
count (automations plus kept runs) adjusted in the same commit; a
finished/<run> index lets prune drop the oldest finished runs past 200
without reading the open ones. A started run keeps its body hash. The
head keeps owner, settings, counters, chains and the counts
automation_count, open_runs, finished_count, row_seq. All four tables
are private, so events and snapshots carry the head only.
One lookup module (domains/scheduler-rows.ts) and one per-op store
(domains/scheduler-store.ts) replace every read of state.automations and
state.runs. New reads run.list and run.get; automation.list pages with
cursor and limit and its first page is unchanged. System op
sched…


Routing-only follow-up to #18182. Keep cmux-next macOS jobs on the owned minis through bot attempts 1 to 3, then use the Blacksmith fallback only after a fourth bot retry or an explicit non-owned route. The test covers every affected job and keeps human retries minis-first.
Changelog
Fixed retry routing so owned minis remain the first route.
Validation:
python3 -m unittest tests/test_ci_side_lane_placement.py(16 passed).Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Keeps cmux-next macOS jobs on the owned minis through bot run attempt 3 before falling back to Blacksmith on attempt 4.
Written for commit 109a9ac. Summary will update on new commits.
Note
Medium Risk
Changes when cmux-next macOS jobs leave the owned fleet for Blacksmith during automated rescue retries; mis-routing could queue jobs longer or spill to paid runners earlier than intended.
Overview
Extends cmux-next macOS job routing so owned-pool placement (
macos-placementoutput) is honored through bot attempts 1–3, not only through attempt 2.runs-onandCMUX_NEXT_RUNNERfor swift-test, daemon-test, generated-files, release-compile, and cmux-scheme-compile now gate on(github.run_attempt <= 3 || triggering_actor != github-actions[bot])before falling through to the Blacksmith overflow path—so a rescue re-run at attempt 4 (after a refusal on attempt 3, with placement output reused) is what moves jobs off the minis.Workflow header comments document that retry sequence.
test_ci_side_lane_placement.pyadds coverage that bot attempt 3 stays on the placement label, bot attempt 4+ uses fallback, and human retries remain minis-first.Reviewed by Cursor Bugbot for commit 109a9ac. Bugbot is set up for automated code reviews on this repo. Configure here.