Overview
The backend is a Rust server that holds The Test Cabinet’s definitions and results. It distributes the test case definitions a runner needs to execute a run and stores the run records those runs produce, so every run and every published result is coordinated through one service.
Two interfaces are the backend’s cross-component contracts: its HTTP API and the public snapshot it exports. Everything else, including how it stores what it serves, is internal.
Responsibilities
Section titled “Responsibilities”The backend serves two kinds of client, described in Runners and Reporters:
- Runners (the CLI and driver) resolve test case definitions from the backend. The driver reports each run record back to it when the run finishes.
- Reporters (the web console, and the public site through the snapshot) read definitions and published results to display them.
Each runner resolves its run-container image from its own registry configuration.
The backend holds two bodies of data.
Test case definitions
Section titled “Test case definitions”Cases are authored in the repository’s test-cases/ and game-jams/ folders,
in the formats the testing pages specify. An ingest scan
copies each new or changed version out of the repository checkout into the
backend’s on-disk definition store, rendering the version’s reference mockups to
screenshots as it goes. The repository is the editing source and the store is
the distribution source a runner resolves at run time. Ingest caches a version
rather than transforming it.
A version’s baseline validation media lives in the checkout’s cold-storage
submodule rather than in its folder. Ingest copies it into the stored version’s
validation-baseline/, where the API serves it and the snapshot publishes it
(see where baselines live).
The deployed ingest sidecar fetches the submodule shallowly on every refresh of
its checkout.
Ingest writes each version as a resolved record whose shape the backend build defines, so a store is readable only by a build that agrees on that shape. The store records a record-format version stamped by the ingest that wrote it, and the backend compares it against the format the running build reads. A store stamped with any other format holds records the running build cannot read. The backend reports it unready, and the next ingest scan re-ingests the whole catalog so the store returns to a format it can serve.
Run results
Section titled “Run results”The stored run records with their reviews and links, persisted in a relational database (embedded SQLite by default, or PostgreSQL). A run’s proof, asset and validation media is written beside the definitions in the on-disk store rather than into that database. This is the system of record for every run, published or not.
A stored record can predate a change to the run record contract, leaving it unreadable by the running build. The backend records, per run, whether the build can read that run’s record and the record-format generation the decision was made under. Every run listing counts and serves exactly the readable runs, so a listing’s reported total equals the number of rows it can return. A build whose record format differs from the stamp on a row re-decides that row’s readability once at startup, before it serves.
The generation is pinned to the shape of the run record contract, which covers the record schema together with every schema it references, such as the gg capability set a gg run’s record embeds. The build records the contract shape each generation was decided against, and a change to that shape fails the build’s tests until it is either recorded under the current generation, which asserts that stored records survive it, or given a new generation.
A run the build cannot read stays reachable on its own terms. GET /runs/unreadable lists each such run’s lifted identity together with the error
its stored record produces, paged like every other listing, and DELETE /runs/{id} deletes it. Both act on the stored row rather than on the record, so
a published run is deletable here, being already absent from the snapshot and
the gallery.
Authentication
Section titled “Authentication”The backend stays on a private network. In a cluster
deployment it is a ClusterIP service with
no public Ingress, so reachability is the first line of access control.
On top of that boundary, bearer tokens identify who is acting:
- Reads are open. Resolving definitions and reading runs require only that the caller can reach the backend.
- Mutations require a token. The mutating run endpoints answer
401without anAuthorization: Bearer <token>header. Each token is resolved to an account by the standalone auth service, and the resulting review is attributed to that account.
The dispatcher authenticates with a shared service token
(TCAB_BACKEND_SERVICE_TOKEN) to claim queued jobs, and each driver
authenticates with the per-job token minted when its job was enqueued.
Review and publish
Section titled “Review and publish”A produced run reaches the gallery through two steps the backend mediates.
A run’s record is stored privately the moment the run finishes: the driver reports it when it posts the job’s terminal status, and the produced build and media land on the artifact service. The build is playable, so the run can be reviewed. Review attaches one review per account to the run.
Publish releases the run: its generated source to its own public repository and
its build to Cloudflare Pages. The endpoint gates the run, refusing a legacy run
with no review, and enqueues a per-publish tcab-publisher Job that the
dispatcher claims. When that Job reports a
terminal success the backend marks the run published, regenerates the public
snapshot from the full set of published runs, uploads it, and triggers a site
rebuild.
The backend serializes publishes so two operators cannot race on shared state, and it coalesces a burst of publishes into one snapshot generation, one upload, and one site rebuild. Regenerating the whole published set on each refresh keeps the operation idempotent.
Artifact reclamation
Section titled “Artifact reclamation”The backend owns the lifetime of a run’s tree on the artifact
service, reaching the service over
TCAB_ARTIFACTS_URL with the shared service token.
Deleting a run removes its row and then prunes its tree. The prune is best-effort, so the delete succeeds regardless of the data plane’s health.
A periodic sweep reclaims what a failed prune left, and anything else the volume holds with no run behind it. Each pass lists the service’s stored trees, keeps every tree whose id still has a run row, and deletes the rest once they are older than a grace window. The grace window covers the interval between a driver uploading a run’s tree and reporting the run terminal.
TCAB_ARTIFACT_SWEEP_INTERVAL_HOURS sets the pass interval and 0 disables the
sweep. TCAB_ARTIFACT_SWEEP_GRACE_HOURS sets the grace window.
A pass acts only on a run-id set the backend read and found at least one run in. A query that fails and one that comes back empty both abandon the pass, which is retried at the next interval, so a database fault or a backend brought up against a fresh database beside a populated volume leaves the volume intact. A failing tree listing abandons the pass the same way.
Review scheduling
Section titled “Review scheduling”The backend holds each account’s reviewer scheduling state: what runs that account wants to exist, and how fast it wants them arriving. The data is private to the account, stays inside the backend and the web console, and stays out of the public snapshot.
- A coverage plan declares cases pinned to a version, variant and engine, crossed with combinations and a target run count per cell. The backend expands the declaration into a matrix, counts what exists against it, and enqueues what is missing.
- A ladder applies the same machinery to an ordered series of cases, which each combination climbs until a gate stops it.
Run counts stay global while judgement stays per-account. A run someone else produced satisfies a plan’s target, while “unreviewed” means unreviewed by the requesting account and a ladder’s gate reads only that account’s own review, so two reviewers share the cabinet’s runs while keeping separate worklists.
Enqueueing is buffered and serialized. A plan holds a review buffer rather than firing its whole matrix, refilling it is an endpoint a caller invokes rather than a background daemon, and each plan’s or ladder’s top-up claims its row first, so two concurrent callers cannot both enqueue for one shortfall. The buffer is bounded unless the plan’s or ladder’s buffer target is unbounded, in which case a top-up enqueues the whole matrix.
Public snapshot
Section titled “Public snapshot”The public site shows published runs to anonymous visitors without reaching the private backend. The backend exports a snapshot of its published dataset to a Cloudflare R2 bucket, and the site build fetches that export.
- Only published runs are exported, apart from the redacted gg document corpus, which is not gated on publication.
- Writing the bucket takes the
TCAB_R2_*credentials, which the backend holds andtcab publish-referenceis given to upload a case’s reference frames. The bucket is read-only to everyone else. - The upload is atomic: a new generation is written first and a small pointer object is swapped in last, so a site build never reads a half-written dataset.
- After uploading, the backend fires the site’s deploy hook. The site build fetches the snapshot and produces static output without connecting to the backend.
Every connection flows outward from the backend, and what crosses into public reach is a read-only export of already-published runs. The snapshot’s file layout is specified in Public Snapshot.
Configuration
Section titled “Configuration”The backend is configured entirely through environment variables.
TCAB_BACKEND_CHECKOUT is the only required one. With the R2 and deploy-hook
variables omitted the backend still ingests, records reviews and publishes, and
regenerates the snapshot, skipping the upload and the rebuild.
| Variable | Purpose | Default |
|---|---|---|
TCAB_BACKEND_CHECKOUT | The repository checkout ingest scans. Required. | — |
TCAB_BACKEND_BIND | Bind address. | 127.0.0.1:8787 |
TCAB_BACKEND_DATABASE_URL | System-of-record database; the scheme picks SQLite or PostgreSQL. | sqlite://./tcab-backend.sqlite?mode=rwc |
TCAB_BACKEND_DB_AZURE_AD | Authenticate to PostgreSQL with a Microsoft Entra managed-identity token. | false |
TCAB_BACKEND_STORE | The on-disk definition store. | ./tcab-store |
TCAB_BACKEND_AUTH_URL | The auth service bearer tokens are verified against. | http://127.0.0.1:8789 |
TCAB_BACKEND_SERVICE_TOKEN | Shared token the dispatcher claims jobs with. Unset disables the claim endpoints. | — |
TCAB_BACKEND_ALLOW_EXPERIMENTAL | Offer experimental case versions to the UI. | false |
TCAB_ENV | Deployment environment name, selecting this backend’s entries in the reference-builds lockfile. | local |
TCAB_SNAPSHOT_COALESCE_MS | Sliding debounce a burst of publishes is coalesced over. | 60000 |
TCAB_SNAPSHOT_RETENTION_HOURS | How long a superseded snapshot generation is kept before it is pruned. | 24 |
TCAB_R2_* | Credentials and bucket the snapshot is uploaded to. | — |
TCAB_SITE_DEPLOY_HOOK_URL | The site deploy hook fired after each upload. | — |
TCAB_OPENROUTER_API_KEY | OpenRouter key the backend’s own model probes are billed to. Distinct from the runners’ OPENROUTER_API_KEY. Unset, a probe trigger fails with openrouter_key_missing. | — |
TCAB_REFERENCE_BROWSER | Headless browser used to render references at ingest. | image Chromium |
TCAB_GG_REFERENCE | Directory holding gg’s projected reference documents. The deployed image bakes them at /opt/gg-reference, projected by the same gg build the driver ships. | <checkout>/target/gg-reference |
TCAB_ARTIFACTS_PUBLIC_URL | Artifact service base URL, advertised to the web console. | — |
TCAB_ARTIFACTS_URL | Artifact service base URL the backend itself calls to prune and sweep run trees. Unset disables the prune, the sweep, and the snapshot’s artifact media fallback. | — |
TCAB_ARTIFACT_SWEEP_INTERVAL_HOURS | Interval between reclamation sweeps; 0 disables the sweep. | 6 |
TCAB_ARTIFACT_SWEEP_GRACE_HOURS | How old a run-less tree must be before a sweep deletes it. | 24 |
TCAB_ARENA_PUBLIC_URL | Arena service base URL, advertised to the web console. | — |
TCAB_GRAFANA_PUBLIC_URL | Grafana base URL, advertised to the web console. | — |
TCAB_SNAPSHOT_PUBLIC_URL | Public read base URL of the snapshot bucket, advertised to the web console. | — |
The backend binds 8787, the auth service 8789,
the artifact service 8790, and the
arena 8791, so all four coexist on one host.