Skip to content

acpmux --group: a variant of a group's name joins that group; a refused group exits 2 as usage.group_name - #28730

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/ao-group-name-match
Nov 1, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/ao-group-name-match

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes manaflow-ai/cmuxterm-hq#4976

For Leo's ask to productionize the acpmux daemon ("do we have more productionized stuff wrt the daemon ... let's go set up more fellas on it"). This finishes what #24581 left open: acpmux new --group makes a stray sidebar group when a name is typed a little differently, and its refusal skips the usage envelope.

What

  • The app matches a group by its label, not its exact string. --group "gui push", "GUI push " or " Gui Push\n" now joins the existing "GUI push" group, and a re-homed lane finds its old row in that group. A group with exactly that name still wins over a case variant, and a new group gets the trimmed name. Before, any variant made a second "GUI push" group next to the first (group.name == name).
  • The group helpers move out of CmuxNextApp. validGroupName, group(named:accepting:in:), predecessor(named:inGroup:in:) and the new sameGroupName are pure sidebar-tree functions. They move from AgentSessionWorkspace to SidebarEdits+NamedGroup.swift in CmuxNextSidebar, next to SidebarEdits.canMove, which they use. CmuxNextApp shrinks by 35 lines (arch-ratchet app_lines).
  • A refused --group is a usage error. A blank or id-shaped --group (grp_…, ws_…, a UUID) used to exit 1 as a runtime error. It now exits 2 with detail: group_name and data.reason: usage.group_name in the --json envelope, still before any session is made.
  • Docs. The --group help, the acpmux skill and the README say that the name is matched ignoring case and outer spaces, and that an id is refused with exit 2.

Test

Red commit 48f6920 adds only tests:

  • cd cmux-tui && cargo test -p acpmux --lib -- a_group_is_a_human_label_and_never_an_object_id: the refusal must classify as exit 2 with usage.group_name. Green at head 96ee062: test result: ok. 39 passed; 0 failed with a_group_is_a_human_label_and_never_an_object_id ... ok (fast-checks run 41159694793). Red: not run. The broker refused the run at the red commit twice (GitHub quota 403, then busy). The reviewer confirmed by reading that it fails on base, where the refusal is a plain bail! that classifies as exit 1 / error.
  • AgentSessionGroupJoinTests.theSameLabelTypedAnotherWayJoinsTheGroup (CmuxNextAppTests): case and whitespace variants join g1 and find the predecessor row, "GUI pushes" does not match, and an exact name beats a case variant, both for the group and for the re-homed row (added after review, 96ee062). On base, every variant returns nil. This lane VM has no fleet client, so the Swift suites run only in this PR's CI at its head.

Observed / Not run

  • Observed: prepush-gate.py reports no new violations; rustfmt is clean on the changed Rust files.
  • Not run: a tagged-build launch of acpmux new --group "gui push" into a sidebar that already has "GUI push". The Swift change is covered by the unit test above, not by a capture.

No capture: the sidebar looks the same; the only change is which existing group a scripted --group open joins.

Default changes: the defaults guard lists the moved functions of AgentSessionWorkspace.swift (a tunable source) by hash. No setting, key or flag default changes: the functions moved to SidebarEdits+NamedGroup.swift, and only group-name matching changed.

Review

Independent review (Codex gpt-6-astra, high): BLOCK at 1627fa5 for a missed test caller (AgentSessionGroupPlacementTests still called AgentSessionWorkspace.group) and for predecessor not preferring the exactly named group. Both were fixed in 96ee062, and the delta review gave SHIP at 96ee062.

Changelog

  • Fixed: acpmux new --group joins the existing sidebar group when the name differs only in case or outer spaces, instead of making a second group.

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits October 31, 2026 01:34
… and that the app matches the label ignoring case and outer spaces (red)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-7016b1d4ce75ef44bdc7
…joins a group whose name is the same label ignoring case and outer spaces

The group-name helpers move from CmuxNextApp to CmuxNextSidebar (SidebarEdits+NamedGroup.swift).

Fixes manaflow-ai/cmuxterm-hq#4976

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-7016b1d4ce75ef44bdc7
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Found 9 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp0o7iiu0a/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmp6pagi6w2/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)/
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)
View Logs
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)/
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)
View Logs

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

…'s; the placement test calls SidebarEdits.group

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-7016b1d4ce75ef44bdc7
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

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

Review e4453fc: 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=pr28730 -f ref=lane/ao-group-name-match -f platform=macos -f backend_mode=local

Not verified: macOS jobs did not run: compile and app tests were skipped on e4453fcd8a; ci-status is green without them.

