Skip to content

base red: move the dialog desk's acpmux pending read into CmuxNextAgentPane (tip arch red from 79b76ff1ed3) - #32858

Merged
lawrencecchen merged 2 commits into
feat-cmux-nextfrom
base-red-arch-32752
Nov 3, 2026
Merged

lawrencecchen merged 2 commits into
feat-cmux-nextfrom
base-red-arch-32752

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The feat-cmux-next tip 79b76ff is red in arch-ratchet: [app_lines] CmuxNextApp Swift lines: +27 (CmuxNextApp +27) over the last green arch tip c5d7e8d. The only commit that grows the App is 79b76ff (#32752): it added the pendingOnly session list to Feed/AgentDialogDesk.swift (+25) and the capabilities field to Feed/AgentDialogLine.swift (+6).

This change fixes forward with no change in behavior. It moves the acpmux side of the dialog read out of CmuxNextApp into CmuxNextAgentPane, the package that already owns AcpmuxPersonLine:

  • AgentDialogLine (the protocol, its default empty capabilities, the AcpmuxPersonLine conformance) moves to CmuxNextAgentPane/Approvals/AgentDialogLine.swift, now public.
  • The pending read moves to AgentDialogLine.pendingPrompts() in the same file: _acpmux/sessions {pendingOnly: true} once when acpmux serves session-list-pending-v1, else every page (limit: 64, cursor loop with the same duplicate and repeated-cursor rules), then _acpmux/info for each session with a pending prompt.
  • The prompt data moves to AgentDialogPrompt (it was AgentDialogDesk.Pending, which stays as a typealias). pendingListCapability is now on AgentDialogPrompt. The question read stays in the App, next to the desk, because it uses CmuxAgentQuestion.

The code is a move: the method bodies are the same, with line. removed.

Testing

  • Arch ratchet, as tip-watcher.py runs it (arch-ratchet.py --repo . --base c5d7e8d52824 --head <head>):
    • before (79b76ff): [app_lines] CmuxNextApp Swift lines: +27, push refused
    • after (60f3cde): app_lines -52 (CmuxNextApp -52), no architecture count rises. No other row goes up.
  • python3 scripts/cmux-next/prepush-gate.py and --only swiftformat: no new violations.
  • Compile at 2678fe9: fleet job ad699fe40000ca23c410a738, compile check CmuxNext: passed (204 s), app: passed, cmux-tui: passed. (60f3cde: job 05a2216aa333bc3a13e8b0ae, all ok.)
  • Tests, package-test-lane.sh suite Packages/macOS/CmuxNext AgentDialogControlTests:
    • base aa30aed (step d185ed7c816937c1be51c62c, aws-m4pro-1): Test run with 10 tests in 1 suite failed ... with 1 issue: Agent reads answer on a loaded app: dialog list skips the paced session list, catalog reads skip the read barrier #32752's own listAsksAnAcpmuxWithPendingOnlyForTheChatsWithAnAskOnce counts 3 items, not 2. Its fake acpmux ignored pendingOnly and listed s-tool twice. The second commit makes the fake answer pendingOnly as acpmux does (hub/peers.rs pending_session_summaries: each session with an ask once). Test-only.
    • head 2678fe9, Blacksmith (hq run 41567692653): Test run with 10 tests in 1 suite passed. Then the XCTest phase aborted (signal 6) after CoreData: error: Failed to create NSXPCConnection.
    • head 2678fe9, aws-m4pro-1 (step 7ecb851de11017fd019e334b): Test run with 10 tests in 1 suite passed. Then xctest exited with signal 6 after the CoreData 134020 store error (the known infrastructure abort, STATUS 7919/7933). The step is red only from that abort: no test failed.

AgentDialogControlTests and SubagentLimitTests stay in CmuxNextAppTests (they test the desk and the limit flow, which stay in the App). They now import CmuxNextAgentPane for the protocol; the pendingOnly test reads AgentDialogPrompt.pendingListCapability.

Observed / Not run

  • Observed: the arch ratchet before and after (above); the prepush gate; the fleet compile and test results above.
  • Not run: no live dogfood of cmux agents dialog list (the behavior is unchanged; this is a move).

Changelog

none

Proof

No capture: no UI change; a code move between two packages.

…ntPane (tip arch red from 79b76ff)

#32752 added 27 lines to CmuxNextApp (the pendingOnly session list in
AgentDialogDesk, the capabilities field of AgentDialogLine), and the arch
ratchet's app_lines row went red at the feat-cmux-next tip.

