The builder could only create games; nothing noticed when a live template
stopped working, and there was no way to tell whether a builder change made
it better or worse.
- repair -id ID: boots an existing template as nodes run it; if it fails,
the same investigation as for a draft runs and the model changes only what
the diagnosis says. The worker handles "repair" jobs (gameId from the
panel) and opens "fix(games): repair ..." on draft/<id>; a template that
boots as it is reports "nothing to repair" and opens no PR. The boot and
fix loop is now shared by builds and repairs.
- validate.yml runs weekly and boot-tests every game; failed games are sent
to the panel (X-GBR-Event: games_boot_failed) to queue repairs.
- eval -ids all: builds games that already have a template from scratch,
blind, and scores each draft against it (boots, same image and app, ports,
ready line, settings found) into eval.md and eval.json.
- research skips our own sites, so neither research nor eval reads our
templates back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What a builder boot sees is now what a node does:
- First boots (untouched, or -as-deployed with exactly a new server's
settings) are deployed by the node-agent's BootTest in keep mode; the
builder only watches the console and inspects what's left. The Go copy of
the deploy (its own docker run, mounts and startup prefix) is gone. It had
drifted: it gave the image's VOLUME folders their own volumes, which nodes
don't, so saves there looked safe while every start loses them.
- Files written outside /server and /data are counted whatever their type
(it only counted config-like extensions, so .sav or .db saves went
unseen), including the image's VOLUME folders; logs, pid and lock files
and system folders are left out.
- Boot tests ask the server to stay up holdSec (60 s, test.yaml can set it)
after its ready line and to listen on every published container port
(needs the node-agent's matching BootTest).
- Steam apps are downloaded once per build into a gbr.cache volume and copied
into each boot, so later boots only check the files (STEAM_CACHE=off).
- RUNNER.md no longer suggests docker system prune, which deletes the
gbr-boottest network when nothing is using it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Launch options must be documented. A draft passed an option its server
doesn't have; servers ignore unknown options, so it booted and passed every
boot test while its setting did nothing. build now reads the pages research
based the variant on, in full, and the drafter rejects any launch option in
the startup command that none of them, nor the image's own scripts, mention.
Shell tools' options (mkdir -p, [ -n ...]) are skipped; the check is off
without sources.
The builder is game-agnostic:
- AUTHORING.md (the model's rules), the research prompt and the schema
describe the rules without naming a game.
- The draft prompt no longer includes real templates from the repo. Its
format example is one invented server (no real command, options, ports or
app id), checked by TestExampleTemplateFollowsTheRules.
- Comments, help texts, BUILDER.md and test fixtures use invented names and
values.
- TestBuilderIsGameAgnostic reads every game's name and id from games/ and
fails if any appears in the builder's code, tests, rules, schemas or docs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The start-up check read the token's account with GET /user, which needs the
read:user scope. A token with only repository scope, which is all the worker
needs, got 403 and the worker exited in a restart loop. On 403 it now
names the commit author from BOT_NAME (default gbr-bot) and still checks
push access on the games repo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The worker committed as a hard-coded "gbr-bot", and a token without Write
access only showed up when a build finished and its push failed. On start it
now reads the token's account (GET /user) for the commit author, and
refuses to run if that account can't push to the games repo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- research: searches SearXNG, reads the best pages through the reader, has the
model list the server's variants, then checks every Docker image and Steam
app it named for real before an admin sees it.
- build: first boot of the variant's images (skipping ones that need root),
a draft by the model, then the draft deployed with the node-agent's
BootTest like CI does; crashes, error lines and saves outside /server go
back to the model, three boots at most.
- worker: polls the panel's builder queue (outbound only), runs research or
build in a fresh clone, streams the output as the job log, and opens the
result as a pull request from the bot account.
- Dockerfile.builder, a workflow publishing gbr-builder:latest, and
BUILDER.md. Everything about where it runs comes from environment
variables; deployment files live outside this public repo.
draft now keeps its conversation in a drafter, so build can send boot
failures back to the same model session. The boot-test runner comment no
longer names its VM.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>