the permission-mode menu lists only the modes; grants are revoked in Session Info (carry #28580)
Leo, 2026-10-29: "What the hell is this? Why the f*** is this? Grant access, trust this. What is this bottom fing nonsense? Who the f? What did this? It's not fing good. What the f is this? And clicking out of a fing context menu is sometimes slow as fing balls. What the f***?"
Carries #28580 (original lane's commits kept with authorship); #28580 closes once this lands. The original lane can no longer push, so this lane branch carries the same commits unchanged.
Takes back #27579: on purpose. #27579 aligned the mode menu's Granted access section and added access-grants-columns.test.ts to measure it; this PR removes that section (grants move to Session Info), so the test has nothing left to measure.
What changed
The composer's permission-mode menu (the "Bypass permissions ⌄" chip) drew a Granted access section under its modes: a "Trusted " row and an "Allow for this chat" row, each with an ×. The section came from #20339 (fix(cx-gakp): make permission cards honest per harness), and #27579 later aligned its columns.
- The mode menu now lists only the modes. The section, its CSS and its
permission.grantsstring are gone. - Revoking still works, from a new place: both grants move to Session Info → Environment, as rows with Revoke. They use the same callbacks as before (
trustAsk.undofor the folder's trust;chat.permission_chat.revoke, still guarded byready === false, for the chat allowance). A subagent's Session Info doesn't list them, because they belong to the chat. The chat allowance also keeps its existing Revoke menu action (permissionRevoke). - A chat whose harness offers no modes no longer draws a lock-only Access chip just to hold a grant. It shows no mode chip, as it would with no grants.
access-grants-columns.test.ts(#27579) measured only the removed section's columns, so it goes. So does theLockIconit leaves without a caller, and its gallery-coverage allowlist line.
Known gap, not changed here: Session Info sits behind Debug Settings agent.inspector, which is off by default. With default settings a grant is still revoked the way it was before it showed in this menu: the folder trust bar's Undo while it shows, and the Revoke menu action for a chat allowance. This PR doesn't change that default (the rulebook says never flip a default unasked). If Leo wants a default-visible home, Settings → Folder Trust is the natural one. It holds the trust rules but no per-folder answers today.
Spec: design/menus.md (this lane owns the mode-menu trust section) and design/session-info.md. After landing, menus.md gets the rule "the mode menu lists modes only; grants are revoked in Session Info".
Tests
test/access-chip-pending-warning.test.tsx: the access menu lists modes and draws no granted-access section and no "Granted access" text. This replaces the test that asserted the section.test/chat-inspector-environment.test.tsx: new test. Environment lists both grants last, each with a Revoke button whose label names the grant, and each click calls its own revoke.- Galleries:
ComposerPickersmodes-onlyreplacesaccess-grants;agent-pane.environment-savegainsgranted;bottomStacktrustThenPermissionnow asserts the composer draws no Access menu for a grant. bun run typecheck: no type errors in 3237 files, at 617a991, on Linux.bun testaccess-chip, chat-inspector-environment, composer-row-layout, gallery-coverage and strings-build-output: 25 pass, 1 skip (browser lane).gallery-coverage.test.tshas 3 failures that are base reds: the same three tests fail at base 17368d28 with the same lists. The only difference is the component count (818 → 817, the removedLockIcon).
Carry re-run (cmux-ci test, Linux, at 617a991f): typecheck clean; access-chip-pending-warning, chat-inspector-environment, composer-row-layout, quiet-access-chip, access-chip-refused-mode, agent-pane-bottom-stack and strings-build-output pass. gallery-coverage.test.ts fails 2 tests scoped to this PR's files (a RowFrame cover in App.tsx, and the stale ChatComposerChips and NewTabComposerChips allowlist lines). Both fail the same way, with the same lists, at base 17368d28: base reds, not changed here.
Screenshots
Gallery stills, Linux Chromium at 2x, synthetic fixtures, from a cmux-ci test gallery run at 617a991f (before: base 17368d28, entry agent-pane.composer-pickers variant access-grants; after: modes-only and agent-pane.environment-save granted). Each menu still is the play step right after clicking Mode. The before stage is 260 px tall, so the top of that menu (which opens upward) is cut off; the Granted access section under the modes is the part that matters.
| light | dark | |
|---|---|---|
| Before: mode menu with Granted access | ![]() | ![]() |
| After: mode menu, modes only | ![]() | ![]() |
The Session Info grants still was taken at 617a991f, before 456cd877 made each grant's Revoke show only while its own row is hovered or focused (inspector.css, .acpmux-chat-inspector-row--grant), so it was removed as stale. Leo, 2026-10-31: "We don't need screenshots, just let me try the stuff out."
Viewed after image: yes
Visual verdict: The mode menu now holds only its mode rows, like the mode menus in ChatGPT and Claude, and the two grants sit as plain rows with Revoke at the end of Session Info's Environment list, in its own row style.
Review
Independent review (Codex gpt-6-astra, high, fast) at 234f147: SHIP, no correctness findings. The stale comments and the unused string it noted are fixed in 617a991. A delta review at the final head follows.
Agent session: agent session
🤖 Generated with Claude Code



