Skip to main content

caixa_flux/
lib.rs

1//! caixa-flux — typed renderer that emits the FluxCD-side fragments a
2//! caixa Servico needs in the cluster's GitOps tree.
3//!
4//! Same naming convention as [`caixa_helm`] (renders per-program Helm
5//! charts) and [`caixa_flake`] (renders flake.nix): `caixa-<target>` =
6//! "Rust crate that takes a typed [`Caixa`] and emits the canonical
7//! source for `<target>`".
8//!
9//! ## Two paths, two surfaces
10//!
11//! Per `theory/META-FRAMEWORK.md` §I, two equally-canonical ways exist
12//! to deploy a caixa Servico:
13//!
14//! 1. **Aggregator path** ([`programs_yaml_entry`]) — the cluster has
15//!    exactly one `lareira-fleet-programs` HelmRelease whose values
16//!    contain a `programs:` array. Adding a Servico = adding one entry
17//!    to that array. **Higher leverage** — one HelmRelease handles the
18//!    whole fleet's worth of caixas, fewer reconciler events, simpler
19//!    cluster surface. This is what `feira deploy` uses by default.
20//!
21//! 2. **Bundle path** ([`cluster_bundle`]) — emit a fresh `GitRepository`
22//!    + `HelmRelease` + `Kustomization` trio for the caixa's own per-
23//!    program chart (rendered by `caixa-helm`). Used for one-off /
24//!    isolated services where the aggregator overhead is undesirable
25//!    (e.g. alpha workloads with non-standard images, breakglass tooling).
26//!
27//! ## V0 contract
28//!
29//! ```rust,ignore
30//! use caixa_core::Caixa;
31//! use caixa_flux::programs_yaml_entry;
32//!
33//! let caixa = Caixa::from_lisp(src)?;
34//! let cu_yaml: serde_yaml::Value =
35//!     serde_yaml::from_str(std::fs::read_to_string("servicos/hello-rio.computeunit.yaml")?)?;
36//! let entry: serde_yaml::Value = programs_yaml_entry(&caixa, &cu_yaml)?;
37//! // → { name: hello-rio, namespace: tatara-system, module: { source: ... }, ... }
38//! ```
39//!
40//! ## What this is NOT
41//!
42//! - Not a Flux CLI wrapper — bytes only.
43//! - Not the operator deploy bundle — that lives in `pleme-io/caixa/operator-flux/`.
44//! - Not an installer — `feira deploy` orchestrates the I/O of writing
45//!   to a GitOps repo + opening a PR.
46
47#![allow(clippy::module_name_repetitions)]
48
49use caixa_core::{Caixa, MappingExt, kube_metadata_str_field, lareira_chart_name};
50use serde::{Deserialize, Serialize};
51use thiserror::Error;
52
53/// Errors caixa-flux can raise.
54#[derive(Debug, Error)]
55pub enum Error {
56    /// The caixa's `:kind` doesn't match what `caixa-flux` targets
57    /// (this renderer only emits `programs.yaml` entries +
58    /// `GitRepository`/`HelmRelease`/`Kustomization` bundles for
59    /// `:kind Servico`). Lifted from a prior `NotAServico(CaixaKind)`
60    /// arm to wrap [`caixa_core::KindMismatch`] so the diagnostic
61    /// names the offending caixa's `:nome` (not just its kind),
62    /// shared verbatim with `caixa-helm` and `caixa-mesh`.
63    #[error("{0}")]
64    NotAServico(#[from] caixa_core::KindMismatch),
65    /// The caixa's `:servicos` list doesn't carry exactly one entry —
66    /// the V0 contract every Servico-kind caixa satisfies (one
67    /// ComputeUnit YAML pointer per Servico, matching the one
68    /// programs.yaml entry / cluster bundle this renderer emits).
69    /// Lifted from a prior `UnsupportedServicoCount(usize)` arm to
70    /// wrap [`caixa_core::ServicoCountMismatch`] so the diagnostic
71    /// names the offending caixa's `:nome` (not just the count),
72    /// shared verbatim with `caixa-helm` (the peer per-Servico
73    /// renderer running the same V0 invariant on the
74    /// `lareira-<nome>` chart-dir axis).
75    #[error("{0}")]
76    UnsupportedServicoCount(#[from] caixa_core::ServicoCountMismatch),
77    #[error("computeunit yaml missing required field: {0}")]
78    MissingField(&'static str),
79    #[error("yaml: {0}")]
80    Yaml(#[from] serde_yaml::Error),
81    #[error("render: {0}")]
82    Render(#[from] caixa_core::RenderError),
83}
84
85/// Default cluster-wide namespace for caixa Servicos when the
86/// computeunit doesn't pin its own. Re-export of the canonical
87/// [`caixa_core::DEFAULT_NAMESPACE`] so the namespace string lives in
88/// exactly one place across every renderer — caixa-flux's
89/// programs.yaml / GitRepository / HelmRelease / Kustomization
90/// emitters and caixa-mesh's programs fan-out / CiliumNetworkPolicy /
91/// Gateway / HTTPRoute emitters now consult the same `&'static str`,
92/// so a future per-cluster-namespace rebrand is a one-line edit on
93/// the canonical [`caixa_core::DEFAULT_NAMESPACE`] declaration, not a
94/// coordinated rewrite across this crate, caixa-mesh, and every
95/// future per-target renderer the substrate adds.
96pub use caixa_core::DEFAULT_NAMESPACE;
97
98/// Canonical Flux v2 `spec.interval` reconcile-poll cadence default the
99/// substrate seeds into every per-caixa `cluster_bundle` CR triplet.
100/// Re-export of the canonical [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`]
101/// so the Flux v2 controller-side reconcile-cadence default scalar-value
102/// string lives in exactly one place across every caixa renderer —
103/// [`ClusterBundleOpts::for_caixa`]'s per-caixa default seed (the sole
104/// production-code site the prior inline `"10m"` scalar-value literal sat
105/// at, seeding the [`ClusterBundleOpts::interval`] field that
106/// [`cluster_bundle`]'s three per-CR format-string templates thread
107/// through their [`FLUX_KEY_INTERVAL`]-keyed `spec.interval` axis
108/// verbatim) now consults the same `&'static str`, so a future substrate-
109/// side reconcile-cadence migration (`"10m"` → `"5m"` on lower-latency-
110/// poll optimizations, `"10m"` → `"15m"` on cost-optimized clusters where
111/// per-CR source-controller poll cost outweighs reconcile-freshness
112/// gains — coordinated with the upstream Flux v2 project's per-controller
113/// tuning cycle) is a one-line edit on the canonical
114/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] declaration, not a
115/// coordinated rewrite across the [`ClusterBundleOpts`] default seed and
116/// every future per-target renderer the substrate adds. Pairs with the
117/// sibling [`FLUX_KEY_INTERVAL`] re-export on the same per-CR
118/// `spec.interval` scalar-axis — the key half of the per-CR scalar-key/
119/// scalar-value pair lives at [`FLUX_KEY_INTERVAL`], the value half's
120/// substrate-side default seed lives here. Same shape as the sibling
121/// [`caixa_core::DEFAULT_NAMESPACE`] / [`caixa_core::DEFAULT_LIBRARY_NAME`]
122/// / [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
123/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] re-exports on the peer
124/// canonical-substrate-default-load-bearing-scalar surface.
125pub use caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL;
126
127/// Canonical Flux v2 `HelmRelease.spec.chart.spec.chart` per-CR chart-
128/// directory-in-GitRepository-source sub-path default the substrate seeds
129/// into every per-caixa `helmrelease.yaml` document. Re-export of the
130/// canonical [`caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH`] so the
131/// Flux v2 helm-controller-side per-CR chart-directory-in-git-source
132/// default scalar-value lives in exactly one place across every caixa
133/// renderer — [`ClusterBundleOpts::for_caixa`]'s per-caixa default seed
134/// (the sole production-code site the prior inline `"chart".into()`
135/// scalar-value literal sat at, seeding the [`ClusterBundleOpts::chart_path`]
136/// field that [`cluster_bundle`]'s `helmrelease.yaml` format-string
137/// template threads through its [`FLUX_HELMCHART_TEMPLATE_KEY_CHART`]-
138/// keyed `spec.chart.spec.chart` axis verbatim) now consults the same
139/// `&'static str`, so a future substrate-side chart-directory-in-git-
140/// source rebrand (`"chart"` → `"charts"` once a per-caixa multi-chart
141/// layout lands and the substrate publishes N sibling `lareira-<nome>/`
142/// charts under one git repository, `"chart"` → `"helm"` on a cross-
143/// language convention alignment with sibling wasm-runtime substrates,
144/// `"chart"` → `"deploy"` on a per-caixa-deploy-directory naming
145/// migration) is a one-line edit on the canonical
146/// [`caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH`] declaration, not a
147/// coordinated rewrite across the [`ClusterBundleOpts`] default seed and
148/// every future per-target renderer the substrate adds. Pairs with the
149/// sibling [`FLUX_HELMCHART_TEMPLATE_KEY_CHART`] re-export on the same
150/// per-CR `spec.chart.spec.chart` scalar-axis — the key half of the per-
151/// CR scalar-key/scalar-value pair lives at
152/// [`FLUX_HELMCHART_TEMPLATE_KEY_CHART`], the value half's substrate-side
153/// default seed lives here. Same shape as the sibling
154/// [`caixa_core::DEFAULT_NAMESPACE`] / [`caixa_core::DEFAULT_LIBRARY_NAME`]
155/// / [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
156/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] /
157/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] /
158/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] re-exports on the peer
159/// canonical-substrate-default-load-bearing-scalar surface.
160pub use caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH;
161
162/// Canonical Flux v2 `HelmRelease.spec.{install,upgrade}.remediation.retries`
163/// bounded retry-count default the substrate seeds into every per-caixa
164/// `helmrelease.yaml` document. Re-export of the canonical
165/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] so the
166/// Flux v2 helm-controller-side remediation-retries default scalar-value
167/// lives in exactly one place across every caixa renderer —
168/// [`cluster_bundle`]'s `helmrelease.yaml` format-string template's two
169/// production-code retry-cap sites (the prior inline `retries: 3`
170/// scalar-value literal under the `install.remediation` sub-block + the
171/// second inline `retries: 3` scalar-value literal under the
172/// `upgrade.remediation` sub-block) now both consume the same `u32` at
173/// emit time through one `{retries_default}` named-arg interpolation, so
174/// a future substrate-side retry-ceiling migration (`3` → `5` once per-
175/// caixa idempotency invariants tighten, `3` → `1` on hardened per-caixa
176/// pipelines where a failed apply should escalate to operator-attention
177/// rather than mask under further retries — coordinated with the
178/// upstream Flux v2 project's per-controller tuning cycle) is a one-line
179/// edit on the canonical
180/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]
181/// declaration, not a coordinated rewrite across the two per-CR
182/// remediation-retries sites. Before this lift the two axes carried
183/// independently-inlined `retries: 3` literals in the sibling
184/// `install.remediation.retries` / `upgrade.remediation.retries`
185/// positions of the [`cluster_bundle`] `helmrelease.yaml` format-string
186/// template — any future retry-ceiling migration on one axis without a
187/// coordinated edit on the other would have silently split the
188/// substrate's canonical retry-ceiling between the install-path (first-
189/// time chart applies) and the upgrade-path (every subsequent per-
190/// caixa-version re-apply the same `HelmRelease` gates), with no field
191/// naming the ceiling-drift root cause. Pairs with the sibling
192/// [`DEFAULT_FLUX_RECONCILE_INTERVAL`] re-export on the same canonical-
193/// Flux-v2-per-CR-substrate-default surface — the reconcile-poll cadence
194/// default names how often the helm-controller re-evaluates per-CR
195/// desired state, and this retry-cap names how many times a per-
196/// evaluation Helm action is allowed to fail-and-retry before it stops.
197/// Same shape as the sibling [`caixa_core::DEFAULT_NAMESPACE`] /
198/// [`caixa_core::DEFAULT_LIBRARY_NAME`] /
199/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
200/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] /
201/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] re-exports on the peer
202/// canonical-substrate-default-load-bearing-scalar surface.
203pub use caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT;
204
205/// Canonical Flux v2 `HelmRelease.spec.{install,upgrade}.remediation.retries`
206/// leaf scalar-key — re-export of the canonical
207/// [`caixa_core::FLUX_HELMRELEASE_KEY_RETRIES`] so the Flux v2
208/// helm-controller-side per-CR remediation-retries leaf-scalar-key lives
209/// in exactly one place across every caixa renderer. Peer to the sibling
210/// [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] (30dcdae) scalar-
211/// value half of the same `(leaf-key, scalar-value)` per-path retry-cap
212/// declaration pair — extends the drift-closing discipline the scalar-
213/// value lift established from the value the leaf holds onto the leaf-
214/// key itself. Two production emit sites (this crate's [`cluster_bundle`]
215/// `helmrelease.yaml` format-string template's install-path retry-cap
216/// leaf under the [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]-valued
217/// sub-block + the sibling upgrade-path retry-cap leaf under the same
218/// scalar-value, both threading the same `&'static str` through a
219/// `{retries_key}` named-arg interpolation) plus two test-fixture
220/// navigation sites in `mod tests` (the install-path
221/// [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
222/// pin's `.get("retries")` probe + the sibling upgrade-path
223/// [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
224/// pin's peer probe) now consult the same `&'static str`. Until this
225/// lift landed the axis carried four inline `retries` literals across
226/// the two production emit sites and the two test-fixture navigation
227/// sites; a future hypothetical Flux v3 rename (`attempts` /
228/// `maxRetries` / `retryCount`) on any production-emit site without a
229/// coordinated edit on the sibling navigation sites would have silently
230/// stripped the retry-cap declaration from the emitted `remediation:`
231/// sub-block, letting the helm-controller fall back to the Flux v2
232/// upstream default rather than the substrate's chosen ceiling with no
233/// diagnostic naming the leaf-key-drift root cause. Same shape as the
234/// sibling [`FLUX_KEY_SOURCE_REF`] (236ef01) / [`FLUX_KEY_CHART`] /
235/// [`FLUX_KEY_VALUES`] / [`FLUX_KEY_INTERVAL`] /
236/// [`FLUX_KEY_HEALTH_CHECKS`] lifts on the peer per-CR container-axis-
237/// key surface — extends the discipline from the container-axis keys
238/// that nest per-CR sub-blocks onto a leaf-scalar-key at the bottom of
239/// a two-level nested per-path retry-cap declaration.
240pub use caixa_core::FLUX_HELMRELEASE_KEY_RETRIES;
241
242/// Canonical Flux v2 `HelmRelease.spec.{install,upgrade}.remediation`
243/// sub-container-axis-key — re-export of the canonical
244/// [`caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATION`] so the Flux v2
245/// helm-controller-side per-CR remediation sub-container-axis-key lives
246/// in exactly one place across every caixa renderer. Peer to the sibling
247/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key half + the
248/// sibling [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] (30dcdae)
249/// scalar-value half of the same
250/// `(container-axis-key, leaf-scalar-key, scalar-value)` per-path retry-
251/// cap declaration triple — closes the parent-container-axis-key axis on
252/// the same per-path retry-cap declaration, so all three halves now live
253/// in one place. Two production emit sites (this crate's
254/// [`cluster_bundle`] `helmrelease.yaml` format-string template's
255/// install-path remediation sub-block-header + the sibling upgrade-path
256/// remediation sub-block-header, both threading the same `&'static str`
257/// through a `{remediation_key}` named-arg interpolation) plus two test-
258/// fixture navigation sites in `mod tests` (the install-path
259/// [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
260/// pin's `.get(FLUX_HELMRELEASE_KEY_REMEDIATION)` probe + the sibling
261/// upgrade-path
262/// [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
263/// pin's peer probe) now consult the same `&'static str`. Until this
264/// lift landed the axis carried four inline `remediation` literals across
265/// the two production emit sites and the two test-fixture navigation
266/// sites; a future hypothetical Flux v3 rename (`recovery` /
267/// `retryPolicy` / `errorHandling`) on any production-emit site without
268/// a coordinated edit on the sibling navigation sites would have
269/// silently stripped the whole per-path remediation sub-block from the
270/// emitted `HelmRelease` CR, letting the helm-controller fall back to
271/// the Flux v2 upstream defaults for the whole remediation surface
272/// rather than the substrate's chosen ceiling with no diagnostic naming
273/// the sub-container-key-drift root cause. Same shape as the sibling
274/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key half plus
275/// the peer [`FLUX_KEY_SOURCE_REF`] (236ef01) / [`FLUX_KEY_CHART`] /
276/// [`FLUX_KEY_VALUES`] / [`FLUX_KEY_INTERVAL`] /
277/// [`FLUX_KEY_HEALTH_CHECKS`] container-axis-key lifts on the peer per-
278/// CR container-axis-key surface — extends the discipline from the
279/// leaf-scalar-key at the bottom of the two-level nested per-path
280/// retry-cap declaration onto the sub-container-axis-key one level up.
281pub use caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATION;
282
283/// Canonical Flux v2 `HelmRelease.spec.install` per-CR helm-action-phase
284/// discriminator parent-container-axis-key — re-export of the canonical
285/// [`caixa_core::FLUX_HELMRELEASE_KEY_INSTALL`] so the Flux v2 helm-
286/// controller-side per-CR install-path phase-discriminator parent-
287/// container-axis-key lives in exactly one place across every caixa
288/// renderer. Pairs with the sibling [`FLUX_HELMRELEASE_KEY_UPGRADE`]
289/// per-CR helm-action-phase discriminator parent-container-axis-key on
290/// the peer per-CR upgrade-path phase. Peer to the sibling
291/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-container-axis-key
292/// hosted beneath both parent-container-axis-keys +
293/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key +
294/// [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] (30dcdae) scalar-
295/// value halves of the same `(parent-container-key, sub-container-key,
296/// leaf-key, scalar-value)` per-path retry-cap declaration quartet —
297/// closes the parent-container-axis-key axis on the same per-path retry-
298/// cap declaration quartet, so all four halves now live in one place.
299/// One production emit site (this crate's [`cluster_bundle`]
300/// `helmrelease.yaml` format-string template's install-path sub-block-
301/// header, threading the same `&'static str` through a new
302/// `{install_key}` named-arg interpolation) plus one test-fixture
303/// navigation site in `mod tests` (the install-path
304/// [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
305/// pin's `.get(FLUX_HELMRELEASE_KEY_INSTALL)` probe) now consult the
306/// same `&'static str`. Until this lift landed the axis carried two
307/// inline `install` literals across the one production emit site and
308/// the one test-fixture navigation site; a future hypothetical Flux v3
309/// rename (`initialize` / `apply` / `create` / `first-run`) on the
310/// production-emit site without a coordinated edit on the sibling
311/// navigation site would have silently stripped the whole install-path
312/// per-CR phase block from the emitted `HelmRelease` CR, letting the
313/// helm-controller fall back to the Flux v2 upstream defaults for the
314/// whole install-path phase surface (the `createNamespace: true` seeder
315/// never fires, the per-CR retry-cap ceiling silently drops off the
316/// emitted document) rather than the substrate's chosen per-CR install-
317/// path knob-set with no diagnostic naming the phase-discriminator-drift
318/// root cause. Same shape as the sibling
319/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-container-axis-key +
320/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key + the peer
321/// [`FLUX_KEY_SOURCE_REF`] (236ef01) / [`FLUX_KEY_CHART`] /
322/// [`FLUX_KEY_VALUES`] / [`FLUX_KEY_INTERVAL`] /
323/// [`FLUX_KEY_HEALTH_CHECKS`] container-axis-key lifts on the peer per-
324/// CR container-axis-key surface — extends the discipline from the sub-
325/// container-axis-key one level up onto the parent-container-axis-key
326/// hosting it, so the four-level nested `spec.install.remediation
327/// .retries` declaration now resolves through four lifted `&'static str`
328/// / `u32` values.
329pub use caixa_core::FLUX_HELMRELEASE_KEY_INSTALL;
330
331/// Canonical Flux v2 `HelmRelease.spec.upgrade` per-CR helm-action-phase
332/// discriminator parent-container-axis-key — re-export of the canonical
333/// [`caixa_core::FLUX_HELMRELEASE_KEY_UPGRADE`] so the Flux v2 helm-
334/// controller-side per-CR upgrade-path phase-discriminator parent-
335/// container-axis-key lives in exactly one place across every caixa
336/// renderer. Pairs with the sibling [`FLUX_HELMRELEASE_KEY_INSTALL`]
337/// per-CR helm-action-phase discriminator parent-container-axis-key on
338/// the peer per-CR install-path phase. Peer to the sibling
339/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-container-axis-key
340/// hosted beneath both parent-container-axis-keys. One production emit
341/// site (this crate's [`cluster_bundle`] `helmrelease.yaml` format-
342/// string template's upgrade-path sub-block-header, threading the same
343/// `&'static str` through a new `{upgrade_key}` named-arg interpolation)
344/// plus one test-fixture navigation site in `mod tests` (the upgrade-
345/// path
346/// [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
347/// pin's `.get(FLUX_HELMRELEASE_KEY_UPGRADE)` probe) now consult the
348/// same `&'static str`. Until this lift landed the axis carried two
349/// inline `upgrade` literals across the one production emit site and
350/// the one test-fixture navigation site; a future hypothetical Flux v3
351/// rename (`reapply` / `reconcile` / `update` / `promote`) on the
352/// production-emit site without a coordinated edit on the sibling
353/// navigation site would have silently stripped the whole upgrade-path
354/// per-CR phase block from the emitted `HelmRelease` CR, letting the
355/// helm-controller fall back to the Flux v2 upstream defaults for the
356/// whole upgrade-path phase surface (the substrate's
357/// `remediateLastFailure: true` toggle never fires, the per-CR retry-
358/// cap ceiling silently drops off the emitted document) rather than the
359/// substrate's chosen per-CR upgrade-path knob-set with no diagnostic
360/// naming the phase-discriminator-drift root cause. Same shape as the
361/// sibling [`FLUX_HELMRELEASE_KEY_INSTALL`] parent-container-axis-key
362/// on the peer per-CR install-path phase — pairs with the install-path
363/// re-export to close the per-CR helm-action-phase discriminator
364/// parent-container-axis-key pair across both per-CR phases the helm-
365/// controller reconciles between.
366pub use caixa_core::FLUX_HELMRELEASE_KEY_UPGRADE;
367
368/// Canonical Flux v2 `HelmRelease.spec.upgrade.remediation.remediateLastFailure`
369/// upgrade-path-only per-CR remediation-toggle leaf-scalar-key — re-export
370/// of the canonical [`caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`]
371/// so the Flux v2 helm-controller-side upgrade-path per-CR remediation-
372/// toggle leaf-scalar-key lives in exactly one place across every caixa
373/// renderer. Sibling to the peer [`FLUX_HELMRELEASE_KEY_RETRIES`] per-CR
374/// retry-cap leaf-scalar-key at the same per-CR upgrade-path per-CR
375/// remediation sub-container position — closes the
376/// `spec.upgrade.remediation.{retries, remediateLastFailure}` per-path
377/// remediation-block leaf-scalar-key pair the substrate seeds into every
378/// emitted per-caixa `HelmRelease` CR on the upgrade-path per-CR
379/// remediation block. One production emit site (this crate's
380/// [`cluster_bundle`] `helmrelease.yaml` format-string template's
381/// upgrade-path remediation-toggle leaf under the sibling
382/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`]-container-keyed sub-block,
383/// threading the same `&'static str` through a new
384/// `{remediate_last_failure_key}` named-arg interpolation) plus one test-
385/// fixture navigation site in `mod tests` (the upgrade-path
386/// [`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
387/// pin's `.get(FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE)` probe) now
388/// consult the same `&'static str`. Until this lift landed the axis
389/// carried the load-bearing `remediateLastFailure` bytes inline at the
390/// one production emit site; a future hypothetical Flux v3 rename
391/// (`rollbackOnFailure` / `remediateOnFailure` / `recoverLastFailure`)
392/// on the production-emit site without a coordinated edit on every
393/// per-renderer consumer the absorption roadmap surfaces (the M4
394/// `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-Aplicacao
395/// `HelmRelease` synthesis) would have silently dropped the substrate's
396/// chosen post-retry-exhaustion rollback semantic from every emitted
397/// per-caixa `HelmRelease` document — the helm-controller would then
398/// leave every terminally-failed upgrade in the failed state without
399/// rolling back to the prior last-known-good release the substrate's
400/// "no chart apply leaves a per-caixa CR in a stalled, unremediated
401/// state" MESH-COMPOSITION.md §V guarantee mandates, with no diagnostic
402/// naming the remediation-toggle-drift root cause far from the source
403/// caixa.lisp / the renderer's format-string template. Same shape as
404/// the sibling [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-
405/// key + the peer [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-
406/// container-axis-key + [`FLUX_HELMRELEASE_KEY_INSTALL`] /
407/// [`FLUX_HELMRELEASE_KEY_UPGRADE`] (7767c26) parent-container-axis-key
408/// pair lifts on the peer per-CR remediation-surface leaf-scalar-key /
409/// container-axis-key surface — extends the discipline from the sibling
410/// retry-cap leaf-scalar-key onto the co-resident remediation-toggle
411/// leaf-scalar-key at the same `spec.upgrade.remediation.*` position.
412pub use caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE;
413
414/// Canonical Flux v2 `HelmRelease.spec.upgrade.remediation.remediateLastFailure`
415/// upgrade-path-only per-CR remediation-toggle scalar-value default the
416/// substrate seeds into every per-caixa `helmrelease.yaml` document at the
417/// paired [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] leaf-scalar-key
418/// axis. Re-export of the canonical
419/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`] so the
420/// Flux v2 helm-controller-side per-CR upgrade-path per-CR post-retry-
421/// exhaustion-rollback-toggle scalar-value default lives in exactly one
422/// place across every caixa renderer — [`cluster_bundle`]'s
423/// `helmrelease.yaml` format-string template's per-CR upgrade-path
424/// remediation-toggle scalar under the [`FLUX_HELMRELEASE_KEY_UPGRADE`]-
425/// keyed sub-block (the sole production-code site the prior inline
426/// `remediateLastFailure: true` scalar-value literal sat at, alongside the
427/// [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`]-keyed leaf-scalar-key
428/// half of the same `(leaf-key, scalar-value)` pair) now threads the same
429/// `bool` through a `{remediate_last_failure_default}` named-arg
430/// interpolation, so a future substrate-side toggle migration (`true` →
431/// `false` on a per-cluster class where terminally-failed upgrades must
432/// escalate to operator-attention rather than mask under an auto-rollback
433/// pipeline; a per-caixa opt-out slot the ABSORPTION-ROADMAP.md M4 typed-
434/// slot trajectory adds once the substrate grows a `:upgrade
435/// :remediate-last-failure` author-side toggle) is a one-line edit on the
436/// canonical [`caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`]
437/// declaration, not a coordinated rewrite across the emit site + every
438/// future per-target renderer the substrate adds. Pairs with the sibling
439/// [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] re-export on the same
440/// per-CR `spec.upgrade.remediation.remediateLastFailure` scalar-axis —
441/// the key half of the per-CR scalar-key/scalar-value pair lives at
442/// [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`], the value half's
443/// substrate-side default seed lives here. Same shape as the sibling
444/// [`FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] (ea857d8) scalar-value default
445/// re-export on the peer per-CR `Kustomization` garbage-collection-toggle
446/// axis — that default names whether the per-CR `Kustomization` reconcile
447/// loop sweeps orphaned resources at all, and this default names whether
448/// the per-CR `HelmRelease` upgrade-path remediation loop rolls back to
449/// the prior last-known-good release once the retry-cap ceiling is
450/// exhausted. Both are substrate-side policy choices the operator
451/// inherits when the per-caixa [`ClusterBundleOpts`] doesn't pin an
452/// override, and both must move together on any coordinated substrate-
453/// side Flux v2 per-CR tuning-cycle promotion. Until this lift landed the
454/// axis carried an inline `true` scalar-value literal at the sole
455/// production-code call site plus the sibling test-fixture navigation
456/// site ([`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
457/// pin's `assert!(remediate_last_failure)` predicate) — two occurrences
458/// of the same load-bearing Flux-v2-per-CR-upgrade-path-remediation-
459/// toggle-scalar-value convention, drift-prone by construction ahead of
460/// the third occurrence the M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR
461/// materializer's per-Aplicacao `HelmRelease` synthesis will surface.
462/// Same shape as the sibling [`caixa_core::DEFAULT_NAMESPACE`] /
463/// [`caixa_core::DEFAULT_LIBRARY_NAME`] /
464/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
465/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] /
466/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] /
467/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] /
468/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] /
469/// [`caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] re-exports on the peer
470/// canonical-substrate-default-load-bearing-scalar surface.
471pub use caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT;
472
473/// Canonical Flux v2 `HelmRelease.spec.install.createNamespace` install-path-
474/// only per-CR namespace-seeder-toggle leaf-scalar-key — re-export of the
475/// canonical [`caixa_core::FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] so the
476/// Flux v2 helm-controller-side install-path per-CR namespace-seeder-toggle
477/// leaf-scalar-key lives in exactly one place across every caixa renderer.
478/// Peer to the sibling [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`]
479/// (96581b7) upgrade-path-only per-CR remediation-toggle leaf-scalar-key at
480/// the mirror-symmetric parent-container-axis-key position — closes the
481/// `spec.{install.createNamespace, upgrade.remediation.remediateLastFailure}`
482/// per-path per-CR phase-specific toggle leaf-scalar-key pair the substrate
483/// seeds into every emitted per-caixa `HelmRelease` CR. One production emit
484/// site (this crate's [`cluster_bundle`] `helmrelease.yaml` format-string
485/// template's install-path namespace-seeder-toggle leaf under the sibling
486/// [`FLUX_HELMRELEASE_KEY_INSTALL`]-container-keyed sub-block, threading
487/// the same `&'static str` through a new `{create_namespace_key}` named-
488/// arg interpolation) plus one test-fixture navigation site in `mod tests`
489/// (the install-path
490/// [`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
491/// pin's `.get(FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE)` probe) now consult
492/// the same `&'static str`. Until this lift landed the axis carried the
493/// load-bearing `createNamespace` bytes inline at the one production emit
494/// site; a future hypothetical Flux v3 rename (`createTargetNamespace` /
495/// `seedNamespace` / `provisionNamespace`) on the production-emit site
496/// without a coordinated edit on every per-renderer consumer the
497/// absorption roadmap surfaces (the M4 `mesh.pleme.io/v1alpha1/Aplicacao`
498/// CR materializer's per-Aplicacao `HelmRelease` synthesis) would have
499/// silently dropped the substrate's chosen first-apply namespace-seeder
500/// semantic from every emitted per-caixa `HelmRelease` document — the
501/// helm-controller would then refuse every first-time per-caixa chart
502/// apply against a fresh cluster whose target namespace has not been
503/// pre-provisioned by an out-of-band pipeline the substrate's "no per-
504/// caixa Servico apply is blocked on manual namespace preprovisioning"
505/// MESH-COMPOSITION.md §V install-path-fluency guarantee mandates, with no
506/// diagnostic naming the seeder-toggle-drift root cause far from the
507/// source caixa.lisp / the renderer's format-string template. Same shape
508/// as the sibling [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] (96581b7)
509/// upgrade-path-only per-CR remediation-toggle leaf-scalar-key +
510/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key + peer
511/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-container-axis-key +
512/// [`FLUX_HELMRELEASE_KEY_INSTALL`] / [`FLUX_HELMRELEASE_KEY_UPGRADE`]
513/// (7767c26) parent-container-axis-key pair lifts on the peer per-CR
514/// HelmRelease-spec surface — extends the discipline from the sibling
515/// upgrade-path-only per-CR remediation-toggle onto the mirror install-
516/// path-only per-CR namespace-seeder-toggle at the `spec.install.*`
517/// position mirroring the peer's `spec.upgrade.remediation.*` position.
518pub use caixa_core::FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE;
519
520/// Canonical Flux v2 `HelmRelease.spec.install.createNamespace` install-path-
521/// only per-CR namespace-seeder-toggle scalar-value default the substrate
522/// seeds into every per-caixa `helmrelease.yaml` document at the paired
523/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] leaf-scalar-key axis. Re-
524/// export of the canonical
525/// [`caixa_core::FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT`] so the Flux
526/// v2 helm-controller-side per-CR install-path per-CR namespace-seeder-
527/// toggle scalar-value default lives in exactly one place across every
528/// caixa renderer — [`cluster_bundle`]'s `helmrelease.yaml` format-
529/// string template's per-CR install-path namespace-seeder-toggle scalar
530/// under the [`FLUX_HELMRELEASE_KEY_INSTALL`]-keyed sub-block (the sole
531/// production-code site the prior inline `createNamespace: true` scalar-
532/// value literal sat at, alongside the [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`]-
533/// keyed leaf-scalar-key half of the same `(leaf-key, scalar-value)`
534/// pair) now threads the same `bool` through a `{create_namespace_default}`
535/// named-arg interpolation, so a future substrate-side toggle migration
536/// (`true` → `false` on hardened per-cluster classes where namespace
537/// provisioning is an out-of-band operator gate; a per-caixa opt-out
538/// slot the ABSORPTION-ROADMAP.md M4 typed-slot trajectory adds once the
539/// substrate grows a `:install :create-namespace` author-side toggle) is
540/// a one-line edit on the canonical
541/// [`caixa_core::FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT`] declaration,
542/// not a coordinated rewrite across the emit site + every future per-
543/// target renderer the substrate adds. Pairs with the sibling
544/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] re-export on the same per-CR
545/// `spec.install.createNamespace` scalar-axis — the key half of the
546/// per-CR scalar-key/scalar-value pair lives at
547/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`], the value half's substrate-
548/// side default seed lives here. Peer with the sibling
549/// [`FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`] mirror-symmetric
550/// upgrade-path-only scalar-value default + the sibling
551/// [`FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] (ea857d8) scalar-value default
552/// on the peer canonical-Flux-v2-per-CR-substrate-default surface — the
553/// three defaults name the substrate's canonical (install-path
554/// namespace-seeder) / (upgrade-path post-retry-exhaustion rollback) /
555/// (garbage-collection-toggle) toggle triple across the per-caixa
556/// `HelmRelease` and `Kustomization` co-resident CRs. All three are
557/// substrate-side policy choices the operator inherits when the per-
558/// caixa [`ClusterBundleOpts`] doesn't pin an override, and all three
559/// must move together on any coordinated substrate-side Flux v2 per-CR
560/// tuning-cycle promotion. Until this lift landed the axis carried an
561/// inline `true` scalar-value literal at the sole production-code call
562/// site plus the sibling test-fixture navigation site
563/// ([`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
564/// pin's `assert!(create_namespace)` predicate) — two occurrences of the
565/// same load-bearing Flux-v2-per-CR-install-path-namespace-seeder-
566/// toggle-scalar-value convention, drift-prone by construction ahead of
567/// the third occurrence the M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR
568/// materializer's per-Aplicacao `HelmRelease` synthesis will surface.
569/// Same shape as the sibling [`caixa_core::DEFAULT_NAMESPACE`] /
570/// [`caixa_core::DEFAULT_LIBRARY_NAME`] /
571/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
572/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] /
573/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] /
574/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] /
575/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] /
576/// [`caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] /
577/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`]
578/// re-exports on the peer canonical-substrate-default-load-bearing-
579/// scalar surface.
580pub use caixa_core::FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT;
581
582/// Canonical Flux v2 `Kustomization.spec.prune` per-CR garbage-collection-
583/// toggle leaf-scalar-key — re-export of the canonical
584/// [`caixa_core::FLUX_KUSTOMIZATION_KEY_PRUNE`] so the Flux v2 kustomize-
585/// controller-side per-CR garbage-collection-toggle leaf-scalar-key lives
586/// in exactly one place across every caixa renderer. Peer to the sibling
587/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] (ba9ab8b) install-path-only
588/// per-CR namespace-seeder-toggle leaf-scalar-key on the co-resident
589/// per-caixa `HelmRelease` CR — extends the per-CR-toggle leaf-scalar-key
590/// discipline from the co-resident per-caixa `HelmRelease` CR spec surface
591/// onto the co-resident per-caixa `Kustomization` CR spec surface at the
592/// mirror-symmetric top-level `spec.prune` position. One production emit
593/// site (this crate's [`cluster_bundle`] `kustomization.yaml` format-
594/// string template's per-CR garbage-collection-toggle leaf under the
595/// top-level `spec` position, threading the same `&'static str` through a
596/// new `{prune_key}` named-arg interpolation) plus one test-fixture
597/// navigation site in `mod tests` (the per-CR
598/// [`cluster_bundle_kustomization_prune_pins_lifted_true`] pin's
599/// `.get(FLUX_KUSTOMIZATION_KEY_PRUNE)` probe) now consult the same
600/// `&'static str`. Until this lift landed the axis carried the load-
601/// bearing `prune` bytes inline at the one production emit site; a
602/// future hypothetical Flux v3 rename (`garbageCollect` / `sweep` /
603/// `pruneOrphaned` / `deleteOrphans`) on the production-emit site
604/// without a coordinated edit on every per-renderer consumer the
605/// absorption roadmap surfaces (the M4 `mesh.pleme.io/v1alpha1/Aplicacao`
606/// CR materializer's per-Aplicacao `Kustomization` synthesis) would have
607/// silently dropped the substrate's chosen sweep-what-you-removed
608/// semantic from every emitted per-caixa `Kustomization` document — the
609/// kustomize-controller would then leave every per-caixa resource the
610/// source manifest set previously reconciled but no longer carries
611/// dangling in the cluster the substrate's "the cluster's per-caixa live
612/// state converges to the caixa's tatara-lisp source-of-truth on every
613/// reconcile — resources the source no longer carries are swept by the
614/// kustomize-controller, not left dangling" CAIXA-SDLC.md §V author-to-
615/// live-convergence guarantee mandates, with no diagnostic naming the
616/// toggle-drift root cause far from the source caixa.lisp / the
617/// renderer's format-string template. Same shape as the sibling
618/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] (ba9ab8b) install-path-only
619/// per-CR namespace-seeder-toggle leaf-scalar-key +
620/// [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] (96581b7) upgrade-
621/// path-only per-CR remediation-toggle leaf-scalar-key +
622/// [`FLUX_HELMRELEASE_KEY_RETRIES`] (a12f9fc) leaf-scalar-key + peer
623/// [`FLUX_HELMRELEASE_KEY_REMEDIATION`] (6fe4e7e) sub-container-axis-key
624/// + [`FLUX_HELMRELEASE_KEY_INSTALL`] / [`FLUX_HELMRELEASE_KEY_UPGRADE`]
625/// (7767c26) parent-container-axis-key pair lifts on the peer per-CR
626/// HelmRelease-spec surface — extends the discipline from the co-
627/// resident per-`HelmRelease`-CR spec surface onto the co-resident per-
628/// `Kustomization`-CR spec surface at the mirror-symmetric top-level
629/// `spec.prune` position.
630pub use caixa_core::FLUX_KUSTOMIZATION_KEY_PRUNE;
631
632/// Canonical Flux v2 `Kustomization.spec.prune` per-CR garbage-collection-
633/// toggle scalar-value default the substrate seeds into every per-caixa
634/// `kustomization.yaml` document at the paired
635/// [`FLUX_KUSTOMIZATION_KEY_PRUNE`] leaf-scalar-key axis. Re-export of
636/// the canonical [`caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] so the
637/// Flux v2 kustomize-controller-side per-CR garbage-collection-toggle
638/// scalar-value default lives in exactly one place across every caixa
639/// renderer — [`cluster_bundle`]'s `kustomization.yaml` format-string
640/// template's per-CR garbage-collection-toggle scalar under the top-level
641/// `spec` position (the sole production-code site the prior inline
642/// `prune: true` scalar-value literal sat at, alongside the
643/// [`FLUX_KUSTOMIZATION_KEY_PRUNE`]-keyed leaf-scalar-key half of the
644/// same `(leaf-key, scalar-value)` pair) now threads the same `bool`
645/// through a `{prune_default}` named-arg interpolation, so a future
646/// substrate-side toggle migration (`true` → `false` on a cluster class
647/// where a human is expected to prune orphaned resources by hand once
648/// per-cluster policy grows an "operator-driven cleanup" mode; a per-
649/// caixa opt-out slot the ABSORPTION-ROADMAP.md M4 typed-slot
650/// trajectory adds once the substrate grows a `:kustomization :prune`
651/// author-side toggle) is a one-line edit on the canonical
652/// [`caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] declaration, not a
653/// coordinated rewrite across the emit site + every future per-target
654/// renderer the substrate adds. Pairs with the sibling
655/// [`FLUX_KUSTOMIZATION_KEY_PRUNE`] re-export on the same per-CR
656/// `spec.prune` scalar-axis — the key half of the per-CR scalar-key /
657/// scalar-value pair lives at [`FLUX_KUSTOMIZATION_KEY_PRUNE`], the
658/// value half's substrate-side default seed lives here. Same shape as
659/// the sibling [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] (30dcdae)
660/// scalar-value default re-export on the peer per-CR HelmRelease
661/// remediation retry-cap axis — that default names the per-path per-CR
662/// remediation retry ceiling, and this default names whether the
663/// per-CR reconcile loop sweeps orphaned resources at all. Both are
664/// substrate-side policy choices the operator inherits when the per-
665/// caixa [`ClusterBundleOpts`] doesn't pin an override, and both must
666/// move together on any coordinated substrate-side Flux v2 per-CR
667/// tuning-cycle promotion. Until this lift landed the axis carried an
668/// inline `true` scalar-value literal at the sole production-code call
669/// site plus the sibling test-fixture navigation site
670/// ([`cluster_bundle_kustomization_prune_pins_lifted_true`] pin's
671/// `assert!(prune)` predicate) — two occurrences of the same load-
672/// bearing Flux-v2-per-CR-garbage-collection-toggle-scalar-value
673/// convention, drift-prone by construction ahead of the third
674/// occurrence the M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's
675/// per-Aplicacao `Kustomization` synthesis will surface. Same shape as
676/// the sibling [`caixa_core::DEFAULT_NAMESPACE`] /
677/// [`caixa_core::DEFAULT_LIBRARY_NAME`] /
678/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] /
679/// [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] /
680/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] /
681/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] /
682/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]
683/// re-exports on the peer canonical-substrate-default-load-bearing-
684/// scalar surface.
685pub use caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT;
686
687/// Canonical substrate-side default for the
688/// `HelmRelease.spec.values.<library>.enabled` child-chart-enablement
689/// toggle scalar every [`cluster_bundle`]-emitted `helmrelease.yaml`
690/// document seeds under its per-`{library_name}` values-overlay wrap
691/// to force-on the paired [`caixa_core::DEFAULT_LIBRARY_NAME`] child
692/// chart at the per-cluster `HelmRelease`-side apply step — re-export
693/// of the canonical [`caixa_core::CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT`]
694/// so the substrate-side child-chart-enablement-toggle scalar-value
695/// default lives in exactly one place across every caixa renderer.
696/// Pairs with the sibling [`caixa_core::HELM_VALUES_KEY_ENABLED`]
697/// leaf-scalar-key half of the `(leaf-key, scalar-value)`
698/// per-values-overlay child-chart-enablement-toggle declaration pair.
699///
700/// Peer with the sibling [`FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT`]
701/// (be1904b), [`FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`]
702/// (be1904b), [`FLUX_KUSTOMIZATION_PRUNE_DEFAULT`] (ea857d8), and
703/// [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]
704/// scalar-value defaults on the peer canonical-Flux-v2-per-CR-
705/// substrate-default surface — the four sibling scalar-value defaults
706/// name per-CR toggle-shape axes at the `HelmRelease.spec.install.*` /
707/// `HelmRelease.spec.upgrade.*` / `HelmRelease.spec.upgrade.remediation.retries`
708/// / `Kustomization.spec.prune` sub-block positions, and this scalar-
709/// value default names the child-chart-enablement toggle at the deeper
710/// `HelmRelease.spec.values.<library>.enabled` values-overlay position.
711///
712/// Until this lift landed the axis carried an inline `true` scalar-value
713/// literal at the sole production-code call site (the `{enabled_key}: true`
714/// leaf inside [`cluster_bundle`]'s `helmrelease.yaml` format-string
715/// template's per-`{library_name}` wrap position) plus its paired
716/// test-fixture navigation site's `Some(true)` assertion — two
717/// occurrences of the same load-bearing values-overlay child-chart-
718/// enablement-toggle-scalar-value convention, drift-prone by construction
719/// ahead of the third occurrence the M4
720/// `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-Aplicacao
721/// `HelmRelease` synthesis will surface.
722pub use caixa_core::CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT;
723
724/// Canonical Flux v2 `Kustomization.spec.path` per-CR source-sub-tree
725/// leaf-scalar-key — re-export of the canonical
726/// [`caixa_core::FLUX_KUSTOMIZATION_KEY_PATH`] so the Flux v2 kustomize-
727/// controller-side per-CR source-sub-tree leaf-scalar-key lives in
728/// exactly one place across every caixa renderer. Peer to the sibling
729/// co-resident [`FLUX_KUSTOMIZATION_KEY_PRUNE`] (8ec7917) per-CR
730/// garbage-collection-toggle leaf-scalar-key on the same top-level
731/// `spec` position of the emitted per-caixa `Kustomization` CR — extends
732/// the per-`Kustomization`-CR-spec leaf-scalar-key discipline from the
733/// co-resident garbage-collection-toggle axis onto the co-resident
734/// source-sub-tree axis at the mirror-symmetric top-level `spec.path`
735/// position. One production emit site (this crate's [`cluster_bundle`]
736/// `kustomization.yaml` format-string template's per-CR source-sub-tree
737/// leaf under the top-level `spec` position, threading the same
738/// `&'static str` through a new `{path_key}` named-arg interpolation)
739/// plus one test-fixture navigation site in `mod tests` (the per-CR
740/// [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`] pin's
741/// `.get(FLUX_KUSTOMIZATION_KEY_PATH)` probe) now consult the same
742/// `&'static str`. Until this lift landed the axis carried the load-
743/// bearing `path` bytes inline at the one production emit site; a
744/// future hypothetical Flux v3 rename (`sourcePath` / `manifestsPath` /
745/// `sourceRoot`) on the production-emit site without a coordinated edit
746/// on every per-renderer consumer the absorption roadmap surfaces (the
747/// M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-
748/// Aplicacao `Kustomization` synthesis) would have silently unbound
749/// every emitted per-caixa `Kustomization` from its paired per-caixa
750/// sub-tree of the pleme-io k8s repository — the Flux v2 kustomize-
751/// controller would then either reconcile the whole GitRepository root
752/// (defaulting to `./` when the CR omits the leaf, pulling every
753/// unrelated cluster's manifests through the wrong per-caixa
754/// `Kustomization`) or refuse to reconcile at all (parking the CR at
755/// `BuildFailed` naming the missing sub-tree far from the source
756/// `caixa.lisp` / the renderer's format-string template).
757pub use caixa_core::FLUX_KUSTOMIZATION_KEY_PATH;
758
759/// Canonical substrate-side per-cluster / per-caixa
760/// `Kustomization.spec.path` source-sub-tree scalar composer — re-export
761/// of the canonical [`caixa_core::flux_kustomization_source_subtree`]
762/// so the `./clusters/<cluster>/services/<nome>` GitRepository-relative
763/// directory-tree seed every emitted per-caixa `kustomization.yaml`
764/// document mounts under its lifted [`FLUX_KUSTOMIZATION_KEY_PATH`]
765/// leaf-scalar-key lives at one composer across every caixa renderer.
766///
767/// Peer to [`FLUX_KUSTOMIZATION_KEY_PATH`] (613d7ed) — the leaf-scalar-
768/// key half of the `spec.path` `(key, value)` per-CR pair — on the
769/// paired value-half axis. Until this lift landed the two-axis
770/// composition (the `./clusters/` per-cluster prefix + the `/services/`
771/// per-caixa infix) sat as a verbatim inline
772/// `format!("./clusters/{cluster}/services/{name}")` at the sole
773/// [`cluster_bundle`] `kustomization.yaml` format-string production
774/// emit site plus a mirror-symmetric verbatim inline
775/// `format!("./clusters/{cluster}/services/{name}", …)` at its paired
776/// `cluster_bundle_kustomization_path_pins_lifted_sub_tree` test-fixture
777/// navigation site, with no compile-time link between the two sites and
778/// no compile-time link ahead of the second production-emit occurrence
779/// the M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-
780/// Aplicacao `Kustomization` synthesis will surface. Both sites now
781/// consult the same canonical composer, so a future substrate-side
782/// directory-tree axis rebrand (`clusters/` → `environments/` for a
783/// multi-env-per-cluster axis extension, `services/` → `servicos/` for
784/// a portuguese-canonical directory-name migration matching the sibling
785/// `:servicos` slot spelling, a per-tenant scoping prefix for multi-
786/// tenant Aplicacao hosting) is one edit at the composer, not a
787/// coordinated sweep across every renderer's `spec.path` emit site.
788/// Same shape as the sibling [`caixa_core::oci_chart_ref`] /
789/// [`caixa_core::cilium_network_policy_name`] /
790/// [`caixa_core::gateway_api_http_route_name`] composer re-exports on
791/// the peer substrate-side canonical-load-bearing-scalar-that-consumers-
792/// key-off axis.
793pub use caixa_core::flux_kustomization_source_subtree;
794
795/// Canonical Flux v2 `Kustomization.spec.timeout` per-CR reconcile
796/// wall-clock cap leaf-scalar-key — re-export of the canonical
797/// [`caixa_core::FLUX_KUSTOMIZATION_KEY_TIMEOUT`] so the Flux v2
798/// kustomize-controller-side per-CR reconcile wall-clock cap leaf-
799/// scalar-key lives in exactly one place across every caixa
800/// renderer. Peer to the co-resident
801/// [`FLUX_KUSTOMIZATION_KEY_PATH`] (613d7ed) per-CR source-sub-tree
802/// leaf-scalar-key and [`FLUX_KUSTOMIZATION_KEY_PRUNE`] (8ec7917)
803/// per-CR garbage-collection-toggle leaf-scalar-key on the same top-
804/// level `spec` position of the emitted per-caixa `Kustomization` CR
805/// — extends the per-`Kustomization`-CR-spec leaf-scalar-key
806/// discipline from the co-resident source-sub-tree and garbage-
807/// collection-toggle axes onto the co-resident reconcile wall-clock
808/// cap axis at the mirror-symmetric top-level `spec.timeout`
809/// position. One production emit site (this crate's
810/// [`cluster_bundle`] `kustomization.yaml` format-string template's
811/// per-CR reconcile wall-clock cap leaf under the top-level `spec`
812/// position, threading the same `&'static str` through a new
813/// `{timeout_key}` named-arg interpolation) plus one test-fixture
814/// navigation site in `mod tests` (the per-CR
815/// [`cluster_bundle_kustomization_timeout_pins_lifted_default`] pin's
816/// `.get(FLUX_KUSTOMIZATION_KEY_TIMEOUT)` probe) now consult the same
817/// `&'static str`. Until this lift landed the axis carried the load-
818/// bearing `timeout` bytes inline at the one production emit site; a
819/// future hypothetical Flux v3 rename (`deadline` / `reconcileTimeout`
820/// / `maxDuration`) on the production-emit site without a coordinated
821/// edit on every per-renderer consumer the absorption roadmap
822/// surfaces (the M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR
823/// materializer's per-Aplicacao `Kustomization` synthesis) would have
824/// silently stripped the substrate's chosen reconcile-ceiling
825/// declaration from every emitted per-caixa `Kustomization` document
826/// — the Flux v2 kustomize-controller would then fall back to the
827/// upstream Flux v2 controller-side default cap, letting a
828/// persistently-failing per-caixa manifest apply consume kustomize-
829/// controller reconcile-loop cycles past the substrate's chosen
830/// ceiling with no field naming the leaf-key-drift root cause far
831/// from the source `caixa.lisp` / the renderer's format-string
832/// template. Pairs with the sibling
833/// [`DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] scalar-value half of the
834/// same `(leaf-key, scalar-value)` per-path reconcile-ceiling-
835/// declaration pair. Same shape as the sibling
836/// [`FLUX_KUSTOMIZATION_KEY_PATH`] (613d7ed) /
837/// [`FLUX_KUSTOMIZATION_KEY_PRUNE`] (8ec7917) /
838/// [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] (96581b7) /
839/// [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] (ba9ab8b) leaf-scalar-
840/// key re-exports on the peer per-Flux-v2-CR-spec-leaf-scalar-key
841/// surface.
842pub use caixa_core::FLUX_KUSTOMIZATION_KEY_TIMEOUT;
843
844/// Canonical Flux v2 `Kustomization.spec.timeout` per-CR reconcile
845/// wall-clock cap default the substrate seeds into every per-caixa
846/// `kustomization.yaml` document. Re-export of the canonical
847/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] so the Flux v2
848/// kustomize-controller-side per-CR reconcile-ceiling default scalar-
849/// value lives in exactly one place across every caixa renderer —
850/// [`cluster_bundle`]'s `kustomization.yaml` format-string template's
851/// sole production-code emit site (the prior inline `timeout: 5m`
852/// scalar-value literal under the top-level `spec` position, keyed by
853/// the sibling [`FLUX_KUSTOMIZATION_KEY_TIMEOUT`] leaf-scalar-key)
854/// now consumes the same `&'static str` at emit time through one
855/// `{timeout_default}` named-arg interpolation, so a future
856/// substrate-side reconcile-ceiling migration (`"5m"` → `"3m"` on
857/// faster per-caixa idempotency-checkpoint cadence, `"5m"` → `"10m"`
858/// on larger per-caixa manifest sets — coordinated with the sibling
859/// [`DEFAULT_FLUX_RECONCILE_INTERVAL`] reconcile-poll cadence tuning
860/// cycle) is a one-line edit on the canonical
861/// [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] declaration, not
862/// a coordinated rewrite across the emit site + every future per-CR
863/// reconcile-cap consumer the substrate adds. Pairs with the sibling
864/// [`FLUX_KUSTOMIZATION_KEY_TIMEOUT`] re-export on the same per-CR
865/// `spec.timeout` scalar-axis — the key half of the per-CR scalar-
866/// key/scalar-value pair lives at [`FLUX_KUSTOMIZATION_KEY_TIMEOUT`],
867/// the value half's substrate-side default seed lives here. Same
868/// shape as the sibling [`DEFAULT_FLUX_RECONCILE_INTERVAL`] (908180f)
869/// / [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] (30dcdae) re-
870/// exports on the peer canonical-substrate-default-load-bearing-
871/// scalar surface.
872pub use caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT;
873
874/// Canonical FluxCD installation namespace — re-export of the lifted
875/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] so the load-bearing
876/// string lives in exactly one place across every consumer of the
877/// rendered `kustomization.yaml`'s `metadata.namespace` and
878/// `spec.sourceRef.name` axes. Both axes are the same conceptual "Flux
879/// installation namespace" the `flux bootstrap` pipeline names; until
880/// this lift landed they sat as two inline `flux-system` literals inside
881/// [`cluster_bundle`]'s `kustomization.yaml` format-string template, and
882/// any future per-edition Flux-installation-namespace rebrand on one
883/// without a coordinated edit on the other would have silently emitted a
884/// `Kustomization` outside the bootstrap controller's watch window or a
885/// dangling `sourceRef`. Same shape as the
886/// [`caixa_core::DEFAULT_NAMESPACE`] (a085b26) /
887/// [`caixa_core::DEFAULT_LIBRARY_NAME`] (41438dc) /
888/// [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`] (0a6a602) lifts on the peer
889/// canonical-load-bearing-string surface.
890pub use caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE;
891
892/// Canonical FluxCD `HelmRelease` CRD `apiVersion` — re-export of the
893/// lifted [`caixa_core::FLUX_HELMRELEASE_API_VERSION`] so the load-bearing
894/// string lives in exactly one place across the rendered Flux bundle's
895/// `helmrelease.yaml` document `apiVersion` axis + the rendered
896/// `kustomization.yaml` document's `spec.healthChecks[].apiVersion` axis.
897/// Both axes are the same conceptual "Flux v2 `HelmRelease` CRD group/
898/// version" load-bearing string and must move together on any future
899/// upstream Flux v3 migration; until this lift landed they sat as four
900/// inline `helm.toolkit.fluxcd.io/v2` literals (two render-side at lines
901/// 455, 504 + two test-fixture-side at lines 928, 970), and any future
902/// per-Flux-v3-migration version bump on one without a coordinated edit
903/// on the other would have silently routed the rendered `HelmRelease`
904/// outside the controller's `Watches` (controller-side: never reconciled,
905/// every dependent chart frozen at last-applied state) or made the
906/// `Kustomization`'s health-check dangle (apply-side: the per-resource
907/// health-gate never resolves, the parent Kustomization sits perpetually
908/// in `Reconciling`). Same shape as the
909/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] (7197d38) lift on the
910/// sibling Flux-installation-namespace axis.
911pub use caixa_core::FLUX_HELMRELEASE_API_VERSION;
912
913/// Canonical FluxCD `GitRepository` CRD `apiVersion` — re-export of the
914/// lifted [`caixa_core::FLUX_GITREPOSITORY_API_VERSION`] so the load-bearing
915/// string lives in exactly one place across the rendered Flux bundle's
916/// `gitrepository.yaml` document `apiVersion` axis. Until this lift landed
917/// the axis sat as an inline `source.toolkit.fluxcd.io/v1` literal at line
918/// 436 of this crate's [`cluster_bundle`] format-string template, and any
919/// future per-Flux-v3-migration version bump on this axis without a
920/// coordinated edit on the sibling [`FLUX_HELMRELEASE_API_VERSION`] axis
921/// would have silently routed the rendered `GitRepository` outside the
922/// Flux v2 `source-controller`'s `Watches` (controller-side: never
923/// reconciled, the dependent HelmRelease's `chart: sourceRef` dangles,
924/// every per-Servico apply silently comes up with the prior reconciled
925/// state). Same shape as the [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) /
926/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] (7197d38) lifts on the
927/// sibling Flux-v2-load-bearing-string axis.
928pub use caixa_core::FLUX_GITREPOSITORY_API_VERSION;
929
930/// Canonical FluxCD `Kustomization` CRD `apiVersion` — re-export of the
931/// lifted [`caixa_core::FLUX_KUSTOMIZATION_API_VERSION`] so the load-
932/// bearing string lives in exactly one place across the rendered Flux
933/// bundle's `kustomization.yaml` document `apiVersion` axis. Completes
934/// the Flux v2 controller-triplet (source-controller +
935/// helm-controller + kustomize-controller) lift alongside the sibling
936/// [`FLUX_GITREPOSITORY_API_VERSION`] (8a6c8a3) and
937/// [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) re-exports — every
938/// per-controller CRD-group/version is now a typed substrate-side
939/// `&'static str` consumed through one `pub use caixa_core::FLUX_*`
940/// re-export.
941///
942/// Until this lift landed the axis sat as an inline
943/// `kustomize.toolkit.fluxcd.io/v1` literal in this crate's
944/// [`cluster_bundle`] `kustomization.yaml` format-string template,
945/// and any future per-Flux-v3-migration version bump on this axis
946/// without a coordinated edit on the sibling
947/// [`FLUX_HELMRELEASE_API_VERSION`] / [`FLUX_GITREPOSITORY_API_VERSION`]
948/// axes (the Flux v2 controller triplet's CRD group/versions move
949/// together upstream) would have silently routed the rendered
950/// `Kustomization` outside the Flux v2 `kustomize-controller`'s
951/// `Watches` (apply-side: the parent Kustomization is never
952/// reconciled, every dependent `HelmRelease` / `GitRepository` it
953/// keys off sits perpetually un-applied at the cluster). Same shape
954/// as the [`FLUX_GITREPOSITORY_API_VERSION`] (8a6c8a3) /
955/// [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) /
956/// [`caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`] (7197d38) lifts on
957/// the sibling Flux-v2-load-bearing-string axis.
958pub use caixa_core::FLUX_KUSTOMIZATION_API_VERSION;
959
960/// Canonical FluxCD `GitRepository` CRD `kind` discriminator — re-export
961/// of the lifted [`caixa_core::FLUX_KIND_GIT_REPOSITORY`] so the load-
962/// bearing string lives in exactly one place across the three rendered
963/// Flux bundle axes that name the same K8s CRD discriminator:
964///
965///   - the rendered `gitrepository.yaml` document's top-level `kind`
966///     axis (the GitRepository CR's own discriminator);
967///   - the rendered `helmrelease.yaml` document's
968///     `spec.chart.spec.sourceRef.kind` axis (pointing back at the
969///     sibling GitRepository this chart sources from);
970///   - the rendered `kustomization.yaml` document's `spec.sourceRef.kind`
971///     axis (pointing back at the cluster's bootstrap GitRepository).
972///
973/// Until this lift landed the three axes sat as three inline
974/// `GitRepository` literals across the [`cluster_bundle`] `gitrepo` +
975/// `helmrelease` + `kustomization` format-string templates (caixa-flux
976/// /src/lib.rs:505, 556, 591). The apiserver-side CRD resolution
977/// contract is the `(apiVersion, kind)` tuple keyed against the
978/// registered `CustomResourceDefinition`; a typo at any one of the three
979/// call sites would have silently dangled the corresponding `sourceRef`
980/// at apply time (the `helm-controller` never resolves a chart for the
981/// HelmRelease, the `kustomize-controller` never reconciles the parent
982/// Kustomization, every per-Servico apply silently comes up with the
983/// prior reconciled state) with no diagnostic naming the kind-drift root
984/// cause far from the source caixa.lisp. Same shape as the
985/// [`FLUX_GITREPOSITORY_API_VERSION`] (8a6c8a3) /
986/// [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) /
987/// [`FLUX_KUSTOMIZATION_API_VERSION`] (d2dd1b1) lifts on the sibling
988/// apiVersion half of the same `(apiVersion, kind)` CRD-lookup tuple —
989/// extends the discipline from the apiVersion axis of the Flux v2
990/// source-controller CRD onto its kind axis.
991pub use caixa_core::FLUX_KIND_GIT_REPOSITORY;
992
993/// Canonical FluxCD `HelmRelease` CRD `kind` discriminator — re-export
994/// of the lifted [`caixa_core::FLUX_KIND_HELM_RELEASE`] so the load-
995/// bearing string lives in exactly one place across the two rendered
996/// Flux bundle axes that name the same K8s CRD discriminator:
997///
998///   - the rendered `helmrelease.yaml` document's top-level `kind`
999///     axis (the HelmRelease CR's own discriminator);
1000///   - the rendered `kustomization.yaml` document's
1001///     `spec.healthChecks[].kind` axis (pointing back at the sibling
1002///     HelmRelease the Kustomization health-gates on before declaring
1003///     its own reconcile complete).
1004///
1005/// Until this lift landed the two axes sat as two inline `HelmRelease`
1006/// literals across the [`cluster_bundle`] `helmrelease` + `kustomization`
1007/// format-string templates (caixa-flux/src/lib.rs:580, 631). The
1008/// apiserver-side CRD resolution contract is the `(apiVersion, kind)`
1009/// tuple keyed against the registered `CustomResourceDefinition`; a
1010/// typo at either of the two call sites would have silently lost the
1011/// apply-side resolution (top-level `kind` typos surface as "no kind
1012/// 'X' is registered" at apply parse time; the nested
1013/// `healthChecks[].kind` typo silently dangles the parent
1014/// Kustomization at `Reconciling` forever) with no diagnostic naming
1015/// the kind-drift root cause far from the source caixa.lisp. Same
1016/// shape as the [`FLUX_KIND_GIT_REPOSITORY`] (dbbcf29) /
1017/// [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) /
1018/// [`FLUX_GITREPOSITORY_API_VERSION`] (8a6c8a3) /
1019/// [`FLUX_KUSTOMIZATION_API_VERSION`] (d2dd1b1) lifts on the sibling
1020/// Flux-v2-load-bearing-string axes — extends the kind-axis discipline
1021/// from the Flux v2 source-controller CRD onto the sibling Flux v2
1022/// helm-controller CRD.
1023pub use caixa_core::FLUX_KIND_HELM_RELEASE;
1024
1025/// Canonical FluxCD `Kustomization` CRD `kind` discriminator — re-export
1026/// of the lifted [`caixa_core::FLUX_KIND_KUSTOMIZATION`] so the load-
1027/// bearing string lives in exactly one place across the rendered Flux
1028/// bundle's `Kustomization`-naming axis:
1029///
1030///   - the rendered `kustomization.yaml` document's top-level `kind`
1031///     axis (the Kustomization CR's own discriminator).
1032///
1033/// Until this lift landed the axis sat as an inline `Kustomization`
1034/// literal inside the [`cluster_bundle`] `kustomization` format-string
1035/// template (caixa-flux/src/lib.rs:651). The apiserver-side CRD
1036/// resolution contract is the `(apiVersion, kind)` tuple keyed against
1037/// the registered `CustomResourceDefinition`; a typo at this call site
1038/// would have surfaced at apply parse time as a non-self-locating "no
1039/// kind 'Kustomizaton' is registered for version
1040/// 'kustomize.toolkit.fluxcd.io/v1'" error, with the rendered parent
1041/// Kustomization never reconciling and every downstream per-Servico
1042/// `dependsOn` chain freezing at the kustomize-controller's CRD-lookup
1043/// boundary. Same shape as the [`FLUX_KIND_GIT_REPOSITORY`] (dbbcf29) /
1044/// [`FLUX_KIND_HELM_RELEASE`] (e24ea3c) /
1045/// [`FLUX_KUSTOMIZATION_API_VERSION`] (d2dd1b1) /
1046/// [`FLUX_GITREPOSITORY_API_VERSION`] (8a6c8a3) /
1047/// [`FLUX_HELMRELEASE_API_VERSION`] (55f0fd9) lifts on the sibling
1048/// Flux-v2-load-bearing-string axes — extends the kind-axis discipline
1049/// from the Flux v2 source-controller + helm-controller CRDs onto the
1050/// sibling Flux v2 kustomize-controller CRD, completing the
1051/// canonical-Flux-v2-CRD-kind-discriminator lift across the
1052/// source/helm/kustomize controller triplet.
1053pub use caixa_core::FLUX_KIND_KUSTOMIZATION;
1054
1055/// Canonical Flux v2 per-`HelmRelease` inline-chart-template container-
1056/// axis key every `caixa-flux`-emitted `HelmRelease` document nests its
1057/// per-CR chart-template block under (`spec.chart` on `HelmRelease`). Re-
1058/// export of the canonical [`caixa_core::FLUX_KEY_CHART`] so the load-
1059/// bearing Flux-v2-helm-controller-side per-`HelmRelease` chart-template
1060/// container-axis key lives in exactly one place across every caixa
1061/// renderer — the sweep converts this crate's one production-code call
1062/// site (the [`cluster_bundle`] `helmrelease.yaml` format-string
1063/// template's baked `chart:\n` container-axis key nesting the
1064/// `HelmChartTemplate` sub-document whose peer sibling lifted
1065/// [`FLUX_KEY_SOURCE_REF`] source-reference container-axis + inner
1066/// chart-name-scalar reach through) plus the two test-fixture
1067/// `.get("chart")` navigation sites in `mod tests` that probe the
1068/// emitted `spec.chart.spec.sourceRef.kind` pin onto the re-export. A
1069/// future Flux v3 rebrand of the per-`HelmRelease` chart-template
1070/// container-axis key (a hypothetical upstream fluxcd/flux2 rename from
1071/// `chart` to `Chart` / `chartTemplate` / `helmChart` / `chartRef`,
1072/// coordinated with the upstream project's per-version deprecation
1073/// cycle) now lands at one const rather than scattered across the one
1074/// emit-side format-string template + two test-fixture probe sites.
1075/// Same "the typed constant lives in one place" discipline the peer
1076/// [`FLUX_KEY_SOURCE_REF`] + [`FLUX_KEY_VALUES`] re-exports enforce on
1077/// the sibling Flux v2 per-`HelmRelease` body-key surfaces — completes
1078/// the triplet of Flux v2 per-`HelmRelease` `spec.*` body-key constants
1079/// (`spec.chart` + `spec.chart.spec.sourceRef` + `spec.values`) the
1080/// `cluster_bundle` renderer threads through its `helmrelease.yaml`
1081/// format-string template.
1082pub use caixa_core::FLUX_KEY_CHART;
1083
1084/// Canonical Flux v2 `HelmChartTemplate.spec.chart` per-CR chart-NAME-
1085/// reference leaf-scalar-axis key every `caixa-flux`-emitted
1086/// `HelmRelease` document nests inside the parent [`FLUX_KEY_CHART`]
1087/// container-axis (a nested [`KUBE_KEY_SPEC`] axis inside that
1088/// container hosts this leaf plus its sibling [`FLUX_KEY_SOURCE_REF`]
1089/// per-CR source-reference triple). Re-export of the canonical
1090/// [`caixa_core::FLUX_HELMCHART_TEMPLATE_KEY_CHART`] so the load-
1091/// bearing Flux-v2-helm-controller-side per-`HelmChartTemplate` chart-
1092/// NAME reference leaf-scalar-axis key lives in exactly one place
1093/// across every caixa renderer — the sweep converts this crate's one
1094/// production-code call site (the [`cluster_bundle`] `helmrelease.yaml`
1095/// format-string template's baked `chart: {chart_path}` leaf-scalar-
1096/// axis interpolation the peer sibling lifted [`FLUX_KEY_SOURCE_REF`]
1097/// source-reference triple's per-CR source-artifact publishes) onto
1098/// the re-export.
1099///
1100/// A future Flux v3 rebrand of the per-`HelmChartTemplate` chart-NAME
1101/// reference leaf-scalar-axis key (a hypothetical upstream fluxcd/flux2
1102/// rename from `chart` to `Chart` / `chartRef` / `chartName`,
1103/// coordinated with the upstream project's per-version deprecation
1104/// cycle) now lands at one const rather than scattered across the one
1105/// emit-side format-string template site. Same "the typed constant
1106/// lives in one place" discipline the peer [`FLUX_KEY_CHART`] +
1107/// [`FLUX_KEY_SOURCE_REF`] + [`FLUX_KEY_VALUES`] re-exports enforce
1108/// on the sibling Flux v2 per-`HelmRelease` body-key surfaces —
1109/// completes the per-`HelmRelease` chart-template `(spec.chart →
1110/// spec.chart.spec.chart + spec.chart.spec.sourceRef)` axis chain by
1111/// descending one level beneath the parent container-axis re-export
1112/// the sibling [`FLUX_KEY_CHART`] anchors.
1113///
1114/// Deliberate axis-independence discipline with the parent
1115/// [`FLUX_KEY_CHART`] container-axis re-export: both re-exports carry
1116/// the same underlying `"chart"` string today but name distinct schema
1117/// axes on the same CRD group (a container-axis parent vs a leaf-
1118/// scalar grandchild inside it), so the two `pub use` re-exports stay
1119/// sibling constants at the rustc symbol-name axis rather than
1120/// coalescing onto one canonical declaration. Peer to the deliberate
1121/// [`CILIUM_KEY_PATH`] / [`caixa_core::GATEWAY_API_KEY_PATH`] axis-
1122/// independence discipline the two-CRD-groups-sharing-a-string
1123/// sibling `"path"` re-exports established on the peer canonical-
1124/// axis-independence surface.
1125pub use caixa_core::FLUX_HELMCHART_TEMPLATE_KEY_CHART;
1126
1127/// Canonical Flux v2 per-`HelmRelease`/`Kustomization` source-reference
1128/// container-axis key every `caixa-flux`-emitted bundle document mounts
1129/// its per-CR source-of-truth `(kind, name, namespace)` reference triple
1130/// under (`spec.chart.spec.sourceRef` on `HelmRelease`, `spec.sourceRef`
1131/// on `Kustomization`). Re-export of the canonical
1132/// [`caixa_core::FLUX_KEY_SOURCE_REF`] so the load-bearing Flux-v2-source-
1133/// controller-side per-CR source-reference container-axis key lives in
1134/// exactly one place across every caixa renderer — the sweep converts
1135/// this crate's two production emit sites (the [`cluster_bundle`]
1136/// `helmrelease.yaml` format-string template's baked
1137/// `spec.chart.spec.sourceRef:\n` sub-block header + the sibling
1138/// `kustomization.yaml` format-string template's baked
1139/// `spec.sourceRef:\n` sub-block header, both now threaded through a
1140/// `{source_ref_key}` named-arg interpolation on the lifted const, closing
1141/// the last two open production sites for this axis) plus the five
1142/// test-fixture `.get("sourceRef")` navigation sites in `mod tests` (the
1143/// `helmrelease.yaml` `spec.chart.spec.sourceRef.kind` pin, the
1144/// `kustomization.yaml` `spec.sourceRef.name` + `spec.sourceRef.kind`
1145/// pins under the paired [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] +
1146/// [`FLUX_KIND_GIT_REPOSITORY`] canonical-string axes, and the two
1147/// cross-axis triplet pins that traverse both bundle documents to
1148/// pin the sibling `GitRepository`-kind axis triplet against one
1149/// canonical string) onto the re-export. A future Flux v3 rebrand of
1150/// the per-CR source-reference container-axis key (a hypothetical
1151/// upstream fluxcd/flux2 rename from `sourceRef` to `source` /
1152/// `sourceReference` / `sourceOf`, coordinated with the upstream
1153/// project's per-version deprecation cycle) now lands at one const
1154/// rather than scattered across the two per-CR format-string templates
1155/// + five test-fixture probe sites. Same "the typed constant lives in
1156/// one place" discipline the peer [`FLUX_KIND_GIT_REPOSITORY`] /
1157/// [`FLUX_KIND_HELM_RELEASE`] / [`FLUX_KIND_KUSTOMIZATION`] +
1158/// [`FLUX_HELMRELEASE_API_VERSION`] / [`FLUX_GITREPOSITORY_API_VERSION`]
1159/// / [`FLUX_KUSTOMIZATION_API_VERSION`] re-exports enforce on the
1160/// sibling canonical-Flux-v2-load-bearing-string surfaces.
1161pub use caixa_core::FLUX_KEY_SOURCE_REF;
1162
1163/// Canonical Flux v2 per-`HelmRelease` values-override block-body-axis
1164/// key every `caixa-flux`-emitted `HelmRelease` document nests its per-
1165/// cluster value overrides under (`spec.values` on `HelmRelease`). Re-
1166/// export of the canonical [`caixa_core::FLUX_KEY_VALUES`] so the load-
1167/// bearing Flux-v2-helm-controller-side per-`HelmRelease` values-
1168/// override block-body-axis key lives in exactly one place across every
1169/// caixa renderer — the sweep converts this crate's one production-code
1170/// call site (the [`cluster_bundle`] `helmrelease.yaml` format-string
1171/// template's baked `values:\n` key beside the sibling lifted
1172/// [`DEFAULT_LIBRARY_NAME`] wrap key + [`HELM_VALUES_KEY_ENABLED`]
1173/// enable-toggle) plus the [`upsert_into_helmrelease_programs`]
1174/// upsert-path's `spec.values.programs[]` write-side navigation onto the
1175/// re-export, and threads three test-fixture `.get("values")` block-
1176/// body-axis probe sites in `mod tests` through the same const. A
1177/// future Flux v3 rebrand of the per-`HelmRelease` values-override
1178/// block-body-axis key (a hypothetical upstream fluxcd/flux2 rename
1179/// from `values` to `Values` / `chartValues` / `overrides`, coordinated
1180/// with the upstream project's per-version deprecation cycle) now lands
1181/// at one const rather than scattered across the one emit-side format-
1182/// string template + one upsert-side write-side navigation + three
1183/// test-fixture probe sites. Same "the typed constant lives in one
1184/// place" discipline the peer [`FLUX_KEY_SOURCE_REF`] +
1185/// [`FLUX_KIND_GIT_REPOSITORY`] / [`FLUX_KIND_HELM_RELEASE`] /
1186/// [`FLUX_KIND_KUSTOMIZATION`] + [`FLUX_HELMRELEASE_API_VERSION`] /
1187/// [`FLUX_GITREPOSITORY_API_VERSION`] / [`FLUX_KUSTOMIZATION_API_VERSION`]
1188/// re-exports enforce on the sibling canonical-Flux-v2-load-bearing-
1189/// string surfaces.
1190pub use caixa_core::FLUX_KEY_VALUES;
1191
1192/// Canonical Flux v2 per-`Kustomization` health-gate reference-list
1193/// container-axis key every `caixa-flux`-emitted `kustomization.yaml`
1194/// document mounts its per-sibling-`HelmRelease` health-probe list under
1195/// (`spec.healthChecks` on `Kustomization`). Re-export of the canonical
1196/// [`caixa_core::FLUX_KEY_HEALTH_CHECKS`] so the load-bearing Flux-v2-
1197/// kustomize-controller-side per-`Kustomization` health-gate reference-
1198/// list container-axis key lives in exactly one place across every caixa
1199/// renderer — the sweep converts this crate's one production-code call
1200/// site (the [`cluster_bundle`] `kustomization.yaml` format-string
1201/// template's baked `healthChecks:\n` container-axis key nesting the
1202/// per-entry `[]NamespacedObjectKindReference` list whose peer sibling
1203/// lifted [`FLUX_HELMRELEASE_API_VERSION`] per-entry `apiVersion` axis +
1204/// [`FLUX_KIND_HELM_RELEASE`] per-entry `kind` axis the health-gate
1205/// references) plus the three test-fixture `.get("healthChecks")`
1206/// navigation sites in `mod tests` that probe the emitted per-entry
1207/// `apiVersion` + `kind` pin onto the re-export. A future Flux v3 rebrand
1208/// of the per-`Kustomization` health-gate reference-list container-axis
1209/// key (a hypothetical upstream fluxcd/flux2 rename from `healthChecks`
1210/// to `HealthChecks` / `healthchecks` / `healthcheck` / `health_checks`
1211/// / `probes`, coordinated with the upstream project's per-version
1212/// deprecation cycle) now lands at one const rather than scattered across
1213/// the one emit-side format-string template + three test-fixture probe
1214/// sites. Same "the typed constant lives in one place" discipline the
1215/// peer [`FLUX_KEY_SOURCE_REF`] + [`FLUX_KEY_CHART`] + [`FLUX_KEY_VALUES`]
1216/// re-exports enforce on the sibling Flux v2 per-`HelmRelease` +
1217/// per-`Kustomization` body-key surfaces — completes the quartet of Flux
1218/// v2 `spec.*` body-key constants (`spec.chart` + `spec.chart.spec.sourceRef`
1219/// + `spec.values` + `spec.healthChecks`) the `cluster_bundle` renderer
1220/// threads through its two format-string templates.
1221pub use caixa_core::FLUX_KEY_HEALTH_CHECKS;
1222
1223/// Canonical Flux v2 per-CR reconcile-poll cadence scalar-axis key every
1224/// `caixa-flux`-emitted Flux document (`GitRepository`, `HelmRelease`,
1225/// `Kustomization`) declares its per-CR `spec.interval` reconcile cadence
1226/// under. Re-export of the canonical [`caixa_core::FLUX_KEY_INTERVAL`] so
1227/// the load-bearing Flux-v2-controller-triplet-side per-CR reconcile-poll
1228/// cadence scalar-axis key lives in exactly one place across every caixa
1229/// renderer — the sweep converts this crate's three production-code call
1230/// sites (the [`cluster_bundle`] `gitrepository.yaml` + `helmrelease.yaml`
1231/// + `kustomization.yaml` format-string templates' baked `interval:`
1232/// scalar-axis keys, one per Flux v2 CRD kind, nested alongside the peer
1233/// sibling lifted per-CR `apiVersion` + `kind` axis re-exports on this
1234/// crate — [`FLUX_GITREPOSITORY_API_VERSION`] + [`FLUX_KIND_GIT_REPOSITORY`]
1235/// on the source-controller CRD, [`FLUX_HELMRELEASE_API_VERSION`] +
1236/// [`FLUX_KIND_HELM_RELEASE`] on the helm-controller CRD, and
1237/// [`FLUX_KUSTOMIZATION_API_VERSION`] + [`FLUX_KIND_KUSTOMIZATION`] on the
1238/// kustomize-controller CRD) onto the re-export. A future Flux v3 rebrand
1239/// of the per-CR reconcile-poll cadence scalar-axis key (a hypothetical
1240/// upstream fluxcd/flux2 rename from `interval` to `Interval` / `period`
1241/// / `cadence` / `pollInterval` / `reconcileInterval`, coordinated with
1242/// the upstream project's per-version deprecation cycle) now lands at one
1243/// const rather than scattered across three per-CR emit-side format-string
1244/// template sites. Same "the typed constant lives in one place" discipline
1245/// the peer [`FLUX_KEY_SOURCE_REF`] + [`FLUX_KEY_CHART`] + [`FLUX_KEY_VALUES`]
1246/// + [`FLUX_KEY_HEALTH_CHECKS`] re-exports enforce on the sibling Flux v2
1247/// per-CR body-key surfaces — extends the per-CR body-key lift trajectory
1248/// onto the sibling *cross-CR-shared* reconcile-poll cadence scalar-axis
1249/// every Flux v2 controller reads to bind its per-CR poll cycle.
1250pub use caixa_core::FLUX_KEY_INTERVAL;
1251
1252/// Canonical Flux v2 per-`GitRepository` `spec.ref.tag` git-tag-
1253/// selector scalar-axis key every [`cluster_bundle`]-rendered
1254/// `gitrepository.yaml` document declares on the tag-arm of the
1255/// [`GitRefSpec`] discriminated-union. Re-export of the canonical
1256/// [`caixa_core::FLUX_GITREPOSITORY_REF_KEY_TAG`] so the sub-selector
1257/// byte-string lives in exactly one place: the two consumer sites
1258/// (the YAML emit-side `gitref_field` composer and the human-readable
1259/// `tag_human` narrator prose) both now read through the lifted
1260/// [`GitRefSpec::ref_field_name`] dispatch that maps the tag-arm of
1261/// the discriminated-union onto this canonical scalar. Pairs with
1262/// [`FLUX_GITREPOSITORY_REF_KEY_BRANCH`] +
1263/// [`FLUX_GITREPOSITORY_REF_KEY_COMMIT`] on the sibling per-shape arms
1264/// of the same FluxCD source-controller `GitRepository.spec.ref`
1265/// discriminated-union axis — three consts, one per arm, one canonical
1266/// dispatch. See the caixa-core docstring for the full lift rationale.
1267pub use caixa_core::FLUX_GITREPOSITORY_REF_KEY_TAG;
1268
1269/// Canonical Flux v2 per-`GitRepository` `spec.ref.branch` git-branch-
1270/// selector scalar-axis key — peer of [`FLUX_GITREPOSITORY_REF_KEY_TAG`]
1271/// on the branch-arm of the [`GitRefSpec`] discriminated-union.
1272/// Re-export of [`caixa_core::FLUX_GITREPOSITORY_REF_KEY_BRANCH`]; see
1273/// [`FLUX_GITREPOSITORY_REF_KEY_TAG`] for the full lift rationale.
1274pub use caixa_core::FLUX_GITREPOSITORY_REF_KEY_BRANCH;
1275
1276/// Canonical Flux v2 per-`GitRepository` `spec.ref.commit` git-commit-
1277/// selector scalar-axis key — peer of [`FLUX_GITREPOSITORY_REF_KEY_TAG`]
1278/// on the commit-arm of the [`GitRefSpec`] discriminated-union.
1279/// Re-export of [`caixa_core::FLUX_GITREPOSITORY_REF_KEY_COMMIT`]; see
1280/// [`FLUX_GITREPOSITORY_REF_KEY_TAG`] for the full lift rationale.
1281pub use caixa_core::FLUX_GITREPOSITORY_REF_KEY_COMMIT;
1282
1283/// Canonical Flux v2 per-`GitRepository` `spec.ref` ref-selection
1284/// discriminated-union parent container-axis key every
1285/// [`cluster_bundle`]-rendered `gitrepository.yaml` document mounts
1286/// its per-shape `{tag, branch, commit}` sub-selector arm under.
1287/// Re-export of the canonical
1288/// [`caixa_core::FLUX_GITREPOSITORY_KEY_REF`] so the container-axis
1289/// byte-string lives in exactly one place across every consumer:
1290/// the writer-side `cluster_bundle` `gitrepo` template composer's
1291/// `ref:` sub-block header (the sole production emission site the
1292/// prior inline `"ref:"` literal sat at) + the peer test-fixture
1293/// `.get("ref")` sub-selector traversal (the sole test-side reader
1294/// site the prior inline `"ref"` literal sat at) both now navigate
1295/// through the same `&'static str`. Nests one level above the
1296/// sibling [`FLUX_GITREPOSITORY_REF_KEY_TAG`] /
1297/// [`FLUX_GITREPOSITORY_REF_KEY_BRANCH`] /
1298/// [`FLUX_GITREPOSITORY_REF_KEY_COMMIT`] per-shape arm sub-selector
1299/// triple it wraps — the parent container-axis KEY now moves
1300/// through one lifted const alongside its already-lifted per-shape
1301/// arm sub-selector-KEY triple, so a future Flux v3 sub-schema
1302/// rebrand (an upstream `fluxcd/flux2` rename of the ref-selection
1303/// container-axis from `spec.ref` to `spec.gitRef` /
1304/// `spec.source.ref`) lands as one const edit coordinated with the
1305/// sibling per-shape arm lifts. See the caixa-core docstring for the
1306/// full lift rationale.
1307pub use caixa_core::FLUX_GITREPOSITORY_KEY_REF;
1308
1309/// Canonical Flux v2 per-`GitRepository` `spec.url` remote-repo-URL
1310/// leaf-scalar-axis key every [`cluster_bundle`]-rendered
1311/// `gitrepository.yaml` document declares. Re-export of the canonical
1312/// [`caixa_core::FLUX_GITREPOSITORY_KEY_URL`] so the byte-string lives
1313/// in exactly one place: the writer-side `cluster_bundle` `gitrepo`
1314/// template composer's `url:` sub-key (the sole production emission
1315/// site the prior inline `"url:"` literal sat at). Sibling to the
1316/// already-lifted [`FLUX_GITREPOSITORY_KEY_REF`] on the peer per-CR
1317/// `spec.ref` container-axis surface — these two constants together
1318/// with the reconcile-cadence [`FLUX_KEY_INTERVAL`] enumerate the
1319/// canonical `GitRepository.spec.*` per-CR sub-block key surface
1320/// caixa-flux emits today. See the caixa-core docstring for the full
1321/// lift rationale.
1322pub use caixa_core::FLUX_GITREPOSITORY_KEY_URL;
1323
1324/// Canonical Flux v2 per-cluster-bundle `HelmRelease` document filename
1325/// every [`cluster_bundle`]-rendered `BundleFile` carries at its per-file
1326/// `path` axis — re-export of the lifted
1327/// [`caixa_core::FLUX_HELMRELEASE_YAML_FILENAME`] so the fixed filename
1328/// the cluster-side FluxCD `kustomize-controller` looks up when it opens
1329/// the per-Servico bundle directory lives in exactly one place across
1330/// every caixa renderer. The single source of truth all thirteen
1331/// consumers reach for — one production [`cluster_bundle`] `BundleFile`
1332/// assembly's `HelmRelease` document `path` axis plus a dozen test-side
1333/// round-trip navigators that reach into the rendered bundle by the
1334/// same filename to pin per-CR body-axis emission — now consult the
1335/// same `&'static str`. Pin the equality + `&'static` static-data
1336/// identity so any local re-introduction of a sibling `pub const
1337/// FLUX_HELMRELEASE_YAML_FILENAME: &str = "…"` at this crate is a
1338/// build-time test failure naming the offending drift, not a silent
1339/// FluxCD `kustomize-controller` "no `HelmRelease` document found under
1340/// this bundle" reroute at cluster-side reconcile time far from the
1341/// drift site. Peer to the [`HELM_CHART_YAML_FILENAME`]
1342/// (`caixa_core::HELM_CHART_YAML_FILENAME`, c2c99b0) /
1343/// [`HELM_VALUES_YAML_FILENAME`] (`caixa_core::HELM_VALUES_YAML_FILENAME`,
1344/// 9a980ba) re-exports on the sibling Helm-chart-directory filename
1345/// surfaces — pivots the canonical-filename single-sourcing discipline
1346/// from the per-Helm-chart-directory metadata / values file axes onto
1347/// the sibling per-Flux-v2-bundle `HelmRelease` document filename axis
1348/// this crate's [`cluster_bundle`] renders.
1349pub use caixa_core::FLUX_HELMRELEASE_YAML_FILENAME;
1350
1351/// Canonical Flux v2 per-cluster-bundle `GitRepository` document
1352/// filename every [`cluster_bundle`]-rendered `BundleFile` carries at
1353/// its per-file `path` axis — re-export of the lifted
1354/// [`caixa_core::FLUX_GITREPOSITORY_YAML_FILENAME`] so the fixed
1355/// filename the cluster-side FluxCD `source-controller` looks up when
1356/// it opens the per-Servico bundle directory lives in exactly one
1357/// place across every caixa renderer. Pairs with the sibling
1358/// [`FLUX_HELMRELEASE_YAML_FILENAME`] +
1359/// [`FLUX_KUSTOMIZATION_YAML_FILENAME`] re-exports to close the
1360/// per-bundle `(gitrepository, helmrelease, kustomization)` filename
1361/// axis triple every rendered cluster bundle carries — the single
1362/// source of truth all nine consumers reach for (one production
1363/// [`cluster_bundle`] `BundleFile` assembly's `GitRepository`
1364/// document `path` axis plus eight test-side round-trip navigators
1365/// that reach into the rendered bundle by the same filename to pin
1366/// per-CR body-axis emission) now consult the same `&'static str`.
1367/// Pin the equality + `&'static` static-data identity so any local
1368/// re-introduction of a sibling `pub const
1369/// FLUX_GITREPOSITORY_YAML_FILENAME: &str = "…"` at this crate is a
1370/// build-time test failure naming the offending drift, not a silent
1371/// FluxCD `source-controller` "no `GitRepository` document found
1372/// under this bundle" reroute at cluster-side reconcile time far
1373/// from the drift site. Peer to the sibling
1374/// [`FLUX_HELMRELEASE_YAML_FILENAME`] (ba7b0b2) re-export — extends
1375/// the canonical-Flux-v2-bundle-filename lifted-const discipline from
1376/// the middle coordinate of the filename triple onto its first
1377/// coordinate.
1378pub use caixa_core::FLUX_GITREPOSITORY_YAML_FILENAME;
1379
1380/// Canonical Flux v2 per-cluster-bundle `Kustomization` document
1381/// filename every [`cluster_bundle`]-rendered `BundleFile` carries at
1382/// its per-file `path` axis — re-export of the lifted
1383/// [`caixa_core::FLUX_KUSTOMIZATION_YAML_FILENAME`] so the fixed
1384/// filename the cluster-side FluxCD `kustomize-controller` looks up
1385/// when it opens the per-Servico bundle directory lives in exactly
1386/// one place across every caixa renderer. Pairs with the sibling
1387/// [`FLUX_GITREPOSITORY_YAML_FILENAME`] +
1388/// [`FLUX_HELMRELEASE_YAML_FILENAME`] re-exports to close the
1389/// per-bundle `(gitrepository, helmrelease, kustomization)` filename
1390/// axis triple every rendered cluster bundle carries — the single
1391/// source of truth all sixteen consumers reach for (one production
1392/// [`cluster_bundle`] `BundleFile` assembly's `Kustomization`
1393/// document `path` axis plus fifteen test-side round-trip navigators
1394/// that reach into the rendered bundle by the same filename to pin
1395/// per-CR body-axis emission) now consult the same `&'static str`.
1396/// Pin the equality + `&'static` static-data identity so any local
1397/// re-introduction of a sibling `pub const
1398/// FLUX_KUSTOMIZATION_YAML_FILENAME: &str = "…"` at this crate is a
1399/// build-time test failure naming the offending drift, not a silent
1400/// FluxCD `kustomize-controller` "no `Kustomization` document found
1401/// under this bundle" reroute at cluster-side reconcile time far
1402/// from the drift site. Peer to the sibling
1403/// [`FLUX_HELMRELEASE_YAML_FILENAME`] (ba7b0b2) +
1404/// [`FLUX_GITREPOSITORY_YAML_FILENAME`] (this commit) re-exports —
1405/// closes the canonical-Flux-v2-bundle-filename lifted-const
1406/// discipline on the third coordinate of the filename triple.
1407pub use caixa_core::FLUX_KUSTOMIZATION_YAML_FILENAME;
1408
1409/// Canonical Helm library-chart name every `lareira-<nome>` chart
1410/// depends on — re-export of the lifted [`caixa_core::DEFAULT_LIBRARY_NAME`]
1411/// so the load-bearing string lives in exactly one place across every
1412/// caixa renderer. The wrap key the `cluster_bundle` `helmrelease.yaml`
1413/// template uses under `spec.values.<library>:` to thread the per-cluster
1414/// overrides through to the rendered chart's dep block must match the
1415/// peer `caixa-helm` chart's `dependencies[0].name` axis exactly
1416/// (Helm's per-dep alias convention scopes values under the dep's
1417/// `name:` when no `alias:` is set), and both axes now consult the same
1418/// `&'static str`. Same shape as the [`caixa_core::DEFAULT_NAMESPACE`]
1419/// (a085b26) / [`caixa_core::DEFAULT_SERVICO_PORT`] (1e22add) lifts on
1420/// the peer canonical-K8s-axis-constant surface.
1421pub use caixa_core::DEFAULT_LIBRARY_NAME;
1422
1423/// Canonical `pleme-computeunit` library-chart values-block enable-toggle
1424/// key — re-export of the lifted [`caixa_core::HELM_VALUES_KEY_ENABLED`]
1425/// so the values-block enable-toggle every rendered `HelmRelease` /
1426/// upstream `values.yaml` carries under its [`DEFAULT_LIBRARY_NAME`] wrap
1427/// key lives in exactly one place across every caixa renderer. The single
1428/// production-code call site consuming it is [`cluster_bundle`]'s
1429/// `helmrelease.yaml` format-string template (formerly an inline
1430/// `enabled: true\n` literal at `caixa-flux/src/lib.rs:844`); the peer
1431/// test-side round-trip navigator
1432/// (`cluster_bundle_helmrelease_wraps_library_values_under_lifted_default_library_name`)
1433/// also consults the re-export so a rebrand of the library-chart's per-
1434/// values enable-toggle axis lands at one const and reaches every
1435/// consumer by construction. A drifted local
1436/// `pub const HELM_VALUES_KEY_ENABLED: &str = "…"` (or any sibling per-
1437/// renderer variant that inlined a stale `"enabled"` / `"enable"` /
1438/// `"disabled"` literal) would silently emit a `HelmRelease` whose per-
1439/// cluster override lands under one key while
1440/// [`caixa_helm::build_values_yaml`]'s default-off toggle inside the
1441/// rendered `values.yaml` lands under another — Helm's per-values merge
1442/// treats them as sibling scalars, the enable-toggle the library chart's
1443/// own template consults never sees the flip, and the workload silently
1444/// comes up with the library chart's admission-time defaults instead of
1445/// the per-cluster override the operator set. Same shape as the
1446/// [`DEFAULT_LIBRARY_NAME`] / [`KUBE_KEY_SPEC`] / [`FLUX_HELMRELEASE_API_VERSION`]
1447/// re-exports on the sibling canonical-Helm-load-bearing-string /
1448/// canonical-K8s-CR-body-key / canonical-Flux-CRD-apiVersion axes.
1449pub use caixa_core::HELM_VALUES_KEY_ENABLED;
1450
1451/// Canonical K8s CR top-level `spec` key. Re-export of the canonical
1452/// [`caixa_core::KUBE_KEY_SPEC`] so the per-kind body key lives in
1453/// exactly one place across every caixa renderer — caixa-flux's
1454/// `programs_yaml_entry` (the upstream ComputeUnit YAML's
1455/// `spec.*` axis the rendered programs.yaml entry splices from),
1456/// `upsert_into_helmrelease_programs` (the canonical
1457/// `spec.values.programs[]` path the `lareira-fleet-programs`
1458/// HelmRelease keys the per-Servico entry list under), and each of the
1459/// three [`cluster_bundle`] format-string templates' four `spec:`
1460/// YAML label positions (`gitrepository.yaml` top-level +
1461/// `helmrelease.yaml` top-level + `helmrelease.yaml` `spec.chart.spec`
1462/// nested + `kustomization.yaml` top-level) all consult the same
1463/// `&'static str` as the peer caixa-mesh / caixa-helm renderers'
1464/// `KUBE_KEY_SPEC` re-exports. The prior inline `"spec"` literals at
1465/// the production-code call sites would have let a typo on one site
1466/// (e.g. `"Spec"`, `"specs"`, `"spec_"`) silently emit a
1467/// programs.yaml entry that no `lareira-fleet-programs` schema
1468/// validator recognizes; the `Error::MissingField("spec")` paths now
1469/// thread the same `&'static str` through the diagnostic surface so
1470/// the error message stays byte-identical to the key it failed to
1471/// find. Same shape as the [`FLUX_HELMRELEASE_API_VERSION`] /
1472/// [`DEFAULT_LIBRARY_NAME`] re-exports on the sibling
1473/// canonical-Flux-load-bearing-string axes. Peer with the sibling
1474/// [`KUBE_KEY_METADATA`] / [`KUBE_KEY_KIND`] /
1475/// [`KUBE_KEY_API_VERSION`] re-exports on the other three canonical
1476/// K8s-CR top-level block-scope label axes the `cluster_bundle`
1477/// format-string templates thread through named-arg interpolation.
1478pub use caixa_core::KUBE_KEY_SPEC;
1479
1480/// Canonical K8s CR top-level `metadata` key. Re-export of the canonical
1481/// [`caixa_core::KUBE_KEY_METADATA`] so the per-kind metadata block key
1482/// lives in exactly one place across every caixa renderer — caixa-flux's
1483/// `programs_yaml_entry` (the upstream ComputeUnit YAML's `metadata.namespace`
1484/// axis the rendered programs.yaml entry's `namespace` field reads from)
1485/// now consults the same `&'static str` as the peer caixa-mesh renderer's
1486/// `KUBE_KEY_METADATA` re-export. The prior inline `"metadata"` literals
1487/// at the production-code + drift-detection call sites would have let a
1488/// typo on one site (e.g. `"Metadata"`, `"meta-data"`, `"medadata"`)
1489/// silently miss the ComputeUnit's `metadata.namespace` lookup and fall
1490/// back to `DEFAULT_NAMESPACE` even when the ComputeUnit YAML pinned a
1491/// distinct target namespace; the lift routes every K8s-CR-top-level-
1492/// metadata-axis retrieval through the same `&'static str` so drift
1493/// between any two sites becomes a single-edit fix at the caixa-core
1494/// const definition. Same shape as the [`KUBE_KEY_SPEC`] re-export on
1495/// the sibling K8s-CR top-level-spec-axis.
1496pub use caixa_core::KUBE_KEY_METADATA;
1497
1498/// Canonical K8s CR top-level `kind` key. Re-export of the canonical
1499/// [`caixa_core::KUBE_KEY_KIND`] so the per-CR-kind-axis discriminator
1500/// key lives in exactly one place across every caixa renderer —
1501/// caixa-flux's `cluster_bundle` drift-detection pins that traverse the
1502/// rendered `gitrepository.yaml` / `helmrelease.yaml` / `kustomization.yaml`
1503/// documents to assert the top-level `kind` + nested `sourceRef.kind`
1504/// / `healthChecks[].kind` axes bind to the lifted
1505/// [`FLUX_KIND_GIT_REPOSITORY`] / [`FLUX_KIND_HELM_RELEASE`] /
1506/// [`FLUX_KIND_KUSTOMIZATION`] discriminators now consult the same
1507/// `&'static str` as the peer caixa-mesh renderer's `KUBE_KEY_KIND`
1508/// re-export (615a13d). The prior inline `"kind"` literals at every
1509/// drift-detection cross-axis-pin call site in this crate would have let
1510/// a typo on any one site (e.g. `"Kind"`, `"kinds"`, `"knid"`) silently
1511/// miss the per-CR kind-axis retrieval — the equality assertion would
1512/// then compare `None` against `Some("GitRepository")` /
1513/// `Some("HelmRelease")` / `Some("Kustomization")` rather than the
1514/// expected discriminator, masking the sibling `FLUX_KIND_*` re-export
1515/// drift the pin was meant to catch under a `.expect("… present")` panic
1516/// on the missing `.and_then` chain. The lift routes every K8s-CR-
1517/// top-level-kind-axis retrieval through the same `&'static str` so
1518/// drift between any two sites becomes a single-edit fix at the
1519/// caixa-core const definition. Same shape as the [`KUBE_KEY_SPEC`] +
1520/// [`KUBE_KEY_METADATA`] re-exports on the sibling K8s-CR top-level-spec
1521/// / top-level-metadata axes — completes the per-K8s-CR top-level
1522/// `(spec, metadata, kind)` axis re-export triple every rendered Flux
1523/// bundle document navigates.
1524pub use caixa_core::KUBE_KEY_KIND;
1525
1526/// Canonical K8s CR top-level `apiVersion` key. Re-export of the
1527/// canonical [`caixa_core::KUBE_KEY_API_VERSION`] so the per-CR-
1528/// group/version-axis discriminator key lives in exactly one place
1529/// across every caixa renderer — caixa-flux's [`cluster_bundle`]
1530/// drift-detection pins that traverse the rendered
1531/// `gitrepository.yaml` / `helmrelease.yaml` / `kustomization.yaml`
1532/// documents to assert the top-level `apiVersion` axis + the
1533/// `kustomization.yaml`'s nested `spec.healthChecks[].apiVersion`
1534/// axis bind to the lifted [`FLUX_GITREPOSITORY_API_VERSION`] /
1535/// [`FLUX_HELMRELEASE_API_VERSION`] / [`FLUX_KUSTOMIZATION_API_VERSION`]
1536/// controller-triplet CRD-group/versions now consult the same
1537/// `&'static str` as the sibling [`KUBE_KEY_SPEC`] / [`KUBE_KEY_METADATA`]
1538/// / [`KUBE_KEY_KIND`] re-exports on the peer K8s-CR top-level axes.
1539/// The prior inline `"apiVersion"` literals at every drift-detection
1540/// cross-axis-pin call site in this crate would have let a typo on
1541/// any one site (e.g. `"ApiVersion"`, `"api_version"`, `"apiversion"`,
1542/// `"apiVer"`) silently miss the per-CR apiVersion-axis retrieval —
1543/// the equality assertion would then compare `None` against
1544/// `Some("source.toolkit.fluxcd.io/v1")` /
1545/// `Some("helm.toolkit.fluxcd.io/v2")` /
1546/// `Some("kustomize.toolkit.fluxcd.io/v1")` rather than the expected
1547/// controller-triplet CRD-group/version, masking the sibling
1548/// `FLUX_*_API_VERSION` re-export drift the pin was meant to catch
1549/// under a `.expect("… present")` panic on the missing `.and_then`
1550/// chain. The lift routes every K8s-CR top-level-apiVersion-axis
1551/// retrieval through the same `&'static str` so drift between any
1552/// two sites becomes a single-edit fix at the caixa-core const
1553/// definition, extending the discipline the sibling [`KUBE_KEY_SPEC`]
1554/// / [`KUBE_KEY_METADATA`] / [`KUBE_KEY_KIND`] re-exports establish
1555/// onto the last of the four K8s-CR top-level axes (`apiVersion`,
1556/// `kind`, `metadata`, `spec`) every rendered Flux v2 bundle
1557/// document declares — completes the per-K8s-CR top-level
1558/// `(apiVersion, kind, metadata, spec)` axis re-export quartet
1559/// across this crate.
1560pub use caixa_core::KUBE_KEY_API_VERSION;
1561
1562/// Canonical K8s CR `metadata.namespace` key. Re-export of the canonical
1563/// [`caixa_core::KUBE_KEY_NAMESPACE`] so the per-CR namespace-axis key
1564/// lives in exactly one place across every caixa renderer — caixa-flux's
1565/// [`programs_yaml_entry`] threads the ComputeUnit YAML's
1566/// `metadata.namespace` retrieval and the emitted `programs:[]` entry's
1567/// isomorphic `namespace:` field (the `lareira-fleet-programs` chart's
1568/// per-Servico namespace axis, populated verbatim from the ComputeUnit's
1569/// `metadata.namespace` per the docstring on `programs_yaml_entry` above)
1570/// through this key, [`cluster_bundle`]'s rendered `kustomization.yaml`
1571/// drift-detection pin traverses the emitted document's
1572/// `metadata.namespace` axis to assert it binds to the lifted
1573/// [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] (the bootstrap kustomize-
1574/// controller's watch window) through this same key, and each of the
1575/// three [`cluster_bundle`] format-string templates' five `namespace:`
1576/// YAML label positions — `gitrepository.yaml` top-level
1577/// `metadata.namespace`, `helmrelease.yaml` top-level
1578/// `metadata.namespace` + nested `spec.chart.spec.sourceRef.namespace`,
1579/// `kustomization.yaml` top-level `metadata.namespace` + nested
1580/// `spec.healthChecks[].namespace` — thread this `&'static str`
1581/// through named-arg interpolation instead of the prior five inline
1582/// `namespace:` label literals.
1583///
1584/// The prior inline `"namespace"` literals at the production-code
1585/// (`programs_yaml_entry` read + write) and drift-detection call sites
1586/// would have let a typo on any one site (e.g. `"Namespace"`,
1587/// `"name space"`, `"namesapce"`, the canonical transposition) silently
1588/// miss the ComputeUnit's `metadata.namespace` lookup and fall back to
1589/// [`DEFAULT_NAMESPACE`] even when the ComputeUnit YAML pinned a
1590/// distinct target namespace, or write a `namesapce:` key that no
1591/// `lareira-fleet-programs` schema validator recognizes, or mask a
1592/// drifted [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] regression by returning
1593/// `None` from the `.get("namesapce")` retrieval so the equality
1594/// assertion never sees the true axis value under the `.expect(…)`
1595/// panic on the missing `.and_then` chain. The lift routes every
1596/// K8s-CR-`metadata.namespace`-axis retrieval / emission through the
1597/// same `&'static str` so drift between any two sites becomes a
1598/// single-edit fix at the caixa-core const definition. Same shape as
1599/// the [`KUBE_KEY_METADATA`] / [`KUBE_KEY_SPEC`] / [`KUBE_KEY_KIND`] /
1600/// [`KUBE_KEY_API_VERSION`] re-exports on the sibling K8s-CR top-level
1601/// axes — extends the discipline the top-level `(apiVersion, kind,
1602/// metadata, spec)` axis re-export quartet establishes onto the
1603/// canonical `metadata.namespace` nested axis every rendered Flux v2
1604/// bundle document navigates.
1605pub use caixa_core::KUBE_KEY_NAMESPACE;
1606
1607/// Canonical K8s CR `metadata.name` key. Re-export of the canonical
1608/// [`caixa_core::KUBE_KEY_NAME`] so the per-CR name-axis key lives in
1609/// exactly one place across every caixa renderer. Each of the three
1610/// [`cluster_bundle`] format-string templates' six `name:` YAML label
1611/// positions — `gitrepository.yaml` top-level `metadata.name`,
1612/// `helmrelease.yaml` top-level `metadata.name` + nested
1613/// `spec.chart.spec.sourceRef.name`, `kustomization.yaml` top-level
1614/// `metadata.name` + nested `spec.sourceRef.name` + nested
1615/// `spec.healthChecks[].name` — thread this `&'static str` through
1616/// named-arg interpolation instead of the prior six inline `name:`
1617/// label literals.
1618///
1619/// The prior inline `"name"` literals at the production-side call
1620/// sites would have let a typo on any one site (e.g. `"Name"`,
1621/// `"nane"`, `"nam"`, the canonical transposition) silently emit a
1622/// document whose per-CR `metadata.name` axis the apiserver-side
1623/// ObjectMeta parser cannot key on — the `helm-controller` /
1624/// `source-controller` / `kustomize-controller` would then treat the
1625/// rendered document as an anonymous CR (or the apiserver would
1626/// reject the apply with a schema-validation error naming the wrong
1627/// key), with no field naming the label-drift root cause far from
1628/// the source caixa.lisp. Now the emit-side and retrieval-side both
1629/// consult one substrate-owned `&'static str`, and the raw-byte-
1630/// label pin structurally forbids the emit format-string from
1631/// drifting away from the canonical key without failing at test
1632/// time. Same shape as the [`KUBE_KEY_NAMESPACE`] /
1633/// [`KUBE_KEY_METADATA`] / [`KUBE_KEY_SPEC`] / [`KUBE_KEY_KIND`] /
1634/// [`KUBE_KEY_API_VERSION`] re-exports on the sibling K8s-CR
1635/// canonical-key axes — extends the discipline the top-level
1636/// `(apiVersion, kind, metadata, spec)` axis re-export quartet +
1637/// the sibling `metadata.namespace` nested-axis re-export establish
1638/// onto the paired `metadata.name` nested axis every rendered Flux
1639/// v2 bundle document navigates as the other half of the `(name,
1640/// namespace)` ObjectMeta / sourceRef / healthCheck identity-pair.
1641pub use caixa_core::KUBE_KEY_NAME;
1642
1643/// Local re-export of [`caixa_core::FLEET_PROGRAMS_KEY_PROGRAMS`] —
1644/// the canonical `lareira-fleet-programs` values-schema array key
1645/// (`programs:` — the exact YAML key the fleet-programs library chart
1646/// reads under `.Values.programs[]` to iterate one `ComputeUnit` CR per
1647/// entry). This crate's two writer-side upsert paths
1648/// ([`upsert_into_helmrelease_programs`] on the aggregator-HelmRelease
1649/// shape, [`upsert_into_programs_yaml`] on the bare-values.yaml shape)
1650/// both anchor on this key when walking the entry sequence to
1651/// match-by-name-and-replace-or-append. Re-exported here so the two
1652/// production sites' `values_map.entry(Value::String(<key>.into()))` /
1653/// `programs_yaml.get(<key>)` navigation reads from the same
1654/// `&'static str` as every peer consumer (and every future fleet-
1655/// programs schema-key consumer — the M4 `app-operator` per-Aplicacao
1656/// reconciler, the future `feira app deploy --apply` writer-side
1657/// aggregator merge). Same re-export shape as the peer
1658/// [`KUBE_KEY_NAMESPACE`] / [`KUBE_KEY_METADATA`] / [`KUBE_KEY_SPEC`]
1659/// / [`KUBE_KEY_KIND`] / [`KUBE_KEY_API_VERSION`] surfaces on the
1660/// sibling K8s-CR canonical-key axes — extends the discipline the
1661/// K8s-CR key re-export quintet establishes onto the canonical
1662/// fleet-programs schema top-level axis.
1663pub use caixa_core::FLEET_PROGRAMS_KEY_PROGRAMS;
1664
1665/// Local re-export of [`caixa_core::FLEET_PROGRAMS_KEY_NAME`] — the
1666/// canonical `lareira-fleet-programs` values-schema per-entry name
1667/// discriminator key (`name:` — the exact YAML key the fleet-programs
1668/// library chart's `range .Values.programs` step reads per-entry to
1669/// key each rendered `ComputeUnit` CR's `metadata.name` off). Peer of
1670/// the sibling [`FLEET_PROGRAMS_KEY_PROGRAMS`] top-level array-key
1671/// re-export on the same fleet-programs schema — that one carries the
1672/// `programs:` array key both writer verbs upsert into, this one
1673/// carries the per-entry name-axis both writer verbs walk that array
1674/// by (and both emit-side entry builders — this crate's
1675/// [`programs_yaml_entry`] and the peer [`caixa_mesh::programs_for_aplicacao`]
1676/// — write the per-entry name-axis at).
1677///
1678/// This crate's three writer-side sites anchor on this key:
1679/// [`programs_yaml_entry`]'s emit-side `entry.insert(<key>.into(), …)`
1680/// call (seeding the per-entry name-axis from the Caixa's `nome`),
1681/// [`upsert_into_helmrelease_programs`]'s two `new_entry.get(<key>)`
1682/// / `slot.get(<key>)` navigations + `Error::MissingField(<key>)`
1683/// diagnostic on the aggregator-HelmRelease shape, and
1684/// [`upsert_into_programs_yaml`]'s peer three-site (extract + match +
1685/// `MissingField`) shape on the bare-values.yaml shape. All three
1686/// verbs now read from the same `&'static str` as every peer
1687/// consumer (and every future fleet-programs schema-key consumer —
1688/// the M4 `app-operator` per-Aplicacao reconciler, the future
1689/// `feira app deploy --apply` writer-side aggregator merge, the peer
1690/// [`caixa_mesh::programs_for_aplicacao`] per-`:membros` emit-side
1691/// name-axis). Same re-export shape as the peer
1692/// [`FLEET_PROGRAMS_KEY_PROGRAMS`] / [`KUBE_KEY_NAMESPACE`] /
1693/// [`KUBE_KEY_METADATA`] / [`KUBE_KEY_SPEC`] / [`KUBE_KEY_KIND`] /
1694/// [`KUBE_KEY_API_VERSION`] surfaces on the sibling fleet-programs /
1695/// K8s-CR canonical-key axes — extends the discipline the K8s-CR key
1696/// re-export quintet + the sibling fleet-programs top-level array-
1697/// key re-export establish onto the canonical fleet-programs schema
1698/// per-entry name-discriminator axis.
1699pub use caixa_core::FLEET_PROGRAMS_KEY_NAME;
1700
1701/// Local re-export of the canonical
1702/// [`caixa_core::COMPUTEUNIT_SPEC_KEY_MODULE`] — the
1703/// `wasm.pleme.io/v1alpha1/ComputeUnit` CRD per-CR wasm-module-reference
1704/// `spec.module` sub-block key every rendered `programs[]` entry
1705/// splices verbatim from the upstream ComputeUnit YAML's `spec.module`
1706/// (per the docstring on [`programs_yaml_entry`] above), so the
1707/// `lareira-fleet-programs` library chart's per-Servico module-source
1708/// axis binds to the exact source the caixa.lisp's `:servicos`
1709/// fixture pins. Four per-entry drift-detection navigators in this
1710/// crate's test module (the `programs_yaml_entry_round_trips` per-key
1711/// pair + the `upsert_helmrelease_replaces_existing` /
1712/// `upsert_into_programs_yaml` per-`module.source` navigators)
1713/// now consult the same `&'static str` as the peer caixa-helm
1714/// per-values navigators' module-source axis. Same re-export shape
1715/// as the peer [`FLEET_PROGRAMS_KEY_NAME`] / [`KUBE_KEY_NAMESPACE`]
1716/// surfaces on the sibling canonical-fleet-programs-schema-key /
1717/// canonical-K8s-CR-key axes — extends the discipline the M2-typed-
1718/// slot / fleet-programs schema / K8s-CR key re-export families
1719/// establish onto the substrate-side ComputeUnit-CRD per-`spec.*`
1720/// sub-block axis. See [`caixa_core::COMPUTEUNIT_SPEC_KEY_MODULE`]
1721/// for the full lift rationale.
1722pub use caixa_core::COMPUTEUNIT_SPEC_KEY_MODULE;
1723
1724/// Local re-export of the canonical
1725/// [`caixa_core::COMPUTEUNIT_SPEC_KEY_TRIGGER`] — the
1726/// `wasm.pleme.io/v1alpha1/ComputeUnit` CRD per-CR invocation-shape
1727/// `spec.trigger` sub-block key every rendered `programs[]` entry
1728/// splices verbatim from the upstream ComputeUnit YAML's
1729/// `spec.trigger`. Peer of [`COMPUTEUNIT_SPEC_KEY_MODULE`] on the same
1730/// ComputeUnit CRD per-`spec.*` sub-block axis. See
1731/// [`caixa_core::COMPUTEUNIT_SPEC_KEY_TRIGGER`] for the full lift
1732/// rationale.
1733pub use caixa_core::COMPUTEUNIT_SPEC_KEY_TRIGGER;
1734
1735/// Local re-export of the canonical
1736/// [`caixa_core::COMPUTEUNIT_SPEC_KEY_CAPABILITIES`] — the
1737/// `wasm.pleme.io/v1alpha1/ComputeUnit` CRD per-CR WASI-capability-list
1738/// `spec.capabilities` sub-block key every rendered `programs[]` entry
1739/// splices verbatim from the upstream ComputeUnit YAML's
1740/// `spec.capabilities`. Peer of [`COMPUTEUNIT_SPEC_KEY_MODULE`] and
1741/// [`COMPUTEUNIT_SPEC_KEY_TRIGGER`] on the same ComputeUnit CRD
1742/// per-`spec.*` sub-block axis — completes the substrate-side
1743/// ComputeUnit-CRD per-`spec.*` sub-block re-export triple in this
1744/// crate. See [`caixa_core::COMPUTEUNIT_SPEC_KEY_CAPABILITIES`] for
1745/// the full lift rationale.
1746pub use caixa_core::COMPUTEUNIT_SPEC_KEY_CAPABILITIES;
1747
1748/// Local re-export of the canonical
1749/// [`caixa_core::COMPUTEUNIT_MODULE_KEY_SOURCE`] — the
1750/// `wasm.pleme.io/v1alpha1/ComputeUnit` CRD nested
1751/// `spec.module.source` per-CR wasm-component-reference leaf-scalar
1752/// sub-block key every rendered `programs[]` entry carries under the
1753/// parent [`COMPUTEUNIT_SPEC_KEY_MODULE`] block to name the exact
1754/// OCI / git / file wasm-component artifact the M2.5 wasm-engine
1755/// instantiator loads at Servico bring-up. Three per-`module.source`
1756/// drift-detection navigators in this crate's test module
1757/// (`programs_yaml_entry_round_trips`'s per-entry
1758/// `.get(COMPUTEUNIT_SPEC_KEY_MODULE).and_then(|m| m.get(…))`
1759/// present-check + `upsert_into_programs_yaml`'s cross-upsert
1760/// readback + `upsert_into_helmrelease_programs`'s peer
1761/// `HelmRelease`-wrapped `spec.values.programs[]` cross-upsert
1762/// readback) now consult the same `&'static str` — extends the
1763/// discipline the peer [`COMPUTEUNIT_SPEC_KEY_MODULE`] /
1764/// [`COMPUTEUNIT_SPEC_KEY_TRIGGER`] / [`COMPUTEUNIT_SPEC_KEY_CAPABILITIES`]
1765/// top-level-`spec.*` re-exports establish one level deeper onto the
1766/// nested `spec.module.*` leaf-scalar-axis. See
1767/// [`caixa_core::COMPUTEUNIT_MODULE_KEY_SOURCE`] for the full lift
1768/// rationale.
1769pub use caixa_core::COMPUTEUNIT_MODULE_KEY_SOURCE;
1770
1771/// Local re-export of the canonical
1772/// [`caixa_core::servico_spec_and_m2_overlay_entries`] — the composed
1773/// per-Servico value-block splice helper this crate's
1774/// [`programs_yaml_entry`] and the peer
1775/// [`caixa_helm::build_values_yaml`] both now route their two-step
1776/// `spec.*` field-splice + M2 typed-slot overlay through. The single
1777/// production-code call site consuming it is
1778/// [`programs_yaml_entry`]'s inner splice loop (formerly two hand-
1779/// written for-loops chained around `string_keyed_entries` +
1780/// `servico_m2_overlay`); re-exported so the shared composition
1781/// contract lives in exactly one place across both per-Servico
1782/// renderers — a future author reading `caixa_flux::programs_yaml_entry`
1783/// finds the composition helper immediately without an extra `use
1784/// caixa_core::…` line, and a rebrand of the composition axis (e.g. a
1785/// swap of the `or_insert` precedence rule) reaches both renderers
1786/// through one canonical `&'static` function pointer. Same shape as
1787/// the peer render-side helper re-exports on the sibling
1788/// canonical-composed-primitive axes.
1789pub use caixa_core::servico_spec_and_m2_overlay_entries;
1790
1791/// Render a single `programs:[]` array entry for the cluster's
1792/// `lareira-fleet-programs` HelmRelease values.
1793///
1794/// The output is `serde_yaml::Value::Mapping`, so callers can splice
1795/// it into an existing `programs:` array without re-parsing the
1796/// containing structure. Schema is enforced by
1797/// `lareira-fleet-programs/values.schema.json` (`#/definitions/program`).
1798///
1799/// Pulls:
1800/// - `name` from `caixa.nome`
1801/// - `namespace` from `computeunit.metadata.namespace` (or `DEFAULT_NAMESPACE`)
1802/// - [`COMPUTEUNIT_SPEC_KEY_MODULE`] / [`COMPUTEUNIT_SPEC_KEY_TRIGGER`] /
1803///   [`COMPUTEUNIT_SPEC_KEY_CAPABILITIES`] / `config` / `resources`
1804///   from `computeunit.spec.*` (verbatim — schemas already match)
1805pub fn programs_yaml_entry(
1806    caixa: &Caixa,
1807    computeunit_yaml: &serde_yaml::Value,
1808) -> Result<serde_yaml::Value, Error> {
1809    caixa_core::require_v0_servico_shape::<Error>(caixa)?;
1810
1811    let spec = computeunit_yaml
1812        .get(KUBE_KEY_SPEC)
1813        .ok_or(Error::MissingField(KUBE_KEY_SPEC))?;
1814
1815    let namespace = kube_metadata_str_field(computeunit_yaml, KUBE_KEY_NAMESPACE)
1816        .unwrap_or(DEFAULT_NAMESPACE)
1817        .to_string();
1818
1819    let mut entry = serde_yaml::Mapping::new();
1820    // Route the per-entry `name:` `String`-carry through the typed
1821    // [`caixa_core::Caixa::nome`] accessor (`caixa.nome().to_string()`)
1822    // instead of the raw `caixa.nome.clone()` field access — sibling
1823    // convergence to the peer 54bf2f3 caixa-mesh
1824    // `programs_for_aplicacao` / `cilium_network_policies` /
1825    // `gateway_routes` three-site converge on the same axis on the
1826    // sibling renderer crate. Every future extension of the accessor
1827    // (an M4 namespace-qualified rewrite the CR materializer applies
1828    // per-CR, a per-cluster alias table pinned through a future
1829    // `:placement`-scoped slot, the `:nome-suffix` overlay
1830    // MESH-COMPOSITION §III.2 acknowledges) reaches this emit site
1831    // through the accessor by construction. Pinned by the drift-
1832    // detection test
1833    // [`programs_yaml_entry_name_field_routes_through_caixa_nome_accessor`]
1834    // in the tests module.
1835    entry.insert_string(FLEET_PROGRAMS_KEY_NAME, caixa.nome().to_string());
1836    entry.insert_string(KUBE_KEY_NAMESPACE, namespace);
1837
1838    // Two-step per-Servico value-block splice — the `spec.*` field
1839    // splice (module / trigger / capabilities / config / resources /
1840    // serviceAccount) and the M2 typed-slot overlay (limits / behavior
1841    // / upgradeFrom, `or_insert` semantics so `spec.*` wins on
1842    // collision) now route through the canonical
1843    // [`caixa_core::servico_spec_and_m2_overlay_entries`] composition
1844    // helper — the two prior inline for-loops chained around
1845    // `string_keyed_entries` + `servico_m2_overlay` this call site
1846    // (and the peer [`caixa_helm::build_values_yaml`] site) each
1847    // re-derived collapse onto one canonical composition, so a future
1848    // change to the per-Servico splice / overlay shape (the M4 typed
1849    // per-edge policy overlay slot addition MESH-COMPOSITION §III.2
1850    // #3 acknowledges, a change to the precedence rule once per-
1851    // Aplicacao operator overrides land, a canonicalization pass on
1852    // the merged key set) reaches both renderers by construction
1853    // instead of a coordinated two-file rewrite. See the helper's
1854    // docstring for the full lift rationale and the byte-shape
1855    // guarantee (spec.* keys preserved in source-Mapping insertion
1856    // order; M2 slots appended in canonical BTreeMap-key ordering at
1857    // every M2 key not already claimed by spec.*).
1858    for (k, v) in caixa_core::servico_spec_and_m2_overlay_entries(caixa, spec)? {
1859        entry.entry_str_key(&k).or_insert(v);
1860    }
1861
1862    Ok(serde_yaml::Value::Mapping(entry))
1863}
1864
1865/// Insert/upsert an entry into a `programs:` array nested under
1866/// the canonical fleet-manifest path: `spec.values.programs[]` in a
1867/// `HelmRelease` document. The pleme-io convention puts the fleet's
1868/// program list inside a HelmRelease (consumed by `lareira-fleet-programs`),
1869/// not at the top level. Same upsert semantics as
1870/// [`upsert_into_programs_yaml`] — match by `name`, replace in place,
1871/// otherwise append.
1872pub fn upsert_into_helmrelease_programs(
1873    helmrelease: serde_yaml::Value,
1874    new_entry: serde_yaml::Value,
1875) -> Result<(serde_yaml::Value, bool), Error> {
1876    let serde_yaml::Value::Mapping(mut root) = helmrelease else {
1877        return Err(Error::MissingField(
1878            "expected mapping at root of HelmRelease",
1879        ));
1880    };
1881
1882    let spec = root
1883        .get_mut(KUBE_KEY_SPEC)
1884        .ok_or(Error::MissingField(KUBE_KEY_SPEC))?;
1885    let serde_yaml::Value::Mapping(spec_map) = spec else {
1886        return Err(Error::MissingField("spec must be a mapping"));
1887    };
1888    let values_map = spec_map
1889        .entry_or_default_mapping(FLUX_KEY_VALUES)
1890        .ok_or(Error::MissingField("spec.values must be a mapping"))?;
1891    let arr = values_map
1892        .entry_or_default_sequence(FLEET_PROGRAMS_KEY_PROGRAMS)
1893        .ok_or(Error::MissingField(
1894            "spec.values.programs must be a sequence",
1895        ))?;
1896
1897    let inserted = caixa_core::upsert_named_entry(arr, new_entry, FLEET_PROGRAMS_KEY_NAME, || {
1898        Error::MissingField(FLEET_PROGRAMS_KEY_NAME)
1899    })?;
1900
1901    Ok((serde_yaml::Value::Mapping(root), inserted))
1902}
1903
1904/// Insert/upsert an entry into a `programs:` array of an existing
1905/// values.yaml structure.
1906///
1907/// Idempotent: if an entry with the same `name` exists, replaces it
1908/// in-place (preserving order). If not, appends. Returns the modified
1909/// document. Operates on `Value` so callers can round-trip via
1910/// `serde_yaml::from_str` / `to_string` without losing structure.
1911///
1912/// Returns the modified `programs_yaml` plus a `bool` indicating
1913/// whether the entry was a new insert (`true`) or a replacement (`false`).
1914pub fn upsert_into_programs_yaml(
1915    programs_yaml: serde_yaml::Value,
1916    new_entry: serde_yaml::Value,
1917) -> Result<(serde_yaml::Value, bool), Error> {
1918    let serde_yaml::Value::Mapping(mut root) = programs_yaml else {
1919        return Err(Error::MissingField(
1920            "expected mapping at root of values.yaml",
1921        ));
1922    };
1923
1924    let arr = root
1925        .entry_or_default_sequence(FLEET_PROGRAMS_KEY_PROGRAMS)
1926        .ok_or(Error::MissingField("programs must be a sequence"))?;
1927
1928    let inserted = caixa_core::upsert_named_entry(arr, new_entry, FLEET_PROGRAMS_KEY_NAME, || {
1929        Error::MissingField(FLEET_PROGRAMS_KEY_NAME)
1930    })?;
1931
1932    Ok((serde_yaml::Value::Mapping(root), inserted))
1933}
1934
1935// ── Cluster bundle (one-off / standalone path) ──────────────────────────
1936
1937/// Inputs for [`cluster_bundle`].
1938#[derive(Debug, Clone, Serialize, Deserialize)]
1939pub struct ClusterBundleOpts {
1940    /// Cluster name — drives output paths (e.g. `rio`, `mar`).
1941    pub cluster: String,
1942    /// Namespace for the rendered HelmRelease.
1943    pub namespace: String,
1944    /// Reconcile interval string (Helm/Flux duration like `"10m"`).
1945    pub interval: String,
1946    /// Path to the chart inside the source repo (default: `chart/`).
1947    pub chart_path: String,
1948    /// Source git URL.
1949    pub git_url: String,
1950    /// Source git ref (branch or tag).
1951    pub git_ref: GitRefSpec,
1952}
1953
1954#[derive(Debug, Clone, Serialize, Deserialize)]
1955#[serde(rename_all = "camelCase")]
1956pub enum GitRefSpec {
1957    Tag(String),
1958    Branch(String),
1959    Commit(String),
1960}
1961
1962impl GitRefSpec {
1963    /// The FluxCD source-controller `GitRepository.spec.ref.<field>`
1964    /// sub-selector scalar-axis key this variant renders under — the
1965    /// per-arm dispatch onto the canonical lifted
1966    /// [`FLUX_GITREPOSITORY_REF_KEY_TAG`] /
1967    /// [`FLUX_GITREPOSITORY_REF_KEY_BRANCH`] /
1968    /// [`FLUX_GITREPOSITORY_REF_KEY_COMMIT`] byte-string trio the
1969    /// caixa-core substrate owns.
1970    ///
1971    /// Both consumer sites in [`cluster_bundle`] (the `gitref_field`
1972    /// YAML emit-side composer and the sibling `tag_human`
1973    /// human-readable narrator prose) now route through this dispatch,
1974    /// closing the 2-site duplication of the prior inline
1975    /// `format!("    {arm}: {v:?}")` + `format!("{arm} {v}")` match
1976    /// blocks that each open-coded the three-way arm-shape mapping
1977    /// side-by-side. Same "one canonical dispatch per typed axis"
1978    /// discipline the peer [`caixa_core::WitTarget::payload_pair`]
1979    /// (6788ed6) established on the sibling `:contratos` payload-arm
1980    /// dispatch surface — a future `GitRefSpec` variant addition
1981    /// (FluxCD's source-controller `spec.ref` schema exposes further
1982    /// `semver` / `name` sub-selectors this V0 shape stops short of)
1983    /// becomes exactly one new match-arm here (a compile-time
1984    /// exhaustiveness error otherwise), not a coordinated three-way
1985    /// rewrite of both format-string templates + every downstream
1986    /// consumer that reaches for the per-arm sub-selector key.
1987    #[must_use]
1988    pub const fn ref_field_name(&self) -> &'static str {
1989        match self {
1990            GitRefSpec::Tag(_) => FLUX_GITREPOSITORY_REF_KEY_TAG,
1991            GitRefSpec::Branch(_) => FLUX_GITREPOSITORY_REF_KEY_BRANCH,
1992            GitRefSpec::Commit(_) => FLUX_GITREPOSITORY_REF_KEY_COMMIT,
1993        }
1994    }
1995
1996    /// The underlying scalar the variant carries — the tag / branch /
1997    /// commit value the FluxCD source-controller feeds into its
1998    /// per-CR git-source clone refspec. Peer of [`Self::ref_field_name`]
1999    /// on the same per-variant dispatch: both consumer sites in
2000    /// [`cluster_bundle`] pair the sub-selector key with the paired
2001    /// scalar to compose the rendered `spec.ref.<field>: <value>`
2002    /// YAML sub-block + the sibling `<field> <value>` narrator prose,
2003    /// so the pair moves together on any future variant addition.
2004    #[must_use]
2005    pub fn ref_value(&self) -> &str {
2006        match self {
2007            GitRefSpec::Tag(t) | GitRefSpec::Branch(t) | GitRefSpec::Commit(t) => t.as_str(),
2008        }
2009    }
2010}
2011
2012impl ClusterBundleOpts {
2013    /// Sensible defaults for a per-program standalone bundle.
2014    #[must_use]
2015    pub fn for_caixa(caixa: &Caixa, cluster: impl Into<String>) -> Self {
2016        Self {
2017            cluster: cluster.into(),
2018            namespace: DEFAULT_NAMESPACE.into(),
2019            interval: DEFAULT_FLUX_RECONCILE_INTERVAL.into(),
2020            chart_path: DEFAULT_FLUX_CHART_SOURCE_SUBPATH.into(),
2021            git_url: caixa.repositorio().map(str::to_owned).unwrap_or_else(|| {
2022                // Canonical typed `&str`-read of the per-`Caixa`
2023                // `:nome` universal-axis DNS-1123-label caixa-identity
2024                // scalar into the `:repositorio`-null pleme-org
2025                // github URL fallback composer. Peer of the sibling
2026                // 22461ef (caixa-helm) / 980c059 (caixa-mesh)
2027                // `caixa.nome()` converges on the co-resident
2028                // non-`.clone()` `&str`/Display raw-field-access axis
2029                // of `Caixa::nome` in the other two substrate-side
2030                // renderers and the sibling 4a363bf `caixa.nome().to_string()`
2031                // converge on the co-resident `String`-carry axis on
2032                // `Caixa::nome` in this crate — this extends the
2033                // "one typed dispatch on the substrate primitive,
2034                // thin projections at each consumer" discipline onto
2035                // the last unlifted non-`.clone()` raw-field-access
2036                // axis of `Caixa::nome` in caixa-flux, so every
2037                // substrate-side renderer (caixa-helm, caixa-flux,
2038                // caixa-mesh) now owns every projection of the
2039                // `Caixa::nome` axis through the typed accessor,
2040                // `.clone()` `String`-carry and `&str`/Display
2041                // raw-field-access alike.
2042                format!(
2043                    "https://github.com/{org}/{nome}",
2044                    org = caixa_core::DEFAULT_PLEME_GIT_ORG,
2045                    nome = caixa.nome(),
2046                )
2047            }),
2048            git_ref: GitRefSpec::Tag(format!(
2049                "{prefix}{versao}",
2050                prefix = caixa_core::DEFAULT_PUBLISH_TAG_PREFIX,
2051                versao = caixa.versao(),
2052            )),
2053        }
2054    }
2055}
2056
2057/// One file of the cluster bundle — `(path, contents)` pair every
2058/// [`cluster_bundle`]-rendered Flux v2 CR YAML document lands at.
2059///
2060/// Type-aliased to the canonical [`caixa_core::RenderedFile`] so the
2061/// substrate-side "one rendered leaf artifact" shape lives at one
2062/// struct definition across every per-target renderer — the peer
2063/// [`caixa_helm::ChartFile`] alias resolves to the same canonical, so
2064/// a future rebrand on either axis (a per-artifact hash / provenance
2065/// field addition, a per-artifact write-mode discriminator once
2066/// per-cluster-writer sandboxing lands) lands at one caixa-core `pub
2067/// struct RenderedFile` edit and reaches both crates by construction.
2068/// Prior to this lift both crates carried an inline `pub struct
2069/// <Xxx>File { pub path: PathBuf, pub contents: String }` with
2070/// identical `#[derive(Debug, Clone, PartialEq, Eq)]` shapes and no
2071/// per-type impls; a future per-target renderer (`caixa-otel`, the
2072/// future `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer, the
2073/// future per-Supervisor reconciler renderer) would have carried a
2074/// third and fourth clone of the same record. Type aliases preserve
2075/// every existing struct-literal construction site
2076/// (`BundleFile { path, contents }`), every field-access site (`f.path`,
2077/// `f.contents`), and every derive-fed navigator by construction —
2078/// Rust type aliases inherit the aliased type's `#[derive]`-generated
2079/// `Debug`/`Clone`/`PartialEq`/`Eq` impls with no per-alias glue.
2080pub type BundleFile = caixa_core::RenderedFile;
2081
2082/// Cluster bundle: the FluxCD trio for a standalone caixa deploy.
2083///
2084/// Three YAMLs:
2085///   gitrepository.yaml — points at the caixa's source repo at a tag
2086///   helmrelease.yaml   — uses the per-program chart from caixa-helm
2087///   kustomization.yaml — the Flux Kustomization that staples them
2088///
2089/// Written under `<cluster>/services/<caixa-name>/` by `feira deploy`.
2090///
2091/// V0 contract: every `:kind Servico` caixa carries exactly one
2092/// `:servicos` entry (one ComputeUnit YAML pointer per Servico,
2093/// matching the one `lareira-<nome>` Helm chart `caixa-helm` renders
2094/// and the one HelmRelease this bundle's `helmrelease.yaml` points at).
2095/// The pair [`caixa_core::require_kind`] + [`caixa_core::require_single_servico`]
2096/// is the canonical per-Servico-renderer entry-point gate axis the peer
2097/// [`programs_yaml_entry`] (the aggregator path) and
2098/// [`caixa_helm::render_chart_for_servico`] (the per-program chart path)
2099/// both run; until this gate landed `cluster_bundle` ran only the kind
2100/// half of the pair, so a Servico-kind caixa with a non-singleton
2101/// `:servicos` list silently passed the bundle render and the failure
2102/// surfaced at the chart-render layer (`caixa-helm` refused the input
2103/// with `UnsupportedServicoCount`) far from the source `caixa.lisp` and
2104/// far from the deploy-path entry point — the canonical "the V0
2105/// invariant is enforced at every per-Servico renderer entry except
2106/// this one" footgun the prior 06b2981 lift commit's body named when
2107/// it called the pair "the canonical V0-shape gate pair for the Servico
2108/// kind, in one place". Same shape every peer per-Servico-renderer
2109/// entry-point uses ([`programs_yaml_entry`] at the aggregator path,
2110/// [`caixa_helm::render_chart_for_servico`] at the per-program chart
2111/// path).
2112pub fn cluster_bundle(caixa: &Caixa, opts: &ClusterBundleOpts) -> Result<Vec<BundleFile>, Error> {
2113    caixa_core::require_v0_servico_shape::<Error>(caixa)?;
2114
2115    // Route the per-bundle `let name` `String`-carry through the typed
2116    // [`caixa_core::Caixa::nome`] accessor (`caixa.nome().to_string()`)
2117    // instead of the raw `caixa.nome.clone()` field access — the one
2118    // `let name` binding threads into every downstream
2119    // `metadata.name` axis this fn emits (the `GitRepository`
2120    // top-level `metadata.name`, the `HelmRelease` top-level
2121    // `metadata.name` + nested `spec.chart.spec.sourceRef.name`, the
2122    // `Kustomization` top-level `metadata.name` + nested
2123    // `spec.healthChecks[0].name`, plus the
2124    // [`flux_kustomization_source_subtree`] composer's per-caixa
2125    // sub-tree scalar), so this single accessor edit shifts every
2126    // per-CR name-axis derivation onto the typed dispatch at once.
2127    // Sibling convergence to the peer 54bf2f3 caixa-mesh three-site
2128    // converge on the same axis on the sibling renderer crate. Pinned
2129    // by the drift-detection tests
2130    // [`cluster_bundle_gitrepository_metadata_name_routes_through_caixa_nome_accessor`],
2131    // [`cluster_bundle_helmrelease_metadata_name_routes_through_caixa_nome_accessor`],
2132    // and
2133    // [`cluster_bundle_kustomization_metadata_name_routes_through_caixa_nome_accessor`]
2134    // in the tests module.
2135    let name = caixa.nome().to_string();
2136    let chart_name = lareira_chart_name(&name);
2137
2138    // The per-variant sub-selector key (`tag` / `branch` / `commit`)
2139    // + its paired scalar (the tag / branch / commit value) now route
2140    // through the canonical [`GitRefSpec::ref_field_name`] +
2141    // [`GitRefSpec::ref_value`] dispatch, closing the 2-site
2142    // duplication the prior inline per-variant `format!("    <arm>:
2143    // {v:?}")` match block open-coded side-by-side with the sibling
2144    // `tag_human` narrator prose block. Byte-identical output to the
2145    // prior 3-arm inline `format!`s: `{value:?}` on `&str` renders
2146    // the same shape as `{v:?}` on `String` (both call the same
2147    // `Debug` impl at the identical stack position).
2148    let gitref_field = format!(
2149        "    {field}: {value:?}",
2150        field = opts.git_ref.ref_field_name(),
2151        value = opts.git_ref.ref_value(),
2152    );
2153
2154    let gitrepo = format!(
2155        "---\n\
2156         # Source — pinned to {tag_human}, rendered by caixa-flux.\n\
2157         {api_version_key}: {api_version}\n\
2158         {kind_key}: {kind}\n\
2159         {metadata_key}:\n  \
2160           {name_key}: {name}\n  \
2161           {namespace_key}: {namespace}\n\
2162         {spec_key}:\n  \
2163           {interval_key}: {interval}\n  \
2164           {url_key}: {url}\n  \
2165           {ref_key}:\n\
2166         {gitref_field}\n",
2167        api_version_key = KUBE_KEY_API_VERSION,
2168        api_version = FLUX_GITREPOSITORY_API_VERSION,
2169        kind_key = KUBE_KEY_KIND,
2170        kind = FLUX_KIND_GIT_REPOSITORY,
2171        metadata_key = KUBE_KEY_METADATA,
2172        name_key = KUBE_KEY_NAME,
2173        namespace_key = KUBE_KEY_NAMESPACE,
2174        spec_key = KUBE_KEY_SPEC,
2175        tag_human = format!(
2176            "{field} {value}",
2177            field = opts.git_ref.ref_field_name(),
2178            value = opts.git_ref.ref_value(),
2179        ),
2180        name = name,
2181        namespace = opts.namespace,
2182        interval_key = FLUX_KEY_INTERVAL,
2183        interval = opts.interval,
2184        url_key = FLUX_GITREPOSITORY_KEY_URL,
2185        url = opts.git_url,
2186        ref_key = FLUX_GITREPOSITORY_KEY_REF,
2187        gitref_field = gitref_field,
2188    );
2189
2190    // The values wrap key under `spec.values.<library>:` must match the
2191    // peer caixa-helm chart's `dependencies[0].name` axis exactly —
2192    // Helm's per-dep alias convention scopes values under the
2193    // dependency's `name:` when no `alias:` is set, so a wrap-key drift
2194    // silently routes the per-cluster `enabled: true` override nowhere
2195    // at `helm template` / `helm install` time. Both axes now consult
2196    // the same lifted [`caixa_core::DEFAULT_LIBRARY_NAME`] constant
2197    // (`caixa-helm`'s `RenderOpts::library_name` defaults to the same
2198    // re-export), so a future per-edition library-chart rebrand reaches
2199    // both consumers through one `&'static str` by construction. Peer
2200    // with the [`DEFAULT_NAMESPACE`] (a085b26) /
2201    // [`DEFAULT_SERVICO_PORT`] (1e22add) lifts on the sibling
2202    // canonical-K8s-axis-constant surface — duplicated load-bearing
2203    // string axes lifted to one source of truth.
2204    let helmrelease = format!(
2205        "---\n\
2206         # HelmRelease consumes the chart caixa-helm renders for this\n\
2207         # caixa Servico. Per-cluster values are injected here.\n\
2208         {api_version_key}: {api_version}\n\
2209         {kind_key}: {kind}\n\
2210         {metadata_key}:\n  \
2211           {name_key}: {name}\n  \
2212           {namespace_key}: {namespace}\n\
2213         {spec_key}:\n  \
2214           {interval_key}: {interval}\n  \
2215           {chart_key}:\n    \
2216             {spec_key}:\n      \
2217               {chart_name_key}: {chart_path}\n      \
2218               {source_ref_key}:\n        \
2219                 {kind_key}: {source_kind}\n        \
2220                 {name_key}: {name}\n        \
2221                 {namespace_key}: {namespace}\n  \
2222           {install_key}:\n    \
2223             {create_namespace_key}: {create_namespace_default}\n    \
2224             {remediation_key}:\n      \
2225               {retries_key}: {retries_default}\n  \
2226           {upgrade_key}:\n    \
2227             {remediation_key}:\n      \
2228               {retries_key}: {retries_default}\n      \
2229               {remediate_last_failure_key}: {remediate_last_failure_default}\n  \
2230           {values_key}:\n    \
2231             {library_name}:\n      \
2232               {enabled_key}: {lareira_enabled_default}\n",
2233        api_version_key = KUBE_KEY_API_VERSION,
2234        api_version = FLUX_HELMRELEASE_API_VERSION,
2235        kind_key = KUBE_KEY_KIND,
2236        kind = FLUX_KIND_HELM_RELEASE,
2237        source_kind = FLUX_KIND_GIT_REPOSITORY,
2238        metadata_key = KUBE_KEY_METADATA,
2239        name_key = KUBE_KEY_NAME,
2240        namespace_key = KUBE_KEY_NAMESPACE,
2241        spec_key = KUBE_KEY_SPEC,
2242        name = name,
2243        namespace = opts.namespace,
2244        interval_key = FLUX_KEY_INTERVAL,
2245        interval = opts.interval,
2246        chart_key = FLUX_KEY_CHART,
2247        chart_name_key = FLUX_HELMCHART_TEMPLATE_KEY_CHART,
2248        chart_path = opts.chart_path,
2249        source_ref_key = FLUX_KEY_SOURCE_REF,
2250        values_key = FLUX_KEY_VALUES,
2251        library_name = DEFAULT_LIBRARY_NAME,
2252        enabled_key = HELM_VALUES_KEY_ENABLED,
2253        retries_default = FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT,
2254        retries_key = FLUX_HELMRELEASE_KEY_RETRIES,
2255        remediation_key = FLUX_HELMRELEASE_KEY_REMEDIATION,
2256        install_key = FLUX_HELMRELEASE_KEY_INSTALL,
2257        upgrade_key = FLUX_HELMRELEASE_KEY_UPGRADE,
2258        remediate_last_failure_key = FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE,
2259        remediate_last_failure_default = FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT,
2260        create_namespace_key = FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE,
2261        create_namespace_default = FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT,
2262        lareira_enabled_default = CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT,
2263    );
2264
2265    // The `spec.path` per-CR source-sub-tree scalar composes through
2266    // the canonical [`flux_kustomization_source_subtree`] helper
2267    // (re-exported from [`caixa_core::flux_kustomization_source_subtree`]),
2268    // so the substrate's canonical per-cluster / per-caixa GitRepository-
2269    // relative directory-tree seed (`./clusters/<cluster>/services/<nome>`)
2270    // lives at one composer instead of a verbatim inline
2271    // `format!("./clusters/{cluster}/services/{name}")` at this emit site.
2272    // Threaded through a `{source_subtree}` named-arg interpolation on
2273    // the paired `{path_key}` leaf-scalar-key emit. Peer to the sibling
2274    // [`caixa_core::oci_chart_ref`] / [`caixa_core::cilium_network_policy_name`]
2275    // / [`caixa_core::gateway_api_http_route_name`] canonical-composer
2276    // re-exports on the substrate-side canonical-load-bearing-scalar
2277    // axis.
2278    let source_subtree = flux_kustomization_source_subtree(&opts.cluster, &name);
2279
2280    let kustomization = format!(
2281        "---\n\
2282         # Flux Kustomization that pins the GitRepository + HelmRelease.\n\
2283         # Paired path: pleme-io/k8s/clusters/{cluster}/services/{name}/\n\
2284         {api_version_key}: {kustomization_api_version}\n\
2285         {kind_key}: {kind}\n\
2286         {metadata_key}:\n  \
2287           {name_key}: {name}\n  \
2288           {namespace_key}: {flux_system}\n\
2289         {spec_key}:\n  \
2290           {interval_key}: {interval}\n  \
2291           {prune_key}: {prune_default}\n  \
2292           {source_ref_key}:\n    \
2293             {kind_key}: {source_kind}\n    \
2294             {name_key}: {flux_system}\n  \
2295           {path_key}: {source_subtree}\n  \
2296           {health_checks_key}:\n    \
2297             - {api_version_key}: {api_version}\n      \
2298               {kind_key}: {health_kind}\n      \
2299               {name_key}: {name}\n      \
2300               {namespace_key}: {namespace}\n  \
2301           {timeout_key}: {timeout_default}\n",
2302        api_version_key = KUBE_KEY_API_VERSION,
2303        kustomization_api_version = FLUX_KUSTOMIZATION_API_VERSION,
2304        kind_key = KUBE_KEY_KIND,
2305        kind = FLUX_KIND_KUSTOMIZATION,
2306        source_kind = FLUX_KIND_GIT_REPOSITORY,
2307        health_kind = FLUX_KIND_HELM_RELEASE,
2308        metadata_key = KUBE_KEY_METADATA,
2309        name_key = KUBE_KEY_NAME,
2310        namespace_key = KUBE_KEY_NAMESPACE,
2311        spec_key = KUBE_KEY_SPEC,
2312        api_version = FLUX_HELMRELEASE_API_VERSION,
2313        name = name,
2314        namespace = opts.namespace,
2315        interval_key = FLUX_KEY_INTERVAL,
2316        interval = opts.interval,
2317        cluster = opts.cluster,
2318        flux_system = DEFAULT_FLUX_SYSTEM_NAMESPACE,
2319        source_ref_key = FLUX_KEY_SOURCE_REF,
2320        health_checks_key = FLUX_KEY_HEALTH_CHECKS,
2321        prune_key = FLUX_KUSTOMIZATION_KEY_PRUNE,
2322        prune_default = FLUX_KUSTOMIZATION_PRUNE_DEFAULT,
2323        path_key = FLUX_KUSTOMIZATION_KEY_PATH,
2324        timeout_key = FLUX_KUSTOMIZATION_KEY_TIMEOUT,
2325        timeout_default = DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT,
2326        source_subtree = source_subtree,
2327    );
2328    // chart_name is reserved for a future kustomization.yaml `resources:`
2329    // entry pointing at the rendered Chart.yaml; not yet wired.
2330    let _ = chart_name;
2331
2332    // Each per-CR YAML leaf routes through the canonical
2333    // [`caixa_core::RenderedFile::new`] `impl Into<PathBuf>` /
2334    // `impl Into<String>` constructor (re-exported by the peer
2335    // [`BundleFile`] alias since Rust inherent methods travel through
2336    // type aliases to the aliased type at name resolution). The prior
2337    // three inline `BundleFile { path: std::path::PathBuf::from(
2338    // FILENAME_CONST), contents: <body> }` blocks each re-derived the
2339    // same `PathBuf::from(&str)` wrap + the same two-field assembly —
2340    // a byte-identical duplicate of the peer
2341    // [`caixa_helm::render_chart_for_servico_with`] `Chart.yaml` /
2342    // `values.yaml` / `README.md` chart-directory trio's three
2343    // per-artifact emit sites. Sweeping both trios onto
2344    // [`RenderedFile::new`] collapses the six substrate-side
2345    // per-artifact-construction sites onto one canonical constructor
2346    // so a future rebrand on the record shape (a per-artifact hash /
2347    // provenance field addition, a per-artifact write-mode discriminator
2348    // once per-cluster-writer sandboxing lands, the
2349    // [`caixa_core::is_sandboxed_relative_path`] discipline the
2350    // [`caixa_core::RenderedFile`] docstring acknowledges is not yet
2351    // run at emit time) reaches every per-target renderer through one
2352    // caixa-core edit instead of a coordinated six-site rewrite.
2353    Ok(vec![
2354        BundleFile::new(FLUX_GITREPOSITORY_YAML_FILENAME, gitrepo),
2355        BundleFile::new(FLUX_HELMRELEASE_YAML_FILENAME, helmrelease),
2356        BundleFile::new(FLUX_KUSTOMIZATION_YAML_FILENAME, kustomization),
2357    ])
2358}
2359
2360#[cfg(test)]
2361mod tests {
2362    use super::*;
2363    use caixa_core::{
2364        Caixa, CaixaKind, M2_BEHAVIOR_KEY_ON_INIT, M2_KEY_BEHAVIOR, M2_KEY_LIMITS,
2365        M2_KEY_UPGRADE_FROM, M2_LIMITS_KEY_CPU, M2_LIMITS_KEY_MEMORY, M2_UPGRADE_FROM_KEY_FROM,
2366        kube_root_str_field,
2367    };
2368
2369    fn sample_caixa() -> Caixa {
2370        Caixa {
2371            nome: "hello-rio".into(),
2372            versao: "0.1.0".into(),
2373            kind: CaixaKind::Servico,
2374            edicao: Some("2026".into()),
2375            descricao: Some("Canonical Rust→wasm32-wasip2 caixa Servico.".into()),
2376            repositorio: Some("https://github.com/pleme-io/hello-rio".into()),
2377            licenca: Some("MIT".into()),
2378            autores: vec!["pleme-io".into()],
2379            etiquetas: vec!["hello-world".into()],
2380            deps: vec![],
2381            deps_dev: vec![],
2382            exe: vec![],
2383            bibliotecas: vec![],
2384            servicos: vec!["servicos/hello-rio.computeunit.yaml".into()],
2385            limits: None,
2386            behavior: None,
2387            upgrade_from: vec![],
2388            estrategia: None,
2389            max_restarts: None,
2390            restart_window: None,
2391            children: vec![],
2392            membros: vec![],
2393            contratos: vec![],
2394            politicas: None,
2395            placement: None,
2396            entrada: None,
2397            ci: None,
2398        }
2399    }
2400
2401    fn sample_cu_yaml() -> serde_yaml::Value {
2402        serde_yaml::from_str(
2403            r#"
2404apiVersion: wasm.pleme.io/v1alpha1
2405kind: ComputeUnit
2406metadata:
2407  name: hello-rio
2408  namespace: tatara-system
2409spec:
2410  module:
2411    source: oci://ghcr.io/pleme-io/hello-rio:v0.1.0
2412  trigger:
2413    service:
2414      port: 8080
2415      paths: ["/", "/hello", "/healthz"]
2416  capabilities:
2417    - http-in:0.0.0.0:8080
2418    - env
2419"#,
2420        )
2421        .unwrap()
2422    }
2423
2424    #[test]
2425    fn default_namespace_re_export_points_at_caixa_core_canonical() {
2426        // The renderer's `pub const DEFAULT_NAMESPACE` was lifted to a
2427        // re-export of [`caixa_core::DEFAULT_NAMESPACE`] so the
2428        // namespace string lives in exactly one place across every
2429        // caixa renderer (caixa-flux + caixa-mesh today, every future
2430        // per-target renderer the substrate adds). Pin the equality
2431        // here so any local re-introduction of a sibling `pub const
2432        // DEFAULT_NAMESPACE: &str = "…"` (the canonical drift footgun
2433        // that motivated this lift, with the prior caixa-mesh doc-
2434        // comment explicitly acknowledging the duplication) is a
2435        // build-time test failure naming the offending drift, not a
2436        // silent apply-time CiliumNetworkPolicy / Gateway / HTTPRoute
2437        // `endpointSelector` namespace mismatch dropping every L7
2438        // contrato flow far from the source rebrand commit. Peer to
2439        // `caixa_mesh::tests::default_namespace_re_export_points_at_caixa_core_canonical`
2440        // on the sibling renderer crate.
2441        caixa_core::assert_str_reexport_identity(
2442            "DEFAULT_NAMESPACE",
2443            DEFAULT_NAMESPACE,
2444            caixa_core::DEFAULT_NAMESPACE,
2445        );
2446    }
2447
2448    #[test]
2449    fn default_flux_reconcile_interval_re_export_points_at_caixa_core_canonical() {
2450        // The renderer's `DEFAULT_FLUX_RECONCILE_INTERVAL` was lifted
2451        // from the inline `"10m"` scalar-value literal at
2452        // [`ClusterBundleOpts::for_caixa`]'s per-caixa default seed (the
2453        // sole production-code site the substrate seeds into the
2454        // [`ClusterBundleOpts::interval`] field that [`cluster_bundle`]'s
2455        // three per-CR format-string templates thread through their
2456        // [`FLUX_KEY_INTERVAL`]-keyed `spec.interval` axis verbatim) to a
2457        // re-export of [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] so
2458        // the Flux v2 controller-side reconcile-cadence default scalar-
2459        // value string lives in exactly one place across every caixa
2460        // renderer. Pin the equality + static-data identity here so any
2461        // local re-introduction of a sibling `pub const
2462        // DEFAULT_FLUX_RECONCILE_INTERVAL: &str = "…"` (the canonical
2463        // drift footgun where a sibling local `pub const` could happen
2464        // to carry the same string at the source while pointing at a
2465        // different `&'static` allocation) is a build-time test failure
2466        // naming the offending drift, not a silent apply-time symptom —
2467        // the prior inline shape would have let a substrate-side
2468        // reconcile-cadence migration without a coordinated caixa-core
2469        // edit silently seed per-caixa Flux v2 CRs at a drifted per-CR
2470        // reconcile-schedule, splitting the substrate's per-caixa
2471        // convergence-freshness contract across renderer versions with
2472        // no diagnostic naming the cadence-drift root cause. Peer to
2473        // [`default_namespace_re_export_points_at_caixa_core_canonical`]
2474        // on the sibling canonical-substrate-default-load-bearing-
2475        // scalar re-export surface.
2476        caixa_core::assert_str_reexport_identity(
2477            "DEFAULT_FLUX_RECONCILE_INTERVAL",
2478            DEFAULT_FLUX_RECONCILE_INTERVAL,
2479            caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL,
2480        );
2481    }
2482
2483    #[test]
2484    fn cluster_bundle_opts_for_caixa_seeds_interval_from_lifted_default() {
2485        // Fail-before-pass-after pin: the substrate's per-caixa default
2486        // seed for [`ClusterBundleOpts::interval`] must resolve to the
2487        // lifted [`DEFAULT_FLUX_RECONCILE_INTERVAL`] verbatim. Before the
2488        // lift the field carried an inline `"10m"` literal at the sole
2489        // production-code call site (the [`ClusterBundleOpts::for_caixa`]
2490        // per-caixa default builder); a future substrate-side
2491        // reconcile-cadence migration on the canonical
2492        // [`caixa_core::DEFAULT_FLUX_RECONCILE_INTERVAL`] declaration
2493        // that failed to reach this seed site would silently split the
2494        // substrate's per-caixa Flux v2 convergence-freshness contract
2495        // between the operator-facing canonical default and the per-
2496        // caixa `cluster_bundle` renderer's seeded reconcile-schedule,
2497        // freezing every per-caixa Flux v2 CR at the drifted cadence
2498        // far from the rebrand commit's source. Pin the identity here
2499        // so a regression that re-introduces an inline literal at the
2500        // seed site surfaces at build time on this test's failure. Peer
2501        // to the sibling
2502        // [`cluster_bundle_every_flux_cr_carries_lifted_flux_key_interval_scalar`]
2503        // pin on the per-CR `spec.interval` axis — that test pins the
2504        // rendered scalar agrees with `opts.interval`, this test pins
2505        // `opts.interval`'s substrate-side seed agrees with the lifted
2506        // canonical default.
2507        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
2508        assert_eq!(
2509            opts.interval, DEFAULT_FLUX_RECONCILE_INTERVAL,
2510            "the substrate's per-caixa Flux v2 reconcile-cadence default \
2511             seed must resolve to the lifted \
2512             `DEFAULT_FLUX_RECONCILE_INTERVAL` scalar — drift here \
2513             silently splits the substrate's per-caixa convergence-\
2514             freshness contract between the operator-facing canonical \
2515             default and the per-caixa seeded reconcile-schedule"
2516        );
2517    }
2518
2519    #[test]
2520    fn default_flux_chart_source_subpath_re_export_points_at_caixa_core_canonical() {
2521        // The renderer's `DEFAULT_FLUX_CHART_SOURCE_SUBPATH` was lifted
2522        // from the inline `"chart".into()` scalar-value literal at
2523        // [`ClusterBundleOpts::for_caixa`]'s per-caixa default seed (the
2524        // sole production-code site the substrate seeds into the
2525        // [`ClusterBundleOpts::chart_path`] field that [`cluster_bundle`]'s
2526        // `helmrelease.yaml` format-string template threads through its
2527        // [`FLUX_HELMCHART_TEMPLATE_KEY_CHART`]-keyed `spec.chart.spec.chart`
2528        // axis verbatim) to a re-export of
2529        // [`caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH`] so the Flux v2
2530        // helm-controller-side chart-directory-in-GitRepository-source
2531        // default scalar-value string lives in exactly one place across
2532        // every caixa renderer. Pin the equality + static-data identity
2533        // here so any local re-introduction of a sibling `pub const
2534        // DEFAULT_FLUX_CHART_SOURCE_SUBPATH: &str = "…"` (the canonical
2535        // drift footgun where a sibling local `pub const` could happen to
2536        // carry the same string at the source while pointing at a
2537        // different `&'static` allocation) is a build-time test failure
2538        // naming the offending drift, not a silent apply-time symptom —
2539        // the prior inline shape would have let a substrate-side chart-
2540        // directory-in-git-source migration without a coordinated caixa-
2541        // core edit silently seed per-caixa `HelmRelease` CRs at a
2542        // drifted per-CR chart-directory pointer, splitting the
2543        // substrate's per-caixa chart-open contract with the Flux v2
2544        // helm-controller across renderer versions with no diagnostic
2545        // naming the sub-path-drift root cause (the source-controller
2546        // would then either fail to open the paired per-caixa chart
2547        // directory or, worse, silently open a stale sibling directory
2548        // the drifted scalar happens to name). Peer to
2549        // [`default_flux_reconcile_interval_re_export_points_at_caixa_core_canonical`]
2550        // on the sibling canonical-substrate-default-load-bearing-
2551        // scalar re-export surface.
2552        caixa_core::assert_str_reexport_identity(
2553            "DEFAULT_FLUX_CHART_SOURCE_SUBPATH",
2554            DEFAULT_FLUX_CHART_SOURCE_SUBPATH,
2555            caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH,
2556        );
2557    }
2558
2559    #[test]
2560    fn cluster_bundle_opts_for_caixa_seeds_chart_path_from_lifted_default() {
2561        // Fail-before-pass-after pin: the substrate's per-caixa default
2562        // seed for [`ClusterBundleOpts::chart_path`] must resolve to the
2563        // lifted [`DEFAULT_FLUX_CHART_SOURCE_SUBPATH`] verbatim. Before
2564        // the lift the field carried an inline `"chart".into()` literal
2565        // at the sole production-code call site (the
2566        // [`ClusterBundleOpts::for_caixa`] per-caixa default builder); a
2567        // future substrate-side chart-directory-in-git-source migration
2568        // on the canonical
2569        // [`caixa_core::DEFAULT_FLUX_CHART_SOURCE_SUBPATH`] declaration
2570        // that failed to reach this seed site would silently split the
2571        // substrate's per-caixa Flux v2 chart-open contract between the
2572        // operator-facing canonical default and the per-caixa
2573        // `cluster_bundle` renderer's seeded chart-directory pointer,
2574        // freezing every per-caixa `HelmRelease` CR at the drifted sub-
2575        // path far from the rebrand commit's source. Pin the identity
2576        // here so a regression that re-introduces an inline literal at
2577        // the seed site surfaces at build time on this test's failure.
2578        // Peer to the sibling
2579        // [`cluster_bundle_opts_for_caixa_seeds_interval_from_lifted_default`]
2580        // pin on the co-resident per-caixa Flux v2 CR substrate-default
2581        // seed surface — that test pins `opts.interval`'s substrate-side
2582        // seed agrees with the lifted canonical default, this test pins
2583        // `opts.chart_path`'s substrate-side seed agrees with the peer
2584        // lifted canonical default.
2585        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
2586        assert_eq!(
2587            opts.chart_path, DEFAULT_FLUX_CHART_SOURCE_SUBPATH,
2588            "the substrate's per-caixa Flux v2 chart-directory-in-git-\
2589             source default seed must resolve to the lifted \
2590             `DEFAULT_FLUX_CHART_SOURCE_SUBPATH` scalar — drift here \
2591             silently splits the substrate's per-caixa chart-open \
2592             contract between the operator-facing canonical default \
2593             and the per-caixa seeded chart-directory pointer"
2594        );
2595    }
2596
2597    #[test]
2598    fn cluster_bundle_opts_for_caixa_git_url_fallback_routes_through_caixa_nome_accessor() {
2599        // Fail-before-pass-after pin: the substrate's per-caixa
2600        // `:repositorio`-null pleme-org github URL fallback composer
2601        // inside [`ClusterBundleOpts::for_caixa`] must derive its
2602        // trailing `<nome>` path segment through the typed
2603        // [`caixa_core::Caixa::nome`] accessor, not the raw
2604        // `caixa.nome` field access. Before this converge the
2605        // fallback branch carried a raw `nome = caixa.nome` Display
2606        // of the underlying `String` field into the `format!("https://\
2607        // github.com/{org}/{nome}", ...)` template, bypassing the
2608        // typed dispatch every peer per-Caixa identity consumer in
2609        // caixa-helm / caixa-mesh already routes through — the
2610        // canonical drift-footgun shape where a future
2611        // `Caixa::nome`-accessor extension (a per-cluster alias
2612        // table the operator pins through a future `:placement`-
2613        // scoped slot, an M4 namespace-qualified rewrite the CR
2614        // materializer applies per-CR, the future `:nome-suffix`
2615        // overlay MESH-COMPOSITION §III.2 acknowledges) would land
2616        // on the accessor but never reach this emit site, silently
2617        // splitting the parent-Caixa identity between the
2618        // FluxCD `GitRepository` `spec.url` `<org>/<nome>` clone
2619        // target this fallback composes and every other per-Caixa
2620        // identity consumer the caixa-helm / caixa-mesh renderers
2621        // emit — the source-controller would then clone from a
2622        // wrong-name pleme-org repository, silently freezing every
2623        // `:repositorio`-null caixa's Flux v2 clone target at the
2624        // pre-extension name and orphaning the paired `HelmRelease`
2625        // `chart: sourceRef` from the actual per-caixa git source
2626        // the substrate resolves through the accessor. Pin the
2627        // equality on the constructed `opts.git_url` so a regression
2628        // that re-inlines `caixa.nome` at the fallback site
2629        // surfaces here as a build-time test failure rather than as
2630        // a silent deploy-time `GitRepository` reconcile loop. Peer
2631        // to the sibling `cluster_bundle_default_git_tag_uses_lifted_caixa_core_prefix`
2632        // pin on the co-resident `git_ref` axis of the same
2633        // `ClusterBundleOpts::for_caixa` composer surface, and to
2634        // the sibling 22461ef (caixa-helm) / 980c059 (caixa-mesh)
2635        // `caixa.nome()` converge pins on the peer non-`.clone()`
2636        // raw-field-access axis of `Caixa::nome` in the other two
2637        // substrate-side renderers.
2638        let mut caixa = sample_caixa();
2639        caixa.repositorio = None;
2640        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
2641        let expected = format!(
2642            "https://github.com/{org}/{nome}",
2643            org = caixa_core::DEFAULT_PLEME_GIT_ORG,
2644            nome = caixa.nome(),
2645        );
2646        assert_eq!(
2647            opts.git_url, expected,
2648            "the substrate's per-caixa `:repositorio`-null pleme-org \
2649             github URL fallback composer must derive its trailing \
2650             `<nome>` path segment through the typed \
2651             `caixa_core::Caixa::nome` accessor — a regression that \
2652             re-inlines `caixa.nome` at the fallback site silently \
2653             splits the parent-Caixa identity between the FluxCD \
2654             `GitRepository` `spec.url` `<org>/<nome>` clone target \
2655             and every other per-Caixa identity consumer the sibling \
2656             caixa-helm / caixa-mesh renderers emit"
2657        );
2658    }
2659
2660    #[test]
2661    fn flux_helmrelease_remediation_retries_default_re_export_points_at_caixa_core_canonical() {
2662        // The renderer's `FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`
2663        // was lifted from the two production-code duplicated inline
2664        // `retries: 3` scalar-value literals inside [`cluster_bundle`]'s
2665        // `helmrelease.yaml` format-string template (the install-path
2666        // `install.remediation.retries` site + the upgrade-path
2667        // `upgrade.remediation.retries` site) to a re-export of
2668        // [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] so
2669        // the Flux v2 helm-controller-side per-CR remediation-retries
2670        // default scalar-value lives in exactly one place across every
2671        // caixa renderer. Pin the equality here so any local
2672        // re-introduction of a sibling `pub const
2673        // FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT: u32 = <n>` (the
2674        // canonical drift footgun where a sibling local `pub const`
2675        // could happen to carry a different value while the rest of the
2676        // codebase keeps consuming the caixa-core canonical) is a
2677        // build-time test failure naming the offending drift, not a
2678        // silent apply-time symptom — the prior duplicated inline shape
2679        // would have let a substrate-side retry-ceiling migration on the
2680        // canonical caixa-core declaration without a coordinated caixa-
2681        // flux edit silently seed per-caixa Flux v2 `HelmRelease` CRs at
2682        // a drifted per-path remediation-retries schedule, splitting the
2683        // substrate's canonical retry-ceiling between the install-path
2684        // and the upgrade-path with no diagnostic naming the ceiling-
2685        // drift root cause. Peer to
2686        // [`default_flux_reconcile_interval_re_export_points_at_caixa_core_canonical`]
2687        // on the sibling canonical-substrate-default-load-bearing-scalar
2688        // re-export surface.
2689        assert_eq!(
2690            FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT,
2691            caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT,
2692            "`caixa_flux::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT` \
2693             must be the value-identical re-export of the canonical \
2694             `caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT` — \
2695             drift here silently splits the substrate's per-caixa Flux \
2696             v2 `HelmRelease` remediation-retries ceiling between the \
2697             canonical caixa-core declaration and the renderer's threaded \
2698             seed"
2699        );
2700    }
2701
2702    #[test]
2703    fn flux_helmrelease_key_retries_re_export_points_at_caixa_core_canonical() {
2704        // The renderer's `pub use caixa_core::FLUX_HELMRELEASE_KEY_RETRIES`
2705        // is the single source of truth for the Flux v2 per-CR
2706        // remediation-retries leaf-scalar-key baked into both the
2707        // install-path + upgrade-path `retries:` sub-block leaf-headers
2708        // of the [`cluster_bundle`] `helmrelease.yaml` format-string
2709        // template (both threading the same `&'static str` through the
2710        // new `{retries_key}` named-arg interpolation) plus the two
2711        // test-fixture navigation sites in `mod tests` that probe the
2712        // rendered document at `.get(FLUX_HELMRELEASE_KEY_RETRIES)`. Pin
2713        // the equality (and the static-data identity, peer with the
2714        // sibling
2715        // [`flux_helmrelease_remediation_retries_default_re_export_points_at_caixa_core_canonical`]
2716        // pin on the scalar-value half of the same
2717        // `(leaf-key, scalar-value)` per-path retry-cap declaration
2718        // pair) so any local re-introduction of a sibling
2719        // `pub const FLUX_HELMRELEASE_KEY_RETRIES: &str = "…"` (the
2720        // canonical drift footgun this lift closes — the load-bearing
2721        // Flux-v2-helm-controller-side per-CR remediation-retries leaf-
2722        // scalar-key across four prior inlined occurrences — two
2723        // production emit sites in the `cluster_bundle` `helmrelease.yaml`
2724        // format-string template plus two test-fixture navigation sites,
2725        // lifted to one re-export at the caixa-core boundary) is a
2726        // build-time test failure naming the offending drift, not a
2727        // silent apply-time symptom (a stripped `retries:` leaf letting
2728        // the helm-controller fall back to the Flux v2 upstream default).
2729        assert_eq!(
2730            FLUX_HELMRELEASE_KEY_RETRIES,
2731            caixa_core::FLUX_HELMRELEASE_KEY_RETRIES
2732        );
2733        assert!(
2734            std::ptr::eq(
2735                FLUX_HELMRELEASE_KEY_RETRIES.as_ptr(),
2736                caixa_core::FLUX_HELMRELEASE_KEY_RETRIES.as_ptr(),
2737            ),
2738            "FLUX_HELMRELEASE_KEY_RETRIES must be a re-export of \
2739             caixa_core::FLUX_HELMRELEASE_KEY_RETRIES, not a sibling `pub const` \
2740             that happens to carry the same string — drift between the two is \
2741             the canonical footgun this lift closes"
2742        );
2743    }
2744
2745    #[test]
2746    fn flux_helmrelease_key_remediation_re_export_points_at_caixa_core_canonical() {
2747        // The renderer's `pub use caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATION`
2748        // is the single source of truth for the Flux v2 per-CR
2749        // remediation sub-container-axis-key baked into both the
2750        // install-path + upgrade-path `remediation:` sub-block-header
2751        // lines of the [`cluster_bundle`] `helmrelease.yaml` format-
2752        // string template (both threading the same `&'static str`
2753        // through the new `{remediation_key}` named-arg interpolation)
2754        // plus the two test-fixture navigation sites in `mod tests` that
2755        // probe the rendered document at
2756        // `.get(FLUX_HELMRELEASE_KEY_REMEDIATION)`. Pin the equality
2757        // (and the static-data identity, peer with the sibling
2758        // [`flux_helmrelease_key_retries_re_export_points_at_caixa_core_canonical`]
2759        // pin on the leaf-scalar-key half of the same
2760        // `(container-axis-key, leaf-scalar-key, scalar-value)` per-path
2761        // retry-cap declaration triple) so any local re-introduction of
2762        // a sibling `pub const FLUX_HELMRELEASE_KEY_REMEDIATION: &str =
2763        // "…"` (the canonical drift footgun this lift closes — the
2764        // load-bearing Flux-v2-helm-controller-side per-CR remediation
2765        // sub-container-axis-key across four prior inlined occurrences —
2766        // two production emit sites in the `cluster_bundle`
2767        // `helmrelease.yaml` format-string template plus two test-
2768        // fixture navigation sites, lifted to one re-export at the
2769        // caixa-core boundary) is a build-time test failure naming the
2770        // offending drift, not a silent apply-time symptom (a stripped
2771        // whole-remediation sub-block letting the helm-controller fall
2772        // back to the Flux v2 upstream defaults for the whole per-path
2773        // remediation surface).
2774        caixa_core::assert_str_reexport_identity(
2775            "FLUX_HELMRELEASE_KEY_REMEDIATION",
2776            FLUX_HELMRELEASE_KEY_REMEDIATION,
2777            caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATION,
2778        );
2779    }
2780
2781    #[test]
2782    fn flux_helmrelease_key_remediation_pins_canonical_remediation_string() {
2783        // Bridge-arm pin: the lifted [`FLUX_HELMRELEASE_KEY_REMEDIATION`]
2784        // constant resolves to the canonical `"remediation"` string
2785        // today, and both rendered Flux v2 `HelmRelease` per-path per-CR
2786        // sub-block-headers must spell it out verbatim. Pin the literal
2787        // here (peer with the sibling
2788        // [`flux_helmrelease_key_retries_pins_canonical_retries_string`]-shape
2789        // canonical-default arm on the sibling per-CR leaf-scalar-key
2790        // surface + the peer
2791        // [`flux_key_source_ref_pins_canonical_source_ref_string`]-shape
2792        // canonical-default arm on the peer per-CR container-axis-key
2793        // surface) so a future rebrand of the lifted constant (Flux v3
2794        // rename like `recovery` / `retryPolicy` / `errorHandling` —
2795        // upstream Flux v3 roadmap candidates that would land the same
2796        // per-CR retry-cap semantics under a different sub-container-
2797        // axis-key) surfaces here as a coordinated edit-point.
2798        assert_eq!(FLUX_HELMRELEASE_KEY_REMEDIATION, "remediation");
2799    }
2800
2801    #[test]
2802    fn flux_helmrelease_key_install_re_export_points_at_caixa_core_canonical() {
2803        // The renderer's `pub use caixa_core::FLUX_HELMRELEASE_KEY_INSTALL`
2804        // is the single source of truth for the Flux v2 per-CR install-
2805        // path helm-action-phase discriminator parent-container-axis-key
2806        // baked into the `install:` sub-block-header line of the
2807        // [`cluster_bundle`] `helmrelease.yaml` format-string template
2808        // (threading the same `&'static str` through the new
2809        // `{install_key}` named-arg interpolation) plus the one test-
2810        // fixture navigation site in `mod tests` that probes the
2811        // rendered document at `.get(FLUX_HELMRELEASE_KEY_INSTALL)`. Pin
2812        // the equality (and the static-data identity, peer with the
2813        // sibling
2814        // [`flux_helmrelease_key_remediation_re_export_points_at_caixa_core_canonical`]
2815        // pin on the sub-container-axis-key half of the same
2816        // `(parent-container-key, sub-container-key, leaf-key, scalar-
2817        // value)` per-path retry-cap declaration quartet) so any local
2818        // re-introduction of a sibling `pub const
2819        // FLUX_HELMRELEASE_KEY_INSTALL: &str = "…"` (the canonical drift
2820        // footgun this lift closes — the load-bearing Flux-v2-helm-
2821        // controller-side per-CR install-path phase-discriminator
2822        // parent-container-axis-key across two prior inlined occurrences —
2823        // one production emit site in the `cluster_bundle`
2824        // `helmrelease.yaml` format-string template plus one test-
2825        // fixture navigation site, lifted to one re-export at the caixa-
2826        // core boundary) is a build-time test failure naming the
2827        // offending drift, not a silent apply-time symptom (a stripped
2828        // whole-install-path per-CR phase block letting the helm-
2829        // controller fall back to the Flux v2 upstream defaults for the
2830        // whole install-path phase surface).
2831        caixa_core::assert_str_reexport_identity(
2832            "FLUX_HELMRELEASE_KEY_INSTALL",
2833            FLUX_HELMRELEASE_KEY_INSTALL,
2834            caixa_core::FLUX_HELMRELEASE_KEY_INSTALL,
2835        );
2836    }
2837
2838    #[test]
2839    fn flux_helmrelease_key_install_pins_canonical_install_string() {
2840        // Bridge-arm pin: the lifted [`FLUX_HELMRELEASE_KEY_INSTALL`]
2841        // constant resolves to the canonical `"install"` string today,
2842        // and the rendered Flux v2 `HelmRelease` per-CR install-path
2843        // phase sub-block-header must spell it out verbatim. Pin the
2844        // literal here (peer with the sibling
2845        // [`flux_helmrelease_key_remediation_pins_canonical_remediation_string`]-shape
2846        // canonical-default arm on the sibling per-CR sub-container-
2847        // axis-key surface + the sibling
2848        // [`flux_helmrelease_key_retries_pins_canonical_retries_string`]-shape
2849        // canonical-default arm on the sibling per-CR leaf-scalar-key
2850        // surface) so a future rebrand of the lifted constant (Flux v3
2851        // rename like `initialize` / `apply` / `create` / `first-run` —
2852        // upstream Flux v3 roadmap candidates that would land the same
2853        // per-CR first-time chart apply phase semantics under a
2854        // different parent-container-axis-key) surfaces here as a
2855        // coordinated edit-point.
2856        assert_eq!(FLUX_HELMRELEASE_KEY_INSTALL, "install");
2857    }
2858
2859    #[test]
2860    fn flux_helmrelease_key_upgrade_re_export_points_at_caixa_core_canonical() {
2861        // The renderer's `pub use caixa_core::FLUX_HELMRELEASE_KEY_UPGRADE`
2862        // is the single source of truth for the Flux v2 per-CR upgrade-
2863        // path helm-action-phase discriminator parent-container-axis-key
2864        // baked into the `upgrade:` sub-block-header line of the
2865        // [`cluster_bundle`] `helmrelease.yaml` format-string template
2866        // (threading the same `&'static str` through the new
2867        // `{upgrade_key}` named-arg interpolation) plus the one test-
2868        // fixture navigation site in `mod tests` that probes the
2869        // rendered document at `.get(FLUX_HELMRELEASE_KEY_UPGRADE)`. Pin
2870        // the equality (and the static-data identity, peer with the
2871        // sibling
2872        // [`flux_helmrelease_key_install_re_export_points_at_caixa_core_canonical`]
2873        // pin on the peer install-path phase-discriminator half of the
2874        // same per-CR helm-action-phase discriminator parent-container-
2875        // axis-key pair) so any local re-introduction of a sibling
2876        // `pub const FLUX_HELMRELEASE_KEY_UPGRADE: &str = "…"` is a
2877        // build-time test failure naming the offending drift, not a
2878        // silent apply-time symptom (a stripped whole-upgrade-path per-
2879        // CR phase block letting the helm-controller fall back to the
2880        // Flux v2 upstream defaults for the whole upgrade-path phase
2881        // surface, silently dropping the substrate's
2882        // `remediateLastFailure: true` toggle + the per-CR retry-cap
2883        // ceiling from every per-version chart re-apply).
2884        caixa_core::assert_str_reexport_identity(
2885            "FLUX_HELMRELEASE_KEY_UPGRADE",
2886            FLUX_HELMRELEASE_KEY_UPGRADE,
2887            caixa_core::FLUX_HELMRELEASE_KEY_UPGRADE,
2888        );
2889    }
2890
2891    #[test]
2892    fn flux_helmrelease_key_upgrade_pins_canonical_upgrade_string() {
2893        // Bridge-arm pin: the lifted [`FLUX_HELMRELEASE_KEY_UPGRADE`]
2894        // constant resolves to the canonical `"upgrade"` string today,
2895        // and the rendered Flux v2 `HelmRelease` per-CR upgrade-path
2896        // phase sub-block-header must spell it out verbatim. Pin the
2897        // literal here (peer with the sibling
2898        // [`flux_helmrelease_key_install_pins_canonical_install_string`]-shape
2899        // canonical-default arm on the peer per-CR install-path phase-
2900        // discriminator surface) so a future rebrand of the lifted
2901        // constant (Flux v3 rename like `reapply` / `reconcile` /
2902        // `update` / `promote` — upstream Flux v3 roadmap candidates
2903        // that would land the same per-CR per-version chart re-apply
2904        // phase semantics under a different parent-container-axis-key)
2905        // surfaces here as a coordinated edit-point.
2906        assert_eq!(FLUX_HELMRELEASE_KEY_UPGRADE, "upgrade");
2907    }
2908
2909    #[test]
2910    fn flux_helmrelease_key_retries_pins_canonical_retries_string() {
2911        // Bridge-arm pin: the lifted [`FLUX_HELMRELEASE_KEY_RETRIES`]
2912        // constant resolves to the canonical `"retries"` string today,
2913        // and both rendered Flux v2 `HelmRelease` per-path retry-cap
2914        // leaf sub-block headers must spell it out verbatim. Pin the
2915        // literal here (peer with the sibling
2916        // [`flux_key_source_ref_pins_canonical_source_ref_string`]-shape
2917        // canonical-default arm on the sibling per-CR container-axis-key
2918        // surface) so a future rebrand of the lifted constant (Flux v3
2919        // rename like `attempts` / `maxRetries` / `retryCount` — the
2920        // upstream Gateway-API-side `spec.rules[].retry.attempts` leaf
2921        // already uses `attempts` on the sibling `GATEWAY_API_KEY_ATTEMPTS`
2922        // axis, an independent CRD group's evolution the two `pub const`
2923        // declarations stay sibling constants against) surfaces here as
2924        // a coordinated edit-point.
2925        assert_eq!(FLUX_HELMRELEASE_KEY_RETRIES, "retries");
2926    }
2927
2928    #[test]
2929    fn cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default() {
2930        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
2931        // document's `spec.install.remediation.retries` scalar must
2932        // resolve to the lifted
2933        // [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] verbatim.
2934        // Before the lift the axis carried an inline `retries: 3`
2935        // scalar-value literal at the sole production-code call site
2936        // (the install-path `install.remediation.retries` position of
2937        // the [`cluster_bundle`] `helmrelease.yaml` format-string
2938        // template); a future substrate-side retry-ceiling migration on
2939        // the canonical
2940        // [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]
2941        // declaration that failed to reach this emit site would
2942        // silently split the substrate's canonical retry-ceiling
2943        // between the operator-facing canonical default and the per-
2944        // caixa `helmrelease.yaml` install-path retry cap the helm-
2945        // controller consumes at first-time chart apply time. Pin the
2946        // identity here so a regression that re-introduces an inline
2947        // literal at the emit site surfaces at build time on this
2948        // test's failure. Peer to the sibling
2949        // [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
2950        // pin on the upgrade-path retry-cap sibling axis — that test
2951        // pins the rendered upgrade-path scalar agrees with the lifted
2952        // default, this test pins the rendered install-path scalar
2953        // agrees with the same.
2954        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
2955        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
2956        let hr = files
2957            .iter()
2958            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
2959            .expect("helmrelease.yaml present");
2960        let parsed: serde_yaml::Value =
2961            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
2962        let install_retries = parsed
2963            .get(KUBE_KEY_SPEC)
2964            .and_then(|s| s.get(FLUX_HELMRELEASE_KEY_INSTALL))
2965            .and_then(|i| i.get(FLUX_HELMRELEASE_KEY_REMEDIATION))
2966            .and_then(|r| r.get(FLUX_HELMRELEASE_KEY_RETRIES))
2967            .and_then(|v| v.as_u64())
2968            .expect(
2969                "spec.install.remediation.retries scalar present; drift on \
2970                 this axis silently splits the substrate's canonical retry-\
2971                 ceiling between the install-path first-time chart apply and \
2972                 the canonical `FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`",
2973            );
2974        assert_eq!(
2975            install_retries,
2976            u64::from(FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT),
2977            "spec.install.remediation.retries must carry the lifted \
2978             `FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT` scalar — \
2979             drift here silently splits the substrate's canonical retry-\
2980             ceiling between the operator-facing canonical default and \
2981             the install-path retry cap the Flux v2 helm-controller \
2982             consumes at first-time chart apply time"
2983        );
2984    }
2985
2986    #[test]
2987    fn cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default() {
2988        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
2989        // document's `spec.upgrade.remediation.retries` scalar must
2990        // resolve to the lifted
2991        // [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] verbatim.
2992        // Before the lift the axis carried a second inline `retries: 3`
2993        // scalar-value literal at the sole production-code call site
2994        // (the upgrade-path `upgrade.remediation.retries` position of
2995        // the [`cluster_bundle`] `helmrelease.yaml` format-string
2996        // template, sibling to the install-path retry-cap the peer
2997        // [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
2998        // pin covers); a future substrate-side retry-ceiling migration
2999        // on the canonical
3000        // [`caixa_core::FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`]
3001        // declaration that failed to reach this emit site would
3002        // silently split the substrate's canonical retry-ceiling
3003        // between the operator-facing canonical default and the per-
3004        // caixa `helmrelease.yaml` upgrade-path retry cap the helm-
3005        // controller consumes on every subsequent per-version chart re-
3006        // apply the same `HelmRelease` CR gates. Pin the identity here
3007        // so a regression that re-introduces an inline literal at the
3008        // emit site surfaces at build time on this test's failure. Peer
3009        // to the sibling
3010        // [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
3011        // pin on the install-path retry-cap sibling axis — closing the
3012        // per-path retry-cap sweep the caixa-core lift established.
3013        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3014        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3015        let hr = files
3016            .iter()
3017            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
3018            .expect("helmrelease.yaml present");
3019        let parsed: serde_yaml::Value =
3020            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
3021        let upgrade_retries = parsed
3022            .get(KUBE_KEY_SPEC)
3023            .and_then(|s| s.get(FLUX_HELMRELEASE_KEY_UPGRADE))
3024            .and_then(|u| u.get(FLUX_HELMRELEASE_KEY_REMEDIATION))
3025            .and_then(|r| r.get(FLUX_HELMRELEASE_KEY_RETRIES))
3026            .and_then(|v| v.as_u64())
3027            .expect(
3028                "spec.upgrade.remediation.retries scalar present; drift on \
3029                 this axis silently splits the substrate's canonical retry-\
3030                 ceiling between the upgrade-path per-version chart re-apply \
3031                 and the canonical `FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`",
3032            );
3033        assert_eq!(
3034            upgrade_retries,
3035            u64::from(FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT),
3036            "spec.upgrade.remediation.retries must carry the lifted \
3037             `FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT` scalar — \
3038             drift here silently splits the substrate's canonical retry-\
3039             ceiling between the operator-facing canonical default and \
3040             the upgrade-path retry cap the Flux v2 helm-controller \
3041             consumes on every subsequent per-caixa-version chart re-apply"
3042        );
3043    }
3044
3045    #[test]
3046    fn cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true() {
3047        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
3048        // document's `spec.upgrade.remediation.remediateLastFailure`
3049        // upgrade-path-only per-CR remediation-toggle leaf-scalar-key must
3050        // resolve to `true` verbatim under the lifted
3051        // [`FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] leaf-key. Before
3052        // the lift the axis carried an inline `remediateLastFailure: true`
3053        // leaf-scalar-key literal at the sole production-code call site
3054        // (the upgrade-path `upgrade.remediation.remediateLastFailure`
3055        // position of the [`cluster_bundle`] `helmrelease.yaml` format-
3056        // string template, sibling to the upgrade-path retry-cap the peer
3057        // [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
3058        // pin covers); a future substrate-side rebrand on the canonical
3059        // [`caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`]
3060        // declaration that failed to reach this emit site would silently
3061        // strip the substrate's chosen post-retry-exhaustion rollback
3062        // semantic from every emitted per-caixa `HelmRelease` document —
3063        // the Flux v2 helm-controller would then leave every terminally-
3064        // failed upgrade in the failed state without rolling back to the
3065        // prior last-known-good release the substrate's "no chart apply
3066        // leaves a per-caixa CR in a stalled, unremediated state"
3067        // MESH-COMPOSITION.md §V guarantee mandates. Pin the identity
3068        // here so a regression that re-introduces an inline literal at
3069        // the emit site — or a rebrand on the canonical const that fails
3070        // to reach the emit site — surfaces at build time on this test's
3071        // failure. Peer to the sibling
3072        // [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
3073        // pin on the upgrade-path retry-cap sibling axis — closes the
3074        // `spec.upgrade.remediation.{retries, remediateLastFailure}` leaf-
3075        // scalar-key pair the substrate seeds under the upgrade-path per-
3076        // CR remediation sub-container.
3077        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3078        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3079        let hr = files
3080            .iter()
3081            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
3082            .expect("helmrelease.yaml present");
3083        let parsed: serde_yaml::Value =
3084            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
3085        let remediate_last_failure = parsed
3086            .get(KUBE_KEY_SPEC)
3087            .and_then(|s| s.get(FLUX_HELMRELEASE_KEY_UPGRADE))
3088            .and_then(|u| u.get(FLUX_HELMRELEASE_KEY_REMEDIATION))
3089            .and_then(|r| r.get(FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE))
3090            .and_then(|v| v.as_bool())
3091            .expect(
3092                "spec.upgrade.remediation.remediateLastFailure boolean scalar \
3093                 present; drift on this axis silently drops the substrate's \
3094                 chosen post-retry-exhaustion rollback semantic from every \
3095                 emitted per-caixa `HelmRelease` document, leaving every \
3096                 terminally-failed upgrade in the failed state without \
3097                 rolling back to the prior last-known-good release",
3098            );
3099        assert_eq!(
3100            remediate_last_failure, FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT,
3101            "spec.upgrade.remediation.remediateLastFailure must carry the \
3102             lifted `FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT` \
3103             scalar — drift silently splits the substrate's canonical \
3104             post-retry-exhaustion rollback semantic between the operator-\
3105             facing canonical default and the per-caixa `HelmRelease` \
3106             document's per-CR upgrade-path remediation-toggle the Flux \
3107             v2 helm-controller's per-CR upgrade-path remediation loop \
3108             keys off to trigger the prior-release rollback pipeline once \
3109             the paired retry-cap ceiling has been exhausted, and every \
3110             terminally-failed per-caixa upgrade sits in the failed state \
3111             indefinitely with no diagnostic naming the remediation-\
3112             toggle-drift root cause"
3113        );
3114    }
3115
3116    #[test]
3117    fn flux_helmrelease_key_remediate_last_failure_re_export_points_at_caixa_core_canonical() {
3118        // The renderer's `FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE` was
3119        // lifted from the production-code inline `remediateLastFailure`
3120        // literal at the sole `cluster_bundle` `helmrelease.yaml` format-
3121        // string template's upgrade-path per-CR remediation-toggle leaf-
3122        // scalar-key emit site + the test-fixture navigation site the
3123        // sibling
3124        // [`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
3125        // pin opens onto the rendered document, to a re-export of
3126        // [`caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE`] so
3127        // the canonical Flux v2 per-CR upgrade-path per-CR remediation-
3128        // toggle leaf-scalar-key lives in exactly one place across every
3129        // caixa renderer. Pin the equality + static-data identity here
3130        // so any local re-introduction of a sibling
3131        // `pub const FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE: &str = "…"`
3132        // at this crate (the canonical drift footgun where a sibling
3133        // local `pub const` could happen to carry the same string at the
3134        // source while pointing at a different `&'static` allocation) is
3135        // a build-time test failure naming the offending drift. Peer to
3136        // [`flux_helmrelease_key_retries_re_export_points_at_caixa_core_canonical`]
3137        // on the sibling per-CR retry-cap leaf-scalar-key re-export axis.
3138        caixa_core::assert_str_reexport_identity(
3139            "FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE",
3140            FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE,
3141            caixa_core::FLUX_HELMRELEASE_KEY_REMEDIATE_LAST_FAILURE,
3142        );
3143    }
3144
3145    #[test]
3146    fn flux_helmrelease_remediate_last_failure_default_re_export_matches_caixa_core_canonical_value()
3147     {
3148        // The renderer's `FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`
3149        // was lifted from the production-code inline `true` scalar-value
3150        // literal at the sole `cluster_bundle` `helmrelease.yaml` format-
3151        // string template's per-CR upgrade-path remediation-toggle scalar-
3152        // value emit site (the `remediateLastFailure: true` leaf inside
3153        // the per-CR `spec.upgrade.remediation` sub-block) + the test-
3154        // fixture navigation site the sibling
3155        // [`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
3156        // pin's `assert!(remediate_last_failure)` predicate opened onto
3157        // the rendered document, to a re-export of
3158        // [`caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT`]
3159        // so the canonical Flux v2 per-CR upgrade-path per-CR remediation-
3160        // toggle scalar-value default lives in exactly one place across
3161        // every caixa renderer. Pin the value-equality here so any local
3162        // re-introduction of a sibling
3163        // `pub const FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT: bool = …`
3164        // at this crate (the canonical drift footgun where a sibling
3165        // local `pub const` could happen to carry a drifted value) is a
3166        // build-time test failure naming the offending drift. Peer to
3167        // [`flux_helmrelease_key_remediate_last_failure_re_export_points_at_caixa_core_canonical`]
3168        // on the paired leaf-scalar-key half of the same `(key, value)`
3169        // per-CR `spec.upgrade.remediation.remediateLastFailure` pair —
3170        // the key half's re-export identity lives at the sibling
3171        // `assert_str_reexport_identity` pin, the value half's canonical
3172        // `bool` seed lives here. Same shape as the sibling
3173        // [`flux_kustomization_prune_default_re_export_matches_caixa_core_canonical_value`]
3174        // pin on the peer per-`Kustomization`-CR garbage-collection-
3175        // toggle scalar-value default axis.
3176        assert_eq!(
3177            FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT,
3178            caixa_core::FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT,
3179            "FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT re-export \
3180             must resolve to the canonical caixa_core value — drift \
3181             silently splits the substrate's canonical post-retry-\
3182             exhaustion rollback default between the two `pub const` \
3183             declarations, and every rendered per-caixa `helmrelease.yaml` \
3184             would emit a different per-CR upgrade-path remediation-toggle \
3185             scalar than every downstream consumer (the future M4 \
3186             `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-\
3187             Aplicacao `HelmRelease` synthesis, the future admission-\
3188             webhook floor) reads at admit / reconcile time"
3189        );
3190        assert!(
3191            FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT,
3192            "FLUX_HELMRELEASE_REMEDIATE_LAST_FAILURE_DEFAULT must remain \
3193             `true` — the substrate's canonical \"no chart apply leaves \
3194             a per-caixa CR in a stalled, unremediated state\" \
3195             (MESH-COMPOSITION.md §V) guarantee requires every emitted \
3196             per-caixa `HelmRelease` opt into the helm-controller's per-CR \
3197             upgrade-path post-retry-exhaustion rollback pipeline; a drift \
3198             to `false` here silently leaves every terminally-failed \
3199             upgrade parked at `Ready: False` without rolling back to the \
3200             prior last-known-good release"
3201        );
3202    }
3203
3204    #[test]
3205    fn cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true() {
3206        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
3207        // document's `spec.install.createNamespace` install-path-only
3208        // per-CR namespace-seeder-toggle leaf-scalar-key must resolve to
3209        // `true` verbatim under the lifted
3210        // [`FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] leaf-key. Before the
3211        // lift the axis carried an inline `createNamespace: true` leaf-
3212        // scalar-key literal at the sole production-code call site (the
3213        // install-path `install.createNamespace` position of the
3214        // [`cluster_bundle`] `helmrelease.yaml` format-string template,
3215        // mirror-symmetric to the upgrade-path remediation-toggle the peer
3216        // [`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
3217        // pin covers); a future substrate-side rebrand on the canonical
3218        // [`caixa_core::FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`]
3219        // declaration that failed to reach this emit site would silently
3220        // strip the substrate's chosen first-apply namespace-seeder
3221        // semantic from every emitted per-caixa `HelmRelease` document —
3222        // the Flux v2 helm-controller would then refuse every first-time
3223        // per-caixa chart apply against a fresh cluster whose target
3224        // namespace has not been pre-provisioned by an out-of-band
3225        // pipeline the substrate's "no per-caixa Servico apply is blocked
3226        // on manual namespace preprovisioning" MESH-COMPOSITION.md §V
3227        // install-path-fluency guarantee mandates. Pin the identity here
3228        // so a regression that re-introduces an inline literal at the
3229        // emit site — or a rebrand on the canonical const that fails to
3230        // reach the emit site — surfaces at build time on this test's
3231        // failure. Peer to the sibling
3232        // [`cluster_bundle_helmrelease_upgrade_remediation_remediate_last_failure_pins_lifted_true`]
3233        // pin on the mirror-symmetric upgrade-path per-CR remediation-
3234        // toggle axis — closes the
3235        // `spec.{install.createNamespace, upgrade.remediation.remediateLastFailure}`
3236        // per-CR phase-specific toggle leaf-scalar-key pair the substrate
3237        // seeds under mirror-symmetric parent-container-axis-keys.
3238        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3239        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3240        let hr = files
3241            .iter()
3242            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
3243            .expect("helmrelease.yaml present");
3244        let parsed: serde_yaml::Value =
3245            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
3246        let create_namespace = parsed
3247            .get(KUBE_KEY_SPEC)
3248            .and_then(|s| s.get(FLUX_HELMRELEASE_KEY_INSTALL))
3249            .and_then(|i| i.get(FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE))
3250            .and_then(|v| v.as_bool())
3251            .expect(
3252                "spec.install.createNamespace boolean scalar present; drift \
3253                 on this axis silently drops the substrate's chosen first-\
3254                 apply namespace-seeder semantic from every emitted per-\
3255                 caixa `HelmRelease` document, leaving every first-time \
3256                 per-caixa chart apply against a fresh cluster refused by \
3257                 the helm-controller because the target namespace was not \
3258                 pre-provisioned by an out-of-band pipeline",
3259            );
3260        assert_eq!(
3261            create_namespace, FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT,
3262            "spec.install.createNamespace must carry the lifted \
3263             `FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT` scalar — drift \
3264             silently splits the substrate's canonical first-apply \
3265             namespace-seeder semantic between the operator-facing \
3266             canonical default and the per-caixa `HelmRelease` document's \
3267             per-CR install-path namespace-seeder-toggle the Flux v2 \
3268             helm-controller's per-CR install-path pre-apply loop keys \
3269             off to materialize the target namespace before the first \
3270             chart apply, and every first-time per-caixa Servico chart \
3271             apply against a fresh cluster is refused with no diagnostic \
3272             naming the seeder-toggle-drift root cause"
3273        );
3274    }
3275
3276    #[test]
3277    fn flux_helmrelease_key_create_namespace_re_export_points_at_caixa_core_canonical() {
3278        // The renderer's `FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE` was
3279        // lifted from the production-code inline `createNamespace`
3280        // literal at the sole `cluster_bundle` `helmrelease.yaml` format-
3281        // string template's install-path per-CR namespace-seeder-toggle
3282        // leaf-scalar-key emit site + the test-fixture navigation site
3283        // the sibling
3284        // [`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
3285        // pin opens onto the rendered document, to a re-export of
3286        // [`caixa_core::FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE`] so the
3287        // canonical Flux v2 per-CR install-path per-CR namespace-seeder-
3288        // toggle leaf-scalar-key lives in exactly one place across every
3289        // caixa renderer. Pin the equality + static-data identity here so
3290        // any local re-introduction of a sibling
3291        // `pub const FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE: &str = "…"`
3292        // at this crate (the canonical drift footgun where a sibling
3293        // local `pub const` could happen to carry the same string at the
3294        // source while pointing at a different `&'static` allocation) is
3295        // a build-time test failure naming the offending drift. Peer to
3296        // [`flux_helmrelease_key_remediate_last_failure_re_export_points_at_caixa_core_canonical`]
3297        // on the sibling mirror-symmetric upgrade-path-only per-CR
3298        // remediation-toggle leaf-scalar-key re-export axis.
3299        caixa_core::assert_str_reexport_identity(
3300            "FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE",
3301            FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE,
3302            caixa_core::FLUX_HELMRELEASE_KEY_CREATE_NAMESPACE,
3303        );
3304    }
3305
3306    #[test]
3307    fn flux_helmrelease_create_namespace_default_re_export_matches_caixa_core_canonical_value() {
3308        // The renderer's `FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT` was
3309        // lifted from the production-code inline `true` scalar-value
3310        // literal at the sole `cluster_bundle` `helmrelease.yaml` format-
3311        // string template's per-CR install-path namespace-seeder-toggle
3312        // scalar-value emit site (the `createNamespace: true` leaf inside
3313        // the per-CR `spec.install` sub-block) + the test-fixture
3314        // navigation site the sibling
3315        // [`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
3316        // pin's `assert!(create_namespace)` predicate opened onto the
3317        // rendered document, to a re-export of
3318        // [`caixa_core::FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT`] so
3319        // the canonical Flux v2 per-CR install-path per-CR namespace-
3320        // seeder-toggle scalar-value default lives in exactly one place
3321        // across every caixa renderer. Pin the value-equality here so any
3322        // local re-introduction of a sibling
3323        // `pub const FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT: bool = …`
3324        // at this crate (the canonical drift footgun where a sibling
3325        // local `pub const` could happen to carry a drifted value) is a
3326        // build-time test failure naming the offending drift. Peer to
3327        // [`flux_helmrelease_key_create_namespace_re_export_points_at_caixa_core_canonical`]
3328        // on the paired leaf-scalar-key half of the same `(key, value)`
3329        // per-CR `spec.install.createNamespace` pair — the key half's
3330        // re-export identity lives at the sibling
3331        // `assert_str_reexport_identity` pin, the value half's canonical
3332        // `bool` seed lives here. Same shape as the sibling
3333        // [`flux_helmrelease_remediate_last_failure_default_re_export_matches_caixa_core_canonical_value`]
3334        // pin on the peer mirror-symmetric upgrade-path-only per-CR
3335        // remediation-toggle scalar-value default axis.
3336        assert_eq!(
3337            FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT,
3338            caixa_core::FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT,
3339            "FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT re-export must \
3340             resolve to the canonical caixa_core value — drift silently \
3341             splits the substrate's canonical first-apply namespace-\
3342             seeder default between the two `pub const` declarations, \
3343             and every rendered per-caixa `helmrelease.yaml` would emit a \
3344             different per-CR install-path namespace-seeder-toggle scalar \
3345             than every downstream consumer (the future M4 \
3346             `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-\
3347             Aplicacao `HelmRelease` synthesis, the future admission-\
3348             webhook floor) reads at admit / reconcile time"
3349        );
3350        assert!(
3351            FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT,
3352            "FLUX_HELMRELEASE_CREATE_NAMESPACE_DEFAULT must remain `true` \
3353             — the substrate's canonical \"no per-caixa Servico apply is \
3354             blocked on manual namespace preprovisioning\" \
3355             (MESH-COMPOSITION.md §V install-path-fluency) guarantee \
3356             requires every emitted per-caixa `HelmRelease` opt into the \
3357             helm-controller's per-CR install-path pre-apply namespace-\
3358             seeder pipeline; a drift to `false` here silently refuses \
3359             every first-time per-caixa chart apply against a fresh \
3360             cluster whose target namespace has not been pre-provisioned \
3361             by an out-of-band pipeline"
3362        );
3363    }
3364
3365    #[test]
3366    fn cluster_bundle_lareira_enabled_default_re_export_matches_caixa_core_canonical_value() {
3367        // The renderer's `CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT` was
3368        // lifted from the production-code inline `true` scalar-value
3369        // literal at the sole `cluster_bundle` `helmrelease.yaml` format-
3370        // string template's per-values-overlay child-chart-enablement-
3371        // toggle scalar-value emit site (the `enabled: true` leaf inside
3372        // the per-`{library_name}` values-overlay wrap under
3373        // `spec.values`) + the test-fixture navigation site the sibling
3374        // `cluster_bundle_helmrelease_wrap_key_pins_canonical_pleme_computeunit_string`
3375        // pin's `Some(true)` `.and_then(|v| v.as_bool())` predicate
3376        // opened onto the rendered document, to a re-export of
3377        // [`caixa_core::CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT`] so the
3378        // canonical substrate-side child-chart-enablement-toggle
3379        // scalar-value default lives in exactly one place across every
3380        // caixa renderer. Pin the value-equality here so any local
3381        // re-introduction of a sibling
3382        // `pub const CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT: bool = …`
3383        // at this crate (the canonical drift footgun where a sibling
3384        // local `pub const` could happen to carry a drifted value) is a
3385        // build-time test failure naming the offending drift. Peer to
3386        // `helm_values_key_enabled_re_export_points_at_caixa_core_canonical`
3387        // on the paired leaf-scalar-key half of the same
3388        // `(key, value)` per-values-overlay
3389        // `spec.values.<library>.enabled` pair — the key half's
3390        // re-export identity lives at the sibling
3391        // `assert_str_reexport_identity` pin, the value half's canonical
3392        // `bool` seed lives here. Same shape as the sibling
3393        // [`flux_helmrelease_create_namespace_default_re_export_matches_caixa_core_canonical_value`]
3394        // /
3395        // [`flux_helmrelease_remediate_last_failure_default_re_export_matches_caixa_core_canonical_value`]
3396        // /
3397        // [`flux_kustomization_prune_default_re_export_matches_caixa_core_canonical_value`]
3398        // pins on the peer canonical-Flux-v2-per-CR-substrate-default
3399        // re-export axes.
3400        assert_eq!(
3401            CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT,
3402            caixa_core::CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT,
3403            "CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT re-export must \
3404             resolve to the canonical caixa_core value — drift silently \
3405             splits the substrate's canonical force-on-under-composition \
3406             child-chart-enablement default between the two `pub const` \
3407             declarations, and every rendered per-caixa `helmrelease.yaml` \
3408             would emit a different per-values-overlay child-chart-\
3409             enablement toggle than every downstream consumer (the future \
3410             M4 `mesh.pleme.io/v1alpha1/Aplicacao` CR materializer's per-\
3411             Aplicacao `HelmRelease` synthesis) reads at admit / reconcile \
3412             time"
3413        );
3414        assert!(
3415            CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT,
3416            "CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT must remain `true` — \
3417             the `cluster_bundle` composition path is the substrate-side \
3418             opt-in path where the operator has already asserted per-caixa \
3419             cluster-scoped ownership by materializing a per-caixa \
3420             GitRepository + HelmRelease + Kustomization trio, so the \
3421             overlay must force the child chart on by seeding \
3422             `enabled: true` under the `values.<library>` wrap; a drift to \
3423             `false` here silently no-ops every per-caixa lareira child \
3424             chart at the per-cluster `HelmRelease` apply step, leaving \
3425             the paired standalone-chart-side `enabled: false` per-chart \
3426             default un-overridden"
3427        );
3428    }
3429
3430    #[test]
3431    fn cluster_bundle_kustomization_prune_pins_lifted_true() {
3432        // Fail-before-pass-after pin: the rendered `kustomization.yaml`
3433        // document's `spec.prune` per-CR garbage-collection-toggle leaf-
3434        // scalar-key must resolve to `true` verbatim under the lifted
3435        // [`FLUX_KUSTOMIZATION_KEY_PRUNE`] leaf-key. Before the lift the
3436        // axis carried an inline `prune: true` leaf-scalar-key literal
3437        // at the sole production-code call site (the top-level `spec`
3438        // position of the [`cluster_bundle`] `kustomization.yaml`
3439        // format-string template, mirror-symmetric to the per-caixa
3440        // `HelmRelease` CR install-path-only namespace-seeder-toggle the
3441        // peer
3442        // [`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
3443        // pin covers on the co-resident per-caixa `HelmRelease` CR); a
3444        // future substrate-side rebrand on the canonical
3445        // [`caixa_core::FLUX_KUSTOMIZATION_KEY_PRUNE`] declaration that
3446        // failed to reach this emit site would silently strip the
3447        // substrate's chosen sweep-what-you-removed semantic from every
3448        // emitted per-caixa `Kustomization` document — the Flux v2
3449        // kustomize-controller would then leave every per-caixa
3450        // resource the source manifest set previously reconciled but no
3451        // longer carries dangling in the cluster the substrate's "the
3452        // cluster's per-caixa live state converges to the caixa's
3453        // tatara-lisp source-of-truth on every reconcile — resources
3454        // the source no longer carries are swept by the kustomize-
3455        // controller, not left dangling" CAIXA-SDLC.md §V author-to-
3456        // live-convergence guarantee mandates. Pin the identity here so
3457        // a regression that re-introduces an inline literal at the emit
3458        // site — or a rebrand on the canonical const that fails to
3459        // reach the emit site — surfaces at build time on this test's
3460        // failure. Peer to the sibling
3461        // [`cluster_bundle_helmrelease_install_create_namespace_pins_lifted_true`]
3462        // pin on the co-resident per-`HelmRelease`-CR install-path per-
3463        // CR namespace-seeder-toggle axis — extends the per-CR-toggle
3464        // leaf-scalar-key discipline from the co-resident per-
3465        // `HelmRelease`-CR spec surface onto the co-resident per-
3466        // `Kustomization`-CR spec surface at the mirror-symmetric top-
3467        // level `spec.prune` position.
3468        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3469        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3470        let ks = files
3471            .iter()
3472            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
3473            .expect("kustomization.yaml present");
3474        let parsed: serde_yaml::Value =
3475            serde_yaml::from_str(&ks.contents).expect("kustomization.yaml parses as YAML");
3476        let prune = parsed
3477            .get(KUBE_KEY_SPEC)
3478            .and_then(|s| s.get(FLUX_KUSTOMIZATION_KEY_PRUNE))
3479            .and_then(|v| v.as_bool())
3480            .expect(
3481                "spec.prune boolean scalar present; drift on this axis \
3482                 silently drops the substrate's chosen sweep-what-you-\
3483                 removed semantic from every emitted per-caixa \
3484                 `Kustomization` document, leaving per-caixa resources \
3485                 the source manifest set previously reconciled but no \
3486                 longer carries dangling in the cluster",
3487            );
3488        assert_eq!(
3489            prune, FLUX_KUSTOMIZATION_PRUNE_DEFAULT,
3490            "spec.prune must carry the lifted \
3491             `FLUX_KUSTOMIZATION_PRUNE_DEFAULT` scalar — drift silently \
3492             splits the substrate's canonical sweep-what-you-removed \
3493             semantic between the operator-facing canonical default and \
3494             the per-caixa `Kustomization` document's per-CR garbage-\
3495             collection-toggle the Flux v2 kustomize-controller's per-CR \
3496             reconcile loop keys off to garbage-collect per-caixa resources \
3497             removed from the source manifest set between reconciles, and \
3498             every per-caixa `Kustomization` reconcile leaves orphaned \
3499             resources dangling in the cluster with no diagnostic naming \
3500             the toggle-drift root cause"
3501        );
3502    }
3503
3504    #[test]
3505    fn flux_kustomization_prune_default_re_export_matches_caixa_core_canonical_value() {
3506        // The renderer's `FLUX_KUSTOMIZATION_PRUNE_DEFAULT` was lifted
3507        // from the production-code inline `true` scalar-value literal at
3508        // the sole `cluster_bundle` `kustomization.yaml` format-string
3509        // template's per-CR garbage-collection-toggle scalar-value emit
3510        // site (the `prune: true` leaf inside the top-level `spec`
3511        // position) + the test-fixture navigation site the sibling
3512        // [`cluster_bundle_kustomization_prune_pins_lifted_true`] pin's
3513        // `assert!(prune)` predicate opened onto the rendered document,
3514        // to a re-export of [`caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT`]
3515        // so the canonical Flux v2 per-CR garbage-collection-toggle
3516        // scalar-value default lives in exactly one place across every
3517        // caixa renderer. Pin the value-equality here so any local re-
3518        // introduction of a sibling
3519        // `pub const FLUX_KUSTOMIZATION_PRUNE_DEFAULT: bool = …` at this
3520        // crate (the canonical drift footgun where a sibling local
3521        // `pub const` could happen to carry a drifted value) is a build-
3522        // time test failure naming the offending drift. Peer to
3523        // [`flux_kustomization_key_prune_re_export_points_at_caixa_core_canonical`]
3524        // on the paired leaf-scalar-key half of the same `(key, value)`
3525        // per-CR `spec.prune` pair — the key half's re-export identity
3526        // lives at the sibling `assert_str_reexport_identity` pin, the
3527        // value half's canonical `bool` seed lives here. Same shape as
3528        // the sibling
3529        // [`cluster_bundle_helmrelease_install_remediation_retries_pins_lifted_default`]
3530        // / [`cluster_bundle_helmrelease_upgrade_remediation_retries_pins_lifted_default`]
3531        // pins on the peer per-CR HelmRelease remediation retry-cap
3532        // scalar-value default axis — that default names the per-path
3533        // per-CR remediation retry ceiling, and this default names
3534        // whether the per-CR reconcile loop sweeps orphaned resources
3535        // at all.
3536        assert_eq!(
3537            FLUX_KUSTOMIZATION_PRUNE_DEFAULT,
3538            caixa_core::FLUX_KUSTOMIZATION_PRUNE_DEFAULT,
3539            "FLUX_KUSTOMIZATION_PRUNE_DEFAULT re-export must resolve to \
3540             the canonical caixa_core value — drift silently splits the \
3541             substrate's canonical sweep-what-you-removed default \
3542             between the two `pub const` declarations, and every rendered \
3543             per-caixa `kustomization.yaml` would emit a different \
3544             per-CR garbage-collection-toggle scalar than every downstream \
3545             consumer (the future M4 `mesh.pleme.io/v1alpha1/Aplicacao` \
3546             CR materializer's per-Aplicacao `Kustomization` synthesis, \
3547             the future admission-webhook floor) reads at admit / \
3548             reconcile time"
3549        );
3550        assert!(
3551            FLUX_KUSTOMIZATION_PRUNE_DEFAULT,
3552            "FLUX_KUSTOMIZATION_PRUNE_DEFAULT must remain `true` — the \
3553             substrate's canonical sweep-what-you-removed semantic \
3554             (CAIXA-SDLC.md §V author-to-live-convergence guarantee) \
3555             requires every emitted per-caixa `Kustomization` opt into \
3556             the kustomize-controller's per-CR resource-tracking \
3557             garbage-collection loop; a drift to `false` here silently \
3558             leaves orphaned resources dangling in every cluster the \
3559             substrate reconciles into"
3560        );
3561    }
3562
3563    #[test]
3564    fn flux_kustomization_key_prune_re_export_points_at_caixa_core_canonical() {
3565        // The renderer's `FLUX_KUSTOMIZATION_KEY_PRUNE` was lifted from
3566        // the production-code inline `prune` literal at the sole
3567        // `cluster_bundle` `kustomization.yaml` format-string template's
3568        // per-CR garbage-collection-toggle leaf-scalar-key emit site +
3569        // the test-fixture navigation site the sibling
3570        // [`cluster_bundle_kustomization_prune_pins_lifted_true`] pin
3571        // opens onto the rendered document, to a re-export of
3572        // [`caixa_core::FLUX_KUSTOMIZATION_KEY_PRUNE`] so the canonical
3573        // Flux v2 per-CR garbage-collection-toggle leaf-scalar-key lives
3574        // in exactly one place across every caixa renderer. Pin the
3575        // equality + static-data identity here so any local re-
3576        // introduction of a sibling
3577        // `pub const FLUX_KUSTOMIZATION_KEY_PRUNE: &str = "…"` at this
3578        // crate (the canonical drift footgun where a sibling local
3579        // `pub const` could happen to carry the same string at the
3580        // source while pointing at a different `&'static` allocation)
3581        // is a build-time test failure naming the offending drift. Peer
3582        // to
3583        // [`flux_helmrelease_key_create_namespace_re_export_points_at_caixa_core_canonical`]
3584        // on the sibling co-resident per-`HelmRelease`-CR install-path-
3585        // only per-CR namespace-seeder-toggle leaf-scalar-key re-export
3586        // axis.
3587        caixa_core::assert_str_reexport_identity(
3588            "FLUX_KUSTOMIZATION_KEY_PRUNE",
3589            FLUX_KUSTOMIZATION_KEY_PRUNE,
3590            caixa_core::FLUX_KUSTOMIZATION_KEY_PRUNE,
3591        );
3592    }
3593
3594    #[test]
3595    fn cluster_bundle_kustomization_path_pins_lifted_sub_tree() {
3596        // Fail-before-pass-after pin: the rendered `kustomization.yaml`
3597        // document's `spec.path` per-CR source-sub-tree leaf-scalar-key
3598        // must resolve to the canonical per-cluster / per-caixa sub-
3599        // tree path seed verbatim under the lifted
3600        // [`FLUX_KUSTOMIZATION_KEY_PATH`] leaf-key. Before the lift the
3601        // axis carried an inline `path: ./clusters/<cluster>/services/<name>`
3602        // leaf-scalar-key literal at the sole production-code call
3603        // site (the top-level `spec` position of the [`cluster_bundle`]
3604        // `kustomization.yaml` format-string template, mirror-symmetric
3605        // to the co-resident per-`Kustomization`-CR garbage-collection-
3606        // toggle the sibling
3607        // [`cluster_bundle_kustomization_prune_pins_lifted_true`] pin
3608        // covers). A future substrate-side rebrand on the canonical
3609        // [`caixa_core::FLUX_KUSTOMIZATION_KEY_PATH`] declaration that
3610        // failed to reach this emit site would silently unbind every
3611        // emitted per-caixa `Kustomization` from its paired per-caixa
3612        // sub-tree of the pleme-io k8s repository — the Flux v2
3613        // kustomize-controller would then either reconcile the whole
3614        // GitRepository root (when the CR omits the leaf, the
3615        // controller defaults to `./`, pulling every unrelated cluster's
3616        // manifests through the wrong per-caixa `Kustomization`) or
3617        // refuse to reconcile at all (when the leaf points at a path
3618        // the GitRepository doesn't carry, the CR sits perpetually at
3619        // `BuildFailed`). Pin the identity here so a regression that
3620        // re-introduces an inline literal at the emit site — or a
3621        // rebrand on the canonical const that fails to reach the emit
3622        // site — surfaces at build time on this test's failure. Peer
3623        // to the sibling
3624        // [`cluster_bundle_kustomization_prune_pins_lifted_true`] pin
3625        // on the co-resident per-`Kustomization`-CR garbage-collection-
3626        // toggle axis — extends the per-`Kustomization`-CR-spec leaf-
3627        // scalar-key discipline from the co-resident garbage-
3628        // collection-toggle onto the co-resident source-sub-tree
3629        // pointer at the mirror-symmetric top-level `spec.path`
3630        // position.
3631        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3632        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3633        let ks = files
3634            .iter()
3635            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
3636            .expect("kustomization.yaml present");
3637        let parsed: serde_yaml::Value =
3638            serde_yaml::from_str(&ks.contents).expect("kustomization.yaml parses as YAML");
3639        let path = parsed
3640            .get(KUBE_KEY_SPEC)
3641            .and_then(|s| s.get(FLUX_KUSTOMIZATION_KEY_PATH))
3642            .and_then(|v| v.as_str())
3643            .expect(
3644                "spec.path string scalar present; drift on this axis \
3645                 silently unbinds every per-caixa Kustomization from \
3646                 its paired per-caixa sub-tree of the pleme-io k8s \
3647                 repository, and the kustomize-controller either \
3648                 defaults to reconciling the GitRepository root or \
3649                 refuses to reconcile at all",
3650            );
3651        // Route the per-caixa `:nome` axis-projection through the
3652        // substrate-canonical [`Caixa::nome`] `&str`-return accessor
3653        // rather than the raw `&sample_caixa().nome` `&String`-borrow
3654        // of the underlying field, so a future rebrand of the
3655        // top-level [`Caixa`] `:nome` universal-axis storage (a
3656        // pre-parsed `CaixaName`-newtype cache the accessor could
3657        // materialize behind the same `&str` return contract, a
3658        // per-cluster `:placement`-scoped nome overlay the caixa-
3659        // operator reconciles ahead of dispatch) reaches this
3660        // fixture-navigation site through the one accessor edit at
3661        // the canonical `caixa-core` declaration rather than a
3662        // coordinated rewrite that includes this file too. Peer to
3663        // the sibling
3664        // [`cluster_bundle_kustomization_spec_path_uses_lifted_composer`]
3665        // pin below on the paired composer-equivalence test-fixture
3666        // navigation site — both halves of the `sample_caixa()`
3667        // per-`:nome` fixture-navigation axis now route through the
3668        // one typed dispatch on the substrate primitive.
3669        let expected = flux_kustomization_source_subtree(&opts.cluster, sample_caixa().nome());
3670        assert_eq!(
3671            path, expected,
3672            "spec.path must carry the substrate's canonical per-cluster \
3673             / per-caixa sub-tree seed — drift silently unbinds every \
3674             per-caixa Kustomization from its paired sub-tree of the \
3675             pleme-io k8s repository"
3676        );
3677    }
3678
3679    #[test]
3680    fn flux_kustomization_key_path_re_export_points_at_caixa_core_canonical() {
3681        // The renderer's `FLUX_KUSTOMIZATION_KEY_PATH` was lifted from
3682        // the production-code inline `path` literal at the sole
3683        // `cluster_bundle` `kustomization.yaml` format-string template's
3684        // per-CR source-sub-tree leaf-scalar-key emit site + the test-
3685        // fixture navigation site the sibling
3686        // [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`] pin
3687        // opens onto the rendered document, to a re-export of
3688        // [`caixa_core::FLUX_KUSTOMIZATION_KEY_PATH`] so the canonical
3689        // Flux v2 per-CR source-sub-tree leaf-scalar-key lives in
3690        // exactly one place across every caixa renderer. Pin the
3691        // equality + static-data identity here so any local re-
3692        // introduction of a sibling
3693        // `pub const FLUX_KUSTOMIZATION_KEY_PATH: &str = "…"` at this
3694        // crate (the canonical drift footgun where a sibling local
3695        // `pub const` could happen to carry the same string at the
3696        // source while pointing at a different `&'static` allocation)
3697        // is a build-time test failure naming the offending drift.
3698        // Peer to
3699        // [`flux_kustomization_key_prune_re_export_points_at_caixa_core_canonical`]
3700        // on the sibling co-resident per-`Kustomization`-CR garbage-
3701        // collection-toggle leaf-scalar-key re-export axis.
3702        caixa_core::assert_str_reexport_identity(
3703            "FLUX_KUSTOMIZATION_KEY_PATH",
3704            FLUX_KUSTOMIZATION_KEY_PATH,
3705            caixa_core::FLUX_KUSTOMIZATION_KEY_PATH,
3706        );
3707    }
3708
3709    #[test]
3710    fn flux_kustomization_source_subtree_re_export_matches_caixa_core_canonical_output() {
3711        // The renderer's `flux_kustomization_source_subtree` was lifted
3712        // from the verbatim inline
3713        // `format!("./clusters/{cluster}/services/{name}")` at the sole
3714        // `cluster_bundle` `kustomization.yaml` format-string production
3715        // emit site + a mirror-symmetric verbatim inline
3716        // `format!("./clusters/{cluster}/services/{name}", …)` at the
3717        // paired `cluster_bundle_kustomization_path_pins_lifted_sub_tree`
3718        // test-fixture navigation site, to a re-export of
3719        // [`caixa_core::flux_kustomization_source_subtree`]. Pin the
3720        // output-shape equality here on representative fixtures so any
3721        // local re-introduction of a sibling
3722        // `pub fn flux_kustomization_source_subtree(...)` shadow at this
3723        // crate (the canonical drift footgun where a sibling local
3724        // `pub fn` could happen to produce the same byte-shape at the
3725        // source while diverging on either axis of the composition) is
3726        // a build-time test failure naming the offending drift. Peer to
3727        // [`flux_kustomization_key_path_re_export_points_at_caixa_core_canonical`]
3728        // on the paired leaf-scalar-key half of the same `(key, value)`
3729        // per-CR `spec.path` pair — the key half's re-export identity
3730        // lives at the sibling `assert_str_reexport_identity` pin, the
3731        // value half's canonical composition lives here. Same shape as
3732        // the sibling composer re-export identity pins the
3733        // [`caixa_mesh::cilium_network_policy_name`] and
3734        // [`caixa_mesh::gateway_api_http_route_name`] re-exports carry
3735        // at their crate's `mod tests` — every composer re-export in
3736        // the substrate reaches the canonical `caixa-core` function
3737        // through one `pub use` and the test-side output-shape identity
3738        // pin closes the "sibling `pub fn` shadow" footgun by
3739        // construction.
3740        assert_eq!(
3741            flux_kustomization_source_subtree("rio", "hello-rio"),
3742            caixa_core::flux_kustomization_source_subtree("rio", "hello-rio"),
3743        );
3744        assert_eq!(
3745            flux_kustomization_source_subtree("rio", "hello-rio"),
3746            "./clusters/rio/services/hello-rio",
3747        );
3748        assert_eq!(
3749            flux_kustomization_source_subtree("paris", "cart"),
3750            caixa_core::flux_kustomization_source_subtree("paris", "cart"),
3751        );
3752    }
3753
3754    #[test]
3755    fn cluster_bundle_kustomization_spec_path_uses_lifted_composer() {
3756        // Composition pin: the `spec.path` scalar emitted by
3757        // `cluster_bundle` for every per-caixa `kustomization.yaml`
3758        // document must byte-equal the output of the lifted
3759        // [`flux_kustomization_source_subtree`] composer with the same
3760        // `(cluster, nome)` arguments — so a future refactor of the
3761        // composer's internals (per-cluster prefix rebrand, per-caixa
3762        // infix rebrand, multi-tenant scoping prefix) reaches the
3763        // renderer through the one function-pointer edit at the
3764        // canonical `caixa-core` declaration, and any rewrite of the
3765        // format-string template's `{path_key}: {source_subtree}` emit
3766        // site that desynchronizes from the composer fires here at
3767        // build-time rather than silently splitting the writer-side
3768        // sub-tree seed at emit time. Peer to
3769        // [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`]
3770        // above on the paired output-shape assertion — that pin locks
3771        // the emitted `spec.path` scalar against the composer's output;
3772        // this pin locks the equivalence to the composer with the
3773        // ClusterBundleOpts's `cluster` axis threaded through, so a
3774        // regression that pinned one axis at the emit site while
3775        // leaving the peer axis inline surfaces on either half.
3776        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3777        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3778        let ks = files
3779            .iter()
3780            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
3781            .expect("kustomization.yaml present");
3782        let parsed: serde_yaml::Value =
3783            serde_yaml::from_str(&ks.contents).expect("kustomization.yaml parses as YAML");
3784        let emitted = parsed
3785            .get(KUBE_KEY_SPEC)
3786            .and_then(|s| s.get(FLUX_KUSTOMIZATION_KEY_PATH))
3787            .and_then(|v| v.as_str())
3788            .expect("spec.path string scalar present")
3789            .to_owned();
3790        // Route the per-caixa `:nome` axis-projection through the
3791        // substrate-canonical [`Caixa::nome`] `&str`-return accessor
3792        // rather than the raw `&sample_caixa().nome` `&String`-borrow
3793        // of the underlying field — sibling to the peer
3794        // [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`]
3795        // pin's own accessor route at the paired output-shape
3796        // assertion site. Closes the last pair of unlifted raw
3797        // `sample_caixa().nome` field-access sites in the caixa-flux
3798        // test suite; the twin `(cluster, nome)`-argument-pair
3799        // `flux_kustomization_source_subtree` fixture-navigation half
3800        // of the per-caixa `:nome` axis now uniformly routes through
3801        // the substrate primitive.
3802        let composed = flux_kustomization_source_subtree(&opts.cluster, sample_caixa().nome());
3803        assert_eq!(
3804            emitted, composed,
3805            "spec.path emit must byte-equal the lifted \
3806             flux_kustomization_source_subtree composer's output — drift \
3807             at either half silently splits the per-cluster / per-caixa \
3808             sub-tree seed axis at emit time from the canonical composer"
3809        );
3810    }
3811
3812    #[test]
3813    fn sample_caixa_nome_accessor_byte_equals_raw_field() {
3814        // Byte-parity pin: [`Caixa::nome`]'s `&str`-return accessor
3815        // must project the same bytes as the raw `sample_caixa().nome`
3816        // `String`-field access on the shared per-test [`sample_caixa`]
3817        // fixture the caixa-flux test-suite's per-`cluster_bundle`
3818        // `spec.path` composer-equivalence pins
3819        // ([`cluster_bundle_kustomization_path_pins_lifted_sub_tree`],
3820        // [`cluster_bundle_kustomization_spec_path_uses_lifted_composer`])
3821        // navigate through. Guards the paired-site convergence that
3822        // just routed both fixture-navigation halves through the
3823        // accessor rather than the raw field: a future implementation
3824        // of [`Caixa::nome`] that returned a differently-bytewidth
3825        // projection (a cached `CaixaName` newtype's `Display` value,
3826        // an operator-side normalized ASCII-lowered projection) would
3827        // silently split the composer's fixture-navigation input from
3828        // the storage-side field the [`crate::cluster_bundle`]
3829        // production emit path still reads from at the peer
3830        // `format!(…, name = &caixa.nome, …)` production site (which
3831        // itself already reaches through [`Caixa::nome`]'s accessor
3832        // — see caixa-flux/src/lib.rs:2135) — this pin surfaces the
3833        // drift at build-time rather than at a downstream
3834        // `kubectl get kustomization` audit on the fleet.
3835        //
3836        // Same byte-parity-pin discipline the sibling caixa-crd
3837        // `round_trip_preserves_core_fields` test-side accessor
3838        // convergence (1a160cd) added to lock its own per-`Caixa`
3839        // scalar-accessor family against the raw field-access at the
3840        // paired serde round-trip fixture — extended here onto the
3841        // caixa-flux `sample_caixa()` fixture's per-`:nome`
3842        // scalar-accessor axis.
3843        let fixture = sample_caixa();
3844        assert_eq!(
3845            fixture.nome(),
3846            fixture.nome.as_str(),
3847            "Caixa::nome() must borrow the same bytes as the raw \
3848             `nome: String` field storage; any implementation drift \
3849             here silently splits every caixa-flux composer-fixture \
3850             navigation site that routes through the accessor from \
3851             the storage-side field the peer production emit path \
3852             still reads verbatim"
3853        );
3854    }
3855
3856    #[test]
3857    fn cluster_bundle_kustomization_timeout_pins_lifted_default() {
3858        // Fail-before-pass-after pin: the rendered `kustomization.yaml`
3859        // document's `spec.timeout` per-CR reconcile wall-clock cap
3860        // leaf-scalar-key must resolve to the canonical
3861        // [`DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] scalar-value verbatim
3862        // under the lifted [`FLUX_KUSTOMIZATION_KEY_TIMEOUT`] leaf-key.
3863        // Before the lift the axis carried an inline `timeout: 5m` leaf-
3864        // scalar literal at the sole production-code call site (the
3865        // top-level `spec` position of the [`cluster_bundle`]
3866        // `kustomization.yaml` format-string template, sibling to the
3867        // co-resident per-`Kustomization`-CR source-sub-tree pointer
3868        // the peer [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`]
3869        // pin covers). A future substrate-side rebrand on either half
3870        // of the canonical `(FLUX_KUSTOMIZATION_KEY_TIMEOUT,
3871        // DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT)` pair that failed to
3872        // reach this emit site would silently strip the substrate's
3873        // chosen reconcile-ceiling declaration from every emitted per-
3874        // caixa `Kustomization` document — the Flux v2 kustomize-
3875        // controller would then fall back to the upstream Flux v2
3876        // controller-side default cap (which the upstream project
3877        // ships tuned for the average upstream Flux-managed manifest
3878        // set, not the substrate's per-caixa idempotency-checkpoint
3879        // cadence the peer
3880        // [`FLUX_HELMRELEASE_REMEDIATION_RETRIES_DEFAULT`] retry-
3881        // ceiling and [`DEFAULT_FLUX_RECONCILE_INTERVAL`] reconcile-
3882        // poll cadence are jointly tuned against), letting a
3883        // persistently-failing per-caixa manifest apply consume
3884        // kustomize-controller reconcile-loop cycles past the
3885        // substrate's chosen ceiling with no field naming the timeout-
3886        // drift root cause. Pin the identity here so a regression that
3887        // re-introduces an inline literal at the emit site — or a
3888        // rebrand on either canonical const that fails to reach the
3889        // emit site — surfaces at build time on this test's failure.
3890        // Peer to the sibling
3891        // [`cluster_bundle_kustomization_path_pins_lifted_sub_tree`]
3892        // and [`cluster_bundle_kustomization_prune_pins_lifted_true`]
3893        // pins on the co-resident per-`Kustomization`-CR spec surface
3894        // axes — extends the per-`Kustomization`-CR-spec leaf-scalar-
3895        // key/scalar-value discipline from the co-resident source-
3896        // sub-tree pointer and garbage-collection-toggle onto the co-
3897        // resident reconcile wall-clock cap at the mirror-symmetric
3898        // top-level `spec.timeout` position.
3899        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
3900        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
3901        let ks = files
3902            .iter()
3903            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
3904            .expect("kustomization.yaml present");
3905        let parsed: serde_yaml::Value =
3906            serde_yaml::from_str(&ks.contents).expect("kustomization.yaml parses as YAML");
3907        let timeout = parsed
3908            .get(KUBE_KEY_SPEC)
3909            .and_then(|s| s.get(FLUX_KUSTOMIZATION_KEY_TIMEOUT))
3910            .and_then(|v| v.as_str())
3911            .expect(
3912                "spec.timeout string scalar present; drift on this axis \
3913                 silently strips the substrate's chosen reconcile-ceiling \
3914                 declaration from every emitted per-caixa `Kustomization` \
3915                 document, letting the kustomize-controller fall back to \
3916                 the upstream Flux v2 controller-side default cap",
3917            );
3918        assert_eq!(
3919            timeout, DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT,
3920            "spec.timeout must carry the substrate's canonical Flux v2 \
3921             per-`Kustomization`-CR reconcile wall-clock cap seed — drift \
3922             silently strips the substrate's chosen reconcile-ceiling \
3923             declaration from every emitted per-caixa `Kustomization` \
3924             document"
3925        );
3926    }
3927
3928    #[test]
3929    fn flux_kustomization_key_timeout_re_export_points_at_caixa_core_canonical() {
3930        // The renderer's `FLUX_KUSTOMIZATION_KEY_TIMEOUT` was lifted
3931        // from the production-code inline `timeout` literal at the
3932        // sole `cluster_bundle` `kustomization.yaml` format-string
3933        // template's per-CR reconcile wall-clock cap leaf-scalar-key
3934        // emit site + the test-fixture navigation site the sibling
3935        // [`cluster_bundle_kustomization_timeout_pins_lifted_default`]
3936        // pin opens onto the rendered document, to a re-export of
3937        // [`caixa_core::FLUX_KUSTOMIZATION_KEY_TIMEOUT`] so the
3938        // canonical Flux v2 per-CR reconcile wall-clock cap leaf-
3939        // scalar-key lives in exactly one place across every caixa
3940        // renderer. Pin the equality + static-data identity here so
3941        // any local re-introduction of a sibling
3942        // `pub const FLUX_KUSTOMIZATION_KEY_TIMEOUT: &str = "…"` at
3943        // this crate (the canonical drift footgun where a sibling
3944        // local `pub const` could happen to carry the same string at
3945        // the source while pointing at a different `&'static`
3946        // allocation) is a build-time test failure naming the
3947        // offending drift. Peer to
3948        // [`flux_kustomization_key_path_re_export_points_at_caixa_core_canonical`]
3949        // and
3950        // [`flux_kustomization_key_prune_re_export_points_at_caixa_core_canonical`]
3951        // on the sibling co-resident per-`Kustomization`-CR spec
3952        // surface re-export axes.
3953        caixa_core::assert_str_reexport_identity(
3954            "FLUX_KUSTOMIZATION_KEY_TIMEOUT",
3955            FLUX_KUSTOMIZATION_KEY_TIMEOUT,
3956            caixa_core::FLUX_KUSTOMIZATION_KEY_TIMEOUT,
3957        );
3958    }
3959
3960    #[test]
3961    fn default_flux_kustomization_timeout_re_export_points_at_caixa_core_canonical() {
3962        // The renderer's `DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT` was
3963        // lifted from the production-code inline `5m` scalar-value
3964        // literal at the sole `cluster_bundle` `kustomization.yaml`
3965        // format-string template's per-CR reconcile wall-clock cap
3966        // emit site, to a re-export of
3967        // [`caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT`] so the
3968        // canonical Flux v2 per-CR reconcile wall-clock cap default
3969        // scalar-value lives in exactly one place across every caixa
3970        // renderer. Pin the equality + static-data identity here so
3971        // any local re-introduction of a sibling
3972        // `pub const DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT: &str = "…"`
3973        // at this crate (the canonical drift footgun where a sibling
3974        // local `pub const` could happen to carry the same string at
3975        // the source while pointing at a different `&'static`
3976        // allocation) is a build-time test failure naming the
3977        // offending drift. Peer to
3978        // [`default_flux_reconcile_interval_re_export_points_at_caixa_core_canonical`]
3979        // on the sibling canonical-Flux-v2-per-CR-substrate-default-
3980        // scalar re-export axis.
3981        caixa_core::assert_str_reexport_identity(
3982            "DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT",
3983            DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT,
3984            caixa_core::DEFAULT_FLUX_KUSTOMIZATION_TIMEOUT,
3985        );
3986    }
3987
3988    #[test]
3989    fn kube_key_spec_re_export_points_at_caixa_core_canonical() {
3990        // The renderer's `KUBE_KEY_SPEC` was lifted from the
3991        // production-code inline `"spec"` literals at the two K8s-CR
3992        // top-level-spec-axis call sites (`programs_yaml_entry`'s
3993        // `computeunit_yaml.get("spec")` ComputeUnit-side spec read +
3994        // its matching `Error::MissingField("spec")` diagnostic;
3995        // `upsert_into_helmrelease_programs`'s `root.get_mut("spec")`
3996        // HelmRelease-side spec mutate + its matching
3997        // `Error::MissingField("spec")` diagnostic) to a re-export of
3998        // [`caixa_core::KUBE_KEY_SPEC`] so the canonical K8s-CR
3999        // top-level spec-axis string lives in exactly one place across
4000        // every caixa renderer. Pin the equality + static-data
4001        // identity here so any local re-introduction of a sibling
4002        // `pub const KUBE_KEY_SPEC: &str = "…"` (the canonical drift
4003        // footgun where a sibling local `pub const` could happen to
4004        // carry the same string at the source while pointing at a
4005        // different `&'static` allocation) is a build-time test
4006        // failure naming the offending drift. Peer to
4007        // [`default_namespace_re_export_points_at_caixa_core_canonical`]
4008        // on the sibling re-export axis +
4009        // `caixa_mesh::tests::kube_key_spec_re_export_points_at_caixa_core_canonical`
4010        // on the sibling renderer crate.
4011        caixa_core::assert_str_reexport_identity(
4012            "KUBE_KEY_SPEC",
4013            KUBE_KEY_SPEC,
4014            caixa_core::KUBE_KEY_SPEC,
4015        );
4016    }
4017
4018    #[test]
4019    fn kube_key_metadata_re_export_points_at_caixa_core_canonical() {
4020        // The renderer's `KUBE_KEY_METADATA` was lifted from the
4021        // production-code inline `"metadata"` literal at
4022        // `programs_yaml_entry`'s `computeunit_yaml.get("metadata")`
4023        // ComputeUnit-side metadata read + the drift-detection pin at
4024        // `cluster_bundle_kustomization_carries_flux_system_namespace_axes`'s
4025        // `parsed.get("metadata")` rendered-kustomization traversal, to a
4026        // re-export of [`caixa_core::KUBE_KEY_METADATA`] so the canonical
4027        // K8s-CR top-level metadata-axis string lives in exactly one
4028        // place across every caixa renderer. Pin the equality +
4029        // static-data identity here so any local re-introduction of a
4030        // sibling `pub const KUBE_KEY_METADATA: &str = "…"` (the
4031        // canonical drift footgun where a sibling local `pub const`
4032        // could happen to carry the same string at the source while
4033        // pointing at a different `&'static` allocation) is a build-time
4034        // test failure naming the offending drift. Peer to
4035        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`] on
4036        // the sibling K8s-CR top-level-spec-axis re-export +
4037        // `caixa_mesh::tests::kube_key_metadata_re_export_points_at_caixa_core_canonical`
4038        // on the sibling renderer crate.
4039        caixa_core::assert_str_reexport_identity(
4040            "KUBE_KEY_METADATA",
4041            KUBE_KEY_METADATA,
4042            caixa_core::KUBE_KEY_METADATA,
4043        );
4044    }
4045
4046    #[test]
4047    fn kube_key_kind_re_export_points_at_caixa_core_canonical() {
4048        // The renderer's `KUBE_KEY_KIND` was lifted from eleven inline
4049        // `"kind"` literals at the test-side K8s-CR top-level-kind-axis
4050        // retrieval calls that navigate the rendered `cluster_bundle`
4051        // multi-file sequence to isolate each per-`(GitRepository,
4052        // HelmRelease, Kustomization)` document's top-level-kind
4053        // discriminator plus its nested `spec.chart.spec.sourceRef.kind`
4054        // (helmrelease) / `spec.sourceRef.kind` (kustomization) /
4055        // `spec.healthChecks[].kind` (kustomization) drift-detection
4056        // pins, to a re-export of [`caixa_core::KUBE_KEY_KIND`] so the
4057        // canonical K8s-CR top-level kind-discriminator axis string
4058        // lives in exactly one place across every caixa renderer. Pin
4059        // the equality + static-data identity here so any local
4060        // re-introduction of a sibling `pub const KUBE_KEY_KIND: &str
4061        // = "…"` (the canonical drift footgun where a sibling local
4062        // `pub const` could happen to carry the same string at the
4063        // source while pointing at a different `&'static` allocation)
4064        // is a build-time test failure naming the offending drift, not
4065        // a silent apply-time symptom — the prior shape would have let
4066        // a typo on any one sibling `pub const` declaration silently
4067        // miss the per-CR kind retrieval so the drift-detection
4068        // `.get(KUBE_KEY_KIND).and_then(|n| n.as_str()) == Some(…)`
4069        // predicate the sibling `FLUX_KIND_*` re-export pins rest on
4070        // would compare against `None` under the trailing
4071        // `.expect("… present")` panic and mask the true sibling
4072        // `FLUX_KIND_*` axis drift. Peer to
4073        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`] +
4074        // [`kube_key_metadata_re_export_points_at_caixa_core_canonical`]
4075        // on the sibling K8s-CR top-level-spec / top-level-metadata
4076        // axis re-exports + `caixa_mesh::tests::kube_key_kind_re_export_points_at_caixa_core_canonical`
4077        // (615a13d) on the sibling renderer crate — completes the
4078        // per-K8s-CR top-level `(spec, metadata, kind)` axis re-export
4079        // triple every rendered Flux bundle document navigates.
4080        caixa_core::assert_str_reexport_identity(
4081            "KUBE_KEY_KIND",
4082            KUBE_KEY_KIND,
4083            caixa_core::KUBE_KEY_KIND,
4084        );
4085    }
4086
4087    #[test]
4088    fn kube_key_api_version_re_export_points_at_caixa_core_canonical() {
4089        // The renderer's `KUBE_KEY_API_VERSION` was lifted from four
4090        // inline `"apiVersion"` literals at the test-side K8s-CR
4091        // top-level-apiVersion-axis retrieval calls that navigate the
4092        // rendered `cluster_bundle` multi-file sequence to isolate each
4093        // per-`(GitRepository, HelmRelease, Kustomization)` document's
4094        // top-level-apiVersion axis plus the `kustomization.yaml`'s
4095        // nested `spec.healthChecks[].apiVersion` drift-detection pin,
4096        // to a re-export of [`caixa_core::KUBE_KEY_API_VERSION`] so the
4097        // canonical K8s-CR top-level apiVersion-axis string lives in
4098        // exactly one place across every caixa renderer. Pin the
4099        // equality + static-data identity here so any local
4100        // re-introduction of a sibling `pub const KUBE_KEY_API_VERSION:
4101        // &str = "…"` (the canonical drift footgun where a sibling
4102        // local `pub const` could happen to carry the same string at
4103        // the source while pointing at a different `&'static`
4104        // allocation) is a build-time test failure naming the offending
4105        // drift, not a silent apply-time symptom — the prior shape
4106        // would have let a typo on any one sibling `pub const`
4107        // declaration silently miss the per-CR apiVersion retrieval so
4108        // the drift-detection `.get(KUBE_KEY_API_VERSION).and_then(|n|
4109        // n.as_str()) == Some(…)` predicate the sibling
4110        // `FLUX_*_API_VERSION` re-export pins rest on would compare
4111        // against `None` under the trailing `.expect("… present")`
4112        // panic and mask the true sibling `FLUX_*_API_VERSION` axis
4113        // drift. Peer to
4114        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`] +
4115        // [`kube_key_metadata_re_export_points_at_caixa_core_canonical`]
4116        // + [`kube_key_kind_re_export_points_at_caixa_core_canonical`]
4117        // on the sibling K8s-CR top-level-spec / top-level-metadata /
4118        // top-level-kind axis re-exports — completes the per-K8s-CR
4119        // top-level `(apiVersion, kind, metadata, spec)` axis
4120        // re-export quartet every rendered Flux v2 bundle document
4121        // navigates.
4122        caixa_core::assert_str_reexport_identity(
4123            "KUBE_KEY_API_VERSION",
4124            KUBE_KEY_API_VERSION,
4125            caixa_core::KUBE_KEY_API_VERSION,
4126        );
4127    }
4128
4129    #[test]
4130    fn kube_key_namespace_re_export_points_at_caixa_core_canonical() {
4131        // The renderer's `KUBE_KEY_NAMESPACE` was lifted from five inline
4132        // `"namespace"` literals — the two production-code call sites in
4133        // `programs_yaml_entry` (the ComputeUnit YAML's
4134        // `metadata.namespace` retrieval that feeds the emitted
4135        // `programs:[]` entry's isomorphic `namespace:` field, and the
4136        // write-side entry-key emission the `lareira-fleet-programs`
4137        // schema keys the per-Servico namespace off) plus the three
4138        // test-side drift-detection call sites (the two
4139        // `programs_yaml_entry` round-trip pins asserting the emitted
4140        // entry's `namespace:` field spells `tatara-system` on the
4141        // metadata-carried path and [`DEFAULT_NAMESPACE`] on the
4142        // fallback path, and the `cluster_bundle_kustomization_carries_\
4143        // flux_system_namespace_axes` pin asserting the rendered
4144        // `kustomization.yaml` document's `metadata.namespace` axis
4145        // binds to the lifted [`DEFAULT_FLUX_SYSTEM_NAMESPACE`]) — to
4146        // a re-export of [`caixa_core::KUBE_KEY_NAMESPACE`] so the
4147        // canonical K8s-CR `metadata.namespace` axis string lives in
4148        // exactly one place across every caixa renderer. Pin the
4149        // equality + static-data identity here so any local
4150        // re-introduction of a sibling `pub const KUBE_KEY_NAMESPACE:
4151        // &str = "…"` (the canonical drift footgun where a sibling
4152        // local `pub const` could happen to carry the same string at
4153        // the source while pointing at a different `&'static`
4154        // allocation) is a build-time test failure naming the
4155        // offending drift, not a silent apply-time symptom — the prior
4156        // shape would have let a typo on any one sibling `pub const`
4157        // declaration silently miss the ComputeUnit's
4158        // `metadata.namespace` lookup and fall back to
4159        // [`DEFAULT_NAMESPACE`] even when the ComputeUnit YAML pinned
4160        // a distinct target namespace, or mask the sibling
4161        // [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] drift the
4162        // `kustomization.yaml`-side pin was meant to catch under the
4163        // `.expect("kustomization.yaml present")` panic on the missing
4164        // `.and_then` chain. Peer to
4165        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`] /
4166        // [`kube_key_metadata_re_export_points_at_caixa_core_canonical`]
4167        // / [`kube_key_kind_re_export_points_at_caixa_core_canonical`]
4168        // / [`kube_key_api_version_re_export_points_at_caixa_core_canonical`]
4169        // on the sibling K8s-CR top-level `(spec, metadata, kind,
4170        // apiVersion)` axis re-exports — extends the discipline the
4171        // top-level quartet establishes onto the canonical
4172        // `metadata.namespace` nested axis every rendered Flux v2
4173        // bundle document navigates.
4174        caixa_core::assert_str_reexport_identity(
4175            "KUBE_KEY_NAMESPACE",
4176            KUBE_KEY_NAMESPACE,
4177            caixa_core::KUBE_KEY_NAMESPACE,
4178        );
4179    }
4180
4181    #[test]
4182    fn fleet_programs_key_programs_re_export_points_at_caixa_core_canonical() {
4183        // The renderer's `FLEET_PROGRAMS_KEY_PROGRAMS` was lifted from
4184        // the two inline `"programs"` production-code call sites
4185        // (`upsert_into_helmrelease_programs` at
4186        // `values_map.entry(Value::String("programs".into()))` on the
4187        // aggregator-HelmRelease shape, `upsert_into_programs_yaml` at
4188        // `let programs_key = Value::String("programs".into())` on the
4189        // bare-values.yaml shape) — the two writer-side upsert paths
4190        // that walk `HelmRelease.spec.values.programs[]` /
4191        // top-level `programs[]` to match-by-name-and-replace-or-append.
4192        // Both now navigate through the same `&'static str` as every
4193        // peer consumer, re-exported to a re-export of
4194        // [`caixa_core::FLEET_PROGRAMS_KEY_PROGRAMS`] so the canonical
4195        // `lareira-fleet-programs` values-schema array key lives in
4196        // exactly one place across every caixa renderer + consumer.
4197        // Pin the equality + static-data identity here so any local
4198        // re-introduction of a sibling `pub const FLEET_PROGRAMS_KEY_PROGRAMS:
4199        // &str = "…"` (the canonical drift footgun where a sibling
4200        // local `pub const` could happen to carry the same string at
4201        // the source while pointing at a different `&'static`
4202        // allocation) is a build-time test failure naming the offending
4203        // drift, not a silent apply-time symptom — the prior shape
4204        // would have let a typo on any one sibling `pub const`
4205        // declaration silently emit an entry under one key while the
4206        // peer-side upsert probed a different key, and the aggregator's
4207        // `range .Values.programs` would then iterate an empty sequence
4208        // (every `ComputeUnit` CR silently vanishing from the cluster's
4209        // fleet). Peer to
4210        // [`kube_key_namespace_re_export_points_at_caixa_core_canonical`]
4211        // /
4212        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`] /
4213        // [`kube_key_metadata_re_export_points_at_caixa_core_canonical`]
4214        // /
4215        // [`kube_key_kind_re_export_points_at_caixa_core_canonical`] /
4216        // [`kube_key_api_version_re_export_points_at_caixa_core_canonical`]
4217        // on the sibling K8s-CR top-level axis re-exports — extends
4218        // the discipline the K8s-CR key re-export quintet establishes
4219        // onto the canonical fleet-programs schema top-level axis
4220        // (`programs:`) every rendered aggregator-HelmRelease /
4221        // bare-values.yaml document navigates.
4222        caixa_core::assert_str_reexport_identity(
4223            "FLEET_PROGRAMS_KEY_PROGRAMS",
4224            FLEET_PROGRAMS_KEY_PROGRAMS,
4225            caixa_core::FLEET_PROGRAMS_KEY_PROGRAMS,
4226        );
4227    }
4228
4229    #[test]
4230    fn fleet_programs_key_name_re_export_points_at_caixa_core_canonical() {
4231        // The renderer's `FLEET_PROGRAMS_KEY_NAME` was lifted from the
4232        // three inline `"name"` production-code call sites in
4233        // [`programs_yaml_entry`] (emit-side per-Servico entry.insert
4234        // seeded from `caixa.nome`), [`upsert_into_helmrelease_programs`]
4235        // (writer-side `new_entry.get("name")` / `slot.get("name")` +
4236        // `Error::MissingField("name")` triplet on the aggregator-
4237        // HelmRelease shape), and [`upsert_into_programs_yaml`] (writer-
4238        // side peer triplet on the bare-values.yaml shape) — every
4239        // fleet-programs per-entry name-axis read + write + missing-
4240        // field diagnostic across the two writer-side upsert paths and
4241        // the one emit-side entry builder now navigates through the
4242        // same `&'static str` re-exported to a re-export of
4243        // [`caixa_core::FLEET_PROGRAMS_KEY_NAME`] so the canonical
4244        // `lareira-fleet-programs` values-schema per-entry name-
4245        // discriminator key lives in exactly one place across every
4246        // caixa renderer + consumer. Pin the equality + static-data
4247        // identity here so any local re-introduction of a sibling
4248        // `pub const FLEET_PROGRAMS_KEY_NAME: &str = "…"` (the canonical
4249        // drift footgun where a sibling local `pub const` could happen
4250        // to carry the same string at the source while pointing at a
4251        // different `&'static` allocation) is a build-time test failure
4252        // naming the offending drift, not a silent apply-time symptom —
4253        // the prior shape would have let a typo on any one sibling
4254        // `pub const` declaration silently emit an entry under one key
4255        // while the peer-side upsert probed a different key, and the
4256        // aggregator's `range .Values.programs` would then iterate
4257        // entries whose per-entry name-axis the library chart's
4258        // `metadata.name` templating reads as empty (or match against
4259        // the wrong entry on upsert), collapsing every rendered
4260        // `ComputeUnit` CR at the aggregator's name-keyed reduce step.
4261        // Peer to
4262        // [`fleet_programs_key_programs_re_export_points_at_caixa_core_canonical`]
4263        // on the sibling fleet-programs top-level array-key re-export
4264        // + [`kube_key_namespace_re_export_points_at_caixa_core_canonical`]
4265        // / [`kube_key_spec_re_export_points_at_caixa_core_canonical`]
4266        // on the peer K8s-CR canonical-key re-export surfaces —
4267        // extends the discipline the K8s-CR key re-export quintet +
4268        // the sibling fleet-programs top-level array-key re-export
4269        // establish onto the canonical fleet-programs schema per-entry
4270        // name-discriminator axis.
4271        caixa_core::assert_str_reexport_identity(
4272            "FLEET_PROGRAMS_KEY_NAME",
4273            FLEET_PROGRAMS_KEY_NAME,
4274            caixa_core::FLEET_PROGRAMS_KEY_NAME,
4275        );
4276    }
4277
4278    #[test]
4279    fn computeunit_spec_key_module_re_export_points_at_caixa_core_canonical() {
4280        // The renderer's `COMPUTEUNIT_SPEC_KEY_MODULE` was lifted from
4281        // the four inline `"module"` test-side call sites in this
4282        // crate (`programs_yaml_entry_round_trips`'s per-entry
4283        // `entry.get("module")` present-check + its per-
4284        // `module.source` nested navigator, plus
4285        // `upsert_helmrelease_replaces_existing` /
4286        // `upsert_into_programs_yaml`'s per-`module.source` cross-
4287        // upsert readback navigators) — every per-Servico ComputeUnit
4288        // CRD `spec.module` sub-block readback across the four
4289        // drift-detection navigators now navigates through the same
4290        // `&'static str` re-exported to a re-export of
4291        // [`caixa_core::COMPUTEUNIT_SPEC_KEY_MODULE`]. Pin the
4292        // equality + static-data identity here so any local re-
4293        // introduction of a sibling `pub const COMPUTEUNIT_SPEC_KEY_MODULE:
4294        // &str = "…"` is a build-time test failure naming the
4295        // offending drift, not a silent apply-time symptom. Peer to
4296        // [`fleet_programs_key_programs_re_export_points_at_caixa_core_canonical`]
4297        // /
4298        // [`kube_key_spec_re_export_points_at_caixa_core_canonical`]
4299        // on the sibling fleet-programs / K8s-CR-key re-export
4300        // surfaces — extends the discipline the K8s-CR / fleet-
4301        // programs key re-export families establish onto the
4302        // substrate-side ComputeUnit-CRD per-`spec.*` sub-block axis.
4303        caixa_core::assert_str_reexport_identity(
4304            "COMPUTEUNIT_SPEC_KEY_MODULE",
4305            COMPUTEUNIT_SPEC_KEY_MODULE,
4306            caixa_core::COMPUTEUNIT_SPEC_KEY_MODULE,
4307        );
4308    }
4309
4310    #[test]
4311    fn computeunit_spec_key_trigger_re_export_points_at_caixa_core_canonical() {
4312        // Peer to
4313        // [`computeunit_spec_key_module_re_export_points_at_caixa_core_canonical`]
4314        // on the same ComputeUnit-CRD per-`spec.*` sub-block re-export
4315        // surface — pins the per-Servico invocation-shape sub-block
4316        // key's identity on the same trajectory.
4317        caixa_core::assert_str_reexport_identity(
4318            "COMPUTEUNIT_SPEC_KEY_TRIGGER",
4319            COMPUTEUNIT_SPEC_KEY_TRIGGER,
4320            caixa_core::COMPUTEUNIT_SPEC_KEY_TRIGGER,
4321        );
4322    }
4323
4324    #[test]
4325    fn computeunit_spec_key_capabilities_re_export_points_at_caixa_core_canonical() {
4326        // Peer to
4327        // [`computeunit_spec_key_module_re_export_points_at_caixa_core_canonical`]
4328        // and
4329        // [`computeunit_spec_key_trigger_re_export_points_at_caixa_core_canonical`]
4330        // on the same ComputeUnit-CRD per-`spec.*` sub-block re-export
4331        // surface — completes the substrate-side ComputeUnit-CRD
4332        // per-`spec.*` sub-block re-export triple in this crate on the
4333        // WASI-capability-token-list axis.
4334        caixa_core::assert_str_reexport_identity(
4335            "COMPUTEUNIT_SPEC_KEY_CAPABILITIES",
4336            COMPUTEUNIT_SPEC_KEY_CAPABILITIES,
4337            caixa_core::COMPUTEUNIT_SPEC_KEY_CAPABILITIES,
4338        );
4339    }
4340
4341    #[test]
4342    fn computeunit_module_key_source_re_export_points_at_caixa_core_canonical() {
4343        // The renderer's `COMPUTEUNIT_MODULE_KEY_SOURCE` was lifted
4344        // from the three inline `"source"` test-side call sites in
4345        // this crate — `programs_yaml_entry_round_trips`'s per-entry
4346        // `.get(COMPUTEUNIT_SPEC_KEY_MODULE).and_then(|m| m.get("source"))`
4347        // present-check + `upsert_replaces_existing_entry`'s per-
4348        // `arr[0].get(COMPUTEUNIT_SPEC_KEY_MODULE).get("source")`
4349        // cross-upsert readback + `upsert_helmrelease_inserts_under_spec_values_programs`'s
4350        // peer `HelmRelease`-wrapped `spec.values.programs[]` cross-
4351        // upsert readback. Every per-Servico ComputeUnit-CRD
4352        // `spec.module.source` leaf-scalar readback across the three
4353        // drift-detection navigators now navigates through the same
4354        // `&'static str` re-exported to a re-export of
4355        // [`caixa_core::COMPUTEUNIT_MODULE_KEY_SOURCE`]. Pin the
4356        // equality + static-data identity here so any local re-
4357        // introduction of a sibling `pub const COMPUTEUNIT_MODULE_KEY_SOURCE:
4358        // &str = "…"` is a build-time test failure naming the
4359        // offending drift, not a silent apply-time symptom. Peer to
4360        // [`computeunit_spec_key_module_re_export_points_at_caixa_core_canonical`]
4361        // on the same ComputeUnit-CRD family — extends the re-export-
4362        // identity gate one level deeper from the top-level `spec.*`
4363        // container-axis surface onto the nested `spec.module.*`
4364        // leaf-scalar-axis.
4365        caixa_core::assert_str_reexport_identity(
4366            "COMPUTEUNIT_MODULE_KEY_SOURCE",
4367            COMPUTEUNIT_MODULE_KEY_SOURCE,
4368            caixa_core::COMPUTEUNIT_MODULE_KEY_SOURCE,
4369        );
4370    }
4371
4372    #[test]
4373    fn programs_yaml_entry_round_trips() {
4374        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4375        assert_eq!(
4376            entry.get(FLEET_PROGRAMS_KEY_NAME).and_then(|n| n.as_str()),
4377            Some("hello-rio")
4378        );
4379        assert_eq!(
4380            entry.get(KUBE_KEY_NAMESPACE).and_then(|n| n.as_str()),
4381            Some(DEFAULT_NAMESPACE)
4382        );
4383        assert!(entry.get(COMPUTEUNIT_SPEC_KEY_MODULE).is_some());
4384        assert!(entry.get(COMPUTEUNIT_SPEC_KEY_TRIGGER).is_some());
4385        assert!(entry.get(COMPUTEUNIT_SPEC_KEY_CAPABILITIES).is_some());
4386        assert!(
4387            entry
4388                .get(COMPUTEUNIT_SPEC_KEY_MODULE)
4389                .and_then(|m| m.get(COMPUTEUNIT_MODULE_KEY_SOURCE))
4390                .is_some(),
4391            "module.source must propagate verbatim"
4392        );
4393    }
4394
4395    #[test]
4396    fn programs_yaml_entry_falls_back_to_default_namespace() {
4397        // A computeunit without metadata.namespace should default.
4398        let cu: serde_yaml::Value = serde_yaml::from_str(
4399            r#"
4400apiVersion: wasm.pleme.io/v1alpha1
4401kind: ComputeUnit
4402metadata:
4403  name: hello-rio
4404spec:
4405  module:
4406    source: oci://ghcr.io/pleme-io/hello-rio:v0.1.0
4407"#,
4408        )
4409        .unwrap();
4410        let entry = programs_yaml_entry(&sample_caixa(), &cu).unwrap();
4411        assert_eq!(
4412            entry.get(KUBE_KEY_NAMESPACE).and_then(|n| n.as_str()),
4413            Some(DEFAULT_NAMESPACE)
4414        );
4415    }
4416
4417    #[test]
4418    fn programs_yaml_entry_refuses_non_servico() {
4419        let mut c = sample_caixa();
4420        c.kind = CaixaKind::Biblioteca;
4421        c.servicos = vec![];
4422        let err = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap_err();
4423        assert!(matches!(err, Error::NotAServico(_)));
4424    }
4425
4426    #[test]
4427    fn kind_mismatch_error_names_offending_caixa_nome() {
4428        // Pinning the lifted [`caixa_core::KindMismatch`] view's
4429        // load-bearing property: a kind-mismatched caixa surfaces a
4430        // diagnostic that *names the offending caixa* (`hello-rio`),
4431        // not just the rejected kind. Before the lift the renderer
4432        // raised `Error::NotAServico(CaixaKind::Biblioteca)` whose
4433        // Display said "caixa :kind must be Servico for caixa-flux
4434        // rendering, got Biblioteca" — the user had to grep their
4435        // source tree for which caixa.lisp triggered it. After the
4436        // lift the wrapped KindMismatch carries the `:nome`, the
4437        // renderer's `#[error("{0}")]` arm prints it through, and
4438        // the diagnostic is self-locating.
4439        let mut c = sample_caixa();
4440        c.kind = CaixaKind::Biblioteca;
4441        c.servicos = vec![];
4442        let err = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap_err();
4443        let msg = format!("{err}");
4444        assert!(
4445            msg.contains("hello-rio"),
4446            "kind-mismatch diagnostic must name the offending caixa nome \
4447             (got: {msg:?})"
4448        );
4449        assert!(
4450            msg.contains("Servico"),
4451            "diagnostic must name the expected kind (got: {msg:?})"
4452        );
4453        assert!(
4454            msg.contains("Biblioteca"),
4455            "diagnostic must name the actual kind (got: {msg:?})"
4456        );
4457    }
4458
4459    #[test]
4460    fn cluster_bundle_kind_mismatch_names_offending_caixa_nome() {
4461        // The second kind-checking call site in caixa-flux —
4462        // [`cluster_bundle`] — must surface the same lifted diagnostic
4463        // shape. Pinning so a future divergence between
4464        // `programs_yaml_entry` and `cluster_bundle` (e.g. one
4465        // re-inlines the kind check, the other uses `require_kind`)
4466        // surfaces here as a test failure rather than as a silent
4467        // diagnostic regression on the deploy path.
4468        let mut c = sample_caixa();
4469        c.kind = CaixaKind::Aplicacao;
4470        c.servicos = vec![];
4471        let opts = ClusterBundleOpts::for_caixa(&c, "rio");
4472        let err = cluster_bundle(&c, &opts).unwrap_err();
4473        let msg = format!("{err}");
4474        assert!(
4475            msg.contains("hello-rio"),
4476            "cluster_bundle's kind-mismatch must also name the caixa \
4477             nome (got: {msg:?})"
4478        );
4479        match err {
4480            Error::NotAServico(km) => {
4481                assert_eq!(km.nome, "hello-rio");
4482                assert_eq!(km.expected, CaixaKind::Servico);
4483                assert_eq!(km.actual, CaixaKind::Aplicacao);
4484            }
4485            other => panic!("expected Error::NotAServico, got {other:?}"),
4486        }
4487    }
4488
4489    #[test]
4490    fn servico_count_mismatch_carries_typed_view_with_nome() {
4491        // Peer to the [`KindMismatch`]-lift pin above on the V0
4492        // `:servicos`-singularity axis: a Servico-kind caixa whose
4493        // `:servicos` list is non-singleton fails
4494        // [`programs_yaml_entry`] with the renderer's
4495        // `Error::UnsupportedServicoCount` variant wrapping the typed
4496        // [`caixa_core::ServicoCountMismatch`] view (carrying the
4497        // offending caixa's `:nome` + the actual count). Before the
4498        // lift the variant carried only `usize` — the user had to grep
4499        // their source tree for which `caixa.lisp` triggered it; after
4500        // the lift the wrapped typed view names the offending caixa
4501        // verbatim. Pins both the variant routing (via `#[from]`) and
4502        // the typed payload so a future refactor can't silently switch
4503        // back to the raw-`usize` payload (which would regress the
4504        // shared-shape contract with caixa-helm on the peer
4505        // `lareira-<nome>` chart-dir path).
4506        let mut c = sample_caixa();
4507        c.servicos = vec![
4508            "servicos/hello-rio.computeunit.yaml".into(),
4509            "servicos/extra.computeunit.yaml".into(),
4510        ];
4511        let err = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap_err();
4512        match err {
4513            Error::UnsupportedServicoCount(scm) => {
4514                assert_eq!(scm.nome, "hello-rio");
4515                assert_eq!(scm.count, 2);
4516            }
4517            other => panic!("expected Error::UnsupportedServicoCount, got {other:?}"),
4518        }
4519    }
4520
4521    #[test]
4522    fn servico_count_mismatch_diagnostic_names_offending_caixa_nome() {
4523        // The renderer's `#[error("{0}")] UnsupportedServicoCount(
4524        // #[from] ServicoCountMismatch)` arm prints the typed view's
4525        // Display through verbatim, so the offending caixa's `:nome`
4526        // appears in the rendered diagnostic on both the
4527        // `programs_yaml_entry` and `cluster_bundle` paths. Pinning the
4528        // self-locating property end-to-end so a future refactor that
4529        // re-wraps the variant in a Display impl that drops the
4530        // `:nome` surfaces here as a test failure rather than as
4531        // silent fragmentation across the two flux deploy paths. Peer
4532        // to `cluster_bundle_kind_mismatch_names_offending_caixa_nome`
4533        // on the sibling V0 Servico-shape axis.
4534        let mut c = sample_caixa();
4535        c.servicos = vec![];
4536        let err = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap_err();
4537        let msg = format!("{err}");
4538        assert!(
4539            msg.contains("hello-rio"),
4540            ":servicos-count-mismatch diagnostic must name the offending caixa nome \
4541             (got: {msg:?})"
4542        );
4543        assert!(
4544            msg.contains("0"),
4545            "diagnostic must name the actual count (got: {msg:?})"
4546        );
4547        assert!(
4548            msg.contains(":servicos"),
4549            "diagnostic must name the offending field axis (got: {msg:?})"
4550        );
4551    }
4552
4553    #[test]
4554    fn cluster_bundle_servico_count_mismatch_carries_typed_view_with_nome() {
4555        // Peer to `cluster_bundle_kind_mismatch_names_offending_caixa_nome`
4556        // on the sibling V0 `:servicos`-singularity axis. The second
4557        // per-Servico renderer entry-point in caixa-flux —
4558        // [`cluster_bundle`] — must surface the same lifted
4559        // [`caixa_core::ServicoCountMismatch`] view the peer
4560        // [`programs_yaml_entry`] path already pins on the sibling V0
4561        // gate axis. Until this gate landed `cluster_bundle` ran only
4562        // the [`require_kind`] half of the V0-shape gate pair, so a
4563        // Servico-kind caixa whose `:servicos` list is non-singleton
4564        // silently passed the bundle render and the failure surfaced at
4565        // the chart-render layer (`caixa-helm` refused the same input
4566        // with `UnsupportedServicoCount`) far from the deploy-path
4567        // entry-point — the canonical "the V0 invariant is enforced at
4568        // every per-Servico renderer entry except this one" footgun.
4569        // Pins both the variant routing (via `#[from]`) and the typed
4570        // payload so a future refactor that re-inlines a raw count
4571        // check, or strips the `require_single_servico` call from this
4572        // path, surfaces here as a test failure rather than as silent
4573        // fragmentation across the two flux deploy paths.
4574        let mut c = sample_caixa();
4575        c.servicos = vec![
4576            "servicos/hello-rio.computeunit.yaml".into(),
4577            "servicos/extra.computeunit.yaml".into(),
4578        ];
4579        let opts = ClusterBundleOpts::for_caixa(&c, "rio");
4580        let err = cluster_bundle(&c, &opts).unwrap_err();
4581        match err {
4582            Error::UnsupportedServicoCount(scm) => {
4583                assert_eq!(scm.nome, "hello-rio");
4584                assert_eq!(scm.count, 2);
4585            }
4586            other => panic!("expected Error::UnsupportedServicoCount, got {other:?}"),
4587        }
4588    }
4589
4590    #[test]
4591    fn cluster_bundle_servico_count_mismatch_diagnostic_names_offending_caixa_nome() {
4592        // End-to-end Display pin on the [`cluster_bundle`] path —
4593        // peer of `servico_count_mismatch_diagnostic_names_offending_caixa_nome`
4594        // on the sibling [`programs_yaml_entry`] path. The rendered
4595        // diagnostic must name the offending caixa's `:nome`, the
4596        // actual count, and the `:servicos` field axis verbatim on
4597        // both per-Servico renderer entry-points in caixa-flux. Peer
4598        // to `cluster_bundle_kind_mismatch_names_offending_caixa_nome`
4599        // on the sibling V0 kind-shape axis — both V0 gate arms now
4600        // pin their self-locating diagnostic shape end-to-end through
4601        // the bundle path.
4602        let mut c = sample_caixa();
4603        c.servicos = vec![];
4604        let opts = ClusterBundleOpts::for_caixa(&c, "rio");
4605        let err = cluster_bundle(&c, &opts).unwrap_err();
4606        let msg = format!("{err}");
4607        assert!(
4608            msg.contains("hello-rio"),
4609            "cluster_bundle's :servicos-count-mismatch must name the offending caixa nome \
4610             (got: {msg:?})"
4611        );
4612        assert!(
4613            msg.contains("0"),
4614            "diagnostic must name the actual count (got: {msg:?})"
4615        );
4616        assert!(
4617            msg.contains(":servicos"),
4618            "diagnostic must name the offending field axis (got: {msg:?})"
4619        );
4620    }
4621
4622    #[test]
4623    fn upsert_inserts_new_entry() {
4624        let initial: serde_yaml::Value = serde_yaml::from_str(
4625            r#"
4626enabled: true
4627defaultNamespace: tatara-system
4628programs: []
4629"#,
4630        )
4631        .unwrap();
4632        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4633        let (modified, inserted) = upsert_into_programs_yaml(initial, entry).unwrap();
4634        assert!(inserted, "first time should be insert");
4635        let arr = modified
4636            .get(FLEET_PROGRAMS_KEY_PROGRAMS)
4637            .unwrap()
4638            .as_sequence()
4639            .unwrap();
4640        assert_eq!(arr.len(), 1);
4641        assert_eq!(
4642            arr[0].get(FLEET_PROGRAMS_KEY_NAME).and_then(|n| n.as_str()),
4643            Some("hello-rio")
4644        );
4645    }
4646
4647    #[test]
4648    fn upsert_replaces_existing_entry() {
4649        let initial: serde_yaml::Value = serde_yaml::from_str(
4650            r#"
4651enabled: true
4652defaultNamespace: tatara-system
4653programs:
4654  - name: hello-rio
4655    namespace: tatara-system
4656    module:
4657      source: oci://ghcr.io/pleme-io/hello-rio:v0.0.1
4658  - name: other
4659    namespace: tatara-system
4660    module: { source: github:foo/bar }
4661"#,
4662        )
4663        .unwrap();
4664        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4665        let (modified, inserted) = upsert_into_programs_yaml(initial, entry).unwrap();
4666        assert!(!inserted, "second time should be replace");
4667        let arr = modified
4668            .get(FLEET_PROGRAMS_KEY_PROGRAMS)
4669            .unwrap()
4670            .as_sequence()
4671            .unwrap();
4672        assert_eq!(arr.len(), 2, "no new entry added");
4673        let updated_module = arr[0]
4674            .get(COMPUTEUNIT_SPEC_KEY_MODULE)
4675            .unwrap()
4676            .get(COMPUTEUNIT_MODULE_KEY_SOURCE)
4677            .and_then(|s| s.as_str());
4678        assert_eq!(
4679            updated_module,
4680            Some("oci://ghcr.io/pleme-io/hello-rio:v0.1.0")
4681        );
4682    }
4683
4684    #[test]
4685    fn upsert_helmrelease_inserts_under_spec_values_programs() {
4686        let initial: serde_yaml::Value = serde_yaml::from_str(
4687            r#"
4688apiVersion: helm.toolkit.fluxcd.io/v2
4689kind: HelmRelease
4690metadata:
4691  name: rio-fleet-programs
4692  namespace: tatara-system
4693spec:
4694  interval: 30m
4695  chart:
4696    spec:
4697      chart: lareira-fleet-programs
4698  values:
4699    enabled: true
4700    defaultNamespace: tatara-system
4701    programs:
4702      - name: existing
4703        module: { source: github:foo/bar }
4704"#,
4705        )
4706        .unwrap();
4707        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4708        let (modified, inserted) = upsert_into_helmrelease_programs(initial, entry).unwrap();
4709        assert!(inserted);
4710        let arr = modified
4711            .get(KUBE_KEY_SPEC)
4712            .unwrap()
4713            .get(FLUX_KEY_VALUES)
4714            .unwrap()
4715            .get(FLEET_PROGRAMS_KEY_PROGRAMS)
4716            .unwrap()
4717            .as_sequence()
4718            .unwrap();
4719        assert_eq!(arr.len(), 2);
4720        assert_eq!(
4721            arr[1].get(FLEET_PROGRAMS_KEY_NAME).and_then(|n| n.as_str()),
4722            Some("hello-rio")
4723        );
4724    }
4725
4726    #[test]
4727    fn upsert_helmrelease_replaces_existing() {
4728        let initial: serde_yaml::Value = serde_yaml::from_str(
4729            r#"
4730apiVersion: helm.toolkit.fluxcd.io/v2
4731kind: HelmRelease
4732metadata: { name: rio-fleet-programs }
4733spec:
4734  values:
4735    programs:
4736      - name: hello-rio
4737        module: { source: oci://ghcr.io/pleme-io/hello-rio:v0.0.1 }
4738      - name: other
4739        module: { source: github:foo/bar }
4740"#,
4741        )
4742        .unwrap();
4743        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4744        let (modified, inserted) = upsert_into_helmrelease_programs(initial, entry).unwrap();
4745        assert!(!inserted);
4746        let arr = modified
4747            .get(KUBE_KEY_SPEC)
4748            .unwrap()
4749            .get(FLUX_KEY_VALUES)
4750            .unwrap()
4751            .get(FLEET_PROGRAMS_KEY_PROGRAMS)
4752            .unwrap()
4753            .as_sequence()
4754            .unwrap();
4755        assert_eq!(arr.len(), 2);
4756        let updated = arr[0]
4757            .get(COMPUTEUNIT_SPEC_KEY_MODULE)
4758            .unwrap()
4759            .get(COMPUTEUNIT_MODULE_KEY_SOURCE)
4760            .and_then(|s| s.as_str());
4761        assert_eq!(updated, Some("oci://ghcr.io/pleme-io/hello-rio:v0.1.0"));
4762    }
4763
4764    #[test]
4765    fn limits_slot_propagates_into_programs_yaml_entry() {
4766        use caixa_core::LimitsSpec;
4767        use std::time::Duration;
4768        let mut c = sample_caixa();
4769        c.limits = Some(LimitsSpec {
4770            memory: Some(64 * 1024 * 1024),
4771            fuel: Some(1_000_000),
4772            wall_clock: Some(Duration::from_secs(30)),
4773            cpu: Some(500),
4774        });
4775        let entry = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap();
4776        let limits = entry.get(M2_KEY_LIMITS).expect("limits propagates");
4777        assert_eq!(
4778            limits.get(M2_LIMITS_KEY_MEMORY).and_then(|m| m.as_str()),
4779            Some("64MiB")
4780        );
4781        assert_eq!(
4782            limits.get(M2_LIMITS_KEY_CPU).and_then(|m| m.as_str()),
4783            Some("500m")
4784        );
4785    }
4786
4787    #[test]
4788    fn behavior_slot_propagates_into_programs_yaml_entry() {
4789        use caixa_core::BehaviorSpec;
4790        use std::path::PathBuf;
4791        let mut c = sample_caixa();
4792        c.behavior = Some(BehaviorSpec {
4793            on_init: Some(PathBuf::from("lib/init.lisp")),
4794            on_state_change: Some(PathBuf::from("lib/migrations.lisp")),
4795            ..Default::default()
4796        });
4797        let entry = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap();
4798        let behavior = entry.get(M2_KEY_BEHAVIOR).expect("behavior propagates");
4799        assert_eq!(
4800            behavior
4801                .get(M2_BEHAVIOR_KEY_ON_INIT)
4802                .and_then(|v| v.as_str()),
4803            Some("lib/init.lisp")
4804        );
4805    }
4806
4807    #[test]
4808    fn upgrade_from_slot_propagates_into_programs_yaml_entry() {
4809        use caixa_core::{UpgradeFromEntry, UpgradeInstruction};
4810        let mut c = sample_caixa();
4811        c.upgrade_from = vec![UpgradeFromEntry {
4812            from: "0.0.9".into(),
4813            instructions: vec![UpgradeInstruction::SoftPurge {
4814                module: "hello-rio-old".into(),
4815            }],
4816        }];
4817        let entry = programs_yaml_entry(&c, &sample_cu_yaml()).unwrap();
4818        let upgrade_from = entry
4819            .get(M2_KEY_UPGRADE_FROM)
4820            .and_then(|u| u.as_sequence())
4821            .expect("upgradeFrom propagates as a sequence");
4822        assert_eq!(upgrade_from.len(), 1);
4823        assert_eq!(
4824            upgrade_from[0]
4825                .get(M2_UPGRADE_FROM_KEY_FROM)
4826                .and_then(|f| f.as_str()),
4827            Some("0.0.9")
4828        );
4829    }
4830
4831    #[test]
4832    fn empty_m2_slots_do_not_appear_in_programs_yaml_entry() {
4833        // Forward-compat invariant: a Servico with no M2 slots emits a
4834        // programs.yaml entry that's structurally identical to V0
4835        // (no extra keys).
4836        let entry = programs_yaml_entry(&sample_caixa(), &sample_cu_yaml()).unwrap();
4837        assert!(entry.get(M2_KEY_LIMITS).is_none());
4838        assert!(entry.get(M2_KEY_BEHAVIOR).is_none());
4839        assert!(entry.get(M2_KEY_UPGRADE_FROM).is_none());
4840    }
4841
4842    #[test]
4843    fn cluster_bundle_three_files() {
4844        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
4845        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
4846        assert_eq!(files.len(), 3);
4847        let names: Vec<_> = files
4848            .iter()
4849            .map(|f| f.path.to_string_lossy().to_string())
4850            .collect();
4851        assert!(names.contains(&FLUX_GITREPOSITORY_YAML_FILENAME.to_string()));
4852        assert!(names.contains(&FLUX_HELMRELEASE_YAML_FILENAME.to_string()));
4853        assert!(names.contains(&FLUX_KUSTOMIZATION_YAML_FILENAME.to_string()));
4854
4855        let kust = files
4856            .iter()
4857            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
4858            .unwrap();
4859        assert!(kust.contents.contains("./clusters/rio/services/hello-rio"));
4860
4861        let gitrepo = files
4862            .iter()
4863            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
4864            .unwrap();
4865        assert!(gitrepo.contents.contains("v0.1.0"));
4866    }
4867
4868    #[test]
4869    fn default_library_name_re_export_points_at_caixa_core_canonical() {
4870        // The renderer's `pub use caixa_core::DEFAULT_LIBRARY_NAME` is
4871        // the single source of truth for the Helm library-chart wrap
4872        // key the `cluster_bundle` `helmrelease.yaml` template scopes
4873        // the per-cluster `enabled: true` override under. Pin the
4874        // equality (and the static-data identity, peer with the
4875        // sibling `default_namespace_re_export_points_at_caixa_core_canonical`
4876        // pin) so any local re-introduction of a sibling `pub const
4877        // DEFAULT_LIBRARY_NAME: &str = "…"` (the canonical drift
4878        // footgun this lift closes — two production-code consumers of
4879        // the same load-bearing Helm library-chart name across
4880        // caixa-helm + caixa-flux, lifted to one re-export at the
4881        // caixa-core boundary) is a build-time test failure naming
4882        // the offending drift, not a silent apply-time wrap-key
4883        // mismatch routing the per-cluster override nowhere. Peer to
4884        // `caixa_helm::tests::default_library_name_re_export_points_at_caixa_core_canonical`
4885        // on the sibling renderer crate.
4886        caixa_core::assert_str_reexport_identity(
4887            "DEFAULT_LIBRARY_NAME",
4888            DEFAULT_LIBRARY_NAME,
4889            caixa_core::DEFAULT_LIBRARY_NAME,
4890        );
4891    }
4892
4893    #[test]
4894    fn cluster_bundle_helmrelease_values_wrap_key_uses_lifted_constant() {
4895        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`'s
4896        // `spec.values.<library>:` wrap key — the scope under which
4897        // per-cluster overrides like `enabled: true` reach the
4898        // dependent library chart at `helm template` / `helm install`
4899        // time — must spell out the lifted [`DEFAULT_LIBRARY_NAME`]
4900        // verbatim. Before the lift this site carried an inline
4901        // `pleme-computeunit:` literal in the format string; a future
4902        // per-edition library-chart rebrand (the substrate forking
4903        // `pleme-computeunit` to `<registry>-computeunit` for a per-
4904        // cluster image-registry mirror, or to `aplicacao-computeunit`
4905        // for the M4 typed-Aplicacao renderer's sibling library chart,
4906        // or any per-tenant variant the absorption-roadmap names) on
4907        // the sibling caixa-helm `RenderOpts::library_name` axis
4908        // without a coordinated edit here would have silently routed
4909        // the per-cluster override nowhere — the cluster's apply would
4910        // come up with the library chart's defaults, far from the
4911        // rebrand commit's source.
4912        //
4913        // The pin is structural: parse the rendered YAML and assert
4914        // the wrap key under `spec.values` equals the lifted constant.
4915        // A regression that re-introduces an inline literal surfaces
4916        // as a key mismatch (the inline literal would survive, but
4917        // the lifted-constant-keyed assertion would fail).
4918        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
4919        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
4920        let hr = files
4921            .iter()
4922            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
4923            .expect("helmrelease.yaml present");
4924        let parsed: serde_yaml::Value =
4925            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
4926        let values = parsed
4927            .get(KUBE_KEY_SPEC)
4928            .and_then(|s| s.get(FLUX_KEY_VALUES))
4929            .and_then(|v| v.as_mapping())
4930            .expect("spec.values mapping present");
4931        assert!(
4932            values.get(DEFAULT_LIBRARY_NAME).is_some(),
4933            "spec.values must wrap under the lifted DEFAULT_LIBRARY_NAME \
4934             ({DEFAULT_LIBRARY_NAME:?}); a drifted literal here silently \
4935             routes per-cluster overrides nowhere at helm template time"
4936        );
4937        // The wrapped block must carry the canonical `enabled: true`
4938        // overlay — the per-cluster override the bundle path threads
4939        // through. Pin the round-trip so a refactor that hoists the
4940        // overlay out of the wrap can't silently drop it.
4941        let wrapped = values
4942            .get(DEFAULT_LIBRARY_NAME)
4943            .and_then(|v| v.as_mapping())
4944            .expect("wrapped library mapping");
4945        assert_eq!(
4946            wrapped
4947                .get(HELM_VALUES_KEY_ENABLED)
4948                .and_then(|v| v.as_bool()),
4949            Some(CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT),
4950            "cluster_bundle helmrelease.yaml `spec.values.<library>.enabled` \
4951             overlay must resolve to the lifted \
4952             CLUSTER_BUNDLE_LAREIRA_ENABLED_DEFAULT — a drifted inline \
4953             literal here would silently disagree with the substrate-side \
4954             child-chart force-on-under-composition seed"
4955        );
4956    }
4957
4958    #[test]
4959    fn cluster_bundle_helmrelease_wrap_key_pins_canonical_pleme_computeunit_string() {
4960        // Bridge-arm pin: the lifted [`DEFAULT_LIBRARY_NAME`] constant
4961        // resolves to the canonical `"pleme-computeunit"` string today,
4962        // and the rendered `helmrelease.yaml`'s wrap key must spell
4963        // it out verbatim. Pin the literal here (peer with the
4964        // [`caixa_helm::tests::values_yaml_wraps_under_pleme_computeunit_key`]
4965        // canonical-default arm on the chart-render side) so a future
4966        // rebrand of the lifted constant surfaces here as a coordinated
4967        // edit-point — same trajectory as the
4968        // `default_servico_port_constant_pins_canonical_8080_literal`
4969        // bridge-arm pin in caixa-core.
4970        assert_eq!(DEFAULT_LIBRARY_NAME, "pleme-computeunit");
4971        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
4972        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
4973        let hr = files
4974            .iter()
4975            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
4976            .unwrap();
4977        assert!(
4978            hr.contents.contains("pleme-computeunit:"),
4979            "helmrelease.yaml must spell the canonical library-chart wrap \
4980             key under spec.values (got: {contents:?})",
4981            contents = hr.contents
4982        );
4983    }
4984
4985    #[test]
4986    fn helm_values_key_enabled_re_export_points_at_caixa_core_canonical() {
4987        // The renderer's `HELM_VALUES_KEY_ENABLED` was lifted from the
4988        // production-code inline `enabled: true\n` fragment inside
4989        // [`cluster_bundle`]'s `helmrelease.yaml` format-string template
4990        // (formerly `caixa-flux/src/lib.rs:844`) plus its test-side
4991        // round-trip navigator
4992        // (`cluster_bundle_helmrelease_values_wrap_key_uses_lifted_constant`,
4993        // where `.get("enabled")`
4994        // isolated the per-cluster override the bundle path threads
4995        // through) to a re-export of
4996        // [`caixa_core::HELM_VALUES_KEY_ENABLED`] so the canonical
4997        // `pleme-computeunit` library-chart values-block enable-toggle
4998        // key lives in exactly one place across every caixa renderer.
4999        // Pin the equality + `&'static` static-data identity here so any
5000        // local re-introduction of a sibling
5001        // `pub const HELM_VALUES_KEY_ENABLED: &str = "…"` at this crate
5002        // — the canonical drift footgun where a sibling local
5003        // `pub const` could happen to carry the same string at the
5004        // source while pointing at a different `&'static` allocation —
5005        // is a build-time test failure naming the offending drift, not
5006        // a silent per-values enable-toggle reroute at `helm template` /
5007        // `helm install` time far from the drift site. Peer to
5008        // [`default_library_name_re_export_points_at_caixa_core_canonical`]
5009        // / [`kube_key_spec_re_export_points_at_caixa_core_canonical`] on
5010        // the sibling re-export axes +
5011        // `caixa_helm::tests::helm_values_key_enabled_re_export_points_at_caixa_core_canonical`
5012        // on the peer per-Servico-chart renderer crate.
5013        caixa_core::assert_str_reexport_identity(
5014            "HELM_VALUES_KEY_ENABLED",
5015            HELM_VALUES_KEY_ENABLED,
5016            caixa_core::HELM_VALUES_KEY_ENABLED,
5017        );
5018    }
5019
5020    #[test]
5021    fn default_flux_system_namespace_re_export_points_at_caixa_core_canonical() {
5022        // The renderer's `pub use caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE`
5023        // is the single source of truth for the FluxCD installation
5024        // namespace both axes of the rendered `kustomization.yaml`
5025        // document (`metadata.namespace` and `spec.sourceRef.name`)
5026        // consume. Pin the equality (and the static-data identity, peer
5027        // with the sibling
5028        // `default_namespace_re_export_points_at_caixa_core_canonical` /
5029        // `default_library_name_re_export_points_at_caixa_core_canonical`
5030        // pins) so any local re-introduction of a sibling `pub const
5031        // DEFAULT_FLUX_SYSTEM_NAMESPACE: &str = "…"` (the canonical
5032        // drift footgun this lift closes — two production-code
5033        // consumers of the same load-bearing FluxCD-installation-
5034        // namespace inside the kustomization template, lifted to one
5035        // re-export at the caixa-core boundary) is a build-time test
5036        // failure naming the offending drift, not a silent apply-time
5037        // `Kustomization`-outside-controller-watch-window / dangling-
5038        // `sourceRef` reconciliation freeze.
5039        caixa_core::assert_str_reexport_identity(
5040            "DEFAULT_FLUX_SYSTEM_NAMESPACE",
5041            DEFAULT_FLUX_SYSTEM_NAMESPACE,
5042            caixa_core::DEFAULT_FLUX_SYSTEM_NAMESPACE,
5043        );
5044    }
5045
5046    #[test]
5047    fn cluster_bundle_kustomization_uses_lifted_flux_system_namespace() {
5048        // Fail-before-pass-after pin: the rendered `kustomization.yaml`'s
5049        // `metadata.namespace` and `spec.sourceRef.name` axes — the two
5050        // physical sites the inline `flux-system` literal previously
5051        // sat at (caixa-flux/src/lib.rs:477, 483 in the prior shape) —
5052        // must both resolve to the lifted
5053        // [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] verbatim. Before this lift
5054        // the kustomization template carried two inline `flux-system`
5055        // literals; a future per-cluster Flux installation rebrand on
5056        // either axis without a coordinated edit on the other would have
5057        // silently emitted a `Kustomization` outside the bootstrap
5058        // controller's watch window (the `kustomize-controller` watches
5059        // the installation namespace by default) or a dangling
5060        // `spec.sourceRef.name` pointing at a `GitRepository` that
5061        // doesn't exist in the rebranded namespace.
5062        //
5063        // The pin is structural: parse the rendered YAML and assert
5064        // each of the two axes equals the lifted constant by value. A
5065        // regression that re-introduces an inline literal at either
5066        // axis surfaces here as a key mismatch (the inline literal
5067        // would survive, but the lifted-constant-keyed assertion would
5068        // fail when the lift's value changes).
5069        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5070        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5071        let kust = files
5072            .iter()
5073            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5074            .expect("kustomization.yaml present");
5075        let parsed: serde_yaml::Value =
5076            serde_yaml::from_str(&kust.contents).expect("kustomization.yaml parses as YAML");
5077        assert_eq!(
5078            kube_metadata_str_field(&parsed, KUBE_KEY_NAMESPACE),
5079            Some(DEFAULT_FLUX_SYSTEM_NAMESPACE),
5080            "kustomization.yaml metadata.namespace must spell the lifted \
5081             DEFAULT_FLUX_SYSTEM_NAMESPACE ({DEFAULT_FLUX_SYSTEM_NAMESPACE:?}); \
5082             a drifted literal here silently places the Kustomization outside \
5083             the bootstrap kustomize-controller's watch window"
5084        );
5085        assert_eq!(
5086            parsed
5087                .get(KUBE_KEY_SPEC)
5088                .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
5089                .and_then(|r| r.get("name"))
5090                .and_then(|n| n.as_str()),
5091            Some(DEFAULT_FLUX_SYSTEM_NAMESPACE),
5092            "kustomization.yaml spec.sourceRef.name must spell the lifted \
5093             DEFAULT_FLUX_SYSTEM_NAMESPACE ({DEFAULT_FLUX_SYSTEM_NAMESPACE:?}); \
5094             a drifted literal here dangles the reference at a GitRepository \
5095             that doesn't exist in the rebranded installation namespace"
5096        );
5097    }
5098
5099    #[test]
5100    fn cluster_bundle_kustomization_pins_canonical_flux_system_string() {
5101        // Bridge-arm pin: the lifted [`DEFAULT_FLUX_SYSTEM_NAMESPACE`]
5102        // constant resolves to the canonical `"flux-system"` string
5103        // today, and both rendered `kustomization.yaml` axes must spell
5104        // it out verbatim. Pin the literal here (peer with the
5105        // [`default_flux_system_namespace_pins_canonical_value`]
5106        // canonical-default arm in caixa-core, and with
5107        // [`cluster_bundle_helmrelease_wrap_key_pins_canonical_pleme_computeunit_string`]
5108        // on the sibling `DEFAULT_LIBRARY_NAME` axis) so a future
5109        // rebrand of the lifted constant surfaces here as a coordinated
5110        // edit-point, same trajectory as the
5111        // `default_servico_port_constant_pins_canonical_8080_literal`
5112        // bridge-arm pin in caixa-core.
5113        assert_eq!(DEFAULT_FLUX_SYSTEM_NAMESPACE, "flux-system");
5114        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5115        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5116        let kust = files
5117            .iter()
5118            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5119            .unwrap();
5120        assert!(
5121            kust.contents.contains("namespace: flux-system\n"),
5122            "kustomization.yaml must spell the canonical FluxCD \
5123             installation namespace at metadata.namespace (got: {contents:?})",
5124            contents = kust.contents
5125        );
5126        assert!(
5127            kust.contents.contains("name: flux-system\n"),
5128            "kustomization.yaml must spell the canonical FluxCD \
5129             installation namespace at spec.sourceRef.name (got: {contents:?})",
5130            contents = kust.contents
5131        );
5132    }
5133
5134    #[test]
5135    fn cluster_bundle_helmrelease_uses_lifted_flux_api_version() {
5136        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
5137        // `apiVersion` axis — the load-bearing Flux v2 CRD-group/version
5138        // declaration the `helm-controller` watches — must resolve to the
5139        // lifted [`FLUX_HELMRELEASE_API_VERSION`] verbatim. Before this
5140        // lift the helmrelease template carried an inline
5141        // `helm.toolkit.fluxcd.io/v2` literal; a future upstream Flux v3
5142        // migration on this axis without a coordinated edit on the
5143        // sibling kustomization `healthChecks[].apiVersion` (the second
5144        // render-side occurrence the same lift threads through) would
5145        // have silently routed the rendered `HelmRelease` outside the
5146        // controller's `Watches` and broken at apply time with a non-
5147        // self-locating "no kind 'HelmRelease' is registered for version
5148        // 'helm.toolkit.fluxcd.io/v2beta2'" error. Peer with
5149        // [`cluster_bundle_kustomization_uses_lifted_flux_system_namespace`]
5150        // on the sibling [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] lift.
5151        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5152        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5153        let hr = files
5154            .iter()
5155            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
5156            .expect("helmrelease.yaml present");
5157        let parsed: serde_yaml::Value =
5158            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
5159        assert_eq!(
5160            kube_root_str_field(&parsed, KUBE_KEY_API_VERSION),
5161            Some(FLUX_HELMRELEASE_API_VERSION),
5162            "helmrelease.yaml apiVersion must spell the lifted \
5163             FLUX_HELMRELEASE_API_VERSION ({FLUX_HELMRELEASE_API_VERSION:?}); \
5164             a drifted literal here routes the HelmRelease outside the Flux v2 \
5165             helm-controller's Watches",
5166        );
5167    }
5168
5169    #[test]
5170    fn cluster_bundle_kustomization_health_check_uses_lifted_flux_api_version() {
5171        // Sibling-axis pin to
5172        // `cluster_bundle_helmrelease_uses_lifted_flux_api_version`: the
5173        // rendered `kustomization.yaml`'s `spec.healthChecks[].apiVersion`
5174        // axis is the Flux v2 contract pairing the parent Kustomization's
5175        // per-resource health-gate to the sibling HelmRelease's CRD
5176        // group/version. Both axes must resolve to the same lifted
5177        // constant by value — a future upstream Flux v3 migration on
5178        // either axis without a coordinated edit on the other would
5179        // have silently dangled the health-check (apply-side: the per-
5180        // resource health-gate never resolves, the parent Kustomization
5181        // sits perpetually in `Reconciling`).
5182        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5183        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5184        let kust = files
5185            .iter()
5186            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5187            .expect("kustomization.yaml present");
5188        let parsed: serde_yaml::Value =
5189            serde_yaml::from_str(&kust.contents).expect("kustomization.yaml parses as YAML");
5190        let health_checks = parsed
5191            .get(KUBE_KEY_SPEC)
5192            .and_then(|s| s.get(FLUX_KEY_HEALTH_CHECKS))
5193            .and_then(|h| h.as_sequence())
5194            .expect("kustomization.yaml spec.healthChecks present");
5195        assert!(
5196            !health_checks.is_empty(),
5197            "kustomization.yaml spec.healthChecks must carry at least one \
5198             entry — the rendered Kustomization gates on its sibling \
5199             HelmRelease's health by construction",
5200        );
5201        for (i, entry) in health_checks.iter().enumerate() {
5202            assert_eq!(
5203                kube_root_str_field(entry, KUBE_KEY_API_VERSION),
5204                Some(FLUX_HELMRELEASE_API_VERSION),
5205                "kustomization.yaml spec.healthChecks[{i}].apiVersion must \
5206                 spell the lifted FLUX_HELMRELEASE_API_VERSION \
5207                 ({FLUX_HELMRELEASE_API_VERSION:?}); a drifted literal here \
5208                 dangles the per-resource health-gate at apply time",
5209            );
5210        }
5211    }
5212
5213    #[test]
5214    fn cluster_bundle_helmrelease_pins_canonical_flux_v2_api_version_string() {
5215        // Bridge-arm pin: the lifted [`FLUX_HELMRELEASE_API_VERSION`]
5216        // constant resolves to the canonical
5217        // `"helm.toolkit.fluxcd.io/v2"` string today, and both rendered
5218        // axes (helmrelease.yaml apiVersion + kustomization.yaml
5219        // healthChecks[].apiVersion) must spell it out verbatim. Pin the
5220        // literal here (peer with the
5221        // [`flux_helmrelease_api_version_pins_canonical_value`] canonical-
5222        // default arm in caixa-core, and with
5223        // [`cluster_bundle_kustomization_pins_canonical_flux_system_string`]
5224        // on the sibling `DEFAULT_FLUX_SYSTEM_NAMESPACE` axis) so a
5225        // future Flux v3 migration of the lifted constant surfaces here
5226        // as a coordinated edit-point.
5227        assert_eq!(FLUX_HELMRELEASE_API_VERSION, "helm.toolkit.fluxcd.io/v2");
5228        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5229        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5230        let hr = files
5231            .iter()
5232            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
5233            .unwrap();
5234        assert!(
5235            hr.contents
5236                .contains("apiVersion: helm.toolkit.fluxcd.io/v2\n"),
5237            "helmrelease.yaml must spell the canonical Flux v2 HelmRelease \
5238             apiVersion at the top-level apiVersion axis (got: {contents:?})",
5239            contents = hr.contents,
5240        );
5241        let kust = files
5242            .iter()
5243            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5244            .unwrap();
5245        assert!(
5246            kust.contents
5247                .contains("apiVersion: helm.toolkit.fluxcd.io/v2\n"),
5248            "kustomization.yaml must spell the canonical Flux v2 HelmRelease \
5249             apiVersion at spec.healthChecks[].apiVersion (got: {contents:?})",
5250            contents = kust.contents,
5251        );
5252    }
5253
5254    #[test]
5255    fn cluster_bundle_default_git_tag_uses_lifted_caixa_core_prefix() {
5256        // Fail-before-pass-after pin: the [`ClusterBundleOpts::for_caixa`]
5257        // constructor's default `git_ref: GitRefSpec::Tag(...)` must
5258        // compose the lifted [`caixa_core::DEFAULT_PUBLISH_TAG_PREFIX`]
5259        // against the caixa's `:versao` — not an inline `"v"` byte the
5260        // peer `feira publish` `--prefix` default and this deploy-side
5261        // default could silently drift on.
5262        //
5263        // Until this lift landed the deploy-side carried a `format!("v{}",
5264        // caixa.versao)` literal while the writer-side (caixa-feira/src/cmd/publish.rs:22)
5265        // carried a clap `default_value = "v"` literal — two production-code
5266        // consumers of the same git-tag-naming convention on the same
5267        // git remote axis, drift-prone by construction. A future
5268        // Zig-style-tag rebrand on one side (e.g. moving the publisher to
5269        // `release/<versao>` once a sibling forge convention lands)
5270        // without a coordinated edit here would silently emit a tag the
5271        // FluxCD `GitRepository` reconciler can't resolve — the
5272        // dependent `HelmRelease`'s `chart: sourceRef` would never
5273        // converge and every per-Servico apply would silently come up
5274        // with the prior reconciled state, with the failure surfacing
5275        // far from the rebrand commit's source at
5276        // `kubectl describe gitrepository` time.
5277        //
5278        // Pin the equality on the constructed `GitRefSpec::Tag` body and
5279        // on the rendered `gitrepository.yaml`'s `ref: { tag: ... }`
5280        // field so a regression that re-inlines the `"v"` literal at
5281        // either layer (this constructor or the format-string in
5282        // [`cluster_bundle`]) surfaces here as a build-time test failure
5283        // rather than as a silent deploy-time `GitRepository` reconcile
5284        // loop. Peer to the sibling [`caixa-feira`]
5285        // `publish_prefix_default_pins_lifted_caixa_core_constant` test
5286        // closing the same drift on the writer-side.
5287        let caixa = sample_caixa();
5288        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
5289        match &opts.git_ref {
5290            GitRefSpec::Tag(tag) => {
5291                assert!(
5292                    tag.starts_with(caixa_core::DEFAULT_PUBLISH_TAG_PREFIX),
5293                    "default git_ref tag must start with the lifted \
5294                     caixa_core::DEFAULT_PUBLISH_TAG_PREFIX (got: {tag:?})"
5295                );
5296                assert_eq!(
5297                    tag,
5298                    &format!(
5299                        "{prefix}{versao}",
5300                        prefix = caixa_core::DEFAULT_PUBLISH_TAG_PREFIX,
5301                        versao = caixa.versao(),
5302                    ),
5303                    "default git_ref tag must compose the lifted prefix \
5304                     against the caixa's :versao verbatim"
5305                );
5306            }
5307            other => panic!("expected GitRefSpec::Tag, got {other:?}"),
5308        }
5309        let files = cluster_bundle(&caixa, &opts).unwrap();
5310        let gr = files
5311            .iter()
5312            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
5313            .expect("gitrepository.yaml present");
5314        let expected_tag = format!(
5315            "{prefix}{versao}",
5316            prefix = caixa_core::DEFAULT_PUBLISH_TAG_PREFIX,
5317            versao = caixa.versao(),
5318        );
5319        assert!(
5320            gr.contents.contains(&format!("tag: {expected_tag:?}")),
5321            "gitrepository.yaml must spell the lifted-prefix-composed tag \
5322             at ref.tag (expected: {expected_tag:?}, got: {contents:?})",
5323            contents = gr.contents
5324        );
5325    }
5326
5327    #[test]
5328    fn cluster_bundle_default_git_tag_versao_routes_through_caixa_versao_accessor() {
5329        // Emit-path pin: the per-`ClusterBundleOpts::for_caixa`
5330        // constructor's default `git_ref: GitRefSpec::Tag(...)` body
5331        // and the paired `gitrepository.yaml`'s `ref.tag` scalar must
5332        // derive their terminal `{versao}` byte-string through the
5333        // typed [`caixa_core::Caixa::versao`] accessor byte-for-byte.
5334        // Before this converge the emit site carried a raw
5335        // `caixa.versao` `Display` field-access into the
5336        // `format!("{prefix}{versao}", ...)` template, bypassing the
5337        // typed dispatch. Sibling of the 05a7701 (caixa-helm)
5338        // `Caixa::versao` Display-axis converge — this closes the
5339        // co-resident `Caixa::versao` Display-axis in caixa-flux the
5340        // sibling 4a363bf `Caixa::nome` `String`-carry axis and
5341        // 162e2e2 `Caixa::nome` `&str`/Display-axis converges in
5342        // this crate already closed on the peer `Caixa::nome`
5343        // primitive, so caixa-flux now owns every projection of the
5344        // `Caixa::versao` axis through the typed accessor.
5345        //
5346        // A future extension of the accessor (a SemVer-2
5347        // build-metadata canonicalization pass, an OCI-tag
5348        // normalization the M4 registry-alignment slot lands, a
5349        // per-edition pre-release-tag overlay dispatched through
5350        // `Caixa::edicao`) that landed on the accessor but not on
5351        // this emit site would silently split the FluxCD
5352        // `GitRepository` clone-target `ref.tag` from every other
5353        // per-Caixa version-identity consumer (the peer caixa-helm
5354        // Chart.yaml `version:` / `appVersion:` and README `Origin`
5355        // line, the paired `feira publish` git-tag `v{versao}`
5356        // emit) — the source-controller would then resolve a
5357        // pre-extension git tag while the paired `HelmRelease` /
5358        // Chart.yaml / README carried the post-extension form,
5359        // silently freezing every deployed chart at the wrong
5360        // per-caixa git snapshot. Pin the equality on the
5361        // constructed `GitRefSpec::Tag` body and on the rendered
5362        // `gitrepository.yaml`'s `ref: { tag: ... }` field so a
5363        // regression that re-inlines the raw `caixa.versao` field
5364        // access at either layer (this constructor or the
5365        // format-string in [`cluster_bundle`]) surfaces here as a
5366        // build-time test failure rather than as a silent
5367        // deploy-time `GitRepository` reconcile loop.
5368        let caixa = sample_caixa();
5369        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
5370        let expected_tag = format!(
5371            "{prefix}{versao}",
5372            prefix = caixa_core::DEFAULT_PUBLISH_TAG_PREFIX,
5373            versao = caixa.versao(),
5374        );
5375        match &opts.git_ref {
5376            GitRefSpec::Tag(tag) => assert_eq!(
5377                tag, &expected_tag,
5378                "default git_ref tag must derive its `{{versao}}` \
5379                 scalar through the typed `caixa_core::Caixa::versao` \
5380                 accessor — a regression that re-inlines \
5381                 `caixa.versao` at the constructor site silently \
5382                 splits the FluxCD `GitRepository` clone-target \
5383                 `ref.tag` from every other per-Caixa \
5384                 version-identity consumer"
5385            ),
5386            other => panic!("expected GitRefSpec::Tag, got {other:?}"),
5387        }
5388        let files = cluster_bundle(&caixa, &opts).unwrap();
5389        let gr = files
5390            .iter()
5391            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
5392            .expect("gitrepository.yaml present");
5393        assert!(
5394            gr.contents.contains(&format!("tag: {expected_tag:?}")),
5395            "gitrepository.yaml must spell the accessor-derived tag \
5396             at ref.tag (expected: {expected_tag:?}, got: {contents:?}) \
5397             — a regression that re-inlines `caixa.versao` at the \
5398             [`cluster_bundle`] format-string site silently splits \
5399             the on-disk Flux v2 `GitRepository` YAML from the \
5400             substrate's per-caixa version-identity dispatch",
5401            contents = gr.contents
5402        );
5403    }
5404
5405    #[test]
5406    fn flux_gitrepository_api_version_re_export_points_at_caixa_core_canonical() {
5407        // The renderer's `pub use caixa_core::FLUX_GITREPOSITORY_API_VERSION`
5408        // is the single source of truth for the Flux v2 `GitRepository`
5409        // CRD-group/version the rendered `gitrepository.yaml` document
5410        // declares at its `apiVersion` axis. Pin the equality (and the
5411        // static-data identity, peer with the sibling
5412        // `default_flux_system_namespace_re_export_points_at_caixa_core_canonical` /
5413        // `default_library_name_re_export_points_at_caixa_core_canonical`
5414        // pins) so any local re-introduction of a sibling `pub const
5415        // FLUX_GITREPOSITORY_API_VERSION: &str = "…"` (the canonical drift
5416        // footgun this lift closes — one production-code consumer of the
5417        // load-bearing Flux v2 `GitRepository` CRD-group/version inside
5418        // the gitrepository template, lifted to one re-export at the
5419        // caixa-core boundary) is a build-time test failure naming the
5420        // offending drift, not a silent apply-time `GitRepository`-
5421        // outside-controller-watch-window reconciliation freeze.
5422        caixa_core::assert_str_reexport_identity(
5423            "FLUX_GITREPOSITORY_API_VERSION",
5424            FLUX_GITREPOSITORY_API_VERSION,
5425            caixa_core::FLUX_GITREPOSITORY_API_VERSION,
5426        );
5427    }
5428
5429    #[test]
5430    fn cluster_bundle_gitrepository_uses_lifted_flux_api_version() {
5431        // Fail-before-pass-after pin: the rendered `gitrepository.yaml`
5432        // `apiVersion` axis — the load-bearing Flux v2 CRD-group/version
5433        // declaration the `source-controller` watches — must resolve to the
5434        // lifted [`FLUX_GITREPOSITORY_API_VERSION`] verbatim. Before this
5435        // lift the gitrepository template carried an inline
5436        // `source.toolkit.fluxcd.io/v1` literal; a future upstream Flux v3
5437        // migration on this axis without a coordinated edit on the sibling
5438        // [`FLUX_HELMRELEASE_API_VERSION`] axis (the Flux v2 controller-
5439        // triple shares the `.toolkit.fluxcd.io` root and promotes together
5440        // on each major bump) would have silently routed the rendered
5441        // `GitRepository` outside the controller's `Watches` and broken at
5442        // apply time with a non-self-locating "no kind 'GitRepository' is
5443        // registered for version 'source.toolkit.fluxcd.io/v1beta2'"
5444        // error. Peer with
5445        // [`cluster_bundle_helmrelease_uses_lifted_flux_api_version`] on
5446        // the sibling [`FLUX_HELMRELEASE_API_VERSION`] lift.
5447        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5448        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5449        let gr = files
5450            .iter()
5451            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
5452            .expect("gitrepository.yaml present");
5453        let parsed: serde_yaml::Value =
5454            serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
5455        assert_eq!(
5456            kube_root_str_field(&parsed, KUBE_KEY_API_VERSION),
5457            Some(FLUX_GITREPOSITORY_API_VERSION),
5458            "gitrepository.yaml apiVersion must spell the lifted \
5459             FLUX_GITREPOSITORY_API_VERSION ({FLUX_GITREPOSITORY_API_VERSION:?}); \
5460             a drifted literal here routes the GitRepository outside the Flux v2 \
5461             source-controller's Watches",
5462        );
5463    }
5464
5465    #[test]
5466    fn cluster_bundle_gitrepository_pins_canonical_flux_v1_api_version_string() {
5467        // Bridge-arm pin: the lifted [`FLUX_GITREPOSITORY_API_VERSION`]
5468        // constant resolves to the canonical
5469        // `"source.toolkit.fluxcd.io/v1"` string today, and the rendered
5470        // `gitrepository.yaml`'s `apiVersion` axis must spell it out
5471        // verbatim. Pin the literal here (peer with the
5472        // [`flux_gitrepository_api_version_pins_canonical_value`]
5473        // canonical-default arm in caixa-core, and with
5474        // [`cluster_bundle_helmrelease_pins_canonical_flux_v2_api_version_string`]
5475        // on the sibling `FLUX_HELMRELEASE_API_VERSION` axis) so a future
5476        // Flux v3 migration of the lifted constant surfaces here as a
5477        // coordinated edit-point.
5478        assert_eq!(
5479            FLUX_GITREPOSITORY_API_VERSION,
5480            "source.toolkit.fluxcd.io/v1"
5481        );
5482        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5483        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5484        let gr = files
5485            .iter()
5486            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
5487            .unwrap();
5488        assert!(
5489            gr.contents
5490                .contains("apiVersion: source.toolkit.fluxcd.io/v1\n"),
5491            "gitrepository.yaml must spell the canonical Flux v2 GitRepository \
5492             apiVersion at the top-level apiVersion axis (got: {contents:?})",
5493            contents = gr.contents,
5494        );
5495    }
5496
5497    #[test]
5498    fn flux_kustomization_api_version_re_export_points_at_caixa_core_canonical() {
5499        // The renderer's `pub use caixa_core::FLUX_KUSTOMIZATION_API_VERSION`
5500        // is the single source of truth for the Flux v2 `Kustomization`
5501        // CRD-group/version the rendered `kustomization.yaml` document
5502        // declares at its `apiVersion` axis. Pin the equality (and the
5503        // static-data identity, peer with the sibling
5504        // [`flux_gitrepository_api_version_re_export_points_at_caixa_core_canonical`]
5505        // / [`default_flux_system_namespace_re_export_points_at_caixa_core_canonical`]
5506        // pins) so any local re-introduction of a sibling `pub const
5507        // FLUX_KUSTOMIZATION_API_VERSION: &str = "…"` (the canonical drift
5508        // footgun this lift closes — one production-code consumer of the
5509        // load-bearing Flux v2 `Kustomization` CRD-group/version inside
5510        // the kustomization template, lifted to one re-export at the
5511        // caixa-core boundary) is a build-time test failure naming the
5512        // offending drift, not a silent apply-time `Kustomization`-
5513        // outside-controller-watch-window reconciliation freeze.
5514        caixa_core::assert_str_reexport_identity(
5515            "FLUX_KUSTOMIZATION_API_VERSION",
5516            FLUX_KUSTOMIZATION_API_VERSION,
5517            caixa_core::FLUX_KUSTOMIZATION_API_VERSION,
5518        );
5519    }
5520
5521    #[test]
5522    fn cluster_bundle_kustomization_uses_lifted_flux_api_version() {
5523        // Fail-before-pass-after pin: the rendered `kustomization.yaml`
5524        // top-level `apiVersion` axis — the load-bearing Flux v2
5525        // CRD-group/version declaration the `kustomize-controller`
5526        // watches — must resolve to the lifted
5527        // [`FLUX_KUSTOMIZATION_API_VERSION`] verbatim. Before this lift
5528        // the kustomization template carried an inline
5529        // `kustomize.toolkit.fluxcd.io/v1` literal; a future upstream
5530        // Flux v3 migration on this axis without a coordinated edit on
5531        // the sibling [`FLUX_HELMRELEASE_API_VERSION`] /
5532        // [`FLUX_GITREPOSITORY_API_VERSION`] axes (the Flux v2
5533        // controller triplet shares the `.toolkit.fluxcd.io` root and
5534        // promotes together on each major bump) would have silently
5535        // routed the rendered `Kustomization` outside the controller's
5536        // `Watches` and broken at apply time with a non-self-locating
5537        // "no kind 'Kustomization' is registered for version
5538        // 'kustomize.toolkit.fluxcd.io/v1beta2'" error. Peer with
5539        // [`cluster_bundle_helmrelease_uses_lifted_flux_api_version`] /
5540        // [`cluster_bundle_gitrepository_uses_lifted_flux_api_version`]
5541        // on the sibling Flux-CRD-axis lifts.
5542        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5543        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5544        let kz = files
5545            .iter()
5546            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5547            .expect("kustomization.yaml present");
5548        let parsed: serde_yaml::Value =
5549            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
5550        assert_eq!(
5551            kube_root_str_field(&parsed, KUBE_KEY_API_VERSION),
5552            Some(FLUX_KUSTOMIZATION_API_VERSION),
5553            "kustomization.yaml apiVersion must spell the lifted \
5554             FLUX_KUSTOMIZATION_API_VERSION ({FLUX_KUSTOMIZATION_API_VERSION:?}); \
5555             a drifted literal here routes the Kustomization outside the Flux v2 \
5556             kustomize-controller's Watches",
5557        );
5558    }
5559
5560    #[test]
5561    fn cluster_bundle_kustomization_pins_canonical_flux_v1_api_version_string() {
5562        // Bridge-arm pin: the lifted [`FLUX_KUSTOMIZATION_API_VERSION`]
5563        // constant resolves to the canonical
5564        // `"kustomize.toolkit.fluxcd.io/v1"` string today, and the
5565        // rendered `kustomization.yaml`'s top-level `apiVersion` axis
5566        // must spell it out verbatim. Pin the literal here (peer with
5567        // the [`flux_kustomization_api_version_pins_canonical_value`]
5568        // canonical-default arm in caixa-core, and with
5569        // [`cluster_bundle_helmrelease_pins_canonical_flux_v2_api_version_string`]
5570        // / [`cluster_bundle_gitrepository_pins_canonical_flux_v1_api_version_string`]
5571        // on the sibling `FLUX_HELMRELEASE_API_VERSION` /
5572        // `FLUX_GITREPOSITORY_API_VERSION` axes) so a future Flux v3
5573        // migration of the lifted constant surfaces here as a
5574        // coordinated edit-point.
5575        assert_eq!(
5576            FLUX_KUSTOMIZATION_API_VERSION,
5577            "kustomize.toolkit.fluxcd.io/v1"
5578        );
5579        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5580        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5581        let kz = files
5582            .iter()
5583            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
5584            .unwrap();
5585        assert!(
5586            kz.contents
5587                .contains("apiVersion: kustomize.toolkit.fluxcd.io/v1\n"),
5588            "kustomization.yaml must spell the canonical Flux v2 Kustomization \
5589             apiVersion at the top-level apiVersion axis (got: {contents:?})",
5590            contents = kz.contents,
5591        );
5592    }
5593
5594    #[test]
5595    fn cluster_bundle_every_flux_cr_carries_top_level_api_version_label_from_lifted_key() {
5596        // Fail-before-pass-after production-side sweep pin: every one of
5597        // the three rendered Flux bundle files' top-level `apiVersion:`
5598        // YAML label — the load-bearing per-CR CRD-group/version-axis
5599        // label naming the exact key the apiserver's `RESTMapper` reads
5600        // to resolve each CR's registered `CustomResourceDefinition` —
5601        // must byte-compose the lifted [`KUBE_KEY_API_VERSION`] verbatim
5602        // as its label prefix. Before this sweep the three
5603        // [`cluster_bundle`] format-string templates carried four inline
5604        // `apiVersion:` YAML label literals (gitrepository.yaml top-level
5605        // + helmrelease.yaml top-level + kustomization.yaml top-level +
5606        // kustomization.yaml `spec.healthChecks[].apiVersion`) side-by-
5607        // side with their `{api_version}`-interpolated value axes; a
5608        // future rebrand of the lifted [`KUBE_KEY_API_VERSION`] const
5609        // (or a coordinated K8s-API-conventions per-major-version
5610        // discriminator promotion) had to reach every inline label site
5611        // in lockstep, or the emit-side silently kept the pre-rebrand
5612        // label byte while the per-CR body-key retrieval sites (already
5613        // routed through [`KUBE_KEY_API_VERSION`]) rebranded — the two
5614        // sides would then disagree on the label byte, and every
5615        // downstream apiserver-side `RESTMapper` lookup on the rendered
5616        // CR would silently miss its per-CR CRD-group/version
5617        // registration with no field naming the label-drift root cause
5618        // far from the source caixa.lisp. Peer to
5619        // [`cluster_bundle_helmrelease_uses_lifted_flux_api_version`] /
5620        // [`cluster_bundle_gitrepository_uses_lifted_flux_api_version`] /
5621        // [`cluster_bundle_kustomization_uses_lifted_flux_api_version`]
5622        // on the sibling per-CR `.get(KUBE_KEY_API_VERSION)` retrieval-
5623        // side pins one level below the raw-byte label-axis this pin
5624        // gates.
5625        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5626        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5627        let label_prefix = format!("{KUBE_KEY_API_VERSION}: ");
5628        for filename in [
5629            FLUX_GITREPOSITORY_YAML_FILENAME,
5630            FLUX_HELMRELEASE_YAML_FILENAME,
5631            FLUX_KUSTOMIZATION_YAML_FILENAME,
5632        ] {
5633            let f = files
5634                .iter()
5635                .find(|f| f.path == std::path::PathBuf::from(filename))
5636                .unwrap_or_else(|| panic!("{filename} present"));
5637            assert!(
5638                f.contents.contains(&label_prefix),
5639                "{filename} must carry the top-level {label_prefix:?} YAML label \
5640                 composed from the lifted KUBE_KEY_API_VERSION ({KUBE_KEY_API_VERSION:?}); \
5641                 a drifted inline label here silently rebrands the per-CR \
5642                 CRD-group/version-axis discriminator away from the lifted key \
5643                 (got: {contents:?})",
5644                contents = f.contents,
5645            );
5646        }
5647    }
5648
5649    #[test]
5650    fn cluster_bundle_every_flux_cr_carries_top_level_kind_label_from_lifted_key() {
5651        // Fail-before-pass-after production-side sweep pin: every one of
5652        // the three rendered Flux bundle files' top-level `kind:` YAML
5653        // label — the load-bearing per-CR CRD-`kind`-discriminator-axis
5654        // label naming the exact key the apiserver's `RESTMapper` reads
5655        // to resolve each CR's registered `CustomResourceDefinition`
5656        // against the sibling `apiVersion:` half of the `(apiVersion,
5657        // kind)` CRD-lookup tuple — must byte-compose the lifted
5658        // [`KUBE_KEY_KIND`] verbatim as its label prefix. Before this
5659        // sweep the three [`cluster_bundle`] format-string templates
5660        // carried six inline `kind:` YAML label literals
5661        // (gitrepository.yaml top-level + helmrelease.yaml top-level +
5662        // helmrelease.yaml `spec.chart.spec.sourceRef.kind` +
5663        // kustomization.yaml top-level + kustomization.yaml
5664        // `spec.sourceRef.kind` + kustomization.yaml
5665        // `spec.healthChecks[].kind`) side-by-side with their
5666        // `{kind}` / `{source_kind}` / `{health_kind}`-interpolated
5667        // value axes; a future rebrand of the lifted [`KUBE_KEY_KIND`]
5668        // const (or a coordinated K8s-API-conventions per-major-version
5669        // discriminator promotion) had to reach every inline label site
5670        // in lockstep, or the emit-side silently kept the pre-rebrand
5671        // label byte while the per-CR body-key retrieval sites (already
5672        // routed through [`KUBE_KEY_KIND`] via `kube_root_str_field` /
5673        // `kube_kind_is`) rebranded — the two sides would then disagree
5674        // on the label byte, and every downstream apiserver-side
5675        // `RESTMapper` / Flux-controller-side `Watches` predicate on the
5676        // rendered CR would silently miss its per-CR CRD-`kind` match
5677        // with no field naming the label-drift root cause far from the
5678        // source caixa.lisp. Peer to
5679        // [`cluster_bundle_every_flux_cr_carries_top_level_api_version_label_from_lifted_key`]
5680        // on the sibling apiVersion half of the same `(apiVersion, kind)`
5681        // CRD-lookup tuple — extends the production-side raw-byte-label-
5682        // sweep discipline established there onto the sibling
5683        // discriminator-half's raw-byte label position, so the two
5684        // halves of the tuple's label axes both consume the same
5685        // substrate-owned `&'static str` by construction.
5686        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5687        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5688        let label_prefix = format!("{KUBE_KEY_KIND}: ");
5689        for filename in [
5690            FLUX_GITREPOSITORY_YAML_FILENAME,
5691            FLUX_HELMRELEASE_YAML_FILENAME,
5692            FLUX_KUSTOMIZATION_YAML_FILENAME,
5693        ] {
5694            let f = files
5695                .iter()
5696                .find(|f| f.path == std::path::PathBuf::from(filename))
5697                .unwrap_or_else(|| panic!("{filename} present"));
5698            assert!(
5699                f.contents.contains(&label_prefix),
5700                "{filename} must carry the top-level {label_prefix:?} YAML label \
5701                 composed from the lifted KUBE_KEY_KIND ({KUBE_KEY_KIND:?}); \
5702                 a drifted inline label here silently rebrands the per-CR \
5703                 CRD-`kind`-discriminator-axis away from the lifted key \
5704                 (got: {contents:?})",
5705                contents = f.contents,
5706            );
5707        }
5708    }
5709
5710    #[test]
5711    fn cluster_bundle_every_flux_cr_carries_top_level_metadata_label_from_lifted_key() {
5712        // Fail-before-pass-after production-side sweep pin: every one of
5713        // the three rendered Flux bundle files' top-level `metadata:`
5714        // YAML label — the load-bearing per-CR block-scope key naming
5715        // the exact axis the apiserver reads to resolve each CR's
5716        // ObjectMeta (`.metadata.name` / `.metadata.namespace` /
5717        // `.metadata.labels` / `.metadata.annotations`) against the
5718        // sibling `spec:` half of the top-level `(metadata, spec)`
5719        // K8s-CR-shape pair — must byte-compose the lifted
5720        // [`KUBE_KEY_METADATA`] verbatim as its label prefix. Before
5721        // this sweep the three [`cluster_bundle`] format-string
5722        // templates carried three inline `metadata:` YAML label
5723        // literals (gitrepository.yaml top-level +
5724        // helmrelease.yaml top-level + kustomization.yaml top-level)
5725        // side-by-side with their `name: {name}` / `namespace:
5726        // {namespace}` children; a future rebrand of the lifted
5727        // [`KUBE_KEY_METADATA`] const (or a coordinated
5728        // K8s-API-conventions per-major-version ObjectMeta-block-key
5729        // promotion) had to reach every inline label site in lockstep,
5730        // or the emit-side silently kept the pre-rebrand label byte
5731        // while the per-CR body-key retrieval sites (already routed
5732        // through [`KUBE_KEY_METADATA`] via `kube_metadata_str_field`)
5733        // rebranded — the two sides would then disagree on the label
5734        // byte, and every downstream apiserver-side ObjectMeta parser
5735        // on the rendered CR would silently miss its per-CR
5736        // `metadata.name` / `metadata.namespace` lookup with no field
5737        // naming the label-drift root cause far from the source
5738        // caixa.lisp. Peer to
5739        // [`cluster_bundle_every_flux_cr_carries_top_level_kind_label_from_lifted_key`]
5740        // (ef2c7ef) /
5741        // [`cluster_bundle_every_flux_cr_carries_top_level_api_version_label_from_lifted_key`]
5742        // (6d3cbf0) on the sibling `kind:` / `apiVersion:` halves of
5743        // the same top-level K8s-CR shape — extends the production-
5744        // side raw-byte-label-sweep discipline established there onto
5745        // the sibling ObjectMeta-block-scope label position, so the
5746        // three top-level K8s-CR body-block label axes all consume
5747        // the same substrate-owned `&'static str`s by construction.
5748        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5749        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5750        let label_prefix = format!("{KUBE_KEY_METADATA}:");
5751        for filename in [
5752            FLUX_GITREPOSITORY_YAML_FILENAME,
5753            FLUX_HELMRELEASE_YAML_FILENAME,
5754            FLUX_KUSTOMIZATION_YAML_FILENAME,
5755        ] {
5756            let f = files
5757                .iter()
5758                .find(|f| f.path == std::path::PathBuf::from(filename))
5759                .unwrap_or_else(|| panic!("{filename} present"));
5760            assert!(
5761                f.contents.contains(&label_prefix),
5762                "{filename} must carry the top-level {label_prefix:?} YAML label \
5763                 composed from the lifted KUBE_KEY_METADATA ({KUBE_KEY_METADATA:?}); \
5764                 a drifted inline label here silently rebrands the per-CR \
5765                 ObjectMeta-block-scope axis away from the lifted key \
5766                 (got: {contents:?})",
5767                contents = f.contents,
5768            );
5769        }
5770    }
5771
5772    #[test]
5773    fn cluster_bundle_every_flux_cr_carries_top_level_spec_label_from_lifted_key() {
5774        // Fail-before-pass-after production-side sweep pin: every one of
5775        // the three rendered Flux bundle files' top-level `spec:` YAML
5776        // label — the load-bearing per-CR block-scope key naming the
5777        // exact axis the apiserver reads to resolve each CR's payload
5778        // (`.spec.interval` / `.spec.url` / `.spec.chart.spec.*` /
5779        // `.spec.sourceRef` / `.spec.path` / `.spec.healthChecks` /
5780        // `.spec.timeout` / `.spec.install` / `.spec.upgrade` /
5781        // `.spec.values` / `.spec.prune`) against the sibling
5782        // `metadata:` half of the top-level `(metadata, spec)` K8s-CR-
5783        // shape pair — must byte-compose the lifted [`KUBE_KEY_SPEC`]
5784        // verbatim as its label prefix. Before this sweep the three
5785        // [`cluster_bundle`] format-string templates carried four inline
5786        // `spec:` YAML label literals (gitrepository.yaml top-level +
5787        // helmrelease.yaml top-level + helmrelease.yaml
5788        // `spec.chart.spec` nested + kustomization.yaml top-level)
5789        // side-by-side with their per-CR `interval:` / `url:` /
5790        // `chart:` / `sourceRef:` / `install:` / `upgrade:` / `values:`
5791        // / `path:` / `healthChecks:` / `timeout:` children; a future
5792        // rebrand of the lifted [`KUBE_KEY_SPEC`] const (or a
5793        // coordinated K8s-API-conventions per-major-version body-block-
5794        // key promotion) had to reach every inline label site in
5795        // lockstep, or the emit-side silently kept the pre-rebrand
5796        // label byte while the retrieval-side per-CR body-key readers
5797        // (already routed through [`KUBE_KEY_SPEC`] via caixa-core's
5798        // `servico_spec_and_m2_overlay_entries` / caixa-flux's
5799        // `programs_yaml_entry` / caixa-mesh's per-CNP/HTTPRoute walks)
5800        // rebranded — the two sides would then disagree on the label
5801        // byte, and every downstream apiserver-side spec-block parser
5802        // on the rendered CR would silently miss its per-CR
5803        // `spec.interval` / `spec.url` / `spec.chart` / `spec.sourceRef`
5804        // / `spec.install` / `spec.upgrade` / `spec.values` /
5805        // `spec.path` / `spec.healthChecks` / `spec.timeout` lookup
5806        // with no field naming the label-drift root cause far from the
5807        // source caixa.lisp. Peer to
5808        // [`cluster_bundle_every_flux_cr_carries_top_level_metadata_label_from_lifted_key`]
5809        // (83ce571) /
5810        // [`cluster_bundle_every_flux_cr_carries_top_level_kind_label_from_lifted_key`]
5811        // (ef2c7ef) /
5812        // [`cluster_bundle_every_flux_cr_carries_top_level_api_version_label_from_lifted_key`]
5813        // (6d3cbf0) on the sibling `metadata:` / `kind:` / `apiVersion:`
5814        // halves of the same top-level K8s-CR shape — closes the
5815        // fourth (and final) canonical K8s-CR top-level block-scope
5816        // label axis under the same production-side raw-byte-label-
5817        // sweep discipline the prior three commits established, so
5818        // every top-level K8s-CR body-block label position across the
5819        // whole `cluster_bundle` render surface consumes the same
5820        // substrate-owned `&'static str`s by construction.
5821        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5822        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5823        let label_prefix = format!("{KUBE_KEY_SPEC}:");
5824        for filename in [
5825            FLUX_GITREPOSITORY_YAML_FILENAME,
5826            FLUX_HELMRELEASE_YAML_FILENAME,
5827            FLUX_KUSTOMIZATION_YAML_FILENAME,
5828        ] {
5829            let f = files
5830                .iter()
5831                .find(|f| f.path == std::path::PathBuf::from(filename))
5832                .unwrap_or_else(|| panic!("{filename} present"));
5833            assert!(
5834                f.contents.contains(&label_prefix),
5835                "{filename} must carry the top-level {label_prefix:?} YAML label \
5836                 composed from the lifted KUBE_KEY_SPEC ({KUBE_KEY_SPEC:?}); \
5837                 a drifted inline label here silently rebrands the per-CR \
5838                 spec-block-scope axis away from the lifted key \
5839                 (got: {contents:?})",
5840                contents = f.contents,
5841            );
5842        }
5843    }
5844
5845    #[test]
5846    fn cluster_bundle_every_flux_cr_carries_metadata_namespace_label_from_lifted_key() {
5847        // Fail-before-pass-after production-side sweep pin: every one
5848        // of the three rendered Flux bundle files' `namespace:` YAML
5849        // label positions — the load-bearing per-CR-`metadata.namespace`
5850        // axis the apiserver reads to route each CR into its target
5851        // namespace (`gitrepository.yaml` top-level +
5852        // `helmrelease.yaml` top-level + `helmrelease.yaml`
5853        // `spec.chart.spec.sourceRef.namespace` nested + `kustomization.yaml`
5854        // top-level + `kustomization.yaml`
5855        // `spec.healthChecks[].namespace` nested) against the sibling
5856        // `name:` half of the ObjectMeta / sourceRef / healthCheck
5857        // `(name, namespace)` identity-pair — must byte-compose the
5858        // lifted [`KUBE_KEY_NAMESPACE`] verbatim as its label prefix.
5859        // Before this sweep the three [`cluster_bundle`] format-string
5860        // templates carried five inline `namespace:` YAML label
5861        // literals side-by-side with the sibling per-CR `name:` half
5862        // of every `(name, namespace)` identity-pair emission; a
5863        // future rebrand of the lifted [`KUBE_KEY_NAMESPACE`] const
5864        // (or a coordinated K8s-API-conventions per-major-version
5865        // ObjectMeta-key promotion) had to reach every inline label
5866        // site in lockstep, or the emit-side silently kept the pre-
5867        // rebrand label byte while the retrieval-side per-CR
5868        // `metadata.namespace` readers (already routed through
5869        // [`KUBE_KEY_NAMESPACE`] via caixa-core's
5870        // `kube_metadata_str_field` walks + this crate's
5871        // `programs_yaml_entry` upstream ComputeUnit YAML retrieval +
5872        // `cluster_bundle`'s rendered `kustomization.yaml` drift-
5873        // detection pin) rebranded — the two sides would then
5874        // disagree on the label byte, and every downstream apiserver-
5875        // side ObjectMeta parser on the rendered CR would silently
5876        // miss its per-CR `metadata.namespace` lookup and route the
5877        // resource into `default` (or whatever fallback the calling
5878        // controller supplies) with no field naming the label-drift
5879        // root cause far from the source caixa.lisp. Peer to
5880        // [`cluster_bundle_every_flux_cr_carries_top_level_metadata_label_from_lifted_key`]
5881        // (83ce571) /
5882        // [`cluster_bundle_every_flux_cr_carries_top_level_kind_label_from_lifted_key`]
5883        // (ef2c7ef) /
5884        // [`cluster_bundle_every_flux_cr_carries_top_level_api_version_label_from_lifted_key`]
5885        // (6d3cbf0) /
5886        // [`cluster_bundle_every_flux_cr_carries_top_level_spec_label_from_lifted_key`]
5887        // (ed23a31) on the sibling `metadata:` / `kind:` /
5888        // `apiVersion:` / `spec:` halves of the top-level K8s-CR
5889        // shape — extends the same production-side raw-byte-label-
5890        // sweep discipline onto the canonical `metadata.namespace`
5891        // nested axis every rendered Flux v2 bundle document
5892        // navigates, so every `namespace:` label position across the
5893        // whole `cluster_bundle` render surface consumes the same
5894        // substrate-owned `&'static str` by construction.
5895        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5896        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5897        let label_prefix = format!("{KUBE_KEY_NAMESPACE}:");
5898        for filename in [
5899            FLUX_GITREPOSITORY_YAML_FILENAME,
5900            FLUX_HELMRELEASE_YAML_FILENAME,
5901            FLUX_KUSTOMIZATION_YAML_FILENAME,
5902        ] {
5903            let f = files
5904                .iter()
5905                .find(|f| f.path == std::path::PathBuf::from(filename))
5906                .unwrap_or_else(|| panic!("{filename} present"));
5907            assert!(
5908                f.contents.contains(&label_prefix),
5909                "{filename} must carry the {label_prefix:?} YAML label \
5910                 composed from the lifted KUBE_KEY_NAMESPACE ({KUBE_KEY_NAMESPACE:?}); \
5911                 a drifted inline label here silently rebrands the per-CR \
5912                 metadata.namespace axis away from the lifted key \
5913                 (got: {contents:?})",
5914                contents = f.contents,
5915            );
5916        }
5917    }
5918
5919    #[test]
5920    fn cluster_bundle_every_flux_cr_carries_metadata_name_label_from_lifted_key() {
5921        // Fail-before-pass-after production-side sweep pin: every one
5922        // of the three rendered Flux bundle files' `name:` YAML label
5923        // positions — the load-bearing per-CR-`metadata.name` axis the
5924        // apiserver-side ObjectMeta parser keys each rendered CR off
5925        // (`gitrepository.yaml` top-level +
5926        // `helmrelease.yaml` top-level +
5927        // `helmrelease.yaml` `spec.chart.spec.sourceRef.name` nested +
5928        // `kustomization.yaml` top-level +
5929        // `kustomization.yaml` `spec.sourceRef.name` nested +
5930        // `kustomization.yaml` `spec.healthChecks[].name` nested)
5931        // against the sibling `namespace:` half of the ObjectMeta /
5932        // sourceRef / healthCheck `(name, namespace)` identity-pair —
5933        // must byte-compose the lifted [`KUBE_KEY_NAME`] verbatim as
5934        // its label prefix. Before this sweep the three
5935        // [`cluster_bundle`] format-string templates carried six
5936        // inline `name:` YAML label literals side-by-side with the
5937        // sibling per-CR `namespace:` half of every `(name,
5938        // namespace)` identity-pair emission; a future rebrand of the
5939        // lifted [`KUBE_KEY_NAME`] const (or a coordinated K8s-API-
5940        // conventions per-major-version ObjectMeta-key promotion) had
5941        // to reach every inline label site in lockstep, or the emit-
5942        // side silently kept the pre-rebrand label byte while the
5943        // retrieval-side per-CR `metadata.name` readers (already
5944        // routed through [`KUBE_KEY_NAME`] via caixa-core's
5945        // `kube_metadata_str_field` walks + this crate's
5946        // `programs_yaml_entry` upstream ComputeUnit YAML retrieval)
5947        // rebranded — the two sides would then disagree on the label
5948        // byte, and every downstream apiserver-side ObjectMeta parser
5949        // on the rendered CR would treat the document as an anonymous
5950        // CR (or the apiserver would reject the apply with a schema-
5951        // validation error naming the wrong key) with no field naming
5952        // the label-drift root cause far from the source caixa.lisp.
5953        // Peer to
5954        // [`cluster_bundle_every_flux_cr_carries_metadata_namespace_label_from_lifted_key`]
5955        // (743e5cd) on the sibling `namespace:` half of the
5956        // ObjectMeta / sourceRef / healthCheck `(name, namespace)`
5957        // identity-pair — extends the same production-side raw-byte-
5958        // label-sweep discipline onto the paired `metadata.name`
5959        // nested axis every rendered Flux v2 bundle document
5960        // navigates, so every `name:` label position across the whole
5961        // `cluster_bundle` render surface consumes the same
5962        // substrate-owned `&'static str` by construction.
5963        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
5964        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
5965        let label_prefix = format!("{KUBE_KEY_NAME}:");
5966        for filename in [
5967            FLUX_GITREPOSITORY_YAML_FILENAME,
5968            FLUX_HELMRELEASE_YAML_FILENAME,
5969            FLUX_KUSTOMIZATION_YAML_FILENAME,
5970        ] {
5971            let f = files
5972                .iter()
5973                .find(|f| f.path == std::path::PathBuf::from(filename))
5974                .unwrap_or_else(|| panic!("{filename} present"));
5975            assert!(
5976                f.contents.contains(&label_prefix),
5977                "{filename} must carry the {label_prefix:?} YAML label \
5978                 composed from the lifted KUBE_KEY_NAME ({KUBE_KEY_NAME:?}); \
5979                 a drifted inline label here silently rebrands the per-CR \
5980                 metadata.name axis away from the lifted key \
5981                 (got: {contents:?})",
5982                contents = f.contents,
5983            );
5984        }
5985    }
5986
5987    #[test]
5988    fn flux_kind_git_repository_re_export_points_at_caixa_core_canonical() {
5989        // The renderer's `pub use caixa_core::FLUX_KIND_GIT_REPOSITORY` is
5990        // the single source of truth for the Flux v2 `GitRepository` CRD
5991        // `kind` discriminator the rendered Flux bundle's three
5992        // `GitRepository`-naming axes declare (the `gitrepository.yaml`
5993        // top-level `kind`, the `helmrelease.yaml`
5994        // `spec.chart.spec.sourceRef.kind`, and the `kustomization.yaml`
5995        // `spec.sourceRef.kind`). Pin the equality (and the static-data
5996        // identity, peer with the sibling
5997        // [`flux_gitrepository_api_version_re_export_points_at_caixa_core_canonical`]
5998        // / [`flux_kustomization_api_version_re_export_points_at_caixa_core_canonical`]
5999        // pins) so any local re-introduction of a sibling `pub const
6000        // FLUX_KIND_GIT_REPOSITORY: &str = "…"` (the canonical drift
6001        // footgun this lift closes — three production-code consumers of
6002        // the load-bearing Flux v2 `GitRepository` CRD `kind`
6003        // discriminator inside the cluster_bundle templates, lifted to one
6004        // re-export at the caixa-core boundary) is a build-time test
6005        // failure naming the offending drift, not a silent apply-time
6006        // `helm-controller` chart-resolution dangle.
6007        caixa_core::assert_str_reexport_identity(
6008            "FLUX_KIND_GIT_REPOSITORY",
6009            FLUX_KIND_GIT_REPOSITORY,
6010            caixa_core::FLUX_KIND_GIT_REPOSITORY,
6011        );
6012    }
6013
6014    #[test]
6015    fn cluster_bundle_gitrepository_kind_uses_lifted_flux_kind_git_repository() {
6016        // Fail-before-pass-after pin: the rendered `gitrepository.yaml`
6017        // top-level `kind` axis — the load-bearing K8s CRD discriminator
6018        // the Flux v2 `source-controller` resolves the rendered document
6019        // against — must resolve to the lifted
6020        // [`FLUX_KIND_GIT_REPOSITORY`] verbatim. Before this lift the
6021        // gitrepository template carried an inline `GitRepository`
6022        // literal at one of three sibling production-code call sites
6023        // across the cluster_bundle templates; the apiserver-side CRD
6024        // resolution contract is the `(apiVersion, kind)` tuple keyed
6025        // against the registered `CustomResourceDefinition`, so drift on
6026        // the kind axis is exactly as load-bearing as drift on the
6027        // sibling [`FLUX_GITREPOSITORY_API_VERSION`] axis (a future Flux
6028        // v3 rebrand on this axis without a coordinated edit on the
6029        // sibling sourceRef.kind axes silently lands the rendered
6030        // `GitRepository` outside the source-controller's `Watches`).
6031        // Peer with [`cluster_bundle_gitrepository_uses_lifted_flux_api_version`]
6032        // on the sibling apiVersion half of the same CRD-lookup tuple.
6033        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6034        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6035        let gr = files
6036            .iter()
6037            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
6038            .expect("gitrepository.yaml present");
6039        let parsed: serde_yaml::Value =
6040            serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
6041        assert_eq!(
6042            kube_root_str_field(&parsed, KUBE_KEY_KIND),
6043            Some(FLUX_KIND_GIT_REPOSITORY),
6044            "gitrepository.yaml top-level kind must spell the lifted \
6045             FLUX_KIND_GIT_REPOSITORY ({FLUX_KIND_GIT_REPOSITORY:?}); a drifted \
6046             literal here routes the GitRepository outside the Flux v2 \
6047             source-controller's CRD registration",
6048        );
6049    }
6050
6051    #[test]
6052    fn cluster_bundle_helmrelease_source_ref_kind_uses_lifted_flux_kind_git_repository() {
6053        // Sibling-axis pin to
6054        // `cluster_bundle_gitrepository_kind_uses_lifted_flux_kind_git_repository`:
6055        // the rendered `helmrelease.yaml`'s `spec.chart.spec.sourceRef.kind`
6056        // axis is the Flux v2 contract pairing the HelmRelease's chart-
6057        // source resolution to the sibling GitRepository's CRD
6058        // discriminator. Both axes must resolve to the same lifted
6059        // constant by value — a future Flux v3 rebrand on either axis
6060        // without a coordinated edit on the other would have silently
6061        // dangled the HelmRelease's chart sourceRef (apply-side: the
6062        // `helm-controller` never resolves a chart for the HelmRelease,
6063        // the rendered Servico chart never reconciles), with the failure
6064        // surfacing far from the rebrand commit's source at
6065        // `kubectl describe helmrelease` time. This is the one of the
6066        // three call sites whose drift the apiserver can't self-locate
6067        // (top-level kind typos surface as "no kind 'X' is registered"
6068        // at apply parse time; a nested sourceRef.kind typo silently
6069        // dangles a controller-side reference).
6070        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6071        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6072        let hr = files
6073            .iter()
6074            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6075            .expect("helmrelease.yaml present");
6076        let parsed: serde_yaml::Value =
6077            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6078        let source_ref_kind = parsed
6079            .get(KUBE_KEY_SPEC)
6080            .and_then(|s| s.get(FLUX_KEY_CHART))
6081            .and_then(|c| c.get(KUBE_KEY_SPEC))
6082            .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6083            .and_then(|r| r.get(KUBE_KEY_KIND))
6084            .and_then(|k| k.as_str())
6085            .expect("helmrelease.yaml spec.chart.spec.sourceRef.kind present");
6086        assert_eq!(
6087            source_ref_kind, FLUX_KIND_GIT_REPOSITORY,
6088            "helmrelease.yaml spec.chart.spec.sourceRef.kind must spell the \
6089             lifted FLUX_KIND_GIT_REPOSITORY ({FLUX_KIND_GIT_REPOSITORY:?}); a \
6090             drifted literal here dangles the HelmRelease's chart sourceRef \
6091             at the Flux v2 source-controller's CRD registration",
6092        );
6093    }
6094
6095    #[test]
6096    fn cluster_bundle_kustomization_source_ref_kind_uses_lifted_flux_kind_git_repository() {
6097        // Sibling-axis pin to
6098        // `cluster_bundle_gitrepository_kind_uses_lifted_flux_kind_git_repository`
6099        // / `cluster_bundle_helmrelease_source_ref_kind_uses_lifted_flux_kind_git_repository`:
6100        // the rendered `kustomization.yaml`'s `spec.sourceRef.kind` axis is
6101        // the Flux v2 contract pairing the parent Kustomization's source
6102        // resolution to the cluster's bootstrap GitRepository's CRD
6103        // discriminator (paired with [`DEFAULT_FLUX_SYSTEM_NAMESPACE`] on
6104        // the namespace axis). Completes the three-axis pin set so any
6105        // local re-introduction of an inline `GitRepository` literal at
6106        // any one of the three rendered Flux bundle axes is a build-time
6107        // test failure, not a silent apply-time dangling-sourceRef
6108        // reconciliation freeze.
6109        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6110        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6111        let kz = files
6112            .iter()
6113            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6114            .expect("kustomization.yaml present");
6115        let parsed: serde_yaml::Value =
6116            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
6117        let source_ref_kind = parsed
6118            .get(KUBE_KEY_SPEC)
6119            .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6120            .and_then(|r| r.get(KUBE_KEY_KIND))
6121            .and_then(|k| k.as_str())
6122            .expect("kustomization.yaml spec.sourceRef.kind present");
6123        assert_eq!(
6124            source_ref_kind, FLUX_KIND_GIT_REPOSITORY,
6125            "kustomization.yaml spec.sourceRef.kind must spell the lifted \
6126             FLUX_KIND_GIT_REPOSITORY ({FLUX_KIND_GIT_REPOSITORY:?}); a drifted \
6127             literal here dangles the parent Kustomization's sourceRef at \
6128             the Flux v2 source-controller's CRD registration",
6129        );
6130    }
6131
6132    #[test]
6133    fn cluster_bundle_three_git_repository_kind_axes_share_one_lifted_constant() {
6134        // Cross-axis triplet invariant: the three rendered Flux bundle
6135        // axes that name the Flux v2 `GitRepository` CRD discriminator
6136        // (gitrepository.yaml top-level kind, helmrelease.yaml
6137        // spec.chart.spec.sourceRef.kind, kustomization.yaml
6138        // spec.sourceRef.kind) all consult one lifted `&'static str`.
6139        // The apiserver-side CRD resolution contract is the
6140        // `(apiVersion, kind)` tuple keyed against the registered
6141        // `CustomResourceDefinition`; the three axes must move
6142        // together on any future Flux v3 CRD rename (e.g. `GitSource`)
6143        // for the rendered HelmRelease's chart sourceRef + the parent
6144        // Kustomization's sourceRef to bind to the sibling
6145        // GitRepository's renamed kind discriminator. Peer to the
6146        // sibling [`flux_controller_triplet_api_versions_share_toolkit_fluxcd_io_root`]
6147        // cross-axis pin on the apiVersion half of the same CRD-lookup
6148        // tuple.
6149        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6150        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6151
6152        let gr_kind = serde_yaml::from_str::<serde_yaml::Value>(
6153            &files
6154                .iter()
6155                .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
6156                .unwrap()
6157                .contents,
6158        )
6159        .unwrap()
6160        .get(KUBE_KEY_KIND)
6161        .and_then(|v| v.as_str())
6162        .map(String::from)
6163        .unwrap();
6164
6165        let hr_source_kind = serde_yaml::from_str::<serde_yaml::Value>(
6166            &files
6167                .iter()
6168                .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6169                .unwrap()
6170                .contents,
6171        )
6172        .unwrap()
6173        .get(KUBE_KEY_SPEC)
6174        .and_then(|s| s.get(FLUX_KEY_CHART))
6175        .and_then(|c| c.get(KUBE_KEY_SPEC))
6176        .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6177        .and_then(|r| r.get(KUBE_KEY_KIND))
6178        .and_then(|v| v.as_str())
6179        .map(String::from)
6180        .unwrap();
6181
6182        let kz_source_kind = serde_yaml::from_str::<serde_yaml::Value>(
6183            &files
6184                .iter()
6185                .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6186                .unwrap()
6187                .contents,
6188        )
6189        .unwrap()
6190        .get(KUBE_KEY_SPEC)
6191        .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6192        .and_then(|r| r.get(KUBE_KEY_KIND))
6193        .and_then(|v| v.as_str())
6194        .map(String::from)
6195        .unwrap();
6196
6197        assert_eq!(gr_kind, FLUX_KIND_GIT_REPOSITORY);
6198        assert_eq!(hr_source_kind, FLUX_KIND_GIT_REPOSITORY);
6199        assert_eq!(kz_source_kind, FLUX_KIND_GIT_REPOSITORY);
6200        assert_eq!(
6201            gr_kind, hr_source_kind,
6202            "gitrepository.yaml top-level kind and helmrelease.yaml \
6203             spec.chart.spec.sourceRef.kind must spell the same lifted \
6204             constant — drift here dangles the HelmRelease's chart sourceRef"
6205        );
6206        assert_eq!(
6207            gr_kind, kz_source_kind,
6208            "gitrepository.yaml top-level kind and kustomization.yaml \
6209             spec.sourceRef.kind must spell the same lifted constant — \
6210             drift here dangles the parent Kustomization's sourceRef"
6211        );
6212    }
6213
6214    #[test]
6215    fn flux_kind_helm_release_re_export_points_at_caixa_core_canonical() {
6216        // The renderer's `pub use caixa_core::FLUX_KIND_HELM_RELEASE` is
6217        // the single source of truth for the Flux v2 `HelmRelease` CRD
6218        // `kind` discriminator the rendered Flux bundle's two
6219        // `HelmRelease`-naming axes declare (the `helmrelease.yaml`
6220        // top-level `kind`, the `kustomization.yaml`
6221        // `spec.healthChecks[].kind`). Pin the equality (and the
6222        // static-data identity, peer with the sibling
6223        // [`flux_kind_git_repository_re_export_points_at_caixa_core_canonical`]
6224        // pin) so any local re-introduction of a sibling `pub const
6225        // FLUX_KIND_HELM_RELEASE: &str = "…"` (the canonical drift
6226        // footgun this lift closes — two production-code consumers of
6227        // the load-bearing Flux v2 `HelmRelease` CRD `kind`
6228        // discriminator inside the cluster_bundle templates, lifted to
6229        // one re-export at the caixa-core boundary) is a build-time
6230        // test failure naming the offending drift, not a silent
6231        // apply-time `helm-controller` resolution dangle or a
6232        // perpetually-`Reconciling` parent Kustomization.
6233        caixa_core::assert_str_reexport_identity(
6234            "FLUX_KIND_HELM_RELEASE",
6235            FLUX_KIND_HELM_RELEASE,
6236            caixa_core::FLUX_KIND_HELM_RELEASE,
6237        );
6238    }
6239
6240    #[test]
6241    fn cluster_bundle_helmrelease_kind_uses_lifted_flux_kind_helm_release() {
6242        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`
6243        // top-level `kind` axis — the load-bearing K8s CRD discriminator
6244        // the Flux v2 `helm-controller` resolves the rendered document
6245        // against — must resolve to the lifted
6246        // [`FLUX_KIND_HELM_RELEASE`] verbatim. Before this lift the
6247        // helmrelease template carried an inline `HelmRelease` literal
6248        // at one of two sibling production-code call sites across the
6249        // cluster_bundle templates; the apiserver-side CRD resolution
6250        // contract is the `(apiVersion, kind)` tuple keyed against the
6251        // registered `CustomResourceDefinition`, so drift on the kind
6252        // axis is exactly as load-bearing as drift on the sibling
6253        // [`FLUX_HELMRELEASE_API_VERSION`] axis (a future Flux v3
6254        // rebrand on this axis without a coordinated edit on the
6255        // sibling healthChecks[].kind axis silently lands the rendered
6256        // `HelmRelease` outside the helm-controller's `Watches`).
6257        // Peer with [`cluster_bundle_helmrelease_uses_lifted_flux_api_version`]
6258        // on the sibling apiVersion half of the same CRD-lookup tuple,
6259        // and with
6260        // [`cluster_bundle_gitrepository_kind_uses_lifted_flux_kind_git_repository`]
6261        // on the sibling Flux-v2 source-controller CRD kind axis.
6262        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6263        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6264        let hr = files
6265            .iter()
6266            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6267            .expect("helmrelease.yaml present");
6268        let parsed: serde_yaml::Value =
6269            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6270        assert_eq!(
6271            kube_root_str_field(&parsed, KUBE_KEY_KIND),
6272            Some(FLUX_KIND_HELM_RELEASE),
6273            "helmrelease.yaml top-level kind must spell the lifted \
6274             FLUX_KIND_HELM_RELEASE ({FLUX_KIND_HELM_RELEASE:?}); a drifted \
6275             literal here routes the HelmRelease outside the Flux v2 \
6276             helm-controller's CRD registration",
6277        );
6278    }
6279
6280    #[test]
6281    fn cluster_bundle_kustomization_health_check_kind_uses_lifted_flux_kind_helm_release() {
6282        // Sibling-axis pin to
6283        // `cluster_bundle_helmrelease_kind_uses_lifted_flux_kind_helm_release`:
6284        // the rendered `kustomization.yaml`'s
6285        // `spec.healthChecks[].kind` axis is the Flux v2 contract
6286        // pairing the parent Kustomization's per-resource health gate
6287        // to the sibling HelmRelease's CRD discriminator. Both axes
6288        // must resolve to the same lifted constant by value — a
6289        // future Flux v3 rebrand on either axis without a coordinated
6290        // edit on the other would have silently pinned the parent
6291        // Kustomization at `Reconciling` forever (apply-side: the
6292        // `kustomize-controller` perpetually re-evaluates an
6293        // unmatched health gate, the Kustomization never declares
6294        // its reconcile complete, every downstream `dependsOn` chain
6295        // freezes), with the failure surfacing far from the rebrand
6296        // commit's source at `kubectl describe kustomization` time.
6297        // This is one of the two call sites whose drift the
6298        // apiserver can't self-locate (top-level kind typos surface
6299        // as "no kind 'X' is registered" at apply parse time; a
6300        // healthChecks[].kind typo silently dangles a controller-side
6301        // health gate). Completes the two-axis pin set so any local
6302        // re-introduction of an inline `HelmRelease` literal at
6303        // either of the two rendered Flux bundle axes is a
6304        // build-time test failure, not a silent apply-time stuck-
6305        // Reconciling reconciliation freeze.
6306        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6307        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6308        let kz = files
6309            .iter()
6310            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6311            .expect("kustomization.yaml present");
6312        let parsed: serde_yaml::Value =
6313            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
6314        let health_checks = parsed
6315            .get(KUBE_KEY_SPEC)
6316            .and_then(|s| s.get(FLUX_KEY_HEALTH_CHECKS))
6317            .and_then(|h| h.as_sequence())
6318            .expect("kustomization.yaml spec.healthChecks present");
6319        assert!(
6320            !health_checks.is_empty(),
6321            "kustomization.yaml spec.healthChecks must carry at least one \
6322             entry — the HelmRelease health gate is the canonical pleme-io \
6323             Flux bundle invariant"
6324        );
6325        let health_kind = health_checks[0]
6326            .get(KUBE_KEY_KIND)
6327            .and_then(|k| k.as_str())
6328            .expect("kustomization.yaml spec.healthChecks[0].kind present");
6329        assert_eq!(
6330            health_kind, FLUX_KIND_HELM_RELEASE,
6331            "kustomization.yaml spec.healthChecks[0].kind must spell the \
6332             lifted FLUX_KIND_HELM_RELEASE ({FLUX_KIND_HELM_RELEASE:?}); a \
6333             drifted literal here dangles the parent Kustomization at \
6334             `Reconciling` forever at the Flux v2 kustomize-controller's \
6335             health-gate evaluation",
6336        );
6337    }
6338
6339    #[test]
6340    fn cluster_bundle_two_helm_release_kind_axes_share_one_lifted_constant() {
6341        // Cross-axis pair invariant: the two rendered Flux bundle axes
6342        // that name the Flux v2 `HelmRelease` CRD discriminator
6343        // (helmrelease.yaml top-level kind, kustomization.yaml
6344        // spec.healthChecks[].kind) both consult one lifted
6345        // `&'static str`. The apiserver-side CRD resolution contract
6346        // is the `(apiVersion, kind)` tuple keyed against the
6347        // registered `CustomResourceDefinition`; the two axes must
6348        // move together on any future Flux v3 CRD rename (e.g.
6349        // `ChartRelease`) for the parent Kustomization's health gate
6350        // to bind to the sibling HelmRelease's renamed kind
6351        // discriminator. Peer to the sibling
6352        // [`cluster_bundle_three_git_repository_kind_axes_share_one_lifted_constant`]
6353        // cross-axis pin on the Flux v2 source-controller CRD kind
6354        // axis.
6355        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6356        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6357
6358        let hr_kind = serde_yaml::from_str::<serde_yaml::Value>(
6359            &files
6360                .iter()
6361                .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6362                .unwrap()
6363                .contents,
6364        )
6365        .unwrap()
6366        .get(KUBE_KEY_KIND)
6367        .and_then(|v| v.as_str())
6368        .map(String::from)
6369        .unwrap();
6370
6371        let kz_health_kind = serde_yaml::from_str::<serde_yaml::Value>(
6372            &files
6373                .iter()
6374                .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6375                .unwrap()
6376                .contents,
6377        )
6378        .unwrap()
6379        .get(KUBE_KEY_SPEC)
6380        .and_then(|s| s.get(FLUX_KEY_HEALTH_CHECKS))
6381        .and_then(|h| h.as_sequence())
6382        .and_then(|seq| seq.first())
6383        .and_then(|e| e.get(KUBE_KEY_KIND))
6384        .and_then(|v| v.as_str())
6385        .map(String::from)
6386        .unwrap();
6387
6388        assert_eq!(hr_kind, FLUX_KIND_HELM_RELEASE);
6389        assert_eq!(kz_health_kind, FLUX_KIND_HELM_RELEASE);
6390        assert_eq!(
6391            hr_kind, kz_health_kind,
6392            "helmrelease.yaml top-level kind and kustomization.yaml \
6393             spec.healthChecks[].kind must spell the same lifted constant \
6394             — drift here dangles the parent Kustomization's health gate \
6395             at the Flux v2 kustomize-controller"
6396        );
6397    }
6398
6399    #[test]
6400    fn flux_kind_kustomization_re_export_points_at_caixa_core_canonical() {
6401        // The renderer's `pub use caixa_core::FLUX_KIND_KUSTOMIZATION` is
6402        // the single source of truth for the Flux v2 `Kustomization` CRD
6403        // `kind` discriminator the rendered Flux bundle's
6404        // `Kustomization`-naming axis declares (the `kustomization.yaml`
6405        // top-level `kind`). Pin the equality (and the static-data
6406        // identity, peer with the sibling
6407        // [`flux_kind_git_repository_re_export_points_at_caixa_core_canonical`]
6408        // /
6409        // [`flux_kind_helm_release_re_export_points_at_caixa_core_canonical`]
6410        // pins) so any local re-introduction of a sibling
6411        // `pub const FLUX_KIND_KUSTOMIZATION: &str = "…"` (the canonical
6412        // drift footgun this lift closes — the load-bearing Flux v2
6413        // `Kustomization` CRD `kind` discriminator inside the
6414        // cluster_bundle template, lifted to one re-export at the
6415        // caixa-core boundary) is a build-time test failure naming the
6416        // offending drift, not a silent apply-time
6417        // `kustomize-controller` CRD-lookup miss that perpetually
6418        // freezes the rendered parent Kustomization and every
6419        // downstream per-Servico `dependsOn` chain.
6420        caixa_core::assert_str_reexport_identity(
6421            "FLUX_KIND_KUSTOMIZATION",
6422            FLUX_KIND_KUSTOMIZATION,
6423            caixa_core::FLUX_KIND_KUSTOMIZATION,
6424        );
6425    }
6426
6427    #[test]
6428    fn flux_key_source_ref_re_export_points_at_caixa_core_canonical() {
6429        // The renderer's `pub use caixa_core::FLUX_KEY_SOURCE_REF` is the
6430        // single source of truth for the Flux v2 per-`HelmRelease` /
6431        // `Kustomization` source-reference container-axis key the
6432        // rendered bundle documents mount their per-CR `(kind, name,
6433        // namespace)` reference triple under. Pin the equality (and the
6434        // static-data identity, peer with the sibling
6435        // [`flux_kind_git_repository_re_export_points_at_caixa_core_canonical`]
6436        // / [`flux_kind_helm_release_re_export_points_at_caixa_core_canonical`]
6437        // / [`flux_kind_kustomization_re_export_points_at_caixa_core_canonical`]
6438        // pins on the sibling per-CRD kind-discriminator surface) so any
6439        // local re-introduction of a sibling `pub const
6440        // FLUX_KEY_SOURCE_REF: &str = "…"` (the canonical drift footgun
6441        // where a sibling local `pub const` could happen to carry the
6442        // same string at the source while pointing at a different
6443        // `&'static` allocation) is a build-time test failure naming
6444        // the offending drift, not a silent apply-time dangling-
6445        // sourceRef reconciliation freeze (a rebrand on this axis
6446        // without a coordinated caixa-core edit silently dangles both
6447        // the `HelmRelease.spec.chart.spec.sourceRef` chart resolution
6448        // + the parent `Kustomization.spec.sourceRef` source resolution
6449        // at the Flux v2 source-controller's CRD registration; the
6450        // dependent per-Servico `dependsOn` chain freezes at apply time
6451        // with no field naming the container-axis-drift root cause).
6452        // Closes the sibling re-export identity axis on the same
6453        // trajectory the peer per-CRD-`kind`-discriminator pins carry.
6454        caixa_core::assert_str_reexport_identity(
6455            "FLUX_KEY_SOURCE_REF",
6456            FLUX_KEY_SOURCE_REF,
6457            caixa_core::FLUX_KEY_SOURCE_REF,
6458        );
6459    }
6460
6461    #[test]
6462    fn cluster_bundle_helmrelease_spec_chart_spec_source_ref_key_pins_lifted_flux_key_source_ref() {
6463        // Production-emit pin traversing a rendered `helmrelease.yaml`
6464        // document via parsed YAML: the `spec.chart.spec.sourceRef:\n`
6465        // sub-block header key baked into the [`cluster_bundle`]
6466        // `helmrelease.yaml` format-string template — the container-axis
6467        // key nesting the Flux v2 `HelmChartTemplate`'s per-CR
6468        // source-of-truth `(kind, name, namespace)` reference triple —
6469        // must resolve at the lifted [`FLUX_KEY_SOURCE_REF`] verbatim
6470        // byte-value. Before this sweep the site inlined `sourceRef:\n`
6471        // as a literal beside its sibling lifted `{chart_key}:` /
6472        // `{values_key}:` axes; a caixa-core rebrand of the const would
6473        // silently drift the probe path (`.get(FLUX_KEY_SOURCE_REF)`)
6474        // away from the emit path (baked `sourceRef:\n`), and a future
6475        // Flux v3 rename would land in the const while the emit-side
6476        // format-string template silently kept the old byte sequence.
6477        // The sweep threads the const through a `{source_ref_key}`
6478        // named-arg interpolation so both paths consult one
6479        // `&'static str`; this pin traverses the rendered document at
6480        // the lifted-const-keyed navigation and asserts a populated
6481        // sub-mapping (the `(kind, name, namespace)` triple) resolves
6482        // there, verifying that the emit path spells the exact const
6483        // byte-value. A regression that re-introduces an inline literal
6484        // in the format-string template surfaces as a `None` at the
6485        // lifted-const-keyed lookup. Peer to the sibling
6486        // [`cluster_bundle_kustomization_spec_source_ref_key_pins_lifted_flux_key_source_ref`]
6487        // pin closing the second production emit site on the same
6488        // container-axis, and to the sibling
6489        // [`cluster_bundle_helmrelease_values_block_uses_lifted_flux_key_values`]
6490        // pin on the sibling per-`HelmRelease` body-key surface.
6491        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6492        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6493        let hr = files
6494            .iter()
6495            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6496            .expect("helmrelease.yaml present");
6497        let parsed: serde_yaml::Value =
6498            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6499        let source_ref = parsed
6500            .get(KUBE_KEY_SPEC)
6501            .and_then(|s| s.get(FLUX_KEY_CHART))
6502            .and_then(|c| c.get(KUBE_KEY_SPEC))
6503            .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6504            .and_then(|r| r.as_mapping())
6505            .expect("spec.chart.spec.<FLUX_KEY_SOURCE_REF> mapping present");
6506        assert!(
6507            !source_ref.is_empty(),
6508            "spec.chart.spec.<FLUX_KEY_SOURCE_REF> ({FLUX_KEY_SOURCE_REF:?}) \
6509             must carry the `(kind, name, namespace)` reference triple; drift \
6510             on this container-axis key silently dangles the HelmRelease's \
6511             chart resolution at the Flux v2 source-controller's CRD \
6512             registration"
6513        );
6514    }
6515
6516    #[test]
6517    fn cluster_bundle_kustomization_spec_source_ref_key_pins_lifted_flux_key_source_ref() {
6518        // Production-emit pin traversing a rendered `kustomization.yaml`
6519        // document via parsed YAML: the `spec.sourceRef:\n` sub-block
6520        // header key baked into the [`cluster_bundle`]
6521        // `kustomization.yaml` format-string template — the
6522        // container-axis key nesting the parent `Kustomization`'s
6523        // source-of-truth `(kind, name)` reference pair pointing back at
6524        // the cluster's bootstrap `GitRepository` — must resolve at the
6525        // lifted [`FLUX_KEY_SOURCE_REF`] verbatim byte-value. Before
6526        // this sweep the site inlined `sourceRef:\n` as a literal
6527        // beside its sibling lifted `{interval_key}:` /
6528        // `{health_checks_key}:` axes; a caixa-core rebrand of the
6529        // const would silently drift the probe path away from the emit
6530        // path, and a future Flux v3 rename would land in the const
6531        // while this format-string template silently kept the old byte
6532        // sequence. The sweep threads the const through a
6533        // `{source_ref_key}` named-arg interpolation so both paths
6534        // consult one `&'static str`; this pin traverses the rendered
6535        // document at the lifted-const-keyed navigation and asserts a
6536        // populated sub-mapping resolves there. A regression that
6537        // re-introduces an inline literal surfaces as a `None` at the
6538        // lifted-const-keyed lookup. Peer to the sibling
6539        // [`cluster_bundle_helmrelease_spec_chart_spec_source_ref_key_pins_lifted_flux_key_source_ref`]
6540        // pin closing the first production emit site on the same
6541        // container-axis, together closing the two-site production
6542        // emit sweep the peer [`FLUX_KEY_SOURCE_REF`] doc block calls
6543        // out.
6544        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6545        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6546        let kz = files
6547            .iter()
6548            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6549            .expect("kustomization.yaml present");
6550        let parsed: serde_yaml::Value =
6551            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
6552        let source_ref = parsed
6553            .get(KUBE_KEY_SPEC)
6554            .and_then(|s| s.get(FLUX_KEY_SOURCE_REF))
6555            .and_then(|r| r.as_mapping())
6556            .expect("spec.<FLUX_KEY_SOURCE_REF> mapping present");
6557        assert!(
6558            !source_ref.is_empty(),
6559            "spec.<FLUX_KEY_SOURCE_REF> ({FLUX_KEY_SOURCE_REF:?}) must \
6560             carry the `(kind, name)` reference pair pointing at the \
6561             cluster's bootstrap GitRepository; drift on this \
6562             container-axis key silently dangles the parent \
6563             Kustomization's source resolution at the Flux v2 \
6564             source-controller's CRD registration"
6565        );
6566    }
6567
6568    #[test]
6569    fn flux_key_values_re_export_points_at_caixa_core_canonical() {
6570        // The renderer's `pub use caixa_core::FLUX_KEY_VALUES` is the
6571        // single source of truth for the Flux v2 per-`HelmRelease`
6572        // values-override block-body-axis key the rendered
6573        // `helmrelease.yaml` nests its per-cluster override YAML under.
6574        // Pin the equality (and the static-data identity, peer with the
6575        // sibling
6576        // [`flux_key_source_ref_re_export_points_at_caixa_core_canonical`]
6577        // pin on the sibling Flux v2 per-CR container-axis-key surface)
6578        // so any local re-introduction of a sibling `pub const
6579        // FLUX_KEY_VALUES: &str = "…"` (the canonical drift footgun
6580        // where a sibling local `pub const` could happen to carry the
6581        // same string at the source while pointing at a different
6582        // `&'static` allocation) is a build-time test failure naming
6583        // the offending drift, not a silent apply-time per-cluster-
6584        // override-routed-nowhere reconciliation (a rebrand on this
6585        // axis without a coordinated caixa-core edit silently routes
6586        // the per-cluster override YAML nowhere at Helm-render time;
6587        // the workload silently comes up with the referenced chart's
6588        // admission-time defaults, far from the source `caixa.lisp` /
6589        // the renderer's format-string template). Closes the sibling
6590        // re-export identity axis on the same trajectory the peer
6591        // [`flux_key_source_ref_re_export_points_at_caixa_core_canonical`]
6592        // pin carries.
6593        caixa_core::assert_str_reexport_identity(
6594            "FLUX_KEY_VALUES",
6595            FLUX_KEY_VALUES,
6596            caixa_core::FLUX_KEY_VALUES,
6597        );
6598    }
6599
6600    #[test]
6601    fn cluster_bundle_helmrelease_values_block_uses_lifted_flux_key_values() {
6602        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`'s
6603        // top-level `spec.values` block-body-axis key — the scope under
6604        // which per-cluster overrides reach the referenced chart at
6605        // Flux v2 `helm-controller` reconcile time — must resolve to the
6606        // lifted [`FLUX_KEY_VALUES`] verbatim. Before the lift this
6607        // site carried an inline `values:\n` literal in the format
6608        // string; a future Flux v3 rebrand on this axis (a hypothetical
6609        // upstream fluxcd/flux2 rename from `values` to `Values` /
6610        // `chartValues` / `overrides`, coordinated with the upstream
6611        // project's per-version deprecation cycle) without a
6612        // coordinated edit here would have silently routed the per-
6613        // cluster override YAML nowhere at `helm-controller` reconcile
6614        // time — the workload's per-cluster overrides never reach the
6615        // referenced chart, and the apply comes up with the chart's
6616        // admission-time defaults far from the rebrand commit's source.
6617        //
6618        // The pin is structural: parse the rendered YAML and assert the
6619        // per-`HelmRelease` values-override block-body-axis key resolves
6620        // under the lifted constant (not `.get("values")` — that is the
6621        // sibling literal-shape probe the peer test at line 1955 pins;
6622        // this test asserts the lifted-const-keyed navigation carries a
6623        // populated mapping under it). A regression that re-introduces
6624        // an inline literal in the format-string template surfaces as a
6625        // `None` at the lifted-const-keyed lookup (the inline literal
6626        // would survive, but the lifted-const-keyed assertion would
6627        // fail). Peer to the sibling
6628        // [`cluster_bundle_helmrelease_values_wrap_key_uses_lifted_constant`]
6629        // pin on the sibling per-`HelmRelease` inner-wrap-key surface
6630        // — extends the canonical-Flux-v2-per-`HelmRelease`-values-
6631        // navigation lift from the wrap-key axis onto the outer block-
6632        // body-axis this test targets.
6633        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6634        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6635        let hr = files
6636            .iter()
6637            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6638            .expect("helmrelease.yaml present");
6639        let parsed: serde_yaml::Value =
6640            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6641        let values = parsed
6642            .get(KUBE_KEY_SPEC)
6643            .and_then(|s| s.get(FLUX_KEY_VALUES))
6644            .and_then(|v| v.as_mapping())
6645            .expect("spec.<FLUX_KEY_VALUES> mapping present");
6646        assert!(
6647            !values.is_empty(),
6648            "spec.<FLUX_KEY_VALUES> ({FLUX_KEY_VALUES:?}) must carry \
6649             at least the lifted-[`DEFAULT_LIBRARY_NAME`]-wrapped per-\
6650             cluster override block; drift on this block-body-axis key \
6651             silently routes overrides nowhere at helm-controller \
6652             reconcile time"
6653        );
6654    }
6655
6656    #[test]
6657    fn cluster_bundle_kustomization_kind_uses_lifted_flux_kind_kustomization() {
6658        // Fail-before-pass-after pin: the rendered `kustomization.yaml`
6659        // top-level `kind` axis — the load-bearing K8s CRD discriminator
6660        // the Flux v2 `kustomize-controller` resolves the rendered
6661        // document against — must resolve to the lifted
6662        // [`FLUX_KIND_KUSTOMIZATION`] verbatim. Before this lift the
6663        // kustomization template carried an inline `Kustomization`
6664        // literal; the apiserver-side CRD resolution contract is the
6665        // `(apiVersion, kind)` tuple keyed against the registered
6666        // `CustomResourceDefinition`, so drift on the kind axis is
6667        // exactly as load-bearing as drift on the sibling
6668        // [`FLUX_KUSTOMIZATION_API_VERSION`] axis (a future Flux v3
6669        // rebrand on this axis without a coordinated edit on the
6670        // sibling apiVersion axis silently lands the rendered
6671        // `Kustomization` outside the kustomize-controller's `Watches`
6672        // and surfaces at apply parse time as a non-self-locating
6673        // "no kind 'Kustomization' is registered" error far from the
6674        // rebrand commit's source). Peer with
6675        // [`cluster_bundle_kustomization_uses_lifted_flux_kustomization_api_version`]
6676        // on the sibling apiVersion half of the same CRD-lookup tuple,
6677        // and with
6678        // [`cluster_bundle_helmrelease_kind_uses_lifted_flux_kind_helm_release`]
6679        // /
6680        // [`cluster_bundle_gitrepository_kind_uses_lifted_flux_kind_git_repository`]
6681        // on the sibling Flux v2 controller-triplet CRD kind axes.
6682        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6683        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6684        let kz = files
6685            .iter()
6686            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6687            .expect("kustomization.yaml present");
6688        let parsed: serde_yaml::Value =
6689            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
6690        assert_eq!(
6691            kube_root_str_field(&parsed, KUBE_KEY_KIND),
6692            Some(FLUX_KIND_KUSTOMIZATION),
6693            "kustomization.yaml top-level kind must spell the lifted \
6694             FLUX_KIND_KUSTOMIZATION ({FLUX_KIND_KUSTOMIZATION:?}); a drifted \
6695             literal here routes the Kustomization outside the Flux v2 \
6696             kustomize-controller's CRD registration",
6697        );
6698    }
6699
6700    #[test]
6701    fn flux_key_chart_re_export_points_at_caixa_core_canonical() {
6702        // The renderer's `pub use caixa_core::FLUX_KEY_CHART` is the
6703        // single source of truth for the Flux v2 per-`HelmRelease`
6704        // chart-template container-axis key the rendered
6705        // `helmrelease.yaml` nests its per-CR `HelmChartTemplate`
6706        // sub-document under. Pin the equality (and the static-data
6707        // identity, peer with the sibling
6708        // [`flux_key_source_ref_re_export_points_at_caixa_core_canonical`]
6709        // / [`flux_key_values_re_export_points_at_caixa_core_canonical`]
6710        // pins on the sibling Flux v2 per-`HelmRelease` body-key
6711        // surfaces) so any local re-introduction of a sibling `pub
6712        // const FLUX_KEY_CHART: &str = "…"` (the canonical drift
6713        // footgun where a sibling local `pub const` could happen to
6714        // carry the same string at the source while pointing at a
6715        // different `&'static` allocation) is a build-time test
6716        // failure naming the offending drift, not a silent apply-
6717        // time dangling-chart-template reconciliation freeze (a
6718        // rebrand on this axis without a coordinated caixa-core edit
6719        // silently dangles the `HelmRelease.spec.chart` chart-
6720        // template resolution at the Flux v2 helm-controller's CRD
6721        // registration; the referenced chart never resolves and the
6722        // per-Servico workload freezes at apply time with no field
6723        // naming the container-axis-drift root cause). Closes the
6724        // sibling re-export identity axis on the same trajectory the
6725        // peer per-CR body-key pins carry.
6726        caixa_core::assert_str_reexport_identity(
6727            "FLUX_KEY_CHART",
6728            FLUX_KEY_CHART,
6729            caixa_core::FLUX_KEY_CHART,
6730        );
6731    }
6732
6733    #[test]
6734    fn cluster_bundle_helmrelease_chart_block_uses_lifted_flux_key_chart() {
6735        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`'s
6736        // top-level `spec.chart` container-axis key — the scope under
6737        // which the Flux v2 `HelmChartTemplate` sub-document lives (the
6738        // `HelmChartTemplate.spec` block that carries the chart-name
6739        // leaf, source-of-truth reference triple, and per-CR reconcile
6740        // cadence the Flux v2 `helm-controller`'s per-CR reconcile loop
6741        // reads to source the referenced chart at Helm-render time) —
6742        // must resolve to the lifted [`FLUX_KEY_CHART`] verbatim.
6743        // Before the lift this site carried an inline `chart:\n`
6744        // literal in the format string; a future Flux v3 rebrand on
6745        // this axis (a hypothetical upstream fluxcd/flux2 rename from
6746        // `chart` to `Chart` / `chartTemplate` / `helmChart` /
6747        // `chartRef`, coordinated with the upstream project's per-
6748        // version deprecation cycle) without a coordinated edit here
6749        // would have silently dangled the whole chart-template block
6750        // at `helm-controller` reconcile time — the workload's
6751        // referenced chart never resolves, and the apply freezes at
6752        // the CRD-registration boundary far from the rebrand commit's
6753        // source.
6754        //
6755        // The pin is structural: parse the rendered YAML and assert
6756        // the per-`HelmRelease` chart-template container-axis key
6757        // resolves under the lifted constant with a populated
6758        // `HelmChartTemplate.spec` sub-mapping under it. A regression
6759        // that re-introduces an inline literal in the format-string
6760        // template surfaces as a `None` at the lifted-const-keyed
6761        // lookup. Peer to the sibling
6762        // [`cluster_bundle_helmrelease_values_block_uses_lifted_flux_key_values`]
6763        // pin on the sibling per-`HelmRelease` values-override block-
6764        // body-axis surface — extends the canonical-Flux-v2-per-
6765        // `HelmRelease`-body-key lifted-const-keyed pin discipline
6766        // from the values-override block-body-axis onto the sibling
6767        // chart-template container-axis this test targets.
6768        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6769        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6770        let hr = files
6771            .iter()
6772            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6773            .expect("helmrelease.yaml present");
6774        let parsed: serde_yaml::Value =
6775            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6776        let chart = parsed
6777            .get(KUBE_KEY_SPEC)
6778            .and_then(|s| s.get(FLUX_KEY_CHART))
6779            .and_then(|v| v.as_mapping())
6780            .expect("spec.<FLUX_KEY_CHART> mapping present");
6781        assert!(
6782            !chart.is_empty(),
6783            "spec.<FLUX_KEY_CHART> ({FLUX_KEY_CHART:?}) must carry \
6784             at least the nested `HelmChartTemplate.spec` sub-document; \
6785             drift on this container-axis key silently dangles the \
6786             whole chart-template block at helm-controller reconcile time"
6787        );
6788    }
6789
6790    #[test]
6791    fn flux_helmchart_template_key_chart_re_export_points_at_caixa_core_canonical() {
6792        // The renderer's `pub use caixa_core::FLUX_HELMCHART_TEMPLATE_KEY_CHART`
6793        // is the single source of truth for the Flux v2 per-`HelmChartTemplate`
6794        // chart-NAME reference leaf-scalar-axis key the rendered
6795        // `helmrelease.yaml`'s `spec.chart.spec.chart` leaf-scalar-
6796        // valued field carries the chart-artifact name at the
6797        // helm-controller's per-CR reconcile-time chart-lookup axis.
6798        // Pin the equality (and the static-data identity, peer with
6799        // the sibling [`flux_key_chart_re_export_points_at_caixa_core_canonical`]
6800        // pin on the parent container-axis re-export the leaf-scalar-
6801        // axis nests inside) so any local re-introduction of a sibling
6802        // `pub const FLUX_HELMCHART_TEMPLATE_KEY_CHART: &str = "…"`
6803        // (the canonical drift footgun this lift closes — the one
6804        // production-code call site the `cluster_bundle`
6805        // `helmrelease.yaml` format-string template threaded the
6806        // chart-NAME leaf-scalar-key through, lifted to one re-export
6807        // at the caixa-core boundary) is a build-time test failure
6808        // naming the offending drift, not a silent apply-time
6809        // "chart 'unknown' not found in <source>" reconciliation
6810        // dangle the CRD's OpenAPI extra-property schema permits at
6811        // the apiserver.
6812        caixa_core::assert_str_reexport_identity(
6813            "FLUX_HELMCHART_TEMPLATE_KEY_CHART",
6814            FLUX_HELMCHART_TEMPLATE_KEY_CHART,
6815            caixa_core::FLUX_HELMCHART_TEMPLATE_KEY_CHART,
6816        );
6817    }
6818
6819    #[test]
6820    fn cluster_bundle_helmrelease_chart_name_leaf_uses_lifted_flux_helmchart_template_key_chart() {
6821        // Fail-before-pass-after pin: the rendered `helmrelease.yaml`'s
6822        // per-`HelmChartTemplate.spec.chart` chart-NAME reference
6823        // leaf-scalar-valued field — the load-bearing chart-lookup
6824        // scalar the Flux v2 helm-controller resolves the referenced
6825        // chart artifact through the sibling `sourceRef` triple's
6826        // source at reconcile time by — must resolve under the lifted
6827        // [`FLUX_HELMCHART_TEMPLATE_KEY_CHART`] leaf-scalar-axis key
6828        // and carry the `ClusterBundleOpts.chart_path` value verbatim.
6829        // Before this lift the leaf site carried an inline `chart:`
6830        // literal at the `cluster_bundle` `helmrelease.yaml` format-
6831        // string template's chart-name-leaf interpolation site — a
6832        // future Flux v3 rebrand on this axis (a hypothetical upstream
6833        // fluxcd/flux2 rename from `chart` to `Chart` / `chartRef` /
6834        // `chartName`) without a coordinated edit on the canonical
6835        // caixa-core const would have silently dangled the chart-
6836        // artifact resolution at the helm-controller's per-CR
6837        // reconcile-time chart-lookup with a non-self-locating
6838        // "chart 'unknown' not found in <source>" error far from the
6839        // rebrand commit's source. Peer to
6840        // [`cluster_bundle_helmrelease_chart_block_uses_lifted_flux_key_chart`]
6841        // on the parent container-axis surface — extends the pin
6842        // discipline one level beneath by asserting the chart-NAME
6843        // leaf-scalar under the container-axis carries the lifted
6844        // constant.
6845        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6846        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6847        let hr = files
6848            .iter()
6849            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
6850            .expect("helmrelease.yaml present");
6851        let parsed: serde_yaml::Value =
6852            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
6853        let chart_name = parsed
6854            .get(KUBE_KEY_SPEC)
6855            .and_then(|s| s.get(FLUX_KEY_CHART))
6856            .and_then(|c| c.get(KUBE_KEY_SPEC))
6857            .and_then(|s| s.get(FLUX_HELMCHART_TEMPLATE_KEY_CHART))
6858            .and_then(|n| n.as_str())
6859            .expect("spec.chart.spec.<FLUX_HELMCHART_TEMPLATE_KEY_CHART> scalar present");
6860        assert_eq!(
6861            chart_name,
6862            opts.chart_path,
6863            "spec.chart.spec.<FLUX_HELMCHART_TEMPLATE_KEY_CHART> \
6864             ({FLUX_HELMCHART_TEMPLATE_KEY_CHART:?}) leaf-scalar must carry the \
6865             ClusterBundleOpts.chart_path verbatim ({expected:?}); a drifted \
6866             key here silently dangles the chart-artifact resolution at the \
6867             Flux v2 helm-controller's per-CR reconcile-time chart-lookup axis",
6868            expected = opts.chart_path,
6869        );
6870    }
6871
6872    #[test]
6873    fn flux_key_health_checks_re_export_points_at_caixa_core_canonical() {
6874        // The renderer's `pub use caixa_core::FLUX_KEY_HEALTH_CHECKS` is
6875        // the single source of truth for the Flux v2 per-`Kustomization`
6876        // health-gate reference-list container-axis key the rendered
6877        // `kustomization.yaml` nests its per-entry
6878        // `[]NamespacedObjectKindReference` list under. Pin the
6879        // equality (and the static-data identity, peer with the sibling
6880        // [`flux_key_source_ref_re_export_points_at_caixa_core_canonical`]
6881        // / [`flux_key_chart_re_export_points_at_caixa_core_canonical`]
6882        // / [`flux_key_values_re_export_points_at_caixa_core_canonical`]
6883        // pins on the sibling Flux v2 body-key surfaces) so any local
6884        // re-introduction of a sibling `pub const FLUX_KEY_HEALTH_CHECKS:
6885        // &str = "…"` (the canonical drift footgun where a sibling local
6886        // `pub const` could happen to carry the same string at the
6887        // source while pointing at a different `&'static` allocation) is
6888        // a build-time test failure naming the offending drift, not a
6889        // silent apply-time dangling-health-gate reconciliation freeze
6890        // (a rebrand on this axis without a coordinated caixa-core edit
6891        // silently dangles the `Kustomization.spec.healthChecks` health-
6892        // gate at the Flux v2 kustomize-controller's per-CR reconcile
6893        // loop; the parent Kustomization stays at `Reconciling` forever
6894        // and the dependent per-cluster fleet-programs upsert chain
6895        // never sees `Ready=True` at apply time with no field naming
6896        // the container-axis-drift root cause). Closes the sibling re-
6897        // export identity axis on the same trajectory the peer per-CR
6898        // body-key pins carry — completes the quartet.
6899        caixa_core::assert_str_reexport_identity(
6900            "FLUX_KEY_HEALTH_CHECKS",
6901            FLUX_KEY_HEALTH_CHECKS,
6902            caixa_core::FLUX_KEY_HEALTH_CHECKS,
6903        );
6904    }
6905
6906    #[test]
6907    fn cluster_bundle_kustomization_health_checks_block_uses_lifted_flux_key_health_checks() {
6908        // Fail-before-pass-after pin: the rendered `kustomization.yaml`'s
6909        // top-level `spec.healthChecks` container-axis key — the scope
6910        // under which the Flux v2 `[]NamespacedObjectKindReference` list
6911        // lives (the per-entry `(apiVersion, kind, name, namespace)`
6912        // triples the Flux v2 `kustomize-controller`'s per-CR reconcile
6913        // loop reads to gate the parent Kustomization's `Ready=True`
6914        // transition on the referenced sibling `HelmRelease` reaching its
6915        // `HelmReleaseReady=True` condition) — must resolve to the
6916        // lifted [`FLUX_KEY_HEALTH_CHECKS`] verbatim. Before the lift
6917        // this site carried an inline `healthChecks:\n` literal in the
6918        // `kustomization` format string; a future Flux v3 rebrand on
6919        // this axis (a hypothetical upstream fluxcd/flux2 rename from
6920        // `healthChecks` to `HealthChecks` / `healthchecks` /
6921        // `healthcheck` / `health_checks` / `probes`, coordinated with
6922        // the upstream project's per-version deprecation cycle) without
6923        // a coordinated edit here would have silently dangled the whole
6924        // health-gate reference-list at `kustomize-controller` reconcile
6925        // time — the parent Kustomization stays at `Reconciling`
6926        // forever, and the dependent per-cluster fleet-programs upsert
6927        // chain never sees `Ready=True` far from the rebrand commit's
6928        // source.
6929        //
6930        // The pin is structural: parse the rendered YAML and assert the
6931        // per-`Kustomization` health-gate reference-list container-axis
6932        // key resolves under the lifted constant with a non-empty
6933        // sequence under it. A regression that re-introduces an inline
6934        // literal in the format-string template surfaces as a `None` at
6935        // the lifted-const-keyed lookup. Peer to the sibling
6936        // [`cluster_bundle_helmrelease_chart_block_uses_lifted_flux_key_chart`]
6937        // / [`cluster_bundle_helmrelease_values_block_uses_lifted_flux_key_values`]
6938        // pins on the sibling per-`HelmRelease` body-key surfaces —
6939        // extends the canonical-Flux-v2-body-key lifted-const-keyed pin
6940        // discipline from the per-`HelmRelease` triplet onto the sibling
6941        // per-`Kustomization` `spec.healthChecks` reference-list
6942        // container-axis this test targets, completing the quartet.
6943        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
6944        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
6945        let kz = files
6946            .iter()
6947            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
6948            .expect("kustomization.yaml present");
6949        let parsed: serde_yaml::Value =
6950            serde_yaml::from_str(&kz.contents).expect("kustomization.yaml parses as YAML");
6951        let health_checks = parsed
6952            .get(KUBE_KEY_SPEC)
6953            .and_then(|s| s.get(FLUX_KEY_HEALTH_CHECKS))
6954            .and_then(|v| v.as_sequence())
6955            .expect("spec.<FLUX_KEY_HEALTH_CHECKS> sequence present");
6956        assert!(
6957            !health_checks.is_empty(),
6958            "spec.<FLUX_KEY_HEALTH_CHECKS> ({FLUX_KEY_HEALTH_CHECKS:?}) must \
6959             carry at least one `[]NamespacedObjectKindReference` entry; \
6960             drift on this container-axis key silently dangles the whole \
6961             health-gate at kustomize-controller reconcile time and freezes \
6962             the parent Kustomization at `Reconciling`"
6963        );
6964    }
6965
6966    #[test]
6967    fn flux_key_interval_re_export_points_at_caixa_core_canonical() {
6968        // The renderer's `pub use caixa_core::FLUX_KEY_INTERVAL` is the
6969        // single source of truth for the Flux v2 per-CR reconcile-poll
6970        // cadence scalar-axis key the three rendered Flux documents
6971        // (`gitrepository.yaml`, `helmrelease.yaml`, `kustomization.yaml`)
6972        // each carry as their `spec.interval` scalar. Pin the equality
6973        // (and the static-data identity, peer with the sibling
6974        // [`flux_key_source_ref_re_export_points_at_caixa_core_canonical`]
6975        // / [`flux_key_chart_re_export_points_at_caixa_core_canonical`]
6976        // / [`flux_key_values_re_export_points_at_caixa_core_canonical`]
6977        // / [`flux_key_health_checks_re_export_points_at_caixa_core_canonical`]
6978        // pins on the sibling Flux v2 per-CR body-key surfaces) so any
6979        // local re-introduction of a sibling `pub const FLUX_KEY_INTERVAL:
6980        // &str = "…"` (the canonical drift footgun where a sibling local
6981        // `pub const` could happen to carry the same string at the
6982        // source while pointing at a different `&'static` allocation) is
6983        // a build-time test failure naming the offending drift, not a
6984        // silent apply-time three-way reconcile freeze (a rebrand on
6985        // this axis without a coordinated caixa-core edit silently drops
6986        // the per-CR reconcile schedule from all three Flux v2
6987        // controllers' per-CR watch registrations simultaneously — the
6988        // referenced Git source never re-polls / the referenced chart
6989        // never re-templates / the parent Kustomization never re-applies
6990        // at upstream drift, freezing the whole cluster's per-`caixa`
6991        // per-cluster bundle at the last-applied snapshot with no field
6992        // naming the axis-drift root cause). Closes the re-export
6993        // identity axis on the same trajectory the peer per-CR body-key
6994        // pins carry — extends the discipline from the per-CR body-key
6995        // quartet onto the sibling cross-CR-shared reconcile-poll cadence
6996        // scalar-axis every Flux v2 controller reads.
6997        caixa_core::assert_str_reexport_identity(
6998            "FLUX_KEY_INTERVAL",
6999            FLUX_KEY_INTERVAL,
7000            caixa_core::FLUX_KEY_INTERVAL,
7001        );
7002    }
7003
7004    #[test]
7005    fn flux_gitrepository_ref_key_tag_re_export_points_at_caixa_core_canonical() {
7006        // The renderer's `pub use caixa_core::FLUX_GITREPOSITORY_REF_KEY_TAG`
7007        // is the single source of truth for the FluxCD source-controller
7008        // `GitRepository.spec.ref.tag` sub-selector scalar-axis key the
7009        // rendered `gitrepository.yaml` document declares on the tag-arm
7010        // of the [`GitRefSpec`] discriminated-union. Pin the equality +
7011        // `&'static` static-data identity so any local re-introduction
7012        // of a sibling `pub const FLUX_GITREPOSITORY_REF_KEY_TAG: &str
7013        // = "…"` at this crate is a build-time test failure naming the
7014        // offending drift, not a silent apply-time `GitRepository`
7015        // sub-selector reroute at cluster-side reconcile time. Peer to
7016        // [`flux_key_interval_re_export_points_at_caixa_core_canonical`]
7017        // on the sibling per-CR body-key surface — pivots the
7018        // canonical-lifted-const single-sourcing discipline onto the
7019        // per-`GitRepository`-`spec.ref`-sub-selector axis.
7020        caixa_core::assert_str_reexport_identity(
7021            "FLUX_GITREPOSITORY_REF_KEY_TAG",
7022            FLUX_GITREPOSITORY_REF_KEY_TAG,
7023            caixa_core::FLUX_GITREPOSITORY_REF_KEY_TAG,
7024        );
7025    }
7026
7027    #[test]
7028    fn flux_gitrepository_ref_key_branch_re_export_points_at_caixa_core_canonical() {
7029        // Peer of
7030        // [`flux_gitrepository_ref_key_tag_re_export_points_at_caixa_core_canonical`]
7031        // on the branch-arm of the FluxCD source-controller
7032        // `GitRepository.spec.ref` discriminated-union axis.
7033        caixa_core::assert_str_reexport_identity(
7034            "FLUX_GITREPOSITORY_REF_KEY_BRANCH",
7035            FLUX_GITREPOSITORY_REF_KEY_BRANCH,
7036            caixa_core::FLUX_GITREPOSITORY_REF_KEY_BRANCH,
7037        );
7038    }
7039
7040    #[test]
7041    fn flux_gitrepository_ref_key_commit_re_export_points_at_caixa_core_canonical() {
7042        // Peer of
7043        // [`flux_gitrepository_ref_key_tag_re_export_points_at_caixa_core_canonical`]
7044        // on the commit-arm of the FluxCD source-controller
7045        // `GitRepository.spec.ref` discriminated-union axis.
7046        caixa_core::assert_str_reexport_identity(
7047            "FLUX_GITREPOSITORY_REF_KEY_COMMIT",
7048            FLUX_GITREPOSITORY_REF_KEY_COMMIT,
7049            caixa_core::FLUX_GITREPOSITORY_REF_KEY_COMMIT,
7050        );
7051    }
7052
7053    #[test]
7054    fn flux_gitrepository_key_ref_re_export_points_at_caixa_core_canonical() {
7055        // Bridge-arm pin: the re-exported FLUX_GITREPOSITORY_KEY_REF
7056        // resolves to the canonical `"ref"` byte + `&'static`
7057        // allocation from caixa-core, closing the local-`pub const`-
7058        // shadow footgun where a sibling `pub const
7059        // FLUX_GITREPOSITORY_KEY_REF: &str = "…"` in this crate could
7060        // silently carry the same string at the source while pointing
7061        // at a different `&'static` allocation. Peer of the sibling
7062        // [`flux_gitrepository_ref_key_tag_re_export_points_at_caixa_core_canonical`]
7063        // / [`flux_gitrepository_ref_key_branch_re_export_points_at_caixa_core_canonical`]
7064        // / [`flux_gitrepository_ref_key_commit_re_export_points_at_caixa_core_canonical`]
7065        // pins on the sibling per-shape arm axes of the FluxCD source-
7066        // controller `GitRepository.spec.ref` discriminated-union — closes
7067        // the parent-container-axis KEY pin above the already-pinned
7068        // per-shape arm sub-selector-KEY triple, so the whole per-
7069        // `GitRepository` `spec.ref` sub-schema (parent container-axis
7070        // KEY + per-shape arm sub-selector-KEY triple) now navigates
7071        // through four caixa-core `&'static str`s pinned in coordination.
7072        caixa_core::assert_str_reexport_identity(
7073            "FLUX_GITREPOSITORY_KEY_REF",
7074            FLUX_GITREPOSITORY_KEY_REF,
7075            caixa_core::FLUX_GITREPOSITORY_KEY_REF,
7076        );
7077    }
7078
7079    #[test]
7080    fn cluster_bundle_gitrepository_spec_ref_key_pins_lifted_flux_gitrepository_key_ref() {
7081        // Production-emit pin: traverse a rendered `gitrepository.yaml`
7082        // document's `spec` block and assert the ref-selection
7083        // discriminated-union parent container-axis is keyed by the
7084        // *lifted* FLUX_GITREPOSITORY_KEY_REF (`"ref"`) verbatim — the
7085        // load-bearing per-`GitRepository` `spec.ref` container-axis
7086        // KEY the FluxCD source-controller reads to source the per-CR
7087        // git-clone refspec. Before the lift the writer template
7088        // carried an inline `ref:\n` literal at the sole
7089        // `format!("… spec:\n  ref:\n{gitref_field}\n", …)` call in
7090        // `cluster_bundle`; a typo there (`"gitRef:"` / `"Ref:"` /
7091        // `"revision:"` / `"source:"`) would have silently landed a
7092        // `GitRepository` whose ref-selection container-axis the CRD
7093        // schema validator drops as unknown at admission, and every
7094        // downstream `HelmRelease` / `Kustomization` bundle document
7095        // that resolves through the sibling
7096        // `HelmRelease.spec.chart.spec.sourceRef` reference would have
7097        // silently dangled at the FluxCD apply chain with no field
7098        // naming the container-axis-drift root cause. Peer of the
7099        // sibling per-shape arm sub-selector-KEY test
7100        // [`cluster_bundle_gitrepository_ref_key_dispatches_per_variant_onto_lifted_consts`]
7101        // on the peer per-arm scalar-axis surface — closes the parent
7102        // container-axis pin above the already-pinned per-shape arm
7103        // sub-selector-KEY triple.
7104        let caixa = sample_caixa();
7105        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7106        let files = cluster_bundle(&caixa, &opts).expect("bundle renders");
7107        let gr = files
7108            .iter()
7109            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
7110            .expect("gitrepository.yaml present");
7111        let parsed: serde_yaml::Value =
7112            serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
7113        assert!(
7114            parsed
7115                .get(KUBE_KEY_SPEC)
7116                .and_then(|s| s.get(FLUX_GITREPOSITORY_KEY_REF))
7117                .is_some(),
7118            "rendered gitrepository.yaml must carry its ref-selection \
7119             container-axis at the lifted FLUX_GITREPOSITORY_KEY_REF key \
7120             verbatim (got: {:?})",
7121            gr.contents
7122        );
7123    }
7124
7125    #[test]
7126    fn flux_gitrepository_key_url_re_export_points_at_caixa_core_canonical() {
7127        // Bridge-arm pin: the re-exported FLUX_GITREPOSITORY_KEY_URL
7128        // resolves to the canonical `"url"` byte + `&'static`
7129        // allocation from caixa-core, closing the local-`pub const`-
7130        // shadow footgun where a sibling `pub const
7131        // FLUX_GITREPOSITORY_KEY_URL: &str = "…"` in this crate could
7132        // silently carry the same string at the source while pointing
7133        // at a different `&'static` allocation. Peer of the sibling
7134        // [`flux_gitrepository_key_ref_re_export_points_at_caixa_core_canonical`]
7135        // pin on the sibling per-CR `spec.ref` container-axis re-export
7136        // surface — closes the second per-`GitRepository` sub-block
7137        // key re-export identity pin, extending the discipline from
7138        // the container-axis surface onto the leaf-scalar remote-URL
7139        // axis.
7140        caixa_core::assert_str_reexport_identity(
7141            "FLUX_GITREPOSITORY_KEY_URL",
7142            FLUX_GITREPOSITORY_KEY_URL,
7143            caixa_core::FLUX_GITREPOSITORY_KEY_URL,
7144        );
7145    }
7146
7147    #[test]
7148    fn cluster_bundle_gitrepository_spec_url_key_pins_lifted_flux_gitrepository_key_url() {
7149        // Production-emit pin: traverse a rendered `gitrepository.yaml`
7150        // document's `spec` block and assert the remote-repo-URL leaf-
7151        // scalar-axis is keyed by the *lifted*
7152        // FLUX_GITREPOSITORY_KEY_URL (`"url"`) verbatim — the load-
7153        // bearing per-`GitRepository` `spec.url` leaf-scalar-axis KEY
7154        // the FluxCD source-controller reads to source the per-CR
7155        // git-remote clone target. Before the lift the writer template
7156        // carried an inline `url: {url}\n` literal at the sole
7157        // `format!(…)` call in `cluster_bundle`'s gitrepo composer;
7158        // a typo there (`"URL:"` / `"gitUrl:"` / `"repository:"` /
7159        // `"repo:"`) would have silently landed a `GitRepository`
7160        // whose CRD schema validator drops the URL field as unknown
7161        // at admission, the per-Servico artifact would never populate,
7162        // and every downstream `HelmRelease` / `Kustomization` bundle
7163        // document would silently no-op at reconcile time with an
7164        // empty artifact. Peer of the sibling per-container-axis KEY
7165        // test
7166        // [`cluster_bundle_gitrepository_spec_ref_key_pins_lifted_flux_gitrepository_key_ref`]
7167        // on the peer `spec.ref` container-axis surface — extends the
7168        // per-CR sub-block key pin discipline from the ref-selection
7169        // container-axis onto the remote-URL leaf-scalar-axis.
7170        let caixa = sample_caixa();
7171        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7172        let files = cluster_bundle(&caixa, &opts).expect("bundle renders");
7173        let gr = files
7174            .iter()
7175            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
7176            .expect("gitrepository.yaml present");
7177        let parsed: serde_yaml::Value =
7178            serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
7179        let url = parsed
7180            .get(KUBE_KEY_SPEC)
7181            .and_then(|s| s.get(FLUX_GITREPOSITORY_KEY_URL))
7182            .and_then(|u| u.as_str())
7183            .expect(
7184                "rendered gitrepository.yaml must carry its remote-URL leaf-scalar \
7185                 axis at the lifted FLUX_GITREPOSITORY_KEY_URL key verbatim",
7186            );
7187        assert!(
7188            !url.is_empty(),
7189            "spec.url leaf-scalar must resolve to a non-empty git-remote clone \
7190             target — a drifted key would collapse the readback to None, an \
7191             empty string would break the source-controller's per-CR clone step"
7192        );
7193    }
7194
7195    #[test]
7196    fn gitrefspec_ref_field_name_dispatches_per_variant_onto_lifted_consts() {
7197        // The [`GitRefSpec::ref_field_name`] method routes each variant
7198        // onto the paired canonical
7199        // [`FLUX_GITREPOSITORY_REF_KEY_TAG`] /
7200        // [`FLUX_GITREPOSITORY_REF_KEY_BRANCH`] /
7201        // [`FLUX_GITREPOSITORY_REF_KEY_COMMIT`] const via a compile-
7202        // time-exhaustive match — closes the drift surface where a
7203        // future variant addition or per-arm rebrand could silently
7204        // desynchronize the YAML emit-side + human-readable narrator
7205        // consumer sites from the sub-selector-key axis. Pin the
7206        // per-variant dispatch identity so a refactor that swaps two
7207        // arms' const references silently at the method-impl site
7208        // fires as a build-time test failure, not as a
7209        // `spec.ref.<wrong-key>` reroute at cluster-apply time.
7210        assert_eq!(
7211            GitRefSpec::Tag("v0.1.0".into()).ref_field_name(),
7212            FLUX_GITREPOSITORY_REF_KEY_TAG,
7213        );
7214        assert_eq!(
7215            GitRefSpec::Branch("main".into()).ref_field_name(),
7216            FLUX_GITREPOSITORY_REF_KEY_BRANCH,
7217        );
7218        assert_eq!(
7219            GitRefSpec::Commit("deadbeef".into()).ref_field_name(),
7220            FLUX_GITREPOSITORY_REF_KEY_COMMIT,
7221        );
7222    }
7223
7224    #[test]
7225    fn gitrefspec_ref_value_extracts_underlying_scalar_per_variant() {
7226        // Peer of
7227        // [`gitrefspec_ref_field_name_dispatches_per_variant_onto_lifted_consts`]:
7228        // the [`GitRefSpec::ref_value`] method extracts the underlying
7229        // scalar the variant carries (tag / branch / commit value)
7230        // through a single collapsed match — the byte-string the
7231        // FluxCD source-controller feeds into its per-CR git-source
7232        // clone refspec. Both consumer sites in [`cluster_bundle`]
7233        // pair the sub-selector key with this scalar; pin the
7234        // per-variant extraction identity so a refactor that mixes
7235        // the arms (a spurious `.to_ascii_lowercase()` in one arm,
7236        // a lifetime-inversion that clones the payload as a scratch
7237        // `String`) surfaces as a build-time test failure.
7238        assert_eq!(GitRefSpec::Tag("v0.1.0".into()).ref_value(), "v0.1.0");
7239        assert_eq!(GitRefSpec::Branch("main".into()).ref_value(), "main");
7240        assert_eq!(
7241            GitRefSpec::Commit("deadbeef".into()).ref_value(),
7242            "deadbeef",
7243        );
7244    }
7245
7246    #[test]
7247    fn cluster_bundle_gitref_field_composes_lifted_dispatch_byte_shape() {
7248        // Fail-before-pass-after emission-side pin: the rendered
7249        // `gitrepository.yaml` document's `spec.ref` sub-block byte-
7250        // shape matches the composition of the canonical lifted
7251        // [`GitRefSpec::ref_field_name`] +
7252        // [`GitRefSpec::ref_value`] dispatch pair against the prior
7253        // inline `format!("    {arm}: {v:?}")` per-arm match block,
7254        // for every arm of the [`GitRefSpec`] discriminated-union.
7255        // Byte-identical output to the prior 3-arm inline match
7256        // (`{v:?}` on `&str` renders the same shape as `{v:?}` on
7257        // `String`) — the composition equation
7258        // `format!("    {field}: {value:?}", ...)` reduces to
7259        // `format!("    tag: {t:?}")` / `format!("    branch: {b:?}")`
7260        // / `format!("    commit: {c:?}")` per arm by construction.
7261        // Peer to the sibling
7262        // [`cluster_bundle_default_git_tag_uses_lifted_caixa_core_prefix`]
7263        // emission-side pin on the tag-arm — pivots the discipline
7264        // from the tag-value axis (the prior lift closed) onto the
7265        // sub-selector-key axis (this lift closes) so the pair of
7266        // pins closes both coordinates of the `spec.ref.<key>:
7267        // <value>` sub-block.
7268        let cases = [
7269            (GitRefSpec::Tag("v0.1.0".into()), "    tag: \"v0.1.0\""),
7270            (GitRefSpec::Branch("main".into()), "    branch: \"main\""),
7271            (
7272                GitRefSpec::Commit("deadbeef".into()),
7273                "    commit: \"deadbeef\"",
7274            ),
7275        ];
7276        for (git_ref, expected) in cases {
7277            let composed = format!(
7278                "    {field}: {value:?}",
7279                field = git_ref.ref_field_name(),
7280                value = git_ref.ref_value(),
7281            );
7282            assert_eq!(
7283                composed, expected,
7284                "GitRefSpec::{git_ref:?} must compose to the prior \
7285                 inline byte-shape via the lifted dispatch",
7286            );
7287        }
7288    }
7289
7290    #[test]
7291    fn cluster_bundle_gitref_narrator_composes_lifted_dispatch_byte_shape() {
7292        // Peer of
7293        // [`cluster_bundle_gitref_field_composes_lifted_dispatch_byte_shape`]
7294        // on the sibling `tag_human` narrator-prose axis in
7295        // [`cluster_bundle`] — pins the byte-shape of the `<arm>
7296        // <value>` operator-facing narrator prose the rendered
7297        // `gitrepository.yaml` document's leading `# Source — pinned
7298        // to <tag_human>` comment quotes. Byte-identical output to
7299        // the prior 3-arm inline `format!("{arm} {v}")` per-variant
7300        // match block by construction.
7301        let cases = [
7302            (GitRefSpec::Tag("v0.1.0".into()), "tag v0.1.0"),
7303            (GitRefSpec::Branch("main".into()), "branch main"),
7304            (GitRefSpec::Commit("deadbeef".into()), "commit deadbeef"),
7305        ];
7306        for (git_ref, expected) in cases {
7307            let composed = format!(
7308                "{field} {value}",
7309                field = git_ref.ref_field_name(),
7310                value = git_ref.ref_value(),
7311            );
7312            assert_eq!(
7313                composed, expected,
7314                "GitRefSpec::{git_ref:?} narrator prose must compose \
7315                 to the prior inline byte-shape via the lifted dispatch",
7316            );
7317        }
7318    }
7319
7320    #[test]
7321    fn cluster_bundle_gitrepo_yaml_carries_lifted_sub_selector_keys() {
7322        // End-to-end emission-side pin: for every arm of
7323        // [`GitRefSpec`], the rendered `gitrepository.yaml` document's
7324        // `spec.ref` sub-block declares the sub-selector under the
7325        // canonical lifted [`FLUX_GITREPOSITORY_REF_KEY_TAG`] /
7326        // [`FLUX_GITREPOSITORY_REF_KEY_BRANCH`] /
7327        // [`FLUX_GITREPOSITORY_REF_KEY_COMMIT`] key — pin the presence
7328        // + value round-trip through the rendered YAML so a regression
7329        // that re-inlines the sub-selector key at the emit site
7330        // surfaces here as a test failure rather than as a silent
7331        // FluxCD source-controller sub-block reroute at reconcile
7332        // time. Peer to the sibling
7333        // [`cluster_bundle_default_git_tag_uses_lifted_caixa_core_prefix`]
7334        // pin that closes the sibling per-arm value axis on the
7335        // tag-arm.
7336        let caixa = sample_caixa();
7337        let cases: [(GitRefSpec, &str, &str); 3] = [
7338            (
7339                GitRefSpec::Tag("v0.1.0".into()),
7340                FLUX_GITREPOSITORY_REF_KEY_TAG,
7341                "v0.1.0",
7342            ),
7343            (
7344                GitRefSpec::Branch("main".into()),
7345                FLUX_GITREPOSITORY_REF_KEY_BRANCH,
7346                "main",
7347            ),
7348            (
7349                GitRefSpec::Commit("deadbeef".into()),
7350                FLUX_GITREPOSITORY_REF_KEY_COMMIT,
7351                "deadbeef",
7352            ),
7353        ];
7354        for (git_ref, expected_key, expected_value) in cases {
7355            let mut opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7356            opts.git_ref = git_ref.clone();
7357            let files = cluster_bundle(&caixa, &opts).expect("bundle renders");
7358            let gr = files
7359                .iter()
7360                .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
7361                .expect("gitrepository.yaml present");
7362            let parsed: serde_yaml::Value =
7363                serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
7364            let sub_selector = parsed
7365                .get(KUBE_KEY_SPEC)
7366                .and_then(|s| s.get(FLUX_GITREPOSITORY_KEY_REF))
7367                .and_then(|r| r.get(expected_key))
7368                .and_then(|v| v.as_str())
7369                .unwrap_or_else(|| {
7370                    panic!(
7371                        "spec.ref.{expected_key:?} missing or non-string \
7372                         for GitRefSpec::{git_ref:?}: {contents:?}",
7373                        contents = gr.contents,
7374                    )
7375                });
7376            assert_eq!(
7377                sub_selector, expected_value,
7378                "spec.ref.{expected_key:?} must carry the paired \
7379                 scalar for GitRefSpec::{git_ref:?}",
7380            );
7381        }
7382    }
7383
7384    #[test]
7385    fn flux_helmrelease_yaml_filename_re_export_points_at_caixa_core_canonical() {
7386        // The renderer's `FLUX_HELMRELEASE_YAML_FILENAME` was lifted from
7387        // the thirteen production + test-side inline `"helmrelease.yaml"`
7388        // / `PathBuf::from("helmrelease.yaml")` /
7389        // `names.contains(&"helmrelease.yaml".to_string())` literals
7390        // across [`cluster_bundle`]'s per-`BundleFile` `HelmRelease`
7391        // document `path` emit site + every test-side round-trip
7392        // navigator that reaches into the rendered bundle by the
7393        // `HelmRelease` document filename to a re-export of
7394        // [`caixa_core::FLUX_HELMRELEASE_YAML_FILENAME`] so the Flux v2
7395        // per-cluster-bundle `HelmRelease` document filename lives in
7396        // exactly one place across every caixa renderer. Pin the equality
7397        // + `&'static` static-data identity here so any local
7398        // re-introduction of a sibling `pub const
7399        // FLUX_HELMRELEASE_YAML_FILENAME: &str = "…"` at this crate — the
7400        // canonical drift footgun where a sibling local `pub const` could
7401        // happen to carry the same string at the source while pointing
7402        // at a different `&'static` allocation — is a build-time test
7403        // failure naming the offending drift, not a silent FluxCD
7404        // `kustomize-controller` "no `HelmRelease` document found under
7405        // this bundle" reroute at cluster-side reconcile time far from
7406        // the drift site. Peer to
7407        // [`flux_key_interval_re_export_points_at_caixa_core_canonical`]
7408        // on the sibling per-CR body-key surface, and to the
7409        // [`caixa_helm::HELM_CHART_YAML_FILENAME`] (c2c99b0) /
7410        // [`caixa_helm::HELM_VALUES_YAML_FILENAME`] (9a980ba) re-exports
7411        // on the sibling Helm-chart-directory filename surfaces — pivots
7412        // the canonical-filename single-sourcing discipline from the
7413        // per-Helm-chart-directory metadata / values file axes onto the
7414        // sibling per-Flux-v2-bundle `HelmRelease` document filename
7415        // axis this crate's [`cluster_bundle`] renders.
7416        caixa_core::assert_str_reexport_identity(
7417            "FLUX_HELMRELEASE_YAML_FILENAME",
7418            FLUX_HELMRELEASE_YAML_FILENAME,
7419            caixa_core::FLUX_HELMRELEASE_YAML_FILENAME,
7420        );
7421    }
7422
7423    #[test]
7424    fn flux_gitrepository_yaml_filename_re_export_points_at_caixa_core_canonical() {
7425        // The renderer's `FLUX_GITREPOSITORY_YAML_FILENAME` was lifted
7426        // from the nine production + test-side inline
7427        // `"gitrepository.yaml"` / `PathBuf::from("gitrepository.yaml")`
7428        // / `names.contains(&"gitrepository.yaml".to_string())` literals
7429        // across [`cluster_bundle`]'s per-`BundleFile` `GitRepository`
7430        // document `path` emit site + every test-side round-trip
7431        // navigator that reaches into the rendered bundle by the
7432        // `GitRepository` document filename to a re-export of
7433        // [`caixa_core::FLUX_GITREPOSITORY_YAML_FILENAME`] so the Flux v2
7434        // per-cluster-bundle `GitRepository` document filename lives in
7435        // exactly one place across every caixa renderer. Pin the
7436        // equality + `&'static` static-data identity here so any local
7437        // re-introduction of a sibling `pub const
7438        // FLUX_GITREPOSITORY_YAML_FILENAME: &str = "…"` at this crate —
7439        // the canonical drift footgun where a sibling local `pub const`
7440        // could happen to carry the same string at the source while
7441        // pointing at a different `&'static` allocation — is a
7442        // build-time test failure naming the offending drift, not a
7443        // silent FluxCD `source-controller` "no `GitRepository`
7444        // document found under this bundle" reroute at cluster-side
7445        // reconcile time far from the drift site. Peer to
7446        // [`flux_helmrelease_yaml_filename_re_export_points_at_caixa_core_canonical`]
7447        // on the sibling per-`HelmRelease`-document filename surface —
7448        // extends the canonical-Flux-v2-bundle-filename lifted-const
7449        // discipline from the middle coordinate of the filename triple
7450        // onto its first coordinate.
7451        caixa_core::assert_str_reexport_identity(
7452            "FLUX_GITREPOSITORY_YAML_FILENAME",
7453            FLUX_GITREPOSITORY_YAML_FILENAME,
7454            caixa_core::FLUX_GITREPOSITORY_YAML_FILENAME,
7455        );
7456    }
7457
7458    #[test]
7459    fn flux_kustomization_yaml_filename_re_export_points_at_caixa_core_canonical() {
7460        // The renderer's `FLUX_KUSTOMIZATION_YAML_FILENAME` was lifted
7461        // from the sixteen production + test-side inline
7462        // `"kustomization.yaml"` /
7463        // `PathBuf::from("kustomization.yaml")` /
7464        // `names.contains(&"kustomization.yaml".to_string())` literals
7465        // across [`cluster_bundle`]'s per-`BundleFile` `Kustomization`
7466        // document `path` emit site + every test-side round-trip
7467        // navigator that reaches into the rendered bundle by the
7468        // `Kustomization` document filename to a re-export of
7469        // [`caixa_core::FLUX_KUSTOMIZATION_YAML_FILENAME`] so the
7470        // Flux v2 per-cluster-bundle `Kustomization` document filename
7471        // lives in exactly one place across every caixa renderer. Pin
7472        // the equality + `&'static` static-data identity here so any
7473        // local re-introduction of a sibling `pub const
7474        // FLUX_KUSTOMIZATION_YAML_FILENAME: &str = "…"` at this crate —
7475        // the canonical drift footgun where a sibling local `pub const`
7476        // could happen to carry the same string at the source while
7477        // pointing at a different `&'static` allocation — is a
7478        // build-time test failure naming the offending drift, not a
7479        // silent FluxCD `kustomize-controller` "no `Kustomization`
7480        // document found under this bundle" reroute at cluster-side
7481        // reconcile time far from the drift site. Peer to
7482        // [`flux_helmrelease_yaml_filename_re_export_points_at_caixa_core_canonical`]
7483        // + [`flux_gitrepository_yaml_filename_re_export_points_at_caixa_core_canonical`]
7484        // on the sibling per-`HelmRelease` / per-`GitRepository`
7485        // document filename surfaces — closes the canonical-Flux-v2-
7486        // bundle-filename lifted-const discipline on the third
7487        // coordinate of the filename triple.
7488        caixa_core::assert_str_reexport_identity(
7489            "FLUX_KUSTOMIZATION_YAML_FILENAME",
7490            FLUX_KUSTOMIZATION_YAML_FILENAME,
7491            caixa_core::FLUX_KUSTOMIZATION_YAML_FILENAME,
7492        );
7493    }
7494
7495    #[test]
7496    fn cluster_bundle_every_flux_cr_carries_lifted_flux_key_interval_scalar() {
7497        // Fail-before-pass-after pin: every rendered Flux v2 document in
7498        // the `cluster_bundle` triplet (`gitrepository.yaml`,
7499        // `helmrelease.yaml`, `kustomization.yaml`) must resolve its
7500        // `spec.interval` reconcile-poll cadence scalar under the lifted
7501        // [`FLUX_KEY_INTERVAL`] verbatim. Before the lift each of the
7502        // three sites carried an inline `interval:` literal in its
7503        // per-CR format string; a future Flux v3 rebrand on this axis (a
7504        // hypothetical upstream fluxcd/flux2 rename from `interval` to
7505        // `Interval` / `period` / `cadence` / `pollInterval` /
7506        // `reconcileInterval`, coordinated with the upstream project's
7507        // per-version deprecation cycle) without a coordinated edit at
7508        // any one of the three emit sites would have silently dropped
7509        // the per-CR reconcile schedule from the affected Flux v2
7510        // controller's per-CR watch registration — the referenced Git
7511        // source never re-polls / the referenced chart never re-templates
7512        // / the parent Kustomization never re-applies at upstream drift,
7513        // freezing the whole cluster's per-`caixa` per-cluster bundle at
7514        // the last-applied snapshot far from the rebrand commit's source.
7515        //
7516        // The pin is structural: parse each rendered YAML document in
7517        // the triplet and assert the per-CR reconcile-poll cadence
7518        // scalar-axis key resolves under the lifted constant with a
7519        // non-empty string scalar under it. A regression that re-introduces
7520        // an inline literal at any of the three emit sites surfaces as a
7521        // `None` at the lifted-const-keyed lookup on that document. Peer
7522        // to the sibling
7523        // [`cluster_bundle_helmrelease_chart_block_uses_lifted_flux_key_chart`]
7524        // /
7525        // [`cluster_bundle_helmrelease_values_block_uses_lifted_flux_key_values`]
7526        // /
7527        // [`cluster_bundle_kustomization_health_checks_block_uses_lifted_flux_key_health_checks`]
7528        // pins on the sibling per-CR body-key surfaces — extends the
7529        // canonical-Flux-v2-body-key lifted-const-keyed pin discipline
7530        // from the per-CR body-key quartet onto the sibling cross-CR-
7531        // shared reconcile-poll cadence scalar-axis this test targets.
7532        let opts = ClusterBundleOpts::for_caixa(&sample_caixa(), "rio");
7533        let files = cluster_bundle(&sample_caixa(), &opts).unwrap();
7534        for filename in [
7535            FLUX_GITREPOSITORY_YAML_FILENAME,
7536            FLUX_HELMRELEASE_YAML_FILENAME,
7537            FLUX_KUSTOMIZATION_YAML_FILENAME,
7538        ] {
7539            let doc = files
7540                .iter()
7541                .find(|f| f.path == std::path::PathBuf::from(filename))
7542                .unwrap_or_else(|| panic!("{filename} present"));
7543            let parsed: serde_yaml::Value = serde_yaml::from_str(&doc.contents)
7544                .unwrap_or_else(|_| panic!("{filename} parses as YAML"));
7545            let interval = parsed
7546                .get(KUBE_KEY_SPEC)
7547                .and_then(|s| s.get(FLUX_KEY_INTERVAL))
7548                .and_then(|v| v.as_str())
7549                .unwrap_or_else(|| {
7550                    panic!(
7551                        "{filename} spec.<FLUX_KEY_INTERVAL> ({FLUX_KEY_INTERVAL:?}) \
7552                         scalar present; drift on this axis silently drops the \
7553                         per-CR reconcile schedule from the Flux v2 controller's \
7554                         per-CR watch registration",
7555                    )
7556                });
7557            assert!(
7558                !interval.is_empty(),
7559                "{filename} spec.<FLUX_KEY_INTERVAL> ({FLUX_KEY_INTERVAL:?}) must \
7560                 carry a non-empty duration scalar; the Flux v2 controller's \
7561                 per-CR reconcile loop rejects an empty cadence at admission",
7562            );
7563            // The renderer threads opts.interval through every CR
7564            // verbatim (the same [`ClusterBundleOpts::interval`] field
7565            // for the whole per-cluster bundle); pin that the emitted
7566            // scalar agrees with the opts-side input so a future
7567            // refactor that per-CR-overrides the cadence surfaces here
7568            // rather than as a silent per-CR reconcile-schedule split.
7569            assert_eq!(
7570                interval, opts.interval,
7571                "{filename} spec.<FLUX_KEY_INTERVAL> ({FLUX_KEY_INTERVAL:?}) \
7572                 must carry the same duration scalar the [`ClusterBundleOpts`] \
7573                 seeded — drift here silently splits the per-CR reconcile \
7574                 schedule across the three Flux v2 controllers",
7575            );
7576        }
7577    }
7578
7579    #[test]
7580    fn bundle_file_alias_resolves_to_caixa_core_rendered_file() {
7581        // Type-alias identity pin: the [`BundleFile`] alias at this
7582        // crate's boundary resolves to the canonical
7583        // [`caixa_core::RenderedFile`] the substrate-side "one rendered
7584        // leaf artifact" shape lives at. `let _: BundleFile = <a
7585        // RenderedFile>` type-checks *iff* [`BundleFile`] is the
7586        // aliased canonical (not a sibling pub-struct re-declaration
7587        // that happens to carry the same field pair — that would
7588        // compile past the struct-literal navigators below but fail
7589        // this assignment). A drifted local `pub struct BundleFile
7590        // { pub path: PathBuf, pub contents: String }` at this crate —
7591        // the canonical drift footgun that would carry the same
7592        // field pair at the source while pointing at a different
7593        // struct definition — trips this pin at caixa-flux build time
7594        // rather than surfacing as a downstream `caixa_core::RenderedFile`
7595        // consumer refusing a `BundleFile`-shaped value at type-check
7596        // time far from the drift commit.
7597        let canonical: caixa_core::RenderedFile = caixa_core::RenderedFile {
7598            path: std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME),
7599            contents: String::new(),
7600        };
7601        let aliased: BundleFile = canonical.clone();
7602        assert_eq!(aliased, canonical);
7603        // Struct-literal construction still resolves through the alias
7604        // — the pre-lift `BundleFile { path, contents }` shape at every
7605        // production emit site (three sites in [`cluster_bundle`])
7606        // continues to compile, and the derive tuple travels through
7607        // the alias.
7608        let via_alias = BundleFile {
7609            path: std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME),
7610            contents: "kind: HelmRelease\n".to_string(),
7611        };
7612        assert_eq!(
7613            via_alias.path.to_string_lossy(),
7614            FLUX_HELMRELEASE_YAML_FILENAME
7615        );
7616    }
7617
7618    #[test]
7619    fn bundle_file_new_constructor_travels_through_alias_to_canonical() {
7620        // Inherent-method-through-alias pin: the canonical
7621        // [`caixa_core::RenderedFile::new`] `impl Into<PathBuf>` /
7622        // `impl Into<String>` constructor every per-CR YAML leaf in
7623        // [`cluster_bundle`] now routes through resolves at
7624        // `BundleFile::new(…)` — Rust inherent methods travel through
7625        // a `pub type BundleFile = caixa_core::RenderedFile` alias to
7626        // the aliased canonical at name resolution, so a drifted
7627        // local `pub struct BundleFile { pub path: PathBuf, pub
7628        // contents: String }` at this crate would carry the field
7629        // pair the sibling type-alias-identity pin above still
7630        // accepts (both records share `pub path` / `pub contents`
7631        // shape) while dropping the constructor — the three sweep
7632        // sites in [`cluster_bundle`] would stop compiling and the
7633        // failing calls would name `BundleFile` directly, making the
7634        // drift-source unambiguous. This test pins the constructor's
7635        // per-alias reachability + the byte-identical record shape
7636        // against a `FLUX_GITREPOSITORY_YAML_FILENAME`-keyed probe so
7637        // the pin fires at caixa-flux build time.
7638        let via_alias_new: BundleFile =
7639            BundleFile::new(FLUX_GITREPOSITORY_YAML_FILENAME, "kind: GitRepository\n");
7640        let via_canonical_new = caixa_core::RenderedFile::new(
7641            FLUX_GITREPOSITORY_YAML_FILENAME,
7642            String::from("kind: GitRepository\n"),
7643        );
7644        assert_eq!(via_alias_new, via_canonical_new);
7645        assert_eq!(
7646            via_alias_new.path,
7647            std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME),
7648        );
7649        assert_eq!(via_alias_new.contents, "kind: GitRepository\n");
7650    }
7651
7652    #[test]
7653    fn programs_yaml_entry_name_field_routes_through_caixa_nome_accessor() {
7654        // Fail-before-pass-after pin: the emit-side `name:` scalar the
7655        // aggregator-path [`programs_yaml_entry`] writes into the
7656        // per-Servico values-schema entry at
7657        // `entry[FLEET_PROGRAMS_KEY_NAME]` must derive from the typed
7658        // [`caixa_core::Caixa::nome`] accessor byte-for-byte. Before
7659        // this converge the emit site carried a raw
7660        // `caixa.nome.clone()` field access at
7661        // [`programs_yaml_entry`]'s per-entry name-insert position —
7662        // the sole production-code `String`-carry from `Caixa::nome`
7663        // on this fn's emit path — and a future extension of the
7664        // accessor (an M4 namespace-qualified rewrite the CR
7665        // materializer applies per-CR, a per-cluster alias table
7666        // pinned through a future `:placement`-scoped slot, the
7667        // `:nome-suffix` overlay MESH-COMPOSITION §III.2 acknowledges)
7668        // that landed on the accessor but not on this emit site would
7669        // silently split the substrate-operator-side aggregator's
7670        // per-entry `name:` axis (the discriminator
7671        // [`caixa_core::upsert_named_entry`] keys off on every peer
7672        // append / replace, and the substrate operator's fleet-programs
7673        // reconciler groups per-Servico HelmRelease materialization by)
7674        // from every peer read-side consumer of `Caixa::nome`
7675        // (`lareira_chart_name` chart-directory composer,
7676        // `flux_kustomization_source_subtree` per-caixa sub-tree
7677        // composer, the error-path diagnostic
7678        // [`caixa_core::KindMismatch`] names the offending caixa's
7679        // `:nome` through). Byte-equal today (the accessor is
7680        // `&self.nome`); the pin catches any future accessor
7681        // extension whose emit-side write regresses to the raw field.
7682        // Peer to
7683        // [`caixa_mesh::tests::programs_for_aplicacao_entry_aplicacao_routes_through_caixa_nome_accessor`]
7684        // on the sibling mesh-side fleet-programs-aggregator emit
7685        // path.
7686        let caixa = sample_caixa();
7687        let entry = programs_yaml_entry(&caixa, &sample_cu_yaml()).unwrap();
7688        let emitted = entry
7689            .get(FLEET_PROGRAMS_KEY_NAME)
7690            .and_then(|n| n.as_str())
7691            .expect(
7692                "programs.yaml entry must carry a `name:` scalar — drift here \
7693                 silently splits the substrate-operator-side fleet-programs \
7694                 aggregator's per-entry identity from every peer read-side \
7695                 consumer of `Caixa::nome`",
7696            );
7697        assert_eq!(
7698            emitted,
7699            caixa.nome(),
7700            "programs.yaml `entry[FLEET_PROGRAMS_KEY_NAME]` must derive from \
7701             the typed `caixa_core::Caixa::nome` accessor byte-for-byte — a \
7702             regression that re-inlines `caixa.nome.clone()` at the emit site \
7703             silently splits the aggregator-path per-entry `name:` axis from \
7704             every future accessor extension (namespace-qualified rewrite, \
7705             per-cluster alias table, `:nome-suffix` overlay) that lands on \
7706             the accessor",
7707        );
7708    }
7709
7710    #[test]
7711    fn cluster_bundle_gitrepository_metadata_name_routes_through_caixa_nome_accessor() {
7712        // Fail-before-pass-after pin: the emit-side `metadata.name`
7713        // scalar the bundle-path [`cluster_bundle`] writes into the
7714        // `GitRepository` CR document must derive from the typed
7715        // [`caixa_core::Caixa::nome`] accessor byte-for-byte. Before
7716        // this converge the emit site carried a raw
7717        // `let name = caixa.nome.clone()` field access at
7718        // [`cluster_bundle`]'s per-bundle name-binding position — the
7719        // sole production-code `String`-carry the fn threads into
7720        // every downstream `metadata.name` axis it emits — so a future
7721        // extension of the accessor that landed on the accessor but
7722        // not on this emit site would silently split the source-
7723        // controller-side `GitRepository` CR's per-Servico identity
7724        // (the axis the paired `HelmRelease`
7725        // `spec.chart.spec.sourceRef.name` binds through) from every
7726        // peer read-side consumer of `Caixa::nome`. Peer to
7727        // [`cluster_bundle_helmrelease_metadata_name_routes_through_caixa_nome_accessor`]
7728        // and
7729        // [`cluster_bundle_kustomization_metadata_name_routes_through_caixa_nome_accessor`]
7730        // on the sibling per-CR emit-position pins.
7731        let caixa = sample_caixa();
7732        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7733        let files = cluster_bundle(&caixa, &opts).unwrap();
7734        let gr = files
7735            .iter()
7736            .find(|f| f.path == std::path::PathBuf::from(FLUX_GITREPOSITORY_YAML_FILENAME))
7737            .expect("gitrepository.yaml present");
7738        let parsed: serde_yaml::Value =
7739            serde_yaml::from_str(&gr.contents).expect("gitrepository.yaml parses as YAML");
7740        let emitted = kube_metadata_str_field(&parsed, KUBE_KEY_NAME).expect(
7741            "gitrepository.yaml `metadata.name` scalar present — drift here \
7742             silently orphans the source-controller-side per-Servico \
7743             GitRepository CR from every peer `spec.sourceRef.name` binding",
7744        );
7745        assert_eq!(
7746            emitted,
7747            caixa.nome(),
7748            "gitrepository.yaml `metadata.name` must derive from the typed \
7749             `caixa_core::Caixa::nome` accessor byte-for-byte — a regression \
7750             that re-inlines `caixa.nome.clone()` at the per-bundle \
7751             `let name` binding silently splits the source-controller-side \
7752             per-Servico GitRepository CR's identity from every future \
7753             accessor extension (namespace-qualified rewrite, per-cluster \
7754             alias table, `:nome-suffix` overlay) that lands on the accessor",
7755        );
7756    }
7757
7758    #[test]
7759    fn cluster_bundle_helmrelease_metadata_name_routes_through_caixa_nome_accessor() {
7760        // Fail-before-pass-after pin: the emit-side `metadata.name`
7761        // scalar the bundle-path [`cluster_bundle`] writes into the
7762        // `HelmRelease` CR document must derive from the typed
7763        // [`caixa_core::Caixa::nome`] accessor byte-for-byte. Same
7764        // single-source `let name = caixa.nome()` binding as the
7765        // peer GitRepository / Kustomization sibling pins — this test
7766        // pins the derived `HelmRelease` `metadata.name` axis (the
7767        // discriminator the Flux v2 helm-controller keys per-Servico
7768        // reconciliation off, and the axis the paired Kustomization
7769        // `spec.healthChecks[0].name` health-checks binds through).
7770        // Peer to
7771        // [`cluster_bundle_gitrepository_metadata_name_routes_through_caixa_nome_accessor`]
7772        // and
7773        // [`cluster_bundle_kustomization_metadata_name_routes_through_caixa_nome_accessor`]
7774        // on the sibling per-CR emit-position pins.
7775        let caixa = sample_caixa();
7776        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7777        let files = cluster_bundle(&caixa, &opts).unwrap();
7778        let hr = files
7779            .iter()
7780            .find(|f| f.path == std::path::PathBuf::from(FLUX_HELMRELEASE_YAML_FILENAME))
7781            .expect("helmrelease.yaml present");
7782        let parsed: serde_yaml::Value =
7783            serde_yaml::from_str(&hr.contents).expect("helmrelease.yaml parses as YAML");
7784        let emitted = kube_metadata_str_field(&parsed, KUBE_KEY_NAME).expect(
7785            "helmrelease.yaml `metadata.name` scalar present — drift here \
7786             silently orphans the helm-controller-side per-Servico \
7787             HelmRelease CR from every peer Kustomization \
7788             `spec.healthChecks[].name` binding",
7789        );
7790        assert_eq!(
7791            emitted,
7792            caixa.nome(),
7793            "helmrelease.yaml `metadata.name` must derive from the typed \
7794             `caixa_core::Caixa::nome` accessor byte-for-byte — a regression \
7795             that re-inlines `caixa.nome.clone()` at the per-bundle \
7796             `let name` binding silently splits the helm-controller-side \
7797             per-Servico HelmRelease CR's identity from every future \
7798             accessor extension (namespace-qualified rewrite, per-cluster \
7799             alias table, `:nome-suffix` overlay) that lands on the accessor",
7800        );
7801    }
7802
7803    #[test]
7804    fn cluster_bundle_kustomization_metadata_name_routes_through_caixa_nome_accessor() {
7805        // Fail-before-pass-after pin: the emit-side `metadata.name`
7806        // scalar the bundle-path [`cluster_bundle`] writes into the
7807        // `Kustomization` CR document must derive from the typed
7808        // [`caixa_core::Caixa::nome`] accessor byte-for-byte. Same
7809        // single-source `let name = caixa.nome()` binding as the
7810        // peer GitRepository / HelmRelease sibling pins — this test
7811        // pins the derived `Kustomization` `metadata.name` axis (the
7812        // discriminator the Flux v2 kustomize-controller keys per-
7813        // Servico prune / reconcile decisions off). Peer to
7814        // [`cluster_bundle_gitrepository_metadata_name_routes_through_caixa_nome_accessor`]
7815        // and
7816        // [`cluster_bundle_helmrelease_metadata_name_routes_through_caixa_nome_accessor`]
7817        // on the sibling per-CR emit-position pins.
7818        let caixa = sample_caixa();
7819        let opts = ClusterBundleOpts::for_caixa(&caixa, "rio");
7820        let files = cluster_bundle(&caixa, &opts).unwrap();
7821        let k = files
7822            .iter()
7823            .find(|f| f.path == std::path::PathBuf::from(FLUX_KUSTOMIZATION_YAML_FILENAME))
7824            .expect("kustomization.yaml present");
7825        let parsed: serde_yaml::Value =
7826            serde_yaml::from_str(&k.contents).expect("kustomization.yaml parses as YAML");
7827        let emitted = kube_metadata_str_field(&parsed, KUBE_KEY_NAME).expect(
7828            "kustomization.yaml `metadata.name` scalar present — drift here \
7829             silently splits the kustomize-controller-side per-Servico \
7830             Kustomization CR's prune / reconcile decisions from every peer \
7831             HelmRelease CR's paired identity",
7832        );
7833        assert_eq!(
7834            emitted,
7835            caixa.nome(),
7836            "kustomization.yaml `metadata.name` must derive from the typed \
7837             `caixa_core::Caixa::nome` accessor byte-for-byte — a regression \
7838             that re-inlines `caixa.nome.clone()` at the per-bundle \
7839             `let name` binding silently splits the kustomize-controller-\
7840             side per-Servico Kustomization CR's identity from every future \
7841             accessor extension (namespace-qualified rewrite, per-cluster \
7842             alias table, `:nome-suffix` overlay) that lands on the accessor",
7843        );
7844    }
7845}