Skip to main content
ollim-bot controls which tools the agent can use through a permission system. You choose a permission mode, and the bot enforces it — from silent denial of unapproved tools all the way to full bypass.

Permission modes

Switch modes with the /permissions slash command or persistently with /config permission_mode.
ModeBehavior
dontAskSilent denial of tools not in the session-allowed set. No prompt. Default.
defaultDiscord message with reaction buttons for each tool use.
acceptEditsFile edits and filesystem commands (mkdir, touch, rm, mv, cp) auto-approved, others prompt.
bypassPermissionsAll tools auto-approved in the main session, no prompts. Background forks still use their own tool restrictions.

Persistence

/permissions changes the mode for the current session only — it resets to the default (dontAsk) on restart. Use /config permission_mode to persist the mode across restarts.

Fork scoping

Permission modes are fork-scoped — changing the mode inside an interactive fork leaves the main session unchanged once the fork exits. Note that dontAsk uses a module-level flag, so switching to or from dontAsk in a fork temporarily affects the main session during the fork. The original mode is restored when you exit the fork.

Approval flow

In default mode, unapproved tool use triggers an interactive approval prompt in your Discord DM. (acceptEdits auto-approves file edits and filesystem commands, and bypassPermissions approves everything in the main session — neither triggers the approval flow below.)
1

Agent requests a tool

The agent attempts to use a tool that isn’t in the session-allowed set.
2

Bot sends an approval message

A message appears in your DM showing the tool label (name + arguments). Three emoji reactions are added automatically.
3

You react

React with one of the three emojis to respond:
ReactionEffect
Allow — approve this single tool use
Deny — reject this tool use
🔓Always — approve and add the tool to the session-allowed set
4

Result is applied

The approval message is edited to show the outcome (allowed, denied, or always allowed), and the agent proceeds or receives a denial.
Approvals time out after 60 seconds. An unanswered prompt is treated as a denial, and the message is edited to show expired.

Session-allowed set

When you react with 🔓 (Always), the tool is added to a session-allowed set. Future uses of that tool are auto-approved without prompting — even in dontAsk mode.
  • The session-allowed set is shared across the main session and interactive forks.
  • /clear resets the session-allowed set (and cancels any pending approvals).
  • The set is in-memory only — it does not persist across bot restarts.

Background forks

Background forks always run with permission_mode="default" — regardless of your main session’s setting. Even if you’ve set bypassPermissions or acceptEdits, background forks don’t inherit that mode. This ensures tool gating and ping budget enforcement are always active for background tasks. Beyond permission mode, background forks have their own tool restrictions based on the job’s YAML configuration:
  • Ping tools (ping_user, discord_embed) — allowed only when allow-ping is true in the job’s YAML
  • Reporting tools (report_updates, follow_up_chain) — allowed unless update-main-session is blocked
All other tools not in the fork’s allowed-tools list are denied. The agent in a background fork cannot trigger approval prompts — see Background forks for details.

Deny messages

The deny message varies by context so the agent understands why a tool was blocked:
SituationDeny message
Background fork (pings disabled)"pings disabled for this job"
Background fork (reporting blocked)"reporting blocked for this job"
Background fork (other tools)"{tool} is not available in background forks"
dontAsk mode (not session-allowed)"{tool} requires permission — denied silently in current mode"

State directory write-protection

The state/ directory under ~/.ollim-bot/ contains infrastructure files — session IDs, credentials, ping budget, and runtime config. These files are managed by ollim-bot itself, not by the agent. The agent can read files in state/ but cannot modify them. Any write or edit attempt targeting state/ is automatically denied — this applies in the main session, interactive forks, and background forks.
Protection is enforced at two layers:
  1. Tool hook — a pre-execution hook intercepts Write and Edit calls. If the target path falls inside state/, the call is denied with "state/ is write-protected".
  2. Pattern validation — tool patterns are validated at startup and dispatch time. Patterns that could match the state/ directory (like Edit(**)) are rejected before the job runs.

Customizing tool sets

Both the main session and background forks start with hard-coded default tool sets. You can extend — or, for background forks, completely replace — those defaults by creating a tool-policy.yaml file in ~/.ollim-bot/. The file is optional. When it doesn’t exist, the built-in defaults apply. Changes take effect without a restart — the file is re-read when its modification time changes.

Keys

KeyTypeEffect
main_session.additional_allowedlist[str]Merged into the main session’s default tools. Duplicates are ignored.
bg_forks.additional_allowedlist[str]Merged into the default background fork tools. Duplicates are ignored.
bg_forks.overridelist[str]Replaces the default background fork tools entirely. Takes precedence over additional_allowed.
bg_forks.override removes all default tools — including read-only helpers like Read(./**.md). Use additional_allowed unless you need full control over the background fork tool set.

Example

A minimal tool-policy.yaml that adds git status to the main session and calendar access to background forks:
~/.ollim-bot/tool-policy.yaml
main_session:
  additional_allowed:
    - "Bash(git status)"

bg_forks:
  additional_allowed:
    - "Bash(ollim-bot cal *)"

Agent-managed additions

When the agent creates a routine that needs tools beyond the defaults, it can either add allowed-tools to the routine’s YAML frontmatter (scoped to that job) or append to bg_forks.additional_allowed in tool-policy.yaml (applies to all background forks). See File formats for the full key reference.

Visual feedback

Inline labels during streaming show what the agent is doing — and what got blocked. When dontAsk mode or an explicit rejection denies a tool, the label shows with strikethrough text:
OutcomeRendering
Approved/executed-# *Read(reminders/foo.md)*
Denied-# *~~Read(reminders/foo.md)~~ — denied (use /permissions ask to approve)*
Errored-# *~~Read(reminders/foo.md)~~ — error*
In dontAsk mode, the stream shows denied tools with strikethrough so you see what the agent tried without receiving approval prompts. In default mode, tools you reject via the ❌ reaction also appear struck through. Tools that fail during execution also render with strikethrough and an ” — error” suffix.

Cancellation

Pending approval prompts are automatically cancelled (treated as denials) when any of the following occur:
  • You use /clear — resets the session-allowed set and cancels all pending approvals
  • You interrupt the agent — cancels pending approvals for the current turn
  • You exit an interactive fork — cancels any approvals pending inside the fork
Cancelled prompts are deleted to avoid orphaned messages in the channel.

Examples

In dontAsk mode, any tool not in the session-allowed set is silently denied — no message appears.
/permissions dontAsk
This is the default. The agent operates autonomously within its allowed toolset without interrupting you for approvals.

Next steps

Slash commands

Full reference for all slash commands including /permissions.

Forks

How interactive and background forks interact with permission scoping.

Discord tools

Reference for all Discord tools the agent can use.

Background forks

Tool restrictions and allowed tool configuration for background forks.