For AI agents: a documentation index is available at https://www.plungeai.com/docs/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://www.plungeai.com/docs/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.

A run is bounded by the money and time you set, not by an arbitrary step count. Set nothing and a run keeps going until the work is done (or the no-progress guard stops it, below).

The bounds

BoundEnvironment variableoceancode run flagSlash command (this session)
Spend cap (USD)OC_MAX_USD--max-usd 25/budget 25
No spend cap—--max-usd off/budget off
Subscription (no cap; spend is a list-price estimate)—--max-usd subscription/budget subscription
Wall clockOC_MAX_MINUTES--max-minutes 8h (also 45, 90m, 2d, off)/limits time 8h
Steps per turn (root), 1–1000OC_MAX_STEPS--max-steps 100 (default clears)/limits steps 100
Steps per sub-agent turnOC_MAX_SUBAGENT_STEPS——
Tideline (% of context)ledger.tideline.percent (config)--tideline 50%/tideline 50%
Tideline (fixed tokens)ledger.tideline.tokens (config)--tideline 60k/tideline 60k
Tideline block (what one cut removes)ledger.tideline.block (config: a token count, or a share of the line as "35%"; unset = 70 % of the line)——

Precedence: slash command / flag > environment variable > built-in default. Flag and slash values are stored on the session, so they survive --continue.

The tideline's old names still work as aliases: --shelve, /shelve and ledger.shelve.

The step cap is a boundary, not a stop

OC_MAX_STEPS (default 300) caps the steps in one root turn, but a root turn that reaches it auto-continues into a fresh turn — no budget or clock needs to be set. The ledger cuts by blocks after every step, so even one long turn stays under the tideline (see 06 · Session ledger and export). 0 is rejected: bound a long run with a budget or a clock instead.

Sub-agents are different: they simply stop at OC_MAX_SUBAGENT_STEPS (default 300), so a raised root cap does not deepen them.

Output tokens

OC_MAX_OUTPUT_TOKENS overrides the per-request output-token cap in either direction, clamped to the model's own published maximum. It bounds how much a single model response may emit, not the run as a whole; leave it unset to use the model's full maximum.

What happens at a bound

Exceeding a bound is a clean, non-error stop, distinct from a crash, and the ledger records it as a step-limited turn. The internal stop reasons are BudgetExceeded and TimeExceeded. Over the Ocean tunnel the response carries a typed stopped_by:

Bound reachedstopped_by
OC_MAX_MINUTES / /limits timetime-exceeded
OC_MAX_USD / /budgetbudget-exceeded
step capstep-limit

The plan drives the run

The model keeps its plan as a todo list (see 05 · Plan mode and todos). A root turn that settles while any todo is still open does not end the run — the engine works off the next open todos and drains again. A run ends only when:

  • the work settles with no open todo; or
  • a spend or clock bound trips; or
  • you interrupt it; or
  • the no-progress guard fires — two consecutive continued turns that leave the open and completed counts unchanged stop the run cleanly with a "Run stopped" toast.

So a model that never plans and never settles runs a few turns and stops; one that plans and makes progress runs until its list is done or a bound trips.

While a background sub-agent of the session is still working, a settled turn is not worked off: the sub-agent is what moves the plan, and its result re-drives the session when it lands. The work-off resumes in that re-driven turn.

Such a turn ends as waiting, not finished, and says on what. The pager's end-of-turn line reads Worked for 6m38s · waiting for sub-agent "Build the mock" · 2 plan rows open · continues when it lands; an ACP client gets _meta.oceanStopReason = "waiting" and _meta.waitingNote on the prompt response, and the session's log holds a durable session.waiting row. When the sub-agent lands, the engine starts the next turn itself (a durable session.resumed row) and the pager draws it as it runs; the sub-agent's result row tells the model how long the run paused, so it can say so when asked. That turn shows as running from its first instant: an ACP client gets ocean/queue/changed naming it as running before its first frame, and the pager's status row reads what a turn you started would (Waiting for response… during a silent think, Thinking…, the running tool, the sub-agent it waits on). Every turn the engine starts this way gets its session.resumed row, including the follow-up that answers a result which landed while a turn was running. A message you send while a turn is ending as waiting is answered as its own turn and streamed under its own prompt id. The restart is guaranteed:

  • a sub-agent that fails or crashes still reports, as an error result, and the run goes on;
  • a sub-agent you stop (ocean/subagent/cancel, or esc esc on the session) does not restart the run; if plan rows are left open, the session records why (reason: user_stopped_child) and the next message you send continues it;
  • if the engine exits while a sub-agent works (a quit, a crash), the next time the session is opened its lost sub-agents are reported as errors ("the engine restarted while it worked") and the run goes on. A session whose engine is still running elsewhere is left to it.

oceancode run waits for its background sub-agents and the turns their results start before it exits.

The Jev supervisor (opt-in)

With the Jev decision layer on (see 13 · Jev decisions), a supervisor reads a root turn's clean finish and, before a bash call whose exact command already ran twice among the prompt's last six, asks whether it would bring anything new (the no-progress check). With jev.supervisor = "act" it may keep a finish from ending the turn — a synthesized continuation, at most jev.supervisor_max_continuations per human prompt (default 1), only when the goal is clearly not complete and progress is real. Two consecutive no-progress answers send one steer message; four stop the run — under headless --auto it ends with stop reason no_progress (exit 5), elsewhere you are asked Continue or Stop. With jev.check = "act", headless --auto also ends a run right after a check verified a pass. It never moves a bound: the spend, clock and step bounds above, the exact-repeat doom-loop trip, the hook cap and the no-progress guard decide exactly as they do without it. In shadow, the default once the layer is enabled, it only records what it would have done.

Stopping a run stops all of it

esc esc (or the palette's abort) stops the session's own drain at its next step boundary, and every sub-agent stops with it — foreground ones immediately, background ones cancelled by the parent. A late background result is recorded as cancelled and never restarts the run.

Background jobs and long waits have no clock of their own

A job the model starts — bash with background: true, a monitor, a loop, a scheduler — runs until it ends or the model calls job_kill. It dies with the run only when the run has a wall clock (OC_MAX_MINUTES / /limits time); without one a build, a watch or a server runs for hours or days, and job_output reads it back whenever the model asks. (Until 2026-10-05 every job was reaped ten minutes after launch while the run had no clock at all.)

A job that ends on its own — done or failed, not killed — reports back. Its result (state, command, the last 2,000 bytes of output) is posted to the session that started it as a <job id=… state=…> message and a new turn starts, the way a background task reports; a turn already running gets exactly one follow-up turn. So the model does not have to sleep and poll to learn a job finished, and a turn that stopped polling still hears about it. A job a sub-agent starts wakes no one.

Polling is not a loop either. The doom-loop trip ends a turn only after three consecutive fast calls with the same input and the same result. A repeat whose output moved (a row count, a timestamp, a log line) or a call that ran 30 seconds or more (a sleep 300; check) resets the count to zero. When the trip does fire, the turn ends with stop reason doom_loop and the final text Stopped by the doom-loop guard: … stays in the transcript, not only in a passing toast. (Until 2026-10-24 three identical sleep 298; wc -l results.jsonl polls of a live benchmark tripped it and the turn went quiet with no visible reason.)

A long wait does not lose the prompt cache either. Every request's cache markers carry the provider's one-hour TTL, and while a step waits — on a sub-agent, on a long bash — or the session idles, the engine re-reads the last request every OC_CACHE_KEEPALIVE_MINUTES (default 50) so that clock restarts: a cache read of the prefix (session.cache.touched, cents) instead of re-writing it when the wait ends. It stops after OC_CACHE_KEEPALIVE_MAX touches (default 48, ≈ 40 h; past a model's break-even — 80 touches on Fable 5.1, 20 on a 0.1× model — a re-write is the cheaper bet). A touch that fails is sent once more a few minutes later before the keep-alive gives up, and pressing Esc on a running turn does not stop it — the next prompt reads the same prefix. See 02 · Configuration.

See also

Planned: TI-34

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