Skip to content

cmux-next: keyboard-first Add project panel - #18395

Merged
teamleaderleo merged 66 commits into
feat-cmux-nextfrom
feat/t3-add-project-panel
Oct 10, 2026
Merged

teamleaderleo merged 66 commits into
feat-cmux-nextfrom
feat/t3-add-project-panel

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Changelog

Added a keyboard-first Add project panel for choosing an environment, project source and local folder.

What changed

  • Replaced the stacked Add project flow with one Base UI Combobox surface.
  • Added environment and source steps, visible setup-required sources, in-pane directory navigation, Add with Cmd-Enter, Open in Finder and footer key hints.
  • Kept panel geometry fixed while async folder rows load and added strict gallery checks for anchors, layout shift and long frames.
  • Production uses the existing reviewed project.browse native folder chooser until a reviewed directory-list host operation is available; the gallery injects a deterministic directory tree for the in-pane flow.

Proof

Before / after

Before: the base Project chooser opened as a compact project-only menu. After: the head provides the keyboard-first Add project panel with environment choices, setup-required rows, and footer key hints at the same gallery viewport.

Before: base Project chooser

After: Add project panel

Gallery variants on the exact head:

The per-PR gallery workflow supplies matching base and head renders for the touched gallery entry.

Validation

  • bun run typecheck passes on the exact source head.
  • bun scripts/check-browser-test-lanes.ts passes.
  • node webviews/scripts/pages/gen-strings.mjs agentPane --check passes.
  • bun test test/gallery-coverage.test.ts passes.
  • bun run check reaches only four pre-existing formatting failures in the base branch's settings chat-roots files; the changed Add project files are formatted and type checked.

Showcase


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


Note

Medium Risk
New daemon project-list sync on app launch and broad cmux-next routing/tree-fallback behavior affect merge gating and same-tree cmux-tui jobs; CI-only changes are lower risk but easy to mis-route PRs.

Overview
This diff is mostly CI and integration plumbing around feat-cmux-next, plus daemon project-list wiring and a small MessagesLab API cleanup—not the Add project web UI described in the PR text.

CI / workflows: Adds cmux-tui-fmt-changed.py (and unit tests) so cmux-tui-spec runs cargo fmt --check only on packages touched by the diff (or all packages when rustfmt/toolchain changes). Introduces cmux-next-base-autofix to commit mechanical repairs on feat-cmux-next after cmux-next (generated files + base-autofix.sh), gated by CMUX_NEXT_BASE_AUTOFIX. cmux-next.yml gains a Swift canary job for package-only CmuxNext edits (routing outputs swift_canary / targets), makes Release compile advisory when the canary is the PR gate, extends macOS placement to include the canary, and lets PRs that don’t change cmux-tui use a published tree fallback (own_tui, CMUX_TUI_TREE_BASE_FALLBACK, tree_fetch_key on scheme/daemon jobs). gallery-pr.yml shards render jobs (4 shards), adds narrow + normal widths, and merges shard results before compare. Nightly caps the release-notes step at 10 minutes.

CmuxNext app: New ProjectsImport relays ChatsFeed into the daemon via ProjectStateClient (project.sync / project.observe) when project-list-v1 is available; AppDelegate starts it alongside the chats feed.

MessagesLab: Replaces HomeAppLinks.isSubagentLink with URL.isChiefSubagentLink and updates markdown policy and tests.

cmux-tui / tooling: Drops several C++ unit test sources from the CMake test target and removes large #[cfg(test)] blocks from the rust-agent-screen-detection example (parity tests file deleted). CONTRIBUTING documents pre-commit vp fmt / rustfmt on staged paths.

Reviewed by Cursor Bugbot for commit b601429. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds a keyboard-first Add project panel to feat-cmux-next, replacing the stacked browse flow in the composer folder menu and project chooser with one Base UI command surface that steps through environment, source, and an in-pane directory browser. Production keeps the reviewed project.browse native folder chooser until a reviewed directory-list host operation exists; the gallery injects a deterministic directory tree.

Panel behavior

  • Fixed panel geometry while folder rows load, with strict gallery checks for anchors, layout shift, and long frames; Arrow keys and Enter navigate, Alt-Left goes back, Cmd-Enter adds the folder, and shortcuts route through a shared ui/KeyboardScope.
  • Setup-required sources stay visible with quiet tags; the directory step shows the path, filter, a semantic loading/retry/empty status output, and Open in Finder via link.openPath.
  • Combobox gains cancelOnBlur, isItemDisabled, autoHighlight, onCommand, and rootClassName so disabled rows render but can't be selected or submitted, the panel stays open while focus moves to its buttons, and shortcut handling stays in ui/.
  • generated/strings.json and Localizable.xcstrings carry the new project.* copy across locales, re-synced after the latest base merge.

