UNOFFICIAL/EXPERIMENTAL. Live receipt generated by scripts/run-crd-ordering-gap.mjs; do not hand-edit. Regenerate with npm run crd-ordering:proof.
Claim. The cub-direct (no-controller) path applies the OCI bundle with plain kubectl apply, which has no dependency ordering or wait. On a FIRST install of a chart that ships a CRD plus a CR of that CRD, the CR fails ('no matches for kind ... ensure CRDs are installed first') and is never created. Helm installs CRDs first; Argo (sync waves) and Flux (retry/health) order it; cub-direct does not.
The doctrine's third delivery path - cub-direct (pull the OCI bundle + kubectl apply) - applies objects in file order with no dependency ordering or wait. Proven live on a throwaway kind cluster with a bundle that ships a CRD + a CR of it:
| Action | Custom resource created? |
|---|---|
kubectl apply -f <bundle> (CRD + CR together) | no - error: resource mapping not found for name: "my-widget" namespace: "default" from "/var/folders/4l/8wvwwzxs3xl78749bmmqzzbw0000gp/T/crdgap-b |
apply CRD → wait --for=condition=established → apply CR | yes (the fix) |
Overall: watch. Confirmed: the cub-direct first install of a CRD-bearing bundle fails - the CR applies before the CRD is established. Ordering CRD-first + waiting fixes it. So the no-controller path must install CRDs first (or wait/retry), or use a controller. Same theme as the prune gap: cub-direct is apply-only.
- Affected: cub-direct / no-controller first install of CRD-bearing charts. Not affected: Helm (installs CRDs first), Argo CD (sync waves), Flux (retry/health).
- The fix: the no-controller applier must install CRDs first and wait for them to be established (or apply-retry), or hand off to a controller. The doctrine should say so.
- Companion to the prune gap - both are apply-only limitations of the cub-direct path. Receipt:
runs/crd-ordering-gap/receipt.yaml.