For AI agents: a documentation index is available at https://docs.plungeai.com/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://docs.plungeai.com/agents.md. One ozk_ key opens every plane, models included.

Documentation Index: fetch the complete documentation index at /llms.txt. Use this file to discover all available pages before exploring further.

Every tool call in a loop is classified, then decided. One function makes the decision, so every door (Studio, REST, MCP, the CLI, the scheduler) gets the same answer, and the rung that decided is written to the run's audit row.

Classes and presets

A call has one of five classes: read, write, send, delete or pay (how each tool gets its class is on Tools). The permissions map on a task, and the stored presets on a saved bot, give a class or a tool name one preset:

PresetEffect
allowThe call runs.
askThe run pauses for approval.
denyThe call does not run; the model gets an error that names the reason.
hand_offA deny that does not retry. The call never runs, and the run's result carries a [handed off to you — not run: …] line so the owner knows it is theirs to do. A hand-off does not count toward the denial breaker.

A preset this build does not recognise is treated as ask, never allow. hand_off is understood only by One Agent; for any other agent the engine rewrites it to deny.

The decision order

The first rung that applies decides:

  1. Posture read_only: write, send, delete and pay are denied. So are delegate, invoke_workflow and every MCP tool, and any tool with an unknown class (fail closed).
  2. Explicit deny: on the tool's name or on its class. Posture adds a class deny on every mutating class.
  3. hand_off.
  4. The money floor: an operation in the always-gated set (buy, purchase, pay, transfer, send, send_payment, withdraw, fetch_paid, shop) is always ask. No allow lowers it, and it pauses the run even when unattended.
  5. The preset: the tool's own entry, then its class entry. Anything other than allow asks.
  6. An admin lock: a locked class lifts allow to ask. It never lifts a deny.
  7. Otherwise allow.

The presets on the task and the presets stored on the saved bot are merged before the run starts: the task's own entries win per class, the bot's locks replace what the YAML carried, and the lower per-run budget wins. See Permissions and budget.

Posture

posture: read_only makes a run safe to point at the open web. A bot's own permissions cannot lift it, and an admin lock never turns a deny into an allow. The browser tool still reads pages under it. Any value other than read_only is forced to read_only: a typo never widens a run.

Review

review: auto adds one model call that reviews each write, send, pay or delete call the permissions allowed. It answers allow, ask the owner (the normal approval pause) or deny (a tool error that names the reason). A reviewer error asks and never allows. Three denials in a row stop the run with stop_reason: review. It costs one model call per gated action. Any other value is forced to auto.

The denial breaker

Three denied calls in a row, with no executed call between them, stop an unattended run with stop_reason: denied. An interactive run pauses and asks the person how to proceed. Any executed call resets the count.

Secrets stay out of results

Tool results, spilled files, the outcome of an approval and the saved result pass through a redactor first. JWTs, bearer tokens and sk- or ozk_ keys become [REDACTED:<type>]. Card numbers, IBANs and email addresses pass, because they are the owner's own data.

Untrusted content

Text someone else wrote is data, not instructions. The results of web_search, web_fetch, browser, message_bot, every mcp__* tool and call_agent calls to search, MCP or scraping agents are scanned for instruction patterns. A result that matches is wrapped in an <untrusted-content> marker listing the patterns it carries; a clean result is returned as it is. Either way the run is marked tainted. Today the taint is recorded in the audit trail only: a later write or send call writes a row saying it would have been asked, and nothing is blocked because of it. code results are not treated as untrusted.

web_fetch refuses private and link-local addresses.

Other run limits

LimitKeyStops with
Spend per runbudget_usd_runstop_reason: budget
Wall-clock timemax_runtime_sstop_reason: timeout
Turnsmax_iterationsthe turn cap

Cancelling a run also cancels the child runs it started with delegate or message_bot wait: true, and the OceanCode sessions it started with code.

Planned: TI-33

Search is not available yet. Until it ships, use the page index or browse the sidebar.

Planned: TI-34

The docs assistant is not available yet. You can hand these docs to your own assistant instead.