Move, with no change in behavior:
- AgentDialogLine (protocol, default capabilities, the AcpmuxPersonLine
  conformance) to CmuxNextAgentPane/Approvals, public.
- The pending read (pendingOnly when acpmux serves session-list-pending-v1,
  else every page; then _acpmux/info per session with a prompt) to
  AgentDialogLine.pendingPrompts() in the same file.
- The prompt data to AgentDialogPrompt (was AgentDialogDesk.Pending, now a
  typealias); its question stays in the App, next to the desk.

Tests: AgentDialogControlTests and SubagentLimitTests import
CmuxNextAgentPane; the pendingOnly test reads
AgentDialogPrompt.pendingListCapability.
@lawrencecchen lawrencecchen added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 2678fe9: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr32858 -f ref=base-red-arch-32752 -f platform=macos -f backend_mode=local

Shipped in:

…x does

The fake's _acpmux/sessions ignored pendingOnly and listed s-tool twice
(a duplicate meant for the paged list, which removes it). acpmux's
pendingOnly reply (hub/peers.rs pending_session_summaries) lists each
session with an ask once, so the test counted 3 items, not 2. It failed
at #32752's own head the same way. Test-only: no product change.
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Review (claude-opus-independent): SHIP at 2678fe9

What I checked (read only, no local build):

  • Moved logic, compared line by line with the App version at 79b76ff: the pendingOnly path (gated on session-list-pending-v1, one _acpmux/sessions {pendingOnly: true} call, empty when it fails), the paged path (limit: 64, cursor, dedupe on peer/id, a repeated cursor or a failed or malformed page gives nil and then empty), and the prompt read (pendingPermissions > 0, then _acpmux/info, entries with no permissionId or request skipped). They are the same. The only change is that line. became self. inside the protocol extension.
  • Access control and isolation: AcpmuxPersonLine already has public isPerson, capabilities, call(_:_:) and close(), so it satisfies the public @MainActor protocol in its own module. The private helpers are in a protocol extension in the same file. Pending is now a typealias of AgentDialogPrompt, and question stays as an App extension. I found no other AgentDialogLine or AgentDialogPrompt in Packages/. The pendingPrompts properties on browser tabs belong to a different type and cannot clash.
  • Other conformers: SubagentLimitTests.FakeLine (with the new import) and SubagentLimitHandlers (already imports CmuxNextAgentPane) still use the default capabilities. The test target compiled at this head.
  • Test fake: the new pendingOnly reply matches acpmux pending_session_summaries and list_reply.rs::pending, which return only rows with an ask, in one reply with no nextCursor. The paged reply keeps its duplicate row, so the peer/id dedupe test still covers that path. The pendingOnly test still asserts 2 items, exactly one sessions call, pendingOnly == true and no limit. This does not weaken the test.
  • Blacksmith run 41567692653 at this sha: all 10 AgentDialogControlTests passed. The step went red only from the CoreData XPC noise in the runner.
  • arch-ratchet.py --base c5d7e8d52824 --head HEAD: app_lines -52, no architecture count rises.

@lawrencecchen lawrencecchen added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Nov 3, 2026
@lawrencecchen
lawrencecchen merged commit 8583b33 into feat-cmux-next Nov 3, 2026
239 of 249 checks passed
@lawrencecchen
lawrencecchen deleted the base-red-arch-32752 branch November 3, 2026 04:03
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

