DEV Community

hefty
hefty

Posted on

A Bigger Context Window Won't Make Your Coding Agent Resumable

Your coding agent has been running for eight hours. It edited twelve files, started a dev server, attempted a migration, hit two failing tests, and then lost its session.

The transcript is still there. It might even fit inside the model's context window. But a fresh process still cannot answer the questions that matter:

  • Which changes were successfully applied?
  • Is the migration safe to run again?
  • Is that dev server still alive?
  • Which failing test blocked the last step?
  • Should the next process resume, roll back, or stop for review?

The transcript survived. The job did not.

Long-running agent work needs a resume protocol. More context can help a model continue a conversation, but it cannot turn chat history into durable job state.

Context is not a checkpoint

Conversation context preserves messages, tool calls, and explanations. That is useful. It can remind a model what the user asked and how the session reasoned about the task.

A checkpoint has a different job. It records what is true about the work now.

That distinction gets expensive when a run is interrupted. A transcript might say, "I'll update the schema and rerun the tests." It does not necessarily prove that the schema changed, identify which command ran, or preserve its exit code. If the session disappeared between the tool call and the final response, the prose may describe an intention rather than the repository's actual state.

A replacement process needs a compact operational record:

  • the run's contract
  • the last completed step
  • changes and external side effects already made
  • exact validation results
  • the next safe decision

Without that record, recovery starts with archaeology.

Give the run a bounded contract

"Keep working until it is done" sounds productive, but it is a terrible recovery contract. Done is undefined, authority is open-ended, and a replacement process cannot tell whether the run stopped normally or simply ran out of road.

A useful contract names the boundary before execution begins:

  • a run ID and owner
  • repository and worktree
  • the goal and stop condition
  • time, tool, and authority limits
  • the expected artifact
  • the checks that decide whether the artifact is acceptable

Nightshift's author describes this shift explicitly: long agent runs become disk-backed, time-bounded jobs with contracts, recovery paths, receipts, and archives. That is a project-authored design, not independent evidence that every run will recover correctly. Still, the operating model is the interesting part. A shift has an end, and its state exists somewhere other than the active chat.

The stop condition deserves special attention. "Implement authentication" leaves too much room for interpretation. "Prepare a reviewable patch for the login callback, stop before deployment, and record the named test results" gives the next operator something they can inspect.

Persist facts at step boundaries

Do not wait until the final response to save state. By then, the process may already be gone.

Checkpoint after meaningful steps: dependency installation, migration generation, code modification, test execution, browser validation, or any external mutation. The record should stay small. Its purpose is fast re-entry, not a polished diary of everything the agent thought about.

Mivia's documented workflow offers a useful implementation signal here. Its README describes isolated workflows, per-step run records, lifecycle hooks, and local files. Those features create places where a harness can persist facts before moving forward.

The word "facts" matters. Save the command and its real result, not "tests look good." Save the files changed, not "updated the frontend." If a check failed, keep the failure visible instead of smoothing it into a progress summary.

A good checkpoint might say:

last_completed_step: generated migration 0042_add_job_receipts
changed_files:
  - db/migrations/0042_add_job_receipts.sql
  - src/jobs/receipt.ts
checks:
  - command: pnpm test --filter job-receipts
    exit_code: 1
    outcome: 2 tests failed in receipt-retry.test.ts
pending_action: inspect whether retries duplicate an existing receipt
Enter fullscreen mode Exit fullscreen mode

That is far more useful than another page of confident narration.

Track side effects separately

File changes are only part of an agent run. The process may have started services, modified a database, opened a pull request, published an artifact, sent a message, or changed remote configuration.

Those effects need their own ledger because replaying the original prompt can repeat them.

A blind retry might apply the same migration twice. It might create a second deployment while the first one is still running. It might overwrite uncertainty with a new sequence of actions that happens to produce cleaner logs.

A side-effect ledger should answer three questions:

  1. What changed outside the transcript?
  2. Can the operation be checked safely?
  3. Is it repeatable, reversible, or neither?

This does not make every action idempotent. It makes the uncertainty visible before another process acts on it.

Recovery must live outside the failed session

A stalled process cannot be the sole owner of its recovery plan. The plan needs to be readable by a fresh process or a human operator with no access to the original model state.

Recovery should begin with inspection, followed by an explicit decision:

  • Resume when the recorded state matches the environment and the pending action is still valid.
  • Roll back when a known reversible change should be removed before work continues.
  • Escalate when the evidence is incomplete, the environment drifted, or another action could compound an unknown side effect.

This is why recovery is not the same as retry. Retry repeats an operation. Recovery first establishes what already happened.

PI-Desktop's project documentation points at the operator-facing side of this problem through project sessions, message-scoped diffs, approvals, and guarded rollback. Those controls do not guarantee safe recovery, and local-first software is not automatically isolated or secure. They do make the unit of change more inspectable than one opaque stream of agent activity.

A resume protocol can be simple. Here is an operating pattern, not a standard or a security guarantee:

run:
  id: auth-callback-2026-09-04-01
  owner: overnight-agent
  repository: web-app
  worktree: ../worktrees/auth-callback

contract:
  goal: prepare a reviewable login-callback patch
  stop_when: named tests pass or a migration needs approval
  time_budget_minutes: 90
  allowed_effects:
    - edit_worktree
    - run_local_tests
  forbidden_effects:
    - deploy
    - modify_production_data
  expected_artifact: git_diff

checkpoint:
  last_completed_step: add receipt persistence
  pending_action: inspect two retry test failures
  changed_files:
    - src/jobs/receipt.ts
    - db/migrations/0042_add_job_receipts.sql

side_effects:
  services_started:
    - name: web-dev-server
      port: 3102
  external_mutations: []

evidence:
  checks:
    - command: pnpm test --filter job-receipts
      exit_code: 1
      outcome: 2 retry tests failed

recovery:
  inspect_first:
    - git diff --stat
    - pnpm test --filter job-receipts
  resume_when: migration is unchanged and failures reproduce
  rollback: discard the isolated worktree
  escalate_when: database state differs from the checkpoint

receipt:
  status: blocked
  reviewer_action: decide whether receipt creation must be idempotent
Enter fullscreen mode Exit fullscreen mode

The schema is deliberately boring. Boring is good when a process wakes up at 3 a.m. and needs to decide whether a migration already ran.

Finish with a receipt, not "done"

A completion message is not evidence. The final receipt should contain the artifacts produced, the exact checks and outcomes, known failures, assumptions, and the next reviewer action.

This also gives review tools a clean handoff. R3's launch describes a local interface that turns scattered comments into explicit feedback for a coding agent. It is a small, low-engagement project signal rather than adoption evidence, but the shape of the loop is useful: review state becomes an artifact that can follow the job into another session.

A receipt does not prove correctness. It tells the next reviewer what was checked and what was not. That is enough to replace a vague claim of completion with a reviewable boundary.

Let old runs improve new contracts

An archive earns its keep when it changes the next run.

The ZeroShot launch describes local capture of agent sessions, clustering repeated friction, and drafting reusable workflow improvements. Those are author claims, not measured productivity results. The useful idea is narrower: repeated interruptions can reveal missing fields in the contract.

If three runs stall because nobody recorded which browser profile owns port 3102, add that ownership to the template. If retries keep duplicating external actions, require idempotency keys or an escalation rule. If reviewers repeatedly ask which checks actually ran, make command outcomes mandatory in the receipt.

The loop is practical: archive the run, find recurring ambiguity, then remove that ambiguity from the next contract.

Apply the replacement-process test

Before letting an agent run unattended for hours, imagine the current session vanishes halfway through.

Can a different process inspect durable artifacts and determine the contract, current state, side effects, evidence, and next safe action? Can it choose resume, rollback, or escalation without treating the old transcript as ground truth?

If the answer is no, a larger context window will only preserve more material to reread. Make the job resumable before making it longer.


Source notes

Top comments (0)