Skip to main content
Background forks run agent tasks on disposable sessions that don’t pollute your main conversation. Routines with background: true and all reminders (which default to background) execute this way — the agent does its work, optionally pings you or reports findings, and the fork is discarded.

Overview

When a background routine or reminder fires, the bot creates a temporary session. The agent’s text output is discarded — it communicates only through notifications, embeds, and reporting to the main session. After the task completes (or times out — default 30 minutes, configurable via /config bg_fork_timeout), the session is thrown away. Background forks run concurrently with your main conversation and with other background forks — they never interrupt what you’re doing.
Each background fork can send at most 1 non-critical notification. When you’re mid-conversation, non-critical notifications are blocked and the agent reports findings to the main session instead. critical: true bypasses all limits — per-session cap, busy state, and ping budget.

Execution modes

Background forks support two execution modes that determine how the agent session is created.
The default mode branches from your current main session. The agent has access to your full conversation history and context.
routines/daily-review.md
---
id: daily-review
cron: "0 9 * * 1-5"
background: true
description: Morning task review
---
Check my Google Tasks and calendar for today.
Ping me with a summary if there's anything actionable.
Forked mode is best when the task needs conversational context — the agent knows what you’ve been working on and can make informed decisions.
FieldDefaultDescription
isolatedfalseNo conversation history instead of forking
modelModel override (works in both forked and isolated modes)
thinkingtrueExtended thinking override

Communication

Background forks have two output channels: pinging (sending a visible Discord message) and reporting (queueing a summary for the main session). These are controlled independently.

Pinging

The agent’s text output is discarded. To reach you, it must call ping_user (plain text) or discord_embed (rich embed). These calls are subject to the ping budget — each non-critical ping consumes one token from the budget. ping_user is background-fork-only; discord_embed is available in all contexts. See Discord tools for full parameter reference. Set allow-ping: false to disable both tools entirely. Unlike the ping budget, this is absolute — critical: true does not bypass it. Use this for tasks that should never produce visible output.

Reporting to the main session

The report_updates tool queues a short summary to ~/.ollim-bot/state/pending_updates.json. These updates are prepended to the next main session interaction, giving the agent context about what happened in the background. The update-main-session field controls when and whether the agent must report:
ModeBehaviorEnforcement
on_pingReport if a ping or embed was sentTask blocked until reported
alwaysMust report regardlessTask blocked until reported
freelyReporting is optionalNone
blockedReporting disabledreport_updates and follow_up_chain unavailable
Use update-main-session: always for tasks where the main session needs the outcome regardless of whether a ping was sent — like checking if a deadline passed.
When update-main-session is blocked and allow-ping is true, the agent is told: no summary is passed to the main session (the main conversation won’t know this task ran), but you can still ping the user directly on Discord for time-sensitive items. This combination is useful for tasks that should notify the user when needed but don’t need to feed context back to the main session.

Permission mode

Background forks always run with permission_mode="default" — they never inherit the main session’s permission mode. Even if you’ve set bypassPermissions or acceptEdits on the main session, background forks are unaffected. This ensures tool gating and ping budget enforcement can’t be bypassed by background tasks. See Permissions for the full permission model.

Tool restrictions

Background forks have limited tool access for safety — the agent can only use a set of default tools plus any you explicitly add.
FieldDefaultDescription
allowed-toolsDefault toolsAdditional tools merged with the defaults

Default tools

Every background fork can read documentation files and run ollim-bot CLI commands. These tools are always available:
  • Bash(ollim-bot help)
  • Bash(ollim-bot tasks *)
  • Read(./**.md)
  • Glob(./**.md)
  • Grep(./**.md)
  • mcp__discord__add_reminder
  • mcp__discord__list_reminders
  • mcp__discord__cancel_reminder
Pinging and reporting tools (ping_user, discord_embed, report_updates, follow_up_chain) are controlled separately by the job’s allow-ping and update-main-session flags — see Communication above and Permissions for details.

Adding tools

List additional tools in allowed-tools using the same format as the defaults above. You only need to list tools beyond the defaults — anything already in the default list is ignored:
routines/email-check.md
---
id: email-check
cron: "0 8,12 * * 1-5"
background: true
isolated: true
model: haiku
allowed-tools:
  - "Bash(ollim-bot gmail *)"
description: Email check (restricted tools)
---
Check Gmail for unread messages from today.
Send an embed summary if anything needs attention.
Don’t list Discord tools — ping_user, discord_embed, report_updates, or follow_up_chain — in allowed-tools. The bot strips them automatically and controls their availability through allow-ping and update-main-session instead.
Chain reminders inherit tool restrictions — follow_up_chain propagates allowed-tools and skills to child reminders automatically.

Pattern validation

The bot validates allowed-tools patterns at startup and again when each job fires. Unsafe patterns are rejected and the job is skipped:
PatternResult
Bash(*)Error — too broad, specify a command prefix
Bash(ollim-bot gmail * ; rm -rf /)Error — command chaining blocked
Edit(**)Error — matches paths inside the protected state/ directory
If a pattern fails validation, the bot logs the error so you can fix it.

Configuration

All background fork fields available in routine and reminder YAML frontmatter:
FieldTypeDefaultDescription
backgroundboolfalse (routines), true (reminders)Run as a background fork
isolatedboolfalseFresh session, no history
modelstringModel override
thinkingbooltrueExtended thinking override
update-main-sessionstringon_pingalways, on_ping, freely, blocked
allow-pingbooltrueAllow pings. critical does not bypass.
allowed-toolslist[string]Additional tools merged with default tools
skillslist[string]Skills to load at fire time

Examples

A fully configured background routine with all options:
routines/accountability-checkin.md
---
id: accountability-checkin
cron: "30 14 * * 1-5"
background: true
isolated: true
model: haiku
thinking: false
update-main-session: always
allow-ping: true
description: Afternoon accountability check-in
---
Check my Google Tasks for items due today.
If anything is overdue or due within 2 hours, ping me.
Always report what you found.
A silent background routine that only reports to the main session:
routines/quiet-sync.md
---
id: quiet-sync
cron: "0 7 * * *"
background: true
allow-ping: false
update-main-session: always
description: Silent morning context sync
---
Check my calendar and tasks for today.
Report a summary to the main session — do not ping.
A background reminder with chain follow-ups:
reminders/take-medication.md
---
id: take-medication
run-at: "2026-02-24T09:00:00-08:00"
max-chain: 3
update-main-session: freely
description: Medication reminder
---
Remind me to take my medication.
If I haven't acknowledged, schedule a follow-up in 30 minutes.

Next steps

Ping budget

How the refill-on-read budget controls background fork pinging.

Routines

Recurring cron-scheduled routines that trigger background forks.

Reminders

One-shot and chainable reminders with follow-up chains.

Real-world examples

Background routine examples with conditional silence, model overrides, and no-ping patterns.