BASE RED XCTEST (STATUS 8187, 8257): the xctest signal 6 after the Swift Testing suites pass is a base red, not a defect of this PR and not a worker fault. Cause: the test-bundle run-loop guard (#25861) holds the main thread of xctest when XCTest start-up turns the main run loop (hung stack from aws-m4pro-6, step 3bd61ca1). The fix is on branch fix/base-red-xctest-contacts (PR follows). For this PR: a Swift step whose only red is xctest ... exited with unexpected signal code 6 after "Test run with N tests ... passed" is this base red. It does not hold the PR.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

BASE RED XCTEST: the fix for the xctest signal 6 base red is PR #33013 (the test-bundle run-loop guard held the main thread of xctest). Red/green on aws-m4pro-6 and -9 run now.

lawrencecchen added a commit that referenced this pull request Nov 3, 2026
…packages (tip arch red after 79b76ff) (#32928)

* base red: move the App lines of #28068, #32722 and #32851 into their packages (tip arch red after 79b76ff)

The tip arch ratchet counts CmuxNextApp +51 over the last green arch tip
c5d7e8d. #32858 takes #32752's +27; #32871's +8 has its exception.
This takes the other three culprits, each by a move of its own code path
with no change in behavior:

- #32851 (+1): the kind of a tab that opens beside a chat (browser,
  local terminal, or document for the Changes page) is
  RightColumnPlacement.Kind(opening:document:) in CmuxNextAgentPane.
- #32722 (+5): a Cloud machine's workspace row (id, name, resource_id)
  is WorkspaceModel.cloudMachineWorkspaceRow in CmuxNextControl.
- #28068 (+15): the half-created workspace close that its create path
  runs through (WorkspaceCreation.withTerminal and its logger) is
  EmptyWorkspaceRepair.withTerminal in CmuxNextWorkspaceRepair, next to
  populating(_:_:), which every caller already wraps it in. Same log
  subsystem and category.

* cloud.machines: map workspace rows with a closure (no key path to a main-actor property)

* cloud.machines workspace row: package access with package imports (the compile refused public over internal imports)
teamleaderleo added a commit that referenced this pull request Nov 3, 2026
…by the team's cmux id (#26910)

* acpmux: the Mac runs an added machine's GitHub action with its own gh login

A peer whose saved config has githubBroker may ask the Mac, on the link the
Mac opened to it, for one of a few fixed GitHub actions (read a repo or PR,
open an issue, comment, open a draft PR). The Mac checks it again, runs one
fixed gh command with its own keyring login, and answers with bounded output;
no token is sent. Every other peer is refused, as every peer request was.

Replaces the earlier owner-forwarding design (lane-to-owner link, shared HMAC
secrets, exact-session policy file), which an Add Machine peer has none of.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the Mac lends GitHub only on a peer link whose handshake finished

Review of #24797 at 758863e: a lent peer's request was served before its
handshake finished and on a link where the peer served the Mac as Web. Now
only a link whose initialize said it serves the Mac as a peer takes one, and
a re-add that lends GitHub to a peer added before keeps its saved tokens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a reload lends only to the machine it read; a GitHub reply holds its slot until queued

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a removal waits for a reconnect in progress; a reconnect shares its peer's GitHub slots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: no GitHub token gh prints goes back to the machine

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the Mac starts no GitHub action its machine stopped waiting for

Review of the lane part at 1ea8bb6: a request held up on a stalled or sleeping
link could reach the Mac after the machine had given up, and still run. Each
request now carries the machine's deadline; the Mac refuses one it could not
finish before it (github.expired).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: an added machine's agent asks the Mac for a GitHub action

An agent session on a machine the person added asks its daemon over the unix
socket for _acpmux/github_action. The daemon checks it, sends it to the Mac as
a request on the link the Mac opened to it (a server-to-client request, the
first acpmux sends), and records a redacted github_broker_action event on the
session. Only a link that proved the peer token and said githubBroker in its
initialize is asked; the Web, app pages, peers and non-session callers are
refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a lending Mac counts from its watch; lane requests are bounded

Review of the lane part at 1ea8bb6: a Mac counted as lending from its
initialize, before its own handshake was done; each initialize listed the
link again; and requests could pile up behind a Mac that stopped reading.
Now the link counts from the Mac's _acpmux/watch, is listed once (at most
16 links), at most 8 requests wait on one client, and each action carries
the deadline the Mac checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a GitHub request never passes the watch answer before it; the machine waits out a Mac clock that is behind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a watch answer or GitHub request to a reader that is gone counts as not sent

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: Add Machine lends the Mac's GitHub login; `acpmux gh` asks for it

