Hook Lifecycle Strategy

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.

UNOFFICIAL/EXPERIMENTAL

Helm hooks are not ordinary rendered configuration. They are lifecycle actions that Helm may run before, during, or after install, upgrade, test, rollback, or delete phases.

The rule is:

Do not execute Helm hooks during recipe import.
Do not hide hooks inside the normal rendered-object proof.
Do not claim hook execution is deterministic without a lifecycle receipt.

The hook policy uses the same seven-stage lifecycle as the rest of the harness:

acquire and pin -> render and capture -> shape base variants -> scan and gate
-> settle prerequisites -> publish and deploy -> observe and operate

Render parity proves the desired non-hook object set. Hook support starts with source inventory and becomes a support claim only when the lifecycle route and receipts exist. The full doctrine is Seven-Stage Helm Lifecycle.

For serious chart support, hooks are required lifecycle work. A chart can have valid render parity while still being unready for production if its hooks are only inventoried or routed. Production support requires the hook route to be observed, translated with equivalent lifecycle evidence, or explicitly blocked with a reason.

What The Top-500 Scan Shows

The retained source scan is:

data/top500-catalog-analysis/source/source-feature-scan.raw.json

It stores more than a hook count: hook examples, phases, weights, delete policies, Jobs, CRDs, cluster RBAC, webhooks, APIServices, lookup, generated fact signals, and related source features.

Current estimate from the stored top-500 source scan:

charts requested: 500
charts scanned: 495
charts with Helm hooks: 54
total hook templates found: 176

likely problematic hook charts: 42
needs review: 6
probably benign/test-only: 6

Risk signals among the 54 hook charts:

non-test lifecycle hooks: 42
post-* hooks: 26
pre-* hooks: 26
hook weights/order: 21
hook delete policies: 44
Job resources: 46
cluster RBAC: 35
CRDs: 22
webhooks: 15
APIService: 6
lookup / cluster facts: 41

This means hooks are not most charts, but they are real. Roughly 11% of scanned public charts use Helm hooks, and most hook-using charts need lifecycle review before production support.

Status Vocabulary

Use these states when discussing hook or hook-like lifecycle behavior:

StatusMeaning
inventoriedThe source scan found hook templates or hook-like lifecycle behavior.
render-provenThe normal non-hook object set is deterministic under recorded inputs.
route-selectedA candidate handling route is recorded, such as test action, preflight, Argo hook, sync wave, managed action, or blocker.
lifecycle-observedThe selected route has a receipt with execution or controller behavior, runtime result, timestamp, and freshness.
blockedThe hook is unsafe, ambiguous, target-dependent, or not yet mapped.

Do not treat inventoried or render-proven as lifecycle support. route-selected means the route has been recorded, usually in a route receipt, but it is still not lifecycle proof until execution or observation evidence exists. blocked is a valid catalog outcome when a hook does not fit the current model safely.

Where To Look Per Chart

The first place to look is the chart row in the master catalog matrix. The Hook column tells you whether the chart has hooks, whether a disposition exists, and whether the route has been observed. From there, follow the row links to the chart catalog, pain report, hook disposition, or lifecycle route receipt.

For a user, the practical contract is:

What you seeWhat it means
observedThe hook or hook-like lifecycle step has a selected route and live evidence. Use the linked route and receipt for the supported target scope.
routedThe route is known, such as preflight, post-apply Job, Argo hook, sync wave, ConfigHub check, or target prerequisite, but the route still needs fresh live evidence before a production claim.
per-targetThe right route depends on the target platform, policy, or operator choice. The catalog names the decision instead of guessing.
refused or blockedThe public catalog does not run that hook automatically. The chart records why and what would be needed to support it.

If the route is a normal Kubernetes object, it can be delivered as a ConfigHub Unit with the rest of the desired state. If the route is an action, it must be set up as an explicit lifecycle operation: preflight, post-apply Job, Argo hook, Argo sync wave, ConfigHub function/check, operator action, or documented manual step. The catalog should make that route visible before OCI delivery, so the user is not surprised by behavior Helm would otherwise hide in an install or upgrade.

The route is not considered production-supported until the row either has live evidence for the target scope or is explicitly marked per-target, refused, or blocked. A chart can have perfect render parity and still be incomplete if its hook route is only inventoried.

A complete direct install and controller upgrade

The Kube Prometheus Stack 85.3.3 example runs the chart's real fresh-install sequence instead of pretending its 124 ordinary objects are the whole release. It applies ten CRDs, runs the chart's admission certificate Job, applies the ordinary objects, runs the webhook patch Job, checks the webhook and six workloads, then performs the chart's hook cleanup policy.

Seven direct route implementations passed. The no-crds preset then installed 85.3.3 and upgraded to 86.1.0 through Argo CD and Flux. Both controllers reran the chart-specific stages, replaced the completed setup Jobs, and passed the runtime checks. ConfigHub does not yet select this route automatically. Read the guide, direct summary, and controller receipt before reusing the pattern.

Machine-Readable Route Contract

The same disposition, route, execution mode, default, and off-ramps are also a machine-readable surface: data/lifecycle-routes/ - routes.csv for spreadsheets, routes.json for agents, and contract.md for the field definitions.

