Skip to content

feat: default agent permission mode to Bypass Permissions - #2225

Merged
simple-agent-manager[bot] merged 2 commits into
mainfrom
sam/default-mode-all-agents-skdxr1
Oct 4, 2026
Merged

simple-agent-manager[bot] merged 2 commits into
mainfrom
sam/default-mode-all-agents-skdxr1

Conversation

@simple-agent-manager

@simple-agent-manager simple-agent-manager Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Raphaël asked: "The default mode for all agents should be bypass permissions."

When no agent profile, project agent override, or user agent setting picks a permission mode, agent sessions now start in Bypass Permissions instead of the agent's always-ask default mode.

Why it matters now: before #2202 (Sep 30) the VM agent auto-approved every ACP permission request whatever the mode. Since #2202, default-mode requests go to the human in chat (or are cancelled when ACP_INTERACTIONS_ENABLED is off), so unconfigured agents started stopping to ask.

  • shared: DEFAULT_AGENT_PERMISSION_MODE = 'bypassPermissions'. The default mode ID is relabelled Manual (Claude Code's own name for it), so "Default" is no longer a non-default option.
  • api: the VM agent's POST /api/workspaces/:id/agent-settings callback resolves project override → user setting → platform default (was → null). Every runtime (VM and Instant) fetches its settings here at session start, so this applies to already-running nodes once the API deploys; no VM-agent rollout is needed. A profile's own mode still overrides it (applyProfileOverrides in the VM agent). Explicit choices are unchanged, including Manual.
  • VM agent unchanged on purpose: if the settings fetch fails, it still falls back to the agent's own always-ask mode. When the config can't be read, it fails closed rather than to the most permissive mode.
  • web / acp-client: Settings → Agents and the workspace chat settings panel preselect Bypass Permissions when nothing is saved (new optional defaultPermissionMode prop on ChatSettingsPanel / AgentPanel).
  • MCP profile/skill permissionMode field text and the public agents guide document the default.

Per-agent effect:

  • Claude Code: switches to bypassPermissions via ACP SetSessionMode. The adapter allows this for non-root users, which covers Instant containers (USER node) and normal devcontainers. Even in Bypass, Claude still asks about a few "bypass-immune" safety checks; those still show in chat.
  • Codex: unchanged; already approval_policy: never + danger-full-access.
  • OpenCode 1.18.32 / Gemini CLI 0.61.0: reject the unknown mode ID without changing state. The VM agent logs a non-fatal warning, the same as an explicit Bypass selection today. Mistral Vibe 2.25.8 ignores non-primary modes. Amp (acp-amp 0.1.3) stores the ID but only auto-approves for its own bypass ID, so it keeps asking. None of these change from today's explicit-Bypass behavior.

Production check (read-only): every saved per-user agent_settings row is already bypassPermissions. The old built-in profiles (implementer/default → Accept Edits, planner/reviewer → Plan, in ~12 projects) are explicit choices and are not migrated by this PR.

Validation

  • pnpm lint (via pnpm check:fast: format ratchet, oxlint, eslint, type-boundary ratchet)
  • pnpm typecheck (shared, acp-client, api, web)
  • pnpm test: shared 773/773, acp-client 557/557, web 3977/3977 (330 files), targeted api suites 67/67 (incl. the new route test); full api suite runs in CI
  • Additional validation: Playwright audits at 375x667 and 1280x800
  • Follow-up commit 083cd5969 (UI review nits): removed AGENT_PERMISSION_MODE_DESCRIPTIONS, which had no consumers, and renamed a test local; typecheck and card tests re-run green
  • N/A: no sweep/cron/alarm candidate selection changes

Discrimination checks (each guard reverted once, then restored):

  • API fallback reverted to ?? null: exactly the 4 default-path tests in workspace-agent-settings-callback.test.ts went red; the explicit user-mode, explicit Manual and project-precedence controls stayed green.
  • AgentSettingsCard fallback reverted to 'default': exactly the 3 new default tests plus the updated agent-card save test went red; the saved-Manual control stayed green.
  • AgentPanel pass-through removed: the new AgentPanel default test went red.

Staging Verification (REQUIRED for all code changes — merge-blocking)

  • Staging deployment green — run 37198922973 (deploy + smoke tests passed) for fb53ed0ea; 083cd5969 only removes an unused export and renames a test local
  • Live app verified via Playwright — token-login as the staging smoke user, then app.sammy.party
  • Existing workflows confirmed working — Settings → Agents, project chat list/session pages and session start all loaded; no console errors captured during the runs
  • New feature/fix verified on staging — see evidence below
  • Infrastructure verification completed — N/A: no infra changes (no VM agent, cloud-init, DNS, TLS or deploy-script changes)
  • Mobile and desktop verification notes added for UI changes

Staging Verification Evidence

A/B on staging with one Claude Code Instant profile with no mode (Claude Code Chat, project hono, which has no Agent Overrides). The prompt and runtime were identical; only the smoke user's saved Claude Code permission mode changed:

Saved user mode Result
none (new default) Settings → Agents shows Bypass Permissions selected. The agent ran the write command mkdir -p /tmp/staging-check && date … > /tmp/staging-check/ts.txt && echo STAGING_CHECK_DONE … with no prompt and replied STAGING_CHECK_DONE 20261004T120553 (session b4fd4654…). The VM agent recorded ACP session mode applied {"mode":"bypassPermissions"} (staging observability, workspace 01M43CVV746APNB4TYWT3660JS). Before this PR that combination sent no SetSessionMode at all. A first run (fec49518…) showed the same.
Manual (control) Both tool calls were denied ("Both tool calls were aborted/denied, so nothing was executed"; session df75c896…). No session-mode event, as expected. Staging has ACP_INTERACTIONS_ENABLED=false, so Manual-mode requests are denied rather than shown in chat.

staging default run
staging manual control
staging settings default

Cleanup: all 4 test sessions are cancelled with workspaces/nodes stopped. The smoke user's Claude Code setting was restored to its original row (bypassPermissions, provider mode sam).

Unrelated pre-existing staging issues seen (not caused by this PR; added to existing ideas):

  • POST …/sessions/:id/stop returned 500 Managed node teardown remains unconfirmed for every Instant stop, in both modes (23+ staging occurrences since 2026-09-11; idea 01M3KYP55W91YQHV2FN1A2NVBT).
  • One Snapshot wip artifact is missing (HTTP 400) from the vm-agent on one stop; it did not recur.
  • Claude sometimes treats SAM's appended get_instructions note in Instant sessions as a possible prompt injection (idea 01KX4HFF2Y66RW1V7TVV1ZTP7X).

UI Compliance Checklist (Required for UI changes)

  • Mobile-first layout verified
  • Accessibility checks completed (radio semantics unchanged; aria-checked/toBeChecked asserted in Playwright)
  • Shared UI components used or exception documented
  • Playwright visual audit run locally — scenarios: no saved mode (default), saved Manual (control), saved Plan next to defaults (mixed states), several agents; 375x667 and 1280x800; assertNoOverflow (includes clipped-overflow walk) on every capture
  • Desktop and mobile screenshots for every changed UI surface are linked below
  • Agent reviewed the screenshots for quality control and found no visual issues

UI Screenshot Evidence

All screenshots below were taken with Playwright from local mock-data audits (apps/web/tests/playwright/agent-settings-audit.spec.ts, apps/web/tests/playwright/chat-settings-permission-default-audit.spec.ts) at 375x667 and 1280x800.

Surface: Settings → Agents permission mode (AgentSettingsCard)

  • Desktop evidence: settings agents default desktop
  • Mobile evidence: settings agents default mobile · saved Manual control: settings agents saved manual mobile
  • Mock/stress data used: Playwright mock data with an empty state (no saved settings) for Claude Code, Codex and OpenCode; an edge case with a saved Plan mode next to defaults; a saved Manual control; many agent cards on one page; not-configured connection states; plus the existing error-state (agents API 500) and long-text provider scenarios in the same spec.
  • Screenshot quality review: reviewed every capture at 375px and 1280px. Bypass Permissions is selected with its warning when nothing is saved, Manual is selected (no warning) when saved, Save stays disabled until a change, and there is no overflow or clipping. No issues found.

Surface: Workspace chat Agent Settings panel (ChatSettingsPanel)

  • Desktop evidence: chat settings default desktop
  • Mobile evidence: chat settings default mobile · saved Manual control: chat settings saved manual mobile
  • Mock/stress data used: Playwright mock data for a running workspace with a legacy Claude Code chat session: an empty state (no saved permission mode) vs. a saved Manual control, with the ACP socket held open without a server (an edge case: no agent connection yet).
  • Screenshot quality review: reviewed at 375px and 1280px. The panel opens on Bypass Permissions with its notice, Manual is labelled correctly, Save is disabled until a change, and there is no overflow. No issues found.

End-to-End Verification (Required for multi-component changes)

  • Data flow traced from user input to final outcome with code path citations
  • Capability test exercises the complete happy path across system boundaries (real runtimeRoutes + real SQLite for the resolution step; staging session for the runtime step)
  • All spec/doc assumptions about existing behavior verified against code
  • Gaps documented below

Data Flow Trace

  1. Session start: packages/vm-agent/internal/acp/session_host_selection.go:loadAgentSettings → session_host_reporting.go:fetchAgentSettings → POST /api/workspaces/:id/agent-settings (same code in VM and Instant runtimes).
  2. apps/api/src/routes/workspaces/runtime.ts agent-settings callback: resolveProjectAgentDefault(project.agentDefaults) → user agent_settings row (scoped by user_id + agent_type) → DEFAULT_AGENT_PERMISSION_MODE.
  3. VM agent applyProfileOverrides (a profile's explicit mode wins) → session_host_settings.go:applySessionSettings → ACP SetSessionMode(bypassPermissions) for non-Codex agents.
  4. claude-agent-acp 0.81.2 session-mode.js switches the session to bypassPermissions (permissions/modes.js: allowed for non-root users or with IS_SANDBOX).

Untested Gaps

  • A devcontainer whose agent user is root cannot enter Bypass (Claude adapter rule); such sessions stay in Manual and prompts go to chat. This is unchanged from an explicit Bypass selection today.
  • OpenCode/Gemini/Vibe/Amp have no bypassPermissions mode ID (Amp calls it bypass, Gemini yolo). Mapping SAM's mode to their native equivalents is out of scope here; those agents keep their own default.

Post-Mortem (Required for bug fix PRs)

N/A: not a bug fix (product default change requested by the owner).

Specialist Review Evidence (Required for agent-authored PRs)

  • All local reviewers completed and findings addressed before merge
  • If any reviewer did NOT complete: needs-human-review label added and merge deferred to human (N/A: both completed)
Reviewer Status Outcome
security-auditor ADDRESSED 0 CRITICAL/HIGH. MEDIUM: Amp's reaction to bypassPermissions was unverified. I checked acp-amp 0.1.3 server.py: set_session_mode stores the ID, and only the literal bypass enables allow_all, so bypassPermissions leaves Amp in its normal asking mode (no escalation; Amp not bypassed, which is noted as a known gap). LOW: saving another field persists the preselected mode explicitly. This is the existing pattern (it persisted default before) and was accepted.
ui-ux-specialist ADDRESSED Nothing blocking (rubric ≥4 on all categories). Nits fixed in 083cd5969 (unused AGENT_PERMISSION_MODE_DESCRIPTIONS removed; test local renamed). Pre-existing, unchanged by this PR: chat-panel warning lacks role="alert"; chat-panel radios lack roving tabindex.

CodeRabbit Review Evidence (Required for agent-authored PRs)

  • CodeRabbit requested after local review, staging if applicable, and CI gates passed
  • Waited about 15 minutes, or up to about 45 minutes in total while a review CodeRabbit had started was still in progress
  • Either CodeRabbit reviewed and no CodeRabbit feedback is unresolved, or it did not review and the observed outcome is recorded below

CodeRabbit Notes

Requested 2026-10-04T12:13:26Z by adding the coderabbit-review label (the coderabbit-bot-review.yml run succeeded) after local review, staging and green CI. I watched until 12:29:48Z (about 16 minutes). CodeRabbit posted only a rate-limit notice ("Review limit reached — You've used all free OSS reviews for now"; run 81fe0860-d673-4f08-9279-33c5f33c5685) and no review. Under .claude/rules/25-review-merge-gate.md that counts as no review: I recorded it and did not re-trigger.

Exceptions (If any)

  • Scope: none
  • Rationale: none
  • Expiration: none

Agent Preflight (Required)

  • Preflight completed before code changes

Classification

  • external-api-change
  • cross-component-change
  • business-logic-change
  • public-surface-change
  • docs-sync-change
  • security-sensitive-change
  • ui-change
  • infra-change

External References

  • @agentclientprotocol/claude-agent-acp 0.81.2 (installed package source): dist/session-mode.js (mode catalog, parseMode), dist/permissions/modes.js (ALLOW_BYPASS: non-root or IS_SANDBOX), dist/acp-agent.js (bypass-immune permission requests still reach the client).
  • OpenCode v1.18.32 packages/opencode/src/acp/service.ts (setSessionMode rejects modes not in availableModes).
  • Gemini CLI v0.61.0 packages/cli/src/acp/acpSession.ts (setMode throws "Invalid or unavailable mode").
  • Mistral Vibe v2.25.8 vibe/acp/agent.py (set_session_mode ignores non-primary modes).

Codebase Impact Analysis

packages/shared (constant + labels), apps/api (routes/workspaces/runtime.ts agent-settings callback; MCP field text), apps/web (AgentSettingsCard, ChatSession), packages/acp-client (ChatSettingsPanel, AgentPanel). packages/vm-agent is intentionally unchanged. Request I/O for the callback is unchanged (2 D1 reads).

Documentation & Specs

apps/www/src/content/docs/docs/guides/agents.md: new "Permission mode" section.

Constitution & Risk Check

Principle XI: the default is one shared constant (DEFAULT_AGENT_PERMISSION_MODE), not a URL, timeout, limit or identifier. Users can still choose any mode per agent, project or profile. Risk: agents now run without permission prompts by default. That is the requested behavior; explicit restrictive choices still win, and an unreadable config falls back to the always-ask mode.

🤖 Generated with Claude Code

When no agent profile, project agent override, or user agent setting picks
a permission mode, agent sessions now start in bypassPermissions instead of
the agent's always-ask "default" mode. Since the ACP permission bridge
(#2202) routes permission prompts to chat, "default" stopped behaving like
the old auto-approve path and left agents waiting on the human.

- shared: DEFAULT_AGENT_PERMISSION_MODE = 'bypassPermissions'; relabel the
  'default' mode "Manual" (Claude Code's name) so it is not mistaken for
  SAM's default
- api: the VM agent's /agent-settings callback falls back to the platform
  default (project override > user setting > default); explicit choices,
  including Manual, are unchanged
- web/acp-client: Settings -> Agents and the workspace chat settings panel
  preselect the platform default when nothing is saved
- MCP profile/skill tool text and the agents guide document the default
- tests: behavioral route test on real SQLite (replaces source-text check),
  card and chat panel unit tests, Playwright audits at 375px and 1280px

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

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: raphaeltm/simple-agent-manager/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 81fe0860-d673-4f08-9279-33c5f33c5685
📥 Commits

Reviewing files that changed from the base of the PR and between b291dce and 083cd59.

📒 Files selected for processing (17)
  • apps/api/src/routes/mcp/tool-definitions-shared-fields.ts
  • apps/api/src/routes/workspaces/runtime.ts
  • apps/api/tests/unit/project-agent-defaults.test.ts
  • apps/api/tests/unit/routes/workspace-agent-settings-callback.test.ts
  • apps/web/src/components/AgentSettingsCard.tsx
  • apps/web/src/components/ChatSession.tsx
  • apps/web/tests/playwright/agent-settings-audit.spec.ts
  • apps/web/tests/playwright/chat-settings-permission-default-audit.spec.ts
  • apps/web/tests/unit/components/agent-card.test.tsx
  • apps/web/tests/unit/components/agent-settings-card.test.tsx
  • apps/www/src/content/docs/docs/guides/agents.md
  • packages/acp-client/src/components/AgentPanel.tsx
  • packages/acp-client/src/components/ChatSettingsPanel.tsx
  • packages/acp-client/tests/unit/components/AgentPanel.test.tsx
  • packages/acp-client/tests/unit/components/ChatSettingsPanel.test.tsx
  • packages/shared/src/constants/agent-settings.ts
  • packages/shared/src/constants/index.ts
  • Autopilot · 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.

@codspeed

codspeed Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing sam/default-mode-all-agents-skdxr1 (083cd59) with main (176385d)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (b291dce) during the generation of this report, so 176385d was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

AGENT_PERMISSION_MODE_DESCRIPTIONS had no consumers. Rename a test local
that now points at the Bypass Permissions radio.

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

sonarqubecloud Bot commented Oct 4, 2026

Copy link
Copy Markdown

@simple-agent-manager simple-agent-manager Bot added the coderabbit-review Trigger CodeRabbit review for opt-in PRs label Oct 4, 2026
@raphaeltm

Copy link
Copy Markdown
Owner

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@simple-agent-manager
simple-agent-manager Bot merged commit 9ef726c into main Oct 4, 2026
54 of 55 checks passed
@simple-agent-manager
simple-agent-manager Bot deleted the sam/default-mode-all-agents-skdxr1 branch October 4, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coderabbit-review Trigger CodeRabbit review for opt-in PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant