Repository navigation
base red: move the dialog desk's acpmux pending read into CmuxNextAgentPane (tip arch red from 79b76ff1ed3) - #32858
Conversation
…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.
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
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.
|
Review (claude-opus-independent): SHIP at 2678fe9 What I checked (read only, no local build):
|
|
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 |
|
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 |
…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)
…ogLine moved there in #32858) Agent-Session: https://cmux.com/deeplink/agent?id=aid-4e15cf5dc754017cf462
…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>
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 thependingOnlysession list toFeed/AgentDialogDesk.swift(+25) and thecapabilitiesfield toFeed/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 emptycapabilities, theAcpmuxPersonLineconformance) moves toCmuxNextAgentPane/Approvals/AgentDialogLine.swift, nowpublic.AgentDialogLine.pendingPrompts()in the same file:_acpmux/sessions {pendingOnly: true}once when acpmux servessession-list-pending-v1, else every page (limit: 64, cursor loop with the same duplicate and repeated-cursor rules), then_acpmux/infofor each session with a pending prompt.AgentDialogPrompt(it wasAgentDialogDesk.Pending, which stays as a typealias).pendingListCapabilityis now onAgentDialogPrompt. Thequestionread stays in the App, next to the desk, because it usesCmuxAgentQuestion.The code is a move: the method bodies are the same, with
line.removed.Testing
tip-watcher.pyruns it (arch-ratchet.py --repo . --base c5d7e8d52824 --head <head>):[app_lines] CmuxNextApp Swift lines: +27,push refusedapp_lines -52 (CmuxNextApp -52),no architecture count rises. No other row goes up.python3 scripts/cmux-next/prepush-gate.pyand--only swiftformat: no new violations.compile check CmuxNext: passed (204 s),app: passed,cmux-tui: passed. (60f3cde: job 05a2216aa333bc3a13e8b0ae, all ok.)package-test-lane.sh suite Packages/macOS/CmuxNext AgentDialogControlTests: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 ownlistAsksAnAcpmuxWithPendingOnlyForTheChatsWithAnAskOncecounts 3 items, not 2. Its fake acpmux ignoredpendingOnlyand listeds-tooltwice. The second commit makes the fake answerpendingOnlyas acpmux does (hub/peers.rspending_session_summaries: each session with an ask once). Test-only.Test run with 10 tests in 1 suite passed. Then the XCTest phase aborted (signal 6) afterCoreData: error: Failed to create NSXPCConnection.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.AgentDialogControlTestsandSubagentLimitTestsstay in CmuxNextAppTests (they test the desk and the limit flow, which stay in the App). They now import CmuxNextAgentPane for the protocol; thependingOnlytest readsAgentDialogPrompt.pendingListCapability.Observed / Not run
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.