Skip to main content

tatara_process/
tagged_union.rs

1//! `tagged_union::resolve` — the typescape's "exactly-one-Option" pattern,
2//! lifted to one source of truth.
3//!
4//! Several CRD-facing types in this crate ([`crate::intent::Intent`],
5//! [`crate::lifetime::Lifetime`], [`crate::export::ArtifactSource`],
6//! [`crate::export::VectorChannel`], [`crate::encapsulates::EncapsulationKind`])
7//! carry `N` `Option<T>` fields where exactly one is expected to be
8//! populated on the wire. Each previously hand-rolled the same
9//! `count() + if-let-chain + unreachable!()` body — four parallel tables
10//! (the struct fields, an `is_some()` count array, an `if-let-else`
11//! resolution chain, and any sibling projection like `IntentVariant::kind`)
12//! kept coherent only by code review. The `unreachable!()` arm at the
13//! bottom of every chain was a sentinel that fires at runtime if the
14//! parallel tables ever drift.
15//!
16//! This module collapses the resolver to ONE typed sweep over an
17//! `IntoIterator<Item = Option<V>>` of candidate variant projections.
18//! Adding a new tagged-union variant is now ONE additional line at the
19//! callsite — no `unreachable!()` arm to update, no parallel `is_some()`
20//! count array to extend.
21
22/// Outcome of [`resolve`] when the candidate list isn't exactly-one.
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum ResolveError {
25    /// No candidate was populated.
26    None,
27    /// More than one candidate was populated.
28    Many,
29}
30
31/// Resolve at most one populated variant from a candidate list.
32///
33/// Each item in `candidates` is the projected borrowed-variant view for
34/// the corresponding `Option<T>` field — `None` when the field is unset,
35/// `Some(V::Variant(...))` when set.
36///
37/// Returns the single populated variant, [`ResolveError::None`] when
38/// none are populated, or [`ResolveError::Many`] when more than one are.
39///
40/// The body is one short-circuiting sweep — `Many` is returned as soon
41/// as the second populated entry is seen, without scanning the rest.
42pub fn resolve<V>(candidates: impl IntoIterator<Item = Option<V>>) -> Result<V, ResolveError> {
43    let mut found: Option<V> = None;
44    for candidate in candidates {
45        if candidate.is_some() {
46            if found.is_some() {
47                return Err(ResolveError::Many);
48            }
49            found = candidate;
50        }
51    }
52    found.ok_or(ResolveError::None)
53}
54
55/// Sibling error carriers on tagged-union `.variant()` sites all
56/// project the two [`ResolveError`] arms onto the SAME closed-set
57/// diagnostic shape — `Empty(&'static str)` for "no variant set"
58/// (carrying the closed-set kind list so the operator diagnostic
59/// names every candidate) and a payload-free `Ambiguous` for
60/// "multiple variants set". This trait names that shared shape as
61/// ONE typed contract; [`resolve_or_err`] then composes [`resolve`]
62/// with the trait so each per-carrier `.map_err(|e| match e { ... })`
63/// site collapses to a one-line typed dispatch.
64///
65/// Impls live at each error carrier's own module so the (diagnostic
66/// message, closed-set list) pair stays owned by the carrier that
67/// publishes it — the trait is the projection, not the message.
68pub trait TaggedUnionError: Sized {
69    /// Construct the "no variant set" arm with the closed-set kind
70    /// list slash-joined into the diagnostic payload.
71    fn empty(kinds: &'static str) -> Self;
72    /// Construct the "multiple variants set" arm.
73    fn ambiguous() -> Self;
74}
75
76/// Resolve at most one populated variant, mapping the two
77/// [`ResolveError`] arms onto the caller's typed carrier via
78/// [`TaggedUnionError`]. The compound-lift primitive: sweep +
79/// short-circuit + typed-error dispatch as ONE call.
80///
81/// Substrate primitive for the four sibling `Xxx::variant()` sites
82/// on `ProcessSpec` (`Intent::variant`,
83/// `EncapsulationKind::variant`, `ArtifactSource::variant`,
84/// `VectorChannel::variant`) that previously restated the SAME
85/// `.map_err(|e| match e { None => Empty(LIST), Many => Ambiguous })`
86/// two-arm dispatch at each call site — every one of them a
87/// byte-identical restatement of the (empty→list, many→ambiguous)
88/// projection whose payload identity is strictly the carrier's own
89/// diagnostic. A fifth sibling error carrier picks up the projection
90/// through ONE `impl TaggedUnionError` block + ONE `resolve_or_err`
91/// call site.
92///
93/// The [`Lifetime::variant`](crate::lifetime::Lifetime::variant)
94/// site is DELIBERATELY not routed through this primitive — its
95/// `ResolveError::None` arm resolves to a `Permanent` default
96/// variant, not to an `Empty` typed error, so the projection shape
97/// diverges at the None arm.
98pub fn resolve_or_err<V, E: TaggedUnionError>(
99    candidates: impl IntoIterator<Item = Option<V>>,
100    kinds: &'static str,
101) -> Result<V, E> {
102    resolve(candidates).map_err(|e| match e {
103        ResolveError::None => E::empty(kinds),
104        ResolveError::Many => E::ambiguous(),
105    })
106}
107
108/// Declare a sibling error carrier for a tagged-union `.variant()`
109/// site — the enum + [`TaggedUnionError`] impl in ONE authoring
110/// surface.
111///
112/// Every one of the four production `.variant()` sites on
113/// `ProcessSpec` ([`crate::intent::Intent`],
114/// [`crate::encapsulates::EncapsulationKind`],
115/// [`crate::export::ArtifactSource`],
116/// [`crate::export::VectorChannel`]) pre-lift restated the same
117/// four-piece authoring shape by hand:
118///
119/// 1. `#[derive(Clone, Copy, Debug, thiserror::Error, PartialEq,
120///    Eq)]` on the carrier — byte-identical across all four.
121/// 2. A two-variant enum body (`Empty(&'static str)`, `Ambiguous`)
122///    — structurally identical.
123/// 3. Two `#[error(...)]` messages whose only per-carrier knob is a
124///    noun-prefix (`"intent"`, `"encapsulation kind"`, ...) — every
125///    other byte of the (`"has no variant set (one of {0}
126///    required)"`, `"has multiple variants set; exactly one
127///    required"`) tails was verbatim.
128/// 4. A six-line `impl TaggedUnionError` whose two constructor
129///    bodies re-projected `Self::Empty(kinds)` / `Self::Ambiguous`
130///    onto each carrier's own typed variants.
131///
132/// The macro collapses (1) + (2) + (4) onto ONE call and takes the
133/// two per-carrier operator-facing diagnostic literals as named
134/// arguments so (3) stays visible at the callsite without re-authoring
135/// the shared derive set or trait impl. A fifth sibling carrier
136/// lands as ONE `declare_tagged_union_error!` invocation — no
137/// re-authored `#[derive(...)]`, no re-authored two-variant enum
138/// body, no re-authored `impl TaggedUnionError` block.
139///
140/// Emitted derives include `Copy` — the `Empty` arm carries only
141/// a `&'static str` and the `Ambiguous` arm is payload-free, so
142/// the carrier is always `Copy` regardless of caller.
143///
144/// # Example
145///
146/// ```ignore
147/// declare_tagged_union_error! {
148///     pub IntentError,
149///     empty = "intent has no variant set (one of {0} required)",
150///     ambiguous = "intent has multiple variants set; exactly one required",
151/// }
152/// ```
153///
154/// Expands to the enum + [`TaggedUnionError`] impl for
155/// `IntentError`; the `Empty` arm carries the caller's closed-set
156/// kind-list literal.
157#[macro_export]
158macro_rules! declare_tagged_union_error {
159    (
160        $(#[$attr:meta])*
161        $vis:vis $name:ident,
162        empty = $empty:literal,
163        ambiguous = $ambiguous:literal $(,)?
164    ) => {
165        $(#[$attr])*
166        #[derive(
167            ::std::clone::Clone,
168            ::std::marker::Copy,
169            ::std::fmt::Debug,
170            ::thiserror::Error,
171            ::std::cmp::PartialEq,
172            ::std::cmp::Eq,
173        )]
174        $vis enum $name {
175            #[error($empty)]
176            Empty(&'static str),
177            #[error($ambiguous)]
178            Ambiguous,
179        }
180
181        impl $crate::tagged_union::TaggedUnionError for $name {
182            fn empty(kinds: &'static str) -> Self {
183                Self::Empty(kinds)
184            }
185            fn ambiguous() -> Self {
186                Self::Ambiguous
187            }
188        }
189    };
190}
191
192/// Declare the three-block impl stanza a tagged-union parent type
193/// publishes to the substrate — inherent `.variant()` forwarder +
194/// [`VariantSelector<Parent>`] impl on the sibling `Kind` +
195/// [`TaggedUnion`] impl on the parent — in ONE authoring surface.
196///
197/// Every one of the four production `.variant()` sites on
198/// `ProcessSpec` ([`crate::intent::Intent`],
199/// [`crate::encapsulates::EncapsulationKind`],
200/// [`crate::export::ArtifactSource`],
201/// [`crate::export::VectorChannel`]) pre-lift restated the same three
202/// impl blocks by hand:
203///
204/// 1. `impl $parent { pub fn variant(&self) -> Result<$variant<'_>, $err> { ... } }`
205///    — a one-line delegation to the [`TaggedUnion::variant`] default
206///    body, plus 5 lines of rustdoc cross-referencing the other three
207///    sibling `.variant()` sites verbatim.
208/// 2. `impl VariantSelector<$parent> for $kind { type Variant<'a> = $variant<'a>; fn select(...) { <$kind>::select(self, parent) } }`
209///    — 6 lines whose only per-site knobs are (`$parent`, `$kind`,
210///    `$variant`); the trait method body a straight delegation to the
211///    inherent `<$kind>::select`.
212/// 3. `impl TaggedUnion for $parent { type Kind = $kind; type Error = $err; const KIND_LIST = $kind_list; }`
213///    — 3 associated-item assignments whose only per-site knobs are
214///    the (`$kind`, `$err`, `$kind_list`) tuple.
215///
216/// The macro takes the (`$parent`, `$kind`, `$variant`, `$err`,
217/// `$kind_list`) five-tuple as named arguments and emits all three
218/// blocks. A fifth sibling tagged-union parent picks up all three
219/// impls through ONE macro call — no re-authored inherent
220/// `.variant()` forwarder, no re-authored `impl VariantSelector`
221/// block, no re-authored `impl TaggedUnion` block.
222///
223/// The emitted inherent `.variant()`'s rustdoc is canonical (names
224/// the substrate primitive, not the exact set of sibling sites) so
225/// a fifth sibling doesn't drift the cross-ref count against reality
226/// merely by existing.
227///
228/// # Example
229///
230/// ```ignore
231/// declare_tagged_union_impls! {
232///     parent = Intent,
233///     kind = IntentKind,
234///     variant = IntentVariant,
235///     error = IntentError,
236///     kind_list = INTENT_KIND_LIST,
237/// }
238/// ```
239///
240/// Expands to the inherent `Intent::variant`, the
241/// `VariantSelector<Intent>` impl on `IntentKind`, and the
242/// `TaggedUnion` impl on `Intent`.
243#[macro_export]
244macro_rules! declare_tagged_union_impls {
245    (
246        parent = $parent:ty,
247        kind = $kind:ty,
248        variant = $variant:ident,
249        error = $err:ty,
250        kind_list = $kind_list:expr $(,)?
251    ) => {
252        impl $parent {
253            /// Resolve to exactly one variant. Errors on zero or many.
254            ///
255            /// One-line inherent forwarder that delegates the sweep
256            /// body to the substrate primitive
257            /// [`crate::tagged_union::TaggedUnion::variant`] — every
258            /// production `.variant()` site on `ProcessSpec` dispatches
259            /// through this ONE default body so the resolve-sweep
260            /// pattern lives at ONE substrate site. The inherent surface
261            /// stays load-bearing so consumer callsites don't need
262            /// `use TaggedUnion`.
263            pub fn variant(&self) -> ::std::result::Result<$variant<'_>, $err> {
264                <Self as $crate::tagged_union::TaggedUnion>::variant(self)
265            }
266
267            /// Presence probe — does this tagged union carry a
268            /// populated slot addressed by the given closed-set
269            /// discriminator?
270            ///
271            /// One-line inherent forwarder that delegates to the
272            /// substrate primitive
273            /// [`crate::tagged_union::TaggedUnion::has`] — every
274            /// closed-set-driven presence check on `ProcessSpec`
275            /// dispatches through this ONE default body so the
276            /// per-slot `spec.<field>.is_some()` pattern lives at
277            /// ONE substrate site. The inherent surface stays
278            /// load-bearing so consumer callsites don't need
279            /// `use TaggedUnion`.
280            pub fn has(&self, kind: $kind) -> bool {
281                <Self as $crate::tagged_union::TaggedUnion>::has(self, kind)
282            }
283        }
284
285        impl $crate::tagged_union::VariantSelector<$parent> for $kind {
286            type Variant<'a> = $variant<'a>;
287            fn select<'a>(self, parent: &'a $parent) -> ::std::option::Option<$variant<'a>>
288            where
289                Self: 'a,
290            {
291                <$kind>::select(self, parent)
292            }
293        }
294
295        impl $crate::tagged_union::TaggedUnion for $parent {
296            type Kind = $kind;
297            type Error = $err;
298            const KIND_LIST: &'static str = $kind_list;
299        }
300    };
301}
302
303/// Project the borrowed-view of a tagged-union variant addressed by
304/// this closed-set discriminator.
305///
306/// Companion trait to [`TaggedUnion`] — binds a `Kind` closed-set to
307/// the parent `P` it discriminates AND to the borrowed-view
308/// [`Self::Variant<'a>`] the resolver hands out. Every one of the
309/// four production `.variant()` sites on `ProcessSpec`
310/// ([`crate::intent::Intent`], [`crate::encapsulates::EncapsulationKind`],
311/// [`crate::export::ArtifactSource`], [`crate::export::VectorChannel`])
312/// pre-lift restated the same
313/// `Self::Kind::ALL.into_iter().map(|k| k.select(self))` sweep body
314/// verbatim at its inherent `.variant()`. Post-lift the trait binds
315/// `(k.select(self), Variant<'a>)` onto ONE typed contract per Kind
316/// so [`TaggedUnion::variant`]'s default body can dispatch the sweep
317/// generically — the four sibling inherent bodies collapse to
318/// one-line delegations and a fifth sibling picks up the sweep for
319/// free through ONE `impl VariantSelector` block.
320///
321/// The GAT `Variant<'a>` carries the parent's lifetime so a borrowed
322/// view projected from `&'a P` composes typed with the resolver's
323/// short-circuit — every projection stays a compile-time refinement,
324/// no `Box<dyn ...>` erasure. The GAT is additionally bound to
325/// [`VariantKind<Self>`] so every implementor's borrowed view knows
326/// its addressing Kind — the reverse projection of [`Self::select`]
327/// closed at compile-time so a fifth sibling that adds `impl
328/// VariantSelector` without opening the peer `impl VariantKind` fails
329/// at the trait bound, not later at a per-consumer round-trip test.
330pub trait VariantSelector<P: ?Sized>: Copy + 'static {
331    /// The borrowed-view enum returned by the parent's inherent
332    /// `.variant()` method — one arm per closed-set variant, each
333    /// arm carrying a `&'a` reference into the parent's populated
334    /// slot. Bound generically here so [`TaggedUnion::variant`]'s
335    /// default body can name the return type without restating it
336    /// per parent. Additionally bound to [`VariantKind<Self>`] so
337    /// the reverse projection `Variant<'a> → Self` is closed at the
338    /// trait boundary — every implementor's borrowed view knows its
339    /// addressing Kind through ONE typed contract, and the substrate
340    /// testkit [`assert_variant_round_trip`] composes `select`
341    /// (forward) with `variant_kind` (reverse) generically.
342    type Variant<'a>: VariantKind<Self>
343    where
344        P: 'a,
345        Self: 'a;
346
347    /// Project a `&'a P` borrow into the optional typed variant view
348    /// for `self` (the addressed discriminator). Returns `None` iff
349    /// the matching slot on `P` is `None`. Composes the closed-set
350    /// sweep [`TaggedUnion::variant`] loops over.
351    fn select<'a>(self, parent: &'a P) -> Option<Self::Variant<'a>>
352    where
353        Self: 'a;
354}
355
356/// Reverse projection — every borrowed-variant view enum knows its
357/// closed-set `K` discriminator.
358///
359/// Dual of [`VariantSelector<P>::select`] on the addressed Kind:
360/// where the selector projects a parent borrow forward into an
361/// optional Variant, this trait projects a populated Variant back
362/// into the Kind that addresses it. Together they compose the
363/// round-trip contract every tagged-union `.variant()` site pins
364/// via the substrate testkit [`assert_variant_round_trip`]:
365/// `k.select(&parent).map(|v| v.variant_kind()) == Some(k)` on the
366/// populated side, and `parent.variant().unwrap().variant_kind() == k`
367/// through the [`TaggedUnion::variant`] resolver's default body.
368///
369/// Every borrowed-view enum on `ProcessSpec`'s tagged-union axis
370/// ([`crate::intent::IntentVariant<'_>`],
371/// [`crate::lifetime::LifetimeVariant<'_>`],
372/// [`crate::encapsulates::EncapsulationKindVariant<'_>`],
373/// [`crate::export::ArtifactVariant<'_>`],
374/// [`crate::export::ChannelVariant<'_>`]) pre-lift restated the same
375/// `match self { Self::A(_) => K::A, Self::B(_) => K::B, ... }`
376/// per-arm mapping at its own inherent method (named `.kind()` on
377/// four of five sites; `.target()` on
378/// [`crate::encapsulates::EncapsulationKindVariant`] where the
379/// discriminator's semantic role is a target of encapsulation, not
380/// a kind of parent). The reverse-projection body must stay
381/// per-implementor — it names the ground-truth arm-to-Kind mapping
382/// only the site knows — but the CONTRACT lives at ONE typed
383/// surface so:
384///
385/// * Every downstream generic consumer binds through
386///   `<T::Variant<'_> as VariantKind<T::Kind>>::variant_kind(&v)`
387///   instead of a per-parent inherent-method restatement.
388/// * [`VariantSelector<P>::Variant<'a>`] bounds this trait — a
389///   fifth sibling that adds `impl VariantSelector<P> for XKind`
390///   without the peer `impl VariantKind<XKind> for XVariant<'_>`
391///   fails at the associated-type bound, so the reverse projection
392///   is closed at compile-time across every implementor.
393/// * The generic testkit [`assert_variant_round_trip`] composes
394///   `select` (forward) with `variant_kind` (reverse) at ONE
395///   substrate site — the four sibling
396///   `_kind_round_trips_through_variant_kind` /
397///   `_target_round_trips_through_variant_target` test bodies
398///   collapse to one-line invocations.
399///
400/// The trait method is named [`Self::variant_kind`] rather than
401/// `kind` to avoid shadowing the inherent `.kind()` (or
402/// `.target()`) methods each borrowed-view enum already publishes.
403/// Every impl body is a one-line delegation to the site's inherent
404/// method — the substrate stays the projection, not the mapping.
405pub trait VariantKind<K: Copy + 'static> {
406    /// Project a borrowed-variant view back into its addressing
407    /// closed-set `K` discriminator. Round-trips the closed set on
408    /// the populated side against [`VariantSelector::select`] — a
409    /// value returned by `k.select(&parent).unwrap()` must satisfy
410    /// `variant_kind() == k`, and a value returned by
411    /// `parent.variant().unwrap()` must satisfy `variant_kind() ==
412    /// k` for the populated slot's `k`.
413    fn variant_kind(&self) -> K;
414}
415
416/// Generic round-trip testkit — pins that
417/// [`VariantSelector::select`] (forward projection) and
418/// [`VariantKind::variant_kind`] (reverse projection) compose the
419/// closed set in both directions on the populated side.
420///
421/// Substrate primitive for the four sibling
422/// `_kind_round_trips_through_variant_kind` /
423/// `_target_round_trips_through_variant_target` tests on
424/// `ProcessSpec` ([`crate::intent::Intent`],
425/// [`crate::encapsulates::EncapsulationKind`],
426/// [`crate::export::ArtifactSource`],
427/// [`crate::export::VectorChannel`]) that pre-lift each restated the
428/// same two-arm round-trip probe at their own test bodies:
429///
430/// 1. For each `k in K::ALL`, construct a parent with only slot `k`
431///    populated (via a site-local `single_slot_X(k) -> Parent`
432///    helper).
433/// 2. Assert that `k.select(&parent).unwrap().variant_kind() == k`
434///    (the forward-then-reverse round-trip).
435/// 3. Assert that `parent.variant().unwrap().variant_kind() == k`
436///    (the resolver-then-reverse round-trip).
437///
438/// Post-lift each site's round-trip test collapses to ONE
439/// `assert_variant_round_trip::<T, _>(single_slot_X)` invocation
440/// whose body is the substrate primitive's own dispatch. A fifth
441/// sibling picks up the round-trip check through ONE call site.
442///
443/// The `make_parent` closure stays per-site — every one of the four
444/// production sites already owns a
445/// `single_slot_intent(k) / single_slot_source(k) /
446/// single_slot_channel(k) / single_slot_kind(t)` helper that
447/// constructs a minimally-valid parent with the addressed slot's
448/// inner spec populated; the closure IS the round-trip's ground
449/// truth for "populate slot k", and lifting it into the primitive
450/// would collapse the per-site construction knowledge that stays
451/// deliberately local.
452///
453/// The [`crate::lifetime::Lifetime`] site is DELIBERATELY excluded
454/// — `Lifetime` doesn't impl [`TaggedUnion`] (its `variant()` returns
455/// `Ok(Permanent)` on empty, not an `Empty` typed error), so the
456/// `<T: TaggedUnion>` bound doesn't reach it. Its per-site
457/// round-trip test binds through [`VariantKind`] directly on
458/// [`crate::lifetime::LifetimeVariant`] instead.
459#[track_caller]
460pub fn assert_variant_round_trip<T, F>(make_parent: F)
461where
462    T: TaggedUnion,
463    T::Kind: PartialEq + std::fmt::Debug,
464    F: Fn(T::Kind) -> T,
465{
466    for k in <T::Kind as tatara_closed_set::ClosedSet>::ALL
467        .iter()
468        .copied()
469    {
470        let parent = make_parent(k);
471        let selected = k.select(&parent).unwrap_or_else(|| {
472            panic!("VariantSelector::select must return Some for populated slot {k:?}")
473        });
474        assert_eq!(
475            <<T::Kind as VariantSelector<T>>::Variant<'_> as VariantKind<T::Kind>>::variant_kind(
476                &selected,
477            ),
478            k,
479            "select→variant_kind round-trip failed for {k:?}",
480        );
481        let resolved = parent.variant().ok().unwrap_or_else(|| {
482            panic!("TaggedUnion::variant must resolve exactly-one populated for {k:?}")
483        });
484        assert_eq!(
485            <<T::Kind as VariantSelector<T>>::Variant<'_> as VariantKind<T::Kind>>::variant_kind(
486                &resolved,
487            ),
488            k,
489            "variant()→variant_kind resolver disagreed on {k:?}",
490        );
491    }
492}
493
494/// Declarative surface that names the (Kind, Error, KIND_LIST) triple
495/// a tagged-union `.variant()` site publishes to the substrate — and
496/// provides the sweep body as ONE default method every implementor
497/// picks up for free.
498///
499/// Every one of the four production `.variant()` sites on `ProcessSpec`
500/// ([`crate::intent::Intent`], [`crate::encapsulates::EncapsulationKind`],
501/// [`crate::export::ArtifactSource`], [`crate::export::VectorChannel`])
502/// exposes the SAME three-piece surface: a closed-set discriminator
503/// [`Self::Kind`], a typed [`Self::Error`] carrier that projects onto
504/// the shared [`TaggedUnionError`] contract, and a slash-joined
505/// operator diagnostic literal [`Self::KIND_LIST`]. Pre-lift the
506/// triple lived on each parent type as independent inherent items —
507/// the (Kind, Error) types cross-referenced only by module-doc prose,
508/// the `KIND_LIST` `&'static str` maintained separately at each site
509/// alongside the inherent `.variant()` body. Post-lift the trait
510/// binds the three onto ONE typed contract per parent so downstream
511/// generic code binds to `<T: TaggedUnion>` instead of restating the
512/// per-parent quadruple of associated names.
513///
514/// The [`Self::variant`] default method is the substrate primitive
515/// every inherent `.variant()` on the four production sites delegates
516/// to — one-line inherent forwarders preserve the load-bearing
517/// calling convention (so no downstream callsite needs
518/// `use crate::tagged_union::TaggedUnion` to reach `.variant()`) while
519/// the resolve-sweep body lives at ONE substrate site. Adding a fifth
520/// sibling means ONE `impl TaggedUnion` block + ONE
521/// `impl VariantSelector<Self>` block on the sibling `Kind` + ONE
522/// one-line inherent forwarder — no re-authored 5-line
523/// `resolve_or_err(K::ALL.into_iter().map(|k| k.select(self)),
524/// KIND_LIST)` sweep body.
525///
526/// The `Kind` type is bound to [`tatara_closed_set::ClosedSet`] so
527/// generic testkit primitives (starting with
528/// [`assert_kind_list_matches_closed_set`]) can compose
529/// `<Self::Kind as ClosedSet>::labels_joined("/")` against
530/// [`Self::KIND_LIST`] byte-identically across every implementor —
531/// the diagnostic-stability invariant every sibling pre-lift pinned
532/// through a hand-rolled per-site test body. It is additionally
533/// bound to [`VariantSelector<Self>`] so [`Self::variant`]'s default
534/// body reaches `k.select(self)` generically.
535///
536/// The [`crate::lifetime::Lifetime`] site is DELIBERATELY not routed
537/// through this trait — its `variant()` returns `Ok(Permanent)` on
538/// empty rather than an `Empty` typed error, so its projection shape
539/// diverges from the four Empty-projecting siblings. Same reasoning
540/// as [`resolve_or_err`]'s explicit exclusion of `Lifetime`.
541pub trait TaggedUnion: Sized {
542    /// The closed-set discriminator over this tagged-union's variants.
543    /// Bound to [`tatara_closed_set::ClosedSet`] so the generic
544    /// diagnostic-stability testkit ([`assert_kind_list_matches_closed_set`])
545    /// can project `<Self::Kind as ClosedSet>::labels_joined("/")`
546    /// against [`Self::KIND_LIST`] byte-identically. Additionally
547    /// bound to [`VariantSelector<Self>`] so [`Self::variant`]'s
548    /// default body can dispatch `k.select(self)` at each
549    /// [`ClosedSet::ALL`] entry generically.
550    type Kind: tatara_closed_set::ClosedSet + VariantSelector<Self>;
551
552    /// The typed error carrier returned by the parent's inherent
553    /// `.variant()` method — projects onto the shared
554    /// [`TaggedUnionError`] contract so [`resolve_or_err`]'s two-arm
555    /// dispatch reaches every implementor uniformly.
556    type Error: TaggedUnionError;
557
558    /// Slash-joined operator diagnostic literal — the payload of
559    /// [`TaggedUnionError::empty`] when no slot is populated on this
560    /// tagged union. Pinned against
561    /// `<Self::Kind as tatara_closed_set::ClosedSet>::labels_joined("/")`
562    /// by [`assert_kind_list_matches_closed_set`] so a variant added
563    /// to `Self::Kind` without updating this constant (or a renamed
564    /// variant) fails-loudly at the testkit boundary.
565    const KIND_LIST: &'static str;
566
567    /// Sweep over every [`Self::Kind`] discriminator in
568    /// [`ClosedSet::ALL`](tatara_closed_set::ClosedSet::ALL) order,
569    /// projecting each into the parent's borrowed variant view via
570    /// [`VariantSelector::select`], and resolve to exactly one populated
571    /// variant through [`resolve_or_err`]. Errors on zero (with
572    /// [`Self::KIND_LIST`] carried on the [`TaggedUnionError::empty`]
573    /// arm) or many.
574    ///
575    /// The substrate primitive every one of the four production
576    /// `.variant()` sites on `ProcessSpec` dispatches through — the
577    /// per-parent inherent `.variant()` is a one-line delegation to
578    /// this default so the calling convention (`intent.variant()`,
579    /// `channel.variant()`, ...) stays load-bearing at the callsite
580    /// without every consumer picking up `use TaggedUnion`.
581    ///
582    /// Adding a fifth sibling picks up this body for free — no
583    /// re-authored `resolve_or_err(...)` sweep at the impl block.
584    fn variant(&self) -> Result<<Self::Kind as VariantSelector<Self>>::Variant<'_>, Self::Error> {
585        resolve_or_err(
586            <Self::Kind as tatara_closed_set::ClosedSet>::ALL
587                .iter()
588                .copied()
589                .map(|k| k.select(self)),
590            Self::KIND_LIST,
591        )
592    }
593
594    /// Presence probe — does this tagged union carry a populated
595    /// slot addressed by the given closed-set discriminator?
596    ///
597    /// One-liner that composes [`VariantSelector::select`]'s optional
598    /// borrow with `.is_some()` — the presence half of the resolve
599    /// contract, without allocating an [`Self::Error`] carrier when the
600    /// caller only needs the yes/no answer. Substrate primitive for
601    /// closed-set-driven dispatch tables (e.g. tatara-check's
602    /// `intent-<kind>` requires-tag sweep) where a hand-authored
603    /// per-slot `spec.<field>.is_some()` chain otherwise drifts from
604    /// the [`ClosedSet::ALL`](tatara_closed_set::ClosedSet::ALL)
605    /// enumeration as new variants land.
606    ///
607    /// Every one of the four production `.variant()` sites on
608    /// `ProcessSpec` picks this up for free through the trait default
609    /// — the [`declare_tagged_union_impls!`] macro emits a one-line
610    /// inherent forwarder so `intent.has(kind)` reads at consumer
611    /// callsites without `use TaggedUnion`. Adding a fifth sibling
612    /// picks up the presence probe with zero re-authored body.
613    fn has(&self, kind: Self::Kind) -> bool {
614        kind.select(self).is_some()
615    }
616}
617
618/// Generic diagnostic-stability testkit — pins that [`TaggedUnion::KIND_LIST`]
619/// matches `<T::Kind as tatara_closed_set::ClosedSet>::labels_joined("/")`
620/// byte-identically for every implementor.
621///
622/// Substrate primitive for the four sibling
623/// `_error_empty_lists_every_kind_in_canonical_order` tests on
624/// `ProcessSpec` ([`crate::intent::Intent`],
625/// [`crate::encapsulates::EncapsulationKind`],
626/// [`crate::export::ArtifactSource`], [`crate::export::VectorChannel`])
627/// that pre-lift each restated the same
628/// `assert_eq!(<XxxKind as ClosedSet>::labels_joined("/"),
629/// XXX_KIND_LIST)` two-argument comparison at their own test bodies —
630/// byte-identical projections whose only per-carrier knobs (the Kind
631/// type + the KIND_LIST constant) are the two associated items the
632/// [`TaggedUnion`] trait names. Post-lift each site collapses to ONE
633/// `assert_kind_list_matches_closed_set::<Xxx>()` invocation whose
634/// body is the substrate primitive's own dispatch.
635///
636/// A fifth sibling tagged-union parent picks up the diagnostic-
637/// stability check through ONE `impl TaggedUnion for X` block + ONE
638/// `assert_kind_list_matches_closed_set::<X>()` call site — no
639/// re-authored `<XKind as ClosedSet>::labels_joined("/")` composition
640/// at the test site, no re-authored per-site `assert_eq!` pair.
641#[track_caller]
642pub fn assert_kind_list_matches_closed_set<T: TaggedUnion>() {
643    let derived = <T::Kind as tatara_closed_set::ClosedSet>::labels_joined("/");
644    assert_eq!(
645        derived,
646        T::KIND_LIST,
647        "TaggedUnion KIND_LIST drift — must equal <T::Kind as ClosedSet>::labels_joined(\"/\")",
648    );
649}
650
651/// Generic presence-probe testkit — pins that [`TaggedUnion::has`]
652/// agrees with [`VariantSelector::select`]`.is_some()` across every
653/// [`ClosedSet::ALL`](tatara_closed_set::ClosedSet::ALL) entry, both
654/// on the diagonal (populated slot AND matching kind → `true`) and
655/// off the diagonal (populated slot BUT other kind → `false`).
656///
657/// Substrate primitive for the presence-probe half of the tagged-
658/// union contract — dispatch tables that key off `intent-<kind>` /
659/// `channel-<kind>` / `source-<kind>` require-tags gain a `.has(k)`
660/// call that structurally CANNOT drift from the closed-set sweep,
661/// but the pin here surfaces a `has` override that would break the
662/// contract (e.g. a future specialization that always returned
663/// `false`) at ONE call site rather than at every downstream
664/// dispatcher.
665///
666/// A fifth sibling tagged-union parent picks up the presence-probe
667/// check through ONE `assert_has_matches_select::<X, _>(single_slot)`
668/// invocation — no re-authored `for k in K::ALL { … }` sweep at the
669/// test site.
670#[track_caller]
671pub fn assert_has_matches_select<T, F>(single_slot: F)
672where
673    T: TaggedUnion,
674    T::Kind: PartialEq + std::fmt::Debug,
675    F: Fn(T::Kind) -> T,
676{
677    for populated in <T::Kind as tatara_closed_set::ClosedSet>::ALL
678        .iter()
679        .copied()
680    {
681        let parent = single_slot(populated);
682        for probed in <T::Kind as tatara_closed_set::ClosedSet>::ALL
683            .iter()
684            .copied()
685        {
686            let expected = probed == populated;
687            assert_eq!(
688                parent.has(probed),
689                expected,
690                "TaggedUnion::has drift — populated={populated:?} probed={probed:?} expected={expected}",
691            );
692            assert_eq!(
693                probed.select(&parent).is_some(),
694                expected,
695                "VariantSelector::select drift — populated={populated:?} probed={probed:?} expected={expected}",
696            );
697        }
698    }
699}
700
701/// Generic ambiguity testkit — pins that [`TaggedUnion::variant`]
702/// resolves to [`TaggedUnionError::ambiguous`] on EVERY off-diagonal
703/// `(a, b)` pair in [`ClosedSet::ALL`](tatara_closed_set::ClosedSet::ALL)
704/// `× ALL`.
705///
706/// Substrate primitive for the sibling
707/// `_two_slots_is_ambiguous_across_every_pair` tests on `ProcessSpec`
708/// ([`crate::encapsulates::EncapsulationKind`],
709/// [`crate::export::ArtifactSource`], [`crate::export::VectorChannel`])
710/// that pre-lift each restated the same nested-`for a in K::ALL { for
711/// b in K::ALL { if a == b { continue; } … } }` sweep at their own
712/// test bodies — byte-identical projections whose only per-carrier
713/// knobs are the (Kind type + the `two_slot_X(a, b) -> Parent`
714/// two-slot factory) pair. Post-lift each site collapses to ONE
715/// `assert_two_slots_ambiguous::<Xxx, _>(two_slot_X)` invocation.
716///
717/// The `two_slot` closure stays per-site — every one of the three
718/// production sites already owns a `two_slot_kind /
719/// two_slot_source / two_slot_channel` helper that composes two
720/// `single_slot_X`s per-field. The closure IS the "populate both
721/// slots a and b" ground truth for the carrier's field structure;
722/// lifting it into the primitive would collapse per-site field-
723/// composition knowledge that stays deliberately local.
724///
725/// The pair sweep excludes the diagonal (`a == b`) — a single slot
726/// populated is exactly-one, not many, and the round-trip primitive
727/// [`assert_variant_round_trip`] already pins that populated slot's
728/// resolution. This primitive is the peer contract for the Many arm.
729///
730/// A fifth sibling tagged-union parent picks up the ambiguity check
731/// through ONE `impl TaggedUnion for X` block + ONE per-site
732/// `two_slot_X` helper + ONE `assert_two_slots_ambiguous::<X, _>`
733/// call site — no re-authored nested-for sweep at the test surface,
734/// no re-authored `assert_eq!(..., X::Error::Ambiguous, ...)` arm.
735///
736/// The [`crate::lifetime::Lifetime`] site is DELIBERATELY excluded
737/// — `Lifetime` doesn't impl [`TaggedUnion`] (its error carrier has
738/// no `Empty` arm; its `variant()` returns `Ok(Permanent)` on empty
739/// rather than an `Empty` typed error), so the `<T: TaggedUnion>`
740/// bound doesn't reach it. Its per-site ambiguity assertion binds
741/// through the inherent `.variant()` + hand-authored two-slot
742/// probe. Same reasoning as [`resolve_or_err`]'s and
743/// [`assert_variant_round_trip`]'s exclusions.
744#[track_caller]
745pub fn assert_two_slots_ambiguous<T, F>(two_slot: F)
746where
747    T: TaggedUnion,
748    T::Kind: PartialEq + std::fmt::Debug,
749    T::Error: PartialEq + std::fmt::Debug,
750    F: Fn(T::Kind, T::Kind) -> T,
751{
752    let expected = T::Error::ambiguous();
753    for a in <T::Kind as tatara_closed_set::ClosedSet>::ALL
754        .iter()
755        .copied()
756    {
757        for b in <T::Kind as tatara_closed_set::ClosedSet>::ALL
758            .iter()
759            .copied()
760        {
761            if a == b {
762                continue;
763            }
764            let parent = two_slot(a, b);
765            let err = parent.variant().err().unwrap_or_else(|| {
766                panic!("({a:?}, {b:?}) two-slot parent must not resolve to a variant")
767            });
768            assert_eq!(err, expected, "({a:?}, {b:?}) should resolve Ambiguous");
769        }
770    }
771}
772
773/// Generic wire-key / kind-label alignment testkit — pins that every
774/// single-slot parent serializes to a JSON object with EXACTLY ONE key
775/// whose name equals `<T::Kind as tatara_closed_set::ClosedSet>::label`
776/// on the populated slot's kind.
777///
778/// Substrate primitive for the four sibling
779/// `X_kind_as_str_matches_field_name` / `intent_kind_as_str_matches_intent_field_name`
780/// tests on `ProcessSpec` ([`crate::intent::Intent`],
781/// [`crate::encapsulates::EncapsulationKind`],
782/// [`crate::export::ArtifactSource`], [`crate::export::VectorChannel`])
783/// that pre-lift each restated the same wire-format sweep at their own
784/// test bodies:
785///
786/// 1. For each `k in K::ALL`, construct a single-slot parent via
787///    the site-local `single_slot_X(k) -> Parent` factory.
788/// 2. Serialize it to the wire format and assert that the emitted
789///    key matches `k.as_str()`.
790///
791/// Post-lift each site's alignment test collapses to ONE
792/// `assert_single_slot_key_matches_label::<T, _>(single_slot_X)`
793/// invocation whose body IS the substrate primitive's own dispatch.
794/// A fifth sibling picks up the alignment check through ONE call site.
795///
796/// The primitive projects through `serde_json::to_value` rather than
797/// `serde_yaml::to_string` for two reasons: (1) the check is
798/// structural (exactly-one-key + name equality), not textual (substring
799/// against a `"{key}:"` YAML fragment), so a future site that gains
800/// non-tagged-union metadata fields is caught HERE at the exactly-one
801/// arm — the YAML-substring check the three encapsulates / export sites
802/// carried pre-lift would silently pass on such drift. (2) serde's
803/// field-rename projection (`rename_all = "camelCase"`) is format-
804/// agnostic, so a JSON check pins the SAME invariant a YAML check
805/// would pin, byte-identically. Every one of the four production
806/// parents already emits exactly one key on a single-slot populate —
807/// their `#[serde(default, skip_serializing_if = "Option::is_none")]`
808/// annotations on every tagged-union slot guarantee it — so upgrading
809/// the three YAML sites to the JSON exactly-one check is a strict
810/// strengthening.
811///
812/// The `single_slot` closure stays per-site — every one of the four
813/// production sites already owns a `single_slot_intent /
814/// single_slot_kind / single_slot_source / single_slot_channel` helper
815/// that constructs a minimally-valid parent with the addressed slot's
816/// inner spec populated; the closure IS the "populate slot k" ground
817/// truth for the carrier's field structure. Reused verbatim from the
818/// [`assert_variant_round_trip`] primitive.
819///
820/// The [`crate::lifetime::Lifetime`] site is DELIBERATELY excluded
821/// from THIS trait-projected surface — `Lifetime` doesn't impl
822/// [`TaggedUnion`] (its `variant()` returns `Ok(Permanent)` on empty
823/// rather than an `Empty` typed error), so the `<T: TaggedUnion>`
824/// bound doesn't reach it. The bound-relaxed peer
825/// [`assert_wire_key_matches_label`] carries the SAME sweep body
826/// under `<T: Serialize>` + `<K: ClosedSet>` alone — Lifetime binds
827/// through it directly and this trait-projected surface becomes a
828/// one-line delegation whose only load-bearing purpose is to name
829/// the TaggedUnion parent's `T::Kind` associated type at the call
830/// site (existing `assert_single_slot_key_matches_label::<T, _>(f)`
831/// callers stay unchanged; the peer inflects the same body onto
832/// non-TaggedUnion parents).
833#[track_caller]
834pub fn assert_single_slot_key_matches_label<T, F>(single_slot: F)
835where
836    T: TaggedUnion + serde::Serialize,
837    T::Kind: PartialEq + std::fmt::Debug,
838    F: Fn(T::Kind) -> T,
839{
840    assert_wire_key_matches_label::<T, T::Kind, F>(single_slot);
841}
842
843/// Bound-relaxed peer of [`assert_single_slot_key_matches_label`] —
844/// the SAME wire-key alignment sweep, but on any `(K, T)` pair where
845/// `K: ClosedSet` addresses `T: Serialize` through a caller-supplied
846/// `single_slot: Fn(K) -> T` factory. Drops the `T: TaggedUnion`
847/// bound the sibling primitive carries so parents whose empty
848/// resolution shape diverges from the tagged-union convention (the
849/// canonical example: [`crate::lifetime::Lifetime`], whose empty
850/// resolves to `Permanent(&DEFAULT_PERMANENT)` rather than to an
851/// [`TaggedUnionError::empty`] carrier) still bind through ONE
852/// substrate wire-key alignment site.
853///
854/// The two primitives share ONE sweep body; the trait-projected
855/// [`assert_single_slot_key_matches_label`] is now a one-line
856/// delegation to this bound-relaxed peer, so every drift-arm the
857/// sibling `#[should_panic]` probe pins on the delegating surface
858/// mechanically pins here too. The compounding gain: a fifth parent
859/// whose closed-set kind K doesn't ride the TaggedUnion trait (a
860/// future variant surface with a default-arm on empty; a wire-only
861/// enum whose parent is a wrapper struct that never publishes a
862/// resolver; a K-addressed `HashMap<K, Payload>` where the payload
863/// isn't a tagged-union variant carrier at all) picks up wire-key
864/// alignment through ONE call site — no re-authored serialize +
865/// exactly-one-key + name-equality body at the test surface, no
866/// per-parent drift risk where the trait-projected surface catches
867/// it and the bespoke surface forgets.
868///
869/// The primitive binds `<K: ClosedSet + PartialEq + Debug>` (the
870/// strict union of the sweep body's projection + the panic-message
871/// substrate-wide shape) — every production `ClosedSet` implementor
872/// across the crate carries `Debug + PartialEq` through the
873/// substrate-wide `#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash,
874/// DeriveClosedSet)]` shape, so no site pays a bound-widening cost
875/// to bind through this peer.
876#[track_caller]
877pub fn assert_wire_key_matches_label<T, K, F>(single_slot: F)
878where
879    T: serde::Serialize,
880    K: tatara_closed_set::ClosedSet + PartialEq + std::fmt::Debug,
881    F: Fn(K) -> T,
882{
883    for k in <K as tatara_closed_set::ClosedSet>::ALL.iter().copied() {
884        let parent = single_slot(k);
885        let value = serde_json::to_value(&parent)
886            .unwrap_or_else(|e| panic!("single_slot({k:?}) must serialize as JSON: {e}"));
887        let obj = value.as_object().unwrap_or_else(|| {
888            panic!("single_slot({k:?}) must serialize to a JSON object, got {value}")
889        });
890        let keys: Vec<&String> = obj.keys().collect();
891        assert_eq!(
892            keys.len(),
893            1,
894            "single_slot({k:?}) must serialize to exactly one populated field, got keys: {keys:?}",
895        );
896        let expected = <K as tatara_closed_set::ClosedSet>::label(k);
897        assert_eq!(
898            keys[0].as_str(),
899            expected,
900            "wire-key drift for {k:?}: single_slot's populated field '{}' must equal <K as ClosedSet>::label ({expected:?})",
901            keys[0],
902        );
903    }
904}
905
906/// Generic Display / [`ClosedSet::label`](tatara_closed_set::ClosedSet::label)
907/// alignment testkit — pins that [`core::fmt::Display`] renders each variant
908/// BYTE-IDENTICALLY to the trait-visible `ClosedSet::label` projection for
909/// every implementor.
910///
911/// Substrate primitive for the 29 sibling
912/// `X_display_matches_as_str` tests across `tatara-process`
913/// (`AllocationPhase`, `IntentKind`, `WorkloadKind`, `EncapsulationMode`,
914/// `EncapsulationTarget`, `ConditionKind`, `TerminateReasonKind`,
915/// `AutoTerminateKind`, `SighupStrategy`, `ReplacementPolicy`,
916/// `ReturnPolicy`, `MemberState`, `PoolPhase`, `VerificationPhase`,
917/// `SelectStrategyKind`, `MustReachPhase`, `ExportTrigger`,
918/// `ReportFormat`, `ReportPayloadShape`, `ArtifactKind`, `ChannelKind`,
919/// `DataClassification`, `ConvergencePointType`, `Arity`,
920/// `SubstrateType`, `CalmClassification`, `OptimizationDirection`,
921/// `HorizonKind`, `TeardownPolicy`) that pre-lift each restated the
922/// same
923/// ```text
924/// for v in K::ALL {
925///     assert_eq!(v.to_string(), v.as_str());
926/// }
927/// ```
928/// two-line probe verbatim at their own test bodies — byte-identical
929/// projections whose only per-carrier knob is the closed-set type name.
930/// Post-lift each site collapses to ONE
931/// `assert_display_matches_label::<X>()` invocation whose body IS the
932/// substrate primitive's own dispatch.
933///
934/// The primitive projects through the STABLE trait-visible name
935/// [`ClosedSet::label`](tatara_closed_set::ClosedSet::label) rather
936/// than the inherent `.as_str()` each site publishes locally. Every
937/// production implementor here derives its `label` body from `as_str`
938/// via `#[closed_set(via = "as_str", display)]` (the substrate-wide
939/// derive shape), so the two are byte-identical by construction; the
940/// primitive's projection through `label` therefore pins the SAME
941/// invariant the pre-lift bodies pinned while binding to the
942/// stable trait-visible surface. A future implementor whose inherent
943/// canonical projection is named something other than `as_str` (e.g.
944/// `.keyword()`, `.spelling()`) but still routes through
945/// `#[closed_set(via = "...", display)]` picks up the alignment check
946/// through ONE `assert_display_matches_label::<X>()` invocation with
947/// no inherent-name coupling at the test site.
948///
949/// A fifth (or thirtieth, or hundredth) implementor picks up the
950/// Display-alignment check through ONE
951/// `#[derive(tatara_closed_set::DeriveClosedSet)]` + `display`
952/// attribute + ONE `assert_display_matches_label::<X>()` call site —
953/// no re-authored two-line
954/// `for v in K::ALL { assert_eq!(v.to_string(), v.as_str()) }` body
955/// at the test surface, no per-site drift risk where 28 sibling
956/// tests carry the assertion and the 29th forgets.
957///
958/// Sibling shape to [`assert_kind_list_matches_closed_set`] on the
959/// (`T::KIND_LIST` slash-join, `Display` byte-identity) axis: both
960/// project the closed-set's label surface onto ONE typed contract
961/// and pin it against a per-implementor rendering; the former for
962/// the tagged-union parent's [`TaggedUnion::KIND_LIST`] `&'static str`,
963/// this one for the enum's `Display` byte stream. Together they close
964/// the "label surface must round-trip verbatim" invariant every
965/// closed-set-carrying implementor across the crate publishes.
966#[track_caller]
967pub fn assert_display_matches_label<T>()
968where
969    T: tatara_closed_set::ClosedSet + core::fmt::Display + PartialEq + core::fmt::Debug,
970{
971    let type_name = core::any::type_name::<T>();
972    for &v in <T as tatara_closed_set::ClosedSet>::ALL {
973        let rendered = v.to_string();
974        let expected = <T as tatara_closed_set::ClosedSet>::label(v);
975        assert_eq!(
976            rendered.as_str(),
977            expected,
978            "{type_name}: Display drifted from ClosedSet::label for {v:?} — expected {expected:?}, got {rendered:?}",
979        );
980    }
981}
982
983/// CANONICAL-KEY CONTRACT testkit — pins that each variant's serde
984/// serialization (as a JSON string value, unquoted) matches its
985/// canonical [`ClosedSet::label`](tatara_closed_set::ClosedSet::label)
986/// projection BYTE-IDENTICALLY for every implementor.
987///
988/// Substrate primitive for the 20 sibling
989/// `X_as_str_matches_serde` tests across `tatara-process`
990/// (`TeardownPolicy`, `EncapsulationMode`, `ConditionKind`,
991/// `SighupStrategy`, `ReplacementPolicy`, `ReturnPolicy`, `MemberState`,
992/// `PoolPhase`, `VerificationPhase`, `MustReachPhase`, `WorkloadKind`,
993/// `ExportTrigger`, `ReportFormat`, `DataClassification`,
994/// `ConvergencePointType`, `SubstrateType`, `CalmClassification`,
995/// `OptimizationDirection`, `HorizonKind`, `AllocationPhase`) that
996/// pre-lift each restated the same
997/// ```text
998/// for v in K::ALL {
999///     let serialized = serde_json::to_string(&v).expect("serialize");
1000///     let unquoted = serialized
1001///         .trim_start_matches('"')
1002///         .trim_end_matches('"')
1003///         .to_string();
1004///     assert_eq!(unquoted, v.as_str(), "as_str drift for {v:?}: ...");
1005/// }
1006/// ```
1007/// four-line probe verbatim at their own test bodies — byte-identical
1008/// projections whose only per-carrier knob is the closed-set type name.
1009/// Post-lift each site collapses to ONE
1010/// `assert_label_matches_serde_serialization::<X>()` invocation whose
1011/// body IS the substrate primitive's own dispatch.
1012///
1013/// The primitive projects through the STABLE trait-visible name
1014/// [`ClosedSet::label`](tatara_closed_set::ClosedSet::label) rather
1015/// than the inherent `.as_str()` each site publishes locally. Every
1016/// production implementor here derives its `label` body from `as_str`
1017/// via `#[closed_set(via = "as_str", display)]` + `#[serde(rename_all
1018/// = "PascalCase")]` (the substrate-wide derive shape), so the two are
1019/// byte-identical by construction; the primitive's projection through
1020/// `label` therefore pins the SAME invariant the pre-lift bodies
1021/// pinned while binding to the stable trait-visible surface. A future
1022/// implementor whose canonical inherent projection is named something
1023/// other than `as_str` (e.g. `.keyword()`, `.spelling()`) but still
1024/// routes through `#[closed_set(via = "...")]` picks up the wire-format
1025/// alignment check through ONE call with no inherent-name coupling at
1026/// the test site.
1027///
1028/// A twenty-first (or hundredth) implementor picks up the alignment
1029/// check through ONE `#[derive(tatara_closed_set::DeriveClosedSet)]` +
1030/// `#[derive(serde::Serialize)]` + `#[serde(rename_all = "...")]`
1031/// attribute + ONE `assert_label_matches_serde_serialization::<X>()`
1032/// call site — no re-authored four-line probe body at the test surface,
1033/// no per-site drift risk where 19 sibling tests carry the assertion
1034/// and the 20th forgets, no `serde_json::to_string`+`trim_matches`+
1035/// `assert_eq!` composition re-derived per implementor.
1036///
1037/// Sibling shape to [`assert_display_matches_label`] on the
1038/// (Display byte-identity, serde-wire-format byte-identity) axis: both
1039/// project the closed-set's label surface onto ONE typed contract and
1040/// pin it against a per-implementor rendering; the former for the
1041/// enum's [`Display`](core::fmt::Display) byte stream, this one for
1042/// the serde JSON-string wire format. Together they close the "label
1043/// surface renders verbatim across every projection consumers reach
1044/// for" invariant every closed-set-carrying implementor across the
1045/// crate publishes.
1046#[track_caller]
1047pub fn assert_label_matches_serde_serialization<T>()
1048where
1049    T: tatara_closed_set::ClosedSet + serde::Serialize + core::fmt::Debug,
1050{
1051    let type_name = core::any::type_name::<T>();
1052    for &v in <T as tatara_closed_set::ClosedSet>::ALL {
1053        let serialized = serde_json::to_string(&v).unwrap_or_else(|e| {
1054            panic!("{type_name}: closed-set variant {v:?} must serialize: {e}")
1055        });
1056        let unquoted = serialized.trim_start_matches('"').trim_end_matches('"');
1057        let expected = <T as tatara_closed_set::ClosedSet>::label(v);
1058        assert_eq!(
1059            unquoted,
1060            expected,
1061            "{type_name}: serde output drifted from ClosedSet::label for {v:?} — expected {expected:?}, got {unquoted:?} (full serialization {serialized:?})",
1062        );
1063    }
1064}
1065
1066/// CLOSED-SET CONVENTION PANEL testkit — pins the FULL three-axis
1067/// label-surface convention (parse round-trip, Display byte-identity,
1068/// serde-JSON-string byte-identity) at ONE substrate call site per
1069/// implementor.
1070///
1071/// Compound-lift of [`tatara_closed_set::assert_closed_set_well_formed`]
1072/// + [`assert_display_matches_label`] + [`assert_label_matches_serde_
1073/// serialization`] — every closed-set enum on `ProcessSpec` that
1074/// carries the substrate-wide `#[derive(DeriveClosedSet)] +
1075/// #[derive(Serialize)] + #[closed_set(via = "as_str", display)] +
1076/// #[serde(rename_all = "PascalCase")]` shape publishes ALL THREE
1077/// axes of the label surface, and pre-lift each production test
1078/// module hand-authored three sibling one-line tests
1079/// (`X_is_well_formed_closed_set`, `X_display_matches_as_str`,
1080/// `X_as_str_matches_serde`) that each restated the SAME
1081/// `crate::tagged_union::assert_<axis>::<X>()` invocation with only
1082/// the axis name varying between siblings. Post-lift each site
1083/// collapses to ONE `assert_closed_set_convention_panel::<X>()`
1084/// invocation whose body IS the three-axis composition dispatched
1085/// through the substrate primitive here.
1086///
1087/// The three sub-assertions stay independently callable — a future
1088/// implementor that publishes only two of the three axes (a
1089/// `Display`-less internal enum, e.g., or a `Serialize`-less
1090/// runtime-only enum) still binds through the two sibling primitives
1091/// individually. The compound is a strict superset: any implementor
1092/// that satisfies the compound's bounds already satisfies each
1093/// sub-assertion's bounds by construction, and the failure mode of
1094/// each sub-assertion still surfaces with the exact-message
1095/// granularity `#[track_caller]` gives the individual primitives
1096/// (the compound is `#[track_caller]` too, so a sub-assertion panic
1097/// surfaces at the compound's call site — a future promotion could
1098/// wrap each sub-assertion in a `std::panic::catch_unwind` to
1099/// aggregate all three axis failures into ONE panic message, but the
1100/// pre-lift discipline is that each axis's failure surfaces with its
1101/// own diagnostic).
1102///
1103/// The compound's bounds are the strict union of the three sub-
1104/// assertions' bounds:
1105///   - [`assert_closed_set_well_formed`] requires
1106///     `T: ClosedSet + PartialEq + Debug` + `T::Unknown: Display`;
1107///   - [`assert_display_matches_label`] requires
1108///     `T: ClosedSet + Display + PartialEq + Debug`;
1109///   - [`assert_label_matches_serde_serialization`] requires
1110///     `T: ClosedSet + Serialize + Debug`.
1111/// The union `T: ClosedSet + Serialize + Display + PartialEq + Debug`
1112/// + `T::Unknown: Display` is what every 3-axis production consumer
1113/// already satisfies through the substrate-wide derive shape — any
1114/// implementor that fails the compound's bounds would ALSO fail the
1115/// individual sub-assertions' bounds, so the compound doesn't shrink
1116/// the reachable set of implementors relative to hand-authoring the
1117/// three sibling calls.
1118///
1119/// A future FOURTH label-surface projection (e.g. a `serde_yaml`
1120/// byte-identity axis if the crate gains a YAML wire form on closed-
1121/// set enums, or a `kubectl_annotation` axis if the reconciler grows
1122/// an annotation-carried label surface) lands as ONE new
1123/// `assert_<axis>_matches_label::<T>()` substrate primitive + ONE
1124/// new line inside this compound's body. Every one of the ~20
1125/// production implementors of the panel picks up the fourth-axis
1126/// alignment check mechanically at their sole `assert_closed_set_
1127/// convention_panel::<X>()` call site — no per-implementor test-site
1128/// authoring, no per-crate test-site drop pathway where 19 sibling
1129/// call sites carry the check and the 20th forgets. The exact
1130/// promise `e4a4eba`'s future gain #2 named after
1131/// `assert_label_matches_serde_serialization` opened the wire-format
1132/// axis: a workspace-wide panel with byte-identical calling shapes
1133/// (`assert_X::<T>()`) that composes as freely as its sub-primitives.
1134///
1135/// Sibling shape to [`assert_variant_round_trip`] +
1136/// [`assert_kind_list_matches_closed_set`] +
1137/// [`assert_two_slots_ambiguous`] +
1138/// [`assert_single_slot_key_matches_label`] on the tagged-union
1139/// PARENT axis: the parent-side compound would compose the four
1140/// parent-side per-axis primitives, this one composes the three
1141/// child-side per-axis primitives on the child's [`ClosedSet`]
1142/// surface. Together the two compounds close the "closed-set
1143/// convention holds across every projection consumers reach for" at
1144/// two adjacent panels — one per closed-set-carrying enum, one per
1145/// tagged-union parent.
1146///
1147/// Theory anchor: THEORY.md §V.1 (knowable platform) — the
1148/// three-axis label-surface convention becomes ONE typed theorem
1149/// provable generically over any
1150/// `T: ClosedSet + Serialize + Display + PartialEq + Debug` bound
1151/// rather than THREE hand-authored per-implementor one-line probes
1152/// held coherent by test-module convention. THEORY.md §II.1
1153/// invariant 5 (composition preserves proofs) — the three sub-
1154/// assertions compose structurally through ONE primitive here, so a
1155/// regression at ONE axis surfaces at the sub-assertion's own
1156/// panic message rather than as silent drift at every consumer that
1157/// might otherwise forget to include the axis in its per-site
1158/// author-time enumeration.
1159#[track_caller]
1160pub fn assert_closed_set_convention_panel<T>()
1161where
1162    T: tatara_closed_set::ClosedSet
1163        + serde::Serialize
1164        + core::fmt::Display
1165        + PartialEq
1166        + core::fmt::Debug,
1167    T::Unknown: core::fmt::Display,
1168{
1169    tatara_closed_set::assert_closed_set_well_formed::<T>();
1170    assert_display_matches_label::<T>();
1171    assert_label_matches_serde_serialization::<T>();
1172}
1173
1174/// TAGGED-UNION CONVENTION PANEL testkit — pins the FULL four-axis
1175/// tagged-union parent convention (KIND_LIST diagnostic-stability,
1176/// variant round-trip on the single-slot side, ALL×ALL two-slot
1177/// ambiguity, wire-key alignment on the single-slot side) at ONE
1178/// substrate call site per parent.
1179///
1180/// Parent-side compound-lift, sibling to
1181/// [`assert_closed_set_convention_panel`] on the child's
1182/// [`tatara_closed_set::ClosedSet`] axis. Composes
1183/// [`assert_kind_list_matches_closed_set`] (no fixture) +
1184/// [`assert_variant_round_trip`] (`single_slot`) +
1185/// [`assert_two_slots_ambiguous`] (`two_slot`) +
1186/// [`assert_single_slot_key_matches_label`] (`single_slot`).
1187///
1188/// Every one of the four production `.variant()` parents on
1189/// `ProcessSpec` ([`crate::intent::Intent`],
1190/// [`crate::encapsulates::EncapsulationKind`],
1191/// [`crate::export::ArtifactSource`],
1192/// [`crate::export::VectorChannel`]) publishes the four-axis
1193/// convention through the shared substrate-wide attribute-set:
1194/// `#[derive(DeriveClosedSet)]` on the addressing `Kind`,
1195/// `declare_tagged_union_impls!` for the resolver+selector+trait
1196/// triple, `#[serde(rename_all = "camelCase")]` +
1197/// `#[serde(default, skip_serializing_if = "Option::is_none")]` on
1198/// every tagged-union slot. Pre-lift each production site
1199/// hand-authored FOUR sibling per-axis tests (`X_kind_round_trips_through_variant_kind`
1200/// / `X_kind_list_matches_ClosedSet_labels` /
1201/// `X_two_slots_are_ambiguous` /
1202/// `X_kind_as_str_matches_field_name`) that each restated the
1203/// SAME `crate::tagged_union::assert_<axis>::<T, _>(fixture)`
1204/// invocation with only the axis name + fixture arity varying
1205/// between siblings. Post-lift each site's four per-axis sibling
1206/// tests can collapse to ONE
1207/// `assert_tagged_union_convention_panel::<T, _, _>(
1208/// single_slot_X, two_slot_X)` invocation whose body IS the
1209/// four-axis composition dispatched through the substrate
1210/// primitive here.
1211///
1212/// The two closures stay per-site — every one of the four
1213/// production parents already owns a `single_slot_X(k) -> Parent`
1214/// / `two_slot_X(a, b) -> Parent` pair, and the substrate-local
1215/// `{single,two}_slot_*_probe` peers (siblings to the wire-key
1216/// sweep's substrate-local probes) let the substrate-wide sweep
1217/// below bind through the compound without reaching across the
1218/// per-crate test-module boundaries. Lifting the two closures
1219/// into the primitive would collapse the per-site construction
1220/// knowledge that stays deliberately local — the closure IS the
1221/// "populate slot k" / "populate the (a, b) pair" ground truth
1222/// for the parent's field structure.
1223///
1224/// Bounds are the strict union of the four sub-assertions' bounds:
1225/// [`assert_kind_list_matches_closed_set`] requires
1226/// `T: TaggedUnion`; [`assert_variant_round_trip`] requires
1227/// `T: TaggedUnion` + `T::Kind: PartialEq + Debug`
1228/// + `F: Fn(T::Kind) -> T`; [`assert_two_slots_ambiguous`] requires
1229/// `T: TaggedUnion` + `T::Kind: PartialEq + Debug`
1230/// + `T::Error: PartialEq + Debug` + `F: Fn(T::Kind, T::Kind) -> T`;
1231/// [`assert_single_slot_key_matches_label`] requires
1232/// `T: TaggedUnion + Serialize` + `T::Kind: PartialEq + Debug`
1233/// + `F: Fn(T::Kind) -> T`. The union
1234/// `T: TaggedUnion + Serialize` + `T::Kind: PartialEq + Debug`
1235/// + `T::Error: PartialEq + Debug` + `F1: Fn(T::Kind) -> T`
1236/// + `F2: Fn(T::Kind, T::Kind) -> T` is what every one of the four
1237/// production parents already satisfies through the shared
1238/// substrate-wide impls — any implementor that fails the compound's
1239/// bounds would ALSO fail the individual sub-assertions' bounds,
1240/// so the compound doesn't shrink the reachable set of
1241/// implementors relative to hand-authoring the four sibling calls.
1242/// The `single_slot` closure is dispatched to
1243/// [`assert_variant_round_trip`] by reference so the compound can
1244/// re-dispatch it to [`assert_single_slot_key_matches_label`] by
1245/// value on the final call — a caller passes ONE `Fn(T::Kind) -> T`
1246/// factory (not `FnOnce`) at the two axes that need it.
1247///
1248/// `#[track_caller]` on both the compound and each sub-primitive,
1249/// so a sub-assertion panic surfaces at the compound's caller site
1250/// with the failing axis's exact panic-message substring
1251/// (e.g. "TaggedUnion KIND_LIST drift", "select→variant_kind
1252/// round-trip failed", "should resolve Ambiguous", "wire-key
1253/// drift"). The four sub-assertions stay independently callable —
1254/// a future parent that publishes only three of the four axes (a
1255/// wire-format-less runtime parent, e.g., or an
1256/// ambiguity-less parent whose `.variant()` short-circuits on
1257/// the first populated slot) still binds through the sibling
1258/// primitives individually.
1259///
1260/// A future FIFTH parent-side projection (e.g. a
1261/// `two_slots_have_stable_diagnostic` axis if the ambiguity error
1262/// gains a per-parent operator-facing message, or a
1263/// `variant_kind_stays_stable_across_generation` axis if the
1264/// resolver's iteration order becomes load-bearing) lands as ONE
1265/// new `assert_<axis>::<T, _>(...)` substrate primitive + ONE new
1266/// line inside this compound's body. Every one of the four
1267/// production parents picks up the fifth-axis alignment check
1268/// mechanically at their sole
1269/// `assert_tagged_union_convention_panel::<T, _, _>(single_slot,
1270/// two_slot)` call site — no per-parent test-site authoring, no
1271/// per-crate test-site drop pathway where 3 sibling call sites
1272/// carry the check and the 4th forgets. The exact promise the
1273/// child-side [`assert_closed_set_convention_panel`] compound's
1274/// docstring named on the child axis, extended here to the parent
1275/// axis: a workspace-wide panel with byte-identical calling shapes
1276/// (`assert_<compound>::<T, _, _>(single_slot, two_slot)`) that
1277/// composes as freely as its sub-primitives.
1278///
1279/// The [`crate::lifetime::Lifetime`] site is DELIBERATELY excluded
1280/// through the `T: TaggedUnion` bound — `Lifetime`'s `variant()`
1281/// returns `Ok(Permanent)` on empty rather than an `Empty` typed
1282/// error, so its projection shape diverges from the four
1283/// Empty-projecting parents. Same reasoning as [`resolve_or_err`]'s
1284/// / [`assert_variant_round_trip`]'s / [`assert_two_slots_ambiguous`]'s
1285/// / [`assert_single_slot_key_matches_label`]'s exclusions.
1286///
1287/// Theory anchor: THEORY.md §V.1 (knowable platform) — the
1288/// four-axis parent-side tagged-union convention becomes ONE typed
1289/// theorem provable generically over any
1290/// `T: TaggedUnion + Serialize` bound rather than FOUR
1291/// hand-authored per-parent tests held coherent by test-module
1292/// convention. THEORY.md §II.1 invariant 5 (composition preserves
1293/// proofs) — the four sub-assertions compose structurally through
1294/// ONE primitive here, so a regression at ONE axis surfaces at the
1295/// sub-assertion's own panic message rather than as silent drift
1296/// at every parent that might otherwise forget to include the
1297/// axis in its per-site author-time enumeration.
1298#[track_caller]
1299pub fn assert_tagged_union_convention_panel<T, F1, F2>(single_slot: F1, two_slot: F2)
1300where
1301    T: TaggedUnion + serde::Serialize,
1302    T::Kind: PartialEq + std::fmt::Debug,
1303    T::Error: PartialEq + std::fmt::Debug,
1304    F1: Fn(T::Kind) -> T,
1305    F2: Fn(T::Kind, T::Kind) -> T,
1306{
1307    assert_kind_list_matches_closed_set::<T>();
1308    assert_variant_round_trip::<T, _>(&single_slot);
1309    assert_two_slots_ambiguous::<T, _>(two_slot);
1310    assert_has_matches_select::<T, _>(&single_slot);
1311    assert_single_slot_key_matches_label::<T, _>(single_slot);
1312}
1313
1314#[cfg(test)]
1315mod tests {
1316    use super::*;
1317
1318    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
1319    enum V {
1320        A,
1321        B,
1322        C,
1323    }
1324
1325    #[test]
1326    fn empty_candidate_list_is_none() {
1327        let r: Result<V, _> = resolve(std::iter::empty());
1328        assert_eq!(r.unwrap_err(), ResolveError::None);
1329    }
1330
1331    #[test]
1332    fn all_none_is_none() {
1333        let r: Result<V, _> = resolve([None, None, None]);
1334        assert_eq!(r.unwrap_err(), ResolveError::None);
1335    }
1336
1337    #[test]
1338    fn single_some_is_resolved_regardless_of_position() {
1339        assert_eq!(resolve([Some(V::A), None, None]).unwrap(), V::A);
1340        assert_eq!(resolve([None, Some(V::B), None]).unwrap(), V::B);
1341        assert_eq!(resolve([None, None, Some(V::C)]).unwrap(), V::C);
1342    }
1343
1344    #[test]
1345    fn two_or_more_some_is_many() {
1346        assert_eq!(
1347            resolve([Some(V::A), Some(V::B), None]).unwrap_err(),
1348            ResolveError::Many
1349        );
1350        assert_eq!(
1351            resolve([Some(V::A), None, Some(V::C)]).unwrap_err(),
1352            ResolveError::Many
1353        );
1354        assert_eq!(
1355            resolve([None, Some(V::B), Some(V::C)]).unwrap_err(),
1356            ResolveError::Many
1357        );
1358        assert_eq!(
1359            resolve([Some(V::A), Some(V::B), Some(V::C)]).unwrap_err(),
1360            ResolveError::Many
1361        );
1362    }
1363
1364    /// Short-circuit invariant: once `Many` is decided, the sweep does
1365    /// NOT inspect further candidates. Encode it as a side-effect probe.
1366    #[test]
1367    fn many_short_circuits_after_second_some() {
1368        let mut visited = 0usize;
1369        let candidates = (0..4).map(|i| {
1370            visited += 1;
1371            // first two are Some, the rest would be Some too if we got there.
1372            Some(i)
1373        });
1374        // We can't actually consume `visited` here because it's borrowed in
1375        // the closure — fold the count via the resolver's short-circuit.
1376        let _ = resolve(candidates);
1377        // The resolver evaluates the iterator lazily up to the second
1378        // Some — index 0 (found = Some(0)), index 1 (Many → return).
1379        assert_eq!(visited, 2);
1380    }
1381
1382    /// The helper is value-agnostic — works with borrowed enum-view
1383    /// types matching the actual on-the-typescape callsites.
1384    #[test]
1385    fn works_with_borrowed_enum_view() {
1386        #[derive(Debug, PartialEq)]
1387        enum View<'a> {
1388            X(&'a u32),
1389            Y(&'a String),
1390        }
1391        let x = 7u32;
1392        let r = resolve([Some(View::X(&x)), None]).unwrap();
1393        assert_eq!(r, View::X(&7));
1394    }
1395
1396    /// Local sibling-shaped carrier used to pin the trait +
1397    /// [`resolve_or_err`] dispatch without depending on the
1398    /// crate's real error types.
1399    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
1400    enum E {
1401        Empty(&'static str),
1402        Ambiguous,
1403    }
1404
1405    impl TaggedUnionError for E {
1406        fn empty(kinds: &'static str) -> Self {
1407            E::Empty(kinds)
1408        }
1409        fn ambiguous() -> Self {
1410            E::Ambiguous
1411        }
1412    }
1413
1414    /// Four-outcome truth table at the compound-lift boundary.
1415    /// Pins that the two failure arms of [`resolve`] project onto
1416    /// the trait's two typed constructors byte-identically, and
1417    /// that the Ok arm falls through untouched.
1418    #[test]
1419    fn resolve_or_err_dispatches_each_arm_through_the_trait() {
1420        const KINDS: &str = "a/b/c";
1421
1422        assert_eq!(
1423            resolve_or_err::<V, E>([Some(V::A), None, None], KINDS).unwrap(),
1424            V::A
1425        );
1426        assert_eq!(
1427            resolve_or_err::<V, E>([None, Some(V::B), None], KINDS).unwrap(),
1428            V::B
1429        );
1430
1431        assert_eq!(
1432            resolve_or_err::<V, E>([None, None, None], KINDS).unwrap_err(),
1433            E::Empty(KINDS)
1434        );
1435
1436        assert_eq!(
1437            resolve_or_err::<V, E>([Some(V::A), Some(V::B), None], KINDS).unwrap_err(),
1438            E::Ambiguous
1439        );
1440    }
1441
1442    /// The trait's Empty arm carries the &'static str the caller
1443    /// hands `resolve_or_err`, verbatim — a rename at the caller's
1444    /// `KINDS` constant reaches the diagnostic surface intact.
1445    #[test]
1446    fn resolve_or_err_empty_carries_the_caller_kinds_verbatim() {
1447        const KINDS_ALPHA: &str = "alpha/beta";
1448        const KINDS_GAMMA: &str = "gamma/delta/epsilon";
1449
1450        assert_eq!(
1451            resolve_or_err::<V, E>([None, None], KINDS_ALPHA).unwrap_err(),
1452            E::Empty(KINDS_ALPHA)
1453        );
1454        assert_eq!(
1455            resolve_or_err::<V, E>([None, None, None], KINDS_GAMMA).unwrap_err(),
1456            E::Empty(KINDS_GAMMA)
1457        );
1458    }
1459
1460    /// The compound-lift preserves [`resolve`]'s short-circuit at
1461    /// the Many arm — a third-and-later candidate is not
1462    /// inspected once the second populated entry is seen.
1463    #[test]
1464    fn resolve_or_err_short_circuits_on_many() {
1465        let mut visited = 0usize;
1466        let candidates = (0..4).map(|i| {
1467            visited += 1;
1468            Some(i)
1469        });
1470        let _ = resolve_or_err::<i32, E>(candidates, "irrelevant");
1471        assert_eq!(visited, 2);
1472    }
1473
1474    // -------------------------------------------------------------------
1475    // `declare_tagged_union_error!` macro-emitted carrier — pins the
1476    // shape a fifth sibling would land through the macro instead of
1477    // hand-rolling the enum + `impl TaggedUnionError` block.
1478    // -------------------------------------------------------------------
1479
1480    crate::declare_tagged_union_error! {
1481        pub(super) MacroEmittedError,
1482        empty = "test carrier has no variant set (one of {0} required)",
1483        ambiguous = "test carrier has multiple variants set; exactly one required",
1484    }
1485
1486    /// The macro-emitted carrier's [`TaggedUnionError`] impl dispatches
1487    /// the same four-outcome truth table [`resolve_or_err`] pins for a
1488    /// hand-rolled carrier — pins that swapping a hand-rolled carrier
1489    /// for a macro-emitted one preserves the compound-lift's projection
1490    /// byte-identically.
1491    #[test]
1492    fn macro_emitted_carrier_projects_through_resolve_or_err() {
1493        const KINDS: &str = "one/two/three";
1494
1495        assert_eq!(
1496            resolve_or_err::<V, MacroEmittedError>([Some(V::A), None, None], KINDS).unwrap(),
1497            V::A
1498        );
1499        assert_eq!(
1500            resolve_or_err::<V, MacroEmittedError>([None, None, None], KINDS).unwrap_err(),
1501            MacroEmittedError::Empty(KINDS)
1502        );
1503        assert_eq!(
1504            resolve_or_err::<V, MacroEmittedError>([Some(V::A), Some(V::B), None], KINDS)
1505                .unwrap_err(),
1506            MacroEmittedError::Ambiguous
1507        );
1508    }
1509
1510    /// The macro-emitted carrier's `#[error(...)]` messages render the
1511    /// two operator-facing diagnostic strings the caller handed the
1512    /// macro, verbatim — a rename at the caller's literal reaches the
1513    /// operator diagnostic surface intact.
1514    #[test]
1515    fn macro_emitted_carrier_display_renders_caller_literals_verbatim() {
1516        assert_eq!(
1517            MacroEmittedError::Empty("alpha/beta").to_string(),
1518            "test carrier has no variant set (one of alpha/beta required)",
1519        );
1520        assert_eq!(
1521            MacroEmittedError::Ambiguous.to_string(),
1522            "test carrier has multiple variants set; exactly one required",
1523        );
1524    }
1525
1526    /// The macro-emitted carrier is `Copy` — a substrate-wide promise
1527    /// pinned by the macro's `#[derive(..., Copy, ...)]` header so a
1528    /// consumer treating the carrier as a value type (memcpy-cheap
1529    /// return, `.copied()` on an `Option<&E>`) stays valid across every
1530    /// carrier the macro emits.
1531    #[test]
1532    fn macro_emitted_carrier_is_copy() {
1533        fn assert_copy<T: Copy>() {}
1534        assert_copy::<MacroEmittedError>();
1535    }
1536
1537    // -------------------------------------------------------------------
1538    // `TaggedUnion` trait — declarative surface pinning the
1539    // (Kind, Error, KIND_LIST) triple. `assert_kind_list_matches_closed_set`
1540    // is the generic diagnostic-stability testkit primitive shared by
1541    // every implementor's `_error_empty_lists_every_kind_in_canonical_order`
1542    // site.
1543    // -------------------------------------------------------------------
1544
1545    /// Local sibling-shaped Kind enum used to pin the trait's
1546    /// diagnostic-stability primitive without depending on the crate's
1547    /// four production tagged unions. Uses [`tatara_closed_set::DeriveClosedSet`]
1548    /// so `<Self as ClosedSet>::labels_joined("/")` reaches the same
1549    /// substrate composition the four production sites bind through.
1550    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, tatara_closed_set::DeriveClosedSet)]
1551    #[closed_set(via = "as_str", generate_unknown, display)]
1552    enum LocalKind {
1553        Alpha,
1554        Beta,
1555        Gamma,
1556    }
1557
1558    impl LocalKind {
1559        const ALL: [Self; 3] = [Self::Alpha, Self::Beta, Self::Gamma];
1560        const fn as_str(self) -> &'static str {
1561            match self {
1562                Self::Alpha => "alpha",
1563                Self::Beta => "beta",
1564                Self::Gamma => "gamma",
1565            }
1566        }
1567    }
1568
1569    /// Local parent type — impls [`TaggedUnion`] with a `KIND_LIST`
1570    /// literal that matches the canonical `<LocalKind as
1571    /// ClosedSet>::labels_joined("/")` projection. Carries three
1572    /// `Option<u32>` slots so the substrate-primitive
1573    /// [`TaggedUnion::variant`] default method can be exercised
1574    /// directly on a sibling-shaped-but-crate-local parent, isolated
1575    /// from the four production tagged unions.
1576    ///
1577    /// Derives [`serde::Serialize`] with `skip_serializing_if =
1578    /// "Option::is_none"` on every slot so the wire-format primitive
1579    /// [`assert_single_slot_key_matches_label`] can be exercised
1580    /// directly against the sibling-shaped scaffold — mirrors the
1581    /// `#[serde(default, skip_serializing_if = "Option::is_none")]`
1582    /// annotation every one of the four production tagged unions
1583    /// carries on its own slots.
1584    #[derive(Default, serde::Serialize)]
1585    struct LocalParent {
1586        #[serde(skip_serializing_if = "Option::is_none")]
1587        alpha: Option<u32>,
1588        #[serde(skip_serializing_if = "Option::is_none")]
1589        beta: Option<u32>,
1590        #[serde(skip_serializing_if = "Option::is_none")]
1591        gamma: Option<u32>,
1592    }
1593
1594    /// Borrowed-view of a populated slot on [`LocalParent`] — the
1595    /// return type of [`LocalKind::select`] and the substrate-primitive
1596    /// [`TaggedUnion::variant`] default on `LocalParent`.
1597    #[derive(Debug, PartialEq)]
1598    enum LocalVariant<'a> {
1599        Alpha(&'a u32),
1600        Beta(&'a u32),
1601        Gamma(&'a u32),
1602    }
1603
1604    impl VariantSelector<LocalParent> for LocalKind {
1605        type Variant<'a> = LocalVariant<'a>;
1606        fn select<'a>(self, parent: &'a LocalParent) -> Option<LocalVariant<'a>>
1607        where
1608            Self: 'a,
1609        {
1610            match self {
1611                Self::Alpha => parent.alpha.as_ref().map(LocalVariant::Alpha),
1612                Self::Beta => parent.beta.as_ref().map(LocalVariant::Beta),
1613                Self::Gamma => parent.gamma.as_ref().map(LocalVariant::Gamma),
1614            }
1615        }
1616    }
1617
1618    impl VariantKind<LocalKind> for LocalVariant<'_> {
1619        fn variant_kind(&self) -> LocalKind {
1620            match self {
1621                Self::Alpha(_) => LocalKind::Alpha,
1622                Self::Beta(_) => LocalKind::Beta,
1623                Self::Gamma(_) => LocalKind::Gamma,
1624            }
1625        }
1626    }
1627
1628    crate::declare_tagged_union_error! {
1629        pub(super) LocalParentError,
1630        empty = "local carrier has no variant set (one of {0} required)",
1631        ambiguous = "local carrier has multiple variants set; exactly one required",
1632    }
1633
1634    impl TaggedUnion for LocalParent {
1635        type Kind = LocalKind;
1636        type Error = LocalParentError;
1637        const KIND_LIST: &'static str = "alpha/beta/gamma";
1638    }
1639
1640    /// The testkit primitive resolves the canonical join of every
1641    /// `LocalKind` variant's label against the trait's `KIND_LIST`
1642    /// constant byte-identically — the four production sites bind
1643    /// through this exact dispatch. The Ok arm is the "no drift"
1644    /// outcome; a divergence surfaces as a labeled assertion failure.
1645    #[test]
1646    fn assert_kind_list_matches_closed_set_accepts_coherent_impl() {
1647        assert_kind_list_matches_closed_set::<LocalParent>();
1648    }
1649
1650    /// The testkit primitive is a `#[track_caller]` compound-lift:
1651    /// a drift between `<T::Kind as ClosedSet>::labels_joined("/")`
1652    /// and `T::KIND_LIST` fails the assertion at the caller's site,
1653    /// not inside the primitive body. Pin the failing case with a
1654    /// local parent whose `KIND_LIST` is deliberately mis-authored
1655    /// (a variant reorder), so a regression that drops the drift
1656    /// detection fails-loudly here.
1657    #[test]
1658    #[should_panic(expected = "TaggedUnion KIND_LIST drift")]
1659    fn assert_kind_list_matches_closed_set_rejects_drifted_impl() {
1660        struct Drifted;
1661        // The `TaggedUnion` trait bounds `Kind: VariantSelector<Self>`
1662        // with `Variant<'a>: VariantKind<Self>`; the drift test only
1663        // exercises `assert_kind_list_matches_closed_set` (which reaches
1664        // the (Kind, KIND_LIST) pair, not the sweep body), so reusing
1665        // the sibling `LocalVariant<'a>` (with its already-load-bearing
1666        // `impl VariantKind<LocalKind>`) + always-`None` `select`
1667        // satisfies both bounds without wiring a real projection.
1668        impl VariantSelector<Drifted> for LocalKind {
1669            type Variant<'a> = LocalVariant<'a>;
1670            fn select<'a>(self, _: &'a Drifted) -> Option<LocalVariant<'a>>
1671            where
1672                Self: 'a,
1673            {
1674                None
1675            }
1676        }
1677        impl TaggedUnion for Drifted {
1678            type Kind = LocalKind;
1679            type Error = LocalParentError;
1680            // Deliberate drift — canonical join is "alpha/beta/gamma".
1681            const KIND_LIST: &'static str = "beta/alpha/gamma";
1682        }
1683        assert_kind_list_matches_closed_set::<Drifted>();
1684    }
1685
1686    /// Every one of the four production `.variant()` sites on
1687    /// `ProcessSpec` impls [`TaggedUnion`] with `KIND_LIST` reaching
1688    /// the substrate primitive `assert_kind_list_matches_closed_set`
1689    /// coherently. Sweep every production implementor at ONE
1690    /// substrate boundary so a regression that drifts a production
1691    /// site's `KIND_LIST` (or renames a `Kind` variant without
1692    /// updating the constant) fails BOTH at the per-crate test site
1693    /// AND at this substrate-wide sweep — no per-implementor test
1694    /// site can drop the check silently.
1695    #[test]
1696    fn every_production_tagged_union_binds_through_the_testkit_primitive() {
1697        assert_kind_list_matches_closed_set::<crate::intent::Intent>();
1698        assert_kind_list_matches_closed_set::<crate::encapsulates::EncapsulationKind>();
1699        assert_kind_list_matches_closed_set::<crate::export::ArtifactSource>();
1700        assert_kind_list_matches_closed_set::<crate::export::VectorChannel>();
1701    }
1702
1703    /// Every one of the four production `.variant()` sites on
1704    /// `ProcessSpec` binds through the wire-key primitive
1705    /// [`assert_single_slot_key_matches_label`] coherently — every
1706    /// per-site `single_slot_X(k)` factory serializes to a JSON object
1707    /// with EXACTLY ONE key whose name equals `k.label()` (delegating
1708    /// to each Kind's inherent `as_str`, matching the parent's serde
1709    /// `rename_all = "camelCase"` projection). Sweep every production
1710    /// implementor at ONE substrate boundary so a regression that
1711    /// drifts a production site's `single_slot_X` factory (populates
1712    /// the wrong slot; leaks residual slots between calls) OR the
1713    /// parent's field-to-kind alignment (`as_str` returns "receipts"
1714    /// but the field is named `receipt`) fails BOTH at the per-crate
1715    /// test site AND at this substrate-wide sweep — no per-implementor
1716    /// test site can drop the check silently.
1717    #[test]
1718    fn every_production_tagged_union_binds_through_the_wire_key_testkit_primitive() {
1719        assert_single_slot_key_matches_label::<crate::intent::Intent, _>(single_slot_intent_probe);
1720        assert_single_slot_key_matches_label::<crate::encapsulates::EncapsulationKind, _>(
1721            single_slot_encapsulation_kind_probe,
1722        );
1723        assert_single_slot_key_matches_label::<crate::export::ArtifactSource, _>(
1724            single_slot_artifact_source_probe,
1725        );
1726        assert_single_slot_key_matches_label::<crate::export::VectorChannel, _>(
1727            single_slot_vector_channel_probe,
1728        );
1729    }
1730
1731    /// The parent-side four-axis compound-lift dispatches Ok on a
1732    /// coherent implementor — the [`LocalParent`] scaffold publishes
1733    /// every axis (`TaggedUnion` via
1734    /// [`crate::declare_tagged_union_error`]-emitted `LocalParentError`
1735    /// + Serialize via `#[derive(serde::Serialize)]` +
1736    /// `LocalKind: PartialEq + Debug` +
1737    /// `LocalParentError: PartialEq + Debug`), matching the
1738    /// substrate-wide four-axis convention every one of the four
1739    /// production parents carries. The Ok arm is the "no drift"
1740    /// outcome; a divergence at ANY sub-assertion's composition
1741    /// inside the compound (accidentally dropped, silently reordered,
1742    /// or short-circuited) surfaces at the sub-primitive's own
1743    /// panic message (each sub-primitive is `#[track_caller]`), and
1744    /// the per-axis failing arms are pinned by the sibling
1745    /// `#[should_panic]` probes already at the per-axis primitive
1746    /// layer (`assert_kind_list_matches_closed_set_rejects_drifted_impl`,
1747    /// `assert_variant_round_trip_rejects_factory_that_leaves_slot_empty`,
1748    /// `assert_two_slots_ambiguous_rejects_factory_that_populates_only_one_slot`,
1749    /// `assert_single_slot_key_matches_label_rejects_factory_that_populates_wrong_slot`).
1750    /// Re-authoring per-axis drift probes at the compound layer
1751    /// would restate the SAME four axis-typed contracts through a
1752    /// compound wrapper without adding a new gate.
1753    #[test]
1754    fn assert_tagged_union_convention_panel_accepts_coherent_local_impl() {
1755        fn single_slot(k: LocalKind) -> LocalParent {
1756            match k {
1757                LocalKind::Alpha => LocalParent {
1758                    alpha: Some(11),
1759                    ..Default::default()
1760                },
1761                LocalKind::Beta => LocalParent {
1762                    beta: Some(22),
1763                    ..Default::default()
1764                },
1765                LocalKind::Gamma => LocalParent {
1766                    gamma: Some(33),
1767                    ..Default::default()
1768                },
1769            }
1770        }
1771        fn two_slot(a: LocalKind, b: LocalKind) -> LocalParent {
1772            let mut p = LocalParent::default();
1773            for k in [a, b] {
1774                match k {
1775                    LocalKind::Alpha => p.alpha = Some(11),
1776                    LocalKind::Beta => p.beta = Some(22),
1777                    LocalKind::Gamma => p.gamma = Some(33),
1778                }
1779            }
1780            p
1781        }
1782        assert_tagged_union_convention_panel::<LocalParent, _, _>(single_slot, two_slot);
1783    }
1784
1785    /// Every one of the four production `.variant()` parents on
1786    /// `ProcessSpec` binds through the four-axis convention-panel
1787    /// primitive [`assert_tagged_union_convention_panel`] coherently.
1788    /// Sweep every production parent at ONE substrate boundary so a
1789    /// regression that (a) drops ANY of the four sub-assertions from
1790    /// the compound's body, (b) reorders them in a way that skips
1791    /// one on Ok, (c) silently binds the compound against a
1792    /// hollowed-out sub-assertion body, or (d) drifts a substrate-
1793    /// local `{single,two}_slot_*_probe` fixture (populates the
1794    /// wrong slot; leaks residual slots between calls; the `.or()`
1795    /// composition drops a slot on the two-slot side) fails BOTH at
1796    /// the per-crate test site AND at this substrate-wide sweep.
1797    ///
1798    /// Pinned in lock-step with the sibling
1799    /// `every_production_tagged_union_binds_through_the_testkit_primitive`
1800    /// (KIND_LIST axis) and
1801    /// `every_production_tagged_union_binds_through_the_wire_key_testkit_primitive`
1802    /// (wire-key axis) sweeps — every parent enumerated below is a
1803    /// member of BOTH sibling sweeps (their bounds are strict
1804    /// subsets of the compound's `T: TaggedUnion + Serialize` +
1805    /// `T::Kind: PartialEq + Debug` + `T::Error: PartialEq + Debug`
1806    /// bound), and every parent additionally publishes both a
1807    /// substrate-local `single_slot_*_probe` and a
1808    /// substrate-local `two_slot_*_probe` peer above. Post-sweep the
1809    /// substrate-wide four-axis parent-side convention-panel
1810    /// discipline is a property of the workspace, not a per-file
1811    /// convention — even before any per-site test-body sweep
1812    /// collapses the four per-parent sibling tests into ONE compound
1813    /// call each.
1814    #[test]
1815    fn every_production_tagged_union_binds_through_the_convention_panel_testkit_primitive() {
1816        assert_tagged_union_convention_panel::<crate::intent::Intent, _, _>(
1817            single_slot_intent_probe,
1818            two_slot_intent_probe,
1819        );
1820        assert_tagged_union_convention_panel::<crate::encapsulates::EncapsulationKind, _, _>(
1821            single_slot_encapsulation_kind_probe,
1822            two_slot_encapsulation_kind_probe,
1823        );
1824        assert_tagged_union_convention_panel::<crate::export::ArtifactSource, _, _>(
1825            single_slot_artifact_source_probe,
1826            two_slot_artifact_source_probe,
1827        );
1828        assert_tagged_union_convention_panel::<crate::export::VectorChannel, _, _>(
1829            single_slot_vector_channel_probe,
1830            two_slot_vector_channel_probe,
1831        );
1832    }
1833
1834    /// The Display / label alignment primitive dispatches Ok on a
1835    /// coherent implementor — the [`LocalKind`] scaffold derives
1836    /// `Display` from `label` via `#[closed_set(via = "as_str",
1837    /// display)]`, matching the substrate-wide derive shape every
1838    /// production implementor across the crate carries. The Ok arm
1839    /// is the "no drift" outcome; a divergence surfaces as a labeled
1840    /// assertion failure at the caller site (this test's own line).
1841    #[test]
1842    fn assert_display_matches_label_accepts_coherent_impl() {
1843        assert_display_matches_label::<LocalKind>();
1844    }
1845
1846    /// A local closed-set scaffold whose `Display` deliberately
1847    /// diverges from `label` — pins the failing arm of the primitive.
1848    /// The `#[closed_set(via = "as_str")]` attribute WITHOUT `display`
1849    /// leaves the `Display` impl uncovered by the derive, and the
1850    /// hand-authored `impl Display` below emits a suffixed rendering
1851    /// that no `label` projection returns. A regression that drops
1852    /// the alignment assertion inside
1853    /// [`assert_display_matches_label`] fails-loudly at this
1854    /// `#[should_panic]` probe before it can silently thread through
1855    /// the 29 production `X_display_matches_as_str` sites.
1856    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, tatara_closed_set::DeriveClosedSet)]
1857    #[closed_set(via = "as_str", generate_unknown)]
1858    enum DisplayDriftKind {
1859        Alpha,
1860        Beta,
1861    }
1862
1863    impl DisplayDriftKind {
1864        const ALL: [Self; 2] = [Self::Alpha, Self::Beta];
1865        const fn as_str(self) -> &'static str {
1866            match self {
1867                Self::Alpha => "alpha",
1868                Self::Beta => "beta",
1869            }
1870        }
1871    }
1872
1873    impl std::fmt::Display for DisplayDriftKind {
1874        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1875            // Deliberate drift — Display suffixes the label with a
1876            // marker no `label` projection returns.
1877            write!(f, "{}!", self.as_str())
1878        }
1879    }
1880
1881    #[test]
1882    #[should_panic(expected = "Display drifted from ClosedSet::label")]
1883    fn assert_display_matches_label_rejects_drifted_impl() {
1884        assert_display_matches_label::<DisplayDriftKind>();
1885    }
1886
1887    /// Every closed-set enum across `tatara-process` that carried a
1888    /// hand-rolled `X_display_matches_as_str` test pre-lift now binds
1889    /// through the substrate primitive at ONE call site each.  This
1890    /// substrate-wide sweep pins every production Display-alignment
1891    /// consumer at ONE boundary so a per-crate test-site drop cannot
1892    /// silently disable the check — the sweep here catches the drift
1893    /// even when the per-site test body is removed. Mirrors the
1894    /// `every_production_tagged_union_binds_through_the_testkit_primitive`
1895    /// and `every_production_tagged_union_binds_through_the_wire_key_testkit_primitive`
1896    /// sibling sweeps on the (`KIND_LIST` slash-join, wire-key)
1897    /// axes; this one closes the (`Display` byte-identity) axis.
1898    #[test]
1899    fn every_production_display_impl_binds_through_the_testkit_primitive() {
1900        assert_display_matches_label::<crate::allocation::AllocationPhase>();
1901        assert_display_matches_label::<crate::boundary::ConditionKind>();
1902        assert_display_matches_label::<crate::classification::Arity>();
1903        assert_display_matches_label::<crate::classification::CalmClassification>();
1904        assert_display_matches_label::<crate::classification::ConvergencePointType>();
1905        assert_display_matches_label::<crate::classification::DataClassification>();
1906        assert_display_matches_label::<crate::classification::HorizonKind>();
1907        assert_display_matches_label::<crate::classification::OptimizationDirection>();
1908        assert_display_matches_label::<crate::classification::SubstrateType>();
1909        assert_display_matches_label::<crate::compliance::VerificationPhase>();
1910        assert_display_matches_label::<crate::encapsulates::EncapsulationMode>();
1911        assert_display_matches_label::<crate::encapsulates::EncapsulationTarget>();
1912        assert_display_matches_label::<crate::export::ArtifactKind>();
1913        assert_display_matches_label::<crate::export::ChannelKind>();
1914        assert_display_matches_label::<crate::export::ExportTrigger>();
1915        assert_display_matches_label::<crate::export::ReportFormat>();
1916        assert_display_matches_label::<crate::export::ReportPayloadShape>();
1917        assert_display_matches_label::<crate::intent::IntentKind>();
1918        assert_display_matches_label::<crate::intent::WorkloadKind>();
1919        assert_display_matches_label::<crate::lifetime::LifetimeKind>();
1920        assert_display_matches_label::<crate::lifetime::TeardownPolicy>();
1921        assert_display_matches_label::<crate::lifetime_clock::AutoTerminateKind>();
1922        assert_display_matches_label::<crate::lifetime_clock::TerminateReasonKind>();
1923        assert_display_matches_label::<crate::matrix::SelectStrategyKind>();
1924        assert_display_matches_label::<crate::pool::MemberState>();
1925        assert_display_matches_label::<crate::pool::PoolPhase>();
1926        assert_display_matches_label::<crate::pool::ReplacementPolicy>();
1927        assert_display_matches_label::<crate::pool::ReturnPolicy>();
1928        assert_display_matches_label::<crate::signal::SighupStrategy>();
1929        assert_display_matches_label::<crate::spec::MustReachPhase>();
1930    }
1931
1932    /// Local closed-set scaffold whose serde `rename_all = "lowercase"`
1933    /// projection matches its `via = "as_str"` label byte-identically —
1934    /// pins the Ok arm of the wire-format primitive. Every production
1935    /// implementor across the crate carries the substrate-wide
1936    /// `#[closed_set(via = "as_str")]` + `#[serde(rename_all = ...)]`
1937    /// pair whose alignment this scaffold pins on the sibling-shaped
1938    /// local surface.
1939    #[derive(
1940        Clone,
1941        Copy,
1942        Debug,
1943        PartialEq,
1944        Eq,
1945        Hash,
1946        serde::Serialize,
1947        tatara_closed_set::DeriveClosedSet,
1948    )]
1949    #[serde(rename_all = "lowercase")]
1950    #[closed_set(via = "as_str", generate_unknown)]
1951    enum SerdeAlignedKind {
1952        Alpha,
1953        Beta,
1954    }
1955
1956    impl SerdeAlignedKind {
1957        const ALL: [Self; 2] = [Self::Alpha, Self::Beta];
1958        const fn as_str(self) -> &'static str {
1959            match self {
1960                Self::Alpha => "alpha",
1961                Self::Beta => "beta",
1962            }
1963        }
1964    }
1965
1966    #[test]
1967    fn assert_label_matches_serde_serialization_accepts_coherent_impl() {
1968        assert_label_matches_serde_serialization::<SerdeAlignedKind>();
1969    }
1970
1971    /// A local closed-set scaffold whose serde output deliberately
1972    /// diverges from `label` — pins the failing arm of the wire-format
1973    /// primitive. The `#[serde(rename_all = "UPPERCASE")]` projection
1974    /// emits uppercase JSON strings while the `via = "as_str"` label
1975    /// stays lowercase. A regression that drops the alignment assertion
1976    /// inside [`assert_label_matches_serde_serialization`] fails-loudly
1977    /// at this `#[should_panic]` probe before it can silently thread
1978    /// through the 20 production `X_as_str_matches_serde` sites.
1979    #[derive(
1980        Clone,
1981        Copy,
1982        Debug,
1983        PartialEq,
1984        Eq,
1985        Hash,
1986        serde::Serialize,
1987        tatara_closed_set::DeriveClosedSet,
1988    )]
1989    #[serde(rename_all = "UPPERCASE")]
1990    #[closed_set(via = "as_str", generate_unknown)]
1991    enum SerdeDriftKind {
1992        Alpha,
1993        Beta,
1994    }
1995
1996    impl SerdeDriftKind {
1997        const ALL: [Self; 2] = [Self::Alpha, Self::Beta];
1998        const fn as_str(self) -> &'static str {
1999            match self {
2000                Self::Alpha => "alpha",
2001                Self::Beta => "beta",
2002            }
2003        }
2004    }
2005
2006    #[test]
2007    #[should_panic(expected = "serde output drifted from ClosedSet::label")]
2008    fn assert_label_matches_serde_serialization_rejects_drifted_impl() {
2009        assert_label_matches_serde_serialization::<SerdeDriftKind>();
2010    }
2011
2012    /// Local closed-set scaffold whose ALL THREE axes of the label-
2013    /// surface convention align by construction — pins the Ok arm of
2014    /// the compound-panel primitive.
2015    ///
2016    /// `#[serde(rename_all = "lowercase")]` matches the `via = "as_str"`
2017    /// labels byte-identically (the serde-alignment axis). The
2018    /// `display` sub-attribute on `#[closed_set(via = "as_str",
2019    /// display)]` derives `impl Display` from the same `as_str`
2020    /// projection (the Display-alignment axis). The `generate_unknown`
2021    /// sub-attribute emits the `T::Unknown` carrier the round-trip
2022    /// axis's `parse_label` returns on unknown input. Together these
2023    /// three attributes stamp the substrate-wide derive shape every
2024    /// production 3-axis-panel consumer carries; a caller that lands
2025    /// through this scaffold satisfies EVERY bound the compound's
2026    /// where-clause names.
2027    ///
2028    /// Peer to the sibling per-axis fixtures [`LocalKind`] (Display
2029    /// axis, no serde) and [`SerdeAlignedKind`] (serde axis, no
2030    /// Display) on the label-surface primitive family; this fixture
2031    /// closes the diagonal by carrying both attribute-sets at once,
2032    /// so a regression at ANY sub-assertion's composition inside the
2033    /// compound (the compound accidentally dropping the well-formed
2034    /// call, silently reordering the three calls, wrapping them in a
2035    /// short-circuit that skips the middle one on Ok, …) fails the
2036    /// compound's happy-path pin below rather than as silent drift at
2037    /// every 3-axis consumer.
2038    #[derive(
2039        Clone,
2040        Copy,
2041        Debug,
2042        PartialEq,
2043        Eq,
2044        Hash,
2045        serde::Serialize,
2046        tatara_closed_set::DeriveClosedSet,
2047    )]
2048    #[serde(rename_all = "lowercase")]
2049    #[closed_set(via = "as_str", generate_unknown, display)]
2050    enum PanelAlignedKind {
2051        Alpha,
2052        Beta,
2053    }
2054
2055    impl PanelAlignedKind {
2056        const ALL: [Self; 2] = [Self::Alpha, Self::Beta];
2057        const fn as_str(self) -> &'static str {
2058            match self {
2059                Self::Alpha => "alpha",
2060                Self::Beta => "beta",
2061            }
2062        }
2063    }
2064
2065    /// The compound-panel primitive dispatches Ok on a coherent
2066    /// implementor — [`PanelAlignedKind`] carries every attribute the
2067    /// substrate-wide 3-axis derive shape publishes, so all three
2068    /// sub-assertions the compound composes (well-formed, Display /
2069    /// label, serde / label) pass by construction. The Ok arm is the
2070    /// "no drift on any axis" outcome; a divergence at any single
2071    /// sub-assertion surfaces as that sub-assertion's own labeled
2072    /// panic message (with the caller-attributed line via
2073    /// `#[track_caller]` on both the compound and its sub-
2074    /// primitives), NOT as a silent pass.
2075    ///
2076    /// The per-axis failing arms are pinned by the sibling per-axis
2077    /// #[should_panic] probes above:
2078    ///   - the round-trip axis's failing arm is pinned by
2079    ///     [`tatara_closed_set::assert_closed_set_well_formed`]'s own
2080    ///     `#[should_panic]` probe in the `tatara-closed-set` crate;
2081    ///   - the Display axis's failing arm is pinned by
2082    ///     [`assert_display_matches_label_rejects_drifted_impl`] on
2083    ///     [`DisplayDriftKind`];
2084    ///   - the serde axis's failing arm is pinned by
2085    ///     [`assert_label_matches_serde_serialization_rejects_drifted_impl`]
2086    ///     on [`SerdeDriftKind`].
2087    /// Each per-axis drift fixture already surfaces its axis's exact
2088    /// panic-message substring, so re-authoring per-axis
2089    /// `#[should_panic]` probes at the compound layer would restate
2090    /// the SAME three axis-typed contracts through a compound
2091    /// wrapper — one more copy of the same three pins, not a new
2092    /// gate. The compound's happy-path pin here suffices to verify
2093    /// the composition doesn't lose ANY sub-assertion (a regression
2094    /// that swallows one axis silently would still fail the sibling
2095    /// sub-assertion's own drift probe on the drift fixture).
2096    #[test]
2097    fn assert_closed_set_convention_panel_accepts_coherent_impl() {
2098        assert_closed_set_convention_panel::<PanelAlignedKind>();
2099    }
2100
2101    /// Every closed-set enum across `tatara-process` that publishes
2102    /// ALL THREE axes of the label-surface convention (well-formed +
2103    /// Display-alignment + serde-alignment) now binds through the
2104    /// substrate compound-panel primitive at ONE call site each in
2105    /// this sweep. Pinned in lock-step with the sibling
2106    /// `every_production_serde_serialization_binds_through_the_testkit_primitive`
2107    /// sweep — every enum enumerated below is a member of BOTH sweeps
2108    /// (the compound's `T: Serialize + Display + ClosedSet + ...`
2109    /// bound is a strict superset of `assert_label_matches_serde_
2110    /// serialization`'s `T: ClosedSet + Serialize + Debug` bound, and
2111    /// the 20 wire-format consumers all additionally impl Display via
2112    /// `#[closed_set(via = "as_str", display)]`).
2113    ///
2114    /// A regression that (a) drops the compound's `assert_closed_set_
2115    /// well_formed` dispatch, (b) reorders the three sub-assertions
2116    /// in a way that skips one on Ok, or (c) silently binds the
2117    /// compound against a hollowed-out sub-assertion body catches
2118    /// here at the substrate-wide boundary — the sweep pins every
2119    /// production 3-axis consumer's compound-panel discipline through
2120    /// ONE test even before any per-site test-body sweep collapses
2121    /// the three per-enum sibling tests into ONE compound call each.
2122    /// Post-sweep the substrate-wide compound-panel discipline is a
2123    /// property of the workspace, not a per-file convention.
2124    #[test]
2125    fn every_production_convention_panel_binds_through_the_testkit_primitive() {
2126        assert_closed_set_convention_panel::<crate::allocation::AllocationPhase>();
2127        assert_closed_set_convention_panel::<crate::boundary::ConditionKind>();
2128        assert_closed_set_convention_panel::<crate::classification::CalmClassification>();
2129        assert_closed_set_convention_panel::<crate::classification::ConvergencePointType>();
2130        assert_closed_set_convention_panel::<crate::classification::DataClassification>();
2131        assert_closed_set_convention_panel::<crate::classification::HorizonKind>();
2132        assert_closed_set_convention_panel::<crate::classification::OptimizationDirection>();
2133        assert_closed_set_convention_panel::<crate::classification::SubstrateType>();
2134        assert_closed_set_convention_panel::<crate::compliance::VerificationPhase>();
2135        assert_closed_set_convention_panel::<crate::encapsulates::EncapsulationMode>();
2136        assert_closed_set_convention_panel::<crate::export::ExportTrigger>();
2137        assert_closed_set_convention_panel::<crate::export::ReportFormat>();
2138        assert_closed_set_convention_panel::<crate::intent::WorkloadKind>();
2139        assert_closed_set_convention_panel::<crate::lifetime::TeardownPolicy>();
2140        assert_closed_set_convention_panel::<crate::pool::MemberState>();
2141        assert_closed_set_convention_panel::<crate::pool::PoolPhase>();
2142        assert_closed_set_convention_panel::<crate::pool::ReplacementPolicy>();
2143        assert_closed_set_convention_panel::<crate::pool::ReturnPolicy>();
2144        assert_closed_set_convention_panel::<crate::signal::SighupStrategy>();
2145        assert_closed_set_convention_panel::<crate::spec::MustReachPhase>();
2146    }
2147
2148    /// Every closed-set enum across `tatara-process` that carried a
2149    /// hand-rolled `X_as_str_matches_serde` test pre-lift now binds
2150    /// through the substrate primitive at ONE call site each. This
2151    /// substrate-wide sweep pins every production wire-format alignment
2152    /// consumer at ONE boundary so a per-crate test-site drop cannot
2153    /// silently disable the check — the sweep here catches the drift
2154    /// even when the per-site test body is removed. Mirrors the sibling
2155    /// `every_production_display_impl_binds_through_the_testkit_primitive`
2156    /// sweep on the (Display byte-identity) axis; this one closes the
2157    /// (serde JSON-string byte-identity) axis.
2158    #[test]
2159    fn every_production_serde_serialization_binds_through_the_testkit_primitive() {
2160        assert_label_matches_serde_serialization::<crate::allocation::AllocationPhase>();
2161        assert_label_matches_serde_serialization::<crate::boundary::ConditionKind>();
2162        assert_label_matches_serde_serialization::<crate::classification::CalmClassification>();
2163        assert_label_matches_serde_serialization::<crate::classification::ConvergencePointType>();
2164        assert_label_matches_serde_serialization::<crate::classification::DataClassification>();
2165        assert_label_matches_serde_serialization::<crate::classification::HorizonKind>();
2166        assert_label_matches_serde_serialization::<crate::classification::OptimizationDirection>();
2167        assert_label_matches_serde_serialization::<crate::classification::SubstrateType>();
2168        assert_label_matches_serde_serialization::<crate::compliance::VerificationPhase>();
2169        assert_label_matches_serde_serialization::<crate::encapsulates::EncapsulationMode>();
2170        assert_label_matches_serde_serialization::<crate::export::ExportTrigger>();
2171        assert_label_matches_serde_serialization::<crate::export::ReportFormat>();
2172        assert_label_matches_serde_serialization::<crate::intent::WorkloadKind>();
2173        assert_label_matches_serde_serialization::<crate::lifetime::TeardownPolicy>();
2174        assert_label_matches_serde_serialization::<crate::pool::MemberState>();
2175        assert_label_matches_serde_serialization::<crate::pool::PoolPhase>();
2176        assert_label_matches_serde_serialization::<crate::pool::ReplacementPolicy>();
2177        assert_label_matches_serde_serialization::<crate::pool::ReturnPolicy>();
2178        assert_label_matches_serde_serialization::<crate::signal::SighupStrategy>();
2179        assert_label_matches_serde_serialization::<crate::spec::MustReachPhase>();
2180    }
2181
2182    // Substrate-local single-slot factories — mirror the per-site
2183    // `single_slot_X` test helpers each production site owns, so the
2184    // substrate-wide sweep above binds through the wire-key primitive
2185    // without reaching across the per-crate test-module boundaries the
2186    // per-site helpers are scoped to. The primitive only requires that
2187    // the addressed slot on the parent is populated; the inner spec's
2188    // exact field values are irrelevant to the wire-key check.
2189
2190    fn single_slot_intent_probe(kind: crate::intent::IntentKind) -> crate::intent::Intent {
2191        use crate::intent::{
2192            AplicacaoIntent, ContainerIntent, FluxIntent, GuestIntent, Intent, IntentKind,
2193            LispIntent, NixIntent, WorkloadKind,
2194        };
2195        match kind {
2196            IntentKind::Nix => Intent {
2197                nix: Some(NixIntent {
2198                    flake_ref: "f".into(),
2199                    attribute: "a".into(),
2200                    system: None,
2201                    attic_cache: None,
2202                    extra_args: vec![],
2203                    delegate_to_nix_build: false,
2204                }),
2205                ..Intent::default()
2206            },
2207            IntentKind::Flux => Intent {
2208                flux: Some(FluxIntent {
2209                    git_repository: "g".into(),
2210                    path: "p".into(),
2211                    git_repository_namespace: None,
2212                    target_namespace: None,
2213                    decrypt_sops: true,
2214                    helm_chart: None,
2215                    helm_values: None,
2216                }),
2217                ..Intent::default()
2218            },
2219            IntentKind::Lisp => Intent {
2220                lisp: Some(LispIntent {
2221                    source: "()".into(),
2222                    reader: "tatara-lisp".into(),
2223                    version: "v1".into(),
2224                    bindings: std::collections::BTreeMap::new(),
2225                }),
2226                ..Intent::default()
2227            },
2228            IntentKind::Container => Intent {
2229                container: Some(ContainerIntent {
2230                    image: "x".into(),
2231                    replicas: None,
2232                    command: vec![],
2233                    args: vec![],
2234                    env: std::collections::BTreeMap::new(),
2235                    workload_kind: WorkloadKind::default(),
2236                }),
2237                ..Intent::default()
2238            },
2239            IntentKind::Aplicacao => Intent {
2240                aplicacao: Some(AplicacaoIntent {
2241                    chart_ref: "x".into(),
2242                    version: "1".into(),
2243                    profile: String::new(),
2244                    values_overlay: serde_json::Value::Null,
2245                    release_name: None,
2246                    target_namespace: None,
2247                    install_timeout: None,
2248                }),
2249                ..Intent::default()
2250            },
2251            IntentKind::Guest => Intent {
2252                guest: Some(GuestIntent {
2253                    spec: serde_json::json!({"name": "x"}),
2254                    state_dir: None,
2255                    allow_remote_build: None,
2256                }),
2257                ..Intent::default()
2258            },
2259        }
2260    }
2261
2262    fn single_slot_encapsulation_kind_probe(
2263        target: crate::encapsulates::EncapsulationTarget,
2264    ) -> crate::encapsulates::EncapsulationKind {
2265        use crate::encapsulates::{
2266            BareWorkload, EncapsulationKind, EncapsulationTarget, ExistingHelmRelease,
2267            ExistingKustomization,
2268        };
2269        match target {
2270            EncapsulationTarget::ExistingHelmRelease => EncapsulationKind {
2271                existing_helm_release: Some(ExistingHelmRelease {
2272                    namespace: "ns".into(),
2273                    name: "hr".into(),
2274                    release_name: "rel".into(),
2275                }),
2276                ..EncapsulationKind::default()
2277            },
2278            EncapsulationTarget::ExistingKustomization => EncapsulationKind {
2279                existing_kustomization: Some(ExistingKustomization {
2280                    namespace: "ns".into(),
2281                    name: "ks".into(),
2282                }),
2283                ..EncapsulationKind::default()
2284            },
2285            EncapsulationTarget::BareWorkload => {
2286                let mut sel = std::collections::BTreeMap::new();
2287                sel.insert("app".into(), "x".into());
2288                EncapsulationKind {
2289                    bare_workload: Some(BareWorkload {
2290                        namespace: "ns".into(),
2291                        selector: sel,
2292                    }),
2293                    ..EncapsulationKind::default()
2294                }
2295            }
2296        }
2297    }
2298
2299    fn single_slot_artifact_source_probe(
2300        kind: crate::export::ArtifactKind,
2301    ) -> crate::export::ArtifactSource {
2302        use crate::export::{
2303            ArtifactKind, ArtifactSource, ProcessSnapshotSource, ReceiptsSource, ReportFormat,
2304            RunMarkerSource, TestReportSource,
2305        };
2306        match kind {
2307            ArtifactKind::Receipts => ArtifactSource {
2308                receipts: Some(ReceiptsSource::default()),
2309                ..ArtifactSource::default()
2310            },
2311            ArtifactKind::TestReport => ArtifactSource {
2312                test_report: Some(TestReportSource {
2313                    configmap: "cm".into(),
2314                    key: "k".into(),
2315                    format: ReportFormat::Junit,
2316                    namespace: None,
2317                }),
2318                ..ArtifactSource::default()
2319            },
2320            ArtifactKind::ProcessSnapshot => ArtifactSource {
2321                process_snapshot: Some(ProcessSnapshotSource::default()),
2322                ..ArtifactSource::default()
2323            },
2324            ArtifactKind::RunMarker => ArtifactSource {
2325                run_marker: Some(RunMarkerSource::default()),
2326                ..ArtifactSource::default()
2327            },
2328        }
2329    }
2330
2331    fn single_slot_vector_channel_probe(
2332        kind: crate::export::ChannelKind,
2333    ) -> crate::export::VectorChannel {
2334        use crate::export::{
2335            ChannelKind, HttpEventChannel, NatsSubjectChannel, StdoutChannel, VectorChannel,
2336        };
2337        match kind {
2338            ChannelKind::HttpEvent => VectorChannel {
2339                http_event: Some(HttpEventChannel {
2340                    endpoint: None,
2341                    signal_type: "x".into(),
2342                }),
2343                ..VectorChannel::default()
2344            },
2345            ChannelKind::NatsSubject => VectorChannel {
2346                nats_subject: Some(NatsSubjectChannel {
2347                    subject: "s".into(),
2348                    stream: "S".into(),
2349                    url: None,
2350                }),
2351                ..VectorChannel::default()
2352            },
2353            ChannelKind::Stdout => VectorChannel {
2354                stdout: Some(StdoutChannel::default()),
2355                ..VectorChannel::default()
2356            },
2357        }
2358    }
2359
2360    // Substrate-local two-slot factories — peers to the sibling
2361    // `single_slot_*_probe` block above. Each composes
2362    // `single_slot_*_probe(a)` with `single_slot_*_probe(b)`
2363    // through per-field `Option::or` on the parent's tagged-union
2364    // slots, matching the shape every per-site `two_slot_X(a, b)`
2365    // helper across the four production parents already carries.
2366    // The ambiguity-primitive only requires that BOTH addressed
2367    // slots on the parent are populated; the inner spec's exact
2368    // field values are irrelevant to the two-slot ambiguity check.
2369
2370    fn two_slot_intent_probe(
2371        a: crate::intent::IntentKind,
2372        b: crate::intent::IntentKind,
2373    ) -> crate::intent::Intent {
2374        let ia = single_slot_intent_probe(a);
2375        let ib = single_slot_intent_probe(b);
2376        crate::intent::Intent {
2377            nix: ia.nix.or(ib.nix),
2378            flux: ia.flux.or(ib.flux),
2379            lisp: ia.lisp.or(ib.lisp),
2380            container: ia.container.or(ib.container),
2381            aplicacao: ia.aplicacao.or(ib.aplicacao),
2382            guest: ia.guest.or(ib.guest),
2383        }
2384    }
2385
2386    fn two_slot_encapsulation_kind_probe(
2387        a: crate::encapsulates::EncapsulationTarget,
2388        b: crate::encapsulates::EncapsulationTarget,
2389    ) -> crate::encapsulates::EncapsulationKind {
2390        let ka = single_slot_encapsulation_kind_probe(a);
2391        let kb = single_slot_encapsulation_kind_probe(b);
2392        crate::encapsulates::EncapsulationKind {
2393            existing_helm_release: ka.existing_helm_release.or(kb.existing_helm_release),
2394            existing_kustomization: ka.existing_kustomization.or(kb.existing_kustomization),
2395            bare_workload: ka.bare_workload.or(kb.bare_workload),
2396        }
2397    }
2398
2399    fn two_slot_artifact_source_probe(
2400        a: crate::export::ArtifactKind,
2401        b: crate::export::ArtifactKind,
2402    ) -> crate::export::ArtifactSource {
2403        let sa = single_slot_artifact_source_probe(a);
2404        let sb = single_slot_artifact_source_probe(b);
2405        crate::export::ArtifactSource {
2406            receipts: sa.receipts.or(sb.receipts),
2407            test_report: sa.test_report.or(sb.test_report),
2408            process_snapshot: sa.process_snapshot.or(sb.process_snapshot),
2409            run_marker: sa.run_marker.or(sb.run_marker),
2410        }
2411    }
2412
2413    fn two_slot_vector_channel_probe(
2414        a: crate::export::ChannelKind,
2415        b: crate::export::ChannelKind,
2416    ) -> crate::export::VectorChannel {
2417        let ca = single_slot_vector_channel_probe(a);
2418        let cb = single_slot_vector_channel_probe(b);
2419        crate::export::VectorChannel {
2420            http_event: ca.http_event.or(cb.http_event),
2421            nats_subject: ca.nats_subject.or(cb.nats_subject),
2422            stdout: ca.stdout.or(cb.stdout),
2423        }
2424    }
2425
2426    /// The trait's `KIND_LIST` associated const IS the same
2427    /// `&'static str` the inherent `_LIST` constant publishes at
2428    /// each production site — pin identity via `std::ptr::eq` so a
2429    /// future silent copy (e.g. `const KIND_LIST: &'static str =
2430    /// "...literal...";` at the impl block) is caught here.
2431    #[test]
2432    fn production_tagged_union_kind_list_borrows_the_inherent_constant() {
2433        assert!(std::ptr::eq(
2434            <crate::intent::Intent as TaggedUnion>::KIND_LIST,
2435            crate::intent::INTENT_KIND_LIST,
2436        ));
2437        assert!(std::ptr::eq(
2438            <crate::encapsulates::EncapsulationKind as TaggedUnion>::KIND_LIST,
2439            crate::encapsulates::ENCAPSULATION_TARGET_LIST,
2440        ));
2441        assert!(std::ptr::eq(
2442            <crate::export::ArtifactSource as TaggedUnion>::KIND_LIST,
2443            crate::export::ARTIFACT_KIND_LIST,
2444        ));
2445        assert!(std::ptr::eq(
2446            <crate::export::VectorChannel as TaggedUnion>::KIND_LIST,
2447            crate::export::CHANNEL_KIND_LIST,
2448        ));
2449    }
2450
2451    // -------------------------------------------------------------------
2452    // `TaggedUnion::variant` default method — substrate primitive every
2453    // production `.variant()` inherent method delegates to. Pin the
2454    // four-outcome truth table (Empty on all-none, Ambiguous on many,
2455    // Ok on exactly-one at every position) directly on the sibling-
2456    // shaped local parent + local kind + local variant scaffold, so a
2457    // regression on the default body's short-circuit or
2458    // ClosedSet::ALL iteration shape fails here — before any per-parent
2459    // inherent test surfaces the drift.
2460    // -------------------------------------------------------------------
2461
2462    /// Every populated position across [`LocalKind::ALL`] resolves to
2463    /// its own [`LocalVariant`] arm through the default body's
2464    /// `resolve_or_err(<Kind as ClosedSet>::ALL.iter().copied()
2465    /// .map(|k| k.select(self)), KIND_LIST)` sweep. Pin every position
2466    /// so a regression that drifts the iteration order (or drops the
2467    /// `.iter().copied()` bridge to owned-`Copy` Kinds) fails at ONE
2468    /// substrate boundary rather than at four per-parent inherent test
2469    /// sites.
2470    #[test]
2471    fn tagged_union_default_variant_resolves_each_populated_slot() {
2472        let mut p = LocalParent {
2473            alpha: Some(11),
2474            ..Default::default()
2475        };
2476        assert_eq!(
2477            <LocalParent as TaggedUnion>::variant(&p).unwrap(),
2478            LocalVariant::Alpha(&11)
2479        );
2480        p = LocalParent {
2481            beta: Some(22),
2482            ..Default::default()
2483        };
2484        assert_eq!(
2485            <LocalParent as TaggedUnion>::variant(&p).unwrap(),
2486            LocalVariant::Beta(&22)
2487        );
2488        p = LocalParent {
2489            gamma: Some(33),
2490            ..Default::default()
2491        };
2492        assert_eq!(
2493            <LocalParent as TaggedUnion>::variant(&p).unwrap(),
2494            LocalVariant::Gamma(&33)
2495        );
2496    }
2497
2498    /// A [`LocalParent`] with no populated slot resolves through the
2499    /// default body to a [`TaggedUnionError::empty`] carrier whose
2500    /// payload IS the trait's [`TaggedUnion::KIND_LIST`] constant —
2501    /// pin identity via [`std::ptr::eq`] so a regression that
2502    /// composes a fresh `&'static str` at the empty arm (instead of
2503    /// carrying the trait's constant verbatim) is caught here. This
2504    /// is the substrate-wide guarantee the four production sites'
2505    /// operator diagnostics depend on: a rename at
2506    /// `<Parent as TaggedUnion>::KIND_LIST` reaches the error surface
2507    /// intact through ONE `&'static str` handoff.
2508    #[test]
2509    fn tagged_union_default_variant_empty_carries_kind_list_by_pointer() {
2510        let empty = LocalParent::default();
2511        let err = <LocalParent as TaggedUnion>::variant(&empty).unwrap_err();
2512        match err {
2513            LocalParentError::Empty(list) => {
2514                assert!(
2515                    std::ptr::eq(list, <LocalParent as TaggedUnion>::KIND_LIST),
2516                    "TaggedUnion::variant default must carry KIND_LIST by pointer, not by re-composition",
2517                );
2518            }
2519            LocalParentError::Ambiguous => {
2520                panic!("expected Empty carrier, got Ambiguous");
2521            }
2522        }
2523    }
2524
2525    /// A [`LocalParent`] with two populated slots resolves through
2526    /// the default body to a [`TaggedUnionError::ambiguous`] carrier —
2527    /// pin the Many arm at the substrate boundary so a regression
2528    /// that drops the short-circuit (or misroutes the Many arm to
2529    /// Empty) is caught here.
2530    #[test]
2531    fn tagged_union_default_variant_ambiguous_on_multiple_populated_slots() {
2532        let p = LocalParent {
2533            alpha: Some(1),
2534            beta: Some(2),
2535            gamma: None,
2536        };
2537        assert_eq!(
2538            <LocalParent as TaggedUnion>::variant(&p).unwrap_err(),
2539            LocalParentError::Ambiguous
2540        );
2541    }
2542
2543    /// Every one of the four production `.variant()` inherent methods
2544    /// dispatches through the trait's default body byte-identically —
2545    /// pin the delegation shape (inherent forwarder → trait default)
2546    /// on a probe per parent so a regression that copies the pre-lift
2547    /// hand-rolled `resolve_or_err(...)` body back into the inherent
2548    /// method (instead of the `<Self as TaggedUnion>::variant(self)`
2549    /// one-line delegation) reaches this substrate boundary before it
2550    /// reaches any operator diagnostic.
2551    #[test]
2552    fn every_production_inherent_variant_dispatches_through_trait_default() {
2553        use crate::encapsulates::{EncapsulationKind, EncapsulationKindError};
2554        use crate::export::{ArtifactError, ArtifactSource, ChannelError, VectorChannel};
2555        use crate::intent::{Intent, IntentError};
2556
2557        // Intent: default of all-None resolves to Empty via the delegation.
2558        let i = Intent::default();
2559        match (i.variant(), <Intent as TaggedUnion>::variant(&i)) {
2560            (Err(IntentError::Empty(a)), Err(IntentError::Empty(b))) => assert!(
2561                std::ptr::eq(a, b),
2562                "Intent inherent and trait dispatch must return the same &'static str",
2563            ),
2564            (a, b) => panic!("Intent inherent/trait mismatch: inherent={a:?}, trait={b:?}"),
2565        }
2566
2567        // EncapsulationKind: same Empty projection through both dispatch paths.
2568        let k = EncapsulationKind::default();
2569        match (k.variant(), <EncapsulationKind as TaggedUnion>::variant(&k)) {
2570            (Err(EncapsulationKindError::Empty(a)), Err(EncapsulationKindError::Empty(b))) => {
2571                assert!(
2572                std::ptr::eq(a, b),
2573                "EncapsulationKind inherent and trait dispatch must return the same &'static str",
2574            )
2575            }
2576            (a, b) => {
2577                panic!("EncapsulationKind inherent/trait mismatch: inherent={a:?}, trait={b:?}")
2578            }
2579        }
2580
2581        // ArtifactSource: same Empty projection through both dispatch paths.
2582        let s = ArtifactSource::default();
2583        match (s.variant(), <ArtifactSource as TaggedUnion>::variant(&s)) {
2584            (Err(ArtifactError::Empty(a)), Err(ArtifactError::Empty(b))) => assert!(
2585                std::ptr::eq(a, b),
2586                "ArtifactSource inherent and trait dispatch must return the same &'static str",
2587            ),
2588            (a, b) => panic!("ArtifactSource inherent/trait mismatch: inherent={a:?}, trait={b:?}"),
2589        }
2590
2591        // VectorChannel: same Empty projection through both dispatch paths.
2592        let c = VectorChannel::default();
2593        match (c.variant(), <VectorChannel as TaggedUnion>::variant(&c)) {
2594            (Err(ChannelError::Empty(a)), Err(ChannelError::Empty(b))) => assert!(
2595                std::ptr::eq(a, b),
2596                "VectorChannel inherent and trait dispatch must return the same &'static str",
2597            ),
2598            (a, b) => panic!("VectorChannel inherent/trait mismatch: inherent={a:?}, trait={b:?}"),
2599        }
2600    }
2601
2602    // -------------------------------------------------------------------
2603    // `declare_tagged_union_impls!` macro — the three-block impl stanza
2604    // (inherent `.variant()` forwarder + `VariantSelector<Parent>` on
2605    // the Kind + `TaggedUnion` on the parent) as ONE authoring surface.
2606    // Pin the macro's shape against a sibling-shaped local family so a
2607    // regression on any of the three emitted blocks fails here before
2608    // it reaches the four production sites.
2609    // -------------------------------------------------------------------
2610
2611    /// Local sibling-shaped Kind for the macro-emitted-impls test — a
2612    /// dedicated closed set so this test can't share substrate with the
2613    /// hand-rolled [`LocalKind`] block above. Uses
2614    /// [`tatara_closed_set::DeriveClosedSet`] so the macro's
2615    /// `TaggedUnion` bound (`Kind: ClosedSet + VariantSelector<Self>`)
2616    /// is satisfied through the derive.
2617    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, tatara_closed_set::DeriveClosedSet)]
2618    #[closed_set(via = "as_str", generate_unknown)]
2619    enum MacroLocalKind {
2620        Foo,
2621        Bar,
2622    }
2623
2624    impl MacroLocalKind {
2625        const ALL: [Self; 2] = [Self::Foo, Self::Bar];
2626        const fn as_str(self) -> &'static str {
2627            match self {
2628                Self::Foo => "foo",
2629                Self::Bar => "bar",
2630            }
2631        }
2632        fn select<'a>(self, parent: &'a MacroLocalParent) -> Option<MacroLocalVariant<'a>> {
2633            match self {
2634                Self::Foo => parent.foo.as_ref().map(MacroLocalVariant::Foo),
2635                Self::Bar => parent.bar.as_ref().map(MacroLocalVariant::Bar),
2636            }
2637        }
2638    }
2639
2640    /// Local sibling-shaped parent for the macro-emitted-impls test —
2641    /// distinct from [`LocalParent`] so the macro's emitted impls
2642    /// don't collide with the hand-rolled trait impls above.
2643    ///
2644    /// Derives [`serde::Serialize`] with `skip_serializing_if =
2645    /// "Option::is_none"` on every slot so the wire-format primitive
2646    /// [`assert_single_slot_key_matches_label`] can be exercised
2647    /// through the macro-emitted `TaggedUnion` impl path — pins the
2648    /// substrate-wide guarantee that a fifth sibling landing through
2649    /// [`declare_tagged_union_impls!`] picks up the wire-alignment
2650    /// check for free.
2651    #[derive(Default, serde::Serialize)]
2652    struct MacroLocalParent {
2653        #[serde(skip_serializing_if = "Option::is_none")]
2654        foo: Option<u32>,
2655        #[serde(skip_serializing_if = "Option::is_none")]
2656        bar: Option<u32>,
2657    }
2658
2659    /// Borrowed-view of a populated slot on [`MacroLocalParent`] — the
2660    /// return type of the macro-emitted inherent `.variant()`.
2661    #[derive(Debug, PartialEq)]
2662    enum MacroLocalVariant<'a> {
2663        Foo(&'a u32),
2664        Bar(&'a u32),
2665    }
2666
2667    impl VariantKind<MacroLocalKind> for MacroLocalVariant<'_> {
2668        fn variant_kind(&self) -> MacroLocalKind {
2669            match self {
2670                Self::Foo(_) => MacroLocalKind::Foo,
2671                Self::Bar(_) => MacroLocalKind::Bar,
2672            }
2673        }
2674    }
2675
2676    crate::declare_tagged_union_error! {
2677        pub(super) MacroLocalError,
2678        empty = "macro-local parent has no variant set (one of {0} required)",
2679        ambiguous = "macro-local parent has multiple variants set; exactly one required",
2680    }
2681
2682    /// Slash-joined kind list — literal peer of
2683    /// [`crate::intent::INTENT_KIND_LIST`] etc. that the macro's
2684    /// `KIND_LIST` associated const borrows verbatim.
2685    const MACRO_LOCAL_KIND_LIST: &str = "foo/bar";
2686
2687    // ONE macro call emits: inherent `MacroLocalParent::variant`,
2688    // `impl VariantSelector<MacroLocalParent> for MacroLocalKind`, and
2689    // `impl TaggedUnion for MacroLocalParent`. The four production
2690    // sites bind through this exact same call shape.
2691    crate::declare_tagged_union_impls! {
2692        parent = MacroLocalParent,
2693        kind = MacroLocalKind,
2694        variant = MacroLocalVariant,
2695        error = MacroLocalError,
2696        kind_list = MACRO_LOCAL_KIND_LIST,
2697    }
2698
2699    /// The macro-emitted `impl TaggedUnion` binds the (Kind, Error,
2700    /// KIND_LIST) triple exactly as a hand-rolled block would — pin
2701    /// the diagnostic-stability testkit primitive through the macro's
2702    /// output so a regression on any of the three associated items
2703    /// (say the macro pulling `KIND_LIST` from the wrong argument
2704    /// slot) fails here.
2705    #[test]
2706    fn macro_emitted_tagged_union_impl_binds_kind_list_coherently() {
2707        assert_kind_list_matches_closed_set::<MacroLocalParent>();
2708        assert!(std::ptr::eq(
2709            <MacroLocalParent as TaggedUnion>::KIND_LIST,
2710            MACRO_LOCAL_KIND_LIST,
2711        ));
2712    }
2713
2714    /// The macro-emitted inherent `.variant()` forwarder dispatches
2715    /// through the trait default body — every populated slot resolves
2716    /// to its own [`MacroLocalVariant`] arm, all-none resolves to
2717    /// [`TaggedUnionError::empty`] carrying the trait's `KIND_LIST`
2718    /// by pointer, two-populated resolves to
2719    /// [`TaggedUnionError::ambiguous`]. The four production sites
2720    /// exercise the same four-outcome truth table through the same
2721    /// macro-emitted delegation shape.
2722    #[test]
2723    fn macro_emitted_inherent_variant_dispatches_the_four_outcome_truth_table() {
2724        // Foo populated.
2725        let p = MacroLocalParent {
2726            foo: Some(11),
2727            bar: None,
2728        };
2729        assert_eq!(p.variant().unwrap(), MacroLocalVariant::Foo(&11));
2730
2731        // Bar populated.
2732        let p = MacroLocalParent {
2733            foo: None,
2734            bar: Some(22),
2735        };
2736        assert_eq!(p.variant().unwrap(), MacroLocalVariant::Bar(&22));
2737
2738        // All none — Empty arm carries the trait's KIND_LIST value.
2739        // The by-pointer preservation across the trait default body is
2740        // pinned substrate-wide by
2741        // `tagged_union_default_variant_empty_carries_kind_list_by_pointer`
2742        // on the sibling hand-rolled `LocalParent`; this test only pins
2743        // that the macro-emitted `KIND_LIST = MACRO_LOCAL_KIND_LIST`
2744        // assignment reaches the operator diagnostic value-identically.
2745        let p = MacroLocalParent::default();
2746        match p.variant().unwrap_err() {
2747            MacroLocalError::Empty(list) => assert_eq!(list, MACRO_LOCAL_KIND_LIST),
2748            MacroLocalError::Ambiguous => panic!("expected Empty, got Ambiguous"),
2749        }
2750
2751        // Two populated — Ambiguous.
2752        let p = MacroLocalParent {
2753            foo: Some(1),
2754            bar: Some(2),
2755        };
2756        assert_eq!(p.variant().unwrap_err(), MacroLocalError::Ambiguous);
2757    }
2758
2759    /// The macro-emitted inherent `.has()` forwarder dispatches
2760    /// through the trait default body — the presence probe agrees
2761    /// with `Kind::select(&parent).is_some()` on the diagonal
2762    /// (populated slot AND matching Kind → `true`) and off the
2763    /// diagonal (populated slot BUT other Kind → `false`) for the
2764    /// same four-outcome truth table the macro-emitted `.variant()`
2765    /// covers. The four production sites bind through this exact
2766    /// same macro-emitted delegation shape; the substrate testkit
2767    /// primitive [`assert_has_matches_select`] sweeps this contract
2768    /// generically once each production Kind picks up the macro's
2769    /// output.
2770    #[test]
2771    fn macro_emitted_inherent_has_dispatches_the_presence_probe_diagonal() {
2772        // Foo populated → has(Foo) is true, has(Bar) is false.
2773        let p = MacroLocalParent {
2774            foo: Some(11),
2775            bar: None,
2776        };
2777        assert!(p.has(MacroLocalKind::Foo));
2778        assert!(!p.has(MacroLocalKind::Bar));
2779
2780        // Bar populated → has(Bar) is true, has(Foo) is false.
2781        let p = MacroLocalParent {
2782            foo: None,
2783            bar: Some(22),
2784        };
2785        assert!(!p.has(MacroLocalKind::Foo));
2786        assert!(p.has(MacroLocalKind::Bar));
2787
2788        // All none — every probe is false; no Empty carrier
2789        // allocation on this path (the presence-probe half of the
2790        // resolve contract deliberately elides diagnostic composition
2791        // when the caller only needs yes/no).
2792        let p = MacroLocalParent::default();
2793        assert!(!p.has(MacroLocalKind::Foo));
2794        assert!(!p.has(MacroLocalKind::Bar));
2795
2796        // Two populated — has(k) is true for BOTH populated slots
2797        // (the probe is a per-slot projection, not the parent-wide
2798        // resolver — Ambiguous is a resolve outcome, not a presence
2799        // outcome).
2800        let p = MacroLocalParent {
2801            foo: Some(1),
2802            bar: Some(2),
2803        };
2804        assert!(p.has(MacroLocalKind::Foo));
2805        assert!(p.has(MacroLocalKind::Bar));
2806    }
2807
2808    /// The macro-emitted `VariantSelector` impl's `select` body
2809    /// delegates to the Kind's inherent `<Kind>::select(self, parent)`
2810    /// — pin the delegation via `std::ptr::eq` on the returned
2811    /// borrowed view so a regression that inlines a divergent select
2812    /// body (rather than reaching the inherent method) is caught here.
2813    #[test]
2814    fn macro_emitted_variant_selector_delegates_to_inherent_select() {
2815        let p = MacroLocalParent {
2816            foo: Some(7),
2817            bar: None,
2818        };
2819        // Trait-dispatched select projects through the macro-emitted body.
2820        let via_trait =
2821            <MacroLocalKind as VariantSelector<MacroLocalParent>>::select(MacroLocalKind::Foo, &p)
2822                .unwrap();
2823        // Inherent select projects through the direct impl.
2824        let via_inherent = MacroLocalKind::Foo.select(&p).unwrap();
2825        match (via_trait, via_inherent) {
2826            (MacroLocalVariant::Foo(a), MacroLocalVariant::Foo(b)) => {
2827                assert!(
2828                    std::ptr::eq(a, b),
2829                    "macro-emitted VariantSelector::select must delegate to <Kind>::select — same borrow, not a copy",
2830                );
2831            }
2832            _ => panic!("expected Foo arm on both dispatch paths"),
2833        }
2834    }
2835
2836    /// The trait's default body sweeps `<Kind as ClosedSet>::ALL` in
2837    /// declaration order — pin the iteration order against the
2838    /// production `Kind::ALL` inherent const on every implementor so
2839    /// a regression on `DeriveClosedSet`'s ALL-projection (or a
2840    /// silent reorder of the enum's variant declarations that drifts
2841    /// only ONE of the two arrays) fails at ONE substrate boundary.
2842    #[test]
2843    fn every_production_kind_closedset_all_matches_inherent_all() {
2844        use crate::encapsulates::EncapsulationTarget;
2845        use crate::export::{ArtifactKind, ChannelKind};
2846        use crate::intent::IntentKind;
2847
2848        assert_eq!(
2849            <IntentKind as tatara_closed_set::ClosedSet>::ALL,
2850            IntentKind::ALL.as_slice(),
2851        );
2852        assert_eq!(
2853            <EncapsulationTarget as tatara_closed_set::ClosedSet>::ALL,
2854            EncapsulationTarget::ALL.as_slice(),
2855        );
2856        assert_eq!(
2857            <ArtifactKind as tatara_closed_set::ClosedSet>::ALL,
2858            ArtifactKind::ALL.as_slice(),
2859        );
2860        assert_eq!(
2861            <ChannelKind as tatara_closed_set::ClosedSet>::ALL,
2862            ChannelKind::ALL.as_slice(),
2863        );
2864    }
2865
2866    // -------------------------------------------------------------------
2867    // `VariantKind<K>` trait — reverse projection from a borrowed-variant
2868    // view back into its addressing Kind, and `assert_variant_round_trip`
2869    // as the substrate testkit primitive that composes it with
2870    // `VariantSelector::select` on the populated side. Pin the four-arm
2871    // truth table (every position round-trips through select→variant_kind
2872    // AND through variant()→variant_kind) directly on the sibling-shaped
2873    // local scaffold, so a regression on either projection or on the
2874    // resolver default body fails here — before any per-parent inherent
2875    // test surfaces the drift.
2876    // -------------------------------------------------------------------
2877
2878    /// Every populated position across [`LocalKind::ALL`] round-trips
2879    /// through both `select→variant_kind` AND `variant()→variant_kind`
2880    /// on the sibling-shaped local scaffold. Pins the substrate
2881    /// primitive's four-arm truth table at ONE boundary — a regression
2882    /// on either projection direction (or on the resolver default
2883    /// short-circuit / iteration order) fails here before any per-parent
2884    /// inherent test surfaces the drift.
2885    #[test]
2886    fn assert_variant_round_trip_accepts_coherent_local_impl() {
2887        fn make_local(k: LocalKind) -> LocalParent {
2888            match k {
2889                LocalKind::Alpha => LocalParent {
2890                    alpha: Some(11),
2891                    ..Default::default()
2892                },
2893                LocalKind::Beta => LocalParent {
2894                    beta: Some(22),
2895                    ..Default::default()
2896                },
2897                LocalKind::Gamma => LocalParent {
2898                    gamma: Some(33),
2899                    ..Default::default()
2900                },
2901            }
2902        }
2903        assert_variant_round_trip::<LocalParent, _>(make_local);
2904    }
2905
2906    /// The testkit primitive is a `#[track_caller]` compound-lift: a
2907    /// factory that fails to populate the addressed slot fails at the
2908    /// caller's site with a labeled panic message, not silently. Pin
2909    /// the failing case with a deliberately empty parent factory so a
2910    /// regression that drops the "select must return Some" check
2911    /// fails-loudly here — the missing-slot arm is the substrate
2912    /// primitive's first failure mode.
2913    #[test]
2914    #[should_panic(expected = "VariantSelector::select must return Some for populated slot")]
2915    fn assert_variant_round_trip_rejects_factory_that_leaves_slot_empty() {
2916        // Factory that returns an all-empty parent regardless of k —
2917        // every `k.select(&parent)` returns None, so the primitive
2918        // panics at the "must return Some" arm.
2919        fn empty_factory(_: LocalKind) -> LocalParent {
2920            LocalParent::default()
2921        }
2922        assert_variant_round_trip::<LocalParent, _>(empty_factory);
2923    }
2924
2925    // -------------------------------------------------------------------
2926    // `assert_two_slots_ambiguous` — the ALL×ALL ambiguity sweep as ONE
2927    // substrate primitive. Pin the truth table (every off-diagonal pair
2928    // resolves to `TaggedUnionError::ambiguous`, diagonal pairs are
2929    // skipped, a factory that yields a non-Ambiguous parent fails-loudly
2930    // at the caller's site) directly on the sibling-shaped `LocalParent`
2931    // scaffold — a regression on either the pair-iteration order or the
2932    // expected-carrier composition fails here before any per-parent test
2933    // surfaces the drift.
2934    // -------------------------------------------------------------------
2935
2936    /// Every off-diagonal pair across [`LocalKind::ALL`] × `ALL`
2937    /// resolves through the substrate primitive to
2938    /// [`LocalParentError::Ambiguous`] on the sibling-shaped local
2939    /// scaffold. Pins the primitive's Ok arm (no false positives on the
2940    /// coherent-impl side) at ONE boundary — a regression that drops
2941    /// the diagonal skip, mis-iterates `ClosedSet::ALL`, or composes a
2942    /// divergent expected carrier fails here before any per-parent
2943    /// inherent test surfaces the drift.
2944    #[test]
2945    fn assert_two_slots_ambiguous_accepts_coherent_local_impl() {
2946        fn two_local(a: LocalKind, b: LocalKind) -> LocalParent {
2947            let mut p = LocalParent::default();
2948            for k in [a, b] {
2949                match k {
2950                    LocalKind::Alpha => p.alpha = Some(11),
2951                    LocalKind::Beta => p.beta = Some(22),
2952                    LocalKind::Gamma => p.gamma = Some(33),
2953                }
2954            }
2955            p
2956        }
2957        assert_two_slots_ambiguous::<LocalParent, _>(two_local);
2958    }
2959
2960    /// A factory that yields a single-slot parent for the FIRST kind
2961    /// (ignoring the second) — every off-diagonal pair resolves to
2962    /// exactly-one Ok(Variant), NOT Ambiguous — MUST fail-loudly at
2963    /// the caller's site through the primitive's "two-slot parent
2964    /// must not resolve to a variant" arm. Pin the Ok-side failure
2965    /// mode so a regression that mis-routes the substrate primitive's
2966    /// resolved-Ok arm past the assertion (silently succeeding on a
2967    /// single-slot factory) is caught here.
2968    #[test]
2969    #[should_panic(expected = "two-slot parent must not resolve to a variant")]
2970    fn assert_two_slots_ambiguous_rejects_factory_that_populates_only_one_slot() {
2971        fn single_only(a: LocalKind, _: LocalKind) -> LocalParent {
2972            let mut p = LocalParent::default();
2973            match a {
2974                LocalKind::Alpha => p.alpha = Some(11),
2975                LocalKind::Beta => p.beta = Some(22),
2976                LocalKind::Gamma => p.gamma = Some(33),
2977            }
2978            p
2979        }
2980        assert_two_slots_ambiguous::<LocalParent, _>(single_only);
2981    }
2982
2983    /// A factory that yields an all-empty parent (so `.variant()`
2984    /// resolves to the `Empty` carrier, NOT `Ambiguous`) MUST
2985    /// fail-loudly at the caller's site through the primitive's
2986    /// `assert_eq!` arm — the composed expected carrier
2987    /// [`TaggedUnionError::ambiguous`] mismatches the resolved
2988    /// [`TaggedUnionError::empty`] carrier. Pin the Empty-arm failure
2989    /// mode so a regression that mis-projects the None arm of
2990    /// [`ResolveError`] onto Ambiguous (silently succeeding on an
2991    /// empty factory) is caught here.
2992    #[test]
2993    #[should_panic(expected = "should resolve Ambiguous")]
2994    fn assert_two_slots_ambiguous_rejects_factory_that_populates_no_slots() {
2995        fn empty_factory(_: LocalKind, _: LocalKind) -> LocalParent {
2996            LocalParent::default()
2997        }
2998        assert_two_slots_ambiguous::<LocalParent, _>(empty_factory);
2999    }
3000
3001    // -------------------------------------------------------------------
3002    // `assert_single_slot_key_matches_label` — the wire-key / kind-label
3003    // alignment sweep as ONE substrate primitive. Pin the truth table
3004    // (every populated slot serializes to exactly one JSON key whose
3005    // name equals the addressing kind's ClosedSet label; a factory that
3006    // populates the wrong slot / no slot / multiple slots fails-loudly
3007    // at the caller's site) directly on the sibling-shaped `LocalParent`
3008    // scaffold — a regression on either the exactly-one arm or the
3009    // name-equality arm fails here before any per-parent inherent test
3010    // surfaces the drift.
3011    // -------------------------------------------------------------------
3012
3013    /// Every kind across [`LocalKind::ALL`] serializes through the
3014    /// substrate primitive to a JSON object with EXACTLY ONE key whose
3015    /// name equals `<LocalKind as ClosedSet>::label` on the addressed
3016    /// kind. Pins the primitive's Ok arm (no false positives on the
3017    /// coherent-impl side) at ONE boundary — a regression that inspects
3018    /// the wrong serde value (e.g. `to_string` instead of `to_value`),
3019    /// counts fields off-by-one, or projects the wrong `ClosedSet`
3020    /// method (`labels_joined` instead of `label`) fails here before any
3021    /// per-parent inherent test surfaces the drift.
3022    #[test]
3023    fn assert_single_slot_key_matches_label_accepts_coherent_local_impl() {
3024        fn make_local(k: LocalKind) -> LocalParent {
3025            match k {
3026                LocalKind::Alpha => LocalParent {
3027                    alpha: Some(11),
3028                    ..Default::default()
3029                },
3030                LocalKind::Beta => LocalParent {
3031                    beta: Some(22),
3032                    ..Default::default()
3033                },
3034                LocalKind::Gamma => LocalParent {
3035                    gamma: Some(33),
3036                    ..Default::default()
3037                },
3038            }
3039        }
3040        assert_single_slot_key_matches_label::<LocalParent, _>(make_local);
3041    }
3042
3043    /// A factory that returns a single-slot parent for the WRONG kind
3044    /// (populates `beta` regardless of what kind is asked for) MUST
3045    /// fail-loudly at the caller's site through the primitive's
3046    /// name-equality arm — the emitted key does not match the addressed
3047    /// kind's label. Pins the drift-detection failure mode so a
3048    /// regression that drops the `assert_eq!(keys[0], label)` arm
3049    /// (silently succeeding on any-key-at-all) is caught here. The
3050    /// caller's site is the `#[should_panic]` boundary through the
3051    /// primitive's `#[track_caller]` compound-lift.
3052    #[test]
3053    #[should_panic(expected = "wire-key drift")]
3054    fn assert_single_slot_key_matches_label_rejects_factory_that_populates_wrong_slot() {
3055        fn always_beta(_: LocalKind) -> LocalParent {
3056            LocalParent {
3057                beta: Some(22),
3058                ..Default::default()
3059            }
3060        }
3061        assert_single_slot_key_matches_label::<LocalParent, _>(always_beta);
3062    }
3063
3064    /// A factory that returns an all-empty parent (so serializing
3065    /// yields ZERO keys, not exactly-one) MUST fail-loudly at the
3066    /// caller's site through the primitive's exactly-one arm. Pins the
3067    /// zero-key failure mode so a regression that projects
3068    /// `obj.keys().count() >= 1` (rather than `== 1`) is caught here.
3069    #[test]
3070    #[should_panic(expected = "exactly one populated field")]
3071    fn assert_single_slot_key_matches_label_rejects_factory_that_populates_no_slots() {
3072        fn empty_factory(_: LocalKind) -> LocalParent {
3073            LocalParent::default()
3074        }
3075        assert_single_slot_key_matches_label::<LocalParent, _>(empty_factory);
3076    }
3077
3078    /// A factory that returns a parent with TWO populated slots (so
3079    /// serializing yields two keys, not exactly-one) MUST fail-loudly
3080    /// at the caller's site through the primitive's exactly-one arm.
3081    /// Pins the many-keys failure mode so a regression that projects
3082    /// `obj.keys().count() <= 1` (rather than `== 1`) is caught here.
3083    /// Cross-pins the substrate promise that a single-slot factory
3084    /// truly populates ONE slot — a future factory bug that leaks
3085    /// residual populated slots between calls (e.g. via shared mutable
3086    /// state) is caught HERE at the primitive boundary.
3087    #[test]
3088    #[should_panic(expected = "exactly one populated field")]
3089    fn assert_single_slot_key_matches_label_rejects_factory_that_populates_two_slots() {
3090        fn two_slot_factory(_: LocalKind) -> LocalParent {
3091            LocalParent {
3092                alpha: Some(1),
3093                beta: Some(2),
3094                gamma: None,
3095            }
3096        }
3097        assert_single_slot_key_matches_label::<LocalParent, _>(two_slot_factory);
3098    }
3099
3100    /// The macro-emitted [`MacroLocalParent`] scaffold impls
3101    /// [`TaggedUnion`] through the [`declare_tagged_union_impls!`]
3102    /// three-block macro AND additionally derives `serde::Serialize` +
3103    /// `#[serde(skip_serializing_if = "Option::is_none")]` on every
3104    /// slot — so the wire-key primitive dispatches on the MACRO-emitted
3105    /// impl path byte-identically with the hand-rolled [`LocalParent`]
3106    /// path above. Pins the substrate-wide guarantee that a fifth
3107    /// sibling landing through the macro picks up the wire-alignment
3108    /// check for free, without a hand-rolled `TaggedUnion` block, so
3109    /// long as its serde derives match the substrate-wide
3110    /// `skip_serializing_if = "Option::is_none"` shape every production
3111    /// site already carries. A regression that mis-routes the
3112    /// primitive's serialize call through the WRONG entry point (e.g.
3113    /// calling a bespoke `to_json` that bypasses serde) is caught here.
3114    #[test]
3115    fn assert_single_slot_key_matches_label_accepts_macro_emitted_impl() {
3116        fn make_macro_local(k: MacroLocalKind) -> MacroLocalParent {
3117            match k {
3118                MacroLocalKind::Foo => MacroLocalParent {
3119                    foo: Some(7),
3120                    bar: None,
3121                },
3122                MacroLocalKind::Bar => MacroLocalParent {
3123                    foo: None,
3124                    bar: Some(8),
3125                },
3126            }
3127        }
3128        assert_single_slot_key_matches_label::<MacroLocalParent, _>(make_macro_local);
3129    }
3130
3131    // -------------------------------------------------------------------
3132    // `assert_wire_key_matches_label` — bound-relaxed peer of the
3133    // `assert_single_slot_key_matches_label` primitive. Pin the truth
3134    // table (every populated slot serializes to exactly one JSON key
3135    // whose name equals the addressing kind's ClosedSet label; a
3136    // factory that populates the wrong slot / no slot / multiple slots
3137    // fails-loudly at the caller's site) on a NON-TaggedUnion parent
3138    // scaffold — the delegation-only path from the trait-projected
3139    // primitive would silently pass this test if the bound-relaxed
3140    // primitive's body regressed, so the direct-dispatch probes here
3141    // pin the bound-relaxed pathway independently.
3142    // -------------------------------------------------------------------
3143
3144    /// Local parent that carries the wire-format shape (`Option<T>`
3145    /// slots + `#[serde(skip_serializing_if = "Option::is_none")]`
3146    /// annotations) but DELIBERATELY does NOT impl [`TaggedUnion`] —
3147    /// pins the bound-relaxed sweep on the exact shape [`crate::lifetime::Lifetime`]
3148    /// carries in production (empty resolves to a default variant,
3149    /// not to a typed error, so the trait's `T::Error` bound doesn't
3150    /// hold and the trait-projected surface excludes it).
3151    #[derive(Default, serde::Serialize)]
3152    struct BareParent {
3153        #[serde(skip_serializing_if = "Option::is_none")]
3154        alpha: Option<u32>,
3155        #[serde(skip_serializing_if = "Option::is_none")]
3156        beta: Option<u32>,
3157        #[serde(skip_serializing_if = "Option::is_none")]
3158        gamma: Option<u32>,
3159    }
3160
3161    /// The bound-relaxed primitive dispatches Ok on a coherent
3162    /// non-TaggedUnion impl — pin the happy path directly on the
3163    /// [`BareParent`] scaffold so a regression that gates the sweep
3164    /// body on the `T: TaggedUnion` bound (accidentally re-adding it,
3165    /// or projecting through `T::Kind` instead of the caller-supplied
3166    /// `K` generic) fails HERE at the primitive-independent boundary
3167    /// rather than at the [`crate::lifetime::Lifetime`] production
3168    /// site alone. The Ok arm is the "no drift" outcome; a divergence
3169    /// surfaces as a labeled assertion failure at the caller site
3170    /// (this test's own line) via the primitive's `#[track_caller]`.
3171    #[test]
3172    fn assert_wire_key_matches_label_accepts_coherent_bare_parent_impl() {
3173        fn make_bare(k: LocalKind) -> BareParent {
3174            match k {
3175                LocalKind::Alpha => BareParent {
3176                    alpha: Some(11),
3177                    ..Default::default()
3178                },
3179                LocalKind::Beta => BareParent {
3180                    beta: Some(22),
3181                    ..Default::default()
3182                },
3183                LocalKind::Gamma => BareParent {
3184                    gamma: Some(33),
3185                    ..Default::default()
3186                },
3187            }
3188        }
3189        assert_wire_key_matches_label::<BareParent, LocalKind, _>(make_bare);
3190    }
3191
3192    /// A factory that returns a bare-parent for the WRONG kind
3193    /// (populates `beta` regardless of what kind is asked for) MUST
3194    /// fail-loudly at the caller's site through the bound-relaxed
3195    /// primitive's name-equality arm — the emitted key does not match
3196    /// the addressed kind's label. Pins the drift-detection failure
3197    /// mode on the non-TaggedUnion pathway so a regression that drops
3198    /// the `assert_eq!(keys[0], label)` arm (silently succeeding on
3199    /// any-key-at-all) is caught here — mechanical peer of the
3200    /// sibling `assert_single_slot_key_matches_label_rejects_factory_that_populates_wrong_slot`
3201    /// on the TaggedUnion pathway.
3202    #[test]
3203    #[should_panic(expected = "wire-key drift")]
3204    fn assert_wire_key_matches_label_rejects_factory_that_populates_wrong_slot() {
3205        fn always_beta(_: LocalKind) -> BareParent {
3206            BareParent {
3207                beta: Some(22),
3208                ..Default::default()
3209            }
3210        }
3211        assert_wire_key_matches_label::<BareParent, LocalKind, _>(always_beta);
3212    }
3213
3214    /// A factory that returns an all-empty bare-parent (so serializing
3215    /// yields ZERO keys, not exactly-one) MUST fail-loudly at the
3216    /// caller's site through the bound-relaxed primitive's
3217    /// exactly-one arm. Pins the zero-key failure mode on the
3218    /// non-TaggedUnion pathway.
3219    #[test]
3220    #[should_panic(expected = "exactly one populated field")]
3221    fn assert_wire_key_matches_label_rejects_factory_that_populates_no_slots() {
3222        fn empty_factory(_: LocalKind) -> BareParent {
3223            BareParent::default()
3224        }
3225        assert_wire_key_matches_label::<BareParent, LocalKind, _>(empty_factory);
3226    }
3227
3228    /// The trait-projected [`assert_single_slot_key_matches_label`]
3229    /// is a one-line delegation to the bound-relaxed
3230    /// [`assert_wire_key_matches_label`] peer — pin the delegation
3231    /// shape at ONE boundary so a regression that inlines a
3232    /// divergent sweep body into the trait-projected surface (rather
3233    /// than the one-line dispatch) is caught here. Ok on a coherent
3234    /// impl means BOTH primitives dispatch through the SAME body on
3235    /// the same fixture — [`LocalParent`] impls [`TaggedUnion`], so
3236    /// both the trait-projected surface and the bound-relaxed peer
3237    /// reach it, and a divergence between the two dispatches would
3238    /// surface here as one succeeding + the other failing.
3239    #[test]
3240    fn assert_single_slot_key_matches_label_delegates_to_wire_key_matches_label() {
3241        fn make_local(k: LocalKind) -> LocalParent {
3242            match k {
3243                LocalKind::Alpha => LocalParent {
3244                    alpha: Some(11),
3245                    ..Default::default()
3246                },
3247                LocalKind::Beta => LocalParent {
3248                    beta: Some(22),
3249                    ..Default::default()
3250                },
3251                LocalKind::Gamma => LocalParent {
3252                    gamma: Some(33),
3253                    ..Default::default()
3254                },
3255            }
3256        }
3257        // Both surfaces reach the same body — dispatched here through
3258        // BOTH entry points so a divergence between them fails one
3259        // arm while the other passes.
3260        assert_single_slot_key_matches_label::<LocalParent, _>(make_local);
3261        assert_wire_key_matches_label::<LocalParent, LocalKind, _>(make_local);
3262    }
3263
3264    /// Every one of the five production borrowed-view enums impls
3265    /// [`VariantKind`] byte-identically with its inherent `.kind()`
3266    /// (or `.target()` on `EncapsulationKindVariant`) — pin the
3267    /// delegation shape at ONE substrate boundary so a regression that
3268    /// inlines a divergent match body into the trait impl (rather than
3269    /// the one-line delegation) is caught here. `Lifetime`'s
3270    /// borrowed-view is included even though `Lifetime` isn't a
3271    /// [`TaggedUnion`] impl — the reverse projection applies uniformly.
3272    #[test]
3273    fn every_production_variant_kind_impl_matches_inherent_projection() {
3274        use crate::encapsulates::{EncapsulationKindVariant, ExistingHelmRelease};
3275        use crate::export::{ArtifactVariant, ChannelVariant, HttpEventChannel, ReceiptsSource};
3276        use crate::intent::{IntentVariant, NixIntent};
3277        use crate::lifetime::{LifetimeVariant, PermanentLifetime};
3278
3279        let nix = NixIntent {
3280            flake_ref: "github:a/b".into(),
3281            attribute: "x".into(),
3282            system: None,
3283            attic_cache: None,
3284            extra_args: vec![],
3285            delegate_to_nix_build: false,
3286        };
3287        let iv = IntentVariant::Nix(&nix);
3288        assert_eq!(iv.kind(), iv.variant_kind());
3289
3290        let perm = PermanentLifetime::default();
3291        let lv = LifetimeVariant::Permanent(&perm);
3292        assert_eq!(lv.kind(), lv.variant_kind());
3293
3294        let hr = ExistingHelmRelease {
3295            namespace: "ns".into(),
3296            name: "n".into(),
3297            release_name: "r".into(),
3298        };
3299        let ev = EncapsulationKindVariant::ExistingHelmRelease(&hr);
3300        assert_eq!(ev.target(), ev.variant_kind());
3301
3302        let rs = ReceiptsSource {};
3303        let av = ArtifactVariant::Receipts(&rs);
3304        assert_eq!(av.kind(), av.variant_kind());
3305
3306        let ch = HttpEventChannel {
3307            endpoint: None,
3308            signal_type: "s".into(),
3309        };
3310        let cv = ChannelVariant::HttpEvent(&ch);
3311        assert_eq!(cv.kind(), cv.variant_kind());
3312    }
3313}