ADR-0052: The judges' lab goes live three ways, each wired with no hand edit
Status: accepted · Date: 2026-10-26 Decided by: the owner · Written by: the executor of wagon W17, round 2 Follows: ADR-0013 (no hardcoded settings), ADR-0017 (the lab), ADR-0019, ADR-0023, ADR-0026, ADR-0031 Trigger: the owner's four relays of 26 October 2026, 00:45 to 01:00 UTC. Number note: ADR-0051 is held for the judges' gateway (wagon W18). This record takes the next number after it.
Context
The lab's workflow ran proven scan --sample and passed no key, so the pull-request reviews in the lab could never be
live, even for a judge who owned an NVIDIA key. make livecheck read lab/.env; nothing else did. Judges have three
different starting points: a free NVIDIA key and nothing else; a token for our services through the judges' gateway; or
their own Zetaris account and a Mac. Each must reach a live review with no hand edit of a file in the repository, and
each must be written down step by step (every act a person must do has numbered steps in the docs).
Decision
- One mechanism for the keys.
make upreadslab/.env. Each non-empty setting named inLAB_LIVE_KEYS(lab/versions.env) becomes an Actions secret of the demo repository. A credential (LAB_SECRET_KEYS) reaches the seed as one 0600 file of the lab's state volume,/state/secrets, written bymake upover standard input and removed by the seed on every exit and again bymake up; it is named nowhere in Compose and is in no container's environment, sodocker compose configanddocker inspectnever show it. A setting that opens nothing (a mode, an address, a model name) still passes by name through Compose. Each value goes to Gitea over a pipe and is never written to an image or a log; the log names the settings it stored. An empty setting is not stored, and a secret that was emptied is removed, so the lab can return to sample mode. (Amended in round 5: before it, the credentials too were passed by name through Compose, and a render of the Compose file or an inspect of the seed showed them.) - The workflow chooses. It runs a live review when the gateway pair, a Nightshift token or a generator key is
stored, in that order of precedence, and a sample review otherwise. The first visible line of Proven's comment says
which:
sample: no keysorlive: <generator>, Zetaris on|off. The marker comment stays the first line of the body, becausemake e2eand the comment-update logic read it there. - Path A, one NVIDIA key. The key alone makes the lab run in
nvidiamode and serves the guardrail too, unless a guardrail key is stored. - Path B, the judges' gateway. The gateway's address and the judge's own token are two settings
(
JUDGES_GATEWAY_URL,JUDGES_GATEWAY_TOKEN). The workflow points Proven's Nightshift address and Zetaris address at the gateway and sends the judge's token; our own Nightshift token and Zetaris key never reach the lab. The names are this lab's, chosen because W18's order was not available to this wagon; if the gateway uses others, only the settings change. The gateway's boundary (who may call, rate limits, logging, read-only Zetaris) is W18's and is decided in its own record. - Path C, on the judge's machine. Zetaris: the sponsor's platform is a bundle from the judge's own account, with
images in the sponsor's registry behind a sign-in. No terms in this repository say a judge may pull and run them
(searched 26 October 2026), so
make up ZETARIS=localruns the judge's bundle with the judge's sign-in and says so; the lab carries neither. Our override publishes the console and REST service on127.0.0.1only and attaches the REST service to the lab's network. A compose profile service registers the evidence definitions as the judge's Zetaris administrator; the key is used once and never stored. Nightshift:make nightshiftorchestrates the measured Tart steps on macOS with Apple silicon, and on any other host says Tart is macOS-only, points to paths A and B, and exits 0. The installer, the email gate, the provider key and the runtime token are acts in an app window with no API; they are numbered steps indocs/LAB.md. - Every address, port, image and VM name is a setting with a default (
lab/versions.env). No secret is baked in or printed. The runtime token is never read or printed by the lab: Nightshift shows it in its own window. - The start page is loopback only. It shows the lab's password, so it is published on
127.0.0.1, named in its own port line oflab/compose.yamllike every port of the lab (ADR-0026 point 7; no setting moves it), andmake uprefuses aLAB_PAGE_BINDthat names any other address, by name, before it starts a container. The renderer stages the page only inside the page volume, with mode 0600, and removes the staging file if it stops. (Both are repairs from the named review of round 1.)
Consequences
- A judge makes one file,
lab/.env, and runsmake up. A review that already ran is not run again when a key changes: the judge opens a new pull request. - A live review of a demo pull request reviews the sample set's change tree baked into Proven's image, not a clone of the pull request. That is the same set of files the pull request carries; cloning the pull request belongs to the CLI track.
- The guardrail's default is a model server of the judge's own. With a Nightshift or gateway generator and no guardrail key, a review names the guardrail as a failed service rather than skipping it (ADR-0005 stays on by default).
- Not measured by this change: a live review against any real service,
docker composeon the files, the sponsor's images, Tart. They are stated as not run in the status report of the round.
ADR-0051: A judge's lab reaches our model service and our evidence store through one gateway, behind Cloudflare Access (the judge's own expiring token is the fallback)
Previous Page
ADR-0053: All four Meterless engines are on by default, each with its own off setting, and Scout never lightens a change it cannot verify
Next Page