`acpmux host enroll` (the app's Add Machine) adds the person's machine with
githubBroker on, and turns it on for a machine added before at its next enroll
(re-added under its own url; one reconnect). A plain peer add, a pairing and a
Cloud lease keep it off.

`acpmux gh` is the broker's actions in gh's own words for an agent there:
repo view, pr view N, pr create --draft, issue create, issue comment N. Each
form takes only its own flags; any other word or flag is refused, never
dropped (the review of #24797 at c3634e0: `--edit-last` became a new comment,
`repo delete` a read). The repository defaults to origin, the head to the
current branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: only enroll lends GitHub; doctor --fix leaves a peer as it was

Review of the Add Machine part at 5e03d7f: `host doctor --fix` shares the
peer step with enroll, so it lent GitHub to peers never enrolled and undid
a `githubBroker: false`. The grant is now enroll's alone (Plan.lends_github).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux gh: a body file is read only up to the broker's limit

Review of the Add Machine part at 8ca6cd7: --body-file (or stdin) was read
whole before the 64 KiB check, so /dev/zero or an endless FIFO could hang the
shim or fill its memory. It now reads at most the limit plus one byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux gh: a remote url loses one .git, not every one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: enroll matches a saved peer's ssh user exactly; acpmux gh bounds its git questions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux gh: a git that runs on past its output, or a body that never comes, is refused in time

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the GitHub broker's fixed actions and the Mac's checked gh runner

The core of the GitHub broker, with no caller yet: the five actions (read a repository or a
pull request, open an issue, comment, open a draft pull request) and their checks, the one
fixed gh command each runs on the Mac with bounded, token-redacted output and a 60 s limit,
the deadline check, and the per-peer-name slots. The peer link that serves it is the next PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: lending that ends stops the actions still running; a refusal waits no longer than any frame

An action the Mac had admitted ran on for up to 60 s after the peer was removed, its link
ended or githubBroker was turned off; now it is stopped then (its gh killed) and a link still
up is told github.denied. A refusal of a peer's request was sent with no time limit, so a peer
that asks and never reads held the link's loop; now it is bounded like every other frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the gh the broker runs gets no GitHub token or host from the daemon's env

Every brokered gh ran with the daemon's env whole, so a GH_TOKEN, GITHUB_TOKEN or enterprise
token there was used instead of the Mac's keyring login, and a GH_HOST sent it elsewhere. Now
those are removed and GH_HOST is github.com (login_env).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: GitHub is lent only over ssh, TLS or loopback

githubBroker was honoured for a plain ws:// peer on another host, so anything on the path could
answer the handshake as the peer and ask as it. Lending now needs an ssh:// (what Add Machine
saves), wss:// or loopback ws:// link. The broker test's gh also checks that no daemon token
and no host but github.com reaches it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the broker cuts tokens out of gh's output before it cuts the output to its limit

The output was cut to 64 KiB first and its tokens replaced after, and [redacted] is longer
than the shortest token, so an output full of tokens grew past the limit. Now tokens go first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a GitHub action admitted just before its peer stops never runs

The task took the link epoch when it was spawned, so a stop between the admission and that
moment gave it the epoch after the stop, and with githubBroker still on it ran. Now the action
carries the epoch of the link it was read on, and both the admission and the task's start
check that link is still live, the peer not stopped, and lending on. The loopback check takes
IPv6 hosts with or without brackets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the app may lend the daemon its cmux sign-in for GitHub App tokens

`_acpmux/github_app_lease {seq, origin, bearer, team, expiresAtMs}` or `{seq, clear}`: only
the app's own unix-socket connection that proved the person; held in memory only, dropped
when expired; an older seq changes nothing; the origin must be cmux Cloud's API. The mint
that uses it comes on top of this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: at the newest seq the app's lease takes only a clear or a renewal of the sign-in it holds

