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:
| Status | Meaning |
|---|---|
inventoried | The source scan found hook templates or hook-like lifecycle behavior. |
render-proven | The normal non-hook object set is deterministic under recorded inputs. |
route-selected | A candidate handling route is recorded, such as test action, preflight, Argo hook, sync wave, managed action, or blocker. |
lifecycle-observed | The selected route has a receipt with execution or controller behavior, runtime result, timestamp, and freshness. |
blocked | The 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 see | What it means |
|---|---|
observed | The hook or hook-like lifecycle step has a selected route and live evidence. Use the linked route and receipt for the supported target scope. |
routed | The 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-target | The right route depends on the target platform, policy, or operator choice. The catalog names the decision instead of guessing. |
refused or blocked | The 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 class | Default disposition |
|---|---|
| Helm test hook only | Convert to explicit post-install check/test where useful. |
pre-install / post-install | Preflight, target fact requirement, install phase action, readiness gate, or blocker. |
pre-upgrade / post-upgrade | Upgrade lifecycle action plus upgrade receipt. |
| Delete or cleanup hook | Delete/rollback lifecycle policy. |
| Hook with weight/order | Preserve ordering through lifecycle policy or sync-wave-style mechanism. |
| Hook with delete policy | Preserve cleanup behavior explicitly or block. |
| CRD/webhook/bootstrap hook | CRD/webhook lifecycle gate plus live observation. |
| Hook depending on lookup, existing objects, RBAC, storage, or release history | Target facts, preflight, managed lifecycle action, or blocker. |
| Unclear procedural hook | Unsupported 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 need | Candidate route |
|---|---|
pre-install setup Job | Argo PreSync hook, explicit preflight, or managed install action. |
post-install smoke test | Argo PostSync hook, ConfigHub check, or observation receipt. |
pre-upgrade migration | Argo PreSync in an upgrade revision, gated by approval. |
post-upgrade validation | Argo PostSync plus observation receipt. |
| hook weight/order | Argo sync waves where semantics match. |
| hook delete policy | Argo hook delete policy or explicit cleanup/rollback policy. |
| unsafe side effect | Block until reviewed. |
Argo translation is not automatic. It is one implementation strategy that must produce lifecycle receipts and observations.
Related Lifecycle 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:
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:
helm-pain-report.yamllists hook pain and disposition.helm-plan.yamlrecords hook policy.- scan/gate receipts include hook findings or explicit test/check mapping.
- production disposition states whether hooks are skipped, translated, tested, blocked, or supported by live lifecycle receipts.
- if translated to Argo/GitOps lifecycle, the mapping has its own receipt and live observation when cluster behavior matters.