Daemon and client

Queue locally, run reliably

The client validates and submits work. The local daemon owns the queue and executes one request at a time.

Documentation home ยท Getting started

Start and stop

contd daemon start
contd daemon status
contd daemon stop

The default HTTP/JSON socket is:

$XDG_RUNTIME_DIR/contd/contd.sock

When XDG_RUNTIME_DIR is unset or not absolute, contd uses:

~/.contd/contd.sock

The matching gRPC socket adds .grpc. Both sockets use owner-only permissions. contd does not open a TCP listener by default. Override the path with --socket PATH on daemon, run, or submit.

daemon start launches the background process and waits up to ten seconds for it to respond. daemon serve is the foreground form used by the launcher or a service manager.

Submit work

contd run
contd run --follow --logs
contd run --follow --json

run finds and validates the config, submits a request, prints a stable request ID and run ID, and exits. --follow waits for job events. --logs adds live stdout, stderr, and AI output records.

Use submit when a script needs explicit paths or an idempotent request ID:

contd submit \
  --workspace /work/project \
  --config /work/project/contd.yml \
  --request-id nightly-2026-08-21 \
  --json

The workspace must be an existing directory. The config must be an existing regular file inside it. contd resolves symlinks before storing the request.

Repeating a request ID with the same parameters returns the existing request. Reusing it with different parameters is a conflict.

Queue lifecycle

queued -> claimed -> running -> succeeded
                         -> failed
                         -> timed_out
                         -> cancelled

Invalid requests are rejected. Requests queue FIFO by submission time. The daemon has capacity one, so later requests wait until the active run finishes or is cancelled.

The daemon renews a short lease and heartbeat while it owns a request. If it crashes, another daemon can reclaim an expired lease. The run keeps its own durable state, events, logs, artifacts, and reproducibility record.

Shutdown and recovery

daemon stop stops accepting new work, cancels the active run, waits for cleanup, and removes both socket files. A forced process exit can leave a lease behind, but it does not erase the queued request or saved run data.

The queue database lives beside the daemon socket. Run metadata and run-scoped files live with the submitted workspace. Clients can therefore read historical results after the daemon and containers are gone.

Socket APIs

The HTTP/JSON endpoint is intended for shell clients and the contd command.

MethodEndpointPurpose
GET/v1/daemon/statusRead daemon state and queue counts.
POST/v1/daemon/stopBegin graceful shutdown.
POST/v1/requestsSubmit a run request.
GET/v1/requests/<id>Read request and run state.
POST/v1/requests/<id>/cancelRequest cancellation.
GET/v1/requests/<id>/inspectRead the complete saved run inspection.

The gRPC service is contd.daemon.v1.Daemon on the .grpc socket. Its methods are Submit, Status, and Cancel. Both transports use the same queue and request records.

Foreground mode

contd run --foreground
contd run --foreground --verbose

Foreground mode skips the daemon and runs the normal executor in the client process. It is useful for interactive debugging. --verbose prints live job log events.