The builder must be game-agnostic, but its prompts named games: AUTHORING.md
(the model's rules) used three games as examples, the research prompt listed
two games' editions, the schema described containerUser by one game's image,
and every draft prompt included two real templates from the repo, so the
model saw, and could copy, other games' commands and options.
- AUTHORING.md, the research prompt and the schema describe the rules without
naming a game.
- The draft prompt's format example is now one invented server (no real
command, options, ports or app id), checked by
TestExampleTemplateFollowsTheRules against validation and the draft checks.
- 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 Valheim draft in #13 passed -maxplayers, an option Valheim doesn't have.
The server ignores unknown options, so the draft booted and passed every
boot test while its MaxPlayers 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. The model gets it back to remove or
spell correctly. Options of shell tools (mkdir -p, [ -n ...]) are skipped.
The check is off when there are no sources (draft run by hand, no reader).
Against #13's 11 real sources it flags -maxplayers and nothing else.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second Valheim build stopped before its boot test: told that
test.yaml's password "looks like a credential; map it under 'secrets'",
the model mapped it to a CI secret nobody created, and boottest-payload's
missing-secret exit ended the build.
- The validator now says to remove a test password first (boot tests fill
password settings with a throwaway value); secrets only when the server
can't start without a real one.
- Drafts with test.yaml 'secrets' fail the draft checks.
- build turns boottest-payload's missing-secret exit into feedback for the
model instead of an error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two problems a draft can boot fine with but break once an owner changes a
setting, both in the builder's Valheim draft:
- splitSettings: text settings used unquoted on the command line, directly
or through ARGS="-name ${SERVER_NAME}"; ./server $ARGS, so "GBRHosting -
My Server" reaches the game as several arguments. Suggests quoting or a
bash array.
- portSettings: game-port settings whose default isn't in defaultPorts, or
that owners can change although nodes always publish the same container
port. Internal ports (RCON, REST) and {PUBLIC_PORT_n} values are left out.
Both run on drafts only; AUTHORING.md gets the matching rules.
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>
`gbrgames draft -name <game> -image <image> [-steam-app ID]
[-first-boot report.json]` has a model write games/<id>/game.yaml and
test.yaml, then checks them like any template and sends problems back
for up to three fix rounds. Ollama (default qwen3.8:27b, OLLAMA_URL) or
Gemini (GEMINI_API_KEY).
The model gets AUTHORING.md (new: the house rules, from how nodes really
run servers and today's bugs: x-generate passwords, no published RCON
ports, containerUser, heap below the limit, env var naming, ready lines),
the inspect-image facts, the first-boot report and the two smallest
templates as examples. With Ollama the answer is forced into the
template schema, tightened for drafts so ports, install config, settings
and their descriptions can't be left out or null.
On top of validation and the image checks, drafts must:
- be complete: player ports, >=3 settings each described, real memory,
a readyPattern or settleSec
- name settings so they reach the container as variables the image reads
(ServerPassword -> SERVER_PASSWORD when the image reads SERVER_PASS)
- not leave files first boot saw outside /server (lost on every start)
A first boot showing the image dies within seconds on permission errors
(it needs root) stops the draft before any model call. A missing
readyPattern is filled from first boot's verified suggestion.
Valheim, which we have no template for: lloesche/valheim-server was
rejected as root-only; via SteamCMD (app 896660) qwen3.8:27b on a local
3090 Ti wrote a passing template in two rounds (~1 min). It is about
70% there: it chose "--save-dir /server", which Valheim doesn't have
(-savedir), and missed -crossplay and 2457/udp. The save check is a text
check; booting the draft itself is the next step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>