A lend at the seq of the lease held now replaced it, so a token minted under that seq stayed
usable after a switch to another team or API, and a cleared or expired sign-in came back
under its seq. Now such a lend is stale unless it renews the unexpired sign-in held (same API
and team).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: the app's lease reads the clock under its lock, and drops an expired sign-in for every call

The expiry was checked against a time read before the lock, so a call that waited for the lock
could pass an expired sign-in; and a stale call after expiry answered lent: true and kept the
expired sign-in in memory. Now the clock is read once the lock is held, and every call (set,
current, still) drops an expired sign-in first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: a lend that expired on its way to the daemon moves seq on and is not kept

Only the sign-in already held was checked for expiry, so a lend that arrived expired was kept
in memory and answered lent: true. Now it is dropped as it lands (the clock read under the
lock), while its seq still counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* cmux-next: lend acpmux the cmux sign-in for GitHub App tokens, named by the team's cmux id

The app lends its acpmux daemon a Mac install token minted for the active team and that
team's cmux id (`_acpmux/github_app_lease`), so that with no gh keyring login the daemon can
ask cmux Cloud for a GitHub App token for a lent action. A signed-out launch clears a lease
the daemon kept from the app's last run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* acpmux: with no gh keyring login, the Mac runs a lent GitHub action with an App token

Per action: the keyring login if `gh auth status` works, else a token for that one repository
minted by cmux Cloud's token route with the lent cmux sign-in, else fail closed with
github.not_connected. The token must be a ghs_ installation token for the action's repository
with no more than the action's permissions; it reaches only that one gh as GH_TOKEN, and any
token gh prints is cut out. A token minted with a sign-in that was replaced, cleared or expired
by the time gh would start is not used (github.app_token, code lease_changed). The source
(keyring or app) is recorded on the event and the reply; the token never is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* cmux-next: a sign-out's clear of the GitHub App lease never waits for an earlier token fetch

Lends and clears all queued one behind the other, so a sign-out (or a switch) waited for a
renewal whose token fetch hung, and the daemon kept the sign-in meanwhile. Now only the calls
of one account change queue behind each other; a later change's go at once, and an earlier
change's stale reply never sends again past them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* cmux-next: a superseded GitHub App lease fetch is cancelled, and its failure is not the current one's

An account change left the earlier change's token fetch running (changes in a row piled them
up), and that fetch's failure counted against the current change's retry delays. Now the
earlier change's task is cancelled when the next starts, and only the current change's
outcome moves its failure count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Test that cancelling a team install-token mint reaches its request

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Cancel a superseded lend's team install-token mint with its task

The scoped client minted in a Task of its own, so cancelling the lend's
task left its requests running and superseded team switches piled up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Build the initialize reply's extension list outside json!

With feat-cmux-next's newer methods, one more name put the json! macro's
expansion past the default recursion limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Lend the cmux sign-in only on a line acpmux took the person proof on

AcpmuxPersonLine.open also returns a line whose proof was refused or never
asked for (an older daemon, or another at the socket path); the bearer went
to it and was only refused there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Take the lender's acpmux environment on the main actor

feat-cmux-next made QuitAgents.environment main-actor isolated, so the
closure that reads it must be too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Drop a lend or clear of an earlier account change before it is queued

A renewal or retry timer of the account before, firing as a sign-out came,
queued its call after the sign-out's clear; queueing a new change's call
cancels the tail, so the clear was cancelled and the daemon kept the sign-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Read the reached calls from the stand-in daemon

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* Read the account test's mutating results outside #expect

The test target did not compile: #expect takes its expression as immutable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-1288bbb2b5d2f5c6b66a

* cmux-next: import CmuxNextAgentPane in GitHubAppLeaseTests (AgentDialogLine moved there in #32858)

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4e15cf5dc754017cf462

---------

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

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 2678fe9c Deployed Nov 3, 2026 by lawrencecchen via namespace autofix #12852
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant