This document gives two worked examples for promoting ConfigHub variants from Helm-derived bases. Each example should be expressible three ways:
UX: foundational user-led creation
AX: agent-based creation
FX: function-based creation
This is about post-render ConfigHub variant promotion. It is not chart catalog promotion, and it is not a hidden Helm rerender. The current cub variant create command provides the clone/link substrate. The richer Creator UX below is product porcelain over that substrate: blueprint selection, fill-value guidance, preview, checks, and receipts.
The promotion model follows ConfigHub's existing promotions example: Spaces and Units carry component and variant labels, and cloned Units keep upstream links back to the source Units. The graph is built from those primitives, not from a separate promotion artifact introduced by this repo.
For the canonical mapping into ConfigHub's component/space/unit/promotion model, see ConfigHub Promotion Mapping Doctrine. For the Kubara-style overlay analysis behind the ExternalDNS example, see Kubara Customized Overlay Analysis. For the current refresh work orders that turn these examples into executable proof work, see data/latest-top20-refresh/variant-work-orders.yaml.
Generated goldens now exist for both examples:
| Example | Generated golden |
|---|---|
| Redis production region | data/variant-goldens/redis-prod-us-east/ |
| ExternalDNS managed overlay | data/managed-overlay-goldens/external-dns-customer-acme-prod/ |
They are verified with:
npm run variant-goldens:verify
Example 1 - Redis Production Region
We start with a reviewed Redis base:
chart: bitnami/redis@25.5.3
base: default
source variant: redis/default
The source has already been rendered, scanned, uploaded, and tested. Now we want production variants:
redis/prod-us-east
redis/prod-eu-west
The promotion should keep the reviewed object set stable unless the user explicitly chooses a different recipe/package base.
Mapping Into ConfigHub
The roadmap records a Kubara org example with this shape:
| ConfigHub object | Base | Promoted variant |
|---|---|---|
| Space | helm-redis-mapping-default | helm-redis-mapping-prod-us-east |
| Component label | Redis | Redis |
| Variant label on Space | default | prod-us-east |
| Unit count | 15 | 15 |
| Promotion edge | source Unit | cloned Unit with UpstreamUnitID |
Observed edge:
statefulset-redis-redis-master default -> prod-us-east
That is the ConfigHub Promotion graph:
Redis/default -> Redis/prod-us-east
The product question is whether cloned Units should also have their Unit-level Variant labels patched from default to prod-us-east. Space labels already identify the downstream node, while Unit labels may preserve source identity unless clone-time relabeling is explicit.
The generated Redis golden records this substrate in:
data/variant-goldens/redis-prod-us-east/creator-contract.yaml
data/variant-goldens/redis-prod-us-east/preview.yaml
data/variant-goldens/redis-prod-us-east/receipts/clone-receipt.yaml
UX: Variant Creator
Variant Creator
From: redis/default
Blueprint: Promote to production
Target variant: prod-us-east
Fill: environment=prod, region=us-east, namespace=redis-prod, target=redis-targets/prod-us-east
Preview: 15 Units, 3 changed paths, 1 link changed
Checks: pass with carried scan warning
Create
The Creator asks only for the values needed to make this production variant real. The source base determines the Redis Secret model. Starting from redis/default preserves the generated-Secret mode. A request to bind redis-existing-secret routes back to the reuse-existing-secret base or to a new cub installer render.
What The Creator Contract Describes
The Creator contract tells ConfigHub how to use its existing primitives:
| Step | Primitive | Result |
|---|---|---|
| Clone reviewed source | variant create / bulk clone | New prod space with copied Units, links, triggers, permissions, and metadata. |
| Set identity | labels and target metadata | Variant=prod-us-east, environment/region labels, target selection. |
| Fill required values | placeholders, parameter Unit, TransformPaths | Namespace, target, and operating labels land in the right paths. |
| Review relationships | links, NeedsProvides, outgoing link review | Cross-Unit bindings are preserved or deliberately changed. |
| Check safety | schema checks, function checks, target facts, gates | No unresolved placeholders, facts satisfied, diff reviewed. |
| Record proof | receipts, MutationSources, scan/apply/observe receipts | The promotion is explainable and repeatable. |
AX: Agent Task
An agent should receive a structured task, not a loose prompt:
task: create_variant
fromSpace: helm-redis-default
blueprint: promote-to-production
parameters:
environment: prod
region: us-east
namespace: redis-prod
redisSecretMode: preserve-generated-secret-reference
requiredChecks:
- source-revision-bound
- no-hidden-helm-rerender
- redis-secret-mode-preserved
- unit-diff-reviewed
- scan-pass-or-approved-exception
expectedReceipts:
- clone
- transformPaths
- functionMutations
- checks
- route-back
- approval
The agent experience is deterministic because the task says what to create, what to check, and which receipts prove the result.
FX: Function-Based Fleet Promotion
The same artifact shape should also work over a matrix:
blueprint: redis-promote-to-production
matrix:
- environment: prod
region: us-east
namespace: redis-prod-use1
redisSecretMode: preserve-generated-secret-reference
- environment: prod
region: eu-west
namespace: redis-prod-euw1
redisSecretMode: preserve-generated-secret-reference
Fleet execution:
map the Variant Creator contract over the matrix
verify each result
summarize fleet receipts
promote in waves
Example 2 - ExternalDNS Managed Customer Overlay
This example uses the inspected external-dns/external-dns@1.21.1 proof as a Kubara-style stand-in for a managed platform app. The generated golden now includes a wrapper chart, platform values, customer overlay values, classification, preview, and receipts. It is still not a claim that all Kubara applications are imported or production-ready.
Inspected inputs in this repo:
| Evidence | Value |
|---|---|
| Source lock | recipes/external-dns/external-dns/1.21.1/source-lock.yaml pins https://kubernetes-sigs.github.io/external-dns/, chart external-dns, version 1.21.1, app version 0.21.0, and package SHA. |
| Dependency lock | recipes/external-dns/external-dns/1.21.1/dependency-lock.yaml records no chart dependencies. |
| Effective values | effective-values.yaml records chart defaults and no captured merged overlay values. |
| Rendered controller args | --source=service, --source=ingress, --policy=upsert-only, --registry=txt, --provider=aws. |
| Rendered image | registry.k8s.io/external-dns/external-dns:v0.21.0. |
| Control points | generated facts, tpl, extension slots, one CRD, and cluster-scoped RBAC are recorded. |
| Generated managed overlay golden | data/managed-overlay-goldens/external-dns-customer-acme-prod/ |
A realistic managed import unit is not just the public chart:
external-dns wrapper chart
+ platform values
+ customer overlay values
+ dependency closure
+ render context
Promotion shape:
ExternalDNS/managed-aws -> ExternalDNS/customer-acme-prod
Mapping into ConfigHub:
| ConfigHub object | Managed base | Customer promoted variant |
|---|---|---|
| Space | helm-external-dns-managed-aws | helm-external-dns-customer-acme-prod |
Space label Component | ExternalDNS | ExternalDNS |
Space label Variant | managed-aws | customer-acme-prod |
| Space labels | Provider=aws, Environment=Catalog | Provider=aws, Customer=acme, Environment=Prod, Region=us-east |
| Units | Rendered wrapper/platform object set | Cloned Units with UpstreamUnitID back to managed base Units |
| Target | none or catalog validation target | customer production target |
| Gates | CRD/RBAC/provider review | customer approval, target facts, observation freshness |
The key product lesson is the boundary:
| Customer choice | Classification | Route |
|---|---|---|
| DNS provider, sources, registry mode, TXT owner ID, domain filters | customer overlay value / base variant selection | Recipe/base render path, because these usually change container args or rendered objects. |
| DNS credential Secret or ExternalSecret reference | target fact | Recipe/base when it changes rendered env/volume shape; Creator contract only when it binds an existing rendered placeholder/reference. |
| Namespace, target, approval gates, region/customer labels | post-render ConfigHub variant field | cub variant create plus Creator contract over ConfigHub primitives. |
| CRD ownership and RBAC review | lifecycle policy / CRD disposition | Recipe/base proof plus promotion gates. |
| Provider account ID, hosted zone ID, IAM role ARN | target fact | Bind/check during variant creation; rerender only if those facts become Helm-rendered args/env. |
Variant Creator:
Variant Creator
From: external-dns/managed-aws
Blueprint: Customer production overlay
Target: customer-acme-prod
Fill: customer, region, target, credential fact, hosted zone fact
Preview: cloned Units, target/label changes, fact bindings, gates
Checks: CRD/RBAC reviewed, credential fact satisfied, observation policy set
Create
AX task:
task: create_variant
fromSpace: helm-external-dns-managed-aws
blueprint: customer-production-overlay
parameters:
customer: acme
environment: prod
region: us-east
target: acme-prod/cluster
dnsCredentialFact: external-dns-aws-credentials
hostedZoneFact: acme-prod-public-zone
requiredChecks:
- target-facts-satisfied
- crd-disposition-reviewed
- cluster-rbac-reviewed
- unit-diff-reviewed
If the user changes provider, domain filters, TXT ownership behavior, sources, or credential wiring in a way that changes rendered Deployment args/env, the Creator should stop and route back to a maintained cub installer recipe/base render.
Promotion Rules
Use the Variant Creator contract when the change is post-render:
target
namespace
labels
links
placeholders
secret references
policy gates
approval state
observation requirements
Go back to the recipe/package base path when the change affects rendered objects:
CRDs on/off
generated Secret vs existing Secret
HA/storage mode
ingress/TLS shape that changes rendered objects
cloud-specific Helm values
anything requiring a new Helm render
The rule is simple:
Promote reviewed ConfigHub variants without rerendering.
Rerender only when the install shape changes.
Expected Proof
A completed promotion should leave enough evidence to answer:
What did we clone?
What changed?
Which target facts were used or checked?
Which scans and gates passed?
Who approved it?
What was applied or published?
How fresh is the observation?
Minimum proof objects:
clone receipt
unit diff / MutationSources
target-fact or preflight receipt
scan/check receipt
approval receipt
apply/publish receipt
observation receipt when live proof is required