Preview & Dry-Run Readiness

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

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

Helm's render is not a pure function of (chart, values) - it depends on live cluster state at install time (lookup, .Capabilities, hooks, generated values, post-render mutation), so a naive helm template preview is untrustworthy for serious charts. The answer is not to re-render on every preview; it is to render once at import, capturing the live-dependence as data, then preview/diff the held data. The quirks become a one-time import problem. This surface names every preview-breaking quirk and says whether it is shift-left-resolved (captured into config pre-deploy) or runtime residue (declared + witnessed, never faked).

Of 26 tracked Helm quirk axes: 19 shift-left (config-resolvable, previewable), 3 runtime residue (witnessed after apply), 4 lifecycle/day-2 (not a preview question). The unpreviewable surface is small and named.

Quirk -> preview disposition

Quirk axisDispositionMechanismCoverage tierPreviewable
capability-profileshift-leftcapability profile pins kubeVersion + apiVersionspartly-trackedpartial
crdsshift-leftCRDs in the render, or staged as a target facttracked-and-surfacedyes
dependency-aliasshift-leftlocked dependencytracked-by-lock-not-front-doorpartial
dependency-lockshift-leftdependencies locked -> deterministic rendertracked-and-surfacedyes
explicit-extension-slot-control-pointsshift-leftcaptured as control points / valuestracked-and-surfacedyes
files-getshift-leftbundled files vendored with the chartsource-scanned-not-surfacedpartial
generated-factsshift-leftgenerated-fact receipt (capture once, reuse)tracked-and-surfacedyes
global-valuesshift-leftdeterministic given captured values (scan gap)not-scannedpartial
helm-flag-profileshift-leftpinned renderer flags in the render receiptpartly-trackedpartial
helm-version-branchingshift-leftpin the Helm version in the render receiptnot-scannedpartial
hook-phaseshift-lefthook-minted object declared as a target fact; hook execution witnessedpartly-trackedpartial
import-valuesshift-leftdeterministic given captured values (scan gap)not-scannedpartial
install-vs-upgradeshift-leftrender-once is install-shaped; upgrade reuse via held datatracked-and-surfacedyes
library-chartshift-leftlocked dependencytracked-by-lock-not-front-doorpartial
lookup-target-factsshift-lefttarget fact (read from config or live, pre-deploy)tracked-and-surfacedyes
required-or-failshift-leftrequired values captured as an input contracttracked-and-surfacedyes
semver-compareshift-leftdeterministic given pinned versionssource-scanned-not-surfacedpartial
tpl-extension-slotsshift-leftdeterministic given captured valuestracked-and-surfacedyes
values-schemashift-leftvalues.schema.json input contracttracked-and-surfacedyes
getHostByNameruntime-residueDNS at render; bind a captured fact or witnessnot-scannedno (witness)
post-rendererruntime-residuefinal applied object differs from helm template; pin a recipe stage or witnessnot-scannedno (witness)
time-uuid-functionsruntime-residuenondeterministic per render; capture-once or witnesssource-scanned-not-surfacedno (witness)
crd-upgrade-behaviorlifecycleCRD schema upgrade safety (day-2, not preview)disclosed-not-completen/a (day-2)
hook-delete-policylifecycleuninstall/rerun cleanup behavior (day-2, not preview)source-scanned-not-surfacedn/a (day-2)
hook-weight-orderinglifecyclehook sequencing (day-2, not preview)source-scanned-not-surfacedn/a (day-2)
resource-policy-keeplifecycleuninstall/prune orphans (day-2, not preview)not-scannedn/a (day-2)

Shift-left adoption across the catalog

Per-chart readiness (anchor charts)

Chartcapabilities pinneddeclared prerequisitesgenerated-fact capturedverdict
ingress-nginx/ingress-nginx/4.15.1yesyes (witnessed)nopreviewable + declared prerequisites (witnessed)
jetstack/cert-manager/v1.20.2yesyes (witnessed)nopreviewable + declared prerequisites (witnessed)
bitnami/redis/25.5.3yesnoneyesfully previewable pre-deploy
prometheus-community/kube-prometheus-stack/85.3.3yesyes (witnessed)nopreviewable + declared prerequisites (witnessed)

Worked example: ingress-nginx

ingress-nginx is the hard case - it has all three classic preview-breakers.

Honest residue (the genuinely unpreviewable surface)

These cannot be made a pure function of captured config; the honest answer is declare + witness, never a fake preview:

Next (breadth + rigor upgrades)

Regenerate

npm run preview-readiness:generate
npm run preview-readiness:verify