Lifecycle Route Contract

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. Schema and derivation rules for routes.csv and routes.json, generated by scripts/generate-lifecycle-routes.mjs. Both the data and this contract are generated from the same constants, so they cannot drift.

Purpose

For every hook or hook-like lifecycle behavior, make machine-readable: the route, who executes it, the default, the named alternatives and their requirements, whether a human and an agent can pick an alternative, the evidence or next action, and whether it is safe to show as automatic.

Columns

ColumnMeaning
chart / versionSource chart and version.
base_or_variantSpecific base when a selected receipt proves an exact route; empty means the chart-level route used by bases without an exact receipt.
quirk_classThe behavior class, derived from route_name (see table).
hook_phasesHelm hook phases recorded by the source scan.
source_dispositionThe raw disposition word from the source data, kept for traceability.
dispositionPublished word: observed, routed, per-target, refused, or todo.
route_nameThe selected/current route for this behavior.
default_routeThe default route among the alternatives (equals route_name).
alternativesNamed off-ramp routes for this quirk class.
route_requirementsWhat the current route needs (target facts, render conditions).
execution_modeWho performs it: product-executes, user-executes, target-owned, or not-yet-executable.
human_offrampHow a human picks an alternative (recipe-base-or-values or none).
agent_offrampHow an agent picks an alternative (routes-json or none).
live_statusobserved, blocked, none, or candidate-route-plan.
safe_as_automaticyes only when execution_mode is product-executes and evidence proves it.
evidence_or_next_actionReceipt path when observed, otherwise the next action.

Invariants

  1. No silent automation. safe_as_automatic = yes requires execution_mode = product-executes plus evidence. No row qualifies today, so the column is uniformly no. This is deliberate.
  2. routed names an executor. A routed row always records an execution_mode; candidate-route/recipe-needed only map to a real disposition once a route and executor are named.
  3. refused is final; todo is unfinished. refused is a deliberate decision not to run a behavior automatically. todo (from recipe-needed/candidate-route-plan) means no recipe/route exists yet and a next action is named. They are never merged.
  4. Generated, not authored. Regenerate with npm run lifecycle:routes; verify byte-for-byte with npm run lifecycle:routes:verify.

Source Disposition Mapping

The source data uses more than one vocabulary. This is the published join.

Source valuePublished disposition
observedobserved
routedrouted
per-targetper-target
refusedrefused
recipe-neededtodo
candidate-routerouted
candidate-route-plantodo
selected-route-receiptobserved

Route → Quirk Class

route_namequirk_class
preflight-or-presynchook-phase
preflight-or-presync-crd-applycrd-install
postsync-check-or-observationhook-phase
upgrade-action-with-receipthook-phase
explicit-managed-actionhook-phase
argocd-or-flux-lifecycle-hookhook-phase
target-class-preflight-and-upgrade-actionper-target-hook
recipe-time-lifecycle-verificationhook-phase
explicit-test-checkhook-test
webhook-readiness-observationwebhook-readiness
target-facts-or-preflighttarget-facts
preserve-orderinghook-weight-ordering
preserve-cleanup-policyhook-delete-policy
delete-cleanup-policyhook-delete-policy
explicit-delete-cleanup-actionhook-delete-policy
explicit-post-install-checkhook-test
postsync-readiness-observationwebhook-readiness
self-contained-crd-basecrd-install

Route → Execution Mode (base)

Before the todo/refused override, which forces not-yet-executable. No route maps to product-executes.

route_nameexecution_mode
preflight-or-presyncuser-executes
preflight-or-presync-crd-applyuser-executes
postsync-check-or-observationuser-executes
upgrade-action-with-receiptuser-executes
explicit-managed-actionnot-yet-executable
argocd-or-flux-lifecycle-hooktarget-owned
target-class-preflight-and-upgrade-actionuser-executes
recipe-time-lifecycle-verificationuser-executes
explicit-test-checkuser-executes
webhook-readiness-observationtarget-owned
target-facts-or-preflightuser-executes
preserve-orderingtarget-owned
preserve-cleanup-policytarget-owned
delete-cleanup-policytarget-owned
explicit-delete-cleanup-actionuser-executes
explicit-post-install-checkuser-executes
postsync-readiness-observationuser-executes
self-contained-crd-basetarget-owned

Quirk Class → Alternatives (off-ramps)

The off-ramp routes a user or agent can choose instead of the default, and what each needs. Grounded in ../../docs/user/hook-lifecycle-strategy.md and ../../docs/planning/where-does-my-hook-go.md.

quirk_classalternative routerequirement
hook-phaseargocd-or-flux-lifecycle-hooka GitOps controller (Argo CD/Flux) that runs sync hooks or sync waves
hook-phasetarget-facts-or-preflightthe prerequisite supplied as a target fact or preflight before apply
hook-phaserefuseaccept that the catalog will not run this automatically and do it manually
crd-installself-contained-crd-basea preset config that renders the required CRDs as ordinary objects before the workloads
crd-installtarget-owned-crdsthe cluster or an operator owns CRD install and upgrade out of band
crd-installrefuseuse a no-crds base and install/upgrade the CRDs yourself
hook-delete-policydelete-on-uninstallaccept deletion of the hook-managed object on uninstall
hook-delete-policyrefusemanage cleanup manually and keep the object
hook-weight-orderingargocd-sync-wavesa GitOps controller that maps hook weights to sync waves
hook-weight-orderingapply-orderan apply step that preserves the documented order
hook-testci-checkrun the test as a CI or post-apply check instead of a Helm test hook
hook-testskip-testaccept that the test is not run automatically
webhook-readinesspostsync-check-or-observationa post-apply readiness check you run or observe
target-factspreflight-or-presynca preflight step that establishes the fact before apply
target-factsrefusesupply the fact manually and accept no preflight
per-target-hookper-target-scope-splitnamed target classes, each with its own route decision

Off-ramps Today

The human off-ramp is recipe base/values selection. The agent off-ramp is routes.json: a stable enumeration of routes, defaults, alternatives, and requirements an agent can read and act on. Selecting an alternative is a recipe-level change today; this contract makes the choice legible to both readers. Neither off-ramp implies the product executes the route - see invariant 1.