> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpander.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Resident processes

> Draft. A harness agent's task stays In progress for hours, days or weeks until the agent says it is done. Messages reach it while it works, it survives fleet rolls and restarts, and waiting costs nothing. Rolling out in three phases from September 2026.

> [!NOTE]
>
> **Draft.** This page describes a change that is on staging and not yet in production. It stays out of the navigation until Phase 1 ships. Until then the pages listed at the end describe the product as it runs today.

## What changes

Today a conversation with an agent runs one turn per message. A turn ends when the harness finishes, when it has produced no output for a set time, or at a hard duration cap. Anything the agent left running dies with the turn, a question ends the turn, and a deploy roll stops it.

With resident processes, a harness agent's task is one **process**. It shows as **In progress** from the first message until the agent itself calls `finish_process`. While it runs:

* Every message you send is delivered into the running process. There is no new turn and no re-routing.
* The agent posts progress notes and asks questions without stopping. The task pill shows the latest note instead of "running".
* A process that waits, for you, for a pull request, for a time, parks to disk and holds no capacity. It wakes into the same files, the same git tree and the same conversation.
* A fleet roll, a scale-in or an executor crash parks the process and resumes it. You see nothing.

This is the default for every external-harness agent. There is no flag and no per-message choice.

## The three calls an agent has

The harness already talks to xpander on every run. Three calls carry the model:

| Call | What it does | Ends the process |
| - | - | - |
| `finish_process(summary)` | The only way the agent ends the process. The task turns **Completed** with the summary. A plain text answer is a message to you, not an exit. On Claude Code, the call does not end the process while a shell command the agent started in the background is still running; see below. | Yes |
| `wait_for(until \| event, reason)` | Declares what the process waits for: a time, a GitHub webhook matching this pull request, a Slack reply, the answer to a question. The process parks at once and wakes when the condition lands. | No, parks |
| `tell_user(text, questions?)` | The agent's voice. Without questions, a progress note in the activity thread, live in Xpander Chat and in channels. With questions, the existing question card. The call returns immediately; the answer arrives as a steer. | No |

While work the agent started is still open, `finish_process` is held: a sub-agent still running, a question card it raised that you have not answered, or a wait it booked. The call records nothing and answers with what is open, so the task stays **In progress**; the agent finishes once the sub-agent reports, the answer arrives or the wait ends.

Asking never stops the task. The question card sits in the activity thread while the agent continues work that does not depend on the answer, or calls `wait_for` and parks. Answering on the card, or typing a reply, delivers the answer into the process.

On Claude Code, if the agent tries to finish while a command it started in the background is still running, the task does not complete. It stays **In progress**, shown as **Working**, and the agent is told which commands are still running. The task completes once those commands have finished or been stopped and the agent finishes its work. A command still running after 240 minutes no longer keeps the task open. You do not have to wait: archiving the conversation ends the process, and the background command ends with it. Pressing **Stop** ends only the agent's current turn; the task stays **In progress**.

## Task states

You see one status, **In progress**, for the life of the process. Underneath it a substate tells you what the agent is doing.

| Substate | Meaning | Holds capacity |
| - | - | - |
| Working | A model call, an action or a background shell command is running; a background command holds Working for up to 240 minutes | Yes |
| Idle | The agent awaits input and you have the conversation open | Yes |
| Waiting | Parked until a time, an event or an answer | No |
| Blocked | An approval a person must grant | No |
| Needs attention | Repeated crashes; the process is parked and you were notified | No |

Three exits exist: **Completed** when the agent calls `finish_process`, **Stopped** when you press **Stop**, and **Failed**, which only an operator sets. xpander never fails a process on its own. A process that is never finished asks "still needed?" after a period of idle days and finishes itself with a summary after a longer one; both periods are per-install settings.

## Conversations

A sub-task is a process. A conversation is a chain of processes.

1. The first message in a conversation starts a process on the harness agent.
2. While that process is live, in any substate including Waiting, every later message is delivered into it. A message to a parked process wakes it.
3. When the process is Completed or Stopped, the next message starts a new process. The conversation shows both cards, for example "Fix PR 5678" Completed and "Cut the release" In progress.
4. Parallel work is a new conversation, like another terminal tab. Two processes of one agent get their own working trees and never edit the same files.

The harness session is per conversation, so a finished process's context carries into the next one. "Now do the release" remembers the pull request it just merged.

Omni follows the same rule one level up. Dispatching to a harness agent creates a process; follow-ups become steers into it; the child's notes and questions appear in Omni's thread; the result comes back when the child finishes. Omni's own conversation is never blocked by a week-long child.

## What stops happening

| Today | With resident processes |
| - | - |
| No output for 15 minutes ends the turn, even mid-build | Working state is read from the harness's own signals: a model call in flight, an action that has started and not finished, CPU in the sandbox. Silence is not a signal. A stuck action is flagged and the agent is nudged, never killed. |
| A turn stops at 2 hours | The cap becomes a segment budget that parks and resumes; you never see it. |
| A dev server or watcher dies when the turn ends | Phase 3 adds agent services that live for the life of the process. |
| A task may re-schedule itself 3 times | No cap; `wait_for` chains freely. |
| A deploy roll stops the turn with "send the message again" | The process parks and resumes when its executor is back. |
| A question or an approval holds a fleet slot for up to 4 hours | The process parks at no cost; the answer or decision wakes it. |
| Three ways to ask a question, one of them a trailing "?" | One call, one card, one answer path. |

