Your agent was halfway through a change when the window disappeared. The repository contains a new implementation and two modified tests. There is no final message. Before saying “continue,” you need to know whether the original agent is still working, which checks finished, and whether the next prompt will reach the same process.
Those questions have different answers. A conversation can remain readable after its process is gone. A file edit can survive even when the result of the command that made it was never recorded. And a new session can know the project's conventions without knowing where this particular task stopped.
This guide follows agent session recovery through CompozyOS. You will end with a way to choose between inspecting, attaching, continuing, and starting a linked session—and a handoff that makes the unfinished work explicit. The commands describe the implementation checked on September 11, 2026; the interrupted change is an illustrative scenario, not a captured crash report.
Start with three reads
Resist the urge to submit the original task again. If the first process is still alive, a second attempt could overlap its edits. If the process died after an external action, repeating that action could repeat the effect. The Python retry lab reproduces that missing-receipt problem and shows why a local record alone cannot settle it.
Find the original session in the session list, then inspect its status, recap, and history. Replace
sess_1234 with the actual ID:
compozy session list -o json
compozy session status sess_1234 -o json
compozy session recap sess_1234 --limit 20
compozy session history sess_1234Status answers what the runtime currently believes about the session. Recap gives a bounded, deterministic view of recent retained messages and markers. History lets you inspect the conversation beyond that summary. A recap is not another model's claim that everything looks fine; it is assembled from persisted records and reports its bounded view.
Look for the last completed tool result, an interrupted turn, a pending request, and the session's failure classification. Then compare the conversation to the checkout. In a Git repository, these read-only commands give you the current files and revision to compare with the recorded work:
git status --short
git diff --stat
git diff
git rev-parse HEADDo not attribute every modified file to the missing agent. Some may predate the task or belong to another developer. Use the task's starting state and retained history where available, and leave uncertain ownership explicit. Recovery should preserve the evidence you already have.
The session owns the record; the process does the work
In CompozyOS, creating a session allocates a durable ID, workspace association, permission policy,
and storage. It does not immediately launch the provider. A newly created session can be active
with runtime.status: "unbound"; the first prompt binds its execution runtime.
That is why “active” alone cannot tell you that a model is generating text. It describes the logical session's lifecycle. The daemon also exposes runtime and activity information so clients do not have to infer liveness from an old assistant message.
The pieces fit together like this:
CLI, Web, or desktop
|
v
CompozyOS daemon
session identity + metadata + retained events
|
| ACP connection, when a runtime is bound
v
Agent provider process
|
v
Configured model serviceThis is an ownership diagram, not a deployment requirement. The local daemon manages the session; the selected provider determines how agent execution and model access happen. Running a local runtime does not imply local model inference.
An AGENT.md file supplies reusable instructions and configuration. An optional SOUL.md supplies
persona. Neither is the running process or the conversation archive. CompozyOS snapshots the soul
at session creation, so editing that file is not a way to rewrite the persona of an existing
session. See the agent definition and soul
contracts when changing those inputs.
This separation is the useful part of the “operating system for AI agents” idea: the interface can come and go while one runtime owns the record and the operations on it. It also gives recovery a place to start. You can ask the daemon what happened even when there is no provider process left to answer.
If only the interface closed, attach to the live session
A browser refresh or a closed CLI does not by itself mean the daemon's session stopped. Check for an eligible live session:
compozy session list --resumable
compozy session resume sess_1234Despite its name, session resume is an attach operation. It acquires a holder lease on an
eligible live session. It does not launch a replacement provider, load a stopped session, or start
another attempt at your task.
The distinction is easy to verify in the
CLI client:
ResumeSession sends a request to the session's /attach endpoint. The
manager
acquires the attach lock and updates the live session snapshot.
If another holder has a live lease, attach can be refused. That is a reason to inspect the existing work and holder, not to create a duplicate worker. If the record is still busy, determine what it is doing before issuing more instructions. The attach reference covers lease duration and conflicts.
If the session stopped normally, continuation uses a prompt
A deliberate stop ends the provider runtime while preserving the session's directory, metadata, events, and selected runtime. If you need to stop an agent before handing the checkout to another worker, request a stop and wait for its reported result:
compozy session stop sess_1234 --wait -o jsonRead that result. A requested stop and verified process termination are different facts. CompozyOS first requests cooperative cancellation and can escalate to stopping or killing the process. When it cannot verify termination, it reports that uncertainty instead of declaring the work stopped. Do not start a competing writer on the assumption that clicking Stop was sufficient.
For an eligible stopped session, a normal prompt is the continuation path:
compozy session prompt sess_1234 \
"Continue from the retained history. First inspect the current diff and identify the last completed verification. Do not repeat an external action without checking its result."The implementation routes a normal prompt through
lookupOrResumePromptSession,
which can restore an eligible stopped session before submitting work. This keeps the CompozyOS
session ID and retained history. It is a different path from the public attach command.
Restoration still depends on valid workspace and provider infrastructure. Preserving an ID does not guarantee that credentials remain valid, that a directory still exists, or that every provider can reproduce its private execution state. Inspect a restoration failure rather than interpreting it as evidence that the retained conversation disappeared.
If the provider died, preserve the failed attempt
An unexpected provider exit can leave a terminal process_exit failure. That session remains
available as read-only history; ordinary prompting and attach do not revive its dead runtime.
The resume guard
checks terminal process failure against session health before allowing restoration.
A daemon crash requires another check: did the provider die too? The implementation
classifies interrupted metadata
using process-exit verification. If it cannot prove the process ended, the session can remain
stopping with a verification failure. An unbound session has no process to lose and is treated
differently. These details are why recovery should use current status instead of assuming that
all records visible after a restart are safe to rerun.
For a confirmed terminal failure, create a new session in the same workspace, linked to the old one:
compozy session new --cwd "$PWD" --agent general \
--parent sess_1234 --name pagination-continuationRun this from the original repository and select the agent you intend to use. The parent link records provenance: this attempt follows that attempt. It does not copy every piece of provider context, transfer an acceptance decision, or apply the lifetime and permission restrictions of safe spawn. Give the new session a continuation brief explicitly.
If the conversation ends with a dangling tool call, you can first inspect planned transcript repairs:
compozy session repair sess_1234 --dry-runThe repair operation can append interrupted results and a terminal error for unfinished turns. It does not finish the command or undo its side effects. A repaired transcript saying “interrupted” therefore leaves a real question: what happened to the file, job, or external system involved? Inspect that result directly before deciding whether to repeat the operation.
Keep history and the checkout separate
CompozyOS retains live session events in its event store, and that store is the source used to
reconstruct the conversation. Read it back with compozy session events and
compozy session history. Session storage documents those boundaries.
For the pagination task, those records answer different questions. History may say the agent changed the pagination link. The current diff shows whether the change is still present. The project's own conventions, such as the rule that URL state owns filters, live in the repository and its instructions. None of those facts establishes that the browser scenario passed on the current patch, and a summary of earlier work cannot decide that an old task should resume or that an unverified patch is accepted.
The same distinction applies to authority. A prior approval in a transcript is evidence of a decision at that time, not a universal grant for the next session. Pending interactions can survive while their provider turn disappears; resolving an orphaned interaction does not revive that turn. Check the permission contract before relying on a remembered or resumed approval.
Leave the next attempt a concrete handoff
Carry over the original acceptance criteria, not just the last conversation summary. The coding agent task brief gives a worked example of the behavior and evidence a reviewer needs at the end of the next attempt.
A useful handoff is shorter than the transcript and more specific than “pick up where we left off.” Fill this template from the retained evidence and the actual checkout. The placeholders are intentional; do not fill a missing test result with an inference from the final message.
Continuation task: Preserve issue filters across pagination
Previous attempt
Session: [original session ID]
Workspace: [absolute path and workspace identity]
Stopped because: [status/failure observed, with timestamp]
Original process: [verified stopped / unresolved]
Current artifact
Revision: [commit ID]
Uncommitted changes: [files and relevant diff]
Unrelated changes to preserve: [known list, or ownership unknown]
What is established
[Completed edits and the evidence for each]
[Checks with actual results and the revision they checked]
What remains uncertain
[Last incomplete tool call or missing result]
[External action whose outcome still needs inspection]
Next step
Inspect the current diff, then verify the page-two filtered URL.
Reuse the existing route suite and browser scenario from the brief.
Do not redo completed work without a reason grounded in the current files.
Done when
[Original acceptance criteria and required evidence]You can now choose the next operation from the evidence:
Is the original runtime confirmed live?
Yes -> inspect it; attach if eligible.
Uncertain / stopping -> resolve liveness before another writer starts.
No -> inspect the stopped record.
Eligible normal stop -> send an explicit continuation prompt.
Terminal process_exit -> create a linked session with a handoff.In the opening example, the useful recovery result is not merely a chat window that opens again. It is a known process state, a preserved patch, an honest list of unfinished checks, and one next action that will move the work toward its original acceptance criteria.
