Skip to content

Inner workings

Run lifecycle

How a task becomes a running agent, how it stays observable, and what happens when it ends.

A run combines an immutable starting point with changing execution state. Its work item and resolved scopes describe what was launched; heartbeats, inbox messages, patches and the final result describe what happened afterward.

One run, from assignment to conclusion

The orchestrator resolves the checkout and snapshots the agent and its scopes. Later blueprint edits do not rewrite this run.

Resolve and freeze

Before provisioning, the orchestrator resolves the task’s repositories and workspace. For each repository, it constructs run-specific forge URLs and a read-only virtual Git key. It resolves service-container declarations when that feature is enabled.

The run keeps the agent snapshot and model, tool and network scopes it starts with. A policy that no longer fits the deployment’s current egress ceiling is refused during task creation. This check is performed in the control plane, not merely in the agent editor.

Boot and prepare

The provisioner launches the environment with the runner contract in its environment variables. The runner retrieves its work item and credentials, then clones the checkout and prepares repository environments before driving the harness.

Repository service declarations come from .ryph/services.yml. The operator must enable services, which allows the whole catalogue; images outside it must match the operator’s image allowlist. Services need a connected repository, since the declaration is read through the forge.

Memory-enabled runs receive a brief. Once clones exist, the runner compares the brief’s file evidence against the checkout and reports claims whose referenced files changed. This check is best effort and only covers the supplied evidence.

Work and stay observable

Three activities proceed alongside the agent’s work:

  • Heartbeats report liveness and execution phase to the orchestrator.
  • The historian receives transcript chunks and diagnostic events.
  • Conversational runs receive messages through the run inbox.

Heartbeat sequence numbers are monotonic, so a delayed heartbeat cannot replace newer state. The reaper periodically evaluates startup grace, missing heartbeats, cancellation and idle deadlines. Its purpose is to reconcile a run that no longer reports reliably, rather than trusting the container to always send a final result.

History uses a bounded retry buffer. Overflow or rejected batches can drop events; the emitter reports gaps when it can. A transcript is useful evidence of a run, not a guarantee that every byte survived a failure.

Submit while working

A conversational run can submit a patch before it finishes. This lets an incident responder propose a fix, hear when its pull request is merged or closed, and continue investigating.

Each repository ships independently. The bundle’s acceptance and the patch’s eventual submission are separate steps, so a forge failure does not have to invalidate an already accepted artifact. See Patch delivery.

Conclude and clean up

On conclusion, Ryph records the terminal state and attempts to revoke model, MCP and forge credentials. The egress token is different: it is a signed claim with an expiry and no per-run revocation lookup. By default it remains valid for up to 24 hours from issuance.

The run’s result and its patches can have different lifetimes. A run can be finished while a patch waits for approval or a delivery retry.

Environment cleanup depends on the backend. The runner normally removes its temporary checkout. On Docker, the reaper removes a run’s containers and networks once the run is no longer active. Kubernetes Jobs are removed after their TTL, an hour by default.

Follow the implementation

Read start task, runner execution, reaper, and run conclusion.