Agent architecture

What happens when your coding agent crashes mid-task

Almost every coding agent can restore a conversation. Very few can tell you which file edits were half-applied, which approval you never answered, and who owned the workspace when the power went out.

By Kendr Research10 min readUpdated August 14, 2026
Diagram representing recovery of an interrupted AI coding agent task from a durable event log
Quick answer

Session resume restores a transcript; durability restores authority. A durable coding agent treats the invocation log as the authoritative state, so after a crash it can answer which turn was running, who held the workspace, which proposed actions were never decided, and which multi-file edits were half-applied. The mechanisms are single-writer leases with heartbeats, idempotent turn starts claimed atomically in a database, restart reconciliation that replays pending approvals, checkpointed edit transactions with compensating rollback, and a hash-chained ledger of the pre-task baseline. Most harnesses in 2026 implement the transcript and not the rest.

Resume and recover are different words

Nearly every coding agent shipped in 2026 advertises session resume, and nearly every one of them means the same thing by it: the conversation is written to disk, so when you restart you can pick up where the chat left off. That is useful and it is not recovery.

Recovery is a question about state, not about conversation. Suppose the process dies fourteen files into a nineteen-file rename, with one command awaiting your approval and a background test process still running. Resume gives you the chat back. Recovery answers: which of those nineteen files were written, whether the write that was in flight completed or left a partial file, whether that approval is still pending or was silently discarded, whether the workspace is still owned by a runtime that no longer exists, and whether the background process is orphaned.

A harness that only implements resume will happily let you continue the conversation into an inconsistent working tree, and the model — which has no way to know the process died — will proceed on the assumption that its last nineteen-file plan succeeded. That is the failure mode this layer exists to prevent.

The invocation log as source of truth

The architectural move that separates durable harnesses from the rest is treating the record of proposed and executed invocations as the authoritative state of the system rather than as a log emitted alongside it. Everything else follows from that inversion. If the log is authoritative, the user interface is a projection of it, a restart is a replay of it, and an approval is a row in it rather than a callback held in memory.

Kendr Code is the clearest example of this design in the current field. It persists Code projects, workspaces, tasks, turns, leases, task-owned checkpoints, changes, and usage projections in versioned storage, and it grounds a hash-chained task ledger at the start of every turn with the objective, the scoped instructions, the repository and Git baseline, the pre-existing state of every path the task will touch, and atomic file hashes. Every invocation, approval, usage record, steering message, and final result is a durable event, and an interrupted turn resumes from those events after restart.[1]

The practical payoff of the ledger is that a completion claim becomes checkable. When an agent reports that it finished, the ledger can be compared against what was actually true when the task began. Without a baseline recorded before the work started, “done” is only ever the model’s opinion.

Leases: the problem nobody expects to have

Two runtimes editing one workspace is not a hypothetical. It happens when a desktop app and a command-line client share the same state directory, when a session is resumed on a second machine over a synced folder, when a crashed process leaves a lock file behind, or simply when a user opens the same project twice. Without an ownership protocol, both write, and the losing writes disappear silently.

The answer is borrowed directly from distributed systems: a single-writer lease with a background heartbeat. A mutating turn acquires it, renews it while it works, and — this is the part that is easy to get wrong — never silently reacquires a missing, expired, or foreign lease. Losing the lease must stop the turn closed before the next model action or workspace mutation, not merely log a warning.

The companion mechanism is an idempotent turn start claimed atomically in the database, so that two runtimes attempting to start the same persisted turn resolve to exactly one winner. Kendr Code implements both, and also takes a short operation lease for manual git staging, restore, and checkpoint restore so an explicit user action cannot race an active agent turn — while documenting that complete fencing of every mutation path is still a production gate rather than a finished claim.[1] That kind of disclosure is rarer than the mechanism itself.

  • Ask what happens when the lease is lost mid-turn. “Stops closed” is the correct answer; “logs and continues” is not.
  • Ask whether the desktop app and the command-line client share state, and if so, what prevents both from starting the same turn.
  • Ask whether an orphaned container or background process from a dead run is reconciled at startup, or left to leak.
  • Ask whether manual git operations are fenced against an active agent turn.

Half-applied edits and what a checkpoint really guarantees

The recovery story for file edits depends entirely on the edit engine. A harness that applies patches file by file with no transaction has nothing to recover: the repository is simply in whatever state the process reached. A harness that runs multi-file changes as a checkpointed transaction — per-file atomic replacement, a rollback journal, and content-addressed blobs isolated to the task — can restore the pre-transaction state exactly.

It is worth being precise about the guarantee, because this is a place where marketing routinely overstates. A rollback-journalled transaction is recoverable; it is not an operating-system-wide atomic commit. Another process observing the filesystem during the transaction can see an intermediate file set. Path-based replacement and deletion also retain a final cross-process race window that no portable implementation closes. The correct claim is that the harness can always get back to a known state, not that no other process ever sees an inconsistent one.

The second half of the problem is external change. If you edit a file in your editor while an agent turn is running, a naive harness overwrites your work. A durable one preconditions writes on a revision captured at read time, detects the conflict, and surfaces an explicit compare, use-latest, or keep-mine decision instead of silently choosing.

Approvals that survive the process

The most consequential thing to lose in a crash is a pending decision. If the harness held that approval in memory, then a process kill while you were away from the keyboard silently discards an action the agent was waiting on — and depending on the implementation, either the turn fails opaquely or the agent proceeds as if it had been denied.

The durable design persists the pending approval with the exact proposed arguments and an audit fingerprint, replays pending approvals oldest-first on restart, and resolves approve or reject as a single conditional state transition so two clients cannot both decide it. Rejections carry free-text feedback stored verbatim and returned to the model as a tool result, so a denied action becomes information the agent can act on rather than a dead turn.[1]

This is also where unattended operation becomes possible or impossible. An agent you leave running overnight will hit an approval boundary at some point. Whether that boundary is a durable row in a database or a promise in a process that may not survive until morning is the difference between coming back to a paused task and coming back to a lost one.

There is a second-order test worth applying once a harness gets this right, and almost nothing in the field passes it: what happens when you deliberately undo work. A conversation rewind is a state change like any other, and a durable design records it as a new event rather than deleting history — otherwise a hash-chained ledger either breaks or quietly stops being evidence. It is also the point at which conversation state and file state must be allowed to diverge: rewinding the conversation and reverting the workspace are different operations, and a product that fuses them will eventually throw away work the user wanted to keep. Kendr Code’s implementation keeps the two separable and appends the rewind to the chain, which is the shape to look for.

Where the field actually stands

Durability is the weakest dimension across the coding-agent field as a whole. In a ten-point architecture rubric applied to nineteen full harnesses, the median score on durability was 6 and only one product scored 10.[2] That is not because the engineering is hard — these are well-understood patterns from database and distributed-systems practice — but because it is invisible in a demo and expensive to retrofit once the transcript is already treated as the record.

The products that score well here tend to have arrived from an adjacent discipline. Kiro’s specification artifacts are durable by construction because the specification, not the chat, is the unit of work. Kendr Code’s ledger and lease design reads like a workflow engine because that is the lineage. The vendor CLIs, which grew from interactive terminal tools, mostly stopped at high-quality session persistence — sufficient for interactive use, insufficient for the unattended and regulated work everyone now says they want to enable.

A five-minute test you can run on any harness

Point the agent at a scratch repository. Ask it to rename a symbol across a dozen files and to run the test suite afterwards. When it begins writing, kill the process — not a graceful interrupt, an actual kill. Then restart the harness and open the same task.

Four things tell you what you need to know. Does it know a turn was interrupted, or does it present a clean slate? Does it report which files it had already modified? If an approval was pending, is it still there with the original arguments? And does git status match what the harness believes it did? A harness that gets all four right is safe to leave unattended. A harness that gets none of them right is a very good interactive tool that should not be given a long leash.

Frequently asked questions

Is session resume the same as crash recovery?

No. Session resume restores the conversation. Crash recovery restores state: which turn was running, who owned the workspace, which approvals were never decided, which multi-file edits were half-applied, and whether background processes were orphaned. Most harnesses implement the first and not the second.

Why do coding agents need leases?

Because two runtimes can share one workspace — a desktop app and a command-line client, a resumed session on a second machine, or the same project opened twice. Without single-writer ownership both write and one set of changes disappears silently. A lease with a heartbeat, which stops the turn closed when lost, prevents that.

Can a coding agent guarantee atomic multi-file edits?

It can guarantee recoverability, not operating-system-wide atomicity. A checkpointed transaction with per-file atomic replacement and a rollback journal can always return to a known state, but another process watching the filesystem can still observe an intermediate file set during the transaction.

How do I test a harness for durability?

Ask it to rename a symbol across a dozen files, kill the process mid-write, restart, and check four things: does it know it was interrupted, does it report which files it changed, did any pending approval survive with its original arguments, and does git status match what it believes it did.

Sources and evidence

Primary and authoritative sources used for factual claims. Company research and executive forecasts are labeled as such in the article.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5