The runtime

Infinite RuntimeAn agent runtime with no turn limit

A task runs until the work is done, not until a counter runs out.

Most agent harnesses stop a task after a fixed number of turns. This runtime keeps one task, and one conversation, alive through crashes, restarts, worker handoffs and weeks of work, and lets the agent decide for itself when it is finished.

216tasks
2,002agent decisions
0context compressions

From one month of the SEO team running unattended on a real product blog.

Identity

One task, many workers.

A task keeps one identity and one conversation for its whole life. The thing that actually runs it is a worker, and a worker can be replaced at any moment without the task noticing.

One task, many workersA task and its session run unbroken. Worker 1 hands over after 200 steps, worker 2 is killed by the platform, worker 3 replaces it and reads the conversation from the database, and a late write from worker 2 is refused because its generation number is stale.Taskone identity, start to finishSessionone conversation, only appended toExecutionthe worker running it. ReplaceableDatabasethe one thing every worker trustsnever restarts, never forksthe same history every worker readsWorker 1Worker 2Worker 3, replaces 2123step 200, nothing pending:hands overkilled by the platform(CPU limit)a minute later: health checkfinds worker 2 gonereads the conversation, finishes thetool calls that never ran, carries onworker 2 wakes up and tries to writerefusedits generation number is staleevery write checks the generation first

Scroll sideways to see the whole diagram.

TaskThe work

One piece of business work, for example “build the SEO strategy for the Brazilian market”. It exists from creation to completion and never gets a second identity.

SessionThe memory

The single continuous conversation that task owns. A new worker picks up the same conversation and carries on. It never starts over.

ExecutionThe worker

One run on the platform. A worker has physical limits, so a task cannot be run to the end in one instance. Workers are rotated, and a dead worker is replaced.

The generation number

  • Every replacement gets a higher number. Every write checks it first. A worker that was thought dead but comes back finds its number is stale, and the database refuses what it writes.
  • It also stops duplicate replacements. If a retry tries to create worker 3 a second time, the number already exists, so it cannot.
  • Two ways to hand over. A worker that is close to the platform’s step limit hands over on purpose, after 200 durable steps. A worker that dies is replaced by the next health check. Both are the same thing: resume from the database.
  1. Worker 1 reaches step 200 with nothing pending, and hands over.
  2. Worker 2 reads the conversation from the database and carries on. Halfway through, the platform kills it for using too much CPU.
  3. A minute later a health check finds worker 2 gone. Its last model request has no saved result, so it is marked “outcome unknown”. No side effect is unknown, so worker 3 is created, labelled “replaces 2”.
  4. Worker 3 reads the conversation, sees the last saved reply still has tool calls that never ran, runs them first, then continues.
  5. If worker 2 was not really dead and tries to write, the database sees its number is no longer current and refuses the write.

Durability

Save first, then act.

Every round writes to the database before and after each step that can fail. Whatever happens, a new worker can find the exact point the last one reached.

Save first, then actFour steps run on the worker, a model request, appending the reply, running a tool and appending its result. Six numbered checkpoints are written to the database around them. A crash during the tool is resumed from the last checkpoint.Workerasks, acts, appendsDatabasesaves before and afterAsk the modelAppend replyRun a toolAppend result1about to send2reply saved3reply appended4tool registered5result saved6result appendeda crash anywhere in herethe next worker resumes from the last save

Scroll sideways to see the whole diagram.

  1. Before the requestSave “I am about to send this”, with the full message, marked in progress.
  2. After the model repliesMark it done. Save the full reply and the real usage.
  3. Append the replyIt goes into the conversation. Any tool calls in it are now “sent, no result yet”.
  4. Before each toolRegister the operation, and whether it can safely be run again if it is interrupted.
  5. After each toolMark it succeeded or failed. Save its output.
  6. Append the resultThe result goes into the conversation.

Replay, never re-ask

On recovery the saved reply is replayed. The model is not called again, so nothing is paid for twice and the answer cannot change halfway through a task.

Any interruption is the same problem

A crash, a platform limit, a lost network or a deploy all end the same way: a new worker reads the database, finds the latest step, and carries straight on.

Self-healing

Failures heal themselves.

A person cannot add any information to these failures, so the engine handles them on its own and keeps a record you can read afterwards.

Retry waits of 5, 15 and 45 secondsAfter a model stream failure, rate limit or server error the same worker waits 5 seconds, 15 seconds and 45 seconds and retries. The fourth failure in a row moves the task to a new worker.5 s15 s45 sfourth failure in a row: a new workersame worker retries after each wait

The model stream cuts, or it rate-limits429, 5xx, a dropped connection

The same worker waits 5, 15, then 45 seconds and retries. The fourth failure in a row moves the task to a new worker.

The account or quota fails401, 402, 403

A new worker tries again in 5 minutes. The task shows as “recovering”, not “paused”, because waiting is something the engine does by itself.

The platform kills a workerCPU limit, a lost worker

A new worker takes over from the saved receipts. Nothing is repeated that already happened.

A tool is called with bad argumentsa business error, not a system fault

The error is recorded and shown to the agent on its next turn, with which fields were wrong and whether any part of the action already took effect. The agent corrects itself.

The outcome of a side effect is unknowna timeout is not proof that nothing happened

Before any call that has an effect outside, such as starting a research job, the runtime records that it is about to submit. On recovery it looks for the original job instead of submitting a second one. Nothing is redone until the outcome is clear.

Context

Context that rarely needs compressing.

For an agent that works for weeks, the valuable memory is not the result. It is the paths it tried, the mistakes it made and why they failed. Compression throws away exactly that, so the rule is: avoid compressing, and when you must, delete nothing.

Isolating context across agentsA parent agent delegates to a research agent, a writer and a reviewer. Each runs in its own long conversation. Only a short result with its evidence comes back to the parent, so the parent conversation stays small.Parentsees conclusions, not processResearchone question, its own conversationWriterone articleReviewerone draft, read alonedozens of searches · 149 rounds · 28 keywords builtresearch, drafting, evidence for every claimchecks the exact draftone short resultresult + evidenceverdictThe parent conversation barely grows. The long process stays in the child.

Scroll sideways to see the whole diagram.

01Isolate the context

Every child agent has its own conversation. A keyword-research child ran 149 rounds and built 28 keywords. Its parent received one conclusion: 4 topic groups, 15 clusters, 28 keywords, and which are high priority.

02Keep big things outside

Documents live in a workspace the agent reads and edits on demand. Large libraries are searched, not pasted. A tool result is stored once per conversation, and later changes are appended, not re-sent.

03Load on demand, then let go

Persist outside the context, bring a piece in when it is needed, and drop its text when done, while keeping the reference so the agent can find it again.

Compression changes what the model reads, not what is storedThe database keeps original messages 1 to 120 and everything after. The model is sent a numbered summary of messages 1 to 120 followed by the later messages unchanged. The agent can read any original message by its number.Storednever deletedSent to the modelwhat it reads this turnoriginal messages 1 to 120messages 121 to nowsummary v3messages 121 to now, as they wereonly what the model reads is replaceda numbered summary records how far it reachesread_conversation: any original message, by number

Scroll sideways to see the whole diagram.

When it must compress, nothing is deleted.

  • Only what the model reads is replaced. The summary is a new, numbered version that records how far it reaches. The original messages, tool receipts and artifact references all stay.
  • Three ways back to the detail. Read the conversation by message number, in pages. Read the task’s memory: its objects, their versions, and every tool call. Or use the business read tools, because documents and libraries were never in the summary.
  • Facts are not left to the summary. Which object was changed, which version was seen, which action really succeeded are recorded when they happen, so a badly written summary cannot corrupt them.
How a summary is writteneach time
Input
The previous summary and the new material, merged into one version.
Keeps
The task and its goal, what is done and its effect, exact references and versions, decisions with their evidence, failures and open obligations.
Rule
Earlier facts stay unless newer evidence clearly replaces them.
Never
Invents a new strategy, or declares the task finished.

Self-audit

No turn limit. A self-audit every 30 turns.

A fixed limit ties two different things to one number: how big a task is allowed to be, and how to stop a runaway. Raise the number and you only move the cliff. Here the agent decides, and the only real limit is the token budget you choose to give it.

No turn limit, a self-audit every 30 turnsA fixed turn limit cuts the task at turn 30 whatever work remains. With self-audit, at turns 30, 60 and 90 the agent reviews its progress and chooses to continue or finish, and the third audit chooses to finish.A fixed turn limitthe usual harnessSelf-auditevery 30 turns, the agent decidescut off, however much is leftwork still to do0102030405060708090audit 1continuestates its next methodaudit 2continueno person clicksaudit 3finishsays what is not done

Scroll sideways to see the whole diagram.

How an audit runs

  • A counter in the conversation. Every 30 normal decisions, the runtime adds an audit instruction to the same conversation.
  • Before each model request, in order: finish any tool that is still pending; take in any new input first; if the counter has reached the threshold, enter the audit; then add the audit instruction. Audit requests are tagged so they can be told apart later.
  • The agent reviews and chooses. What it achieved, what failed, what is left. Then it continues with a stated method for the next stage, or finishes and says honestly what is done and what is not.
  • No person clicks “continue”. Tools that change business data are locked to read-only during the audit. Usage is recorded, but never used to stop the task.
An audit recordone per audit
Decision
Continue, or finish.
Reason
Required. Why this decision.
Progress
Required. What is actually done so far.
Remaining work
Required if it continues.
Next-stage method
Required if it continues. How it will go about it.
Outcome
Completed, partial, or unable to complete.
Artifacts
References to what it produced.
Unresolved
What is still open.

If a person has to come back and give the agent its next step, it is not really running 24/7.

That is what the runtime is for: a task that can be left alone for as long as the work takes, and still be the same task when you return.