## Harness differences

Claude Code gets a true hot session from day one: the harness stays open between messages while you are present. Codex and OpenCode run resident with a park after every turn until their multi-turn drivers exist. The experience is the same; the wake is slower.

## For operators

* Only a hot segment holds a fleet slot. Parked processes cost nothing, so hundreds of waiting processes coexist with a small fleet. Autoscaling demand is pending wakes plus hot segments.
* Parking is presence-based: with nobody in the conversation for a couple of minutes the segment parks. A safety timer sits underneath for a stream that never closed. `wait_for` parks at once.
* A process lives on the executor volume that holds its agent's home directory. A demand floor keeps that executor's ordinal alive while a process waits on it. Nightly volume snapshots join the infrastructure as code.
* Credentials are per segment: the turn token is minted at claim and revoked at park. A week-long process never holds a credential for a week. Provider keys never reach the harness, as today.
* A process pins the harness version it started on. Roll-forward happens at finish or at an explicit park, never mid-flight.
* Log events per process: `process.start`, `process.park` with reason, `process.wake` with trigger, `process.crash`, `process.finish`. A staff page and `GET /fleet/processes` list every process in the organization with state, volume, executor, age and last update.
* Billing is per segment: compute from the sandbox at park, tokens per response through the proxy, rolled up per process in the task view.

Defaults proposed in the design and still to be confirmed:

| Setting | Proposed default |
| - | - |
| Park after absence | 2 minutes, with a 30-minute safety net |
| Disk for developer-machine agents | 20 GiB |
| "Still needed?" nudge | 7 idle days |
| Self-finish with summary | 30 idle days |

## Phases

| Phase | Name | Scope | Estimate | Status on 2026-09-20 |
| - | - | - | - | - |
| 1 | Runs until I'm done | Resident is the default execution kind; process registry and reconciler; hot segments on open stdin, park and resume; watchdog and drain outcomes become parks; `finish_process`, `tell_user` updates and the progress entry; steer into hot or parked; In progress pill with substate; removal of the legacy ask builtin | About 2 weeks | Merged, on staging |
| 2 | Waits, wakes, one way to ask | `wait_for` with time and event wakes; working-state detection; presence-based parking; `tell_user` questions with the other doors closed; per-process budget and the staff process page; per-process working tree | About 2 weeks | In development |
| 3 | Hardening and parity | Crash backoff with the reason handed to the agent; demand floor; approval holds as parks; agent services; harness version pin and volume snapshots; GitHub App credential broker, screenshot quality, bring-your-own-setup importer; Codex and OpenCode multi-turn drivers | About 3 weeks | Plans approved |

A message is one turn of the conversation, streamed token by token, and the conversation record keeps the whole thread. See [Conversations, tasks and files](https://docs.xpander.ai/use/agents/conversations.md) and the [Conversations API](https://docs.xpander.ai/api-reference/v1/agents/conversations/overview.md).

## Still open

Decisions the design asks for:

* Keep or drop the two "Ask user" display labels in Xpander Chat and the legacy frontend.
* Confirm the defaults in the table above.
* Confirm the names `tell_user`, `wait_for`, `finish_process` and `start_service`.

Risks named in the design:

* Session growth over weeks. Claude Code compacts on its own; Codex has no compaction on resume and long Codex processes lean on the handoff digest.
* The volume pin keeps an executor from scaling in while a single process waits on it.
* Docker inside the sandbox is not available yet.
* A personal Claude Max subscription cannot be used; API pricing applies.

## Pages that change

| Page | What it says today | Phase |
| - | - | - |
| [Agents and conversations](https://docs.xpander.ai/use/agents.md) | "What launching does" (an executor and a sandbox per turn) and "When a session ends" (the inactivity limit, the duration cap, resume on next message) | 1 |
| [Xpander Chat](https://docs.xpander.ai/use/app.md) | "Tasks and the execution log": each run is a task; "Approvals": a card that holds the run | 1 and 3 |
| [Permissions](https://docs.xpander.ai/use/agents/permissions.md) | Gated commands hold the run for approval | 3 |
| [Budgets](https://docs.xpander.ai/use/agents/budgets.md) | A budget stops the run at its next model call; with resident processes a budget parks with a reason and raising it resumes | 2 |
| [Sizing](https://docs.xpander.ai/self-hosted/sizing.md) | "Per Turn", "Concurrency Caps", "Safe Rollout, Drain, and Upgrades", "Reading the runtime logs" | 1 and 3 |
| [Conversations overview](https://docs.xpander.ai/api-reference/v1/agents/conversations/overview.md) | One task per message, streaming, the conversation record | Done |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.