OceanCode
Work modes
A work mode decides how agents work together on your prompt. There are three answers to "who decides?":
- The model — Model, the default. The model decides on its own whether to work alone, call sub-agents or run a workflow. This is OceanCode as it was before work modes: every tool is offered, any sub-agent type may be called, nothing is added to the prompt, there are no new limits and no badge.
- Jev — Auto. Once per prompt, Jev picks one of the modes below; when it cannot, simple rules pick.
- You — one of seven diagrams: Solo, Delegate, Pair, Pipeline, Orchestrate, Goal, Race.
Nothing needs setting up. Until you pick another mode, nothing changes.
Picking a mode
F4 or /mode opens the picker: the modes on the left with the highlighted one's description under them, its
picture and cost on the right. Model is first; the configured default (Model unless your config's mode names
another) is tagged default; your own diagrams follow a ── custom ── divider.
| Key | What it does |
|---|---|
↑ / ↓ (k / j) | Move. The picture follows at once. |
Enter | Use this mode for this session. |
d | Make it the current agent's default: writes agents.<id>.mode to your user oceancode.json (the footer names the agent: d: default for Build). |
e | Copy a built-in to .oceancode/modes/<id>-copy.jsonc to edit (toast: Copied to <path>). |
Esc | Close without a change. |
Typed forms: /mode <id> sets this session's mode, /mode default clears it. The toast reads Mode: <label>; an
unknown id is refused with the list of known ones (crates/ocean-acp/src/extensions/mode.rs:98).
Which mode a session runs, first match wins (crates/ocean-session/src/run/mode.rs:55):
- the session's own pick (
Enter,/mode <id>); agents.<id>.modefor the session's agent (d, or F2 › Agent defaults);- the
modekey inoceancode.json; model.
workflows.orchestrate: "always" with no mode set is read as mode: "goal", and logs that once. A sub-agent always
runs under its lead's mode; /mode on a sub-agent's session is refused.
agents.<id>.mode in oceancode.json is the work mode. It is not the mode: line of an agent's markdown file, which
says where the agent may run (primary, subagent, all). A config row that sets "mode": "subagent" names no
diagram, so that agent runs Model, with a log line.
The badge. Every mode but Model shows a badge on the prompt's top border: solo, delegate ≤4, pair,
pipeline, orchestrate ≤8, goal, race ×3. Auto shows auto until its first pick, then the pick and why:
auto → goal · Jev 0.82 or auto → model · rules: default (crates/ocean-protocol/src/diagram.rs:590). Model
shows no badge, so the border looks as it always did.
The modes
Model, Solo, Delegate, Pair and Orchestrate are lead modes: your prompt is an ordinary turn, and the mode only
shapes what the lead may do. Pipeline, Goal and Race are script modes: each prompt you type becomes the task of a
workflow run. The turn answers at once (race ×3 — started run <id>) and the result arrives later in the session.
Delegate, Pair and Orchestrate also add a short block to the lead's prompt naming the agents it may call and the
limits.
Model — the model decides
you
│
┌─────────▼──────────┐
│ Lead ✎ │
│ decides: alone, │
│ sub-agents or a │
│ workflow │
└─────────┬──────────┘
▼
youNothing is added or hidden, on any provider. Sub-agents may nest 4 deep, as before; only numbers you set in
subagent.max_* limit it further.
Auto — Jev picks per task
you
│
◇ Jev picks a diagram
│ (the rules, if Jev is off)
▼
the picked diagram runsSee Auto below.
Solo — one agent does everything
you
│
┌─────────▼──────────┐
│ Lead ✎ │
│ reads · edits · │
│ runs the tests ↺ │
└─────────┬──────────┘
▼
youOne model, one context. The lead is not offered task, send_subagent_message or workflow, and works off its
plan until every row is done. For small or tightly connected changes. Cost ≈ 1×.
Delegate — a lead that calls helpers
you
│
┌───────▼───────┐
│ Lead ✎ │
└───────┬───────┘
┌────────────┼────────────┐
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ explore │ │ general │ │ review │
└─────────┘ └─────────┘ └─────────┘The lead does the work and sends side questions to helpers, which return evidence (path:line). task takes only
these three types; another is refused with mode Delegate allows: explore, general, review. Up to 4 at once. For
everyday work. Cost ≈ 1.2–2×.
Pair — the lead decides, one builder writes
you
│
┌──────▼─────┐ spec ┌────────────┐
│ Lead │────────▶│ builder ✎ │
│ decides, │◀────────│ edits, runs│
│ reads diff │ diff │ the checks │
└──────┬─────┘ └────────────┘
│ optional
┌────▼────┐
│ explore │
└─────────┘The lead never edits (edit, write, apply_patch and hashline are taken away). It writes a change spec, one
builder edits and runs the checks, and the lead reads the diff and accepts it or sends corrections. The builder keeps
its context between hand-offs; a second running builder is refused (bound: max_builder 1/1). For a strong thinker
with a faster, cheaper coder. Cost ≈ 1.3–2×.
Pipeline — spec, your approval, build, review
you
┌─────────▼─────────┐
│ Spec · explore │
└─────────┬─────────┘
◇ you approve
┌─────────▼─────────┐
│ Build ✎ · builder │◀─┐
└─────────┬─────────┘ │ fix list
┌─────────▼─────────┐ │ ↺ ≤ 2
│ Review · review │──┘
└─────────┬─────────┘
▼ youFixed stages, each its own agent. Nothing is built until you approve the spec in a question card; review findings go back to the builder at most twice. For features where the spec should be agreed first. Cost ≈ 1.5–3×.
Orchestrate — a workflow per task
you
│
┌─────▼──────┐
│ Lead │
└─────┬──────┘
├─ 1 scouts explore ×N
├─ 2 plan from the evidence
├─ 3 build builder ✎ ◀─┐
├─ 4 checks review ×3 ──┘ ↺ ≤ 2
└─ 5 report general ──▶ youFor a substantive task the lead runs a workflow in this shape (the built-in implement diagram, or a script it
writes), adjusted to the task. Short questions stay plain turns. Up to 8 at once. For specs, research and large
changes with several parts. Cost ≈ 3–15×.
Goal — loop until proven done
you: objective
│
┌──────▼──────┐
│ Plan │
└──────┬──────┘
┌──────▼──────┐
┌─▶│ Worker ✎ │
│ └──────┬──────┘
│ ◇ 3 skeptics check
└─not yet─┤ ↺ ≤ 10
▼
done · paused · bound reached ──▶ youThe built-in goal workflow: it plans deliverables you can check, then one worker, resumed every pass, works until a
panel of skeptics agrees it is done. At most 10 passes; it pauses when the same gaps come back twice. Goal writes no
limits of its own: the workflow bounds apply (workflows.max_concurrent_agents, workflows.agent_budget,
02). For long tasks with a clear finish line. Cost ≈ 5–20×.
Race — attempts, a judge ranks, you pick
you: task
┌─────────────┼─────────────┐
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ Attempt A │ │ Attempt B │ │ Attempt C │
│ builder ✎ │ │ builder ✎ │ │ builder ✎ │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
◇ tests ◇ tests ◇ tests
└─────────────┼─────────────┘
┌─────▼─────┐
│ judge │
└─────┬─────┘
◇ you pick ──▶ appliedThree attempts, each running the sub-agent model (else the session's) in its own copy of the project. The tests run in every copy, the
judge ranks the attempts on their diffs and test results, and you pick one (or None). Nothing touches your project
until you pick; the winner is applied as a patch. For important changes with tests. Cost ≈ 3× plus the judge.
builder, review and judge are built-in agents, hidden from every agent list; review and judge are
read-only. Your own agent file or config row with a prompt or description under one of these names replaces the
built-in; a row that sets only model or effort tunes it (crates/ocean-agent/src/agentdef/agent.rs:238).
Limits
A mode can bound sub-agents three ways: how many run at once in the whole tree, how many one turn may start,
and how deep they nest. For each number, your subagent.max_* setting wins, then the mode's own, else there is
none; depth falls back to 4 (crates/ocean-protocol/src/diagram.rs:272).
| Mode | At once | Per turn | Depth |
|---|---|---|---|
| Model | none | none | 4 |
| Solo | 0 (no sub-agents) | none | 4 |
| Delegate, Pair, Pipeline | 4 | 30 | 2 |
| Orchestrate | 8 | 30 | 2 |
| Goal | none (the workflow bounds apply) | none | 4 |
| Race | 3 | 30 | 2 |
| Auto | the pick's | the pick's | the pick's |
How each limit acts (crates/ocean-session/src/run/spawn_governor.rs:156):
- At once covers the lead and every sub-agent under it. When no slot is free, the lead's spawn (or a workflow's)
waits, and the dock shows a
waiting (4/4 running)row until a slot frees. A deeper sub-agent's spawn is refused rather than queued (bound: max_concurrent 4/4), because its caller already holds a slot. At0thetasktool is not offered at all. - Per turn counts spawns since your last prompt. At the limit a question card asks
Sub-agents this turn reached 30. Continue?—Continue (+30)allows 30 more,Stop spawningrefuses the rest of the turn. With no one to ask (a headless run) the spawn is refused:bound: max_per_turn 30/30. - Depth: at the limit the
tasktool is not offered, and a spawn is refused with the depth message it always had. - Per type: a diagram may limit one agent type (
"max": 1in Pair):bound: max_builder 1/1.
A refused spawn reaches the model as that task call's error; the turn goes on. Switching modes gives the new limit
to the next spawn, while children already running keep their old slots, so for a moment old and new can run side
by side. Edit the three numbers under F2 › Sub-agents, or in oceancode.json (02).
Auto
Once per prompt, Jev answers one typed question: which of the modes that can run here fits the task best
(crates/ocean-session/src/run/work_mode_jev.rs:120). It answers within Jev's deadline (jev.deadline_ms, 1.5 s by
default); the first Auto prompt of a process can take longer while the connection opens. Jev's pick runs when its confidence is at least
jev.thresholds.work_mode_confidence (0.6). With Jev off, no TypeSafe key, an error, a time-out or lower confidence,
the rules pick instead (crates/ocean-protocol/src/auto_route.rs:22):
- three or more file paths, or three or more list lines → Orchestrate;
- a finish line (
until,tests pass,make … pass,suite) → Goal; - one line of fewer than 25 words that is not a question → Solo;
- anything else → Model.
The badge says which decided: auto → goal · Jev 0.82, or auto → solo · rules: short task. Auto never picks a mode
that cannot run here (see Requirements). /mode overrides it. Every Jev decision is a row in
jev-decisions.jsonl under the point work_mode, which is asked only under Auto (13).
Requirements
- Pipeline, Goal and Race need workflows on (
workflows.enabled, the default). - Race needs a git project and a
test_commandinoceancode.json. - Pipeline and Race need an interactive session, because they ask you to approve or pick; headless runs refuse them.
A mode that cannot run answers the prompt with the reason, for example race needs a git project or
pipeline needs an interactive session (crates/ocean-session/src/run/mode.rs:122).
Race copies. Each attempt runs in a git clone --local of the project under the run's directory
(<data dir>/workflows/<run id>/copies/, crates/ocean-session/src/run/workflow/launcher.rs:353), never inside the
project. The copy carries your uncommitted changes and untracked files (ignored ones stay out). The winner comes back
as one patch applied to the working tree only — nothing is staged — and a patch that does not apply changes nothing;
the result then names the copy, which is kept. The other copies are removed when the run ends; a paused run keeps
them. Copies of a run that never ended (OceanCode quit or crashed mid-race, or a pause never resumed) are removed by a
later OceanCode once the run has sat untouched for a day (crates/ocean-session/src/run/workflow/launcher.rs:498). A copy does not include submodules, an absolute symlink in it still points at your real project, and Git LFS
may fetch while the copy is made (crates/ocean-session/src/run/workflow/race_copy.rs:48).
Trust. Commands from project files — test_command, and a custom diagram step's command — run through the same
bash permission rules as the model's own commands, without a separate repo-trust check. That is how the
formatter setting already behaves. Race runs a diff and the tests in each copy through those rules, so with
bash: ask it asks for each one: six questions for three attempts.
Custom diagrams
A diagram is one .jsonc (or .json) file. OceanCode reads <project>/.oceancode/modes/ and
<config-dir>/oceancode/modes/ (crates/ocean-app/src/modes.rs:28). The quickest start is e in the picker, which
copies a built-in to <id>-copy.jsonc; edit it and save, and the picker has it on its next open. The folder is
watched even when it is created after start.
{
"id": "review-first", // lowercase letters, digits and dashes
"label": "Review first",
"summary": "explore, then build, then review",
"flow": "script", // "lead" or "script"
"agents": { "explore": {}, "builder": {}, "review": {} },
"steps": [
{ "agent": "explore", "do": "Find what this touches:\n{task}", "as": "scan" },
{ "agent": "builder", "do": "Make the change:\n{task}\n\n{scan}" },
{ "agent": "review", "do": "Review the change", "as": "review", "schema": "verdict" }
],
"limits": { "at_once": 2, "per_turn": 20 }
}- A file is keyed by its
id. A built-in id cannot be reused, and when two files share an id the project's wins; the other file is skipped. agentsnames real agent ids. A lead diagram may set"lead_writes": falseand alead_prompt. A step is anagent, aparallelstep ("n", or a"models"list), aloop(it needs"max") or agate(approve,pick,tests); two writers that run at once each need"isolate": "copy", which needs git.pictureis optional: without one the picker shows a line per step."picker": falsekeeps a diagram out of the picker.- A file that does not parse or validate is left out, and the engine log names the file and the reason (18). A session whose custom mode's file was deleted runs Model.
See also
- 02 · Configuration —
mode,test_command,agents.<id>.mode,subagent.max_*. - 13 · Jev decisions — the
work_modepoint. - 19 · Ocean pager and 22 · Ocean pager reference — the picker, the badge, F2 and the dock.