CI passes on e4453fcd8a (run 41268222451 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

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.

Default changes

This pull request changes 12 defaults at e4453fcd8a92 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:group: "38112813c99d6e8f90ff39c61392640484a6d41ca0c24341876949523f62ce0a" -> (none)
  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:join: "4fda0e2193d3c245fb15282abaeb52b570a403f5d819fc659f7820b12d6a71cb" -> "adfee61fb9aca5c1f15a6c292bf78da01b62fc64b9b98e67925e33ff173cfe1f"
  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:open: "f7a01c08fb4e78315598f9afc7f7fdf4b5d6a420a43d433ce90cec68d1deabf7" -> "c341eede0224c6ae8ddca81e6ab5a4173134996ea905c6dee347d0a07edff698"
  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:open#: "17c409a46c8e7e7c43c321c4f89ec953a7a66b1d6d4bd6f146e49e37d2deeee1" -> "97b3ad6857e383d4fdca0e04955f200038cdb695f4dc5924a041080584a0426f"
  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:predecessor: "d8de7ca42c2d51422a9550817edec657608ed74514693dd38abb7c800fe5c601" -> (none)
  • tunable-source.CmuxNextApp/Handlers/AgentSessionWorkspace.swift:validGroupName: "77900eaf377fb73b664ea8d86f0c9a6f8561a59dc224f5087400b53fa7d19f99" -> (none)
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:group: (none) -> "13f2201c4f4faca1eb5ba3c347e338c55294e950e151d82b5362a103814e8161"
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:listsGroup: (none) -> "0c3e076ec33b57e32a62f9664842edf748c96e222f2adbbe73b23dabf637ad7d"
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:predecessor: (none) -> "501cb25674f2f60599810d9974a4ae49516187d6302b76189c2dfd6972057812"
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:predecessor#: (none) -> "dc0ecf65fe16fb8652c34785fcb56a602eb56a2bd419733652acb251637e6d90"
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:sameGroupName: (none) -> "f2f1fe9d293ac9f6fe2aa415ab8458f6d6f35add13fe2218e2da5f0fde42e897"
  • tunable-source.CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:validGroupName: (none) -> "77900eaf377fb73b664ea8d86f0c9a6f8561a59dc224f5087400b53fa7d19f99"

Signed off on this commit by review (codex, router-review).

Merge receipt: merged as 67aa3f884a32 with these defaults changed, signed off by review (codex, router-review).

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6-astra, high): SHIP at 96ee062

Independent review of the full diff (BLOCK at 1627fa5, both findings fixed in 96ee062), then a delta review of the fix: SHIP. The defaults guard lists only moved-function hashes from AgentSessionWorkspace.swift; no setting, key or flag default changes.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, next-review): BLOCK at ff23c86

BLOCK at ff23c86

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] AgentSessionWorkspace.swift:96 applies exact-name precedence separately per window, then takes the first result. If the first window has a case-variant group/row (GUI push) and a later window has the exact requested group (gui push), the fuzzy fallback in the first window reuses the wrong row. The previous exact matching skipped that first row and selected the later exact match. Search all windows for an exact predecessor before considering case-insensitive/trimmed matches.

Rust and Swift toolchains were unavailable in this environment, so verification was by code inspection.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Awareness (independent Opus 5.5 medium subagent read, not a receipt; broker refused adoption because the owning session cannot be read): no blocking findings at ff23c86

Independent read of the exact head (router-review could not run, so this is an Opus 5.5 medium subagent read). No blocking findings.

  • Swift: the new SidebarEdits+NamedGroup.swift resolves WorkspaceID/GroupID/SidebarSection in CmuxNextSidebar; SidebarEdits and canMove are public; SidebarWorkspaceID is a typealias for CmuxNextSidebar.WorkspaceID; no call site of the old AgentSessionWorkspace.validGroupName/group/predecessor remains, tests included.
  • Rust: AppError::new, with_data, classify, exit_status, envelope and Code::Usage = 2 exist with those signatures; Display still prints the message, so the existing assertions hold.
  • Behaviour: exact name wins first, so groups that resolved before resolve the same; only a case or outer-space variant now joins instead of making a duplicate group.

Follow-ups:

  • [follow-up] No Unicode normalization (composed vs decomposed accents still make a separate group).
  • [follow-up] The id-prefix list lives in both Swift SidebarEdits.validGroupName and Rust validate_group; a shared fixture or cross-check test would keep them in sync.

@teamleaderleo

teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 37b9486

Reviewer: codex gpt-6-astra high, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at 37b9486

Visual verdict: no images; Leo tries the build

No correctness findings.

Follow-ups:

  • [P2] [follow-up] No after screenshots were provided, so visual verification is unavailable.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift:12">
P2: This prefix-only check rejects legitimate group labels such as `ws_project` even though they are not object IDs. Validate the complete identifier shape rather than reserving every label with an ID prefix, so `--group` refuses actual IDs without blocking human names.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Handlers/AgentSessionWorkspace.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/Handlers/AgentSessionWorkspace.swift:50">
P2: An explicitly supplied empty `--group` is silently treated as omitted, so `cmux agent open --group ""` bypasses validation and creates the session without a group. Preserve the empty string and let `validGroupName` reject it.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

let label = name.trimmingCharacters(in: .whitespacesAndNewlines)
guard !label.isEmpty else { return false }
let lower = label.lowercased()
if ["grp_", "ws_", "tab_", "pane_", "win_", "workspace_group:"].contains(where: lower.hasPrefix) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This prefix-only check rejects legitimate group labels such as ws_project even though they are not object IDs. Validate the complete identifier shape rather than reserving every label with an ID prefix, so --group refuses actual IDs without blocking human names.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/SidebarEdits+NamedGroup.swift, line 12:

<comment>This prefix-only check rejects legitimate group labels such as `ws_project` even though they are not object IDs. Validate the complete identifier shape rather than reserving every label with an ID prefix, so `--group` refuses actual IDs without blocking human names.</comment>

<file context>
@@ -0,0 +1,66 @@
+        let label = name.trimmingCharacters(in: .whitespacesAndNewlines)
+        guard !label.isEmpty else { return false }
+        let lower = label.lowercased()
+        if ["grp_", "ws_", "tab_", "pane_", "win_", "workspace_group:"].contains(where: lower.hasPrefix) {
+            return false
+        }
</file context>

let host = invocation["host"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
let group = invocation["group"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
if let group, !validGroupName(group) {
let givenGroup = invocation["group"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: An explicitly supplied empty --group is silently treated as omitted, so cmux agent open --group "" bypasses validation and creates the session without a group. Preserve the empty string and let validGroupName reject it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextApp/Handlers/AgentSessionWorkspace.swift, line 50:

<comment>An explicitly supplied empty `--group` is silently treated as omitted, so `cmux agent open --group ""` bypasses validation and creates the session without a group. Preserve the empty string and let `validGroupName` reject it.</comment>

<file context>
@@ -47,10 +47,12 @@ enum AgentSessionWorkspace {
         let host = invocation["host"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
-        let group = invocation["group"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
-        if let group, !validGroupName(group) {
+        let givenGroup = invocation["group"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
+        if let givenGroup, !SidebarEdits.validGroupName(givenGroup) {
             throw ActionFailure(message: "agent.openSessionWorkspace: group must be a non-empty human label, not a cmux id; omit group or use a label such as \"GUI push\"")
</file context>
Suggested change
let givenGroup = invocation["group"]?.stringValue.flatMap { $0.isEmpty ? nil : $0 }
let givenGroup = invocation["group"]?.stringValue

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at dcedcfd

BLOCK at dcedcfd

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] SidebarEdits+NamedGroup.swift:64: An exact group loses precedence when it lacks the requested row. With groups GUI push containing lane and gui push containing another row, requesting --group "gui push" --name lane now reuses the uppercase group’s workspace. Base created the row in the explicitly named lowercase group. Only try variant groups when no eligible exact group exists.

  2. [P1] [blocking] AgentSessionWorkspace.swift:55: Trimming before lookup also breaks existing exact matches. If GUI push and GUI push both exist, requesting the latter now selects the former, including its predecessor row. Base selected the padded name correctly. Preserve the supplied name for lookup and trim only when creating a group.

  3. [P1] [blocking] SidebarEdits+NamedGroup.swift:53: Commit 1c284fd2b2f changes this file without a Sidebar-Look: trailer or an acknowledgment in sidebar-owner.md. Replaying the repository’s validator against the supplied commit metadata reports this violation. The fast-gates workflow runs that validator in fail mode, so this head fails CI. Add the required acknowledgment.

Swift and Cargo suites could not run because neither toolchain is installed.

teamleaderleo and others added 3 commits November 1, 2026 03:12
… tried only when no exact group is listed

Searches every window for an exactly named group before a case or outer-space
variant, falls back to a variant only when no group of exactly that name is
listed (an exact group without the row gets a new row, as before), and looks
the name up as given so a padded exact group still matches; a new group gets
the trimmed name.

Sidebar-Look: no visual change

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

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at e4453fc

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at e4453fc

Visual verdict: no images; Leo tries the build

  1. [P2] [follow-up] No after screenshots are available (review/images/selection.json:1), so visual verification remains for the build.

Follow-ups:

  • [P2] [follow-up] No after screenshots are available for visual comparison.

@teamleaderleo
teamleaderleo merged commit 67aa3f8 into feat-cmux-next Nov 1, 2026
145 of 149 checks passed
@teamleaderleo
teamleaderleo deleted the lane/ao-group-name-match branch November 1, 2026 03:57

This branch was previously deployed

3 inactive deployments
artifacts — e4453fcd Deployed Nov 1, 2026 by teamleaderleo via publish tree-addressed cmux-tui #93338
sentry-dsyms — e4453fcd Deployed Nov 1, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #93338
ci-routing-agent — e4453fcd Deployed Nov 1, 2026 by teamleaderleo via cmux-tui tree preflight #93338
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant