Agentic Engineering

Long-Running Codex Tasks Need a Runtime, Not a Longer Prompt

How to design Codex work that can run unattended, recover safely, and return evidence instead of an unfinished transcript.

5 min read
State machine for a long-running agent task moving through queued, running, waiting, retrying, blocked, and complete states.

An agent can spend four hours on a dependency upgrade and still leave you with nothing useful.

The process may have died during a test run. A credential may have expired. The repository may have changed underneath it. The agent may have reached a question that required approval, then buried that fact inside a long transcript.

The problem is not that the prompt was too short. The task had no runtime.

Long-running work needs durable state, isolated execution, bounded retries, permission rules, and an evidence packet at the end. Otherwise “run this overnight” means “hope the chat is still coherent in the morning.”

A concrete overnight job

Take a routine but nontrivial task: upgrade a frontend monorepo from one major framework version to the next.

The work naturally breaks into stages:

inventory → compatibility plan → isolated edits
→ focused tests → full verification → review packet

Each stage has an input, an artifact, and an exit condition.

The inventory produces the affected packages and known incompatibilities. The plan names the migration sequence and files likely to change. The edit stage produces a branch. Focused tests prove each package. Full verification checks integration. The review packet explains the diff, evidence, risk, and remaining work.

That structure is what allows the task to stop, resume, or hand off without replaying the entire conversation.

The transcript is context, not the task database

For durable execution, persist at least:

task_id
goal and constraints
starting revision
current stage
artifacts produced
commands and checks completed
approvals received
retry count
blocker or stop reason
next safe action

This can be a database record, structured file, job object, or a small set of versioned artifacts. The format matters less than the invariant: a new worker should be able to understand the current state without inferring it from hundreds of messages.

The transcript still matters. It preserves hypotheses and context. But it is a poor source of truth for whether a command completed or which revision a patch was based on.

Checkpoint after useful work, not after every thought

Checkpointing is a product decision.

Save too rarely and a failure discards expensive work. Save after every tool call and the runtime becomes a slow log collector. A useful checkpoint occurs when the workflow produces a stable artifact: inventory complete, plan accepted, patch applied, focused tests passed.

Each checkpoint should record the starting assumptions it depends on. Before resuming, confirm those assumptions still hold. If the branch moved, dependency metadata changed, or an external ticket was closed, the old “next action” may no longer be safe.

Retry only operations that are safe to repeat

“Try again” is not a recovery policy.

A read-only API request that timed out may be retried with backoff. A package download may be retried if its inputs are pinned. A database migration that returned an ambiguous result should stop until the system can establish what changed.

For each stage, define:

  • whether the action is idempotent
  • what proves it completed
  • how many retries are allowed
  • what must be revalidated first
  • which failure requires a person

This turns failure handling from improvisation into explicit state transitions.

Unattended execution deserves narrower permissions

An interactive agent can ask before it crosses a boundary. An overnight job may have nobody available to approve it.

That is a reason to reduce authority, not grant blanket access.

For the framework upgrade, the job may write only to a dedicated Git worktree, run repository commands, and access approved package registries. It should not merge, deploy, modify unrelated checkouts, or browse arbitrary internal systems.

OpenAI’s current scheduled-task documentation makes the same boundaries visible. Local scheduled work uses the selected project’s environment and unattended sandbox settings. Git repositories can run in a dedicated worktree so scheduled edits do not collide with unfinished local work. The guidance also recommends testing a workflow manually before scheduling it.

That last point is easy to skip: a schedule does not make an unstable method reliable. It only repeats the instability on time.

Decide whether the work needs a schedule, a heartbeat, or a queue

These are different problems.

A schedule starts recurring work: scan dependencies every Monday, summarize merged changes each morning, check a release branch nightly.

A heartbeat revisits an existing job: check whether CI finished, see whether a deployment recovered, continue a review loop while context matters.

A queue manages many independent jobs with concurrency, retries, ownership, and backpressure.

Do not turn a multi-job system into one immortal chat. Use one coherent task per outcome and let the runtime own coordination.

The morning-after test

Before calling a long-running workflow production-ready, walk through this scenario:

The agent edits three packages. The second package’s test runner hangs. While the job is waiting, another developer changes the lockfile. The machine restarts. You return six hours later.

Can the system tell you:

  • which edits were completed
  • which checks actually passed
  • whether the worktree is still based on the expected revision
  • whether retrying package two is safe
  • what changed outside the task
  • what requires your decision

If not, the task is long-running only in the sense that it takes a long time.

Durable work is work that can be interrupted without becoming mysterious.

Further reading