Skip to content

Run and maintain

One a13n-service executable runs every part of the Service. All processes of a deployment share one PostgreSQL database, one Redis endpoint, one object store and one encryption key ring, configured identically.

Process roles

a13n-service --config service.toml run --role control
a13n-service --config service.toml run --role worker
Role Serves Background work
control The HTTP API, thread streams, /api/v1/openapi.json and the interactive API page at /api/v1/docs. All maintenance sweeps and deliveries.
worker Only /healthz and /readyz. Claims accepted runs and executes them with the Harness.
all (default) Everything control serves. Everything control and worker do.

Run all for a single process. For larger deployments, run any number of control replicas behind a load balancer and any number of worker replicas; workers accept no API traffic. Sweeps coordinate through database row claims, so every control replica runs them safely.

Each worker executes up to worker.slots attempts at once. It holds a lease on each attempt and renews it every worker.authority_seconds, rechecking cancellation and the principal's current access at the same time. When a worker stops renewing, for example because it crashed, the lease expires and another worker continues the run from its last checkpoint. A run fails after it has been charged worker.max_attempts attempts.

On shutdown a worker stops claiming, asks its attempts to hand off at their next safe boundary and waits up to worker.drain_seconds; another worker then continues them without charging an attempt. Attempts that do not finish in time are recovered after their lease expires.

Schema migrations

a13n-service --config service.toml migrate          # upgrade to this build's schema
a13n-service --config service.toml migrate --check  # verify the schema matches without changing it

With database.auto_migrate = true (the default), all and control processes migrate at startup. Every migration holds a PostgreSQL advisory lock, so concurrent starts migrate once; database.migration_advisory_lock_timeout bounds the wait for it. Workers never migrate. Every process checks at startup that the database schema is exactly the one its build expects, and refuses to start otherwise ("run a13n-service migrate").

For a dedicated migration step, such as the Helm chart's migration Job, set database.auto_migrate = false on replicas and run migrate before starting them. During rolling upgrades, older replicas keep serving against the migrated schema, so review each release's schema changes for compatibility with the previous one.

Health and readiness

Endpoint Response
GET /healthz Always 200 {"status": "ok", "role": "<role>"} while the process serves HTTP.
GET /readyz 200 {"status": "ready", "role": "<role>"} once startup finished, background tasks are running and the database schema is usable.

Readiness returns 503 {"status": "unavailable", "dependency": "runtime"} before startup completes or after a background task stopped, and "dependency": "database" when the schema cannot be checked within server.readiness_timeout. Losing Redis keeps the process ready and adds "degraded": ["redis"], because Redis only speeds the Service up.

Background work

Control processes run these sweeps. Each pass handles a bounded batch (control.sweep_batch), and a failed pass is logged (Sweep failed) and retried at the next interval.

Sweep Interval Work
advance_threads control.scan_seconds Starts the next queued input of idle threads.
expire_leases worker.authority_seconds Ends attempts whose lease expired, so the run continues on another worker or fails.
expire_credentials auth.expiry_scan_seconds Deletes expired or revoked login sessions, mail links and unaccepted invitations.
maintain_environments environments.scan_seconds Stops or deletes managed environments idle past their template's thresholds, and continues unfinished provider operations.
renew_environments environments.scan_seconds Renews ready hosted sandboxes that would otherwise end, each call bounded by environments.renewal_seconds.
recover_connection_operations providers.operation_scan_seconds Settles connection authorization operations whose owner disappeared past their deadline.
deliver_outbox control.scan_seconds Delivers webhooks, identity mail and subagent results.
purge_outbox hourly Removes settled deliveries older than control.outbox_retention_days.

Deliveries are at least once. A sender claims a batch of control.outbox_batch rows for control.outbox_lease_seconds; a failed delivery is retried with exponential backoff (up to one hour between tries) until it has used control.outbox_attempts attempts, and is then marked dead. Webhook subscribers can inspect and redeliver deliveries through the API; see webhooks.

Operator commands

Command Purpose
a13n-service bootstrap --email EMAIL [--password-stdin] Creates the first organization, workspace and administrator. Prompts for a password of at least 12 characters, or reads the first line of standard input. Prints the new IDs as JSON; exits 3 without changes when the Service is already initialized, and 1 for invalid input.
a13n-service user disable --email EMAIL Disables a user's account; see operator account control.
a13n-service user enable --email EMAIL Re-enables it with the grants and keys it had.
a13n-service migrate [--check] Migrates or checks the database schema.
a13n-service run [--role ROLE] Runs a process.
a13n-service --version Prints the installed version.

Pass --config before the command name. bootstrap, user and run refuse a database whose schema does not match the build.

Logs

Processes log through a13n-logging in the format chosen by telemetry.log_format. HTTP access logging is off, so request URLs, including authorization callback parameters, are not logged by the Service; configure proxies in front of it to redact query strings as well. Every response carries an X-Request-Id that also appears in error bodies.

Backups

Back up PostgreSQL, the object store and the encryption key ring together. Stored credentials cannot be decrypted without the key that wrote them, and run checkpoints, displays, assets and skill packages live in the object store.