Skip to content
EvalBook

Readiness and operations

The liveness and readiness endpoints with their five checks, the job queue, the outbox and inbox, the daily retention purge, and what an operator does when a check fails.

EvalBook answers two questions on two unauthenticated routes. /health is liveness: is the process up. It touches nothing, so a database that blinks cannot make a restart policy kill a healthy process. /ready is readiness: can this instance do its job. It runs five checks and answers 200 or 503.

An anonymous caller of /ready gets { "ready": true } or { "ready": false } and nothing else: an open endpoint that names the dependency that is down is a map for an attacker. The detail is for a platform admin on Admin → Readiness (platform/api/readiness, run fresh) and for a monitor that sends Authorization: Bearer <EVALBOOK_DIAGNOSTICS_TOKEN> (at least 32 characters). Results are shared for 5 seconds so polling cannot become load; the response carries Cache-Control: no-store.

The five checks

Each check is pass, warn or fail. Only a fail makes /ready answer 503; warnings leave it ready and are named in the reason.

Check Passes when Fails or warns when
database every context (authContext, userContext, evalContext) answers SELECT 1 fail: any context does not answer
sso SSO accepts this app's token at apps/api/bootstrap (cached 30 s, 4 s timeout) fail: SSO_APP_TOKEN is not set, or SSO refuses it; nobody can sign in
encryption EVALBOOK_ENCRYPTION_KEY is set and is 32 bytes fail: missing or the wrong length
peers the peer directory has an answer from SSO or from local overrides warn: the answer is a cached one, or there is no token and no overrides; fail: SSO reports EvalBook as switched off, or SSO is configured and has never answered
queue no due job has waited more than 10 minutes warn: due jobs are waiting, so no worker is claiming; fail: the job table cannot be read

The job queue

Every background task is a Job row with its JobAttempt history, claimed by the worker process. The API only enqueues (unless EVALBOOK_INLINE_WORKER=1, for local work). In the container the worker is its own process, and the container exits if it stops. The queues are evaluation, scoring, ingestion, judge, analytics, delivery and maintenance; the registry decides each job type's queue, attempt limit and timeout.

  • Claims are atomic and fair: round-robin over the organizations with due work, so one organization cannot starve another.
  • Claims are leased for 60 s with a heartbeat every 15 s. Past the lease the job is taken back: requeued, or failed if its attempts are spent.
  • Claims are fenced: each claim increments a fencing token, and a completion, failure or heartbeat is accepted only with the current token.
  • Failures have classes: transient retries with backoff; permanent and deadline_exceeded fail now; cancelled is cancelled; outcome_unknown parks the job as awaiting_reconcile for a reconcile step or a person. Nothing that may already have happened is blindly retried.

The API and the worker execute no customer code. Executable scorers run only in the separately installed, outbound-only runner; see Executable verification.

Outbox and inbox

A fact and the message that announces it to CodeBook or MadeBook commit in one transaction: the message exists if and only if the fact does. The outbox.deliver job sends each message signed and keyed. Backoff is 30 s, 1 m, 2 m, 4 m and so on, capped at 30 m; after 17 attempts (about six hours) the message is failed, stays visible, and a person may send it again. A message goes only to an app the peer directory names, under that app's API base.

Inbound events are deduplicated by (source app, idempotency key) with a payload digest: the same key with the same digest is a duplicate; with a different digest it is a recorded conflict, answered 409, never applied. See Peer links.

The daily purge

retention.purge runs once a day. It applies each project's retention policy per content class (raw_bodies, traces, results, cost_records, audit_metadata), writes a retention receipt shown on Settings → Privacy & retention, and leaves tombstones. See Retention, export and deletion.

When a check fails

What you see Where to look
sso fails SSO_ORIGIN and SSO_APP_TOKEN; whether EvalBook is registered and switched on at SSO
encryption fails EVALBOOK_ENCRYPTION_KEY: 32 bytes as 64 hex characters or base64
peers fails the same SSO registration (it only warns while a cached answer is reused)
queue warns the worker process (in the container it starts once the API answers /health)
database fails EVALBOOK_DB_*; the container refuses to start, naming the first missing variable

The variables are listed on Deployment; the views are on Platform admin.