Merged base work

  • The daemon's project.list is fed by real sources: VS Code family and Zed report on project.sync, and the app relays the chat index as project.observe (project-list-v1, ProjectsImport, ProjectStateClient).
  • The cx-034r lane deleted the SDK unit tests across the bindings, keeping only wire-boundary and generated checks.
  • Base CI carries per-package rustfmt on changed cmux-tui packages, staged-file formatting in the pre-commit hook, a base autofix bot, narrow gallery widths, the mini-first Swift canary, tree-gate self-pinning, and a 10-minute bound on nightly notes.

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

View guided diff Turn on auto-fix

Showcase

showcase
showcase

Open the live gallery

Co-authored-by: Leo Li <cheerleaderleo@outlook.com>
…-project-panel

# Conflicts:
#	webviews/src/agent-session/acpmux/ProjectChooser.gallery.tsx
#	webviews/src/agent-session/acpmux/ProjectChooser.tsx
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.
Generated remotely from the exact Add Project panel head.
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Important

Review skipped

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

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

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 9636a307-4f1a-417b-95dc-e3bcdb4230f3

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Unclear: web / react-apps-check failed: no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check).

CI failed on b6014295c7 (run 38018017904 attempt 1): 1 unknown.
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped.

Job Verdict Why
web / react-apps-check unknown no known signature; failed step: Check webviews (Oxlint, Oxfmt, type check)

Not re-run automatically: web / react-apps-check is not a machine failure.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

@blacksmith-sh

This comment has been minimized.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread webviews/src/agent-session/acpmux/generated/strings.json
Comment thread webviews/src/agent-session/acpmux/AddProjectPanel.tsx Outdated
Comment thread webviews/src/agent-session/acpmux/AddProjectPanel.tsx
Comment thread webviews/src/agent-session/acpmux/AddProjectPanel.tsx Outdated
Comment thread webviews/src/agent-session/acpmux/addProject.css Outdated
lawrencecchen and others added 23 commits October 9, 2026 18:01
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.
…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>
…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>
…x-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 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
* 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

* ci: remove unit tests from Swift canary change
…e 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>
* docs(cmux-next): map UI parity reference sources

* docs(cmux-next): add media preview reference source

* docs(cmux-next): define reference freshness checks
* 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>
…self (#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

* test(gallery): cover workflow matrix changes

* fix(gallery): dedupe equal responsive widths

* ci: shard gallery matrix renders

* ci: retrigger sharded gallery validation
Resolutions: FolderMenu keeps base's control anchor and the PR's Add
project dialog state; ProjectChooser keeps base's `side` prop and the PR's
`projectHost`. Localizable.xcstrings is base's plus the PR's 21 new
project.* keys, and generated/strings.json is regenerated with
gen-strings.mjs agentPane. projectChooser.test.tsx stays deleted as on
base (no unit tests in cmux-next), dropping this PR's added cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

CI fast guards failed on b6014295c7 (https://github.com/manaflow-ai/cmux/actions/runs/38018017904). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally. This comment is updated in place on each push.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b601429. Configure here.

contents: read
timeout-minutes: 20
env:
CMUX_NEXT_RUNNER: ${{ 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') }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canary skips Blacksmith overflow path

Medium Severity

swift-canary still binds runs-on and CMUX_NEXT_RUNNER to macos-placement's label on every attempt. Sibling Mac jobs drop that label on bot attempt 4 and take Blacksmith. After a mini refusal, this merge-gate job stays on the refused runner.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b601429. Configure here.

@teamleaderleo
teamleaderleo merged commit 224eda3 into feat-cmux-next Oct 10, 2026
83 of 88 checks passed
@teamleaderleo
teamleaderleo deleted the feat/t3-add-project-panel branch October 10, 2026 02:55
@github-actions

Copy link
Copy Markdown
Contributor

Gallery

Review in feed

No state changed · 3797 removed states · 15 broken states · 16 play checks failed

Diff page and renders (the run's gallery-pr artifact)

Play checks failed (0 px anchor movement, 0 layout shift, no frame over 33 ms unless the entry gives a reason):

  • agent-pane.chat-gallery/renders (Apple System Colors Light, chromium): step 3 click button "Renders 2": layout shift 0.1338 (limit 0.1)
  • agent-pane.chat-gallery/renders (Apple System Colors, chromium): step 3 click button "Renders 2": layout shift 0.1338 (limit 0.1)
  • agent-pane.composer/image-attached (Apple System Colors Light, chromium): step 1 hover .acpmux-attachment-image: layout shift 0.0902 (limit 0)
  • agent-pane.composer/image-attached (Apple System Colors Light, chromium): step 1 hover .acpmux-attachment-image: layout shift 0.0498 (limit 0)
  • agent-pane.composer/image-attached (Apple System Colors, chromium): step 1 hover .acpmux-attachment-image: layout shift 0.0902 (limit 0)
  • agent-pane.composer/image-attached (Apple System Colors, chromium): step 1 hover .acpmux-attachment-image: layout shift 0.0498 (limit 0)
  • 75 more on the diff page

0 unchanged · base d808aa1 · head b601429

teamleaderleo added a commit that referenced this pull request Oct 10, 2026
…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…
teamleaderleo added a commit that referenced this pull request Oct 10, 2026
* 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…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants