Bots
Bot playbook reference
Every key a One Agent bot reads, one row each: its type, its default, what it does and which door sets it.
Every key a One Agent bot reads, one row each. This page is generated from the playbook reference template, scripts/bot-templates/bot-playbook-reference.yaml, so the table and the template cannot disagree. Copy the lines you need into the harness task of a bot and delete the rest; the order of keys does not matter.
The keys posture, peers, review, max_runtime_s and workspace apply only on agent: one-agent; saving them on another loop runtime is refused. See Bots.
Doors
| Door | What it is |
|---|---|
| YAML | Any door that saves the bot's YAML: Studio's Code tab, POST /v1/workflows and PATCH /v1/workflows/{id}, MCP plungeai_workflow create and update, ocean-cli workflows create and update. |
| Studio | The bot-config block of Studio's Think tab, which writes these keys into the YAML for you; the bot's Settings panel edits some of them too. |
| Stored policy | The permission presets and the spend cap stored on the saved bot: PUT /v1/workflows/{id}/permissions, MCP permissions_set, ocean-cli workflows permissions set, and Studio's Permissions and Budget fields. They are merged with the YAML on every run (Permissions and budget). |
Keys
| Key | Type | Default | What it does | Set by |
|---|---|---|---|---|
type | string | none, required | A bot is exactly one task of type harness (a mission-bounded loop run). | YAML |
id | string | none, required | The task id; the run's result is stored under it. | YAML |
agent | string | harness-agent on a task with no agent line | The runtime that runs the loop; only one-agent reads the bot keys below. | YAML |
goal | string | none, required | What this run is asked to do; {input} is replaced by the run's input. | YAML |
mission | string | none, required | The standing instructions (system prompt); end it by telling the bot to call task_complete. | YAML |
workspace | string | bot for a saved bot | bot keeps the bot's virtual files across runs; run starts every run clean. | YAML, Studio |
posture | string | unset (not read-only) | read_only denies every write, send, delete and pay (and delegate, invoke_workflow, MCP tools) whatever permissions says. | YAML, Studio |
peers | list | none (no 1:1 messaging) | The only bots, or a2a:<url> agents, that message_bot may reach by name or id; a group:<name> send needs no peers. | YAML, Studio |
review | string | unset (no review) | auto has a model check each allowed write, send, delete or pay call before it runs (one extra call each). | YAML, Studio |
max_runtime_s | number | unset (no cap beyond the turn cap) | Wall-clock cap in seconds for the whole run; the run stops with stop_reason timeout. | YAML, Studio |
budget_usd_run | number | unset (no cap); a lower cap stored on the saved bot wins | Per-run spend cap in USD, above 0 (blank = no cap; 0 is refused by the YAML block and Settings, and the runtime ignores a non-positive stored value); the loop stops at the next turn once cost passes it. | YAML, Stored policy |
permissions | map | allow, except the money floor which always asks | Per-class or per-tool presets for send, write, pay and delete; reads are allowed unless you name read or the tool. | YAML, Stored policy |
permissions.send | string | allow, but a registry-agent call with operation send is always gated (ALWAYS_GATED) even with send: allow | Preset for outward messages (email, chat, message_bot); ask pauses the run for the owner's approval. | YAML, Stored policy |
permissions.write | string | allow | Preset for calls that change something (files, schedule create, browser clicks). | YAML, Stored policy |
permissions.pay | string | allow, but payment ops always ask | hand_off never runs the call and tells the owner it is theirs to do; the result ends with a [handed off to you] line. | YAML, Stored policy |
permissions.delete | string | allow | Preset for destructive calls; deny refuses them. | YAML, Stored policy |
allowed_tools | list | every tool of the runtime on agent one-agent (universal-agent's default is the 8-tool DEFAULT_FENCE); list tools to narrow it | The tool fence; only these tools reach the model and task_complete must be in it. | YAML, Studio |
allowed_tools.schedule | tool name | available when allowed_tools is absent; name it to keep it in a narrowed fence | The bot schedules itself (create, list, pause, resume, delete, run_now, wake); needs a saved bot. | YAML, Studio |
allowed_tools.message_bot | tool name | available when allowed_tools is absent; name it to keep it in a narrowed fence | Sends to a peer or group:<name> (async by default, replies arrive as [MESSAGE from ...] in a later run); needs a saved bot. | YAML, Studio |
allowed_tools.browser | tool name | available when allowed_tools is absent; name it to keep it in a narrowed fence | Drives a cloud browser in one session, with the bot's saved login (click and type count as writes). | YAML, Studio |
allowed_tools.memory | tool name | available when allowed_tools is absent; name it to keep it in a narrowed fence | Add, replace, remove, read, or forget {query} to purge matching entries. | YAML, Studio |
allowed_tools.code | tool name | available when allowed_tools is absent; name it to keep it in a narrowed fence | Hands one turn (max 300 s) to the owner's OceanCode over the Local Tunnel; no daemon connected means no tool. | YAML, Studio |
allowed_agents | list | all except payment agents | The registry agents call_agent may reach (payment agents only when named). | YAML |
skills | list | none | Registry skill ids injected into the system prompt, at most 5. | YAML, Studio |
persona | string | none | One persona id that sets the voice. | YAML, Studio |
max_turns | number | the effort preset's cap, else the runtime's own | Turn cap for the loop (max_iterations is the legacy spelling). | YAML, Studio |
effort | string | unset | quick, standard or deep sets the default turn cap and how wide the bot works. | YAML |
The whole file
# Playbook reference: every key a one-agent bot reads, set once, with one comment line above it.
# Each comment reads "what it does. Default: what you get when the key is absent."
# Copy the lines you need and delete the rest. Order in a real bot does not matter.
workflow:
name: "Playbook Reference"
description: "Every one-agent bot key, set and explained in comments. Copy the lines you need."
tasks:
# type: a bot is exactly one task of type harness (a mission-bounded loop run). Default: none, required.
- type: harness
# id: the task id; the run's result is stored under it. Default: none, required.
id: reference
# agent: the runtime that runs the loop; only one-agent reads the bot keys below. Default: harness-agent on a task with no agent line.
agent: one-agent
# goal: what this run is asked to do; {input} is replaced by the run's input. Default: none, required.
goal: "{input}"
# mission: the standing instructions (system prompt); end it by telling the bot to call task_complete. Default: none, required.
mission: |
You are Playbook Reference, a bot that exists to show every bot key in its own YAML.
What each key does is written as a comment in that YAML, which you cannot see, so
never explain a key from memory. Reply with REFERENCE-OK, a one-line echo of the
goal, and the sentence "Read the comment above each key in this playbook."
Your persona only sets the voice; this reply format always wins.
When your task is finished, call the task_complete tool with your reply.
# workspace: bot keeps the bot's virtual files across runs; run starts every run clean. Default: bot for a saved bot.
workspace: bot
# posture: read_only denies every write, send, delete and pay (and delegate, invoke_workflow, MCP tools) whatever permissions says. Default: unset (not read-only).
posture: read_only
# peers: the only bots, or "a2a:<url>" agents, that message_bot may reach by name or id; a group:<name> send needs no peers. Default: none (no 1:1 messaging).
peers: ["Playbook Peer"]
# review: auto has a model check each allowed write, send, delete or pay call before it runs (one extra call each). Default: unset (no review).
review: auto
# max_runtime_s: wall-clock cap in seconds for the whole run; the run stops with stop_reason timeout. Default: unset (no cap beyond the turn cap).
max_runtime_s: 300
# budget_usd_run: per-run spend cap in USD, above 0 (blank = no cap; 0 is refused by the YAML block and Settings, and the runtime ignores a non-positive stored value); the loop stops at the next turn once cost passes it. Default: unset (no cap); a lower cap stored on the saved bot wins.
budget_usd_run: 1
# permissions: per-class or per-tool presets for send, write, pay and delete; reads are allowed unless you name `read` or the tool. Default: allow, except the money floor which always asks.
permissions:
# permissions.send: preset for outward messages (email, chat, message_bot); ask pauses the run for the owner's approval. Default: allow, but a registry-agent call with operation send is always gated (ALWAYS_GATED) even with send: allow.
send: ask
# permissions.write: preset for calls that change something (files, schedule create, browser clicks). Default: allow.
write: allow
# permissions.pay: hand_off never runs the call and tells the owner it is theirs to do; the result ends with a [handed off to you] line. Default: allow, but payment ops always ask.
pay: hand_off
# permissions.delete: preset for destructive calls; deny refuses them. Default: allow.
delete: deny
# allowed_tools: the tool fence; only these tools reach the model and task_complete must be in it. Default: every tool of the runtime on agent one-agent (universal-agent's default is the 8-tool DEFAULT_FENCE); list tools to narrow it.
allowed_tools: [web_search, web_fetch, memory, schedule, message_bot, browser, code, task_complete]
# allowed_tools.schedule: the bot schedules itself (create, list, pause, resume, delete, run_now, wake); needs a saved bot. Default: available when allowed_tools is absent; name it to keep it in a narrowed fence.
# allowed_tools.message_bot: sends to a peer or group:<name> (async by default, replies arrive as [MESSAGE from ...] in a later run); needs a saved bot. Default: available when allowed_tools is absent; name it to keep it in a narrowed fence.
# allowed_tools.browser: drives a cloud browser in one session, with the bot's saved login (click and type count as writes). Default: available when allowed_tools is absent; name it to keep it in a narrowed fence.
# allowed_tools.memory: add, replace, remove, read, or forget {query} to purge matching entries. Default: available when allowed_tools is absent; name it to keep it in a narrowed fence.
# allowed_tools.code: hands one turn (max 300 s) to the owner's OceanCode over the Local Tunnel; no daemon connected means no tool. Default: available when allowed_tools is absent; name it to keep it in a narrowed fence.
# allowed_agents: the registry agents call_agent may reach (payment agents only when named). Default: all except payment agents.
allowed_agents: [google-gmail]
# skills: registry skill ids injected into the system prompt, at most 5. Default: none.
skills: [web-search]
# persona: one persona id that sets the voice. Default: none.
persona: richard-feynman
# max_turns: turn cap for the loop (max_iterations is the legacy spelling). Default: the effort preset's cap, else the runtime's own.
max_turns: 8
# effort: quick, standard or deep sets the default turn cap and how wide the bot works. Default: unset.
effort: quick