To read one row: route_name is where the behavior goes; disposition is one of observed, routed, per-target, refused, or todo; execution_mode is who runs it (user-executes, target-owned, or not-yet-executable; product-executes only with evidence); default_route plus alternatives are the off-ramps; and safe_as_automatic stays no unless the product itself runs the route. No row is shown as automatic without evidence.

For the current recipe corpus, use:

data/chart-facts/chart-facts.csv

The hook columns show the phases found for each chart, the current route state, the evidence file, and the next lifecycle action. That view is scoped to charts with current recipes. The broader source-scan hook inventory lives under:

data/hook-lifecycle/

Keep the two views separate. The source scan answers "which public charts appear to use Helm hooks." Chart facts answer "what does this maintained recipe know about hooks now, and what remains before a stronger support claim."

Classification

Hook classDefault disposition
Helm test hook onlyConvert to explicit post-install check/test where useful.
pre-install / post-installPreflight, target fact requirement, install phase action, readiness gate, or blocker.
pre-upgrade / post-upgradeUpgrade lifecycle action plus upgrade receipt.
Delete or cleanup hookDelete/rollback lifecycle policy.
Hook with weight/orderPreserve ordering through lifecycle policy or sync-wave-style mechanism.
Hook with delete policyPreserve cleanup behavior explicitly or block.
CRD/webhook/bootstrap hookCRD/webhook lifecycle gate plus live observation.
Hook depending on lookup, existing objects, RBAC, storage, or release historyTarget facts, preflight, managed lifecycle action, or blocker.
Unclear procedural hookUnsupported for production until reviewed.

Public Catalog Strategy

For public catalog entries:

inventory hooks
classify hook phase and risk
render normal objects with an explicit hook policy
bind scan/gate findings to the rendered revision
record whether hook behavior is skipped, translated, tested, or blocked

The catalog can safely prove:

source chart contains hooks
normal rendered object set has render parity under recorded inputs
hook behavior has an explicit disposition
production support is blocked unless lifecycle proof exists

The catalog must not claim:

Helm hook execution was reproduced by normal render equivalence
cluster-dependent hook behavior is deterministic
all hook behavior can be translated automatically

Some charts will have hooks that do not fit the first-pass categories cleanly. The correct behavior is to record the uncertainty and block production support for that chart/base until the lifecycle route is reviewed and receipted.

GitOps And Argo Route

When Helm is not the runtime installer, many hook-like behaviors need another lifecycle surface. The first practical route is GitOps lifecycle handling, especially Argo CD sync hooks and sync waves where they are safe.

Suggested mapping:

Helm hook needCandidate route
pre-install setup JobArgo PreSync hook, explicit preflight, or managed install action.
post-install smoke testArgo PostSync hook, ConfigHub check, or observation receipt.
pre-upgrade migrationArgo PreSync in an upgrade revision, gated by approval.
post-upgrade validationArgo PostSync plus observation receipt.
hook weight/orderArgo sync waves where semantics match.
hook delete policyArgo hook delete policy or explicit cleanup/rollback policy.
unsafe side effectBlock until reviewed.

Argo translation is not automatic. It is one implementation strategy that must produce lifecycle receipts and observations.

Some charts have no Helm hook but still need lifecycle observation because controllers populate fields or Secrets after apply. External Secrets is the current example: the chart does not use a Helm hook in the tested bases, but the controller and webhook flow populate runtime data that rendered YAML alone cannot prove.

Cert-manager is the opposite cross-lane case. It does have the startupapicheck Helm post-install hook, but the retained top-100 source-scan row did not flag hooks. The lifecycle lane therefore records cert-manager explicitly: both default and crds-enabled model startupapicheck as a post-apply API dry-run and readiness check.

The cert-manager / External Secrets lifecycle lane records this pattern:

data/lifecycle-observations/cert-manager-eso/summary.md

That lane is not a claim that all hooks are solved. It proves the receipt shape for common lifecycle issues: CRD ownership, webhook API readiness, CA bundle injection, controller-populated Secret data, and server dry-run checks.

The generated boundary page keeps the two claims separate:

Hook And Lifecycle Boundary

Managed / Commercial Strategy

Hooks can support paid value, but the offer should not be "we run arbitrary hooks for you." The valuable paid work is lifecycle intelligence and managed translation:

hook inventory for private or old chart versions
classification of install/upgrade/delete side effects
safe Argo/GitOps lifecycle mapping where possible
preflight and target fact requirements
upgrade/rollback simulation and receipts
blocked-hook remediation recommendations
fresh observation receipts after live execution
evidence pack for audit and change review

This fits naturally beside a broader commercial lifecycle-intelligence story:

chart/version inventory
known-risk and breaking-change analysis
annotated rendered-object diffs
upgrade project templates
agent-ready remediation tasks
policy and misconfiguration findings
freshness-aware runtime observations
auditable receipts

The differentiation should remain ConfigHub-shaped:

We reason about the exact rendered configuration variants you approve and run.

Competitors can summarize Kubernetes upgrade risk. ConfigHub should connect the risk to concrete recipe inputs, rendered objects, ConfigHub variants, scans, gates, approvals, observations, and evidence.

Acceptance Criteria

For any catalog-supported chart with hooks: