A draft built on a ready-made image whose files all live outside /server
went round three times and ended as WIP, although research had also
verified the game's Steam app, which SteamCMD installs straight into
/server. The build picked among the variant's images on its own.
- research reads each Steam app's OS list. When it ships a Linux server,
the SteamCMD route is the recommended option; for Windows-only servers,
images that bring Proton or Wine come first. The research prompt says
the same.
- A variant that can run on several images becomes one option per image
("... (SteamCMD)", "... (image x/y)"), so the admin picks exactly how the
server runs.
- build uses exactly the chosen option and never switches to another; if it
can't be made to work, the PR says so and another option can be picked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI's boot test gave every blank password-like setting a throwaway value. A
real deploy only fills x-generate fields, so a template whose server won't
start without one passed CI and failed for the first owner who deployed it.
boottest-payload now fills only x-generate fields, for CI and the builder
alike. The old behaviour is kept as -fill-blank-passwords, used only by
the builder's second boot to tell whether an empty setting is why a draft
fails. Messages and AUTHORING.md no longer say boot tests fill passwords;
a server that needs a join password gets x-generate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Booting drafts as deployed catches a server that stops when a setting is
empty, but the server's own output rarely says why, so the model guessed
(more memory) for three rounds and the draft ended as WIP.
When a draft fails with its defaults and has blank password-like settings
without x-generate, the builder boots it once more with those filled. If
that boot passes, the cause is certain, and the model is told exactly that:
these settings stop the server when empty; give them x-generate (a password
per server) or a working default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The builder's boot test filled every blank password-like setting with a
throwaway value. A real deploy only fills x-generate fields, so a draft whose
server refuses to run with an empty join password passed the builder and CI,
and then shut down on its first real deploy.
The builder now boots drafts with boottest-payload -as-deployed: only
x-generate fields are filled, everything else exactly as the template's
defaults. A server that won't run with its own defaults fails the build, and
the model is told that empty settings stay empty, so the value must come from
a default or x-generate. CI's boot test is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the worker is restarted mid-build (watchtower updating its image), the
boot test's container and volume are left behind, and the next boot test of
that game deploys under the same name. Remove them before each boot test.
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 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>
- 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>