Consumer onboarding (plain RBE / image-builder repos)
config/consumer-registry.json is the registry-of-record for repositories
that consume the shared GloriousFlywheel substrate as plain RBE / container
image builders — they build/test/push on the shared runner pool via an
overlay extra_runner_sets anchor. It answers the question that is
otherwise archaeology: “is THIS repo enrolled, and via which path?”
This is not the PR-environment spoke registry. If your repo needs per-PR
ephemeral environments (*.pr.<brand_domain>, Blahaj app install, a per-spoke
cache quota), use config/spoke-registry.json / docs/build-system/spoke-onboarding.md
instead. A repo is a spoke or a consumer, never both (the validator enforces
the mutual exclusion).
Onboard in one PR
Add one entry to config/consumer-registry.json consumers[]:
{
"github_repository": "Owner/repo",
"runner_class": "tinyland-nix",
"image_repository": "ghcr.io/owner/repo",
"tfvars_anchor": "repo-nix",
"substrate_mode": "executor-backed",
"enrolled_via": "overlay-extra_runner_sets",
"workflow": ".github/workflows/docker-ghcr.yml",
"build_targets": ["//path:image", "//path:push"],
"enrolled": true
}
| field | meaning / rule |
|---|---|
github_repository |
<owner>/<repo>. Unique; must not also be a spoke. |
runner_class |
the shared capability label the workflow’s runs-on requests (tinyland-nix, tinyland-dind, …). Validated against the same taxonomy as the runs-on guard — a repo-shaped label (repo-nix) is rejected. |
image_repository |
must equal ghcr.io/<owner-lowercased>/<repo> (site.scaffold CI-SCHEMA). |
tfvars_anchor |
the extra_runner_sets key in the implementation overlay’s arc-runners tfvars (registration identity). Unique. Recorded here; verified live by flywheel-enroll-verify. |
substrate_mode |
executor-backed or shared-cache-backed (the arc-runner module’s own value). |
enrolled_via |
overlay-extra_runner_sets. |
enrolled |
boolean. The static validator asserts the type only; flywheel-enroll-verify earns true by checking the three live realities. |
Then run just flywheel-enroll-register (or just consumers-onboarding-contract-check,
which also runs in just check).
Static vs live: what is checked where
The static validator (scripts/validate-consumer-registry.py, in just check)
is GF-core-self-contained — it cannot see the overlay tfvars (a separate
repo), the consumer workflow (another repo), or the cluster. It checks the
entry’s internal honesty: required fields, the runner_class taxonomy, the
ghcr image-org convention, the substrate/path enums, uniqueness, and the
spoke mutual exclusion.
The three live realities are confirmed by just flywheel-enroll-verify in
the implementation overlay (where the overlay tfvars, the consumer checkout, and
the kubeconfig are reachable), each reusing an already-built guard:
- the
tfvars_anchorexists and is RBE-wired (validate-overlay-runner-taxonomy.py); - the consumer workflow
runs-onuses the sharedrunner_class(the runs-on label rules); - the live runner is
managed-by=Helmwith no manual drift (the drift audit).
enrolled: true requires all three. Runner provisioning (tofu apply) is
operator-gated — the just flywheel-enroll umbrella stops and hands off.