# Approval levels Approval levels belong to a bot and apply to its next provider turn, including when that provider resumes an existing native thread. You can also change one while the bot is working (see below). Each level is one of the provider's own permission modes, passed through. A native tool request that reaches you is one the provider left for you. OpenMausBot only answers from an explicit grant: Full Access, a saved exact command or MCP read-shaped tool, the narrow built-in web-search allowance under Approve for me, or a bot reading its own files. In Full Access, OMB also applies its own configuration tools without another approval. **A bot reading its own files never asks**, at any level: its standing instructions (`SOUL.md`), its skills with every saved revision, its memory and its conversation folders. That covers a plain reading command (`cat`, `head`, `tail`, `grep`, `rg`, `sed -n`, `ls`, `wc`, `nl`, `stat`) made of plain words alone, and Claude's Read, Grep, Glob, LS and NotebookRead, when every path is inside the bot's own folders once links are followed. Anything else in the command (a pipe, a redirect, a second command, a variable, a glob) asks as before, and so does every read in a guest's turn, since a bot's folder holds its owner's memory. On a Cloud the bot's box also shows it its own `SOUL.md`, read-only. Every bot and conversation starts at **Full access**, the default T3 Code uses too: each engine runs in its own most permissive mode, and a real question or a missing credential still reaches you. That covers a bot made in New bot, through the API or by onboarding, each new thread, a Chief's new teammates, and bots imported from a team backup, a shared team file or the organization library. A level a person picks stays until someone changes it. On a hosted company workspace the default stays Ask, because Full access there comes only from the operator's dedicated policy. | Level | Behavior | | --- | --- | | **Ask for approval** | Requests approval for commands and file changes, the way the provider's supervised mode does. | | **Auto-accept edits** | Approves file edits automatically; other actions can still require approval. Offered where the provider has such a mode (Claude, Grok, Antigravity). | | **Approve for me** | Uses the provider's automatic review on Codex, Claude, Cursor, and Grok to approve routine actions and ask about others. Providers without an equivalent fall back to asking. | | **Full access** | Enables the provider's permissive mode for commands, edits, and selected-computer actions, including potentially destructive or sensitive work. Residual native permission prompts are answered for you. OMB profile changes, routine actions, team setup, bot deletion, and enabled skill authoring apply without a second approval. Peer-review prompts are skipped within the bot's authorized scope. Sends through connected apps (email, messages, posts, payments) follow the bot's Sending on your behalf setting: Ask every time requires consent, and Send without asking, or no setting at all, sends with no daily limit. Apps outside the bot's connected-app scope are still refused. Work handed on with `coordinate_bots` uses the receiving bot's setting, never the sender's — except from a Chief of Staff, whose level flows down (below). Actual questions and missing credentials still need your input. | | **Custom (`config.toml`)** | Codex only. OpenMausBot reads and reapplies the effective approval and sandbox settings from your Codex configuration. | Full access applies the moment you pick it: no confirmation dialog, no second step. It can be turned on from any client that can reach the app's API: the desktop app, a browser, a paired phone or web client, or a bot or script calling the local API where local calls count as you (development, the CLI, a self-hosted server). Picked in bot settings, it applies to the bot and every one of its existing threads at once; picked in the composer, to that thread; Refresh permissions copies it onto one thread. Every engine runs it (see Provider mappings). On a hosted company workspace, Full access still comes only from the operator's dedicated policy ([guarded messages](verification/guarded-messages.md)). Custom is different: it can only be entered or left from a packaged local desktop app, where the choice crosses a private process channel rather than the bot-accessible HTTP API, because it holds restrictions you wrote yourself. It is hidden in development, standalone web, and remote pages. ### Changing the level while the bot works You don't have to stop a bot to change its level. From the moment you pick one, every approval decision OMB makes in that conversation uses it. How far that reaches depends on who runs the tools: - **API engines** (OpenAI-compatible, Grok API, MiniMax, Mistral, Cerebras, Groq, Greenference, ModelGo, Meta): OMB's tool gate reads the level before each tool call, so the change applies from the next call, up or down. - **Engines with their own modes** (Codex, Claude, Cursor, Antigravity, Grok Build, Qwen Code, Gemini CLI, Droid, Pi's custom MCP tools): the engine got its mode when the turn started and keeps it to the end of the turn. A permission request it still sends is answered at the new level, so raising to Full access applies to the next request. Lowering from Full access, and moving between Ask, Auto-accept edits and Approve for me, applies from the next turn. - **Agents whose requests OMB answers** (OpenCode, Cline, Kimi, Hermes, custom ACP agents, Pi's computer-control confirms): every request reaches OMB, so the change applies from the next request, up or down. A request already on screen stays for you to answer, and an action already running finishes. A team change sets the level on working bots too. A department's sidebar menu has **Set for all bots in this department…**, for the owner or an admin. It sets one approval level (Ask, Auto-accept edits, Approve for me or Full access), or one model and effort, on every bot in that department. It lists what each bot will get before anything changes, then saves the bots one at a time with the same request and checks as each bot's own settings. A bot whose engine does not offer the level, model or effort, or that is working during a model change, is skipped and the summary gives the reason. A skipped bot is not changed later: once its turn ends, run the team change again or set that bot in its own settings. A level reaches each bot and every one of its threads, the same way for every level, so a thread opened with New thread moves too; a bot is "already set" only when all of its threads are. Choosing Auto for a bot on this computer shows the same warning as its own settings. Model changes keep each bot on its own engine and move the threads that use the bot's model; a thread with a model of its own keeps it, including the one open on screen (the bot's own settings, by contrast, move that thread with the bot). Custom stays a per-bot setting: a bot or thread on Custom leaves it only in the desktop app. Full access does not bypass operating system privacy controls, authentication, CAPTCHA or MFA, service permissions, or workspace/team ownership and computer-sharing grants. Full Access controls approval prompts; it does not sign in for you, enable a feature you disabled, or grant another bot access to a different workspace. The effective setting belongs to the source conversation. An existing Ask thread remains Ask even if the bot default is Full; a Full thread works without these extra prompts even if the bot default is Ask. A bot nobody has set a level on follows the default, and so does each of its threads without a level of its own. Bots and threads that saved Ask before Full access became the default keep it: choose Full access in the bot's settings, or **Set for all bots in this team…**, to move a bot and every one of its threads at once. OpenMausBot adds no review card of its own at any level: a bot's profile, working folder, model, skill, team setup and team memory changes apply at once and leave a one-line receipt with Undo, so the bot continues in the same turn. Routine requests keep their own rule until Triggers v2 replaces them, and on My Cloud a turn a guest or a webhook drove still waits for the owner. Invalid input, unavailable services, or failed writes return errors, not a request to approve again. An expired native permission request is not turned into another Allow/Deny card. A turn a webhook, a routine, or another bot started runs in the bot's level like any other turn. The decision log records that nobody was at the keyboard when such a turn asked. ### A Chief of Staff's level covers the work it delegates Teammates start at Full access like every bot, but a person may have set one lower, and switching each thread a Chief opens back up by hand was where a team's owner spent their day. So **a Chief of Staff's level flows down**. Work it hands out with `coordinate_bots` — into the work thread the Chief's conversation has with a teammate, a fresh thread with `thread: "new"`, or a thread it opened earlier, named by its id — starts at the level of the Chief conversation it came from: Auto-accept edits, Approve for me, or Full access. The teammate's thread is switched to that level, keeps it, and opens with a line saying so ("Approve for me — delegated by Clive, a Chief of Staff on Approve for me"); you can still change it in that thread. Work a Chief hands out inside a room runs at the Chief's level for that turn. It flows down every hop, not just the first: when Ada, working for Clive, hands part of it to Bea, Bea's work runs at Clive's level too ("Approve for me — delegated by Ada, from Clive, a Chief of Staff on Approve for me"), in threads and rooms alike. Each hand-off looks up its chain to the nearest Chief conversation (`server/host/delegated-level.ts`). The level is computed once when the assignment is written and recorded on it (docs/runtime-contract.md §3); the turn runs with exactly that level. It only ever raises: a teammate already on a higher level keeps it, a teammate on Custom keeps its own configuration, and a Chief handing work out from an Ask conversation passes nothing on. Every engine runs Full access, so only Auto-accept edits can be capped: a teammate on an engine without it (Codex, whose Ask already writes the workspace) stays on its own level. The teammate's own default and its other conversations do not change, and an ordinary bot's hand-off, with no Chief up its chain, still uses the recipient's setting. A consultation (`consult: true`) answers from what the teammate knows and acts on nothing, so no level travels with it. Questions and missing credentials still reach you. ## Answering a request Approve or deny requests in the conversation to let the bot continue. **Allow once** answers this request only. **Always allow this session** hands the provider its own remembered approval: Claude receives its suggested permission rules, and ACP agents such as Grok receive their `allow_always` option, or the driver repeats your answer for that exact operation until the native session ends. API models (OpenAI-compatible, MiniMax, Mistral, Grok API) have no native session, so their driver keeps the allow for that bot, that exact tool and that exact server (as launched: a changed command, URL or credential is another server, and a bridge into a VM or a Boat is new each turn) for the rest of the conversation, in memory until the server restarts. Another bot in the same room asks again. For a read-shaped tool from a configured custom MCP server, the card also offers **Always allow**. This is an explicit standing grant for that exact bot, provider instance, MCP server, tool name, and current server configuration. A different tool still asks; editing the server command, URL, headers, or credentials invalidates the grant. It is not offered for create/update/delete tools, computer control, a sandbox change, an unconfigured server, or a guest's turn. A custom MCP server controls its own tool names, so only remember tools from a server you trust. The grant applies to the bot's current and future conversations, including newly delegated work. Saved entries are visible and revocable in the bot's Access settings. The harness's own agents tools (coordinating teammates, threads, memory) never ask on Claude, Codex or API models: OpenMausBot authorizes each of those routes itself. Auto-accept edits and Ask card whatever the provider asks about. Approve for me cards whatever the provider's reviewer leaves for you, with the note "The provider requires your approval for this action." A sandbox widening is held in every level but Full. ### When the native reviewer never starts Claude Code accepts `--permission-mode auto` for every model and, when auto mode is unavailable to the session, starts in Manual without an error. On Claude Code 2.1.266 that is the case for Claude Haiku 4.5 and Sonnet 4.5, and for any organization that set `disableAutoMode`. In that session the bot asks before each action unless you have explicitly remembered that exact MCP read tool. The Claude driver reads the mode the session actually runs in from the CLI's `init` frame; when Approve for me was requested and the session runs Manual, the chat shows one notice per session naming the model. Choose a model the reviewer supports, remember the MCP reads you trust, or use Full access to stop the prompts. ### Changing a bot's engine A bot at **Full access** keeps it when you switch it to another engine: every engine runs Full access, so there is no reset to Ask and no confirmation. The bot's threads that follow its model keep their level too. **Custom** rules belong to Codex, so a Custom bot goes back to Ask before it changes engine. Switching to an engine that cannot run the bot's level (for example Auto-accept edits on Codex) still asks to choose Ask first. ### Antigravity: Ask, Edits, or Auto (full access) For Antigravity, the composer and bot settings offer **Ask for approval**, **Auto-accept edits** (its native `auto_edit` mode), and **Auto (full access)**. Auto enables native `yolo` mode and automatically approves remaining tool-permission requests for commands, edits, and computer actions, without an automatic reviewer. The composer chip reads **Auto**. This is the Full access level under another name, not a separate permission setting, applies at once like Full access, and covers every model in that Antigravity instance, including Gemini. A new Antigravity bot starts on Auto, the default. Old Antigravity `auto` / `autoApprove` settings still behave as Ask and are displayed as Ask; they never become unrestricted access on upgrade. Switching back to Ask restores prompts on the next turn. Questions and missing-credential forms still require an answer. A Chief or teammate can hand work to this bot with `coordinate_bots` without downgrading its explicit Auto (full access) grant. It does not enable Auto on any other bot. ## Asking you questions Every engine can stop and ask, and no approval level ever answers a question for you: Ask, Auto-accept edits, Auto, and Full access all leave a question card for a person. What differs per engine is only how the ask travels: | Engine family | How an ask travels | Multiple questions at once | | --- | --- | --- | | Claude Code | Structured round-trip (its own `AskUserQuestion`). In Full access the CLI does not offer that tool, so the model uses the injected `ask_user` tool | Yes — capped at 4 by the CLI, up to 6 with `ask_user` | | Codex | Structured round-trip, or an async question that does not stop the turn | Yes — up to 6 | | Grok Build | Structured round-trip (its own `ask_user_question`, sent as `_x.ai/ask_user_question`) | Yes — up to 6 | | Cursor | Structured round-trip (its own `cursor/ask_question`). Cursor accepts only option ids, so an answer in your own words goes back as a skipped question with your words as the reason | Yes — up to 6 | | Grok (API), MiniMax, OpenAI-compatible endpoints | The injected `ask_user` tool | Yes — up to 6 | | Other ACP engines (Antigravity, Gemini CLI, Qwen Code, OpenCode, …) | Option-match round-trip on the ACP permission request | One at a time — the request carries one choice set | | Pi | The injected `ask_user` tool over `extension_ui_request`; each question is its own card | Up to 6 per call, shown one after another. One pick per question, no multi-select | Codex can also ask without waiting (its `request_user_input_async` tool). The question arrives with the bot's message as the same question card, and the turn keeps working. Your answer is steered into that turn while it runs. After the turn ends, the answer is sent as your reply, like any question answered late. Older conversations may still hold a question the removed Computer engine parsed out of model-authored output rather than a real tool call. Those cards keep their "Agent-composed question" badge, and their decision-log rows keep `origin: output`. Flat clients (notifications, older companion builds) see plain buttons only when a card asks a single choice question; a multi-question card renders its structured form on current apps instead. ## Provider mappings | Provider | Ask | Auto-accept edits | Auto | Full access | | --- | --- | --- | --- | --- | | Codex | `on-request` approvals, `workspace-write` sandbox, you review | not offered (Ask already writes in the workspace) | same sandbox, native `auto_review` reviewer | `never` approvals, `danger-full-access` sandbox | | Claude | Native `default` | Native `acceptEdits` | Native `auto` | Native `bypassPermissions` | | Cursor | Native default | not offered | Native `--auto-review` | Native `--force` | | Antigravity | Native `default` | Native `auto_edit` | Legacy `auto` behaves as Ask; UI Auto selects Full access | Native `yolo` plus automatic approval of remaining tool-permission requests; shown as Auto | | Grok Build | Native `default` | Native `acceptEdits` | Native `--permission-mode auto`; availability of Grok's reviewer depends on its feature rollout | Native `bypassPermissions` plus automatic approval of remaining tool-permission requests | | OpenCode | Ask | not offered | Ask | Approve individual ACP permission requests, never task questions | | Qwen Code | Native `default` | Native `--approval-mode auto-edit` | Native `--approval-mode auto` (Qwen's LLM classifier approves safe actions, blocks risky ones) | `--yolo`, plus automatic approval of remaining ACP permission requests | | Gemini CLI | Native `default` | Native `--approval-mode auto_edit` | Ask (no reviewer) | `--yolo`, plus automatic approval of remaining ACP permission requests | | Cline | `--auto-approve false`, you review | not offered | Ask (no reviewer) | Approve individual ACP permission requests, never task questions | | Droid | Session mode `normal` (reads only) | not offered | Ask (no reviewer) | Session mode `auto-high`, plus automatic approval of remaining ACP permission requests | | Kimi, Hermes, custom ACP agents | The agent's own default | not offered | Ask (no reviewer) | Approve individual ACP permission requests, never task questions | | Pi | Pi's own tools run; computer control and custom MCP tools ask | not offered | Ask (no reviewer) | Custom MCP tools run without asking; computer-control confirms are approved | | API engines (OpenAI-compatible, Grok API, MiniMax, Mistral, Cerebras, Groq, Greenference, ModelGo, Meta) | OMB's tool gate asks | not offered | Ask (no reviewer) | OMB's tool gate approves each call | These settings apply on each turn, including resumed conversations. Switching to a different provider while on Custom requires leaving Custom first; choose Ask. Switching models within Antigravity keeps the selected level. Native modes require a CLI version that supports them; OpenMausBot does not silently substitute unrestricted access when a mode is rejected. ### Read-only integration tools OpenMausBot's built-in agents MCP server describes its scoped reads with explicit read-only, non-destructive, idempotent, closed-world metadata: `list_bots`, `list_rooms`, `list_threads`, `assignment_status`, `session_search`, `trigger_info`, and `skills_list`. Session recall still enforces own-bot access and records its existing room disclosure audit. These hints do not grant access to another bot's conversations. Writes, credential requests, proposals, and third-party tools do not inherit these hints. The metadata is available to every engine using this integration; whether an engine consumes it remains that engine's behavior. Arbitrary MCP display titles or `readOnlyHint` claims from a third-party server are not authorization to bypass a prompt. The level set follows the provider-boundary approach in [T3 Code's permission modes](https://github.com/pingdotgg/t3code/blob/e16b8b059c9f5ff6dfed1addecffb831c6aee043/docs/user/permission-modes.md): Supervised, Auto-accept edits, Auto, and Full access, each a provider mode rather than an app rule, with a remembered approval that belongs to the provider's session. Its default is Full access, and so is OpenMausBot's (`DEFAULT_APPROVAL_MODE` in `shared/approval-mode.ts`). ## Verification for contributors The [Full Access workflow recipe](verification/full-access.md) tests immediate profile, routine, team, skill, and peer actions through the real server and MCP proxy. Its fixture also verifies that explicit Ask sibling threads still wait. Run `pnpm exec electron scripts/smoke-approval-modes.cjs` to exercise the real private desktop-to-server grant protocol in a disposable fixture. It verifies that Full access applies over HTTP while Custom is refused there, Full → Auto → Ask on resumed Claude turns, and Antigravity automatic tool approvals on new and resumed Full access turns across multiple model variants. It also checks that Ask and legacy Auto still prompt, peer-started Full turns auto-approve, switching the receiving bot back to Ask restores prompts even for a Full-access sender, delegated Codex Custom uses the native Auto reviewer consistently, and questions remain interactive. Provider processes are scripted fakes; this does not verify live account eligibility or the quality of a provider's automatic reviewer. No live user data is used. Grok coverage exercises two model selections across fresh/resumed Auto turns, real built-in MCP reads under a scripted native reviewer, returning to Ask, and held deletion, credential, spoofed-title command, and question requests.