Pilot: switch-effect map and generate-on-demand with a parity gate

A repository document, rendered for the site. View source markdown.

New to cub? Install the cub CLI first. You can pull and render public catalog packages without an account. Commands that save or change ConfigHub data require you to sign in.

Generated at: 2026-07-30T12:38:02.000Z UTC · source: committed helm-expt evidence for this rendered repository document.

A prototype of the model where an AI agent (Pilot) navigates a chart's switch space and generates variants on demand, and ConfigHub holds and governs them. Pilot is the author of intent; the chart renderer authors the objects; parity authors the trust. Run on redis, 2026-07-04.

1. The switch-effect map (classified by rendering, not by hand)

scripts/pilot-switch-effect-map.mjs renders redis with each top-level feature toggle flipped and diffs the object set against the baseline. The verdict is the diff, not an opinion. See redis.md.

Structural switches are base-variant territory; field switches are data edits. Nobody curated the list. The machine decided by rendering.

2. Generate one variant on demand, gated by parity

scripts/pilot-generate-variant.mjs takes a plain-English intent, maps it to switches (the only AI step), renders, and refuses to let the variant exist unless parity holds. See generated-variant-receipt.md.

3. Live landing check (ConfigHub stores it faithfully)

Uploaded the generated variant to a throwaway Space via cub variant upload, compared the stored object set to the helm render, then deleted the Space (org at 978/1000 links; nothing left behind).

Why this is the answer to "should Pilot manage ad-hoc variants"

Pilot generated a variant nobody pre-blessed, from an intent in words, and it arrived with a proof that it is the genuine chart output: composition against the map, determinism, a named route, and faithful ConfigHub storage. An AI that wrote the YAML directly could ship a plausible but wrong object set. This flow cannot, because a wrong set fails composition and a non-reproducible one fails determinism. Pilot authors the intent; parity certifies the render; ConfigHub governs the result.

Update 2026-07-04: five charts, an external-agent hook, and a live refusal

The map now covers five charts (redis, postgresql, rabbitmq, nginx, grafana; 65 switches classified by rendering), with the toggles auto-extracted from each chart's own values. Run any of them with npm run pilot:switch-map -- --chart <name> or --all. The spread is real information: grafana is 8/10 structural, rabbitmq 3/18. A flip that fails to render is recorded as its own finding (nginx's cloneStaticSiteFromGit needs more than the toggle).

The generator now takes its mapping from outside. pilot-generate-variant.mjs --intent "<words>" --switches <file> --mapped-by <agent> lets the Pilot checkout (or any agent) do the intent-to-switches step at run time; the built-in fixture keeps CI standalone. The receipt records who mapped the intent.

And the gate refused a live mapping. An agent mapped "a standalone redis with TLS on, certs auto-generated" to tls.enabled + tls.autoGenerated. The render succeeded, the object set was plausible, and the determinism check failed: auto-generated TLS mints new certificates every render, so two renders are not byte-identical. That nondeterminism is exactly what breaks config-as-data, and the right route is cert-manager or a pre-staged secret. The variant was refused (refused-variant-receipt.md). This is the anti-hallucination claim demonstrated on a real mistake: the agent's choice looked reasonable, rendered cleanly, and was still caught, with the reason named.

Update: refusals name the correct route forward, and the route works

Doctrine #9 now requires more than the block. On failure the gate names what to do instead in this paradigm, keyed to the failing check, in the receipt itself. The full loop is receipted as a trilogy:

  1. Refused (refused-variant-receipt.md): auto-generated TLS certs, determinism diverged, and the receipt names the route: keep certificates out of the render, use tls.existingSecret against a pre-staged Secret, or let cert-manager own issuance.
  2. Corrected (corrected-route-receipt.md): the same intent remapped to the named route. Determinism identical, gate PASS, variant may exist.
  3. The fixture PASS receipt stands as the baseline case.

A refusal is not a wall. It is a redirect, with the receipt teaching the config-as-data route.