Skip to main content

Durable Jobs and Monitors

Meerkat’s detached job subsystem owns long-running execution outside an agent turn. Submission commits a stable job record before returning. The generated DetachedJobMachine then owns attempts, leases, fencing, progress, cancellation, retry, and terminal result.
Detached means durable. A persistent realm job store, blob store, runtime delivery projector, and canonical session/operation binding are required. Memory realms, ephemeral services, WASM, and other hosts missing those pieces fail closed. There is no volatile background fallback.

Background Shell Jobs

The agent-side shell tool submits a durable, non-resumable job when background: true:
The receipt contains a stable job_id. Use shell_job_status, shell_jobs, and shell_job_cancel from the same shell tool surface. The job record and its terminal delivery survive restart, but the Unix process does not become resumable. If the process is lost, the current attempt becomes worker_lost after its committed lease expires. Meerkat never silently replays a non-resumable shell command. command: "some-command &" is different. It follows the foreground shell path, creates no Meerkat job ID, and leaves any surviving child unmanaged.

Lifecycle And Restart Contract

Safe job projections use these phases:
Runner restart classes state what recovery may do: Worker attempt IDs and fence tokens are host-only. App projections expose the job ID, runner, phase, restart class, attempt count, progress, cancellation request, terminal result, subscription count, and delivery backlog.

Public JSON-RPC Surface

The public job surface is JSON-RPC plus the generated Python and TypeScript SDKs. There is no general REST, CLI, or public MCP job-management surface. Agent shell tools provide their own job-oriented commands. Read a job:
Cancellation is a request until the current worker proves containment and acknowledges the machine transition. Continue observing the job instead of assuming the first cancel response is terminal. jobs/retry does not grant callers a second execution authority. The machine admits it only from a compatible loss state and keeps the existing job ID and attempt history.

SDK Method Names

Durable Delivery Subscriptions

A subscription has a caller-stable subscription_id, target session_id, and delivery kind:
  • record stores the observation without notifying the conversation.
  • notification produces durable user-visible notification delivery without opening a provider turn.
  • event requests ordinary agent work with handling_mode: "steer" or "queue".
Unsubscribe and cancel are deliberately separate. Unsubscribing stops future delivery to that subscription but leaves the job running. The job outbox and runtime inbox form an ordered, replay-safe handoff. A crash on either side retries the same durable identity, and the origin session can be woken from idle keep-alive without keeping a provider call open.

Script Monitors

monitors/start is a convenience submission surface over the same durable job authority. It is high trust because it starts an agent-authored process. The host must have a persistent realm, shell capability, and an explicit project or working-directory context.
Protocols:
  • framed_jsonl accepts typed notification, progress, checkpoint, and completion frames. A notification never terminalizes the job.
  • lines turns stdout lines into notifications. It cannot provide stable per-observation identity and therefore requires non_resumable. Prefer framed JSONL for replay-sensitive work.
Script monitors may declare checkpoint_resumable, replayable, or non_resumable. They cannot claim adoptable, because an ordinary script has no stable external runner handle that proves adoption. Inside an agent session, the shell tool set exposes the related monitor_start tool. It uses event_steer and event_queue shorthand for event delivery and otherwise shares the durable monitor authority.

Health

jobs/health returns:
status is ok, degraded, or unreadable. degraded means the census actually observed a wedged condition. unreadable means the census could not establish any result. Independently, truncated coverage has the shape {"kind":"truncated","scanned":N,"limit":N} and makes phase counts lower bounds. pending_outbox_jobs and runtime_inbox_backlog name different seams. The first is realm-scoped and counts jobs whose delivery has not reached a runtime. The second is host-store scoped and counts deliveries a host runtime accepted but has not drained, including sessions from other logical realms served by that store. Legitimately long or awaited work is not degraded by duration alone.

Compose Without Merging Authorities

Schedule

ScheduledDurableJobRunnable derives a stable submission key from the occurrence, submits or ensures the job, and lets the occurrence complete after durable acceptance. Schedule redelivery then finds the same job instead of launching duplicate work. Schedule owns due time; the job machine owns the execution.

WorkGraph

JobWorkGraphLink associates a job with a commitment. JobTerminalEvidenceProjector projects typed terminal evidence and requests closure, but WorkGraph still applies its completion policy. Job execution must also work when WorkGraph is disabled.

Waiting Sessions

Embedding hosts use JobAwaitCoordinator::await_job to create a durable DetachedJobWait operation for a session. It records intentional waiting and can be reconstructed after restart; it never keeps a provider call open. Notification subscriptions are independent from this wait binding.

See Also