Skip to main content

tatara_process/
classification.rs

1//! The six classification dimensions — CRD-facing with `JsonSchema`,
2//! `From`/`Into` bridges to `tatara_core::domain::classification`.
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7use tatara_core::domain::classification as core;
8use tatara_core::domain::compliance_binding as core_compl;
9
10/// Lattice position of a Process — six orthogonal axes.
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
12#[serde(rename_all = "camelCase")]
13pub struct Classification {
14    pub point_type: ConvergencePointType,
15    pub substrate: SubstrateType,
16    #[serde(default)]
17    pub horizon: Horizon,
18    #[serde(default)]
19    pub calm: CalmClassification,
20    #[serde(default)]
21    pub data_classification: DataClassification,
22}
23
24impl Classification {
25    /// The workspace-baseline classification — a [`ConvergencePointType::Gate`]
26    /// point on the [`SubstrateType::Compute`] substrate with every other axis
27    /// at its [`Default`]. The `(Gate, Compute)` pair names an unremarkable
28    /// barrier point in the Compute plane: no domain-specific structural
29    /// claim (no fan-out / fan-in / broadcast / observation semantics beyond
30    /// the barrier gate) and no domain-specific substrate claim (no
31    /// `Financial` / `Network` / `Storage` / `Security` / `Identity` /
32    /// `Observability` / `Regulatory` plane bringing in its own compliance
33    /// baselines). The three defaulted axes ride at the intentional
34    /// workspace baseline the sibling closed-set primitives already own:
35    /// [`Horizon`] at [`HorizonKind::Bounded`] (terminates naturally, no
36    /// asymptotic metric axes required), [`CalmClassification::Monotone`]
37    /// (no coordination required per CALM), and
38    /// [`DataClassification::Internal`] (access-controlled but not
39    /// externally regulated).
40    ///
41    /// Pre-lift the six-line `Classification { point_type: Gate, substrate:
42    /// Compute, horizon: Default::default(), calm: Default::default(),
43    /// data_classification: Default::default() }` struct-literal recurred
44    /// at TEN sites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold
45    /// — one production consumer plus nine test-fixture callsites spread
46    /// across four crates, each restating the SAME `(Gate, Compute)`
47    /// baseline verbatim:
48    /// * `crate::ephemeral::default_ephemeral_class` — the substitute
49    ///   [`EphemeralSpec::into::<crate::crd::ProcessSpec>`] fills into
50    ///   [`crate::crd::ProcessSpec::classification`] when the operator
51    ///   omits an explicit `:classification` slot on `(defephemeral …)`.
52    ///   The one PRODUCTION consumer of the shape — a regression that
53    ///   drifted its point-type or substrate axis silently retargets every
54    ///   unadorned ephemeral to a different plane.
55    /// * `crate::crd`'s + `crate::lib`'s + `crate::lifetime_clock`'s +
56    ///   `tatara_reconciler::{claim,render}`'s + `tatara_pool_reconciler::
57    ///   controller_pool`'s `empty_spec` / `empty_process_spec` /
58    ///   `ephemeral_process` / `permanent_process` test-fixture helpers +
59    ///   inline `ProcessSpec` literals — nine test-fixture callsites
60    ///   restating the SAME six-line struct-literal at the same shape.
61    ///
62    /// Post-lift every callsite reads `Classification::gate_compute()`;
63    /// a future workspace-wide baseline shift (a new [`Horizon`] default,
64    /// a promotion of `Compute` to a compound baseline that pre-fills a
65    /// canonical [`CalmClassification`], a per-baseline compliance overlay
66    /// stamping through the classification, or a rename of either axis
67    /// enum) lands at ONE substrate function here and every downstream
68    /// consumer inherits the upgrade mechanically. The current pin ties
69    /// the three defaulted axes to the sibling closed-set defaults
70    /// ([`HorizonKind::Bounded`], [`CalmClassification::Monotone`],
71    /// [`DataClassification::Internal`]) so a future change to any sibling
72    /// default surfaces at this primitive's tests rather than as silent
73    /// drift across ten independent callsites.
74    ///
75    /// Sibling to the `_or_default` / `_or_placeholder` primitive family on
76    /// [`crate::prelude::Process`] on the (return-form × axis) axis — those
77    /// primitives own the borrow-form projections off a live `Process`;
78    /// this one owns the construction shape for a fresh
79    /// [`crate::crd::ProcessSpec`] whose classification axis is
80    /// unremarkable. A future peer `Classification::observe_observability()`
81    /// or similar named variant lands as a sibling method here when a
82    /// second unremarkable-baseline shape opens.
83    ///
84    /// Theory anchor: THEORY.md §VI.1 (generation over composition — the
85    /// six-line struct-literal shape recurred at TEN hand-authored sites
86    /// past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger and is lifted
87    /// onto ONE workspace-wide owner here). THEORY.md §II.1 invariant 5
88    /// (composition preserves proofs — a regression that drifted the
89    /// baseline axis choice at only one consumer, or that broke the
90    /// sibling-default correspondence, surfaces at this primitive's tests
91    /// rather than as silent operator-visible skew between the ephemeral
92    /// sugar substitute and the ten downstream test-fixtures whose
93    /// assertions depend on the shape).
94    #[must_use]
95    pub fn gate_compute() -> Self {
96        Self {
97            point_type: ConvergencePointType::Gate,
98            substrate: SubstrateType::Compute,
99            horizon: Horizon::default(),
100            calm: CalmClassification::default(),
101            data_classification: DataClassification::default(),
102        }
103    }
104
105    /// Closed-set-driven presence probe — does this [`Classification`]
106    /// carry the given [`ConvergencePointType`] discriminator on its
107    /// [`Self::point_type`] slot? The ONE substrate primitive that owns
108    /// the `(Classification, ConvergencePointType) -> bool`
109    /// scalar-carrier walk shape.
110    ///
111    /// # Third scalar-carrier peer on the presence-probe axis
112    ///
113    /// Peer of [`crate::spec::SignalPolicy::has_sighup_strategy`] and
114    /// [`crate::encapsulates::EncapsulatesSpec::has_mode`] — all three
115    /// probe a scalar closed-set-discriminator field on an inner
116    /// [`crate::crd::ProcessSpec`] struct via a one-line
117    /// `self.<field> == kind` body. Together they compose the
118    /// SCALAR-CARRIER stratum of the workspace-wide closed-set-driven
119    /// presence-probe algebra (the workspace-wide algebra spans three
120    /// underlying representation kinds — Option-slot, slice, scalar —
121    /// see the [`crate::spec::SignalPolicy::has_sighup_strategy`]
122    /// docstring for the full-shape rundown; this method is the third
123    /// scalar-carrier instance).
124    ///
125    /// # Semantics — VARIANT match, not POPULATED slot
126    ///
127    /// `has_point_type(kind)` returns `true` iff `self.point_type ==
128    /// kind`. Distinct from BOTH prior scalar-carrier peers on the
129    /// (parent-shape × child-shape) axis:
130    ///
131    /// * [`crate::spec::SignalPolicy::has_sighup_strategy`] lives on a
132    ///   non-Option, DEFAULTED parent (`SignalPolicy: Default`) with a
133    ///   defaulted scalar child (`SighupStrategy: Default =
134    ///   Reconverge`) — a default carrier reads `true` for the default
135    ///   variant only.
136    /// * [`crate::encapsulates::EncapsulatesSpec::has_mode`] lives on
137    ///   an OPTION parent (`spec.encapsulates:
138    ///   Option<EncapsulatesSpec>`) with a defaulted scalar child
139    ///   (`EncapsulationMode: Default = Manage`) — a bare `None`
140    ///   parent reads `false` for every variant.
141    /// * `has_point_type` lives on a REQUIRED, non-Option, NON-DEFAULT
142    ///   parent ([`Classification`] has no `impl Default`) with a
143    ///   NON-DEFAULT scalar child ([`ConvergencePointType`] has no
144    ///   `impl Default`) — every well-formed [`crate::crd::ProcessSpec`]
145    ///   carries a `Classification` whose `point_type` slot is
146    ///   deliberately chosen by the operator, so the probe returns
147    ///   `true` on exactly ONE variant per spec and `false` on the
148    ///   other seven, with no default-arm short-circuit shortcut.
149    ///
150    /// This closes the (required-parent × required-scalar-child) corner
151    /// of the workspace-wide closed-set-driven presence-probe algebra
152    /// at its first substrate primitive.
153    ///
154    /// # Compounding
155    ///
156    /// A future closed-set-discriminator scalar field on
157    /// [`Classification`] (a peer `has_substrate`, `has_calm`,
158    /// `has_data_classification` — the four remaining
159    /// classification-axis closed sets) lands as ONE peer inherent
160    /// method with the same one-line `self.<field> == kind` body and
161    /// routes through the same `strip_and_classify_prefixed_kind::<K,
162    /// _>` shape in `tatara-check`. A future
163    /// [`ConvergencePointType`] variant (a hypothetical `Demux` /
164    /// `Mux` / `Pipeline` for finer topology carving) reaches every
165    /// downstream through ONE `ALL` entry on the closed set with the
166    /// probe body untouched.
167    ///
168    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition preserves
169    /// proofs; the scalar-carrier presence-probe body lives at ONE
170    /// substrate site so every downstream (`point-type-<kind>`
171    /// require-tag family in `tatara-check`, closed-set audit
172    /// dispatchers, future variant additions on
173    /// [`ConvergencePointType`]) binds through the SAME shape rather
174    /// than restating the `classification.point_type == kind` closure
175    /// body at each callsite. THEORY.md §VI.1 — generation over
176    /// composition; a future [`ConvergencePointType`] variant lands at
177    /// ONE `ALL` entry + ONE `as_str` arm on the closed set and the
178    /// probe picks it up mechanically without further per-consumer
179    /// edits.
180    #[must_use]
181    pub fn has_point_type(&self, kind: ConvergencePointType) -> bool {
182        self.point_type == kind
183    }
184
185    /// Closed-set-driven presence probe — does this [`Classification`]
186    /// carry the given [`SubstrateType`] discriminator on its
187    /// [`Self::substrate`] slot? The ONE substrate primitive that
188    /// owns the `(Classification, SubstrateType) -> bool`
189    /// scalar-carrier walk shape.
190    ///
191    /// # Fourth scalar-carrier peer on the presence-probe axis
192    ///
193    /// Peer of [`crate::spec::SignalPolicy::has_sighup_strategy`],
194    /// [`crate::encapsulates::EncapsulatesSpec::has_mode`], and
195    /// [`Self::has_point_type`] — all four probe a scalar closed-set-
196    /// discriminator field on an inner [`crate::crd::ProcessSpec`]
197    /// struct via a one-line `self.<field> == kind` body. Together
198    /// they compose the SCALAR-CARRIER stratum of the workspace-wide
199    /// closed-set-driven presence-probe algebra (the workspace-wide
200    /// algebra spans three underlying representation kinds — Option-
201    /// slot, slice, scalar — see the
202    /// [`crate::spec::SignalPolicy::has_sighup_strategy`] docstring
203    /// for the full-shape rundown; this method is the fourth scalar-
204    /// carrier instance).
205    ///
206    /// # Semantics — VARIANT match, not POPULATED slot
207    ///
208    /// `has_substrate(kind)` returns `true` iff `self.substrate ==
209    /// kind`. FIRST co-tenant on the (required-parent × required-
210    /// scalar-child) corner of the algebra with [`Self::has_point_type`]
211    /// — both probe REQUIRED, non-Option, NON-DEFAULT slots on the
212    /// same [`Classification`] parent whose two required axes carry
213    /// no [`Default`] impl, so exactly ONE of the eight [`SubstrateType`]
214    /// variants and exactly ONE of the eight [`ConvergencePointType`]
215    /// variants answer `true` per well-formed [`crate::crd::ProcessSpec`],
216    /// with no default-arm short-circuit shortcut. Distinct from the
217    /// two prior scalar-carrier peers on the (parent-shape × child-
218    /// shape) axis: `has_sighup_strategy` lives on a non-Option,
219    /// DEFAULTED parent ([`crate::spec::SignalPolicy`] carries
220    /// `#[derive(Default)]`) with a defaulted scalar child
221    /// ([`crate::signal::SighupStrategy`] defaults to
222    /// [`crate::signal::SighupStrategy::Reconverge`]); `has_mode`
223    /// lives on an OPTION parent (`spec.encapsulates:
224    /// Option<EncapsulatesSpec>`) with a defaulted scalar child
225    /// ([`crate::encapsulates::EncapsulationMode`] defaults to
226    /// [`crate::encapsulates::EncapsulationMode::Manage`]).
227    ///
228    /// This POPULATES the (required-parent × required-scalar-child)
229    /// corner of the workspace-wide closed-set-driven presence-probe
230    /// algebra at its SECOND substrate primitive after
231    /// [`Self::has_point_type`] opened the corner, pinning the corner
232    /// as a proven-repeatable primitive shape rather than a single-
233    /// example curiosity.
234    ///
235    /// # Compounding
236    ///
237    /// A future closed-set-discriminator scalar field on
238    /// [`Classification`] (a peer `has_calm` on [`CalmClassification`],
239    /// `has_data_classification` on [`DataClassification`] — the two
240    /// remaining defaulted-scalar-child classification-axis closed
241    /// sets) lands as ONE peer inherent method with the same one-line
242    /// `self.<field> == kind` body and routes through the same
243    /// `strip_and_classify_prefixed_kind::<K, _>` shape in
244    /// `tatara-check`. A future [`SubstrateType`] variant (a
245    /// hypothetical `Consensus` for governance substrates, `Physical`
246    /// for hardware substrates, `Cache` for ephemeral memoization
247    /// substrates) reaches every downstream through ONE `ALL` entry
248    /// on the closed set with the probe body untouched.
249    ///
250    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition preserves
251    /// proofs; the scalar-carrier presence-probe body lives at ONE
252    /// substrate site so every downstream (`substrate-<kind>`
253    /// require-tag family in `tatara-check`, closed-set audit
254    /// dispatchers, future variant additions on [`SubstrateType`])
255    /// binds through the SAME shape rather than restating the
256    /// `classification.substrate == kind` closure body at each
257    /// callsite. THEORY.md §VI.1 — generation over composition; a
258    /// future [`SubstrateType`] variant lands at ONE `ALL` entry +
259    /// ONE `as_str` arm on the closed set and the probe picks it up
260    /// mechanically without further per-consumer edits.
261    #[must_use]
262    pub fn has_substrate(&self, kind: SubstrateType) -> bool {
263        self.substrate == kind
264    }
265
266    /// Closed-set-driven presence probe — does this [`Classification`]
267    /// carry the given [`CalmClassification`] discriminator on its
268    /// [`Self::calm`] slot? The ONE substrate primitive that owns the
269    /// `(Classification, CalmClassification) -> bool` scalar-carrier
270    /// walk shape.
271    ///
272    /// # Fifth scalar-carrier peer on the presence-probe axis
273    ///
274    /// Peer of [`crate::spec::SignalPolicy::has_sighup_strategy`],
275    /// [`crate::encapsulates::EncapsulatesSpec::has_mode`],
276    /// [`Self::has_point_type`], and [`Self::has_substrate`] — all
277    /// five probe a scalar closed-set-discriminator field on an inner
278    /// [`crate::crd::ProcessSpec`] struct via a one-line
279    /// `self.<field> == kind` body. Together they compose the
280    /// SCALAR-CARRIER stratum of the workspace-wide closed-set-driven
281    /// presence-probe algebra (the workspace-wide algebra spans three
282    /// underlying representation kinds — Option-slot, slice, scalar
283    /// — see the [`crate::spec::SignalPolicy::has_sighup_strategy`]
284    /// docstring for the full-shape rundown; this method is the
285    /// fifth scalar-carrier instance).
286    ///
287    /// # Semantics — VARIANT match, not POPULATED slot
288    ///
289    /// `has_calm(kind)` returns `true` iff `self.calm == kind`. FIRST
290    /// occupant on a FRESH corner of the (parent-shape × child-shape)
291    /// axis: a REQUIRED, non-Option, NON-DEFAULT parent
292    /// ([`Classification`] has no `impl Default` because its two
293    /// required axes `point_type`/`substrate` carry no default)
294    /// combined with a DEFAULTED scalar child
295    /// ([`CalmClassification`] defaults to
296    /// [`CalmClassification::Monotone`] via `#[default]`). Distinct
297    /// from every prior scalar-carrier peer on the (parent-shape ×
298    /// child-shape) axis:
299    ///
300    /// * [`crate::spec::SignalPolicy::has_sighup_strategy`] lives on
301    ///   a non-Option, DEFAULTED parent
302    ///   ([`crate::spec::SignalPolicy`] carries `#[derive(Default)]`)
303    ///   with a defaulted scalar child
304    ///   ([`crate::signal::SighupStrategy`] defaults to
305    ///   [`crate::signal::SighupStrategy::Reconverge`]) — a bare
306    ///   `SignalPolicy` reads `true` on the default variant only.
307    /// * [`crate::encapsulates::EncapsulatesSpec::has_mode`] lives on
308    ///   an OPTION parent (`spec.encapsulates:
309    ///   Option<EncapsulatesSpec>`) with a defaulted scalar child
310    ///   ([`crate::encapsulates::EncapsulationMode`] defaults to
311    ///   [`crate::encapsulates::EncapsulationMode::Manage`]) — a
312    ///   bare `None` parent reads `false` for every variant.
313    /// * [`Self::has_point_type`] + [`Self::has_substrate`] both live
314    ///   on the REQUIRED, non-Option, NON-DEFAULT [`Classification`]
315    ///   parent with a NON-DEFAULT scalar child — every well-formed
316    ///   [`crate::crd::ProcessSpec`] carries a `Classification` whose
317    ///   corresponding slot was deliberately chosen by the operator,
318    ///   so exactly ONE of the eight variants answers `true` per
319    ///   spec.
320    /// * `has_calm` lives on the REQUIRED, non-Option, NON-DEFAULT
321    ///   [`Classification`] parent with a DEFAULTED scalar child
322    ///   ([`CalmClassification::Monotone`] is the [`Default`] via
323    ///   `#[default]`) — a bare `Classification` filled via
324    ///   `..Default::default()` on the defaulted axes reads `true`
325    ///   for the default variant ([`CalmClassification::Monotone`])
326    ///   and `false` for every other. Exactly ONE of the two variants
327    ///   answers `true` per spec, and the default-arm short-circuit
328    ///   is present (the operator can DECLINE to name the CALM axis
329    ///   and the spec still answers `true` on the default variant).
330    ///
331    /// This OPENS the (required-parent × defaulted-scalar-child)
332    /// corner of the workspace-wide closed-set-driven presence-probe
333    /// algebra at its first substrate primitive — a corner distinct
334    /// from all four prior scalar-carrier peers (which sit on the
335    /// three prior corners: defaulted-parent × defaulted-child,
336    /// Option-parent × defaulted-child, required-parent ×
337    /// required-child).
338    ///
339    /// # Compounding
340    ///
341    /// A future closed-set-discriminator scalar field on
342    /// [`Classification`] whose child carries `#[derive(Default)]`
343    /// (a peer `has_data_classification` on [`DataClassification`],
344    /// whose default is [`DataClassification::Internal`] via
345    /// `#[default]` — the remaining classification-axis closed set
346    /// on a defaulted-scalar-child slot) lands as ONE peer inherent
347    /// method with the same one-line `self.<field> == kind` body and
348    /// routes through the same `strip_and_classify_prefixed_kind::<K,
349    /// _>` shape in `tatara-check`. A future [`CalmClassification`]
350    /// variant (a hypothetical `ConditionallyMonotone` for ops that
351    /// are monotone under a witness, like CRDT joins under a fixed
352    /// schema) reaches every downstream through ONE `ALL` entry on
353    /// the closed set with the probe body untouched.
354    ///
355    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
356    /// preserves proofs; the scalar-carrier presence-probe body
357    /// lives at ONE substrate site so every downstream
358    /// (`calm-<kind>` require-tag family in `tatara-check`,
359    /// closed-set audit dispatchers, future variant additions on
360    /// [`CalmClassification`]) binds through the SAME shape rather
361    /// than restating the `classification.calm == kind` closure body
362    /// at each callsite. THEORY.md §VI.1 — generation over
363    /// composition; a future [`CalmClassification`] variant lands at
364    /// ONE `ALL` entry + ONE `as_str` arm on the closed set and the
365    /// probe picks it up mechanically without further per-consumer
366    /// edits.
367    #[must_use]
368    pub fn has_calm(&self, kind: CalmClassification) -> bool {
369        self.calm == kind
370    }
371
372    /// Closed-set-driven presence probe — does this [`Classification`]
373    /// carry the given [`DataClassification`] discriminator on its
374    /// [`Self::data_classification`] slot? The ONE substrate primitive
375    /// that owns the `(Classification, DataClassification) -> bool`
376    /// scalar-carrier walk shape.
377    ///
378    /// # Sixth scalar-carrier peer on the presence-probe axis
379    ///
380    /// Peer of [`crate::spec::SignalPolicy::has_sighup_strategy`],
381    /// [`crate::encapsulates::EncapsulatesSpec::has_mode`],
382    /// [`Self::has_point_type`], [`Self::has_substrate`], and
383    /// [`Self::has_calm`] — all six probe a scalar closed-set-
384    /// discriminator field on an inner [`crate::crd::ProcessSpec`]
385    /// struct via a one-line `self.<field> == kind` body. Together
386    /// they compose the SCALAR-CARRIER stratum of the workspace-wide
387    /// closed-set-driven presence-probe algebra (the workspace-wide
388    /// algebra spans three underlying representation kinds — Option-
389    /// slot, slice, scalar — see the
390    /// [`crate::spec::SignalPolicy::has_sighup_strategy`] docstring
391    /// for the full-shape rundown; this method is the sixth scalar-
392    /// carrier instance).
393    ///
394    /// # Semantics — VARIANT match, not POPULATED slot
395    ///
396    /// `has_data_classification(kind)` returns `true` iff
397    /// `self.data_classification == kind`. SECOND co-tenant on the
398    /// (required-parent × defaulted-scalar-child) corner of the
399    /// algebra alongside [`Self::has_calm`] — both probe REQUIRED,
400    /// non-Option, NON-DEFAULT [`Classification`] parent slots with
401    /// a DEFAULTED scalar child ([`DataClassification`] defaults to
402    /// [`DataClassification::Internal`] via `#[default]`, sibling to
403    /// [`CalmClassification::Monotone`]'s `#[default]`), so exactly
404    /// ONE of the six [`DataClassification`] variants answers `true`
405    /// per spec AND the default-arm short-circuit is present (a
406    /// `Classification` filled via `..Default::default()` on the
407    /// `data_classification` axis reads `true` on the default
408    /// variant [`DataClassification::Internal`] and `false` on every
409    /// other).
410    ///
411    /// This POPULATES the (required-parent × defaulted-scalar-child)
412    /// corner of the workspace-wide closed-set-driven presence-probe
413    /// algebra at its SECOND substrate primitive after
414    /// [`Self::has_calm`] opened the corner, pinning the corner as a
415    /// proven-repeatable primitive shape rather than a single-example
416    /// curiosity. The corner-property contract ("bare
417    /// [`Classification`] reads `true` on the default variant")
418    /// now walks TWO independent defaulted-scalar-child slots on the
419    /// SAME [`Classification`] parent — a regression that promoted
420    /// a different [`DataClassification`] variant to `#[default]`
421    /// (or wired the arm to a fixed variant answer) fails HERE at
422    /// ONE narrow substrate site before drifting through every
423    /// unadorned Process's baseline data-classification answer.
424    ///
425    /// # Compounding
426    ///
427    /// This method exhausts the four scalar closed-set-discriminator
428    /// axes on [`Classification`] ([`Self::has_point_type`],
429    /// [`Self::has_substrate`], [`Self::has_calm`], and
430    /// [`Self::has_data_classification`]) — the six-axis classification
431    /// lattice publishes ALL FOUR of its scalar-carrier presence
432    /// probes at ONE substrate site each. The remaining two axes
433    /// (`horizon` — a nested struct threading [`HorizonKind`] through
434    /// `horizon.kind`; the sixth axis is variant-dependent on the
435    /// [`HorizonKind::Asymptotic`] arm) live on nested-struct-scalar
436    /// slots rather than the direct-scalar corner the four current
437    /// peers span — the [`Self::has_horizon_kind`] peer opens that
438    /// fresh (required-parent × nested-struct-scalar-child) corner
439    /// with the same `has(kind)` shape composed through one struct
440    /// hop. A future [`DataClassification`] variant (a
441    /// hypothetical seventh variant beyond `Public / Internal /
442    /// Confidential / Pii / Phi / Pci` — say a `TradeSecret` bucket
443    /// for competitive-sensitive data, or an `Anonymized` bucket for
444    /// pseudonymized-PII whose regulatory posture differs) reaches
445    /// every downstream through ONE `ALL` entry on the closed set +
446    /// ONE `as_str` arm + ONE `sensitivity_rank` arm + one arm per
447    /// predicate with the probe body untouched.
448    ///
449    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
450    /// preserves proofs; the scalar-carrier presence-probe body
451    /// lives at ONE substrate site so every downstream
452    /// (`data-classification-<kind>` require-tag family in
453    /// `tatara-check`, closed-set audit dispatchers, future variant
454    /// additions on [`DataClassification`]) binds through the SAME
455    /// shape rather than restating the
456    /// `classification.data_classification == kind` closure body at
457    /// each callsite. THEORY.md §VI.1 — generation over composition;
458    /// a future [`DataClassification`] variant lands at ONE `ALL`
459    /// entry + ONE `as_str` arm on the closed set and the probe
460    /// picks it up mechanically without further per-consumer edits.
461    #[must_use]
462    pub fn has_data_classification(&self, kind: DataClassification) -> bool {
463        self.data_classification == kind
464    }
465
466    /// Closed-set-driven presence probe — does this [`Classification`]
467    /// carry the given [`HorizonKind`] discriminator on its
468    /// [`Self::horizon`]`.kind` slot? The ONE substrate primitive that
469    /// owns the `(Classification, HorizonKind) -> bool` nested-struct-
470    /// scalar-carrier walk shape.
471    ///
472    /// # Seventh peer on the presence-probe axis — first on a fresh corner
473    ///
474    /// Peer of [`crate::spec::SignalPolicy::has_sighup_strategy`],
475    /// [`crate::encapsulates::EncapsulatesSpec::has_mode`],
476    /// [`Self::has_point_type`], [`Self::has_substrate`],
477    /// [`Self::has_calm`], and [`Self::has_data_classification`] on the
478    /// workspace-wide closed-set-driven presence-probe algebra — the
479    /// four scalar-carrier peers on [`Classification`] all read a
480    /// closed-set discriminator DIRECTLY off a scalar `Classification`
481    /// slot (`point_type`, `substrate`, `calm`, `data_classification`).
482    /// `has_horizon_kind` instead threads through a NESTED-STRUCT
483    /// intermediary ([`Horizon`], the defaulted nested struct owning
484    /// the `horizon` axis on the six-axis classification lattice) to
485    /// reach a scalar [`HorizonKind`] discriminator on
486    /// `horizon.kind`. This OPENS the (required-parent × nested-
487    /// struct-scalar-child) corner of the algebra at its FIRST
488    /// substrate primitive — a fresh corner distinct from all four
489    /// corner-property-exhaustive scalar-carrier peers on
490    /// [`Classification`].
491    ///
492    /// # Semantics — VARIANT match on the nested scalar, not POPULATED nested struct
493    ///
494    /// `has_horizon_kind(kind)` returns `true` iff
495    /// `self.horizon.kind == kind`. The nested [`Horizon`] struct
496    /// carries [`Default`] via `#[derive(Default)]` and its `kind`
497    /// field defaults to [`HorizonKind::Bounded`] via `#[default]`, so
498    /// a [`Classification`] filled via `..Default::default()` on the
499    /// `horizon` axis reads `true` on the default kind
500    /// [`HorizonKind::Bounded`] and `false` on
501    /// [`HorizonKind::Asymptotic`]. The default-arm short-circuit is
502    /// therefore present at this corner too — but through the extra
503    /// struct hop the peer scalar-carrier peers on the defaulted-
504    /// child corner (`has_calm`, `has_data_classification`) walk
505    /// directly. A regression that dropped `#[default]` on
506    /// [`HorizonKind`], or that replaced `Horizon::default()` in
507    /// [`Classification::gate_compute`] with an explicit non-`Bounded`
508    /// kind, surfaces at this primitive's tests before drifting
509    /// through every unadorned Process's baseline horizon answer.
510    ///
511    /// # Compounding
512    ///
513    /// This method OPENS the (required-parent × nested-struct-scalar-
514    /// child) corner of the workspace-wide closed-set-driven
515    /// presence-probe algebra, distinct from the four corner-property-
516    /// exhaustive scalar-carrier peers on [`Classification`]
517    /// ([`Self::has_point_type`], [`Self::has_substrate`],
518    /// [`Self::has_calm`], [`Self::has_data_classification`]) whose
519    /// bodies read a closed-set discriminator directly off a scalar
520    /// slot. A future co-tenant on this fresh corner (a peer probe on
521    /// another nested-struct's scalar discriminator, e.g. a
522    /// hypothetical `has_optimization_direction` reaching
523    /// `spec.classification.horizon.direction.unwrap_or_default()`, or
524    /// a nested-struct-scalar discriminator on a different `ProcessSpec`
525    /// field's inner struct) lands as ONE peer inherent method with
526    /// the same two-hop `self.<outer>.<inner> == kind` body and routes
527    /// through the same `strip_and_classify_prefixed_kind::<K, _>`
528    /// shape in `tatara-check`. A future [`HorizonKind`] variant (a
529    /// hypothetical `Periodic` sentinel for "terminates on each
530    /// window boundary then re-arms", pre-flagged on the closed set's
531    /// `ALL` docstring) reaches every downstream through ONE `ALL`
532    /// entry + one `as_str` arm + one `terminates` arm + one
533    /// `requires_metric_axes` arm on the closed set with the probe
534    /// body untouched.
535    ///
536    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
537    /// preserves proofs; the nested-struct-scalar-carrier presence-
538    /// probe body lives at ONE substrate site so every downstream
539    /// (`horizon-<kind>` require-tag family in `tatara-check`, future
540    /// audit dispatchers walking [`HorizonKind::ALL`], future variant
541    /// additions on [`HorizonKind`]) binds through the SAME
542    /// `has(kind)` shape rather than restating the
543    /// `classification.horizon.kind == kind` closure body at each
544    /// callsite. THEORY.md §VI.1 — generation over composition; a
545    /// future [`HorizonKind`] variant lands at ONE `ALL` entry + ONE
546    /// `as_str` arm on the closed set and the probe picks it up
547    /// mechanically without further per-consumer edits.
548    #[must_use]
549    pub fn has_horizon_kind(&self, kind: HorizonKind) -> bool {
550        self.horizon.kind == kind
551    }
552
553    /// Closed-set-driven presence probe — does this [`Classification`]
554    /// carry the given [`OptimizationDirection`] discriminator on its
555    /// [`Self::horizon`]`.direction` slot (with the substrate
556    /// `Option::unwrap_or_default` treating `None` as the closed set's
557    /// `#[default] Minimize`)? The ONE substrate primitive that owns
558    /// the `(Classification, OptimizationDirection) -> bool` nested-
559    /// struct-Option-scalar-carrier walk shape.
560    ///
561    /// # Second occupant on the nested-struct-scalar-child corner —
562    /// the Option-hop co-tenant
563    ///
564    /// Peer of [`Self::has_horizon_kind`] on the (required-parent ×
565    /// nested-struct-scalar-child) corner opened by that method — same
566    /// two-hop composition through the nested defaulted [`Horizon`]
567    /// intermediary, but the inner scalar slot is `direction:
568    /// Option<OptimizationDirection>` (an `Option`-hop past the same
569    /// nested [`Horizon`]) rather than a bare scalar. The corner
570    /// therefore admits BOTH direct nested-scalar shapes ([`Horizon`]
571    /// carries `kind: HorizonKind` directly, [`Self::has_horizon_kind`]
572    /// walks it) AND Option-nested-scalar shapes ([`Horizon`] carries
573    /// `direction: Option<OptimizationDirection>`, this method walks
574    /// it through `Option::unwrap_or_default`), pinning the corner as
575    /// a proven-repeatable primitive shape rather than a single-
576    /// example curiosity. Every prior scalar-carrier peer on
577    /// [`Classification`] (`has_point_type`, `has_substrate`,
578    /// `has_calm`, `has_data_classification`) reads a closed-set
579    /// discriminator DIRECTLY off a scalar `Classification` slot; this
580    /// method (like [`Self::has_horizon_kind`]) threads through the
581    /// nested [`Horizon`] intermediary, and additionally traverses the
582    /// `Option`-slot with `unwrap_or_default` so the operator's
583    /// `:requires (optimization-direction-Minimize)` on an unadorned
584    /// baseline still answers `true` on the closed set's default arm.
585    ///
586    /// # Semantics — VARIANT match on the Option-defaulted nested
587    /// scalar, not POPULATED Option
588    ///
589    /// `has_optimization_direction(kind)` returns `true` iff
590    /// `self.horizon.direction.unwrap_or_default() == kind`.
591    /// [`OptimizationDirection`] carries `#[default] Minimize` via
592    /// the derived [`Default`] impl, so a Process filled through
593    /// [`Horizon::bounded`] (which leaves `direction: None`) or
594    /// through `Horizon::default()` (same shape, `direction: None`)
595    /// answers `true` on [`OptimizationDirection::Minimize`] and
596    /// `false` on [`OptimizationDirection::Maximize`]. This mirrors
597    /// the default-arm short-circuit contract every other closed-set-
598    /// defaulted-child probe on [`Classification`] publishes
599    /// (`has_calm`, `has_data_classification`, `has_horizon_kind`) —
600    /// the `Option`-hop is soft-mapped to the closed set's default
601    /// arm rather than surfaced as a distinct presence axis. A
602    /// regression that flipped [`OptimizationDirection`]'s
603    /// `#[default]` off `Minimize` (which would silently invert every
604    /// unadorned `Asymptotic` Process's rate-window evaluator
605    /// polarity — see the [`OptimizationDirection::Minimize`] variant
606    /// docstring) fails at this probe's default-arm tests before
607    /// drifting through every downstream consumer.
608    ///
609    /// # Semantics rationale — Option-hop as default vs presence
610    ///
611    /// The `direction: Option<OptimizationDirection>` slot on
612    /// [`Horizon`] is documented as "Asymptotic only" — a `Bounded`
613    /// horizon has no meaningful direction so the operator leaves
614    /// it `None`. Yet the closed set carries `#[default] Minimize`,
615    /// so a bare `Bounded` Process's optimization direction reads
616    /// as `Minimize` at every consumer downstream via
617    /// [`Option::unwrap_or_default`]. That default IS the substrate's
618    /// operator-facing answer for "what direction would this Process
619    /// optimize toward if it became Asymptotic without further
620    /// annotation?", and a `:requires (optimization-direction-
621    /// Minimize)` audit at the checks.lisp surface correctly matches
622    /// every unadorned Process — matching the corner-property contract
623    /// every other defaulted-child probe publishes. An operator who
624    /// wants a strict presence axis (`is direction *actually* set?`)
625    /// gets that answer through a distinct future primitive
626    /// (`has_optimization_direction_set`) that would read the
627    /// `is_some` bit alone — orthogonal to this variant-equality
628    /// probe. This method commits to the variant-equality
629    /// interpretation so the corner-property contract stays uniform
630    /// with the four scalar-carrier peers.
631    ///
632    /// # Compounding
633    ///
634    /// This method POPULATES the (required-parent × nested-struct-
635    /// scalar-child) corner at its SECOND substrate primitive after
636    /// [`Self::has_horizon_kind`] opened it — pinning the corner as
637    /// a proven-repeatable primitive shape rather than a single-
638    /// example curiosity, and DEMONSTRATING that the corner admits
639    /// both direct-scalar and Option-scalar traversals through the
640    /// same nested-struct intermediary via the closed set's default.
641    /// A future co-tenant on this corner (a peer probe on another
642    /// nested-struct's scalar or Option-scalar discriminator, e.g.
643    /// a hypothetical `has_backend_port_family` reaching
644    /// `spec.routing.as_ref().and_then(|r| r.backend.tls_issuer.as_ref()).is_some()`
645    /// or a nested-struct-scalar discriminator on
646    /// `spec.encapsulates.<some-inner>.kind`) lands as ONE peer
647    /// inherent method with the same two-hop `self.<outer>.<inner>`
648    /// walk (with or without an Option-hop threading through the
649    /// closed set's `Default`) and routes through the same
650    /// `strip_and_classify_prefixed_kind::<K, _>` shape in
651    /// `tatara-check`. A future [`OptimizationDirection`] variant
652    /// (a hypothetical `Stabilize` sentinel for "drive toward a
653    /// target value", pre-flagged on the closed set's `ALL`
654    /// docstring) reaches every downstream through ONE `ALL` entry
655    /// + one `as_str` arm + one `prefers_lower` arm + one
656    /// `is_improvement` arm on the closed set with the probe body
657    /// untouched.
658    ///
659    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
660    /// preserves proofs; the nested-struct-Option-scalar-carrier
661    /// presence-probe body lives at ONE substrate site so every
662    /// downstream (`optimization-direction-<kind>` require-tag family
663    /// in `tatara-check`, future audit dispatchers walking
664    /// [`OptimizationDirection::ALL`], future variant additions on
665    /// [`OptimizationDirection`]) binds through the SAME
666    /// `has(kind)` shape rather than restating the
667    /// `classification.horizon.direction.unwrap_or_default() == kind`
668    /// closure body at each callsite. THEORY.md §VI.1 — generation
669    /// over composition; a future [`OptimizationDirection`] variant
670    /// lands at ONE `ALL` entry + ONE `as_str` arm on the closed set
671    /// and the probe picks it up mechanically without further
672    /// per-consumer edits.
673    #[must_use]
674    pub fn has_optimization_direction(&self, kind: OptimizationDirection) -> bool {
675        self.horizon.direction.unwrap_or_default() == kind
676    }
677
678    /// Closed-set-driven presence probe — does this [`Classification`]
679    /// carry a [`ConvergencePointType`] whose typed input-edge
680    /// cardinality projection ([`ConvergencePointType::input_arity`])
681    /// matches the given [`Arity`] discriminator? The ONE substrate
682    /// primitive that owns the `(Classification, Arity) -> bool`
683    /// derived-typed-projection walk shape.
684    ///
685    /// # Third occupant on the (required-parent × nested-struct-scalar-child) corner — first via a derived-typed-projection
686    ///
687    /// Peer of [`Self::has_horizon_kind`] and
688    /// [`Self::has_optimization_direction`] on the (required-parent ×
689    /// nested-struct-scalar-child) corner. Distinct from the two on
690    /// ONE dimension: those two read a raw discriminator directly off
691    /// the nested [`Horizon`] slot (`self.horizon.kind` /
692    /// `self.horizon.direction.unwrap_or_default()`) so the child's
693    /// closed set IS the field's type; this probe threads through the
694    /// closed-set typed projection [`ConvergencePointType::input_arity`]
695    /// (a `const fn` many-to-one collapse `Transform | Fork |
696    /// Broadcast | Observe → One`, `Join | Gate | Select | Reduce →
697    /// Many`) so the child's closed set is REACHED THROUGH a typed
698    /// projection layer, not read raw off a scalar. Byte-for-byte
699    /// symmetric with the derived-typed-projection precedent set by
700    /// [`crate::export::ExportSpecSliceExt::has_report_payload_shape`]
701    /// on the (Option-parent × Vec-child × nested-Option-carrier ×
702    /// derived-typed-projection) corner — that peer routes through
703    /// [`crate::export::ReportFormat::payload_shape`] the same way
704    /// this method routes through [`ConvergencePointType::input_arity`].
705    /// FIRST occupant of the derived-typed-projection variant on the
706    /// (required-parent × nested-struct-scalar-child) corner —
707    /// widening the corner from "raw discriminator only" to "raw
708    /// discriminator OR typed projection over the child" and pinning
709    /// the corner as a proven-repeatable primitive shape rather than a
710    /// direct-field-equality curiosity.
711    ///
712    /// # Semantics — VARIANT match on the projected image, not on the source
713    ///
714    /// `has_input_arity(kind)` returns `true` iff
715    /// `self.point_type.input_arity() == kind`. [`Arity`] carries no
716    /// `Default` impl (the `Arity::ALL` closed set is a bare 2-arm
717    /// enum with no `#[default]`), so exactly ONE of the two arms
718    /// answers `true` per well-formed [`crate::crd::ProcessSpec`],
719    /// with no default-arm short-circuit shortcut. The many-to-one
720    /// projection shape means the answer is invariant under intra-
721    /// bucket point-type swaps (`Transform ↔ Fork ↔ Broadcast ↔
722    /// Observe` all keep `input-arity-One = true`) and flips at
723    /// bucket boundaries (`Transform ↔ Join` flips `input-arity-One`
724    /// from `true` to `false`). A regression that (a) probed
725    /// [`ConvergencePointType`] directly (dropping the
726    /// `.input_arity()` call), (b) inverted the projection (`One ↔
727    /// Many`), or (c) crossed the wires with the sibling
728    /// [`ConvergencePointType::output_arity`] projection (which
729    /// disagrees on the fan-out arms `Fork | Broadcast → Many` vs.
730    /// `input_arity`'s `Fork | Broadcast → One`) fails at this probe's
731    /// substrate site before drifting through every downstream
732    /// consumer.
733    ///
734    /// # Compounding
735    ///
736    /// This method POPULATES the (required-parent × nested-struct-
737    /// scalar-child) corner at its THIRD substrate primitive after
738    /// [`Self::has_horizon_kind`] opened it (direct-nested-scalar) and
739    /// [`Self::has_optimization_direction`] populated it
740    /// (Option-nested-scalar). Together the three demonstrate the
741    /// corner admits three traversal shapes through the SAME
742    /// two-hop `self.<field>.<projection>` walk: direct-scalar,
743    /// Option-scalar-with-default, and derived-typed-projection. A
744    /// future co-tenant reading a projected value off the same
745    /// [`ConvergencePointType`] (a peer `has_output_arity` reading
746    /// `self.point_type.output_arity() == kind` — the natural fourth
747    /// occupant, opening the pair for DAG-composition axis coverage;
748    /// a hypothetical `has_topology_bucket` reading `.is_preserving()`
749    /// / `.is_diffusive()` / `.is_convergent()`) lands as ONE peer
750    /// inherent method with the same one-line
751    /// `self.point_type.<projection>() == kind` body and routes
752    /// through the same `strip_and_classify_prefixed_kind::<K, _>`
753    /// shape in `tatara-check`. A future [`ConvergencePointType`]
754    /// variant (a hypothetical `Demux` for `One → Many` or `Mux` for
755    /// `Many → One`) reaches every downstream through ONE `ALL`
756    /// entry + one `as_str` arm + one `input_arity` arm + one
757    /// `output_arity` arm on the closed set with THIS probe body
758    /// untouched — the many-to-one projection means the bucket
759    /// membership shift lands exactly at the projection's own site.
760    ///
761    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
762    /// preserves proofs; the derived-typed-projection presence-probe
763    /// body lives at ONE substrate site so every downstream
764    /// (`input-arity-<kind>` require-tag family in `tatara-check`,
765    /// future DAG-composition validators, future variant additions
766    /// on [`ConvergencePointType`]) binds through the SAME
767    /// `has(kind)` shape rather than restating the
768    /// `classification.point_type.input_arity() == kind` closure body
769    /// at each callsite. THEORY.md §VI.1 — generation over
770    /// composition; a future [`Arity`] variant (a hypothetical `Zero`
771    /// for sinks) lands at ONE `ALL` entry + ONE `as_str` arm on the
772    /// closed set + ONE arm on each `input_arity`/`output_arity`
773    /// projection and the probe picks it up mechanically without
774    /// further per-consumer edits.
775    #[must_use]
776    pub fn has_input_arity(&self, kind: Arity) -> bool {
777        self.point_type.input_arity() == kind
778    }
779
780    /// Closed-set-driven presence probe — does this [`Classification`]
781    /// carry a [`ConvergencePointType`] whose typed output-edge
782    /// cardinality projection ([`ConvergencePointType::output_arity`])
783    /// matches the given [`Arity`] discriminator? The ONE substrate
784    /// primitive that owns the `(Classification, Arity) -> bool`
785    /// output-side derived-typed-projection walk shape.
786    ///
787    /// # Fourth occupant on the (required-parent × nested-struct-scalar-child) corner — second via a derived-typed-projection; closes the DAG-composition arity pair
788    ///
789    /// Peer of [`Self::has_horizon_kind`],
790    /// [`Self::has_optimization_direction`], and
791    /// [`Self::has_input_arity`] on the (required-parent ×
792    /// nested-struct-scalar-child) corner. Byte-for-byte symmetric with
793    /// [`Self::has_input_arity`]: this method walks the SAME
794    /// `self.point_type` scalar carrier through the SAME `Arity`
795    /// closed set — the sole distinction is the typed projection
796    /// composed on the walk. `has_input_arity` composes
797    /// [`ConvergencePointType::input_arity`] (`Transform | Fork |
798    /// Broadcast | Observe → One`, `Join | Gate | Select | Reduce →
799    /// Many`); this method composes
800    /// [`ConvergencePointType::output_arity`] (`Fork | Broadcast →
801    /// Many`, everything else → `One`). Together the two probes close
802    /// the DAG-composition arity pair — the `(input_arity,
803    /// output_arity)` typed projection that pins each variant to
804    /// exactly one cell of the `Arity × Arity` topology table
805    /// (endomorphic `(One, One)`, diffusive `(One, Many)`, convergent
806    /// `(Many, One)`) so future DAG-composition validators dispatch on
807    /// a typed projection rather than re-deriving from variant names.
808    /// SECOND derived-typed-projection occupant on the
809    /// (required-parent × nested-struct-scalar-child) corner — pinning
810    /// the corner's "one carrier, N typed-projection probes" property
811    /// with a second projection over the same source closed set.
812    ///
813    /// # Semantics — VARIANT match on the OUTPUT-projected image
814    ///
815    /// `has_output_arity(kind)` returns `true` iff
816    /// `self.point_type.output_arity() == kind`. [`Arity`] carries no
817    /// `Default` impl, so exactly ONE of the two arms answers `true`
818    /// per well-formed [`crate::crd::ProcessSpec`], with no default-
819    /// arm short-circuit. The many-to-one projection shape means the
820    /// answer is invariant under intra-bucket swaps (`Fork ↔
821    /// Broadcast` both keep `output-arity-Many = true`; `Transform ↔
822    /// Join ↔ Gate ↔ Select ↔ Reduce ↔ Observe` all keep
823    /// `output-arity-One = true`) and flips at bucket boundaries
824    /// (`Fork ↔ Transform` flips `output-arity-Many` from `true` to
825    /// `false`). CROSS-PROJECTION DIAGONAL: `Fork | Broadcast` have
826    /// `(input_arity, output_arity) = (One, Many)` so `has_input_arity`
827    /// and `has_output_arity` DISAGREE on those two variants (the
828    /// diffusive bucket is the unique cell where the two projections
829    /// answer opposite `Arity` values); `Join | Gate | Select |
830    /// Reduce` have `(Many, One)` so the two probes disagree there too
831    /// (the convergent bucket is the mirror cell); `Transform |
832    /// Observe` have `(One, One)` so the two probes AGREE (the
833    /// endomorphic bucket). A regression that (a) probed
834    /// [`ConvergencePointType`] directly (dropping the
835    /// `.output_arity()` call), (b) inverted the projection (`One ↔
836    /// Many`), or (c) crossed the wires with
837    /// [`ConvergencePointType::input_arity`] (which disagrees on the
838    /// four arms in the diffusive + convergent cells) fails at this
839    /// probe's substrate site before drifting through every downstream
840    /// consumer.
841    ///
842    /// # Compounding
843    ///
844    /// This method POPULATES the DAG-composition arity pair for full
845    /// axis coverage — the natural fourth occupant the
846    /// [`Self::has_input_arity`] docstring names as the next
847    /// derived-typed-projection co-tenant on the same
848    /// `self.point_type` carrier. Operators authoring `(defpoint …
849    /// :requires (output-arity-Many))` in `checks.lisp` now get typed
850    /// access to the fan-out axis (edge-cardinality checks: "every
851    /// diffusive topology point emits fan-out" — the exact fleet-wide
852    /// property the (`Fork | Broadcast`, `Many`) projection composition
853    /// is designed to name) as the mirror of the input-side family,
854    /// and the two conjoined (`input-arity-One AND
855    /// output-arity-Many`) names the diffusive bucket exactly through
856    /// the two typed projections rather than through the OR of raw
857    /// `point-type-<Fork | Broadcast>` conjuncts. A future
858    /// [`ConvergencePointType`] variant (a hypothetical `Demux` for
859    /// `One → Many` or `Mux` for `Many → One`) reaches every downstream
860    /// through ONE `ALL` entry + one `as_str` arm + one `input_arity`
861    /// arm + one `output_arity` arm on the closed set with THIS probe
862    /// body untouched — the many-to-one projection means the bucket
863    /// membership shift lands exactly at each projection's own site,
864    /// not at every consumer that previously restated the bucket in
865    /// code.
866    ///
867    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
868    /// preserves proofs; the second derived-typed-projection presence-
869    /// probe body over the SAME `self.point_type` carrier lives at ONE
870    /// substrate site so every downstream (`output-arity-<kind>`
871    /// require-tag family in `tatara-check`, future DAG-composition
872    /// validators, future variant additions on
873    /// [`ConvergencePointType`]) binds through the SAME `has(kind)`
874    /// shape. THEORY.md §VI.1 — generation over composition; a future
875    /// [`Arity`] variant lands at ONE `ALL` entry + ONE `as_str` arm
876    /// on the closed set + ONE arm on each `input_arity`/`output_arity`
877    /// projection and both probes pick it up mechanically.
878    #[must_use]
879    pub fn has_output_arity(&self, kind: Arity) -> bool {
880        self.point_type.output_arity() == kind
881    }
882
883    /// Derived-boolean predicate — does this [`Classification`] carry a
884    /// [`Horizon`] whose kind projects to `true` under
885    /// [`HorizonKind::terminates`]? The ONE substrate primitive that
886    /// owns the `(Classification) -> bool` derived-nullary-predicate
887    /// walk shape on the `horizon.kind` slot.
888    ///
889    /// # First occupant on the (required-parent × nested-struct-derived-nullary-bool) corner
890    ///
891    /// Distinct from every prior presence-probe method on
892    /// [`Classification`] — those all admit a closed-set `kind`
893    /// argument that the probe compares against the stored /
894    /// projected discriminator ([`Self::has_horizon_kind`] walks
895    /// `horizon.kind == kind`, [`Self::has_optimization_direction`]
896    /// walks `horizon.direction.unwrap_or_default() == kind`,
897    /// [`Self::has_input_arity`] / [`Self::has_output_arity`] walk
898    /// `point_type.<projection>() == kind`). This probe has NO
899    /// argument at all: it collapses [`HorizonKind::ALL`] onto a
900    /// single boolean question ("does this horizon terminate?") via
901    /// the closed set's own [`HorizonKind::terminates`] predicate,
902    /// so callers asking the workspace-wide scheduler-facing
903    /// question "will this Process ever reach [`crate::phase::ProcessPhase::Reaped`]
904    /// via natural termination" reach the answer through a nullary
905    /// substrate call rather than restating
906    /// `classification.horizon.kind.terminates()` at every consumer.
907    ///
908    /// # Semantics — derived nullary boolean, not variant equality
909    ///
910    /// `horizon_terminates()` returns `true` iff
911    /// `self.horizon.kind.terminates()`. The two-variant
912    /// [`HorizonKind`] closed set publishes the truth table:
913    /// [`HorizonKind::Bounded`] → `true` (has a fixed point,
914    /// distance reaches 0, terminates naturally);
915    /// [`HorizonKind::Asymptotic`] → `false` (runs in perpetuity,
916    /// rate is the health signal, never terminates on its own). A
917    /// [`Classification::gate_compute`] baseline (which uses
918    /// [`Horizon::default`] with `kind = HorizonKind::Bounded` via
919    /// `#[default]`) answers `true` — the substrate's default-arm
920    /// short-circuit propagates through the nested [`Horizon`]
921    /// struct's own [`Default`] impl to this predicate's answer
922    /// the same way it propagates through
923    /// [`Self::has_horizon_kind`]'s `HorizonKind::Bounded` arm.
924    ///
925    /// A future third [`HorizonKind`] variant (a hypothetical
926    /// `Periodic` sentinel for "terminates on each window boundary
927    /// then re-arms" — pre-flagged on the closed set's `ALL`
928    /// docstring) reaches this probe through ONE `terminates` arm
929    /// on the closed set with the probe body untouched — the
930    /// nullary-predicate shape defers every per-variant policy
931    /// decision to the closed set's own truth table
932    /// ([`HorizonKind::terminates`]) rather than duplicating the
933    /// discriminator sweep here.
934    ///
935    /// # Compounding
936    ///
937    /// This method OPENS the (required-parent ×
938    /// nested-struct-derived-nullary-bool) corner of the workspace-
939    /// wide closed-set-driven presence-probe algebra at its FIRST
940    /// substrate primitive — distinct from every prior corner
941    /// occupant on [`Classification`] (which all take a closed-set
942    /// `kind` argument). A future co-tenant on this fresh corner (a
943    /// peer nullary predicate on another nested-struct's derived
944    /// boolean projection — a hypothetical `horizon_requires_metric_axes`
945    /// composing [`HorizonKind::requires_metric_axes`] as the
946    /// antisymmetric partner of `horizon_terminates`; a hypothetical
947    /// `intent_is_helm_driven` composing over the tagged-union
948    /// intent variants; a peer collapsing a routing form's
949    /// [`crate::routing::RoutingForm::ALL`] → bool) lands as ONE
950    /// peer inherent method with the same nullary derived body and
951    /// routes through the same fixed-tag substrate in
952    /// [`tatara-check`]'s classifier — no per-consumer restatement
953    /// of the `classification.<field>.<projection>()` chain.
954    ///
955    /// The point-domain require-tag surface in
956    /// `tatara-reconciler::bin::tatara-check` composes this primitive
957    /// as a fixed tag `terminating-horizon` on
958    /// [`POINT_FIXED_TAG_ARMS`] — byte-for-byte peer of the fixed
959    /// tags [`FixedTagArm`] already publishes (`depends-on`,
960    /// `boundary-pre`, `boundary-post`, `compliance`, `signals`).
961    /// The ephemeral surface publishes the same tag via
962    /// [`crate::ephemeral::EphemeralSpec::horizon_terminates`], which
963    /// composes THIS method through
964    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
965    /// so the two-surface parity contract holds — the operator's
966    /// `:requires (terminating-horizon)` audit answers the same
967    /// question on both surfaces.
968    ///
969    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
970    /// preserves proofs; the derived-nullary-bool predicate body
971    /// lives at ONE substrate site so every downstream (the
972    /// `terminating-horizon` fixed tag in [`tatara-check`], future
973    /// scheduler / termination-shape validators, future variant
974    /// additions on [`HorizonKind`]) binds through the SAME
975    /// `horizon_terminates()` shape rather than restating the
976    /// `classification.horizon.kind.terminates()` chain at each
977    /// callsite. THEORY.md §VI.1 — generation over composition; a
978    /// future [`HorizonKind`] variant lands at ONE `ALL` entry +
979    /// ONE `terminates` arm on the closed set and this probe picks
980    /// it up mechanically.
981    #[must_use]
982    pub fn horizon_terminates(&self) -> bool {
983        self.horizon.kind.terminates()
984    }
985
986    /// Derived-boolean predicate — does this [`Classification`] carry a
987    /// [`Horizon`] whose kind projects to `true` under
988    /// [`HorizonKind::requires_metric_axes`]? The ONE substrate
989    /// primitive that owns the `(Classification) -> bool` derived-
990    /// nullary-predicate walk shape on the `horizon.kind` slot for
991    /// the metric-axes-required question.
992    ///
993    /// # Second occupant on the (required-parent × nested-struct-derived-nullary-bool) corner
994    ///
995    /// Byte-for-byte peer of [`Self::horizon_terminates`] via the SAME
996    /// closed set [`HorizonKind`] reached through the SAME nested
997    /// [`Horizon`] struct: [`Self::horizon_terminates`] composes
998    /// [`HorizonKind::terminates`] as `self.horizon.kind.terminates()`;
999    /// this method composes the ANTISYMMETRIC partner
1000    /// [`HorizonKind::requires_metric_axes`] as
1001    /// `self.horizon.kind.requires_metric_axes()`. The closed set
1002    /// pins the XOR contract
1003    /// `terminates() ^ requires_metric_axes()` on every variant (see
1004    /// `horizon_kind_terminate_xor_requires_metric_axes` on the closed
1005    /// set itself), so exactly ONE of the two derived-nullary probes
1006    /// answers `true` per [`Classification`] and the two probes
1007    /// together partition [`HorizonKind::ALL`] into two disjoint
1008    /// buckets. This POPULATES the (required-parent × nested-struct-
1009    /// derived-nullary-bool) corner of the workspace-wide closed-set-
1010    /// driven presence-probe algebra at its SECOND substrate primitive
1011    /// after [`Self::horizon_terminates`] opened the corner, pinning
1012    /// the corner as a proven-repeatable primitive shape rather than
1013    /// a single-example curiosity.
1014    ///
1015    /// # Semantics — derived nullary boolean, not variant equality
1016    ///
1017    /// `horizon_requires_metric_axes()` returns `true` iff
1018    /// `self.horizon.kind.requires_metric_axes()`. The two-variant
1019    /// [`HorizonKind`] closed set publishes the truth table:
1020    /// [`HorizonKind::Bounded`] → `false` (has a fixed point, no
1021    /// asymptotic metric axes required); [`HorizonKind::Asymptotic`]
1022    /// → `true` (runs in perpetuity, `rate` and `oscillation` are the
1023    /// health signal and must be measured). A
1024    /// [`Classification::gate_compute`] baseline (which uses
1025    /// [`Horizon::default`] with `kind = HorizonKind::Bounded` via
1026    /// `#[default]`) answers `false` — the substrate's default-arm
1027    /// short-circuit propagates through the nested [`Horizon`]
1028    /// struct's own [`Default`] impl to this predicate's answer, the
1029    /// mirror image of [`Self::horizon_terminates`]'s default-arm
1030    /// answer.
1031    ///
1032    /// A future third [`HorizonKind`] variant (a hypothetical
1033    /// `Periodic` sentinel for "terminates on each window boundary
1034    /// then re-arms" — pre-flagged on the closed set's `ALL`
1035    /// docstring) reaches this probe through ONE `requires_metric_axes`
1036    /// arm on the closed set with the probe body untouched — the
1037    /// nullary-predicate shape defers every per-variant policy
1038    /// decision to the closed set's own truth table
1039    /// ([`HorizonKind::requires_metric_axes`]) rather than duplicating
1040    /// the discriminator sweep here.
1041    ///
1042    /// # Compounding
1043    ///
1044    /// The point-domain require-tag surface in
1045    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1046    /// as a fixed tag `metric-axes-required` on
1047    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte antisymmetric peer of
1048    /// the sibling `terminating-horizon` fixed tag. The ephemeral
1049    /// surface publishes the same tag via
1050    /// [`crate::ephemeral::EphemeralSpec::horizon_requires_metric_axes`],
1051    /// which composes THIS method through
1052    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1053    /// so the two-surface parity contract holds — the operator's
1054    /// `:requires (metric-axes-required)` audit answers the same
1055    /// question on both surfaces.
1056    ///
1057    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1058    /// preserves proofs; the derived-nullary-bool predicate body
1059    /// lives at ONE substrate site so every downstream (the
1060    /// `metric-axes-required` fixed tag in `tatara-check`, future
1061    /// scheduler / metric-provisioning validators, future variant
1062    /// additions on [`HorizonKind`]) binds through the SAME
1063    /// `horizon_requires_metric_axes()` shape rather than restating
1064    /// the `classification.horizon.kind.requires_metric_axes()` chain
1065    /// at each callsite. THEORY.md §VI.1 — generation over
1066    /// composition; a future [`HorizonKind`] variant lands at ONE
1067    /// `ALL` entry + ONE `requires_metric_axes` arm on the closed set
1068    /// and this probe picks it up mechanically.
1069    #[must_use]
1070    pub fn horizon_requires_metric_axes(&self) -> bool {
1071        self.horizon.kind.requires_metric_axes()
1072    }
1073
1074    /// Derived-boolean predicate — does this [`Classification`] carry a
1075    /// [`CalmClassification`] whose variant projects to `true` under
1076    /// [`CalmClassification::requires_coordination`]? The ONE substrate
1077    /// primitive that owns the `(Classification) -> bool` derived-
1078    /// nullary-predicate walk shape on the `calm` slot.
1079    ///
1080    /// # Third occupant on the (parent × derived-nullary-bool) corner
1081    ///
1082    /// Peer of [`Self::horizon_terminates`] and
1083    /// [`Self::horizon_requires_metric_axes`] on the workspace-wide
1084    /// (parent × derived-nullary-bool) corner of the closed-set-driven
1085    /// presence-probe algebra — the FIRST occupant threading the
1086    /// `calm` axis rather than the `horizon.kind` sub-axis. Distinct
1087    /// from the two `horizon.*` peers by ONE structural degree: this
1088    /// probe reads a DIRECT scalar closed-set field
1089    /// ([`Self::calm`]) rather than the NESTED-STRUCT projection
1090    /// (`self.horizon.kind`) both `horizon_*` peers walk; the derived-
1091    /// nullary shape and the truth-table composition style match
1092    /// exactly. Populates the corner as a proven-repeatable primitive
1093    /// shape across TWO distinct closed-set axes (`HorizonKind`,
1094    /// `CalmClassification`) rather than an axis-local curiosity.
1095    ///
1096    /// # Semantics — derived nullary boolean, not variant equality
1097    ///
1098    /// `calm_requires_coordination()` returns `true` iff
1099    /// `self.calm.requires_coordination()`. The two-variant
1100    /// [`CalmClassification`] closed set publishes the truth table
1101    /// (the CALM theorem's typed image, Hellerstein 2010):
1102    /// [`CalmClassification::Monotone`] → `false` (can be distributed
1103    /// without coordination); [`CalmClassification::NonMonotone`] →
1104    /// `true` (requires coordination). A
1105    /// [`Classification::gate_compute`] baseline (which uses
1106    /// [`CalmClassification::default = Monotone`] via `#[default]`)
1107    /// answers `false` — the substrate's default-arm short-circuit
1108    /// propagates through the scalar closed-set field's own
1109    /// [`Default`] impl to this predicate's answer. The mirror-image
1110    /// distinguishing feature vs the two `horizon_*` peers: those
1111    /// short-circuit through TWO layers of `Default`
1112    /// ([`Horizon::default`] → [`HorizonKind::default`]); this probe
1113    /// short-circuits through ONE layer of `Default`
1114    /// ([`CalmClassification::default`]) because `Self::calm` is a
1115    /// direct scalar rather than a nested struct wrapper.
1116    ///
1117    /// A future third [`CalmClassification`] variant (a hypothetical
1118    /// `ConditionallyMonotone` sentinel — pre-flagged on the closed
1119    /// set's `ALL` docstring) reaches this probe through ONE
1120    /// `requires_coordination` arm on the closed set with the probe
1121    /// body untouched — the nullary-predicate shape defers every
1122    /// per-variant policy decision to the closed set's own truth
1123    /// table ([`CalmClassification::requires_coordination`]) rather
1124    /// than duplicating the discriminator sweep here.
1125    ///
1126    /// # Compounding
1127    ///
1128    /// The point-domain require-tag surface in
1129    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1130    /// as a fixed tag `coordination-required` on
1131    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte peer of the sibling
1132    /// `terminating-horizon` and `metric-axes-required` fixed tags on
1133    /// the (parent × derived-nullary-bool) corner. The ephemeral
1134    /// surface publishes the same tag via
1135    /// [`crate::ephemeral::EphemeralSpec::calm_requires_coordination`],
1136    /// which composes THIS method through
1137    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1138    /// so the two-surface parity contract holds — the operator's
1139    /// `:requires (coordination-required)` audit answers the same
1140    /// question on both surfaces.
1141    ///
1142    /// Future scheduler dispatch between Raft writes and gossip
1143    /// propagation (documented on
1144    /// [`CalmClassification::requires_coordination`] itself) reads
1145    /// THIS predicate rather than re-deriving from the variant name
1146    /// at each callsite — the classification-axis lattice-typed
1147    /// image of the CALM theorem lives at ONE substrate site and
1148    /// every scheduler / coordination-mode chooser downstream binds
1149    /// through the SAME `calm_requires_coordination()` shape.
1150    ///
1151    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1152    /// preserves proofs; the derived-nullary-bool predicate body
1153    /// lives at ONE substrate site so every downstream (the
1154    /// `coordination-required` fixed tag in `tatara-check`, future
1155    /// scheduler / coordination-mode validators, future variant
1156    /// additions on [`CalmClassification`]) binds through the SAME
1157    /// `calm_requires_coordination()` shape rather than restating the
1158    /// `classification.calm.requires_coordination()` chain at each
1159    /// callsite. THEORY.md §VI.1 — generation over composition; a
1160    /// future [`CalmClassification`] variant lands at ONE `ALL` entry +
1161    /// ONE `requires_coordination` arm on the closed set and this probe
1162    /// picks it up mechanically.
1163    #[must_use]
1164    pub fn calm_requires_coordination(&self) -> bool {
1165        self.calm.requires_coordination()
1166    }
1167
1168    /// Derived-boolean predicate — does this [`Classification`] carry a
1169    /// [`DataClassification`] whose variant projects to `true` under
1170    /// [`DataClassification::is_regulated`]? The ONE substrate primitive
1171    /// that owns the `(Classification) -> bool` derived-nullary-
1172    /// predicate walk shape on the `data_classification` slot for the
1173    /// regulated-data question.
1174    ///
1175    /// # Fourth occupant on the (parent × derived-nullary-bool) corner
1176    ///
1177    /// Peer of [`Self::horizon_terminates`],
1178    /// [`Self::horizon_requires_metric_axes`], and
1179    /// [`Self::calm_requires_coordination`] on the workspace-wide
1180    /// (parent × derived-nullary-bool) corner of the closed-set-driven
1181    /// presence-probe algebra — the FIRST occupant threading the
1182    /// classification-data axis rather than the horizon or calm
1183    /// sub-axes. Populates the corner across THREE distinct closed-set
1184    /// axes (`HorizonKind`, `CalmClassification`, `DataClassification`)
1185    /// rather than two — pinning the corner as a proven-repeatable
1186    /// primitive shape across the substrate's three classification-
1187    /// axis closed sets that publish a `#[default]` variant, not a
1188    /// single-axis or two-axis curiosity. Byte-for-byte structural
1189    /// peer of [`Self::calm_requires_coordination`]: both walk a
1190    /// DIRECT scalar closed-set field (`self.calm` /
1191    /// `self.data_classification`) on the [`Classification`] parent —
1192    /// TWO layers of `Default` short-circuit (`Classification::gate_compute`
1193    /// → the direct scalar child's `#[default]`) — distinct from the
1194    /// two `horizon_*` peers which walk a NESTED-STRUCT projection
1195    /// (`self.horizon.kind`) with THREE layers of `Default`
1196    /// (`Classification::gate_compute` → `Horizon::default` →
1197    /// `HorizonKind::default`). SECOND direct-scalar peer on the
1198    /// corner: `calm_requires_coordination` opened the direct-scalar
1199    /// variant, this method populates it, pinning "direct-scalar
1200    /// derived-nullary-bool" as a proven-repeatable structural
1201    /// sub-corner rather than a single-example curiosity.
1202    ///
1203    /// # Semantics — derived nullary boolean, not variant equality
1204    ///
1205    /// `data_is_regulated()` returns `true` iff
1206    /// `self.data_classification.is_regulated()`. The six-variant
1207    /// [`DataClassification`] closed set publishes the truth table:
1208    /// [`DataClassification::Public`] / [`DataClassification::Internal`]
1209    /// / [`DataClassification::Confidential`] → `false` (not subject
1210    /// to external regulatory regime); [`DataClassification::Pii`] /
1211    /// [`DataClassification::Phi`] / [`DataClassification::Pci`] →
1212    /// `true` (HIPAA / PCI-DSS / GDPR-style data-subject controls
1213    /// apply). A [`Classification::gate_compute`] baseline (which
1214    /// uses [`DataClassification::default = Internal`] via
1215    /// `#[default]`) answers `false` — the substrate's default-arm
1216    /// short-circuit propagates through the scalar closed-set field's
1217    /// own [`Default`] impl to this predicate's answer, mirror image
1218    /// of [`Self::calm_requires_coordination`]'s Monotone-default
1219    /// short-circuit through the same structural depth.
1220    ///
1221    /// The closed-set-internal pin
1222    /// `data_classification_regulated_implies_restricted` seals the
1223    /// implication `is_regulated() ⇒ is_restricted()` on every
1224    /// variant, so a `true` answer here implies the sibling
1225    /// (`data_is_restricted`, when it lands) also answers `true`;
1226    /// the reverse does not hold (`Internal | Confidential` are
1227    /// restricted but not regulated).
1228    ///
1229    /// A future seventh [`DataClassification`] variant (a hypothetical
1230    /// `TradeSecret` bucket for competitive-sensitive data, or an
1231    /// `Anonymized` bucket for pseudonymized-PII whose regulatory
1232    /// posture differs from raw PII) reaches this probe through ONE
1233    /// `is_regulated` arm on the closed set with the probe body
1234    /// untouched — the nullary-predicate shape defers every per-
1235    /// variant policy decision to the closed set's own truth table
1236    /// ([`DataClassification::is_regulated`]) rather than duplicating
1237    /// the discriminator sweep here.
1238    ///
1239    /// # Compounding
1240    ///
1241    /// The point-domain require-tag surface in
1242    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1243    /// as a fixed tag `data-regulated` on `POINT_FIXED_TAG_ARMS` —
1244    /// byte-for-byte peer of the sibling `terminating-horizon`,
1245    /// `metric-axes-required`, and `coordination-required` fixed tags
1246    /// on the (parent × derived-nullary-bool) corner. The ephemeral
1247    /// surface publishes the same tag via
1248    /// [`crate::ephemeral::EphemeralSpec::data_is_regulated`], which
1249    /// composes THIS method through
1250    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1251    /// so the two-surface parity contract holds — the operator's
1252    /// `:requires (data-regulated)` audit answers the same question
1253    /// on both surfaces.
1254    ///
1255    /// Future compliance-baseline auto-selectors dispatching on the
1256    /// `(is_regulated, is_restricted)` two-axis projection
1257    /// (documented on [`DataClassification::is_regulated`] itself)
1258    /// read THIS predicate rather than re-deriving from the variant
1259    /// name at each callsite — the classification-data-axis lattice-
1260    /// typed image of the regulated-data question lives at ONE
1261    /// substrate site and every compliance-mode chooser downstream
1262    /// binds through the SAME `data_is_regulated()` shape.
1263    ///
1264    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1265    /// preserves proofs; the derived-nullary-bool predicate body
1266    /// lives at ONE substrate site so every downstream (the
1267    /// `data-regulated` fixed tag in `tatara-check`, future
1268    /// compliance-baseline / regulatory-regime validators, future
1269    /// variant additions on [`DataClassification`]) binds through
1270    /// the SAME `data_is_regulated()` shape rather than restating the
1271    /// `classification.data_classification.is_regulated()` chain at
1272    /// each callsite. THEORY.md §VI.1 — generation over composition;
1273    /// a future [`DataClassification`] variant lands at ONE `ALL`
1274    /// entry + ONE `is_regulated` arm on the closed set and this
1275    /// probe picks it up mechanically.
1276    #[must_use]
1277    pub fn data_is_regulated(&self) -> bool {
1278        self.data_classification.is_regulated()
1279    }
1280
1281    /// Derived-boolean predicate — does this [`Classification`] carry a
1282    /// [`DataClassification`] whose variant projects to `true` under
1283    /// [`DataClassification::is_restricted`]? The ONE substrate primitive
1284    /// that owns the `(Classification) -> bool` derived-nullary-
1285    /// predicate walk shape on the `data_classification` slot for the
1286    /// restricted-data question.
1287    ///
1288    /// # Fifth occupant on the (parent × derived-nullary-bool) corner
1289    ///
1290    /// Peer of [`Self::horizon_terminates`],
1291    /// [`Self::horizon_requires_metric_axes`],
1292    /// [`Self::calm_requires_coordination`], and
1293    /// [`Self::data_is_regulated`] on the workspace-wide (parent ×
1294    /// derived-nullary-bool) corner of the closed-set-driven presence-
1295    /// probe algebra — the SECOND peer threading the classification-
1296    /// data axis after [`Self::data_is_regulated`] opened it, pinning
1297    /// the classification-data axis as a proven-repeatable structural
1298    /// sub-corner across TWO sibling closed-set projections
1299    /// (`DataClassification::is_regulated` / `is_restricted`) rather
1300    /// than a single-projection curiosity. Byte-for-byte structural
1301    /// peer of [`Self::data_is_regulated`]: both walk the SAME
1302    /// direct scalar closed-set field (`self.data_classification`) on
1303    /// the [`Classification`] parent through TWO layers of `Default`
1304    /// short-circuit (`Classification::gate_compute` →
1305    /// [`DataClassification::default = Internal`]) — distinct from the
1306    /// two `horizon_*` peers by ONE structural degree (they walk a
1307    /// NESTED-STRUCT projection with THREE layers of `Default`). THIRD
1308    /// direct-scalar peer on the corner after
1309    /// [`Self::calm_requires_coordination`] opened +
1310    /// [`Self::data_is_regulated`] populated the sub-corner: seals
1311    /// "direct-scalar derived-nullary-bool" as the substrate's third
1312    /// occupant on the sub-corner and the FIRST corner peer whose
1313    /// gate-compute baseline projects to `true` rather than `false`,
1314    /// mirror-image of the `Bounded`-default `terminating-horizon`
1315    /// baseline on the horizon-axis nested sub-corner.
1316    ///
1317    /// # Semantics — derived nullary boolean, not variant equality
1318    ///
1319    /// `data_is_restricted()` returns `true` iff
1320    /// `self.data_classification.is_restricted()`. The six-variant
1321    /// [`DataClassification`] closed set publishes the truth table:
1322    /// [`DataClassification::Public`] → `false` (freely distributable);
1323    /// [`DataClassification::Internal`] / [`DataClassification::Confidential`]
1324    /// / [`DataClassification::Pii`] / [`DataClassification::Phi`] /
1325    /// [`DataClassification::Pci`] → `true` (access controls beyond
1326    /// freely-distributable apply). A [`Classification::gate_compute`]
1327    /// baseline (which uses [`DataClassification::default = Internal`]
1328    /// via `#[default]`) answers `true` — the substrate's default-arm
1329    /// short-circuit propagates through the scalar closed-set field's
1330    /// own [`Default`] impl to this predicate's answer, distinct from
1331    /// [`Self::data_is_regulated`]'s `false` baseline (which projects
1332    /// the SAME `Internal` default through the antisymmetric arm of
1333    /// the closed set's predicate pair). This baseline-flip is the
1334    /// FIRST direct-scalar corner peer where the gate-compute baseline
1335    /// answers `true`, not `false`.
1336    ///
1337    /// The closed-set-internal pin
1338    /// `data_classification_regulated_implies_restricted` seals the
1339    /// implication `is_regulated() ⇒ is_restricted()` on every
1340    /// variant, so `data_is_regulated()` returning `true` implies THIS
1341    /// predicate also returns `true`; the reverse does not hold
1342    /// (`Internal | Confidential` are restricted but not regulated).
1343    /// This is the FIRST substrate-primitive pair on the (parent ×
1344    /// derived-nullary-bool) corner whose two predicates carry a non-
1345    /// trivial closed-set-internal implication relationship — a
1346    /// future compliance-baseline auto-selector can rely on
1347    /// `data_is_regulated() ⇒ data_is_restricted()` by construction
1348    /// rather than restating the implication at every callsite.
1349    ///
1350    /// A future seventh [`DataClassification`] variant (a hypothetical
1351    /// `TradeSecret` bucket for competitive-sensitive data, or an
1352    /// `Anonymized` bucket for pseudonymized-PII whose access posture
1353    /// differs from raw PII) reaches this probe through ONE
1354    /// `is_restricted` arm on the closed set with the probe body
1355    /// untouched — the nullary-predicate shape defers every per-
1356    /// variant policy decision to the closed set's own truth table
1357    /// ([`DataClassification::is_restricted`]) rather than duplicating
1358    /// the discriminator sweep here.
1359    ///
1360    /// # Compounding
1361    ///
1362    /// The point-domain require-tag surface in
1363    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1364    /// as a fixed tag `data-restricted` on `POINT_FIXED_TAG_ARMS` —
1365    /// byte-for-byte peer of the sibling `terminating-horizon`,
1366    /// `metric-axes-required`, `coordination-required`, and
1367    /// `data-regulated` fixed tags on the (parent × derived-nullary-
1368    /// bool) corner. The ephemeral surface publishes the same tag via
1369    /// [`crate::ephemeral::EphemeralSpec::data_is_restricted`], which
1370    /// composes THIS method through
1371    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1372    /// so the two-surface parity contract holds — the operator's
1373    /// `:requires (data-restricted)` audit answers the same question
1374    /// on both surfaces.
1375    ///
1376    /// Future compliance-baseline auto-selectors dispatching on the
1377    /// `(is_regulated, is_restricted)` two-axis projection
1378    /// (documented on [`DataClassification::is_regulated`] itself)
1379    /// read THIS predicate rather than re-deriving from the variant
1380    /// name at each callsite — the classification-data-axis lattice-
1381    /// typed image of the restricted-data question lives at ONE
1382    /// substrate site and every compliance-mode chooser downstream
1383    /// binds through the SAME `data_is_restricted()` shape.
1384    ///
1385    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1386    /// preserves proofs; the derived-nullary-bool predicate body
1387    /// lives at ONE substrate site so every downstream (the
1388    /// `data-restricted` fixed tag in `tatara-check`, future
1389    /// compliance-baseline / access-control-mandatory validators,
1390    /// future variant additions on [`DataClassification`]) binds
1391    /// through the SAME `data_is_restricted()` shape rather than
1392    /// restating the
1393    /// `classification.data_classification.is_restricted()` chain at
1394    /// each callsite. THEORY.md §VI.1 — generation over composition;
1395    /// a future [`DataClassification`] variant lands at ONE `ALL`
1396    /// entry + ONE `is_restricted` arm on the closed set and this
1397    /// probe picks it up mechanically.
1398    #[must_use]
1399    pub fn data_is_restricted(&self) -> bool {
1400        self.data_classification.is_restricted()
1401    }
1402
1403    /// Derived-boolean predicate — does this [`Classification`]'s
1404    /// [`ConvergencePointType`] project to `true` under
1405    /// [`ConvergencePointType::is_endomorphic`]? The ONE substrate
1406    /// primitive that owns the `(Classification) -> bool` derived-
1407    /// nullary-predicate walk shape on the `point_type` slot for the
1408    /// 1→1 topology-bucket question.
1409    ///
1410    /// # Sixth occupant on the (parent × derived-nullary-bool) corner
1411    ///
1412    /// Peer of [`Self::horizon_terminates`],
1413    /// [`Self::horizon_requires_metric_axes`],
1414    /// [`Self::calm_requires_coordination`],
1415    /// [`Self::data_is_regulated`], and [`Self::data_is_restricted`]
1416    /// on the workspace-wide (parent × derived-nullary-bool) corner of
1417    /// the closed-set-driven presence-probe algebra — the SIXTH
1418    /// occupant on the corner and the FIRST peer threading the
1419    /// classification-`point_type` axis rather than the horizon,
1420    /// calm, or data axes. Direct-scalar peer of
1421    /// [`Self::calm_requires_coordination`] /
1422    /// [`Self::data_is_regulated`] / [`Self::data_is_restricted`]:
1423    /// walks a DIRECT scalar closed-set field's derived projection on
1424    /// the [`Classification`] parent (no nested-struct hop like the
1425    /// two `horizon_*` peers), but distinct from all three by ONE
1426    /// structural degree — [`ConvergencePointType`] has NO
1427    /// [`Default`] impl, so the derived-nullary answer here does NOT
1428    /// carry a substrate default-arm short-circuit through the
1429    /// parent's `#[default]` chain. The [`Self::gate_compute`]
1430    /// baseline still fixes an answer (`Gate.is_endomorphic() =
1431    /// false`), pinned by
1432    /// `classification_gate_compute_point_is_endomorphic_is_false`,
1433    /// but that answer is chosen deliberately by the baseline's
1434    /// `point_type: Gate` field rather than reached through a
1435    /// closed-set-side `#[default]`. Populates the corner as a
1436    /// proven-repeatable primitive shape across FOUR distinct
1437    /// classification-axis closed sets ([`HorizonKind`],
1438    /// [`CalmClassification`], [`DataClassification`],
1439    /// [`ConvergencePointType`]) rather than a three-axis curiosity.
1440    ///
1441    /// # Semantics — derived nullary boolean, not variant equality
1442    ///
1443    /// `point_is_endomorphic()` returns `true` iff
1444    /// `self.point_type.is_endomorphic()`. The eight-variant
1445    /// [`ConvergencePointType`] closed set publishes the truth table
1446    /// (via the shape-preserving-topology (1,1) arity partition):
1447    /// [`ConvergencePointType::Transform`] /
1448    /// [`ConvergencePointType::Observe`] → `true` (1→1 shape);
1449    /// [`ConvergencePointType::Fork`] /
1450    /// [`ConvergencePointType::Broadcast`] → `false` (1→N diffusive);
1451    /// [`ConvergencePointType::Join`] / [`ConvergencePointType::Gate`]
1452    /// / [`ConvergencePointType::Select`] /
1453    /// [`ConvergencePointType::Reduce`] → `false` (N→1 convergent).
1454    /// A [`Classification::gate_compute`] baseline (which uses
1455    /// [`ConvergencePointType::Gate`] deliberately as the baseline
1456    /// convergent barrier point) answers `false` — this is NOT a
1457    /// [`Default`]-arm short-circuit (unlike the four earlier
1458    /// direct-scalar / nested-struct corner peers), because
1459    /// [`ConvergencePointType`] has no `impl Default`; the baseline
1460    /// is a chosen field value, not a defaulted one.
1461    ///
1462    /// A future ninth [`ConvergencePointType`] variant lands at ONE
1463    /// `ALL` entry + ONE `is_endomorphic` arm on the closed set with
1464    /// the probe body untouched — the nullary-predicate shape defers
1465    /// every per-variant policy decision to the closed set's own
1466    /// truth table ([`ConvergencePointType::is_endomorphic`]) rather
1467    /// than duplicating the discriminator sweep here.
1468    ///
1469    /// # Compounding
1470    ///
1471    /// The point-domain require-tag surface in
1472    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1473    /// as a fixed tag `endomorphic-point` on
1474    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte peer of the sibling
1475    /// `terminating-horizon` / `metric-axes-required` /
1476    /// `coordination-required` / `data-regulated` / `data-restricted`
1477    /// fixed tags on the (parent × derived-nullary-bool) corner. The
1478    /// ephemeral surface publishes the same tag via
1479    /// [`crate::ephemeral::EphemeralSpec::point_is_endomorphic`],
1480    /// which composes THIS method through
1481    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1482    /// so the two-surface parity contract holds — the operator's
1483    /// `:requires (endomorphic-point)` audit answers the same
1484    /// question on both surfaces. Sibling projections
1485    /// [`ConvergencePointType::is_diffusive`] and
1486    /// [`ConvergencePointType::is_convergent`] compose byte-
1487    /// identically as future seventh + eighth corner occupants; when
1488    /// all three land the three-way partition contract
1489    /// `is_endomorphic ⊕ is_diffusive ⊕ is_convergent` sealed on the
1490    /// closed set by `convergence_point_type_buckets_cover_every_variant`
1491    /// composes through the parent-composed layer as a substrate-
1492    /// wide theorem exactly as the closed-set XOR pair
1493    /// `terminates ^ requires_metric_axes` composes through this
1494    /// corner today.
1495    ///
1496    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1497    /// preserves proofs; the derived-nullary-bool predicate body
1498    /// lives at ONE substrate site so every downstream (the
1499    /// `endomorphic-point` fixed tag in `tatara-check`, future DAG
1500    /// composition / edge-cardinality validators, future variant
1501    /// additions on [`ConvergencePointType`]) binds through the SAME
1502    /// `point_is_endomorphic()` shape rather than restating the
1503    /// `classification.point_type.is_endomorphic()` chain at each
1504    /// callsite. THEORY.md §VI.1 — generation over composition; a
1505    /// future [`ConvergencePointType`] variant lands at ONE `ALL`
1506    /// entry + ONE `is_endomorphic` arm on the closed set and this
1507    /// probe picks it up mechanically.
1508    #[must_use]
1509    pub fn point_is_endomorphic(&self) -> bool {
1510        self.point_type.is_endomorphic()
1511    }
1512
1513    /// Derived-boolean predicate — does this [`Classification`]'s
1514    /// [`ConvergencePointType`] project to `true` under
1515    /// [`ConvergencePointType::is_diffusive`]? The ONE substrate
1516    /// primitive that owns the `(Classification) -> bool` derived-
1517    /// nullary-predicate walk shape on the `point_type` slot for the
1518    /// 1→N fan-out topology-bucket question.
1519    ///
1520    /// # Seventh occupant on the (parent × derived-nullary-bool) corner
1521    ///
1522    /// Peer of [`Self::horizon_terminates`],
1523    /// [`Self::horizon_requires_metric_axes`],
1524    /// [`Self::calm_requires_coordination`],
1525    /// [`Self::data_is_regulated`], [`Self::data_is_restricted`], and
1526    /// [`Self::point_is_endomorphic`] on the workspace-wide (parent ×
1527    /// derived-nullary-bool) corner of the closed-set-driven presence-
1528    /// probe algebra — the SEVENTH occupant on the corner and the
1529    /// SECOND peer threading the classification-`point_type` axis,
1530    /// pinning that axis as a proven-repeatable structural sub-corner
1531    /// across TWO sibling projections rather than a one-off. Direct-
1532    /// scalar peer of [`Self::point_is_endomorphic`]: the two share
1533    /// the SAME parent slot (`self.point_type`), the SAME closed-set
1534    /// carrier ([`ConvergencePointType`]), and the SAME chosen-field
1535    /// baseline discipline ([`ConvergencePointType`] has no
1536    /// [`Default`] impl, so the derived-nullary answer here does NOT
1537    /// carry a substrate default-arm short-circuit through the
1538    /// parent's `#[default]` chain — [`Self::gate_compute`] fixes
1539    /// `point_type: Gate` deliberately, and `Gate.is_diffusive() =
1540    /// false`).
1541    ///
1542    /// # Semantics — derived nullary boolean, disjoint from endomorphic
1543    ///
1544    /// `point_is_diffusive()` returns `true` iff
1545    /// `self.point_type.is_diffusive()`. The eight-variant
1546    /// [`ConvergencePointType`] closed set publishes the truth table
1547    /// (via the (One, Many) arity cell): [`ConvergencePointType::Fork`]
1548    /// / [`ConvergencePointType::Broadcast`] → `true` (1→N fan-out);
1549    /// every other variant → `false` (endomorphic or convergent).
1550    /// A [`Classification::gate_compute`] baseline answers `false`
1551    /// deliberately (Gate is a convergent barrier, not a diffusive
1552    /// fan-out).
1553    ///
1554    /// A future ninth [`ConvergencePointType`] variant lands at ONE
1555    /// `ALL` entry + ONE `is_diffusive` arm on the closed set with the
1556    /// probe body untouched — the nullary-predicate shape defers every
1557    /// per-variant policy decision to the closed set's own truth
1558    /// table ([`ConvergencePointType::is_diffusive`]) rather than
1559    /// duplicating the discriminator sweep here.
1560    ///
1561    /// # Compounding — first corner-peer mutex on the `point_type` axis
1562    ///
1563    /// This is the FIRST corner-peer pair on the `point_type` axis
1564    /// (with [`Self::point_is_endomorphic`]) whose two projections
1565    /// carry a non-trivial closed-set-internal MUTEX relationship
1566    /// (`point_is_endomorphic ⇒ ¬point_is_diffusive` — no variant
1567    /// lands in both buckets, sealed on the closed set by
1568    /// `convergence_point_type_buckets_cover_every_variant`). Distinct
1569    /// from the FIRST corner-peer implication pair on the `data`
1570    /// axis (`data_is_regulated ⇒ data_is_restricted`) by the
1571    /// implication direction — regulated-⇒-restricted has one bucket
1572    /// contained in the other, while endomorphic-vs-diffusive has
1573    /// two disjoint buckets partitioning a common universe. When the
1574    /// third sibling [`Self::point_is_convergent`] lands, the mutex
1575    /// closes into the three-way XOR partition contract
1576    /// `point_is_endomorphic ⊕ point_is_diffusive ⊕
1577    /// point_is_convergent` sealed on the closed set by
1578    /// `convergence_point_type_buckets_cover_every_variant` — a
1579    /// substrate-wide theorem that composes through this corner
1580    /// exactly as the closed-set XOR pair `terminates ^
1581    /// requires_metric_axes` composes today.
1582    ///
1583    /// The point-domain require-tag surface in
1584    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1585    /// as a fixed tag `diffusive-point` on `POINT_FIXED_TAG_ARMS` —
1586    /// byte-for-byte peer of the sibling `endomorphic-point` fixed
1587    /// tag. The ephemeral surface publishes the same tag via
1588    /// [`crate::ephemeral::EphemeralSpec::point_is_diffusive`], which
1589    /// composes THIS method through
1590    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`] so
1591    /// the two-surface parity contract holds — the operator's
1592    /// `:requires (diffusive-point)` audit answers the same question
1593    /// on both surfaces.
1594    ///
1595    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1596    /// preserves proofs; the derived-nullary-bool predicate body
1597    /// lives at ONE substrate site so every downstream (the
1598    /// `diffusive-point` fixed tag in `tatara-check`, future DAG
1599    /// composition / edge-cardinality validators, future variant
1600    /// additions on [`ConvergencePointType`]) binds through the SAME
1601    /// `point_is_diffusive()` shape rather than restating the
1602    /// `classification.point_type.is_diffusive()` chain at each
1603    /// callsite. THEORY.md §VI.1 — generation over composition; a
1604    /// future [`ConvergencePointType`] variant lands at ONE `ALL`
1605    /// entry + ONE `is_diffusive` arm on the closed set and this
1606    /// probe picks it up mechanically.
1607    #[must_use]
1608    pub fn point_is_diffusive(&self) -> bool {
1609        self.point_type.is_diffusive()
1610    }
1611
1612    /// Derived-boolean predicate — does this [`Classification`]'s
1613    /// [`ConvergencePointType`] project to `true` under
1614    /// [`ConvergencePointType::is_convergent`]? The ONE substrate
1615    /// primitive that owns the `(Classification) -> bool` derived-
1616    /// nullary-predicate walk shape on the `point_type` slot for the
1617    /// N→1 fan-in topology-bucket question.
1618    ///
1619    /// # Eighth occupant on the (parent × derived-nullary-bool) corner
1620    ///
1621    /// Peer of [`Self::horizon_terminates`],
1622    /// [`Self::horizon_requires_metric_axes`],
1623    /// [`Self::calm_requires_coordination`],
1624    /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
1625    /// [`Self::point_is_endomorphic`], and [`Self::point_is_diffusive`]
1626    /// on the workspace-wide (parent × derived-nullary-bool) corner of
1627    /// the closed-set-driven presence-probe algebra — the EIGHTH
1628    /// occupant on the corner and the THIRD peer threading the
1629    /// classification-`point_type` axis. Direct-scalar peer of
1630    /// [`Self::point_is_endomorphic`] / [`Self::point_is_diffusive`]:
1631    /// the three share the SAME parent slot (`self.point_type`), the
1632    /// SAME closed-set carrier ([`ConvergencePointType`]), and the
1633    /// SAME chosen-field baseline discipline
1634    /// ([`ConvergencePointType`] has no [`Default`] impl, so the
1635    /// derived-nullary answer here does NOT carry a substrate default-
1636    /// arm short-circuit through the parent's `#[default]` chain).
1637    /// Distinct from the two sibling probes on ONE structural degree
1638    /// — the [`Self::gate_compute`] baseline's `point_type: Gate`
1639    /// answer projects to `true` HERE (`Gate.is_convergent() = true`),
1640    /// mirror-inverted from the two siblings' `false` answers, so
1641    /// this is the FIRST direct-scalar corner peer whose parent-
1642    /// composed gate-compute baseline projects `true` through a
1643    /// chosen-field (rather than defaulted) answer.
1644    ///
1645    /// # Semantics — derived nullary boolean, closes the three-way carving
1646    ///
1647    /// `point_is_convergent()` returns `true` iff
1648    /// `self.point_type.is_convergent()`. The eight-variant
1649    /// [`ConvergencePointType`] closed set publishes the truth table
1650    /// (via the (Many, One) arity cell): [`ConvergencePointType::Join`]
1651    /// / [`ConvergencePointType::Gate`] /
1652    /// [`ConvergencePointType::Select`] / [`ConvergencePointType::Reduce`]
1653    /// → `true` (N→1 fan-in); every other variant → `false`
1654    /// (endomorphic or diffusive). A [`Classification::gate_compute`]
1655    /// baseline answers `true` deliberately (Gate is the canonical
1656    /// convergent barrier point of the workspace baseline).
1657    ///
1658    /// A future ninth [`ConvergencePointType`] variant lands at ONE
1659    /// `ALL` entry + ONE `is_convergent` arm on the closed set with
1660    /// the probe body untouched — the nullary-predicate shape defers
1661    /// every per-variant policy decision to the closed set's own truth
1662    /// table ([`ConvergencePointType::is_convergent`]) rather than
1663    /// duplicating the discriminator sweep here.
1664    ///
1665    /// # Compounding — closes the three-way XOR partition on the `point_type` axis
1666    ///
1667    /// This is the THIRD sibling on the `point_type` axis closing the
1668    /// mutex pair [`Self::point_is_endomorphic`] /
1669    /// [`Self::point_is_diffusive`] (which sealed
1670    /// `point_is_endomorphic ⇒ ¬point_is_diffusive`) into the FULL
1671    /// three-way XOR partition contract
1672    /// `point_is_endomorphic ⊕ point_is_diffusive ⊕
1673    /// point_is_convergent = true` for every
1674    /// [`ConvergencePointType`] variant. Sealed on the closed set by
1675    /// `convergence_point_type_buckets_cover_every_variant` (which
1676    /// pins each variant lands in EXACTLY ONE bucket) and now
1677    /// composed through the parent-composed layer as a substrate-wide
1678    /// theorem. THREE-way XOR is a stricter contract than the closed-
1679    /// set XOR pair `terminates ^ requires_metric_axes` that composes
1680    /// through this corner today via the two `horizon_*` peers — this
1681    /// axis carries a partition of THREE non-empty buckets rather
1682    /// than TWO, so the ternary XOR is the natural generalization
1683    /// composed through the corner.
1684    ///
1685    /// The point-domain require-tag surface in
1686    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1687    /// as a fixed tag `convergent-point` on `POINT_FIXED_TAG_ARMS` —
1688    /// byte-for-byte peer of the sibling `endomorphic-point` /
1689    /// `diffusive-point` fixed tags. The ephemeral surface publishes
1690    /// the same tag via
1691    /// [`crate::ephemeral::EphemeralSpec::point_is_convergent`], which
1692    /// composes THIS method through
1693    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`] so
1694    /// the two-surface parity contract holds — the operator's
1695    /// `:requires (convergent-point)` audit answers the same question
1696    /// on both surfaces.
1697    ///
1698    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1699    /// preserves proofs; the derived-nullary-bool predicate body
1700    /// lives at ONE substrate site so every downstream (the
1701    /// `convergent-point` fixed tag in `tatara-check`, future DAG
1702    /// composition / edge-cardinality validators, future variant
1703    /// additions on [`ConvergencePointType`]) binds through the SAME
1704    /// `point_is_convergent()` shape rather than restating the
1705    /// `classification.point_type.is_convergent()` chain at each
1706    /// callsite. THEORY.md §VI.1 — generation over composition; a
1707    /// future [`ConvergencePointType`] variant lands at ONE `ALL`
1708    /// entry + ONE `is_convergent` arm on the closed set and this
1709    /// probe picks it up mechanically.
1710    #[must_use]
1711    pub fn point_is_convergent(&self) -> bool {
1712        self.point_type.is_convergent()
1713    }
1714
1715    /// Derived-boolean predicate — does this [`Classification`]'s
1716    /// [`SubstrateType`] project to `true` under
1717    /// [`SubstrateType::is_resource`]? The ONE substrate primitive
1718    /// that owns the `(Classification) -> bool` derived-nullary-
1719    /// predicate walk shape on the `substrate` slot for the
1720    /// resource-plane bucket question.
1721    ///
1722    /// # Ninth occupant on the (parent × derived-nullary-bool) corner
1723    ///
1724    /// Peer of [`Self::horizon_terminates`],
1725    /// [`Self::horizon_requires_metric_axes`],
1726    /// [`Self::calm_requires_coordination`],
1727    /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
1728    /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
1729    /// and [`Self::point_is_convergent`] on the workspace-wide
1730    /// (parent × derived-nullary-bool) corner of the closed-set-
1731    /// driven presence-probe algebra — the NINTH occupant on the
1732    /// corner and the FIRST peer threading the classification-
1733    /// `substrate` axis (the fourth of six classification axes,
1734    /// after `horizon`, `calm`, `data_classification`, and
1735    /// `point_type`). Direct-scalar peer of
1736    /// [`Self::point_is_endomorphic`] /
1737    /// [`Self::point_is_diffusive`] /
1738    /// [`Self::point_is_convergent`]: all four share the shape
1739    /// (direct scalar closed-set field with no [`Default`] impl on
1740    /// the child, so no default-arm short-circuit through the
1741    /// child's `#[default]` chain). Distinct from the three
1742    /// `point_type`-axis siblings on the parent slot walked
1743    /// (`self.substrate` vs `self.point_type`) and on the closed set
1744    /// carried ([`SubstrateType`] vs [`ConvergencePointType`]) — the
1745    /// [`Classification::gate_compute`] baseline's chosen field
1746    /// (`substrate: Compute`) projects `true` HERE
1747    /// (`Compute.is_resource() = true`), mirror-aligned with the
1748    /// [`Self::point_is_convergent`] sibling's `true`-on-baseline
1749    /// answer and mirror-inverted from the two other `point_type`
1750    /// peers.
1751    ///
1752    /// # Semantics — derived nullary boolean over the closed-set plane
1753    ///
1754    /// `substrate_is_resource()` returns `true` iff
1755    /// `self.substrate.is_resource()`. The eight-variant
1756    /// [`SubstrateType`] closed set publishes the truth table (via
1757    /// the plane partition):
1758    /// [`SubstrateType::Financial`] / [`SubstrateType::Compute`] /
1759    /// [`SubstrateType::Network`] / [`SubstrateType::Storage`] →
1760    /// `true` (resource plane — you allocate budgets from it);
1761    /// [`SubstrateType::Security`] / [`SubstrateType::Identity`] /
1762    /// [`SubstrateType::Observability`] /
1763    /// [`SubstrateType::Regulatory`] → `false` (policy or telemetry
1764    /// plane). A [`Classification::gate_compute`] baseline answers
1765    /// `true` because its `substrate: Compute` field is deliberately
1766    /// resource-plane.
1767    ///
1768    /// A future ninth [`SubstrateType`] variant lands at ONE `ALL`
1769    /// entry + ONE `is_resource` arm on the closed set with the
1770    /// probe body untouched — the nullary-predicate shape defers
1771    /// every per-variant policy decision to the closed set's own
1772    /// truth table ([`SubstrateType::is_resource`]) rather than
1773    /// duplicating the discriminator sweep here.
1774    ///
1775    /// # Compounding — first substrate-axis peer, opens the three-way plane partition
1776    ///
1777    /// The point-domain require-tag surface in
1778    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1779    /// as a fixed tag `resource-substrate` on
1780    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte structural peer of the
1781    /// sibling `terminating-horizon` / `metric-axes-required` /
1782    /// `coordination-required` / `data-regulated` / `data-restricted`
1783    /// / `endomorphic-point` / `diffusive-point` / `convergent-point`
1784    /// fixed tags on the (parent × derived-nullary-bool) corner. The
1785    /// ephemeral surface publishes the same tag via
1786    /// [`crate::ephemeral::EphemeralSpec::substrate_is_resource`],
1787    /// which composes THIS method through
1788    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1789    /// so the two-surface parity contract holds — the operator's
1790    /// `:requires (resource-substrate)` audit answers the same
1791    /// question on both surfaces. Sibling projections
1792    /// [`SubstrateType::is_policy`] and
1793    /// [`SubstrateType::is_telemetry`] compose byte-identically as
1794    /// future tenth + eleventh corner occupants; when all three land
1795    /// the three-way partition contract
1796    /// `is_resource ⊕ is_policy ⊕ is_telemetry` sealed on the closed
1797    /// set by `substrate_type_buckets_cover_every_variant` composes
1798    /// through the parent-composed layer as a substrate-wide theorem
1799    /// — the exact ternary lift already sealed on the sibling
1800    /// `point_type` axis by
1801    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`.
1802    ///
1803    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1804    /// preserves proofs; the derived-nullary-bool predicate body
1805    /// lives at ONE substrate site so every downstream (the
1806    /// `resource-substrate` fixed tag in `tatara-check`, future
1807    /// plane-baseline / compliance-baseline selectors, future
1808    /// variant additions on [`SubstrateType`]) binds through the
1809    /// SAME `substrate_is_resource()` shape rather than restating
1810    /// the `classification.substrate.is_resource()` chain at each
1811    /// callsite. THEORY.md §VI.1 — generation over composition; a
1812    /// future [`SubstrateType`] variant lands at ONE `ALL` entry +
1813    /// ONE `is_resource` arm on the closed set and this probe picks
1814    /// it up mechanically.
1815    #[must_use]
1816    pub fn substrate_is_resource(&self) -> bool {
1817        self.substrate.is_resource()
1818    }
1819
1820    /// Derived-boolean predicate — does this [`Classification`]'s
1821    /// [`SubstrateType`] project to `true` under
1822    /// [`SubstrateType::is_policy`]? The ONE substrate primitive
1823    /// that owns the `(Classification) -> bool` derived-nullary-
1824    /// predicate walk shape on the `substrate` slot for the
1825    /// policy-plane bucket question.
1826    ///
1827    /// # Tenth occupant on the (parent × derived-nullary-bool) corner
1828    ///
1829    /// Peer of [`Self::horizon_terminates`],
1830    /// [`Self::horizon_requires_metric_axes`],
1831    /// [`Self::calm_requires_coordination`],
1832    /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
1833    /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
1834    /// [`Self::point_is_convergent`], and
1835    /// [`Self::substrate_is_resource`] on the workspace-wide
1836    /// (parent × derived-nullary-bool) corner of the closed-set-
1837    /// driven presence-probe algebra — the TENTH occupant on the
1838    /// corner and the SECOND peer threading the classification-
1839    /// `substrate` axis, promoting that axis from a proven-repeatable
1840    /// one-off (`substrate_is_resource` alone) to a proven-repeatable
1841    /// pair. FIRST corner-peer pair on the `substrate` axis whose
1842    /// two projections carry a non-trivial closed-set-internal
1843    /// MUTEX relationship (`substrate_is_resource ⇒ ¬substrate_is_policy`
1844    /// — the eight-variant [`SubstrateType`] closed set carves its
1845    /// variants into THREE disjoint buckets sealed by
1846    /// `substrate_type_buckets_cover_every_variant`), structural
1847    /// twin of the sibling `point_type`-axis MUTEX pair sealed by
1848    /// `classification_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`.
1849    /// Direct-scalar peer of [`Self::substrate_is_resource`] and the
1850    /// three sibling `point_type`-axis arms: all five share the
1851    /// shape (direct scalar closed-set field with no [`Default`]
1852    /// impl on the child, so no default-arm short-circuit through
1853    /// the child's `#[default]` chain). The
1854    /// [`Classification::gate_compute`] baseline's chosen field
1855    /// (`substrate: Compute`) projects `false` HERE
1856    /// (`Compute.is_policy() = false`), mirror-inverted from the
1857    /// sibling `substrate_is_resource` baseline's `true`.
1858    ///
1859    /// # Semantics — derived nullary boolean over the closed-set plane
1860    ///
1861    /// `substrate_is_policy()` returns `true` iff
1862    /// `self.substrate.is_policy()`. The eight-variant
1863    /// [`SubstrateType`] closed set publishes the truth table (via
1864    /// the plane partition):
1865    /// [`SubstrateType::Security`] / [`SubstrateType::Identity`] /
1866    /// [`SubstrateType::Regulatory`] → `true` (policy plane — you
1867    /// enforce constraints on it); [`SubstrateType::Financial`] /
1868    /// [`SubstrateType::Compute`] / [`SubstrateType::Network`] /
1869    /// [`SubstrateType::Storage`] / [`SubstrateType::Observability`]
1870    /// → `false` (resource or telemetry plane). A
1871    /// [`Classification::gate_compute`] baseline answers `false`
1872    /// because its `substrate: Compute` field is deliberately
1873    /// resource-plane, not policy-plane.
1874    ///
1875    /// A future ninth [`SubstrateType`] variant lands at ONE `ALL`
1876    /// entry + ONE `is_policy` arm on the closed set with the
1877    /// probe body untouched — the nullary-predicate shape defers
1878    /// every per-variant policy decision to the closed set's own
1879    /// truth table ([`SubstrateType::is_policy`]) rather than
1880    /// duplicating the discriminator sweep here.
1881    ///
1882    /// # Compounding — second substrate-axis peer, opens the substrate MUTEX pair
1883    ///
1884    /// The point-domain require-tag surface in
1885    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1886    /// as a fixed tag `policy-substrate` on
1887    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte structural peer of the
1888    /// sibling `resource-substrate` / `terminating-horizon` /
1889    /// `metric-axes-required` / `coordination-required` /
1890    /// `data-regulated` / `data-restricted` / `endomorphic-point` /
1891    /// `diffusive-point` / `convergent-point` fixed tags on the
1892    /// (parent × derived-nullary-bool) corner. The ephemeral surface
1893    /// publishes the same tag via
1894    /// [`crate::ephemeral::EphemeralSpec::substrate_is_policy`],
1895    /// which composes THIS method through
1896    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
1897    /// so the two-surface parity contract holds — the operator's
1898    /// `:requires (policy-substrate)` audit answers the same
1899    /// question on both surfaces. Sibling projection
1900    /// [`SubstrateType::is_telemetry`] composes byte-identically as
1901    /// a future eleventh corner occupant; when it lands the
1902    /// three-way partition contract
1903    /// `is_resource ⊕ is_policy ⊕ is_telemetry` sealed on the closed
1904    /// set by `substrate_type_buckets_cover_every_variant` composes
1905    /// through the parent-composed layer as a substrate-wide theorem
1906    /// — the exact ternary lift already sealed on the sibling
1907    /// `point_type` axis by
1908    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`.
1909    ///
1910    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
1911    /// preserves proofs; the derived-nullary-bool predicate body
1912    /// lives at ONE substrate site so every downstream (the
1913    /// `policy-substrate` fixed tag in `tatara-check`, future
1914    /// plane-baseline / compliance-baseline selectors, future
1915    /// variant additions on [`SubstrateType`]) binds through the
1916    /// SAME `substrate_is_policy()` shape rather than restating
1917    /// the `classification.substrate.is_policy()` chain at each
1918    /// callsite. THEORY.md §VI.1 — generation over composition; a
1919    /// future [`SubstrateType`] variant lands at ONE `ALL` entry +
1920    /// ONE `is_policy` arm on the closed set and this probe picks
1921    /// it up mechanically.
1922    #[must_use]
1923    pub fn substrate_is_policy(&self) -> bool {
1924        self.substrate.is_policy()
1925    }
1926
1927    /// Derived-boolean predicate — does this [`Classification`]'s
1928    /// [`SubstrateType`] project to `true` under
1929    /// [`SubstrateType::is_telemetry`]? The ONE substrate primitive
1930    /// that owns the `(Classification) -> bool` derived-nullary-
1931    /// predicate walk shape on the `substrate` slot for the
1932    /// telemetry-plane bucket question.
1933    ///
1934    /// # Eleventh occupant on the (parent × derived-nullary-bool) corner — CLOSES the substrate axis
1935    ///
1936    /// Peer of [`Self::horizon_terminates`],
1937    /// [`Self::horizon_requires_metric_axes`],
1938    /// [`Self::calm_requires_coordination`],
1939    /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
1940    /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
1941    /// [`Self::point_is_convergent`], [`Self::substrate_is_resource`],
1942    /// and [`Self::substrate_is_policy`] on the workspace-wide
1943    /// (parent × derived-nullary-bool) corner of the closed-set-
1944    /// driven presence-probe algebra — the ELEVENTH occupant on the
1945    /// corner and the THIRD peer threading the classification-
1946    /// `substrate` axis. This peer CLOSES the substrate axis on the
1947    /// corner into the FULL three-way XOR partition contract
1948    /// `substrate_is_resource ⊕ substrate_is_policy ⊕
1949    /// substrate_is_telemetry` — the closed-set partition already
1950    /// sealed on [`SubstrateType`] by
1951    /// `substrate_type_buckets_cover_every_variant` now composes
1952    /// through the parent-composed layer as a substrate-wide theorem
1953    /// pinned by
1954    /// `classification_substrate_probes_form_three_way_xor_partition_over_all`.
1955    /// The ternary lift on the substrate axis is the structural
1956    /// twin of the sibling `point_type`-axis ternary lift sealed by
1957    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`.
1958    /// Direct-scalar peer of [`Self::substrate_is_resource`],
1959    /// [`Self::substrate_is_policy`], and the three sibling
1960    /// `point_type`-axis arms: all six share the shape (direct scalar
1961    /// closed-set field with no [`Default`] impl on the child, so no
1962    /// default-arm short-circuit through the child's `#[default]`
1963    /// chain). The [`Classification::gate_compute`] baseline's chosen
1964    /// field (`substrate: Compute`) projects `false` HERE
1965    /// (`Compute.is_telemetry() = false`), mirror-inverted from the
1966    /// sibling `substrate_is_resource` baseline's `true` and aligned
1967    /// with the sibling `substrate_is_policy` baseline's `false`.
1968    ///
1969    /// # Semantics — derived nullary boolean over the closed-set plane
1970    ///
1971    /// `substrate_is_telemetry()` returns `true` iff
1972    /// `self.substrate.is_telemetry()`. The eight-variant
1973    /// [`SubstrateType`] closed set publishes the truth table (via
1974    /// the plane partition): [`SubstrateType::Observability`] →
1975    /// `true` (telemetry plane — the singleton bucket that passively
1976    /// observes other workloads without carrying their payload or
1977    /// gating their access); every other variant → `false`
1978    /// (resource or policy plane). A [`Classification::gate_compute`]
1979    /// baseline answers `false` because its `substrate: Compute`
1980    /// field is deliberately resource-plane, not telemetry-plane.
1981    ///
1982    /// A future ninth [`SubstrateType`] variant lands at ONE `ALL`
1983    /// entry + ONE `is_telemetry` arm on the closed set with the
1984    /// probe body untouched — the nullary-predicate shape defers
1985    /// every per-variant telemetry decision to the closed set's own
1986    /// truth table ([`SubstrateType::is_telemetry`]) rather than
1987    /// duplicating the discriminator sweep here.
1988    ///
1989    /// # Compounding — CLOSES the substrate axis into a three-way XOR partition
1990    ///
1991    /// The point-domain require-tag surface in
1992    /// `tatara-reconciler::bin::tatara-check` composes this primitive
1993    /// as a fixed tag `telemetry-substrate` on
1994    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte structural peer of the
1995    /// sibling `resource-substrate` / `policy-substrate` /
1996    /// `terminating-horizon` / `metric-axes-required` /
1997    /// `coordination-required` / `data-regulated` / `data-restricted`
1998    /// / `endomorphic-point` / `diffusive-point` / `convergent-point`
1999    /// fixed tags on the (parent × derived-nullary-bool) corner. The
2000    /// ephemeral surface publishes the same tag via
2001    /// [`crate::ephemeral::EphemeralSpec::substrate_is_telemetry`],
2002    /// which composes THIS method through
2003    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
2004    /// so the two-surface parity contract holds — the operator's
2005    /// `:requires (telemetry-substrate)` audit answers the same
2006    /// question on both surfaces. THIRD substrate-axis peer CLOSES
2007    /// the three-way XOR partition contract
2008    /// `is_resource ⊕ is_policy ⊕ is_telemetry` sealed on the closed
2009    /// set by `substrate_type_buckets_cover_every_variant` through
2010    /// the parent-composed layer as a substrate-wide theorem — the
2011    /// exact ternary lift already sealed on the sibling `point_type`
2012    /// axis by
2013    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`.
2014    ///
2015    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2016    /// preserves proofs; the derived-nullary-bool predicate body
2017    /// lives at ONE substrate site so every downstream (the
2018    /// `telemetry-substrate` fixed tag in `tatara-check`, future
2019    /// plane-baseline / compliance-baseline selectors, future
2020    /// variant additions on [`SubstrateType`]) binds through the
2021    /// SAME `substrate_is_telemetry()` shape rather than restating
2022    /// the `classification.substrate.is_telemetry()` chain at each
2023    /// callsite. THEORY.md §VI.1 — generation over composition; a
2024    /// future [`SubstrateType`] variant lands at ONE `ALL` entry +
2025    /// ONE `is_telemetry` arm on the closed set and this probe picks
2026    /// it up mechanically.
2027    #[must_use]
2028    pub fn substrate_is_telemetry(&self) -> bool {
2029        self.substrate.is_telemetry()
2030    }
2031
2032    /// Derived-boolean predicate — does this [`Classification`]'s
2033    /// [`CalmClassification`] project to `true` under
2034    /// [`CalmClassification::is_monotone`]? The ONE substrate
2035    /// primitive that owns the `(Classification) -> bool` derived-
2036    /// nullary-predicate walk shape on the `calm` slot for the
2037    /// CALM-monotone-plane question — the positive framing peer of
2038    /// [`Self::calm_requires_coordination`].
2039    ///
2040    /// # Twelfth occupant on the (parent × derived-nullary-bool) corner — CLOSES the calm axis
2041    ///
2042    /// Peer of [`Self::horizon_terminates`],
2043    /// [`Self::horizon_requires_metric_axes`],
2044    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2045    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2046    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2047    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2048    /// and [`Self::substrate_is_telemetry`] on the workspace-wide
2049    /// (parent × derived-nullary-bool) corner of the closed-set-driven
2050    /// presence-probe algebra — the TWELFTH occupant on the corner and
2051    /// the SECOND peer threading the classification-`calm` axis. This
2052    /// peer CLOSES the calm axis on the corner into the FULL binary
2053    /// XOR partition contract `calm_is_monotone ⊕
2054    /// calm_requires_coordination` — the closed-set partition sealed
2055    /// on [`CalmClassification`] by
2056    /// `calm_classification_monotone_xor_requires_coordination` now
2057    /// composes through the parent-composed layer as a substrate-wide
2058    /// theorem pinned by
2059    /// `classification_calm_probes_form_binary_xor_partition_over_all`.
2060    /// Structural twin of the sibling horizon-axis binary XOR
2061    /// partition sealed on the closed set by
2062    /// `horizon_kind_terminate_xor_requires_metric_axes` (which
2063    /// composes at the closed-set layer today — the parent-composed
2064    /// lift lands here as the calm axis's counterpart). The calm axis
2065    /// becomes the THIRD classification axis (after `point_type`,
2066    /// `substrate`) to reach the closed XOR partition landmark on
2067    /// this corner, promoting the axis-closure milestone from a
2068    /// twin (ternary on `point_type` + `substrate`) to a triple
2069    /// (adding binary on `calm`). Direct-scalar peer of
2070    /// [`Self::calm_requires_coordination`]: both walk the same
2071    /// scalar `calm` slot on the parent — TWO layers of `Default`
2072    /// short-circuit reaching the derived-nullary predicate
2073    /// ([`Classification::gate_compute`] → [`CalmClassification::default`]).
2074    /// The [`Classification::gate_compute`] baseline's default-arm
2075    /// answer projects `true` HERE (Monotone default →
2076    /// `is_monotone() = true`), mirror-inverted from
2077    /// [`Self::calm_requires_coordination`]'s Monotone-default `false`.
2078    ///
2079    /// # Semantics — derived nullary boolean over the closed-set plane
2080    ///
2081    /// `calm_is_monotone()` returns `true` iff
2082    /// `self.calm.is_monotone()`. The two-variant
2083    /// [`CalmClassification`] closed set publishes the truth table:
2084    /// [`CalmClassification::Monotone`] → `true` (CALM ⇒ can be
2085    /// distributed without coordination); [`CalmClassification::NonMonotone`]
2086    /// → `false` (CALM ⇒ requires coordination). A
2087    /// [`Classification::gate_compute`] baseline answers `true`
2088    /// because its `calm: CalmClassification::default() = Monotone`
2089    /// field defaults via [`CalmClassification`]'s `#[default]`, so
2090    /// every unadorned Process reads as gossip-eligible (safe under
2091    /// the CALM theorem: monotone operations distribute without
2092    /// coordination).
2093    ///
2094    /// A future third [`CalmClassification`] variant (a hypothetical
2095    /// `ConditionallyMonotone` sentinel for CRDT joins under a fixed
2096    /// schema) lands at ONE `ALL` entry + ONE `is_monotone` arm on
2097    /// the closed set with the probe body untouched — the nullary-
2098    /// predicate shape defers every per-variant monotonicity decision
2099    /// to the closed set's own truth table
2100    /// ([`CalmClassification::is_monotone`]) rather than duplicating
2101    /// the discriminator sweep here.
2102    ///
2103    /// # Compounding — CLOSES the calm axis into a binary XOR partition
2104    ///
2105    /// The point-domain require-tag surface in
2106    /// `tatara-reconciler::bin::tatara-check` composes this primitive
2107    /// as a fixed tag `monotone-calm` on `POINT_FIXED_TAG_ARMS` —
2108    /// byte-for-byte structural peer of the sibling
2109    /// `coordination-required` fixed tag (the antisymmetric partner
2110    /// on the same axis) and of every other `(parent × derived-
2111    /// nullary-bool)` corner arm. The ephemeral surface publishes the
2112    /// same tag via
2113    /// [`crate::ephemeral::EphemeralSpec::calm_is_monotone`], which
2114    /// composes THIS method through
2115    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
2116    /// so the two-surface parity contract holds — the operator's
2117    /// `:requires (monotone-calm)` audit answers the same question on
2118    /// both surfaces. SECOND calm-axis peer CLOSES the binary XOR
2119    /// partition contract `is_monotone ⊕ requires_coordination`
2120    /// sealed on the closed set by
2121    /// `calm_classification_monotone_xor_requires_coordination`
2122    /// through the parent-composed layer as a substrate-wide theorem
2123    /// — the exact binary lift already sealed on the sibling
2124    /// `horizon` axis at the closed-set layer by
2125    /// `horizon_kind_terminate_xor_requires_metric_axes`, now with
2126    /// the parent-composed layer's own XOR partition test on the
2127    /// calm axis.
2128    ///
2129    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2130    /// preserves proofs; the derived-nullary-bool predicate body
2131    /// lives at ONE substrate site so every downstream (the
2132    /// `monotone-calm` fixed tag in `tatara-check`, future scheduler
2133    /// / coordination-mode validators reading the positive CALM
2134    /// framing, future variant additions on [`CalmClassification`])
2135    /// binds through the SAME `calm_is_monotone()` shape rather than
2136    /// restating either `!self.calm_requires_coordination()` or
2137    /// `self.calm.is_monotone()` at the callsite. THEORY.md §VI.1 —
2138    /// generation over composition; a future [`CalmClassification`]
2139    /// variant lands at ONE `ALL` entry + ONE `is_monotone` arm on
2140    /// the closed set and this probe picks it up mechanically.
2141    #[must_use]
2142    pub fn calm_is_monotone(&self) -> bool {
2143        self.calm.is_monotone()
2144    }
2145
2146    /// Derived-boolean predicate — does this [`Classification`]'s
2147    /// [`DataClassification`] project to `true` under
2148    /// [`DataClassification::is_public`]? The ONE substrate primitive
2149    /// that owns the `(Classification) -> bool` derived-nullary-
2150    /// predicate walk shape on the `data_classification` slot for the
2151    /// freely-distributable-data question — the positive framing peer
2152    /// of [`Self::data_is_restricted`].
2153    ///
2154    /// # Thirteenth occupant on the (parent × derived-nullary-bool) corner — CLOSES the data axis
2155    ///
2156    /// Peer of [`Self::horizon_terminates`],
2157    /// [`Self::horizon_requires_metric_axes`],
2158    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2159    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2160    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2161    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2162    /// [`Self::substrate_is_telemetry`], and [`Self::calm_is_monotone`]
2163    /// on the workspace-wide (parent × derived-nullary-bool) corner of
2164    /// the closed-set-driven presence-probe algebra — the THIRTEENTH
2165    /// occupant on the corner and the THIRD peer threading the
2166    /// classification-`data_classification` axis. This peer CLOSES
2167    /// the data axis on the corner into the FULL binary XOR partition
2168    /// contract `data_is_public ⊕ data_is_restricted` — the closed-set
2169    /// partition sealed on [`DataClassification`] by
2170    /// `data_classification_public_xor_restricted` now composes
2171    /// through the parent-composed layer as a substrate-wide theorem
2172    /// pinned by
2173    /// `classification_data_probes_form_binary_xor_partition_over_all`.
2174    /// Structural twin of the calm-axis binary XOR partition sealed at
2175    /// the parent-composed layer by
2176    /// `classification_calm_probes_form_binary_xor_partition_over_all`
2177    /// on the sibling `calm` axis — both axes carve into a `is_X /
2178    /// requires_X` (positive/negative-framing) complementary bucket
2179    /// pair whose union covers every closed-set variant. The data axis
2180    /// becomes the FOURTH classification axis (after `point_type`,
2181    /// `substrate`, `calm`) to reach the closed XOR partition landmark
2182    /// on this corner, promoting the axis-closure milestone from a
2183    /// proven-repeatable triple (ternary on `point_type` + `substrate`
2184    /// plus binary on `calm`) to a proven-repeatable quadruple (adding
2185    /// a SECOND binary on `data_classification`). Direct-scalar peer
2186    /// of [`Self::data_is_regulated`] and [`Self::data_is_restricted`]:
2187    /// all three walk the same scalar `data_classification` slot on the
2188    /// parent — TWO layers of `Default` short-circuit reaching the
2189    /// derived-nullary predicate ([`Classification::gate_compute`] →
2190    /// [`DataClassification::default`]). The
2191    /// [`Classification::gate_compute`] baseline's default-arm answer
2192    /// projects `false` HERE (Internal default →
2193    /// `is_public() = false`), mirror-inverted from
2194    /// [`Self::data_is_restricted`]'s Internal-default `true` on the
2195    /// SAME defaulted `data_classification` slot.
2196    ///
2197    /// # Semantics — derived nullary boolean over the closed-set plane
2198    ///
2199    /// `data_is_public()` returns `true` iff
2200    /// `self.data_classification.is_public()`. The six-variant
2201    /// [`DataClassification`] closed set publishes the truth table:
2202    /// [`DataClassification::Public`] → `true` (freely distributable —
2203    /// no access control required); [`DataClassification::Internal`] /
2204    /// [`DataClassification::Confidential`] / [`DataClassification::Pii`]
2205    /// / [`DataClassification::Phi`] / [`DataClassification::Pci`] →
2206    /// `false` (some access-control regime applies). A
2207    /// [`Classification::gate_compute`] baseline answers `false`
2208    /// because its `data_classification:
2209    /// DataClassification::default() = Internal` field defaults via
2210    /// [`DataClassification`]'s `#[default]`, so every unadorned
2211    /// Process reads as access-controlled (safe under the compliance
2212    /// baseline: an operator must deliberately opt into public
2213    /// distribution).
2214    ///
2215    /// The closed-set-internal pin
2216    /// `data_classification_regulated_implies_not_public` seals the
2217    /// implication `is_regulated() ⇒ ¬is_public()` on every variant, so
2218    /// [`Self::data_is_regulated`] returning `true` implies THIS
2219    /// predicate returns `false`; this is the ANTISYMMETRIC pair to
2220    /// the sibling `data_classification_regulated_implies_restricted`
2221    /// on the same closed set, and the FIRST substrate-primitive pair
2222    /// on the (parent × derived-nullary-bool) corner whose two
2223    /// predicates project ONE closed set into the pair of
2224    /// complementary buckets whose union is a full binary XOR
2225    /// partition AND whose intersection is empty on every variant.
2226    ///
2227    /// A future seventh [`DataClassification`] variant (a hypothetical
2228    /// `TradeSecret` bucket for competitive-sensitive data, or an
2229    /// `Anonymized` bucket for pseudonymized-PII whose regulatory
2230    /// posture differs from raw PII) reaches this probe through ONE
2231    /// `is_public` arm on the closed set with the probe body untouched
2232    /// — the nullary-predicate shape defers every per-variant policy
2233    /// decision to the closed set's own truth table
2234    /// ([`DataClassification::is_public`]) rather than duplicating the
2235    /// discriminator sweep here.
2236    ///
2237    /// # Compounding — CLOSES the data axis into a binary XOR partition
2238    ///
2239    /// The point-domain require-tag surface in
2240    /// `tatara-reconciler::bin::tatara-check` composes this primitive
2241    /// as a fixed tag `public-data` on `POINT_FIXED_TAG_ARMS` —
2242    /// byte-for-byte structural peer of the sibling `data-restricted`
2243    /// fixed tag (the antisymmetric partner on the same axis) and of
2244    /// every other `(parent × derived-nullary-bool)` corner arm. The
2245    /// ephemeral surface publishes the same tag via
2246    /// [`crate::ephemeral::EphemeralSpec::data_is_public`], which
2247    /// composes THIS method through
2248    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
2249    /// so the two-surface parity contract holds — the operator's
2250    /// `:requires (public-data)` audit answers the same question on
2251    /// both surfaces. THIRD data-axis peer CLOSES the binary XOR
2252    /// partition contract `is_public ⊕ is_restricted` sealed on the
2253    /// closed set by `data_classification_public_xor_restricted`
2254    /// through the parent-composed layer as a substrate-wide theorem
2255    /// — mirror of the calm axis's parent-composed binary XOR closure
2256    /// `classification_calm_probes_form_binary_xor_partition_over_all`.
2257    ///
2258    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2259    /// preserves proofs; the derived-nullary-bool predicate body
2260    /// lives at ONE substrate site so every downstream (the
2261    /// `public-data` fixed tag in `tatara-check`, future compliance-
2262    /// baseline / audit-log-optional validators reading the positive
2263    /// distribution framing, future variant additions on
2264    /// [`DataClassification`]) binds through the SAME
2265    /// `data_is_public()` shape rather than restating either
2266    /// `!self.data_is_restricted()` or `self.data_classification.is_public()`
2267    /// at the callsite. THEORY.md §VI.1 — generation over composition;
2268    /// a future [`DataClassification`] variant lands at ONE `ALL`
2269    /// entry + ONE `is_public` arm on the closed set and this probe
2270    /// picks it up mechanically.
2271    #[must_use]
2272    pub fn data_is_public(&self) -> bool {
2273        self.data_classification.is_public()
2274    }
2275
2276    /// Derived-boolean predicate — does this [`Classification`]'s
2277    /// [`Horizon::direction`] slot (defaulted through
2278    /// [`OptimizationDirection::default = Minimize`] on absence) project
2279    /// to `true` under [`OptimizationDirection::prefers_lower`]? The ONE
2280    /// substrate primitive that owns the `(Classification) -> bool`
2281    /// derived-nullary-predicate walk on the `horizon.direction` slot
2282    /// for the lower-is-better optimization-polarity question.
2283    ///
2284    /// # Fourteenth occupant on the (parent × derived-nullary-bool) corner — first via the optimization-direction axis
2285    ///
2286    /// Peer of the thirteen prior nullary-bool substrate primitives on
2287    /// [`Classification`] ([`Self::horizon_terminates`],
2288    /// [`Self::horizon_requires_metric_axes`],
2289    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2290    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2291    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2292    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2293    /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
2294    /// [`Self::data_is_public`]) on the workspace-wide (parent ×
2295    /// derived-nullary-bool) corner of the closed-set-driven presence-
2296    /// probe algebra. FIRST occupant threading the classification-
2297    /// `horizon.direction` axis — opens the SIXTH classification axis
2298    /// into the fixed-tag algebra after the horizon, calm, data, point,
2299    /// and substrate axes; distinct from every prior corner peer on ONE
2300    /// structural degree: the source carrier is `Option<OptimizationDirection>`
2301    /// nested inside the [`Horizon`] struct rather than a direct scalar
2302    /// or a nested direct-scalar. Byte-for-byte peer of the sibling
2303    /// [`Self::has_optimization_direction`] on the Option-carrier hop
2304    /// (both unwrap the [`Horizon::direction`] slot through
2305    /// [`Option::unwrap_or_default`] against the closed-set-level
2306    /// [`OptimizationDirection::default = Minimize`]); this method is
2307    /// the derived-nullary-bool projection over the same defaulted
2308    /// scalar, mirroring the (has-variant, is-projection) pair on the
2309    /// sibling `point_type` axis.
2310    ///
2311    /// # Semantics — derived nullary boolean, defaulted through Option
2312    ///
2313    /// `direction_prefers_lower()` returns `true` iff
2314    /// `self.horizon.direction.unwrap_or_default().prefers_lower()`. The
2315    /// two-variant [`OptimizationDirection`] closed set publishes the
2316    /// truth table: [`OptimizationDirection::Minimize`] → `true` (cost /
2317    /// latency / error rate — lower is better);
2318    /// [`OptimizationDirection::Maximize`] → `false` (throughput /
2319    /// coverage / revenue — higher is better). A
2320    /// [`Classification::gate_compute`] baseline (which carries
2321    /// `horizon: Horizon::default()` whose `direction` field is `None`)
2322    /// answers `true` deliberately — an unadorned Process's polarity
2323    /// reads as lower-is-better, matching the substrate
2324    /// [`OptimizationDirection::default = Minimize`] chosen precisely so
2325    /// an under-specified `Asymptotic` horizon can't silently flip the
2326    /// rate-window evaluator's polarity onto the Maximize path (a
2327    /// future `Maximize`-default-via-rename would silently invert every
2328    /// existing alert that treats decreasing rate as healthy).
2329    ///
2330    /// A future third [`OptimizationDirection`] variant (a hypothetical
2331    /// `Stabilize` sentinel for "drive toward a target value", which
2332    /// neither minimization nor maximization names) reaches this probe
2333    /// through ONE `prefers_lower` arm on the closed set with the probe
2334    /// body untouched — the nullary-predicate shape defers every
2335    /// per-variant policy decision to the closed set's own truth table
2336    /// ([`OptimizationDirection::prefers_lower`]) rather than
2337    /// duplicating the discriminator sweep here.
2338    ///
2339    /// # Compounding — opens the optimization-direction axis on the corner
2340    ///
2341    /// The point-domain require-tag surface in
2342    /// `tatara-reconciler::bin::tatara-check` composes this primitive
2343    /// as a fixed tag `prefers-lower-direction` on `POINT_FIXED_TAG_ARMS`
2344    /// — the SIXTH classification axis to reach the fixed-tag corner.
2345    /// The ephemeral surface publishes the same tag via
2346    /// [`crate::ephemeral::EphemeralSpec::direction_prefers_lower`],
2347    /// which composes THIS method through
2348    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`] so
2349    /// the two-surface parity contract holds — the operator's
2350    /// `:requires (prefers-lower-direction)` audit answers the same
2351    /// question on both surfaces. A future antisymmetric peer
2352    /// (`direction_prefers_higher` reading
2353    /// `!self.horizon.direction.unwrap_or_default().prefers_lower()`,
2354    /// or a projection through a peer `OptimizationDirection::prefers_higher`
2355    /// closed-set arm) closes the binary XOR partition on this axis —
2356    /// mirror of the calm-axis (`monotone-calm ⊕ coordination-required`)
2357    /// and data-axis (`public-data ⊕ data-restricted`) closures — as
2358    /// the SECOND occupant on the axis.
2359    ///
2360    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2361    /// preserves proofs; the derived-nullary-bool predicate body lives
2362    /// at ONE substrate site so every downstream (the
2363    /// `prefers-lower-direction` fixed tag in `tatara-check`, future
2364    /// asymptotic-health rate-window / regression-detector evaluators
2365    /// keying on the optimization-polarity, future variant additions on
2366    /// [`OptimizationDirection`]) binds through the SAME
2367    /// `direction_prefers_lower()` shape rather than restating the
2368    /// `classification.horizon.direction.unwrap_or_default().prefers_lower()`
2369    /// chain at each callsite. THEORY.md §VI.1 — generation over
2370    /// composition; a future [`OptimizationDirection`] variant lands at
2371    /// ONE `ALL` entry + ONE `prefers_lower` arm on the closed set and
2372    /// this probe picks it up mechanically.
2373    #[must_use]
2374    pub fn direction_prefers_lower(&self) -> bool {
2375        self.horizon.direction.unwrap_or_default().prefers_lower()
2376    }
2377
2378    /// POSITIVE-FRAMING PEER of [`Self::direction_prefers_lower`] —
2379    /// does this [`Classification`]'s [`Horizon::direction`] slot
2380    /// (defaulted through [`OptimizationDirection::default = Minimize`]
2381    /// on absence) project to `true` under
2382    /// [`OptimizationDirection::prefers_higher`]? The ONE substrate
2383    /// primitive that owns the `(Classification) -> bool` derived-
2384    /// nullary-predicate walk on the `horizon.direction` slot for the
2385    /// higher-is-better optimization-polarity question.
2386    ///
2387    /// # Fifteenth occupant on the (parent × derived-nullary-bool) corner — CLOSES the optimization-direction axis
2388    ///
2389    /// Peer of the fourteen prior nullary-bool substrate primitives on
2390    /// [`Classification`] ([`Self::horizon_terminates`],
2391    /// [`Self::horizon_requires_metric_axes`],
2392    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2393    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2394    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2395    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2396    /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
2397    /// [`Self::data_is_public`], [`Self::direction_prefers_lower`]) on
2398    /// the workspace-wide (parent × derived-nullary-bool) corner of
2399    /// the closed-set-driven presence-probe algebra. FIFTEENTH
2400    /// occupant on the corner and SECOND peer threading the
2401    /// classification-`horizon.direction` axis — CLOSES the axis into
2402    /// the FULL binary XOR partition contract `direction_prefers_lower
2403    /// ⊕ direction_prefers_higher` sealed on the closed set by
2404    /// `optimization_direction_prefers_lower_xor_prefers_higher` and
2405    /// composed through the parent-composed layer by
2406    /// `classification_direction_probes_form_binary_xor_partition_over_all`.
2407    /// ALL SIX classification axes (horizon, calm, data, point,
2408    /// substrate, optimization-direction) now have their partitions
2409    /// closed at the corner — the fixed-tag algebra reaches full
2410    /// axis-coverage on the classification lattice.
2411    ///
2412    /// Direct byte-for-byte structural peer of
2413    /// [`Self::direction_prefers_lower`]: both walk the SAME
2414    /// [`Horizon::direction`] slot through TWO layers of `Default`
2415    /// (`Horizon::default` → `direction: None`; then
2416    /// [`OptimizationDirection::default = Minimize`]) to reach the
2417    /// closed-set-level projection. The [`Classification::gate_compute`]
2418    /// baseline's default-arm answer projects `false` HERE (Minimize
2419    /// default → `prefers_higher() = false`), mirror-inverted from
2420    /// [`Self::direction_prefers_lower`]'s Minimize-default `true` on
2421    /// the SAME defaulted `horizon.direction` slot — the antisymmetric
2422    /// twin on the substrate polarity default.
2423    ///
2424    /// # Semantics — derived nullary boolean over the closed-set plane
2425    ///
2426    /// `direction_prefers_higher()` returns `true` iff
2427    /// `self.horizon.direction.unwrap_or_default().prefers_higher()`.
2428    /// The two-variant [`OptimizationDirection`] closed set publishes
2429    /// the truth table: [`OptimizationDirection::Minimize`] → `false`
2430    /// (cost / latency / error rate — decreasing values improve);
2431    /// [`OptimizationDirection::Maximize`] → `true` (throughput /
2432    /// coverage / revenue — increasing values improve). A
2433    /// [`Classification::gate_compute`] baseline (which carries
2434    /// `horizon: Horizon::default()` whose `direction` field is `None`)
2435    /// answers `false` because [`OptimizationDirection::default =
2436    /// Minimize`] projects `prefers_higher = false`, so every
2437    /// unadorned Process reads under the lower-is-better polarity —
2438    /// matching the substrate polarity default (safe under the
2439    /// asymptotic-health rate-window evaluator's convention: an
2440    /// operator must deliberately opt into Maximize polarity rather
2441    /// than the substrate silently flipping every unadorned Process
2442    /// onto the higher-is-better path).
2443    ///
2444    /// A future third [`OptimizationDirection`] variant (a hypothetical
2445    /// `Stabilize` sentinel for "drive toward a target value", which
2446    /// neither minimization nor maximization names) reaches this probe
2447    /// through ONE `prefers_higher` arm on the closed set with the
2448    /// probe body untouched — the nullary-predicate shape defers every
2449    /// per-variant policy decision to the closed set's own truth table
2450    /// ([`OptimizationDirection::prefers_higher`]) rather than
2451    /// duplicating the discriminator sweep here. The XOR pin on the
2452    /// closed set forces such a variant to answer `false` on BOTH
2453    /// `prefers_lower` AND `prefers_higher` unless a deliberate
2454    /// extension carves the closed set into a ternary partition.
2455    ///
2456    /// # Compounding — CLOSES the optimization-direction axis into a binary XOR partition
2457    ///
2458    /// The point-domain require-tag surface in
2459    /// `tatara-reconciler::bin::tatara-check` composes this primitive
2460    /// as a fixed tag `prefers-higher-direction` on `POINT_FIXED_TAG_ARMS`
2461    /// — byte-for-byte structural peer of the sibling
2462    /// `prefers-lower-direction` fixed tag (the antisymmetric partner
2463    /// on the same axis) and of every other `(parent × derived-
2464    /// nullary-bool)` corner arm. The ephemeral surface publishes the
2465    /// same tag via
2466    /// [`crate::ephemeral::EphemeralSpec::direction_prefers_higher`],
2467    /// which composes THIS method through
2468    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`] so
2469    /// the two-surface parity contract holds — the operator's
2470    /// `:requires (prefers-higher-direction)` audit answers the same
2471    /// question on both surfaces. SECOND optimization-direction-axis
2472    /// peer CLOSES the binary XOR partition contract
2473    /// `direction_prefers_lower ⊕ direction_prefers_higher` sealed on
2474    /// the closed set by
2475    /// `optimization_direction_prefers_lower_xor_prefers_higher`
2476    /// through the parent-composed layer as a substrate-wide theorem
2477    /// — mirror of the calm-axis (`monotone-calm ⊕ coordination-required`)
2478    /// and data-axis (`public-data ⊕ data-restricted`) closures
2479    /// already landed on the corner, and the SIXTH (and final)
2480    /// classification axis to reach the closed XOR partition landmark
2481    /// at this corner.
2482    ///
2483    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2484    /// preserves proofs; the derived-nullary-bool predicate body
2485    /// lives at ONE substrate site so every downstream (the
2486    /// `prefers-higher-direction` fixed tag in `tatara-check`, future
2487    /// asymptotic-health rate-window / regression-detector evaluators
2488    /// keying on the positive higher-is-better polarity framing,
2489    /// future variant additions on [`OptimizationDirection`]) binds
2490    /// through the SAME `direction_prefers_higher()` shape rather
2491    /// than restating either `!self.direction_prefers_lower()` or
2492    /// `self.horizon.direction.unwrap_or_default().prefers_higher()`
2493    /// at the callsite. THEORY.md §VI.1 — generation over composition;
2494    /// a future [`OptimizationDirection`] variant lands at ONE `ALL`
2495    /// entry + ONE `prefers_higher` arm on the closed set and this
2496    /// probe picks it up mechanically.
2497    #[must_use]
2498    pub fn direction_prefers_higher(&self) -> bool {
2499        self.horizon.direction.unwrap_or_default().prefers_higher()
2500    }
2501
2502    /// Derived-boolean predicate — does this [`Classification`]'s
2503    /// `point_type` slot project to `Arity::One` under
2504    /// [`ConvergencePointType::input_arity`]? The ONE substrate
2505    /// primitive that owns the `(Classification) -> bool` derived-
2506    /// nullary-predicate walk on the DAG-composition input-arity
2507    /// projection.
2508    ///
2509    /// # First derived-nullary-bool corner occupant on the input-arity axis
2510    ///
2511    /// Peer of the fifteen prior nullary-bool substrate primitives on
2512    /// [`Classification`] ([`Self::horizon_terminates`],
2513    /// [`Self::horizon_requires_metric_axes`],
2514    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2515    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2516    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2517    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2518    /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
2519    /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
2520    /// [`Self::direction_prefers_higher`]) on the workspace-wide
2521    /// (parent × derived-nullary-bool) corner of the closed-set-driven
2522    /// presence-probe algebra. SIXTEENTH occupant on the corner and
2523    /// FIRST occupant threading the classification-`point_type`-
2524    /// derived input-arity axis — opens the SEVENTH classification
2525    /// axis into the fixed-tag algebra after the six axes (horizon,
2526    /// calm, data, point-type, substrate, optimization-direction)
2527    /// already closed at the corner. The input-arity axis is a
2528    /// derived typed projection through
2529    /// [`ConvergencePointType::input_arity`] rather than a stored
2530    /// classification slot — so this predicate composes an extra
2531    /// closed-set-level projection hop compared to the sibling
2532    /// `point_is_*` triple that walks the raw `point_type` slot.
2533    ///
2534    /// # Semantics — derived nullary boolean over the input-arity projection
2535    ///
2536    /// `input_arity_is_one()` returns `true` iff
2537    /// `self.point_type.input_arity().is_one()`. The eight-variant
2538    /// [`ConvergencePointType`] closed set publishes the truth table
2539    /// through [`ConvergencePointType::input_arity`]: `Transform |
2540    /// Fork | Broadcast | Observe → One → true`; `Join | Gate |
2541    /// Select | Reduce → Many → false`. A
2542    /// [`Classification::gate_compute`] baseline (which carries
2543    /// `point_type: Gate`) answers `false` — `Gate.input_arity() =
2544    /// Many`, so the multi-input bucket carves the workspace-wide
2545    /// baseline into the multi-input cell.
2546    ///
2547    /// A future [`ConvergencePointType`] variant (a hypothetical
2548    /// `Demux` for `One → Many` or `Mux` for `Many → One`) reaches
2549    /// this probe through ONE `input_arity` arm on
2550    /// [`ConvergencePointType`] with the probe body untouched — the
2551    /// many-to-one projection means the bucket membership shift lands
2552    /// exactly at [`ConvergencePointType::input_arity`], not at every
2553    /// consumer that previously restated the bucket in code.
2554    ///
2555    /// # Compounding — opens the input-arity axis at the parent-composed corner
2556    ///
2557    /// The point-domain require-tag surface in
2558    /// `tatara-reconciler::bin::tatara-check` composes this primitive
2559    /// as a fixed tag `single-input-arity` on `POINT_FIXED_TAG_ARMS`
2560    /// — byte-for-byte structural peer of every other `(parent ×
2561    /// derived-nullary-bool)` corner arm. The antisymmetric partner
2562    /// [`Self::input_arity_is_many`] closes the input-arity axis into
2563    /// the FULL binary XOR partition contract sealed on the closed
2564    /// set by `arity_is_one_xor_is_many_over_all` — mirror of the
2565    /// binary XOR closures on the calm axis (`monotone-calm ⊕
2566    /// coordination-required`), the data axis (`public-data ⊕
2567    /// data-restricted`), and the optimization-direction axis
2568    /// (`prefers-lower-direction ⊕ prefers-higher-direction`). A
2569    /// future ephemeral-surface peer
2570    /// (`EphemeralSpec::input_arity_is_one`) will compose THIS method
2571    /// through [`crate::ephemeral::EphemeralSpec::resolved_classification`]
2572    /// so the two-surface parity contract holds — the operator's
2573    /// `:requires (single-input-arity)` audit answers the same
2574    /// question on both surfaces.
2575    ///
2576    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2577    /// preserves proofs; the derived-nullary-bool predicate body
2578    /// lives at ONE substrate site so every downstream (the future
2579    /// `single-input-arity` fixed tag in `tatara-check`, DAG
2580    /// composition validators keying on the single-input framing,
2581    /// future variant additions on [`ConvergencePointType`]) binds
2582    /// through the SAME `input_arity_is_one()` shape rather than
2583    /// restating the two-hop `self.point_type.input_arity().is_one()`
2584    /// chain at each callsite. THEORY.md §VI.1 — generation over
2585    /// composition; a future [`ConvergencePointType`] variant lands
2586    /// at ONE `ALL` entry + ONE `input_arity` arm on the closed set
2587    /// and this probe picks it up mechanically.
2588    #[must_use]
2589    pub fn input_arity_is_one(&self) -> bool {
2590        self.point_type.input_arity().is_one()
2591    }
2592
2593    /// ANTISYMMETRIC PEER of [`Self::input_arity_is_one`] — does
2594    /// this [`Classification`]'s `point_type` slot project to
2595    /// `Arity::Many` under [`ConvergencePointType::input_arity`]?
2596    /// The ONE substrate primitive that owns the `(Classification) ->
2597    /// bool` derived-nullary-predicate walk on the multi-input side
2598    /// of the DAG-composition input-arity projection.
2599    ///
2600    /// # Seventeenth corner occupant — CLOSES the input-arity axis into a binary XOR partition
2601    ///
2602    /// SEVENTEENTH occupant on the (parent × derived-nullary-bool)
2603    /// corner of the workspace-wide closed-set-driven presence-probe
2604    /// algebra and SECOND peer threading the classification-
2605    /// `point_type`-derived input-arity axis — CLOSES the SEVENTH
2606    /// classification axis into the FULL binary XOR partition
2607    /// contract `input_arity_is_one ⊕ input_arity_is_many` sealed on
2608    /// the closed set by `arity_is_one_xor_is_many_over_all` and
2609    /// composed through the parent-composed layer by
2610    /// `classification_input_arity_probes_form_binary_xor_partition_over_all`.
2611    /// Structural mirror of the calm-axis binary XOR partition
2612    /// (`monotone-calm ⊕ coordination-required`), the data-axis
2613    /// binary XOR partition (`public-data ⊕ data-restricted`), and
2614    /// the optimization-direction-axis binary XOR partition
2615    /// (`prefers-lower-direction ⊕ prefers-higher-direction`) — the
2616    /// FOURTH parent-composed binary XOR partition on the corner.
2617    ///
2618    /// # Semantics — derived nullary boolean over the multi-input projection
2619    ///
2620    /// `input_arity_is_many()` returns `true` iff
2621    /// `self.point_type.input_arity().is_many()`. The eight-variant
2622    /// [`ConvergencePointType`] closed set publishes the truth table
2623    /// through [`ConvergencePointType::input_arity`]: `Transform |
2624    /// Fork | Broadcast | Observe → One → false`; `Join | Gate |
2625    /// Select | Reduce → Many → true`. A
2626    /// [`Classification::gate_compute`] baseline (which carries
2627    /// `point_type: Gate`) answers `true` — `Gate.input_arity() =
2628    /// Many`, so the multi-input bucket carves the workspace-wide
2629    /// baseline. Direct antisymmetric mirror of
2630    /// [`Self::input_arity_is_one`] on the SAME projection through
2631    /// the SAME closed set.
2632    ///
2633    /// # Compounding — CLOSES the input-arity axis into a binary XOR partition
2634    ///
2635    /// The point-domain require-tag surface will compose this
2636    /// primitive as a fixed tag `multi-input-arity` on
2637    /// `POINT_FIXED_TAG_ARMS` — antisymmetric peer of the sibling
2638    /// `single-input-arity` fixed tag. Together with the sibling
2639    /// [`Self::input_arity_is_one`] the two predicates seal the
2640    /// input-arity axis into a binary XOR partition on the parent-
2641    /// composed layer as a substrate-wide theorem, closing the
2642    /// axis at the SEVENTH-classification-axis landmark.
2643    ///
2644    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2645    /// preserves proofs; the derived-nullary-bool predicate body
2646    /// lives at ONE substrate site so every downstream (the future
2647    /// `multi-input-arity` fixed tag, DAG composition validators
2648    /// keying on multi-input fan-in semantics, future variant
2649    /// additions on [`ConvergencePointType`]) binds through the SAME
2650    /// `input_arity_is_many()` shape rather than restating either
2651    /// `!self.input_arity_is_one()` or
2652    /// `self.point_type.input_arity().is_many()` at each callsite.
2653    /// THEORY.md §VI.1 — generation over composition; a future
2654    /// [`ConvergencePointType`] variant lands at ONE `ALL` entry +
2655    /// ONE `input_arity` arm on the closed set and this probe picks
2656    /// it up mechanically.
2657    #[must_use]
2658    pub fn input_arity_is_many(&self) -> bool {
2659        self.point_type.input_arity().is_many()
2660    }
2661
2662    /// Derived-boolean predicate — does this [`Classification`]'s
2663    /// `point_type` slot project to `Arity::One` under
2664    /// [`ConvergencePointType::output_arity`]? The ONE substrate
2665    /// primitive that owns the `(Classification) -> bool` derived-
2666    /// nullary-predicate walk on the DAG-composition OUTPUT-arity
2667    /// projection — antisymmetric partner (on the DAG-composition
2668    /// arity PAIR) of the sibling [`Self::input_arity_is_one`] that
2669    /// walks the SAME `point_type` slot through the SAME `Arity`
2670    /// closed set but composes a DIFFERENT typed projection
2671    /// ([`ConvergencePointType::output_arity`] rather than
2672    /// [`ConvergencePointType::input_arity`]).
2673    ///
2674    /// # Eighteenth (parent × derived-nullary-bool) corner occupant — opens the EIGHTH classification axis
2675    ///
2676    /// Peer of the seventeen prior nullary-bool substrate primitives
2677    /// on [`Classification`] ([`Self::horizon_terminates`],
2678    /// [`Self::horizon_requires_metric_axes`],
2679    /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
2680    /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
2681    /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
2682    /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
2683    /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
2684    /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
2685    /// [`Self::direction_prefers_higher`],
2686    /// [`Self::input_arity_is_one`], [`Self::input_arity_is_many`]) on
2687    /// the workspace-wide (parent × derived-nullary-bool) corner of
2688    /// the closed-set-driven presence-probe algebra. EIGHTEENTH
2689    /// occupant on the corner and FIRST occupant threading the
2690    /// classification-`point_type`-derived output-arity axis — opens
2691    /// the EIGHTH classification axis into the fixed-tag algebra
2692    /// after the seven axes (horizon, calm, data, point-type,
2693    /// substrate, optimization-direction, input-arity) already opened
2694    /// at the corner. The output-arity axis is the SECOND derived
2695    /// typed projection ([`ConvergencePointType::output_arity`],
2696    /// after the input-arity axis's [`ConvergencePointType::input_arity`])
2697    /// rather than a stored classification slot — so this predicate
2698    /// composes an extra closed-set-level projection hop compared to
2699    /// the sibling `point_is_*` triple that walks the raw `point_type`
2700    /// slot.
2701    ///
2702    /// # Distinctness from the input-arity axis
2703    ///
2704    /// The input-arity and output-arity axes carve the eight-variant
2705    /// [`ConvergencePointType`] closed set into DISTINCT partitions —
2706    /// six of the eight variants (`Fork | Broadcast | Join | Gate |
2707    /// Select | Reduce`) DISAGREE between the two projections, and
2708    /// only the two endomorphic variants (`Transform | Observe` —
2709    /// both `(One, One)`) agree. So `output_arity_is_one` is NOT a
2710    /// redundant restatement of `input_arity_is_one`; the two together
2711    /// name the `(input_arity, output_arity)` typed pair contract
2712    /// canonically already carried on [`ConvergencePointType`] by the
2713    /// `is_endomorphic | is_diffusive | is_convergent` triple — but
2714    /// as SEPARATE nullary predicates on the parent-composed layer
2715    /// rather than as a bucket dispatcher.
2716    ///
2717    /// # Semantics — derived nullary boolean over the output-arity projection
2718    ///
2719    /// `output_arity_is_one()` returns `true` iff
2720    /// `self.point_type.output_arity().is_one()`. The eight-variant
2721    /// [`ConvergencePointType`] closed set publishes the truth table
2722    /// through [`ConvergencePointType::output_arity`]: `Transform |
2723    /// Join | Gate | Select | Reduce | Observe → One → true`; `Fork |
2724    /// Broadcast → Many → false`. A [`Classification::gate_compute`]
2725    /// baseline (which carries `point_type: Gate`) answers `true` —
2726    /// `Gate.output_arity() = One`, so the single-output bucket
2727    /// carves the workspace-wide baseline into the single-output
2728    /// cell. Note the workspace-baseline answer FLIPS between the
2729    /// input-arity and output-arity axes on the exact same baseline:
2730    /// `input_arity_is_one` is `false` on `gate_compute`, but
2731    /// `output_arity_is_one` is `true` — direct evidence that the two
2732    /// axes carve the closed set into structurally different
2733    /// partitions.
2734    ///
2735    /// A future [`ConvergencePointType`] variant (a hypothetical
2736    /// `Demux` for `One → Many` or `Mux` for `Many → One`) reaches
2737    /// this probe through ONE `output_arity` arm on
2738    /// [`ConvergencePointType`] with the probe body untouched — the
2739    /// many-to-one projection means the bucket membership shift lands
2740    /// exactly at [`ConvergencePointType::output_arity`], not at
2741    /// every consumer that previously restated the bucket in code.
2742    ///
2743    /// # Compounding — opens the output-arity axis at the parent-composed corner
2744    ///
2745    /// The point-domain require-tag surface in
2746    /// `tatara-reconciler::bin::tatara-check` will compose this
2747    /// primitive as a fixed tag `single-output-arity` on
2748    /// `POINT_FIXED_TAG_ARMS` — byte-for-byte structural peer of
2749    /// every other `(parent × derived-nullary-bool)` corner arm. The
2750    /// antisymmetric partner [`Self::output_arity_is_many`] closes
2751    /// the output-arity axis into the FULL binary XOR partition
2752    /// contract sealed on the closed set by
2753    /// `arity_is_one_xor_is_many_over_all` — mirror of the binary
2754    /// XOR closures on the calm axis (`monotone-calm ⊕
2755    /// coordination-required`), the data axis (`public-data ⊕
2756    /// data-restricted`), the optimization-direction axis
2757    /// (`prefers-lower-direction ⊕ prefers-higher-direction`), and
2758    /// the input-arity axis (`input_arity_is_one ⊕
2759    /// input_arity_is_many`). A future ephemeral-surface peer
2760    /// (`EphemeralSpec::output_arity_is_one`) will compose THIS
2761    /// method through
2762    /// [`crate::ephemeral::EphemeralSpec::resolved_classification`]
2763    /// so the two-surface parity contract holds — the operator's
2764    /// `:requires (single-output-arity)` audit answers the same
2765    /// question on both surfaces.
2766    ///
2767    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2768    /// preserves proofs; the derived-nullary-bool predicate body
2769    /// lives at ONE substrate site so every downstream (the future
2770    /// `single-output-arity` fixed tag in `tatara-check`, DAG
2771    /// composition validators keying on the single-output framing,
2772    /// future variant additions on [`ConvergencePointType`]) binds
2773    /// through the SAME `output_arity_is_one()` shape rather than
2774    /// restating the two-hop `self.point_type.output_arity().is_one()`
2775    /// chain at each callsite. THEORY.md §VI.1 — generation over
2776    /// composition; a future [`ConvergencePointType`] variant lands
2777    /// at ONE `ALL` entry + ONE `output_arity` arm on the closed set
2778    /// and this probe picks it up mechanically.
2779    #[must_use]
2780    pub fn output_arity_is_one(&self) -> bool {
2781        self.point_type.output_arity().is_one()
2782    }
2783
2784    /// ANTISYMMETRIC PEER of [`Self::output_arity_is_one`] — does
2785    /// this [`Classification`]'s `point_type` slot project to
2786    /// `Arity::Many` under [`ConvergencePointType::output_arity`]?
2787    /// The ONE substrate primitive that owns the `(Classification) ->
2788    /// bool` derived-nullary-predicate walk on the multi-output side
2789    /// of the DAG-composition output-arity projection.
2790    ///
2791    /// # Nineteenth corner occupant — CLOSES the output-arity axis into a binary XOR partition
2792    ///
2793    /// NINETEENTH occupant on the (parent × derived-nullary-bool)
2794    /// corner of the workspace-wide closed-set-driven presence-probe
2795    /// algebra and SECOND peer threading the classification-
2796    /// `point_type`-derived output-arity axis — CLOSES the EIGHTH
2797    /// classification axis into the FULL binary XOR partition
2798    /// contract `output_arity_is_one ⊕ output_arity_is_many` sealed
2799    /// on the closed set by `arity_is_one_xor_is_many_over_all` and
2800    /// composed through the parent-composed layer by
2801    /// `classification_output_arity_probes_form_binary_xor_partition_over_all`.
2802    /// Structural mirror of the input-arity-axis binary XOR partition
2803    /// (`input_arity_is_one ⊕ input_arity_is_many`), the calm-axis
2804    /// binary XOR partition (`monotone-calm ⊕ coordination-required`),
2805    /// the data-axis binary XOR partition
2806    /// (`public-data ⊕ data-restricted`), and the optimization-
2807    /// direction-axis binary XOR partition (`prefers-lower-direction
2808    /// ⊕ prefers-higher-direction`) — the FIFTH parent-composed
2809    /// binary XOR partition on the corner and the SECOND on the
2810    /// derived-typed-projection stratum (after the input-arity
2811    /// closure).
2812    ///
2813    /// # Semantics — derived nullary boolean over the multi-output projection
2814    ///
2815    /// `output_arity_is_many()` returns `true` iff
2816    /// `self.point_type.output_arity().is_many()`. The eight-variant
2817    /// [`ConvergencePointType`] closed set publishes the truth table
2818    /// through [`ConvergencePointType::output_arity`]: `Transform |
2819    /// Join | Gate | Select | Reduce | Observe → One → false`; `Fork
2820    /// | Broadcast → Many → true`. A [`Classification::gate_compute`]
2821    /// baseline (which carries `point_type: Gate`) answers `false` —
2822    /// `Gate.output_arity() = One`, so the single-output bucket
2823    /// carves the workspace-wide baseline. Direct antisymmetric
2824    /// mirror of [`Self::output_arity_is_one`] on the SAME projection
2825    /// through the SAME closed set.
2826    ///
2827    /// # Compounding — CLOSES the output-arity axis into a binary XOR partition
2828    ///
2829    /// The point-domain require-tag surface will compose this
2830    /// primitive as a fixed tag `multi-output-arity` on
2831    /// `POINT_FIXED_TAG_ARMS` — antisymmetric peer of the sibling
2832    /// `single-output-arity` fixed tag. Together with the sibling
2833    /// [`Self::output_arity_is_one`] the two predicates seal the
2834    /// output-arity axis into a binary XOR partition on the parent-
2835    /// composed layer as a substrate-wide theorem, closing the axis
2836    /// at the EIGHTH-classification-axis landmark. Together with the
2837    /// four sibling closed binary XOR partitions (input-arity, calm,
2838    /// data, optimization-direction) the (parent × derived-nullary-
2839    /// bool) corner now carries FIVE closed binary XOR partitions —
2840    /// the derived-typed-projection stratum grows the corner from
2841    /// stored-slot walks into DAG-composition typed projections
2842    /// systematically.
2843    ///
2844    /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
2845    /// preserves proofs; the derived-nullary-bool predicate body
2846    /// lives at ONE substrate site so every downstream (the future
2847    /// `multi-output-arity` fixed tag, DAG composition validators
2848    /// keying on multi-output fan-out semantics, future variant
2849    /// additions on [`ConvergencePointType`]) binds through the SAME
2850    /// `output_arity_is_many()` shape rather than restating either
2851    /// `!self.output_arity_is_one()` or
2852    /// `self.point_type.output_arity().is_many()` at each callsite.
2853    /// THEORY.md §VI.1 — generation over composition; a future
2854    /// [`ConvergencePointType`] variant lands at ONE `ALL` entry +
2855    /// ONE `output_arity` arm on the closed set and this probe picks
2856    /// it up mechanically.
2857    #[must_use]
2858    pub fn output_arity_is_many(&self) -> bool {
2859        self.point_type.output_arity().is_many()
2860    }
2861
2862    /// Compose the workspace-baseline [`Self::gate_compute`] with a
2863    /// single-axis mutation — return `Self::gate_compute()` with the
2864    /// axis slot carrying `axis`'s classification-axis type overwritten
2865    /// by `axis`. The ONE substrate primitive that owns the
2866    /// (Classification, single-axis variant) → Classification
2867    /// baseline-with-axis-mutated composition shape.
2868    ///
2869    /// # Substrate ergonomics
2870    ///
2871    /// Pre-lift the shape `Classification::gate_compute()` with a
2872    /// single axis slot overwritten by a per-test swept variant
2873    /// recurred at ≥ 40 hand-authored test-fixture callsites past the
2874    /// ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold, each restating the
2875    /// SAME six-line struct-literal that names FOUR baseline slots
2876    /// verbatim and mutates ONE. Post-lift every callsite reads
2877    /// `Classification::gate_compute_with_axis(populated)` — one line,
2878    /// ONE substrate primitive owns the four-baseline-slot restatement,
2879    /// and a future workspace-wide baseline shift lands at ONE site
2880    /// via [`Self::gate_compute`] rather than at every downstream
2881    /// test fixture that names the four unmutated slots explicitly.
2882    ///
2883    /// # Compounding
2884    ///
2885    /// A future SIXTH classification axis (foreshadowed by the
2886    /// six-axis lattice language on the CRD-facing prose) lands as
2887    /// ONE peer `impl ClassificationAxis` on the new axis's closed
2888    /// set + ONE new slot on [`Classification`] itself — every test
2889    /// fixture using `gate_compute_with_axis` picks up the sixth axis
2890    /// mechanically without touching the callsite. A future audit
2891    /// dispatcher walking every classification axis (the "walk every
2892    /// classification axis through its XOR partition landmark" shape
2893    /// the FIFTH-axis-closure commit `2c74fab` explicitly named as
2894    /// the next-lift target) binds through the SAME trait rather than
2895    /// a five-arm dispatch on axis identity.
2896    ///
2897    /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2898    /// preserves proofs — the four-baseline-slot restatement is the
2899    /// composition proof `gate_compute` already carries at ONE site;
2900    /// this primitive extends the ONE-site composition guarantee
2901    /// through the per-axis mutation shape). THEORY.md §VI.1
2902    /// (generation over composition — a future sixth axis lands as
2903    /// ONE ClassificationAxis impl and every test fixture picks it
2904    /// up mechanically).
2905    #[must_use]
2906    pub fn gate_compute_with_axis<A: ClassificationAxis>(axis: A) -> Self {
2907        let mut c = Self::gate_compute();
2908        axis.overlay(&mut c);
2909        c
2910    }
2911
2912    /// Fluent per-axis overlay — post-composes ONE additional
2913    /// [`ClassificationAxis`] variant on top of `self`, returning
2914    /// the mutated [`Classification`] by value. Sibling to
2915    /// [`Self::gate_compute_with_axis`] on the (baseline-composer ×
2916    /// per-axis-overlay) axis: `gate_compute_with_axis(a)` is the
2917    /// (start-from-baseline, overlay-one-axis) shape; `with_axis(a)`
2918    /// is the (start-from-arbitrary-classification, overlay-one-more-
2919    /// axis) shape. Together they compose the workspace-wide
2920    /// (Classification, N-axis-conjunction) construction algebra:
2921    /// `Classification::gate_compute_with_axis(a).with_axis(b).with_axis(c)`
2922    /// chains an arbitrary N-axis conjunction onto the [`Self::gate_compute`]
2923    /// baseline through ONE substrate primitive per axis rather than
2924    /// restating the FIVE-field struct-literal (`point_type`,
2925    /// `substrate`, `horizon`, `calm`, `data_classification`) verbatim
2926    /// at every N-axis-conjunction test-fixture callsite.
2927    ///
2928    /// # Substrate ergonomics
2929    ///
2930    /// Pre-lift the shape `Classification { <mutated-axes>,
2931    /// ..(remaining-baselines) }` recurred at ≥ 5 hand-authored
2932    /// multi-axis-conjunction test-fixture callsites in this file
2933    /// past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold,
2934    /// each restating the FIVE-field struct-literal with distinct
2935    /// (Fork+Storage), (Fork+Storage+NonMonotone),
2936    /// (Fork+Storage+NonMonotone+Pii),
2937    /// (Fork+Storage+NonMonotone+Pii+HorizonKind::Asymptotic), and
2938    /// (Fork+Storage+NonMonotone+Pii+HorizonKind::Asymptotic+
2939    /// direction=Maximize) conjunctions. Post-lift each callsite
2940    /// reads
2941    /// `Classification::gate_compute_with_axis(Fork).with_axis(Storage)`
2942    /// … (chained per axis), and the four/three/two/one-baseline-slot
2943    /// restatement binds through the ONE substrate composer at every
2944    /// callsite. The prior lift onto [`Self::gate_compute_with_axis`]
2945    /// (`76d469c` + `08714f6` + `7f14656`) closed the SINGLE-axis-
2946    /// overlay shape; this primitive extends the same trait dispatch
2947    /// through arbitrary N-axis conjunctions without introducing a
2948    /// variadic-tuple-overlay dispatch path.
2949    ///
2950    /// # Compounding
2951    ///
2952    /// A future SIXTH classification axis (foreshadowed by the
2953    /// six-axis lattice language on the CRD-facing prose) lands as
2954    /// ONE peer `impl ClassificationAxis` on the new axis's closed
2955    /// set — every multi-axis-conjunction test fixture using
2956    /// `.with_axis(...)` picks up the sixth axis mechanically by
2957    /// appending ONE more `.with_axis(new_variant)` call rather than
2958    /// growing an N-field struct-literal to N+1 fields at every
2959    /// site. A future audit dispatcher walking a fixed N-axis
2960    /// conjunction on every classification axis binds through the
2961    /// SAME chained-overlay shape rather than a per-N-arity
2962    /// composer family (`gate_compute_with_axes2`,
2963    /// `gate_compute_with_axes3`, …).
2964    ///
2965    /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2966    /// preserves proofs — the per-axis overlay is the axis-local
2967    /// composition proof [`ClassificationAxis::overlay`] owns at ONE
2968    /// site; this primitive lifts the ONE-axis composition guarantee
2969    /// through arbitrary chaining without a per-arity dispatch
2970    /// path). THEORY.md §VI.1 (generation over composition — a
2971    /// future N-axis-conjunction test lands as ONE chained
2972    /// `.with_axis(...)` sequence versus a fresh N+1-field struct-
2973    /// literal per callsite).
2974    #[must_use]
2975    pub fn with_axis<A: ClassificationAxis>(mut self, axis: A) -> Self {
2976        axis.overlay(&mut self);
2977        self
2978    }
2979}
2980
2981/// Test/audit helper — a closed-set variant that can overlay its
2982/// classification-axis slot onto a base [`Classification`]. Unifies
2983/// the five per-axis assignments (`horizon = Horizon { kind: self, ..
2984/// default() }`, `calm = self`, `data_classification = self`,
2985/// `point_type = self`, `substrate = self`) under ONE substrate
2986/// shape so [`Classification::gate_compute_with_axis`] can compose
2987/// the workspace baseline with a single-axis mutation generically
2988/// over any of the five classification axes.
2989///
2990/// # Compounding
2991///
2992/// A future SIXTH classification axis lands as ONE peer `impl
2993/// ClassificationAxis` on the new axis's closed set — every
2994/// downstream test fixture and audit dispatcher that binds through
2995/// [`Classification::gate_compute_with_axis`] picks up the sixth
2996/// axis mechanically without a five-arm-becomes-six-arm dispatch
2997/// edit. A future workspace-wide "walk every classification axis"
2998/// audit primitive binds through the SAME trait rather than
2999/// restating the five-per-axis assignment shape at its own body.
3000///
3001/// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3002/// preserves proofs. The five per-axis assignments each carry an
3003/// axis-local composition proof (nested-struct `horizon.kind` gets
3004/// a fresh `Horizon::default()` around the mutation; direct-scalar
3005/// axes get a bare `self` assignment); this trait promotes the
3006/// five proofs to ONE shape so a downstream composer binds through
3007/// the same primitive regardless of which axis it targets.
3008pub trait ClassificationAxis {
3009    /// Overlay this axis-variant onto `c`, replacing the corresponding
3010    /// classification-axis slot with `self`. Leaves every other slot
3011    /// on `c` untouched.
3012    fn overlay(self, c: &mut Classification);
3013}
3014
3015impl ClassificationAxis for HorizonKind {
3016    fn overlay(self, c: &mut Classification) {
3017        // Sub-slot overlay — set ONLY the `kind` field on the nested
3018        // `Horizon` struct, preserving any `direction` / `metric` /
3019        // `healthy_rate_threshold` a prior [`Classification::with_axis`]
3020        // overlay may have populated. Byte-symmetric with the previous
3021        // whole-`Horizon` reset shape (`c.horizon = Horizon { kind: self,
3022        // ..Horizon::default() }`) when the base carrier is
3023        // [`Classification::gate_compute`] (whose `horizon` is
3024        // `Horizon::default()` — every sub-slot already `None`), but
3025        // order-independent under chaining: a downstream
3026        // `.with_axis(OptimizationDirection::Maximize).with_axis(HorizonKind::Asymptotic)`
3027        // no longer stomps the prior `direction: Some(Maximize)` overlay.
3028        c.horizon.kind = self;
3029    }
3030}
3031
3032impl ClassificationAxis for OptimizationDirection {
3033    fn overlay(self, c: &mut Classification) {
3034        // Nested-struct-Option sub-slot overlay — set ONLY the
3035        // `direction` field on the nested `Horizon` struct as
3036        // `Some(self)`, preserving `kind` / `metric` /
3037        // `healthy_rate_threshold`. Peer to the direct-nested-scalar
3038        // [`ClassificationAxis for HorizonKind`] overlay: both hop into
3039        // the nested `Horizon` struct, but this overlay wraps its assign
3040        // in `Some(...)` per the `Horizon::direction: Option<OptimizationDirection>`
3041        // typed slot. Chain
3042        // `.with_axis(HorizonKind::Asymptotic).with_axis(OptimizationDirection::Maximize)`
3043        // to compose the (kind, direction) pair the
3044        // [`crate::export`]-facing rate-window Asymptotic-horizon
3045        // fixtures otherwise restate as `Horizon { kind: Asymptotic,
3046        // direction: Some(Maximize), ..Horizon::default() }` inline.
3047        c.horizon.direction = Some(self);
3048    }
3049}
3050
3051impl ClassificationAxis for CalmClassification {
3052    fn overlay(self, c: &mut Classification) {
3053        c.calm = self;
3054    }
3055}
3056
3057impl ClassificationAxis for DataClassification {
3058    fn overlay(self, c: &mut Classification) {
3059        c.data_classification = self;
3060    }
3061}
3062
3063impl ClassificationAxis for ConvergencePointType {
3064    fn overlay(self, c: &mut Classification) {
3065        c.point_type = self;
3066    }
3067}
3068
3069impl ClassificationAxis for SubstrateType {
3070    fn overlay(self, c: &mut Classification) {
3071        c.substrate = self;
3072    }
3073}
3074
3075/// Structural type — how data flows through the point.
3076///
3077/// Closed-set sibling on the classification axis algebra; the `ALL` /
3078/// `as_str` / Display / `FromStr` triad mirrors
3079/// [`DataClassification::ALL`], [`crate::pool::PoolPhase::ALL`],
3080/// [`crate::pool::MemberState::ALL`], [`crate::pool::ReplacementPolicy::ALL`],
3081/// [`crate::pool::ReturnPolicy::ALL`],
3082/// [`crate::boundary::ConditionKind::ALL`],
3083/// [`crate::lifetime::TeardownPolicy::ALL`],
3084/// [`crate::lifetime::LifetimeKind::ALL`],
3085/// [`crate::intent::IntentKind::ALL`],
3086/// [`crate::phase::ProcessPhase::ALL`],
3087/// [`crate::signal::ProcessSignal::ALL`]. The
3088/// `(input_arity, output_arity)` projection (via [`Arity`]) closes the
3089/// graph-topology contract: each variant lands in exactly one of the
3090/// three structural buckets — endomorphic (1→1), diffusive (1→N), or
3091/// convergent (N→1) — so future DAG composition / edge-cardinality
3092/// validators dispatch on a typed projection rather than re-deriving
3093/// from variant names.
3094#[derive(
3095    Clone,
3096    Copy,
3097    Debug,
3098    PartialEq,
3099    Eq,
3100    Hash,
3101    Serialize,
3102    Deserialize,
3103    JsonSchema,
3104    tatara_closed_set::DeriveClosedSet,
3105)]
3106#[serde(rename_all = "PascalCase")]
3107#[closed_set(via = "as_str", generate_unknown, display)]
3108pub enum ConvergencePointType {
3109    /// 1 input → 1 output (linear conversion).
3110    Transform,
3111    /// 1 input → N outputs (fan-out, spawns downstream DAGs).
3112    Fork,
3113    /// N inputs → 1 output (fan-in, merges upstream results).
3114    Join,
3115    /// N inputs → 1 output (barrier, waits for all inputs).
3116    Gate,
3117    /// N inputs → 1 output (choice, picks best by policy).
3118    Select,
3119    /// 1 input → N outputs same type (replicate signal).
3120    Broadcast,
3121    /// N inputs → 1 output (fold/aggregate).
3122    Reduce,
3123    /// 1 input → 1 output + side-channel (tap for observation).
3124    Observe,
3125}
3126
3127impl ConvergencePointType {
3128    /// The closed set of point types — single source of truth that
3129    /// drives the `as_str` / Display / `FromStr` triad AND the
3130    /// `(input_arity, output_arity)` typed pair (via [`Arity`]) AND the
3131    /// `is_endomorphic` / `is_diffusive` / `is_convergent` predicate
3132    /// triple. Adding a ninth variant lands at one `ALL` entry + one
3133    /// `as_str` arm + one `input_arity` arm + one `output_arity` arm +
3134    /// one arm per predicate — exhaustively checked by the compiler
3135    /// (the `[Self; 8]` array literal forces the arity) AND by the
3136    /// per-variant truth-table contract test (a new variant must
3137    /// declare its own `(input, output)` arity pair or any future
3138    /// DAG composition validator that dispatches on
3139    /// `(input_arity, output_arity)` will silently mis-wire it).
3140    /// Closes the load-bearing classification-axis enum that
3141    /// `tatara_core::domain::compliance_binding::PointSelector::ByType`
3142    /// already dispatches against and that every `Process`'s
3143    /// `Classification.point_type` reads as the topological identity
3144    /// of the convergence point.
3145    pub const ALL: [Self; 8] = [
3146        Self::Transform,
3147        Self::Fork,
3148        Self::Join,
3149        Self::Gate,
3150        Self::Select,
3151        Self::Broadcast,
3152        Self::Reduce,
3153        Self::Observe,
3154    ];
3155
3156    /// Canonical PascalCase wire-format projection — matches the
3157    /// serde `rename_all = "PascalCase"` output verbatim AND the CRD
3158    /// `enum:` enumeration that the Process schema stamps on
3159    /// `spec.classification.pointType`. Pinned by
3160    /// `convergence_point_type_as_str_matches_serde` so a variant
3161    /// rename can't drift between the typed surface, the CRD enum,
3162    /// the YAML wire format AND any future operator-facing
3163    /// diagnostic that composes `pointType={kind}` via Display
3164    /// rather than a hard-coded literal that would silently rot.
3165    /// Display + FromStr triad over `ALL` mirrors `DataClassification`
3166    /// / `PoolPhase` / `MemberState` / `ReplacementPolicy` /
3167    /// `ReturnPolicy` / `TeardownPolicy` / `ConditionKind` /
3168    /// `ProcessPhase` / `ProcessSignal`.
3169    pub const fn as_str(self) -> &'static str {
3170        match self {
3171            Self::Transform => "Transform",
3172            Self::Fork => "Fork",
3173            Self::Join => "Join",
3174            Self::Gate => "Gate",
3175            Self::Select => "Select",
3176            Self::Broadcast => "Broadcast",
3177            Self::Reduce => "Reduce",
3178            Self::Observe => "Observe",
3179        }
3180    }
3181
3182    /// Cardinality of the input edge into this point — `One` for
3183    /// `Transform | Fork | Broadcast | Observe` (single-source
3184    /// projections), `Many` for `Join | Gate | Select | Reduce`
3185    /// (multi-source convergent reductions). Closed-set match (not
3186    /// `matches!`) so a future variant triggers the compiler's
3187    /// exhaustiveness check at this site rather than silently
3188    /// defaulting to `One`. Paired with [`Self::output_arity`] they
3189    /// form the typed `(input, output)` projection that future
3190    /// DAG composition validators (edge-cardinality checks: "you
3191    /// can't connect a Fork's output to a Transform's input
3192    /// without a Join in between") dispatch against — a single
3193    /// projection per variant means a future `Demux` / `Mux` /
3194    /// `Pipeline` point lands in exactly one cell of the
3195    /// `Arity × Arity` topology table rather than rotting against
3196    /// open-coded `== ConvergencePointType::Fork` checks.
3197    pub const fn input_arity(self) -> Arity {
3198        match self {
3199            Self::Transform | Self::Fork | Self::Broadcast | Self::Observe => Arity::One,
3200            Self::Join | Self::Gate | Self::Select | Self::Reduce => Arity::Many,
3201        }
3202    }
3203
3204    /// Cardinality of the output edge from this point — `Many` for
3205    /// `Fork | Broadcast` (fan-out), `One` for everything else.
3206    /// Closed-set match so a future variant triggers the compiler's
3207    /// exhaustiveness check. See [`Self::input_arity`] for the
3208    /// arity-pair contract + bucket definitions.
3209    pub const fn output_arity(self) -> Arity {
3210        match self {
3211            Self::Fork | Self::Broadcast => Arity::Many,
3212            Self::Transform
3213            | Self::Join
3214            | Self::Gate
3215            | Self::Select
3216            | Self::Reduce
3217            | Self::Observe => Arity::One,
3218        }
3219    }
3220
3221    /// Does this point preserve the single-input single-output
3222    /// shape? `(input, output) == (One, One)` — `Transform`
3223    /// (identity-shaped reshape) and `Observe` (passthrough +
3224    /// side-channel tap). Closed-set match so a future variant
3225    /// triggers the compiler's exhaustiveness check. Paired with
3226    /// `is_diffusive` and `is_convergent` they form the three-way
3227    /// disjoint bucket carving sealed by
3228    /// `convergence_point_type_buckets_cover_every_variant` AND
3229    /// `convergence_point_type_arity_pair_agrees_with_bucket` —
3230    /// the bridge that lets the bucket predicates and the arity
3231    /// pair name the same topology partition from two angles.
3232    pub const fn is_endomorphic(self) -> bool {
3233        match self {
3234            Self::Transform | Self::Observe => true,
3235            Self::Fork
3236            | Self::Join
3237            | Self::Gate
3238            | Self::Select
3239            | Self::Broadcast
3240            | Self::Reduce => false,
3241        }
3242    }
3243
3244    /// Does this point fan out — single input replicated/split
3245    /// across many outputs? `(input, output) == (One, Many)` —
3246    /// `Fork` and `Broadcast`. Closed-set match so a future variant
3247    /// triggers the compiler's exhaustiveness check. See
3248    /// `is_endomorphic` for the bucket-carving contract.
3249    pub const fn is_diffusive(self) -> bool {
3250        match self {
3251            Self::Fork | Self::Broadcast => true,
3252            Self::Transform
3253            | Self::Join
3254            | Self::Gate
3255            | Self::Select
3256            | Self::Reduce
3257            | Self::Observe => false,
3258        }
3259    }
3260
3261    /// Does this point reduce — many inputs collapsed to one
3262    /// output? `(input, output) == (Many, One)` — `Join`, `Gate`,
3263    /// `Select`, `Reduce`. Closed-set match so a future variant
3264    /// triggers the compiler's exhaustiveness check. See
3265    /// `is_endomorphic` for the bucket-carving contract. The
3266    /// impossible `(Many, Many)` topology bucket is pinned empty
3267    /// by `convergence_point_type_arity_pair_agrees_with_bucket`
3268    /// — a `(Many, Many)` point would mean "many independent
3269    /// inputs replicated across many independent outputs", which
3270    /// has no convergence semantics: every DAG-composition
3271    /// validator would have to special-case it. A future variant
3272    /// that wants `(Many, Many)` must first extend the bucket
3273    /// carving deliberately.
3274    pub const fn is_convergent(self) -> bool {
3275        match self {
3276            Self::Join | Self::Gate | Self::Select | Self::Reduce => true,
3277            Self::Transform | Self::Fork | Self::Broadcast | Self::Observe => false,
3278        }
3279    }
3280}
3281
3282// `impl FromStr for ConvergencePointType` +
3283// `impl tatara_lisp::ClosedSet for ConvergencePointType` +
3284// `impl std::fmt::Display for ConvergencePointType` +
3285// `pub struct UnknownConvergencePointType(pub String)` are all generated
3286// by `#[derive(tatara_closed_set::DeriveClosedSet)]` +
3287// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
3288// enum declaration above. `label` delegates to the inherent
3289// `ConvergencePointType::as_str` — the inherent name (PascalCase
3290// `as_str`) stays the load-bearing wire-vocabulary projection that
3291// matches the serde `rename_all = "PascalCase"` output AND the CRD
3292// `enum:` enumeration the Process schema stamps on
3293// `spec.classification.pointType` verbatim, while generic
3294// `T: ClosedSet` consumers reach the STABLE workspace-wide name
3295// (`label`). The `display` flag emits the
3296// `f.write_str(self.as_str())` delegation block at the same
3297// proc-macro site rather than a hand-rolled `fmt::Display` block per
3298// implementor. The auto-derived carrier label "convergence point
3299// type" matches the prior hand-rolled `#[error("unknown convergence
3300// point type: {0}")]` annotation byte-for-byte. Symmetric to the
3301// other five classification-axis closed-sets in this file
3302// (`SubstrateType` / `HorizonKind` / `OptimizationDirection` /
3303// `CalmClassification` / `DataClassification`) AND every other
3304// `#[derive(DeriveClosedSet)]` implementor across the workspace
3305// (`crate::pool::{ReplacementPolicy,MemberState,PoolPhase,ReturnPolicy}`,
3306// `crate::export::{ArtifactKind,ReportFormat,ChannelKind,ExportTrigger}`,
3307// `crate::allocation::{RequestorKind,AllocationPhase}`).
3308
3309/// Edge cardinality of a [`ConvergencePointType`]'s input or output.
3310///
3311/// Typed projection used by [`ConvergencePointType::input_arity`] and
3312/// [`ConvergencePointType::output_arity`] so DAG composition validators
3313/// reach for a closed-set enum rather than re-deriving the in/out
3314/// cardinality from variant names. `Many` is the "≥1, could be N"
3315/// cardinality — it carries no upper bound because the convergence
3316/// point's variant tag is already the structural identity; the
3317/// number itself is a runtime property of the DAG, not the typescape.
3318#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, tatara_closed_set::DeriveClosedSet)]
3319#[closed_set(via = "as_str", display, generate_unknown)]
3320pub enum Arity {
3321    /// Single edge — exactly one input or one output.
3322    One,
3323    /// Multiple edges — any number ≥ 1.
3324    Many,
3325}
3326
3327impl Arity {
3328    /// The closed set of arities — single source of truth that
3329    /// drives `as_str` / Display AND the `is_one` predicate. Adding
3330    /// a third variant (e.g. `Arity::Zero` for sinks) lands at one
3331    /// `ALL` entry + one `as_str` arm + one predicate arm —
3332    /// exhaustively checked by the compiler.
3333    pub const ALL: [Self; 2] = [Self::One, Self::Many];
3334
3335    /// Canonical projection — `"One" | "Many"`. Pinned by
3336    /// `arity_display_matches_as_str` so a future Display impl
3337    /// can't drift from the canonical string.
3338    pub const fn as_str(self) -> &'static str {
3339        match self {
3340            Self::One => "One",
3341            Self::Many => "Many",
3342        }
3343    }
3344
3345    /// Is this the single-edge cardinality? Closed-set match (not
3346    /// `matches!`) so a future variant triggers the compiler's
3347    /// exhaustiveness check.
3348    pub const fn is_one(self) -> bool {
3349        match self {
3350            Self::One => true,
3351            Self::Many => false,
3352        }
3353    }
3354
3355    /// POSITIVE-FRAMING PEER of [`Self::is_one`] — is this the
3356    /// multi-edge cardinality? Closed-set match (not `matches!`) so a
3357    /// future variant triggers the compiler's exhaustiveness check at
3358    /// this site rather than silently defaulting to `false` (which
3359    /// would mis-bucket a `Zero`-style sink variant onto the multi-
3360    /// edge path). The boolean partition is the antisymmetric image
3361    /// of [`Self::is_one`]: `One ⇒ false`, `Many ⇒ true`. Exactly
3362    /// one of `(is_one, is_many)` is true per variant on the current
3363    /// two-variant closed set — pinned by
3364    /// `arity_is_one_xor_is_many_over_all` — exactly the binary XOR
3365    /// partition already sealed on the sibling optimization-direction
3366    /// axis by `optimization_direction_prefers_lower_xor_prefers_higher`,
3367    /// on the calm axis by
3368    /// `calm_classification_monotone_xor_requires_coordination`, and
3369    /// on the data axis by
3370    /// `data_classification_public_xor_restricted`. Structural mirror
3371    /// of [`OptimizationDirection::prefers_higher`] as the positive-
3372    /// framing peer that any future dispatch on the multi-edge
3373    /// cardinality (DAG fan-out validators, edge-cardinality checks:
3374    /// "every diffusive topology point emits fan-out") reads once
3375    /// rather than re-deriving from the variant name or the
3376    /// `!is_one()` inversion at each callsite.
3377    ///
3378    /// A future third variant (a hypothetical `Zero` sentinel for
3379    /// pure sinks with no edge, which neither single nor multi
3380    /// cardinality names) MUST answer `false` here — matching the
3381    /// antisymmetric complement on [`Self::is_one`] so the binary
3382    /// XOR partition either extends into a ternary partition
3383    /// deliberately (adding a third derived-nullary predicate on the
3384    /// closed set) OR the author flips one of the existing predicates
3385    /// to reclaim the XOR. The exhaustiveness check plus the XOR pin
3386    /// force the decision at the closed set rather than silently
3387    /// bucketing the new variant onto an existing cardinality.
3388    pub const fn is_many(self) -> bool {
3389        match self {
3390            Self::One => false,
3391            Self::Many => true,
3392        }
3393    }
3394}
3395
3396// `impl fmt::Display for Arity` + `impl std::str::FromStr for Arity` +
3397// `impl tatara_lisp::ClosedSet for Arity` + `pub struct UnknownArity(pub
3398// String)` are all generated by
3399// `#[derive(tatara_closed_set::DeriveClosedSet)]` +
3400// `#[closed_set(via = "as_str", display, generate_unknown)]` on the enum
3401// declaration above. The inherent `as_str` projection stays load-bearing
3402// — the canonical `"One" | "Many"` string every DAG composition
3403// validator reads; `via = "as_str"` binds `ClosedSet::label` to the same
3404// projection so the substrate-wide `assert_display_matches_label` /
3405// `assert_closed_set_well_formed` primitives dispatch through the same
3406// byte-identical shape every other closed-set implementor across the
3407// crate publishes. Aligns `Arity` with the substrate-wide
3408// `#[derive(DeriveClosedSet)]` idiom that every other closed-set enum on
3409// this classification axis (`ConvergencePointType`, `SubstrateType`,
3410// `HorizonKind`, `OptimizationDirection`, `CalmClassification`,
3411// `DataClassification`) already carries — the last hand-rolled
3412// `impl fmt::Display` on the axis is closed at ONE substrate site.
3413
3414/// Operational substrate.
3415///
3416/// Closed-set sibling on the classification axis algebra; the `ALL` /
3417/// `as_str` / Display / `FromStr` triad mirrors
3418/// [`ConvergencePointType::ALL`], [`DataClassification::ALL`],
3419/// [`crate::pool::PoolPhase::ALL`], [`crate::pool::MemberState::ALL`],
3420/// [`crate::pool::ReplacementPolicy::ALL`],
3421/// [`crate::pool::ReturnPolicy::ALL`],
3422/// [`crate::boundary::ConditionKind::ALL`],
3423/// [`crate::lifetime::TeardownPolicy::ALL`],
3424/// [`crate::lifetime::LifetimeKind::ALL`],
3425/// [`crate::intent::IntentKind::ALL`],
3426/// [`crate::phase::ProcessPhase::ALL`],
3427/// [`crate::signal::ProcessSignal::ALL`]. The
3428/// `is_resource` / `is_policy` / `is_telemetry` predicate triple
3429/// carves the eight variants into three structurally-disjoint
3430/// substrate planes — resource (you allocate from it), policy (it
3431/// gates access for other workloads), telemetry (it observes other
3432/// workloads) — so future compliance-baseline selectors that
3433/// dispatch on a substrate's plane (resource budgets only apply to
3434/// resource substrates; policy substrates inherit baselines from
3435/// what they govern; telemetry substrates inherit baselines from
3436/// what they observe) read a typed projection rather than
3437/// re-deriving from variant names.
3438#[derive(
3439    Clone,
3440    Copy,
3441    Debug,
3442    PartialEq,
3443    Eq,
3444    Hash,
3445    PartialOrd,
3446    Ord,
3447    Serialize,
3448    Deserialize,
3449    JsonSchema,
3450    tatara_closed_set::DeriveClosedSet,
3451)]
3452#[serde(rename_all = "PascalCase")]
3453#[closed_set(via = "as_str", generate_unknown, display)]
3454pub enum SubstrateType {
3455    Financial,
3456    Compute,
3457    Network,
3458    Storage,
3459    Security,
3460    Identity,
3461    Observability,
3462    Regulatory,
3463}
3464
3465impl SubstrateType {
3466    /// The closed set of substrates — single source of truth that
3467    /// drives the `as_str` / Display / `FromStr` triad AND the
3468    /// `is_resource` / `is_policy` / `is_telemetry` predicate triple.
3469    /// Adding a ninth variant lands at one `ALL` entry + one
3470    /// `as_str` arm + one arm per predicate — exhaustively checked
3471    /// by the compiler (the `[Self; 8]` array literal forces the
3472    /// arity) AND by the per-variant plane-bucket contract test (a
3473    /// new variant must declare its own plane or any future
3474    /// compliance-baseline selector that dispatches on
3475    /// `(is_resource, is_policy, is_telemetry)` will silently
3476    /// mis-classify it). Closes the load-bearing classification-axis
3477    /// enum that
3478    /// `tatara_core::domain::compliance_binding::PointSelector::BySubstrate`
3479    /// already dispatches against and that every `Process`'s
3480    /// `Classification.substrate` reads as the operational
3481    /// substrate the convergence point lives on.
3482    pub const ALL: [Self; 8] = [
3483        Self::Financial,
3484        Self::Compute,
3485        Self::Network,
3486        Self::Storage,
3487        Self::Security,
3488        Self::Identity,
3489        Self::Observability,
3490        Self::Regulatory,
3491    ];
3492
3493    /// Canonical PascalCase wire-format projection — matches the
3494    /// serde `rename_all = "PascalCase"` output verbatim AND the CRD
3495    /// `enum:` enumeration that the Process schema stamps on
3496    /// `spec.classification.substrate`. Pinned by
3497    /// `substrate_type_as_str_matches_serde` so a variant rename
3498    /// can't drift between the typed surface, the CRD enum, the YAML
3499    /// wire format AND any future operator-facing diagnostic that
3500    /// composes `substrate={kind}` via Display rather than a
3501    /// hard-coded literal that would silently rot. Display + FromStr
3502    /// triad over `ALL` mirrors `ConvergencePointType` /
3503    /// `DataClassification` / `PoolPhase` / `MemberState` /
3504    /// `ReplacementPolicy` / `ReturnPolicy` / `TeardownPolicy` /
3505    /// `ConditionKind` / `ProcessPhase` / `ProcessSignal`.
3506    pub const fn as_str(self) -> &'static str {
3507        match self {
3508            Self::Financial => "Financial",
3509            Self::Compute => "Compute",
3510            Self::Network => "Network",
3511            Self::Storage => "Storage",
3512            Self::Security => "Security",
3513            Self::Identity => "Identity",
3514            Self::Observability => "Observability",
3515            Self::Regulatory => "Regulatory",
3516        }
3517    }
3518
3519    /// Is this a resource substrate — one you allocate budgets from
3520    /// to run workloads? `Financial | Compute | Network | Storage`.
3521    /// Closed-set match (not `matches!`) so a future variant
3522    /// triggers the compiler's exhaustiveness check at this site
3523    /// rather than silently defaulting to `false`. Paired with
3524    /// `is_policy` and `is_telemetry` they form the three-way
3525    /// disjoint plane carving sealed by
3526    /// `substrate_type_buckets_cover_every_variant` — the bridge
3527    /// that lets future compliance-baseline selectors dispatch on
3528    /// plane without re-deriving from variant names.
3529    pub const fn is_resource(self) -> bool {
3530        match self {
3531            Self::Financial | Self::Compute | Self::Network | Self::Storage => true,
3532            Self::Security | Self::Identity | Self::Observability | Self::Regulatory => false,
3533        }
3534    }
3535
3536    /// Is this a policy substrate — one that gates access or
3537    /// compliance for other workloads rather than carrying their
3538    /// payload? `Security | Identity | Regulatory`. Closed-set match
3539    /// so a future variant triggers the compiler's exhaustiveness
3540    /// check. See `is_resource` for the bucket-carving contract.
3541    pub const fn is_policy(self) -> bool {
3542        match self {
3543            Self::Security | Self::Identity | Self::Regulatory => true,
3544            Self::Financial
3545            | Self::Compute
3546            | Self::Network
3547            | Self::Storage
3548            | Self::Observability => false,
3549        }
3550    }
3551
3552    /// Is this a telemetry substrate — one that passively observes
3553    /// other workloads (metrics, logs, traces) without carrying
3554    /// their payload or gating their access? `Observability` only.
3555    /// Closed-set match so a future variant triggers the compiler's
3556    /// exhaustiveness check. See `is_resource` for the
3557    /// bucket-carving contract. A telemetry substrate's compliance
3558    /// baseline is inherited from what it observes — the singleton
3559    /// bucket is intentional, not a placeholder.
3560    pub const fn is_telemetry(self) -> bool {
3561        match self {
3562            Self::Observability => true,
3563            Self::Financial
3564            | Self::Compute
3565            | Self::Network
3566            | Self::Storage
3567            | Self::Security
3568            | Self::Identity
3569            | Self::Regulatory => false,
3570        }
3571    }
3572}
3573
3574// `impl FromStr for SubstrateType` +
3575// `impl tatara_lisp::ClosedSet for SubstrateType` +
3576// `impl std::fmt::Display for SubstrateType` +
3577// `pub struct UnknownSubstrateType(pub String)` are all generated by
3578// `#[derive(tatara_closed_set::DeriveClosedSet)]` +
3579// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
3580// enum declaration above. The auto-derived carrier label "substrate
3581// type" matches the prior hand-rolled `#[error("unknown substrate
3582// type: {0}")]` annotation byte-for-byte. See the retrofit comment
3583// block on [`ConvergencePointType`] for the canonical narrative.
3584
3585/// How long the point runs. Flattened struct-of-optionals so the OpenAPI
3586/// schema carries a single `kind` discriminator without per-variant merge.
3587#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
3588#[serde(rename_all = "camelCase")]
3589pub struct Horizon {
3590    #[serde(default)]
3591    pub kind: HorizonKind,
3592    /// Metric being optimized (Asymptotic only).
3593    #[serde(default, skip_serializing_if = "Option::is_none")]
3594    pub metric: Option<String>,
3595    /// Whether to minimize or maximize the metric (Asymptotic only).
3596    #[serde(default, skip_serializing_if = "Option::is_none")]
3597    pub direction: Option<OptimizationDirection>,
3598    /// Rate threshold considered healthy (Asymptotic only).
3599    #[serde(default, skip_serializing_if = "Option::is_none")]
3600    pub healthy_rate_threshold: Option<f64>,
3601}
3602
3603/// The shape of a convergence horizon's lifetime — does the point
3604/// run toward a fixed point and terminate, or run in perpetuity with
3605/// a rate signal?
3606///
3607/// Closed-set sibling on the classification axis algebra; the `ALL` /
3608/// `as_str` / Display / `FromStr` triad mirrors
3609/// [`ConvergencePointType::ALL`], [`SubstrateType::ALL`],
3610/// [`DataClassification::ALL`], [`CalmClassification::ALL`],
3611/// [`OptimizationDirection::ALL`], [`crate::pool::PoolPhase::ALL`],
3612/// [`crate::pool::MemberState::ALL`],
3613/// [`crate::pool::ReplacementPolicy::ALL`],
3614/// [`crate::pool::ReturnPolicy::ALL`],
3615/// [`crate::boundary::ConditionKind::ALL`],
3616/// [`crate::lifetime::TeardownPolicy::ALL`],
3617/// [`crate::lifetime::LifetimeKind::ALL`],
3618/// [`crate::intent::IntentKind::ALL`],
3619/// [`crate::phase::ProcessPhase::ALL`],
3620/// [`crate::signal::ProcessSignal::ALL`]. The [`Self::terminates`]
3621/// predicate is the load-bearing horizon-shape primitive — schedulers
3622/// asking "will this Process ever reach `Reaped` via natural
3623/// termination?" read it as the typed image of the lattice ordering
3624/// (`Bounded ≤ Asymptotic` because the bounded horizon strictly
3625/// refines the asymptotic one by also terminating) rather than
3626/// re-deriving from the variant name. The
3627/// [`Self::requires_metric_axes`] predicate is the typed validity
3628/// witness for the [`Horizon`] struct's three `Option<…>` fields
3629/// (`metric`, `direction`, `healthy_rate_threshold`) — they're
3630/// `Some(_)` iff the kind requires them, so the implicit invariant
3631/// the optionality encodes becomes a checkable per-kind predicate
3632/// instead of operator folklore.
3633#[derive(
3634    Clone,
3635    Copy,
3636    Debug,
3637    PartialEq,
3638    Eq,
3639    Hash,
3640    Serialize,
3641    Deserialize,
3642    JsonSchema,
3643    Default,
3644    tatara_closed_set::DeriveClosedSet,
3645)]
3646#[serde(rename_all = "PascalCase")]
3647#[closed_set(via = "as_str", generate_unknown, display)]
3648pub enum HorizonKind {
3649    /// Has a fixed point — distance reaches 0 and terminates.
3650    #[default]
3651    Bounded,
3652    /// Runs in perpetuity — rate is the health signal, not distance.
3653    Asymptotic,
3654}
3655
3656impl HorizonKind {
3657    /// The closed set of horizon kinds — single source of truth that
3658    /// drives the `as_str` / Display / `FromStr` triad AND the
3659    /// `terminates` predicate AND the `requires_metric_axes` shape-
3660    /// validity witness. Adding a third variant (e.g. a `Periodic`
3661    /// sentinel for "terminates on each window boundary then
3662    /// re-arms", which neither perpetually-running nor singularly-
3663    /// terminating names) lands at one `ALL` entry + one `as_str`
3664    /// arm + one `terminates` arm + one `requires_metric_axes` arm —
3665    /// exhaustively checked by the compiler (the `[Self; 2]` array
3666    /// literal forces the arity) AND by the per-variant truth-table
3667    /// tests (a new variant must declare its own termination AND
3668    /// metric-axes requirement, or every scheduler / horizon-shape
3669    /// validator will silently bucket it). Closes the load-bearing
3670    /// classification sub-axis that the `Horizon.kind` field threads
3671    /// through every `Classification.horizon` field on every
3672    /// Process — the last open sibling on the classification axis
3673    /// algebra after `OptimizationDirection` (980a318),
3674    /// `CalmClassification` (da3430c), `SubstrateType` (b9d7b3b),
3675    /// `ConvergencePointType` (7941527), `Arity`, and
3676    /// `DataClassification` (81bffa0).
3677    pub const ALL: [Self; 2] = [Self::Bounded, Self::Asymptotic];
3678
3679    /// Canonical PascalCase wire-format projection — matches the
3680    /// serde `rename_all = "PascalCase"` output verbatim AND the CRD
3681    /// `enum:` enumeration the Process schema stamps on
3682    /// `spec.classification.horizon.kind`. Pinned by
3683    /// `horizon_kind_as_str_matches_serde` so a variant rename
3684    /// can't drift between the typed surface, the CRD enum, the
3685    /// YAML wire format AND any future operator-facing diagnostic
3686    /// composing `horizon.kind={kind}` via Display rather than a
3687    /// hard-coded literal. Display + FromStr triad over `ALL`
3688    /// mirrors every sibling closed-set enum in this crate.
3689    pub const fn as_str(self) -> &'static str {
3690        match self {
3691            Self::Bounded => "Bounded",
3692            Self::Asymptotic => "Asymptotic",
3693        }
3694    }
3695
3696    /// LOAD-BEARING HORIZON-SHAPE PRIMITIVE: does this kind terminate
3697    /// naturally — i.e. does it have a fixed point that
3698    /// `ConvergenceDistance` can reach? Closed-set match (not
3699    /// `matches!`) so a future variant triggers the compiler's
3700    /// exhaustiveness check rather than silently defaulting to
3701    /// `false` (which would silently mis-route a terminating
3702    /// variant through the asymptotic rate-window evaluator) or
3703    /// `true` (which would silently invent a fixed point for a
3704    /// perpetual variant). `Bounded ⇒ true`, `Asymptotic ⇒ false`
3705    /// is the typed image of the documented lattice ordering
3706    /// `Bounded ≤ Asymptotic` — the bounded horizon strictly refines
3707    /// the asymptotic one BY ALSO TERMINATING. Future schedulers
3708    /// asking "will this Process reach `Reaped` via natural
3709    /// termination?" read this predicate, and the tatara-lattice
3710    /// `Lattice for Horizon` impl (which currently dispatches on
3711    /// `self.kind == HorizonKind::Bounded` at three sites) can be
3712    /// recast in a future run to read `self.kind.terminates()` so
3713    /// the lattice basis is the typed primitive rather than a
3714    /// variant-name comparison.
3715    pub const fn terminates(self) -> bool {
3716        match self {
3717            Self::Bounded => true,
3718            Self::Asymptotic => false,
3719        }
3720    }
3721
3722    /// LOAD-BEARING SHAPE-VALIDITY WITNESS: does this kind require
3723    /// the three asymptotic-only [`Horizon`] axes (`metric`,
3724    /// `direction`, `healthy_rate_threshold`) to be `Some(_)`?
3725    /// Closed-set match (not `matches!`) so a future variant
3726    /// triggers the compiler's exhaustiveness check rather than
3727    /// silently defaulting to `false` (which would silently let an
3728    /// asymptotic-shaped variant ship with missing metric axes and
3729    /// trip the rate-window evaluator at runtime). `Bounded ⇒
3730    /// false`, `Asymptotic ⇒ true` is the typed image of the
3731    /// optionality the [`Horizon`] struct encodes via three
3732    /// `Option<…>` fields — the implicit invariant ("Asymptotic
3733    /// only" in the field docs) is now a checkable per-kind
3734    /// predicate. Future horizon-shape validators (CRD admission,
3735    /// `tatara-check` form linter, Lisp authoring-time predicate)
3736    /// read this rather than re-deriving from variant names.
3737    /// Pinned as the antisymmetric partner of [`Self::terminates`]
3738    /// — exactly one of `(terminates, requires_metric_axes)` is
3739    /// true per variant — by
3740    /// `horizon_kind_terminate_xor_requires_metric_axes`.
3741    pub const fn requires_metric_axes(self) -> bool {
3742        match self {
3743            Self::Bounded => false,
3744            Self::Asymptotic => true,
3745        }
3746    }
3747}
3748
3749// `impl FromStr for HorizonKind` +
3750// `impl tatara_lisp::ClosedSet for HorizonKind` +
3751// `impl std::fmt::Display for HorizonKind` +
3752// `pub struct UnknownHorizonKind(pub String)` are all generated by
3753// `#[derive(tatara_closed_set::DeriveClosedSet)]` +
3754// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
3755// enum declaration above. The auto-derived carrier label "horizon
3756// kind" matches the prior hand-rolled `#[error("unknown horizon
3757// kind: {0}")]` annotation byte-for-byte. See the retrofit comment
3758// block on [`ConvergencePointType`] for the canonical narrative.
3759
3760impl Horizon {
3761    pub fn bounded() -> Self {
3762        Self::default()
3763    }
3764
3765    pub fn asymptotic(
3766        metric: impl Into<String>,
3767        direction: OptimizationDirection,
3768        threshold: f64,
3769    ) -> Self {
3770        Self {
3771            kind: HorizonKind::Asymptotic,
3772            metric: Some(metric.into()),
3773            direction: Some(direction),
3774            healthy_rate_threshold: Some(threshold),
3775        }
3776    }
3777}
3778
3779/// Direction of asymptotic optimization — does the metric trend
3780/// downward (cost / latency / error rate) or upward
3781/// (throughput / coverage / revenue)?
3782///
3783/// Closed-set sibling on the classification axis algebra; the `ALL` /
3784/// `as_str` / Display / `FromStr` triad mirrors
3785/// [`ConvergencePointType::ALL`], [`SubstrateType::ALL`],
3786/// [`DataClassification::ALL`], [`CalmClassification::ALL`],
3787/// [`crate::pool::PoolPhase::ALL`], [`crate::pool::MemberState::ALL`],
3788/// [`crate::pool::ReplacementPolicy::ALL`],
3789/// [`crate::pool::ReturnPolicy::ALL`],
3790/// [`crate::boundary::ConditionKind::ALL`],
3791/// [`crate::lifetime::TeardownPolicy::ALL`],
3792/// [`crate::lifetime::LifetimeKind::ALL`],
3793/// [`crate::intent::IntentKind::ALL`],
3794/// [`crate::phase::ProcessPhase::ALL`],
3795/// [`crate::signal::ProcessSignal::ALL`]. The
3796/// [`Self::is_improvement`] predicate is the load-bearing
3797/// optimization primitive — `Asymptotic` horizons read it as the
3798/// typed image of "did this metric sample improve over the last
3799/// one?" rather than re-deriving `<` vs `>` from the variant name
3800/// at every consumer site (rate-window evaluators, breathe-band
3801/// regression detectors, asymptotic-health probes).
3802#[derive(
3803    Clone,
3804    Copy,
3805    Debug,
3806    PartialEq,
3807    Eq,
3808    Hash,
3809    Serialize,
3810    Deserialize,
3811    JsonSchema,
3812    Default,
3813    tatara_closed_set::DeriveClosedSet,
3814)]
3815#[serde(rename_all = "PascalCase")]
3816#[closed_set(via = "as_str", generate_unknown, display)]
3817pub enum OptimizationDirection {
3818    /// Cost / latency / error rate — lower is better. The default for
3819    /// an under-specified `Asymptotic` horizon so an unannotated
3820    /// metric can't silently flip the rate-window evaluator's polarity
3821    /// (a future `Maximize`-default-via-rename would silently invert
3822    /// every existing alert that treats decreasing rate as healthy).
3823    #[default]
3824    Minimize,
3825    /// Throughput / coverage / revenue — higher is better.
3826    Maximize,
3827}
3828
3829impl OptimizationDirection {
3830    /// The closed set of optimization directions — single source of
3831    /// truth that drives the `as_str` / Display / `FromStr` triad AND
3832    /// the `prefers_lower` partition AND the `is_improvement`
3833    /// load-bearing primitive AND both `From` bridge arms. Adding a
3834    /// third variant (e.g. a `Stabilize` sentinel for "drive toward
3835    /// a target value", which neither minimization nor maximization
3836    /// names) lands at one `ALL` entry + one `as_str` arm + one
3837    /// `prefers_lower` arm + one `is_improvement` arm + two bridge
3838    /// arms — exhaustively checked by the compiler (the `[Self; 2]`
3839    /// array literal forces the arity) AND by the per-variant
3840    /// truth-table tests (a new variant must declare its own
3841    /// improvement semantics, or every asymptotic-health probe will
3842    /// silently bucket it). Closes the load-bearing classification
3843    /// sub-axis that the `Horizon.direction` field threads through
3844    /// every `Asymptotic` Process.
3845    pub const ALL: [Self; 2] = [Self::Minimize, Self::Maximize];
3846
3847    /// Canonical PascalCase wire-format projection — matches the serde
3848    /// `rename_all = "PascalCase"` output verbatim AND the CRD `enum:`
3849    /// enumeration the Process schema stamps on
3850    /// `spec.classification.horizon.direction`. Pinned by
3851    /// `optimization_direction_as_str_matches_serde` so a variant
3852    /// rename can't drift between the typed surface, the CRD enum, the
3853    /// YAML wire format AND any future operator-facing diagnostic
3854    /// composed as `direction={kind}` via Display rather than a
3855    /// hard-coded literal. Display + `FromStr` triad over `ALL`
3856    /// mirrors every sibling closed-set enum in this crate.
3857    pub const fn as_str(self) -> &'static str {
3858        match self {
3859            Self::Minimize => "Minimize",
3860            Self::Maximize => "Maximize",
3861        }
3862    }
3863
3864    /// Does this direction prefer numerically lower values?
3865    /// Closed-set match (not `matches!`) so a future variant triggers
3866    /// the compiler's exhaustiveness check at this site rather than
3867    /// silently defaulting to `false` (which would mis-bucket a
3868    /// `Stabilize`-style variant onto the maximization path). The
3869    /// boolean partition is the algebraic shape of an optimization
3870    /// direction: `Minimize ⇒ true`, `Maximize ⇒ false`. Mirrors
3871    /// [`CalmClassification::requires_coordination`] — a two-variant
3872    /// truth-table that any future dispatch on a per-direction policy
3873    /// (rate-window evaluator polarity, breathe-band regression
3874    /// detector sign, asymptotic-health threshold direction) reads
3875    /// once rather than re-deriving from the variant name.
3876    pub const fn prefers_lower(self) -> bool {
3877        match self {
3878            Self::Minimize => true,
3879            Self::Maximize => false,
3880        }
3881    }
3882
3883    /// POSITIVE-FRAMING PEER of [`Self::prefers_lower`] — does this
3884    /// direction prefer numerically higher values? Closed-set match
3885    /// (not `matches!`) so a future variant triggers the compiler's
3886    /// exhaustiveness check at this site rather than silently
3887    /// defaulting to `false` (which would mis-bucket a `Stabilize`-
3888    /// style variant onto the minimization path). The boolean
3889    /// partition is the antisymmetric image of [`Self::prefers_lower`]:
3890    /// `Minimize ⇒ false`, `Maximize ⇒ true`. Exactly one of
3891    /// `(prefers_lower, prefers_higher)` is true per variant on the
3892    /// current two-variant closed set — pinned by
3893    /// `optimization_direction_prefers_lower_xor_prefers_higher` —
3894    /// exactly the binary XOR partition already sealed on the sibling
3895    /// calm axis by `calm_classification_monotone_xor_requires_coordination`
3896    /// and on the sibling data axis by `data_classification_public_xor_restricted`.
3897    /// Structural mirror of [`CalmClassification::is_monotone`] as the
3898    /// positive-framing peer that any future dispatch on the higher-
3899    /// is-better polarity (throughput / coverage / revenue rate-window
3900    /// evaluator, breathe-band regression detector's positive sign)
3901    /// reads once rather than re-deriving from either the variant name
3902    /// or the `!prefers_lower()` inversion at each callsite.
3903    ///
3904    /// A future third variant (a hypothetical `Stabilize` sentinel for
3905    /// "drive toward a target value", which neither minimization nor
3906    /// maximization names) MUST answer `false` here — matching the
3907    /// antisymmetric complement on [`Self::prefers_lower`] so the
3908    /// binary XOR partition either extends into a ternary partition
3909    /// deliberately (adding a third derived-nullary predicate on the
3910    /// closed set) OR the author flips one of the existing predicates
3911    /// to reclaim the XOR. The exhaustiveness check plus the XOR pin
3912    /// force the decision at the closed set rather than silently
3913    /// bucketing the new variant onto an existing polarity.
3914    pub const fn prefers_higher(self) -> bool {
3915        match self {
3916            Self::Minimize => false,
3917            Self::Maximize => true,
3918        }
3919    }
3920
3921    /// LOAD-BEARING OPTIMIZATION PRIMITIVE: under this direction, is
3922    /// `after` strictly better than `before`? Closed-set match so a
3923    /// future variant triggers the compiler's exhaustiveness check
3924    /// rather than silently defaulting to `false` (which would
3925    /// silently mark every sample as a regression). For `Minimize`,
3926    /// improvement means `after < before`; for `Maximize`, `after >
3927    /// before`. Strict inequality so a no-op sample (equal values) is
3928    /// NOT counted as improvement — pinned by
3929    /// `optimization_direction_no_op_is_not_improvement`, which
3930    /// guarantees a flatlined rate-window evaluator doesn't silently
3931    /// keep claiming "still improving" forever and skipping the
3932    /// healthy-rate-threshold gate. NaN on either operand short-
3933    /// circuits to `false` (no improvement claim from indeterminate
3934    /// data) via the standard `PartialOrd` behavior — pinned by
3935    /// `optimization_direction_nan_is_not_improvement`. The
3936    /// asymmetry contract (`is_improvement(a, b)` xor
3937    /// `is_improvement(b, a)` for distinct finite samples) is pinned
3938    /// by `optimization_direction_is_improvement_is_antisymmetric`,
3939    /// the algebraic shape that every asymptotic-health rate-window
3940    /// evaluator depends on to avoid double-counting an improvement
3941    /// as a regression on the reverse traversal.
3942    pub fn is_improvement(self, before: f64, after: f64) -> bool {
3943        match self {
3944            Self::Minimize => after < before,
3945            Self::Maximize => after > before,
3946        }
3947    }
3948}
3949
3950// `impl FromStr for OptimizationDirection` +
3951// `impl tatara_lisp::ClosedSet for OptimizationDirection` +
3952// `impl std::fmt::Display for OptimizationDirection` +
3953// `pub struct UnknownOptimizationDirection(pub String)` are all
3954// generated by `#[derive(tatara_closed_set::DeriveClosedSet)]` +
3955// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
3956// enum declaration above. The auto-derived carrier label
3957// "optimization direction" matches the prior hand-rolled
3958// `#[error("unknown optimization direction: {0}")]` annotation
3959// byte-for-byte. See the retrofit comment block on
3960// [`ConvergencePointType`] for the canonical narrative.
3961
3962/// CALM theorem classification — determines whether coordination is required.
3963///
3964/// Closed-set sibling on the classification axis algebra; the `ALL` /
3965/// `as_str` / Display / `FromStr` triad mirrors
3966/// [`ConvergencePointType::ALL`], [`SubstrateType::ALL`],
3967/// [`DataClassification::ALL`], [`crate::pool::PoolPhase::ALL`],
3968/// [`crate::pool::MemberState::ALL`], [`crate::pool::ReplacementPolicy::ALL`],
3969/// [`crate::pool::ReturnPolicy::ALL`],
3970/// [`crate::boundary::ConditionKind::ALL`],
3971/// [`crate::lifetime::TeardownPolicy::ALL`],
3972/// [`crate::lifetime::LifetimeKind::ALL`],
3973/// [`crate::intent::IntentKind::ALL`],
3974/// [`crate::phase::ProcessPhase::ALL`],
3975/// [`crate::signal::ProcessSignal::ALL`]. The
3976/// [`Self::requires_coordination`] predicate is the CALM theorem
3977/// keystone — Hellerstein's "Consistency As Logical Monotonicity"
3978/// states that a program can be distributed without coordination iff
3979/// it computes a monotone function, so `Monotone ⇒ no coordination`
3980/// and `NonMonotone ⇒ requires coordination` is a typed image of the
3981/// theorem itself rather than a runtime convention. Future reconciler
3982/// dispatch on `calm.requires_coordination()` (Raft for non-monotone
3983/// writes; gossip for monotone ones) reads this projection rather
3984/// than re-deriving from variant names.
3985#[derive(
3986    Clone,
3987    Copy,
3988    Debug,
3989    PartialEq,
3990    Eq,
3991    Hash,
3992    Serialize,
3993    Deserialize,
3994    JsonSchema,
3995    Default,
3996    tatara_closed_set::DeriveClosedSet,
3997)]
3998#[serde(rename_all = "PascalCase")]
3999#[closed_set(via = "as_str", generate_unknown, display)]
4000pub enum CalmClassification {
4001    /// Can be distributed without coordination (CALM ⇒ the program
4002    /// computes a monotone function).
4003    #[default]
4004    Monotone,
4005    /// Requires coordination (CALM ⇒ the program is not monotone).
4006    NonMonotone,
4007}
4008
4009impl CalmClassification {
4010    /// The closed set of CALM classifications — single source of truth
4011    /// that drives the `as_str` / Display / `FromStr` triad AND the
4012    /// `requires_coordination` predicate. Adding a third variant
4013    /// (e.g. a `ConditionallyMonotone` sentinel for ops that are
4014    /// monotone under a witness, like CRDT joins under a fixed
4015    /// schema) lands at one `ALL` entry + one `as_str` arm + one
4016    /// predicate arm + one bridge-pair arm — exhaustively checked by
4017    /// the compiler (the `[Self; 2]` array literal forces the arity)
4018    /// AND by the per-variant predicate truth-table test (a new
4019    /// variant must declare its own coordination requirement or any
4020    /// future reconciler-side dispatch will silently bucket it).
4021    /// Closes the load-bearing classification-axis enum that the
4022    /// `Classification.calm` field exposes to every Process and that
4023    /// [`tatara_lattice`]'s boolean-lattice `Lattice for
4024    /// CalmClassification` impl reads via [`Self::requires_coordination`]
4025    /// as the lattice's `top()` predicate.
4026    pub const ALL: [Self; 2] = [Self::Monotone, Self::NonMonotone];
4027
4028    /// Canonical PascalCase wire-format projection — matches the
4029    /// serde `rename_all = "PascalCase"` output verbatim AND the CRD
4030    /// `enum:` enumeration that the Process schema stamps on
4031    /// `spec.classification.calm`. Pinned by
4032    /// `calm_classification_as_str_matches_serde` so a variant rename
4033    /// can't drift between the typed surface, the CRD enum, the YAML
4034    /// wire format AND any future operator-facing diagnostic that
4035    /// composes `calm={kind}` via Display rather than a hard-coded
4036    /// literal that would silently rot. Display + FromStr triad over
4037    /// `ALL` mirrors every sibling closed-set enum in this crate.
4038    pub const fn as_str(self) -> &'static str {
4039        match self {
4040            Self::Monotone => "Monotone",
4041            Self::NonMonotone => "NonMonotone",
4042        }
4043    }
4044
4045    /// CALM-THEOREM KEYSTONE: does this classification require
4046    /// distributed coordination? Closed-set match (not `matches!`) so
4047    /// a future variant triggers the compiler's exhaustiveness check
4048    /// at this site rather than silently defaulting to `false` and
4049    /// shipping a non-monotone operation onto the no-coordination
4050    /// path. The theorem (Hellerstein 2010) states that a program can
4051    /// be distributed without coordination iff it computes a monotone
4052    /// function — `Monotone ⇒ false` and `NonMonotone ⇒ true` is the
4053    /// typed image of that biconditional. Consumers (future reconciler
4054    /// dispatch between Raft writes and gossip propagation; current
4055    /// `tatara_lattice` boolean-lattice ordering where `Monotone ≤
4056    /// NonMonotone`) read this predicate rather than re-deriving from
4057    /// variant names.
4058    pub const fn requires_coordination(self) -> bool {
4059        match self {
4060            Self::Monotone => false,
4061            Self::NonMonotone => true,
4062        }
4063    }
4064
4065    /// CALM-THEOREM POSITIVE FRAMING: is this classification monotone
4066    /// — i.e. can it be distributed WITHOUT coordination per the
4067    /// biconditional half of Hellerstein's CALM theorem
4068    /// (Consistency As Logical Monotonicity)? Closed-set match (not
4069    /// `matches!`) so a future variant triggers the compiler's
4070    /// exhaustiveness check at this site rather than silently
4071    /// defaulting to `false` (which would silently mark a genuinely
4072    /// monotone operation as coordination-required and pay the Raft
4073    /// tax indefinitely) or `true` (which would silently ship a non-
4074    /// monotone operation onto the no-coordination path). The typed
4075    /// image of the theorem's LOAD-BEARING half: `Monotone ⇒ true`
4076    /// and `NonMonotone ⇒ false` is the antisymmetric partner of
4077    /// [`Self::requires_coordination`] — exactly one of
4078    /// `(is_monotone, requires_coordination)` is true per variant —
4079    /// pinned by `calm_classification_monotone_xor_requires_coordination`.
4080    /// Mirror of [`HorizonKind::terminates`] /
4081    /// [`HorizonKind::requires_metric_axes`] on the horizon axis:
4082    /// both closed sets are binary and both publish their two
4083    /// derived-nullary-bool projections at ONE site each so the axis
4084    /// carves into complementary buckets by construction. The
4085    /// positive framing is the substrate primitive Hellerstein
4086    /// himself names ("Consistency As Logical Monotonicity"); a
4087    /// future consumer asking "can this Process participate in
4088    /// gossip-only writes?" reads [`Self::is_monotone`] rather than
4089    /// re-deriving via `!requires_coordination()` at the callsite.
4090    pub const fn is_monotone(self) -> bool {
4091        match self {
4092            Self::Monotone => true,
4093            Self::NonMonotone => false,
4094        }
4095    }
4096}
4097
4098// `impl FromStr for CalmClassification` +
4099// `impl tatara_lisp::ClosedSet for CalmClassification` +
4100// `impl std::fmt::Display for CalmClassification` +
4101// `pub struct UnknownCalmClassification(pub String)` are all generated
4102// by `#[derive(tatara_closed_set::DeriveClosedSet)]` +
4103// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
4104// enum declaration above. The auto-derived carrier label
4105// "calm classification" matches the prior hand-rolled
4106// `#[error("unknown calm classification: {0}")]` annotation
4107// byte-for-byte. See the retrofit comment block on
4108// [`ConvergencePointType`] for the canonical narrative.
4109
4110/// Data sensitivity, drives compliance baseline selection.
4111///
4112/// Sibling closed-set on the classification axis algebra; the `ALL` /
4113/// `as_str` / Display / `FromStr` triad mirrors
4114/// [`crate::pool::PoolPhase::ALL`], [`crate::pool::MemberState::ALL`],
4115/// [`crate::pool::ReplacementPolicy::ALL`],
4116/// [`crate::pool::ReturnPolicy::ALL`],
4117/// [`crate::boundary::ConditionKind::ALL`],
4118/// [`crate::lifetime::TeardownPolicy::ALL`],
4119/// [`crate::lifetime::LifetimeKind::ALL`],
4120/// [`crate::intent::IntentKind::ALL`],
4121/// [`crate::phase::ProcessPhase::ALL`],
4122/// [`crate::signal::ProcessSignal::ALL`].
4123#[derive(
4124    Clone,
4125    Copy,
4126    Debug,
4127    PartialEq,
4128    Eq,
4129    PartialOrd,
4130    Ord,
4131    Hash,
4132    Serialize,
4133    Deserialize,
4134    JsonSchema,
4135    Default,
4136    tatara_closed_set::DeriveClosedSet,
4137)]
4138#[serde(rename_all = "PascalCase")]
4139#[closed_set(via = "as_str", generate_unknown, display)]
4140pub enum DataClassification {
4141    Public,
4142    #[default]
4143    Internal,
4144    Confidential,
4145    Pii,
4146    Phi,
4147    Pci,
4148}
4149
4150impl DataClassification {
4151    /// The closed set of data classifications — single source of truth
4152    /// that drives the `as_str` / Display / `FromStr` triad AND the
4153    /// `sensitivity_rank` total-order projection AND the
4154    /// `is_restricted` / `is_regulated` predicate pair. Adding a
4155    /// seventh variant lands at one `ALL` entry + one `as_str` arm +
4156    /// one `sensitivity_rank` arm + one arm per predicate —
4157    /// exhaustively checked by the compiler (the `[Self; 6]` array
4158    /// literal forces the arity) AND by the per-variant truth-table
4159    /// contract test (a new variant must declare its own
4160    /// `(is_restricted, is_regulated)` bucket or any future
4161    /// compliance-baseline auto-selector that dispatches on the pair
4162    /// will silently bucket it into the wrong sensitivity column).
4163    /// This closes the sixth classification-axis enum and the closure
4164    /// is consumed by [`tatara_lattice`]'s total-order `Lattice` impl
4165    /// via [`Self::sensitivity_rank`] so the lattice ordering no
4166    /// longer rides silently on declaration order.
4167    pub const ALL: [Self; 6] = [
4168        Self::Public,
4169        Self::Internal,
4170        Self::Confidential,
4171        Self::Pii,
4172        Self::Phi,
4173        Self::Pci,
4174    ];
4175
4176    /// Canonical PascalCase wire-format projection — matches the
4177    /// serde `rename_all = "PascalCase"` output verbatim AND the CRD
4178    /// `enum:` enumeration that the Process schema stamps on
4179    /// `spec.classification.dataClassification`. Pinned by
4180    /// `data_classification_as_str_matches_serde` so a variant rename
4181    /// can't drift between the typed surface, the CRD enum, the YAML
4182    /// wire format AND any future operator-facing diagnostic that
4183    /// composes `dataClassification={class}` via Display rather than
4184    /// a hard-coded literal that would silently rot. Display +
4185    /// FromStr triad over `ALL` mirrors `PoolPhase` / `MemberState` /
4186    /// `ReplacementPolicy` / `ReturnPolicy` / `TeardownPolicy` /
4187    /// `ConditionKind` / `ProcessPhase` / `ProcessSignal`.
4188    pub const fn as_str(self) -> &'static str {
4189        match self {
4190            Self::Public => "Public",
4191            Self::Internal => "Internal",
4192            Self::Confidential => "Confidential",
4193            Self::Pii => "Pii",
4194            Self::Phi => "Phi",
4195            Self::Pci => "Pci",
4196        }
4197    }
4198
4199    /// Explicit total-order rank, sealed at one site so the lattice
4200    /// ordering stops riding silently on declaration order. Pre-lift
4201    /// the tatara-lattice `Lattice for DataClassification` impl
4202    /// compared variants via `(*self as u8) <= (*other as u8)`, so a
4203    /// future variant inserted in the middle of the enum (say a
4204    /// `Restricted` between `Internal` and `Confidential`) would
4205    /// silently shift every subsequent variant's `as u8` value AND
4206    /// the lattice's `leq` relation — no compile error, no test
4207    /// failure, but every compliance-baseline comparison
4208    /// downstream would have moved by one slot. Post-lift the rank
4209    /// is declared explicitly per variant; an insertion forces the
4210    /// author to pick a rank deliberately (and
4211    /// `data_classification_rank_is_strictly_monotone_over_all`
4212    /// pins the existing six variants at 0..6 so the lattice's
4213    /// total order remains the documented
4214    /// `Public < Internal < Confidential < Pii < Phi < Pci`).
4215    pub const fn sensitivity_rank(self) -> u8 {
4216        match self {
4217            Self::Public => 0,
4218            Self::Internal => 1,
4219            Self::Confidential => 2,
4220            Self::Pii => 3,
4221            Self::Phi => 4,
4222            Self::Pci => 5,
4223        }
4224    }
4225
4226    /// Is this classification subject to external regulatory regime
4227    /// (HIPAA / PCI-DSS / GDPR-style data-subject controls)?
4228    /// Closed-set match (not `matches!`) so a future variant triggers
4229    /// the compiler's exhaustiveness check at this site rather than
4230    /// silently defaulting to `false`. Paired with `is_restricted`
4231    /// they form the two-axis projection that future
4232    /// compliance-baseline auto-selectors dispatch against —
4233    /// `(false, false)` ⇒ freely distributable (`Public`);
4234    /// `(false, true)` ⇒ access-controlled but not regulated
4235    /// (`Internal | Confidential`); `(true, true)` ⇒ regulated data
4236    /// that implies access control (`Pii | Phi | Pci`). The
4237    /// impossible bucket `(true, false)` — regulated data without
4238    /// access control — is pinned empty by
4239    /// `data_classification_regulated_implies_restricted`.
4240    pub const fn is_regulated(self) -> bool {
4241        match self {
4242            Self::Pii | Self::Phi | Self::Pci => true,
4243            Self::Public | Self::Internal | Self::Confidential => false,
4244        }
4245    }
4246
4247    /// Does this classification require access controls beyond
4248    /// freely-distributable? Closed-set match so a future variant
4249    /// triggers the compiler's exhaustiveness check. See
4250    /// `is_regulated` for the predicate-pair contract + bucket
4251    /// definitions.
4252    pub const fn is_restricted(self) -> bool {
4253        match self {
4254            Self::Public => false,
4255            Self::Internal | Self::Confidential | Self::Pii | Self::Phi | Self::Pci => true,
4256        }
4257    }
4258
4259    /// POSITIVE-FRAMING PEER of [`Self::is_restricted`] — is this
4260    /// classification freely distributable (i.e. bearing no access-
4261    /// control requirement)? Closed-set match (not `matches!`) so a
4262    /// future variant triggers the compiler's exhaustiveness check at
4263    /// this site rather than silently defaulting to `false` (silently
4264    /// marking a genuinely-public dataset as restricted and paying the
4265    /// access-control tax indefinitely) or `true` (silently shipping a
4266    /// restricted or regulated dataset onto the freely-distributable
4267    /// path — a compliance-catastrophic mislabel). The typed image of
4268    /// the "freely distributable?" question: `Public ⇒ true` and every
4269    /// other variant `⇒ false` is the antisymmetric partner of
4270    /// [`Self::is_restricted`] — exactly one of
4271    /// `(is_public, is_restricted)` is true per variant — pinned by
4272    /// `data_classification_public_xor_restricted`. Mirror of
4273    /// [`CalmClassification::is_monotone`] /
4274    /// [`CalmClassification::requires_coordination`] on the calm axis
4275    /// and [`HorizonKind::terminates`] /
4276    /// [`HorizonKind::requires_metric_axes`] on the horizon axis: each
4277    /// closed set publishes its two derived-nullary-bool projections
4278    /// at ONE site each so the axis carves into complementary buckets
4279    /// by construction. The positive framing is the substrate primitive
4280    /// a compliance auditor asks first ("is this dataset publicly
4281    /// distributable?"); a future consumer answering that question
4282    /// reads [`Self::is_public`] rather than re-deriving via
4283    /// `!is_restricted()` at the callsite. Sealed further against
4284    /// [`Self::is_regulated`] by
4285    /// `data_classification_regulated_implies_not_public` — regulated
4286    /// data is by definition not publicly distributable, the exact
4287    /// closed-set-internal implication that composes forward through
4288    /// both the parent-composed and resolver-hop layers on this axis.
4289    pub const fn is_public(self) -> bool {
4290        match self {
4291            Self::Public => true,
4292            Self::Internal | Self::Confidential | Self::Pii | Self::Phi | Self::Pci => false,
4293        }
4294    }
4295}
4296
4297// `impl FromStr for DataClassification` +
4298// `impl tatara_lisp::ClosedSet for DataClassification` +
4299// `impl std::fmt::Display for DataClassification` +
4300// `pub struct UnknownDataClassification(pub String)` are all generated
4301// by `#[derive(tatara_closed_set::DeriveClosedSet)]` +
4302// `#[closed_set(via = "as_str", generate_unknown, display)]` on the
4303// enum declaration above. The auto-derived carrier label
4304// "data classification" matches the prior hand-rolled
4305// `#[error("unknown data classification: {0}")]` annotation
4306// byte-for-byte. See the retrofit comment block on
4307// [`ConvergencePointType`] for the canonical narrative.
4308
4309// ───────────────────────────── bridges to tatara-core ─────────────────
4310
4311impl From<ConvergencePointType> for core::ConvergencePointType {
4312    fn from(v: ConvergencePointType) -> Self {
4313        use ConvergencePointType::*;
4314        match v {
4315            Transform => Self::Transform,
4316            Fork => Self::Fork,
4317            Join => Self::Join,
4318            Gate => Self::Gate,
4319            Select => Self::Select,
4320            Broadcast => Self::Broadcast,
4321            Reduce => Self::Reduce,
4322            Observe => Self::Observe,
4323        }
4324    }
4325}
4326
4327impl From<core::ConvergencePointType> for ConvergencePointType {
4328    fn from(v: core::ConvergencePointType) -> Self {
4329        use core::ConvergencePointType as C;
4330        match v {
4331            C::Transform => Self::Transform,
4332            C::Fork => Self::Fork,
4333            C::Join => Self::Join,
4334            C::Gate => Self::Gate,
4335            C::Select => Self::Select,
4336            C::Broadcast => Self::Broadcast,
4337            C::Reduce => Self::Reduce,
4338            C::Observe => Self::Observe,
4339        }
4340    }
4341}
4342
4343impl From<SubstrateType> for core::SubstrateType {
4344    fn from(v: SubstrateType) -> Self {
4345        use SubstrateType::*;
4346        match v {
4347            Financial => Self::Financial,
4348            Compute => Self::Compute,
4349            Network => Self::Network,
4350            Storage => Self::Storage,
4351            Security => Self::Security,
4352            Identity => Self::Identity,
4353            Observability => Self::Observability,
4354            Regulatory => Self::Regulatory,
4355        }
4356    }
4357}
4358
4359impl From<core::SubstrateType> for SubstrateType {
4360    fn from(v: core::SubstrateType) -> Self {
4361        use core::SubstrateType as C;
4362        match v {
4363            C::Financial => Self::Financial,
4364            C::Compute => Self::Compute,
4365            C::Network => Self::Network,
4366            C::Storage => Self::Storage,
4367            C::Security => Self::Security,
4368            C::Identity => Self::Identity,
4369            C::Observability => Self::Observability,
4370            C::Regulatory => Self::Regulatory,
4371        }
4372    }
4373}
4374
4375impl From<OptimizationDirection> for core::OptimizationDirection {
4376    fn from(v: OptimizationDirection) -> Self {
4377        match v {
4378            OptimizationDirection::Minimize => Self::Minimize,
4379            OptimizationDirection::Maximize => Self::Maximize,
4380        }
4381    }
4382}
4383
4384impl From<core::OptimizationDirection> for OptimizationDirection {
4385    fn from(v: core::OptimizationDirection) -> Self {
4386        use core::OptimizationDirection as C;
4387        match v {
4388            C::Minimize => Self::Minimize,
4389            C::Maximize => Self::Maximize,
4390        }
4391    }
4392}
4393
4394impl From<Horizon> for core::ConvergenceHorizon {
4395    fn from(v: Horizon) -> Self {
4396        match v.kind {
4397            HorizonKind::Bounded => Self::Bounded,
4398            HorizonKind::Asymptotic => Self::Asymptotic {
4399                metric: v.metric.unwrap_or_default(),
4400                direction: v.direction.unwrap_or_default().into(),
4401                healthy_rate_threshold: v.healthy_rate_threshold.unwrap_or_default(),
4402            },
4403        }
4404    }
4405}
4406
4407impl From<CalmClassification> for core::CalmClassification {
4408    fn from(v: CalmClassification) -> Self {
4409        match v {
4410            CalmClassification::Monotone => Self::Monotone,
4411            CalmClassification::NonMonotone => Self::NonMonotone,
4412        }
4413    }
4414}
4415
4416impl From<core::CalmClassification> for CalmClassification {
4417    fn from(v: core::CalmClassification) -> Self {
4418        use core::CalmClassification as C;
4419        match v {
4420            C::Monotone => Self::Monotone,
4421            C::NonMonotone => Self::NonMonotone,
4422        }
4423    }
4424}
4425
4426impl From<DataClassification> for core_compl::DataClassification {
4427    fn from(v: DataClassification) -> Self {
4428        use DataClassification::*;
4429        match v {
4430            Public => Self::Public,
4431            Internal => Self::Internal,
4432            Confidential => Self::Confidential,
4433            Pii => Self::Pii,
4434            Phi => Self::Phi,
4435            Pci => Self::Pci,
4436        }
4437    }
4438}
4439
4440impl From<core_compl::DataClassification> for DataClassification {
4441    fn from(v: core_compl::DataClassification) -> Self {
4442        use core_compl::DataClassification as C;
4443        match v {
4444            C::Public => Self::Public,
4445            C::Internal => Self::Internal,
4446            C::Confidential => Self::Confidential,
4447            C::Pii => Self::Pii,
4448            C::Phi => Self::Phi,
4449            C::Pci => Self::Pci,
4450        }
4451    }
4452}
4453
4454#[cfg(test)]
4455mod tests {
4456    use super::*;
4457    // The closed-set tests below call `T::from_str(bad)` via the
4458    // derive-generated `FromStr` impls — bring the trait into scope at
4459    // the test module so the lib body doesn't carry an otherwise-unused
4460    // `use std::str::FromStr;` at the file head.
4461    use std::str::FromStr;
4462
4463    #[test]
4464    fn bridges_roundtrip() {
4465        let pt: core::ConvergencePointType = ConvergencePointType::Gate.into();
4466        let back: ConvergencePointType = pt.into();
4467        assert_eq!(back, ConvergencePointType::Gate);
4468
4469        let sub: core::SubstrateType = SubstrateType::Observability.into();
4470        let back: SubstrateType = sub.into();
4471        assert_eq!(back, SubstrateType::Observability);
4472    }
4473
4474    #[test]
4475    fn data_classification_ordering() {
4476        assert!(DataClassification::Public < DataClassification::Pii);
4477        assert!(DataClassification::Internal < DataClassification::Confidential);
4478    }
4479
4480    #[test]
4481    fn horizon_default_is_bounded() {
4482        assert_eq!(Horizon::default().kind, HorizonKind::Bounded);
4483    }
4484
4485    // ── Classification::gate_compute substrate pins ─────────────────────
4486    //
4487    // The six-line `Classification { point_type: Gate, substrate: Compute,
4488    // horizon: Default::default(), calm: Default::default(),
4489    // data_classification: Default::default() }` struct-literal was
4490    // open-coded verbatim at ten hand-authored callsites before the
4491    // primitive closed it. These pins bind the composed shape at
4492    // fail-before-pass-after granularity so a regression that flipped a
4493    // baseline axis, drifted a sibling default, or leaked a non-baseline
4494    // slot into the substrate composer surfaces HERE rather than as
4495    // silent operator-visible drift at every unadorned ephemeral env
4496    // (the one production consumer, `default_ephemeral_class`) AND every
4497    // downstream test fixture that keys assertions on the shape.
4498
4499    #[test]
4500    fn gate_compute_composes_the_five_baseline_axes() {
4501        // Primary shape: every axis parked at the workspace baseline.
4502        // A regression that flipped `point_type` off `Gate` or
4503        // `substrate` off `Compute` — the two axes with no `Default` —
4504        // surfaces here.
4505        let c = Classification::gate_compute();
4506        assert_eq!(c.point_type, ConvergencePointType::Gate);
4507        assert_eq!(c.substrate, SubstrateType::Compute);
4508        assert_eq!(c.horizon, Horizon::default());
4509        assert_eq!(c.calm, CalmClassification::default());
4510        assert_eq!(c.data_classification, DataClassification::default());
4511    }
4512
4513    #[test]
4514    fn gate_compute_defaulted_axes_ride_sibling_closed_set_defaults() {
4515        // Pins the sibling-default correspondence the doc comment
4516        // names — a regression that flipped a sibling default (a new
4517        // `HorizonKind` variant promoted to `#[default]`, a rename of
4518        // `CalmClassification::Monotone`, a promotion of `Pii` above
4519        // `Internal` in the `DataClassification` ordering) would move
4520        // the baseline HERE rather than at every downstream consumer.
4521        let c = Classification::gate_compute();
4522        assert_eq!(c.horizon.kind, HorizonKind::Bounded);
4523        assert_eq!(c.calm, CalmClassification::Monotone);
4524        assert_eq!(c.data_classification, DataClassification::Internal);
4525    }
4526
4527    #[test]
4528    fn gate_compute_matches_hand_authored_pre_lift_bytewise() {
4529        // Byte-identical parity with the pre-lift six-line struct-literal
4530        // that recurred at ten hand-authored sites. A regression that
4531        // reshaped the primitive would diverge from the pre-lift block
4532        // HERE rather than at every downstream fixture that keys on the
4533        // shape.
4534        let composed = Classification::gate_compute();
4535        let hand_authored = Classification {
4536            point_type: ConvergencePointType::Gate,
4537            substrate: SubstrateType::Compute,
4538            horizon: Horizon::default(),
4539            calm: CalmClassification::default(),
4540            data_classification: DataClassification::default(),
4541        };
4542        assert_eq!(composed, hand_authored);
4543    }
4544
4545    #[test]
4546    fn gate_compute_is_call_time_construction_not_a_shared_singleton() {
4547        // Two independent calls produce structurally-equal but distinct
4548        // values — pins that the primitive is a plain constructor
4549        // rather than a `lazy_static` clone (which would leak a shared
4550        // singleton whose in-place mutation at one consumer would
4551        // silently mutate the shape at every other consumer). The `!=`
4552        // check on `&mut _`-obtained pointer addresses is intentional:
4553        // a shared singleton would collide, and the pin catches the
4554        // regression at the primitive rather than at the operator-facing
4555        // shape-drift downstream.
4556        let a = Classification::gate_compute();
4557        let b = Classification::gate_compute();
4558        assert_eq!(a, b);
4559        assert!(!std::ptr::eq(&a, &b));
4560    }
4561
4562    // ── Classification::gate_compute_with_axis substrate pins ────────
4563    //
4564    // Fail-before-pass-after granularity: `gate_compute_with_axis` did
4565    // not exist before this commit — the (`gate_compute()` with ONE
4566    // axis slot overwritten by a per-test swept variant) shape recurred
4567    // at ≥ 40 hand-authored test-fixture callsites, each restating the
4568    // SAME six-line struct-literal that names FOUR baseline slots
4569    // verbatim and mutates ONE. Post-lift the shape lives at ONE
4570    // substrate primitive that composes `Self::gate_compute` with a
4571    // per-axis overlay through the [`ClassificationAxis`] trait. The
4572    // two pins below fence the primitive's contract:
4573    // (1) at every axis, feeding the baseline-of-that-axis variant
4574    //     reconstructs exactly `gate_compute()` byte-for-byte, so the
4575    //     overlay is the IDENTITY under baseline input;
4576    // (2) at every axis, feeding a variant mutates ONLY that axis
4577    //     slot and leaves the other four at their baseline.
4578    // A regression that crossed the wires between the five per-axis
4579    // impls (silently overlaying the wrong slot) or that broke the
4580    // identity under baseline input (silently drifting the baseline
4581    // slot on a non-baseline overlay) fails HERE at the substrate
4582    // primitive rather than at each of the ≥ 40 downstream test
4583    // callsites that would otherwise silently key an assertion on the
4584    // wrong axis's variant.
4585
4586    #[test]
4587    fn gate_compute_with_axis_is_identity_under_axis_baseline_input() {
4588        // For each axis, feeding the baseline-of-that-axis variant
4589        // reconstructs exactly `gate_compute()`. On the two axes with
4590        // no `Default` (`ConvergencePointType`, `SubstrateType`) the
4591        // baseline is the `gate_compute` chosen value (`Gate`,
4592        // `Compute`); on the three defaulted axes the baseline is the
4593        // sibling closed-set `#[default]` (`Bounded`, `Monotone`,
4594        // `Internal`).
4595        let baseline = Classification::gate_compute();
4596        assert_eq!(
4597            Classification::gate_compute_with_axis(HorizonKind::Bounded),
4598            baseline,
4599        );
4600        assert_eq!(
4601            Classification::gate_compute_with_axis(CalmClassification::Monotone),
4602            baseline,
4603        );
4604        assert_eq!(
4605            Classification::gate_compute_with_axis(DataClassification::Internal),
4606            baseline,
4607        );
4608        assert_eq!(
4609            Classification::gate_compute_with_axis(ConvergencePointType::Gate),
4610            baseline,
4611        );
4612        assert_eq!(
4613            Classification::gate_compute_with_axis(SubstrateType::Compute),
4614            baseline,
4615        );
4616    }
4617
4618    #[test]
4619    fn gate_compute_with_axis_mutates_only_the_named_axis_slot() {
4620        // For each axis, sweep every variant and pin that the four
4621        // sibling axis slots stay at their `gate_compute` baseline
4622        // while only the named axis slot carries the swept variant.
4623        // A regression that crossed the per-axis impls (a
4624        // `ClassificationAxis for HorizonKind` body that mutated
4625        // `c.calm` instead of `c.horizon.kind`, or a swap between
4626        // `data_classification` and `calm` impls) fails HERE.
4627        let baseline = Classification::gate_compute();
4628        for populated in HorizonKind::ALL {
4629            let c = Classification::gate_compute_with_axis(populated);
4630            assert_eq!(c.horizon.kind, populated);
4631            assert_eq!(c.calm, baseline.calm);
4632            assert_eq!(c.data_classification, baseline.data_classification);
4633            assert_eq!(c.point_type, baseline.point_type);
4634            assert_eq!(c.substrate, baseline.substrate);
4635        }
4636        for populated in CalmClassification::ALL {
4637            let c = Classification::gate_compute_with_axis(populated);
4638            assert_eq!(c.calm, populated);
4639            assert_eq!(c.horizon, baseline.horizon);
4640            assert_eq!(c.data_classification, baseline.data_classification);
4641            assert_eq!(c.point_type, baseline.point_type);
4642            assert_eq!(c.substrate, baseline.substrate);
4643        }
4644        for populated in DataClassification::ALL {
4645            let c = Classification::gate_compute_with_axis(populated);
4646            assert_eq!(c.data_classification, populated);
4647            assert_eq!(c.horizon, baseline.horizon);
4648            assert_eq!(c.calm, baseline.calm);
4649            assert_eq!(c.point_type, baseline.point_type);
4650            assert_eq!(c.substrate, baseline.substrate);
4651        }
4652        for populated in ConvergencePointType::ALL {
4653            let c = Classification::gate_compute_with_axis(populated);
4654            assert_eq!(c.point_type, populated);
4655            assert_eq!(c.horizon, baseline.horizon);
4656            assert_eq!(c.calm, baseline.calm);
4657            assert_eq!(c.data_classification, baseline.data_classification);
4658            assert_eq!(c.substrate, baseline.substrate);
4659        }
4660        for populated in SubstrateType::ALL {
4661            let c = Classification::gate_compute_with_axis(populated);
4662            assert_eq!(c.substrate, populated);
4663            assert_eq!(c.horizon, baseline.horizon);
4664            assert_eq!(c.calm, baseline.calm);
4665            assert_eq!(c.data_classification, baseline.data_classification);
4666            assert_eq!(c.point_type, baseline.point_type);
4667        }
4668    }
4669
4670    // ── Classification::with_axis chaining primitive pins ────────────
4671    //
4672    // Fail-before-pass-after granularity: `with_axis` did not exist
4673    // before this commit — the (Classification, N-axis-conjunction)
4674    // construction shape recurred at ≥ 5 hand-authored test-fixture
4675    // callsites in this file (Fork+Storage, Fork+Storage+NonMonotone,
4676    // Fork+Storage+NonMonotone+Pii, +HorizonKind::Asymptotic,
4677    // +direction=Maximize) each restating the FIVE-field struct-
4678    // literal (`point_type`, `substrate`, `horizon`, `calm`,
4679    // `data_classification`) verbatim with distinct axis conjunctions.
4680    // Post-lift the shape lives at ONE substrate primitive that
4681    // post-composes ONE additional [`ClassificationAxis`] overlay onto
4682    // an arbitrary [`Classification`] carrier through the SAME trait
4683    // dispatch [`Classification::gate_compute_with_axis`] uses for the
4684    // start-from-baseline single-axis overlay. The pins below fence
4685    // the primitive's contract:
4686    // (1) chaining N distinct-slot axes onto `gate_compute_with_axis(x)`
4687    //     produces the SAME [`Classification`] as populating every
4688    //     slot at once via a hand-authored struct-literal;
4689    // (2) chaining any permutation of a fixed set of distinct-slot
4690    //     axes produces the SAME [`Classification`] (order-independent
4691    //     across distinct slots);
4692    // (3) the [`OptimizationDirection`] sub-slot overlay PRESERVES the
4693    //     [`HorizonKind`] sub-slot's prior overlay (both slots live on
4694    //     the nested `Horizon` struct — a stomping overlay would drop
4695    //     `direction` to `None` on `.with_axis(HorizonKind::_)`).
4696
4697    #[test]
4698    fn with_axis_chains_multi_axis_overlays_matching_open_coded_struct_literal() {
4699        // Chain the six-axis conjunction (point_type + substrate +
4700        // calm + data_classification + horizon.kind + horizon.direction)
4701        // through `with_axis` and pin byte-identical parity with the
4702        // open-coded FIVE-field struct-literal + nested `Horizon`
4703        // struct-literal that recurred at the six-axis-independence
4704        // test-fixture callsite. A regression that (a) mis-routed one
4705        // `ClassificationAxis::overlay` impl (a stray slot assignment),
4706        // (b) stomped a prior overlay (the [`HorizonKind`] impl
4707        // resetting the whole nested `Horizon`), or (c) collapsed the
4708        // fluent chain onto a single-axis overlay (only the last axis
4709        // takes effect) would drop parity here.
4710        let composed = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
4711            .with_axis(SubstrateType::Storage)
4712            .with_axis(CalmClassification::NonMonotone)
4713            .with_axis(DataClassification::Pii)
4714            .with_axis(HorizonKind::Asymptotic)
4715            .with_axis(OptimizationDirection::Maximize);
4716        let hand_authored = Classification {
4717            point_type: ConvergencePointType::Fork,
4718            substrate: SubstrateType::Storage,
4719            horizon: Horizon {
4720                kind: HorizonKind::Asymptotic,
4721                direction: Some(OptimizationDirection::Maximize),
4722                ..Horizon::default()
4723            },
4724            calm: CalmClassification::NonMonotone,
4725            data_classification: DataClassification::Pii,
4726        };
4727        assert_eq!(composed, hand_authored);
4728    }
4729
4730    #[test]
4731    fn with_axis_is_order_independent_across_distinct_slot_axes() {
4732        // Chain the same set of five distinct-slot axes in TWO
4733        // permutations and pin byte-identical parity. A regression
4734        // that leaked cross-slot dependency into an overlay impl (a
4735        // stray [`ConvergencePointType`] impl mutating `c.substrate`,
4736        // a stray [`DataClassification`] impl mutating `c.calm`, or
4737        // any impl that read from another slot before writing its
4738        // own) would drop parity here — an order-dependent overlay
4739        // means the impls are not commutative, which the
4740        // (distinct-slot × per-slot-overlay) contract requires. The
4741        // horizon-nested (`HorizonKind`, `OptimizationDirection`)
4742        // pair is deliberately NOT included in either permutation
4743        // here — that pair lives on the SAME nested-struct slot and
4744        // has an ordering constraint tested by
4745        // `with_axis_optimization_direction_overlay_preserves_horizon_kind_overlay`
4746        // below.
4747        let axes_forward = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
4748            .with_axis(SubstrateType::Storage)
4749            .with_axis(CalmClassification::NonMonotone)
4750            .with_axis(DataClassification::Pii)
4751            .with_axis(HorizonKind::Asymptotic);
4752        let axes_reversed = Classification::gate_compute_with_axis(HorizonKind::Asymptotic)
4753            .with_axis(DataClassification::Pii)
4754            .with_axis(CalmClassification::NonMonotone)
4755            .with_axis(SubstrateType::Storage)
4756            .with_axis(ConvergencePointType::Fork);
4757        assert_eq!(axes_forward, axes_reversed);
4758    }
4759
4760    #[test]
4761    fn with_axis_optimization_direction_overlay_preserves_horizon_kind_overlay() {
4762        // Chain `HorizonKind::Asymptotic` THEN
4763        // `OptimizationDirection::Maximize` — both overlays live on
4764        // the SAME nested `Horizon` struct's distinct sub-slots
4765        // (`kind`, `direction`). Pin that the second overlay
4766        // PRESERVES the first. A regression that either (a) reverted
4767        // [`ClassificationAxis for HorizonKind`] to the pre-change
4768        // whole-`Horizon`-reset shape (which would drop `direction`
4769        // to `None` if that overlay ran after `direction` was set) —
4770        // pinned via `.with_axis(Maximize).with_axis(Asymptotic)`
4771        // below — or (b) wrote `OptimizationDirection::overlay`
4772        // through a whole-`Horizon` reset (which would drop `kind`
4773        // to `HorizonKind::default()` — Bounded — on this call
4774        // sequence) would fail HERE. Also pins the byte-symmetric
4775        // reverse ordering `.with_axis(Maximize).with_axis(Asymptotic)`
4776        // preserves `direction: Some(Maximize)` — the sub-slot
4777        // overlays are commutative on the nested struct.
4778        let forward = Classification::gate_compute_with_axis(HorizonKind::Asymptotic)
4779            .with_axis(OptimizationDirection::Maximize);
4780        assert_eq!(forward.horizon.kind, HorizonKind::Asymptotic);
4781        assert_eq!(
4782            forward.horizon.direction,
4783            Some(OptimizationDirection::Maximize),
4784        );
4785
4786        let reversed = Classification::gate_compute_with_axis(OptimizationDirection::Maximize)
4787            .with_axis(HorizonKind::Asymptotic);
4788        assert_eq!(reversed.horizon.kind, HorizonKind::Asymptotic);
4789        assert_eq!(
4790            reversed.horizon.direction,
4791            Some(OptimizationDirection::Maximize),
4792        );
4793
4794        // Byte-parity across the two orderings — both produce the
4795        // identical (kind, direction) pair AND both preserve every
4796        // other slot at its `gate_compute` baseline.
4797        assert_eq!(forward, reversed);
4798        let baseline = Classification::gate_compute();
4799        assert_eq!(forward.point_type, baseline.point_type);
4800        assert_eq!(forward.substrate, baseline.substrate);
4801        assert_eq!(forward.calm, baseline.calm);
4802        assert_eq!(forward.data_classification, baseline.data_classification);
4803        assert_eq!(forward.horizon.metric, baseline.horizon.metric);
4804        assert_eq!(
4805            forward.horizon.healthy_rate_threshold,
4806            baseline.horizon.healthy_rate_threshold,
4807        );
4808    }
4809
4810    #[test]
4811    fn with_axis_optimization_direction_overlay_wraps_variant_in_some() {
4812        // For every `OptimizationDirection` variant, `with_axis`
4813        // sets `horizon.direction = Some(variant)`. A regression
4814        // that dropped the `Some(...)` wrap (a stray `c.horizon.direction
4815        // = self.into()` that only compiles because
4816        // [`Option<OptimizationDirection>: From<OptimizationDirection>`]
4817        // is derived, but which would silently answer `None` on
4818        // some variants), or that wrote through the wrong nested
4819        // slot, fails HERE.
4820        for populated in OptimizationDirection::ALL {
4821            let c = Classification::gate_compute_with_axis(HorizonKind::Asymptotic)
4822                .with_axis(populated);
4823            assert_eq!(
4824                c.horizon.direction,
4825                Some(populated),
4826                "OptimizationDirection::{populated:?} overlay must set horizon.direction = Some({populated:?})",
4827            );
4828            assert_eq!(
4829                c.horizon.kind,
4830                HorizonKind::Asymptotic,
4831                "OptimizationDirection::{populated:?} overlay must preserve prior HorizonKind::Asymptotic overlay",
4832            );
4833        }
4834    }
4835
4836    // ── closed-set algebra contracts for DataClassification
4837    //    (ALL × as_str × FromStr × rank × predicate pair) ────────────
4838
4839    /// Structural well-formedness of [`DataClassification`] as a
4840    /// [`tatara_lisp::ClosedSet`] implementor — the workspace-wide
4841    /// testkit lift that pins all three structural invariants (`ALL`
4842    /// is non-empty, every variant round-trips through
4843    /// `label ↔ parse_label`, labels are pairwise distinct, `""` is
4844    /// outside the closed set) at ONE call site. Replaces the hand-
4845    /// derived `data_classification_all_is_unique_and_complete` +
4846    /// `data_classification_roundtrip_via_as_str` + the empty-input arm
4847    /// of `unknown_data_classification_errors`. `FromStr` delegates to
4848    /// `<Self as tatara_closed_set::ClosedSet>::parse_label`, so this helper
4849    /// exercises the same code path the reconciler hits when parsing a
4850    /// CRD `enum:`-validated `dataClassification` value back to the
4851    /// typed classification.
4852    #[test]
4853    fn data_classification_is_well_formed_closed_set() {
4854        tatara_closed_set::assert_closed_set_well_formed::<DataClassification>();
4855    }
4856
4857    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
4858    /// output verbatim for every variant. A future variant rename (or
4859    /// an `as_str` arm typo) lands here at one site, instead of
4860    /// drifting between the typed surface, the CRD enum, and the YAML
4861    /// wire format the reconciler stamps on
4862    /// `spec.classification.dataClassification`.
4863    #[test]
4864    fn data_classification_as_str_matches_serde() {
4865        crate::tagged_union::assert_label_matches_serde_serialization::<DataClassification>();
4866    }
4867
4868    /// The Display impl IS `as_str` — pinning this lets future callers
4869    /// reach for either projection without drift. Any operator-facing
4870    /// "dataClassification={class}" diagnostic that composes through
4871    /// Display inherits the canonical wire-format string automatically.
4872    #[test]
4873    fn data_classification_display_matches_as_str() {
4874        crate::tagged_union::assert_display_matches_label::<DataClassification>();
4875    }
4876
4877    /// `FromStr` rejects strings that aren't in the canonical
4878    /// projection — lowercased / typo / cross-axis-leaked — and the
4879    /// error echoes the input verbatim so the operator-facing
4880    /// diagnostic carries the offending value, not a normalized form.
4881    /// The empty-input arm is pinned by
4882    /// [`data_classification_is_well_formed_closed_set`] via the
4883    /// `tatara_lisp::ClosedSet` testkit; the cases here pin the
4884    /// verbatim-echo contract on the [`UnknownDataClassification`]
4885    /// newtype, which the trait's `make_unknown` can't see.
4886    #[test]
4887    fn unknown_data_classification_errors() {
4888        for bad in [
4889            "pii",          // lowercased
4890            "PII",          // uppercased
4891            "PersonalData", // typo
4892            "internal_data",
4893            "Steady",   // PoolPhase-axis leak
4894            "Replace",  // ReturnPolicy-axis leak
4895            "Attested", // ProcessPhase-axis leak
4896            "Compute",  // SubstrateType-axis leak
4897            "Gate",     // ConvergencePointType-axis leak
4898            "Monotone", // CalmClassification-axis leak
4899        ] {
4900            let err = DataClassification::from_str(bad).unwrap_err();
4901            assert_eq!(err.0, bad, "error payload should echo input verbatim");
4902        }
4903    }
4904
4905    // `unknown_data_classification_message_matches_substrate_convention`
4906    // removed — clause (5) of
4907    // `tatara_closed_set::assert_closed_set_well_formed::<DataClassification>()`
4908    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
4909    // shape generically (called from
4910    // `data_classification_is_well_formed_closed_set` above); the
4911    // `SET_LABEL` projection is pinned by
4912    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
4913
4914    /// TRUTH-TABLE CONTRACT: the predicate pair agrees with the
4915    /// documented per-variant compliance role. Pinning this table at
4916    /// one site means any future compliance-baseline auto-selector
4917    /// reads the same projection that the reconciler writes.
4918    #[test]
4919    fn data_classification_predicate_truth_tables() {
4920        assert!(DataClassification::Public.is_public());
4921        assert!(!DataClassification::Public.is_restricted());
4922        assert!(!DataClassification::Public.is_regulated());
4923
4924        assert!(!DataClassification::Internal.is_public());
4925        assert!(DataClassification::Internal.is_restricted());
4926        assert!(!DataClassification::Internal.is_regulated());
4927
4928        assert!(!DataClassification::Confidential.is_public());
4929        assert!(DataClassification::Confidential.is_restricted());
4930        assert!(!DataClassification::Confidential.is_regulated());
4931
4932        assert!(!DataClassification::Pii.is_public());
4933        assert!(DataClassification::Pii.is_restricted());
4934        assert!(DataClassification::Pii.is_regulated());
4935
4936        assert!(!DataClassification::Phi.is_public());
4937        assert!(DataClassification::Phi.is_restricted());
4938        assert!(DataClassification::Phi.is_regulated());
4939
4940        assert!(!DataClassification::Pci.is_public());
4941        assert!(DataClassification::Pci.is_restricted());
4942        assert!(DataClassification::Pci.is_regulated());
4943    }
4944
4945    /// IMPLICATION CONTRACT: every regulated classification is also
4946    /// restricted. The impossible bucket (regulated AND
4947    /// freely-distributable) is pinned empty so a future variant that
4948    /// returned `(true, false)` from the predicate pair would FAIL
4949    /// here, forcing the author to either flip `is_restricted` or
4950    /// extend the consumer dispatch sites (compliance-baseline
4951    /// auto-selector, audit-log mandatory-fields validator)
4952    /// deliberately rather than silently producing a regulated class
4953    /// the API server would accept as freely-distributable. Encoded as
4954    /// material implication `is_regulated → is_restricted` so the
4955    /// boolean reads as the documented contract, not its NAND form.
4956    #[test]
4957    fn data_classification_regulated_implies_restricted() {
4958        for class in DataClassification::ALL {
4959            assert!(
4960                !class.is_regulated() || class.is_restricted(),
4961                "{class:?} is regulated but not restricted — \
4962                 regulated data is by definition not freely distributable",
4963            );
4964        }
4965    }
4966
4967    /// POSITIVE-FRAMING TRUTH-TABLE CONTRACT: `is_public` implements
4968    /// the antisymmetric partner of `is_restricted` — `Public ⇒ true`
4969    /// and every other variant `⇒ false`. Pinning this table at one
4970    /// site means any future consumer asking the positive
4971    /// distribution framing ("is this dataset publicly distributable?")
4972    /// reads the same projection the compliance auditor reads. A
4973    /// future variant that flipped this mapping would have to renumber
4974    /// every consumer deliberately rather than silently promoting an
4975    /// access-controlled dataset onto the freely-distributable path.
4976    #[test]
4977    fn data_classification_is_public_truth_table() {
4978        assert!(DataClassification::Public.is_public());
4979        assert!(!DataClassification::Internal.is_public());
4980        assert!(!DataClassification::Confidential.is_public());
4981        assert!(!DataClassification::Pii.is_public());
4982        assert!(!DataClassification::Phi.is_public());
4983        assert!(!DataClassification::Pci.is_public());
4984    }
4985
4986    /// XOR PARTITION CONTRACT: for every [`DataClassification`]
4987    /// variant, EXACTLY ONE of `is_public` / `is_restricted` is true
4988    /// — the two predicates carve the closed set into COMPLEMENTARY
4989    /// buckets (publicly distributable ↔ no access-control regime
4990    /// applies; access-controlled ↔ some regime applies), the exact
4991    /// binary partition already sealed on the sibling calm axis by
4992    /// `calm_classification_monotone_xor_requires_coordination` on the
4993    /// two-variant closed set, now lifted through the projection layer
4994    /// to the six-variant data axis. A future variant that returned
4995    /// `true` for both (publicly distributable AND access-controlled —
4996    /// a category error) or `false` for both (an inert variant with
4997    /// no distribution classification — nothing to dispatch on) would
4998    /// fail here, forcing the author to extend either the predicates
4999    /// or the [`DataClassification`] enum deliberately. Structural
5000    /// twin of `calm_classification_monotone_xor_requires_coordination`
5001    /// and `horizon_kind_terminate_xor_requires_metric_axes` on the
5002    /// sibling calm + horizon axes — all three binary XOR partitions
5003    /// publish their two derived-nullary-bool projections as
5004    /// complementary XOR pairs at ONE site each so the axis carves
5005    /// into disjoint buckets by construction.
5006    #[test]
5007    fn data_classification_public_xor_restricted() {
5008        for class in DataClassification::ALL {
5009            assert!(
5010                class.is_public() ^ class.is_restricted(),
5011                "{class:?}: is_public() XOR is_restricted() must hold",
5012            );
5013        }
5014    }
5015
5016    /// ANTISYMMETRIC IMPLICATION CONTRACT: every regulated
5017    /// classification is NEVER publicly distributable — the impossible
5018    /// bucket (regulated AND public) is pinned empty on the closed
5019    /// set. Paired with `data_classification_regulated_implies_restricted`
5020    /// this is the antisymmetric MUTEX pin against the positive
5021    /// framing peer — a future variant that returned `(true, true)`
5022    /// from `(is_regulated, is_public)` would fail HERE, forcing the
5023    /// author to either flip `is_public` or extend the consumer
5024    /// dispatch sites (compliance-baseline auto-selector, audit-log
5025    /// mandatory-fields validator) deliberately rather than silently
5026    /// producing a regulated class the API server would accept as
5027    /// freely distributable.
5028    #[test]
5029    fn data_classification_regulated_implies_not_public() {
5030        for class in DataClassification::ALL {
5031            assert!(
5032                !class.is_regulated() || !class.is_public(),
5033                "{class:?} is regulated AND public — \
5034                 regulated data is by definition not freely distributable",
5035            );
5036        }
5037    }
5038
5039    /// COVERAGE CONTRACT: every variant lands in exactly one of three
5040    /// compliance buckets — freely distributable (`Public`),
5041    /// restricted-only (`Internal | Confidential`), or regulated
5042    /// (`Pii | Phi | Pci`). Pins the three buckets at their declared
5043    /// cardinalities (1, 2, 3 — sum to `ALL.len()`) so a future
5044    /// variant lands somewhere deliberately.
5045    #[test]
5046    fn data_classification_buckets_cover_every_variant() {
5047        let mut free = 0u32;
5048        let mut restricted_only = 0u32;
5049        let mut regulated = 0u32;
5050        for class in DataClassification::ALL {
5051            match (class.is_restricted(), class.is_regulated()) {
5052                (false, false) => free += 1,
5053                (true, false) => restricted_only += 1,
5054                (true, true) => regulated += 1,
5055                (false, true) => {
5056                    panic!("regulated_implies_restricted already pins this empty for {class:?}")
5057                }
5058            }
5059        }
5060        assert_eq!(free, 1, "free bucket: Public");
5061        assert_eq!(
5062            restricted_only, 2,
5063            "restricted-only bucket: Internal + Confidential"
5064        );
5065        assert_eq!(regulated, 3, "regulated bucket: Pii + Phi + Pci");
5066        assert_eq!(
5067            free + restricted_only + regulated,
5068            DataClassification::ALL.len() as u32
5069        );
5070    }
5071
5072    /// MONOTONE-RANK CONTRACT: `sensitivity_rank` is strictly
5073    /// monotone over `ALL`'s declared order, so the lattice ordering
5074    /// `Public < Internal < Confidential < Pii < Phi < Pci` is sealed
5075    /// at one site (this enum's projection) instead of riding on the
5076    /// silent `as u8` cast in [`tatara_lattice`]. A future variant
5077    /// inserted in the middle would either preserve strict monotonicity
5078    /// here (and the lattice keeps working) or FAIL here at compile or
5079    /// test time (and the author has to renumber deliberately). Also
5080    /// pins the rank codomain at `0..ALL.len()` so no variant can
5081    /// silently outrank the documented top.
5082    #[test]
5083    fn data_classification_rank_is_strictly_monotone_over_all() {
5084        let ranks: Vec<u8> = DataClassification::ALL
5085            .into_iter()
5086            .map(DataClassification::sensitivity_rank)
5087            .collect();
5088        for win in ranks.windows(2) {
5089            assert!(win[0] < win[1], "ranks not strictly monotone: {ranks:?}");
5090        }
5091        assert_eq!(*ranks.first().unwrap(), 0, "bottom rank must be 0");
5092        assert_eq!(
5093            *ranks.last().unwrap(),
5094            (DataClassification::ALL.len() as u8) - 1,
5095            "top rank must be ALL.len() - 1"
5096        );
5097    }
5098
5099    /// RANK-AGREES-WITH-ORD CONTRACT: the typed `sensitivity_rank`
5100    /// projection agrees with the derived `PartialOrd` / `Ord` for
5101    /// every pair in `ALL × ALL`. This is the bridge that lets
5102    /// [`tatara_lattice`]'s total-order `Lattice for DataClassification`
5103    /// impl call `sensitivity_rank` instead of `as u8` without changing
5104    /// any observable lattice behavior — and it lets a future
5105    /// reordering of the enum's variant declarations land at this test
5106    /// site (forcing the rank arms to be renumbered) rather than
5107    /// silently shifting the lattice's `leq` relation.
5108    #[test]
5109    fn data_classification_rank_agrees_with_partial_ord() {
5110        for a in DataClassification::ALL {
5111            for b in DataClassification::ALL {
5112                assert_eq!(
5113                    a.sensitivity_rank() <= b.sensitivity_rank(),
5114                    a <= b,
5115                    "rank vs. PartialOrd drift on ({a:?}, {b:?})"
5116                );
5117            }
5118        }
5119    }
5120
5121    /// DEFAULT-AGREEMENT CONTRACT: `DataClassification::default()`
5122    /// returns `Internal` (the variant tagged `#[default]`), AND that
5123    /// variant lands in the restricted-only bucket — neither freely
5124    /// distributable nor externally regulated. A future `#[default]`
5125    /// rename without flipping the predicates fails here.
5126    #[test]
5127    fn data_classification_default_is_internal_in_restricted_only_bucket() {
5128        let d = DataClassification::default();
5129        assert_eq!(d, DataClassification::Internal);
5130        assert!(d.is_restricted());
5131        assert!(!d.is_regulated());
5132        assert_eq!(d.sensitivity_rank(), 1);
5133    }
5134
5135    /// BRIDGE ROUND-TRIP CONTRACT: every variant survives the
5136    /// CRD-facing (`PascalCase`) ↔ tatara-core (`snake_case`)
5137    /// `From` hop. Today the bridge is two hand-written 6-arm matches
5138    /// in this file; pinning the round-trip over `ALL` means a future
5139    /// variant added without extending the bridge fails here at one
5140    /// site instead of drifting between the CRD wire format and the
5141    /// `core_compl::DataClassification` selector axis.
5142    #[test]
5143    fn data_classification_bridge_roundtrip_over_all() {
5144        for class in DataClassification::ALL {
5145            let core: core_compl::DataClassification = class.into();
5146            let back: DataClassification = core.into();
5147            assert_eq!(back, class, "bridge round-trip failed for {class:?}");
5148        }
5149    }
5150
5151    // ── closed-set algebra contracts for ConvergencePointType
5152    //    (ALL × as_str × FromStr × arity-pair × predicate triple) ────
5153
5154    /// Structural well-formedness of [`ConvergencePointType`] as a
5155    /// [`tatara_lisp::ClosedSet`] implementor — the workspace-wide
5156    /// testkit lift that pins all three structural invariants (`ALL`
5157    /// is non-empty, every variant round-trips through `label ↔
5158    /// parse_label`, labels are pairwise distinct, `""` is outside
5159    /// the closed set) at ONE call site. Replaces the hand-derived
5160    /// `convergence_point_type_all_is_unique_and_complete` +
5161    /// `convergence_point_type_roundtrip_via_as_str` + the empty-
5162    /// input arm of `unknown_convergence_point_type_errors`.
5163    /// `FromStr` delegates to `<Self as tatara_closed_set::ClosedSet>::parse_label`,
5164    /// so this helper exercises the same code path the reconciler
5165    /// hits when parsing a CRD `enum:`-validated value back to the
5166    /// typed point-type. The forced `[Self; 8]` array literal on
5167    /// `ConvergencePointType::ALL` still pins the cardinality at the
5168    /// declaration site.
5169    #[test]
5170    fn convergence_point_type_is_well_formed_closed_set() {
5171        tatara_closed_set::assert_closed_set_well_formed::<ConvergencePointType>();
5172    }
5173
5174    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
5175    /// output verbatim for every variant. A future variant rename (or
5176    /// an `as_str` arm typo) lands here at one site, instead of
5177    /// drifting between the typed surface, the CRD enum, and the YAML
5178    /// wire format the reconciler reads from
5179    /// `spec.classification.pointType`.
5180    #[test]
5181    fn convergence_point_type_as_str_matches_serde() {
5182        crate::tagged_union::assert_label_matches_serde_serialization::<ConvergencePointType>();
5183    }
5184
5185    /// The Display impl IS `as_str` — pinning this lets future callers
5186    /// reach for either projection without drift.
5187    #[test]
5188    fn convergence_point_type_display_matches_as_str() {
5189        crate::tagged_union::assert_display_matches_label::<ConvergencePointType>();
5190    }
5191
5192    /// `FromStr` rejects strings outside the canonical projection —
5193    /// lowercased / typo / cross-axis-leaked — and the error echoes
5194    /// the input verbatim so the operator-facing diagnostic surfaces
5195    /// the bad value, not a normalized form. The empty-input arm is
5196    /// pinned by [`convergence_point_type_is_well_formed_closed_set`]
5197    /// via the `tatara_lisp::ClosedSet` testkit; the cases here pin
5198    /// the verbatim-echo contract on the
5199    /// [`UnknownConvergencePointType`] newtype, which the trait's
5200    /// `make_unknown` can't see.
5201    #[test]
5202    fn unknown_convergence_point_type_errors() {
5203        for bad in [
5204            "gate",       // lowercased
5205            "GATE",       // uppercased
5206            "Transformr", // typo
5207            "Filter",
5208            "Steady",   // PoolPhase-axis leak
5209            "Pii",      // DataClassification-axis leak
5210            "Attested", // ProcessPhase-axis leak
5211            "Compute",  // SubstrateType-axis leak
5212            "Monotone", // CalmClassification-axis leak
5213            "PromQL",   // ConditionKind-axis leak
5214        ] {
5215            let err = ConvergencePointType::from_str(bad).unwrap_err();
5216            assert_eq!(err.0, bad, "error payload should echo input verbatim");
5217        }
5218    }
5219
5220    // `unknown_convergence_point_type_message_matches_substrate_convention`
5221    // removed — clause (5) of
5222    // `tatara_closed_set::assert_closed_set_well_formed::<ConvergencePointType>()`
5223    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
5224    // shape generically (called from
5225    // `convergence_point_type_is_well_formed_closed_set` above); the
5226    // `SET_LABEL` projection is pinned by
5227    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
5228
5229    /// TRUTH-TABLE CONTRACT: the predicate triple agrees with the
5230    /// documented per-variant topology role. Pinning this table at
5231    /// one site means any future DAG validator reads the same
5232    /// projection that compliance bindings dispatch against.
5233    #[test]
5234    fn convergence_point_type_predicate_truth_tables() {
5235        // Endomorphic: 1→1
5236        assert!(ConvergencePointType::Transform.is_endomorphic());
5237        assert!(!ConvergencePointType::Transform.is_diffusive());
5238        assert!(!ConvergencePointType::Transform.is_convergent());
5239
5240        assert!(ConvergencePointType::Observe.is_endomorphic());
5241        assert!(!ConvergencePointType::Observe.is_diffusive());
5242        assert!(!ConvergencePointType::Observe.is_convergent());
5243
5244        // Diffusive: 1→N
5245        assert!(!ConvergencePointType::Fork.is_endomorphic());
5246        assert!(ConvergencePointType::Fork.is_diffusive());
5247        assert!(!ConvergencePointType::Fork.is_convergent());
5248
5249        assert!(!ConvergencePointType::Broadcast.is_endomorphic());
5250        assert!(ConvergencePointType::Broadcast.is_diffusive());
5251        assert!(!ConvergencePointType::Broadcast.is_convergent());
5252
5253        // Convergent: N→1
5254        for t in [
5255            ConvergencePointType::Join,
5256            ConvergencePointType::Gate,
5257            ConvergencePointType::Select,
5258            ConvergencePointType::Reduce,
5259        ] {
5260            assert!(!t.is_endomorphic(), "{t:?} should not be endomorphic");
5261            assert!(!t.is_diffusive(), "{t:?} should not be diffusive");
5262            assert!(t.is_convergent(), "{t:?} should be convergent");
5263        }
5264    }
5265
5266    /// COVERAGE CONTRACT: every variant lands in *exactly one* of the
5267    /// three topology buckets — endomorphic, diffusive, or convergent.
5268    /// Pins the three buckets at their declared cardinalities (2, 2, 4
5269    /// — sum to `ALL.len()`) so a future variant lands somewhere
5270    /// deliberately. No variant returns true from more than one
5271    /// predicate; no variant returns false from all three.
5272    #[test]
5273    fn convergence_point_type_buckets_cover_every_variant() {
5274        let mut endomorphic = 0u32;
5275        let mut diffusive = 0u32;
5276        let mut convergent = 0u32;
5277        for t in ConvergencePointType::ALL {
5278            let buckets = [t.is_endomorphic(), t.is_diffusive(), t.is_convergent()];
5279            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
5280            assert_eq!(
5281                hits, 1,
5282                "{t:?} landed in {hits} buckets: {buckets:?} (must be exactly one)"
5283            );
5284            if t.is_endomorphic() {
5285                endomorphic += 1;
5286            }
5287            if t.is_diffusive() {
5288                diffusive += 1;
5289            }
5290            if t.is_convergent() {
5291                convergent += 1;
5292            }
5293        }
5294        assert_eq!(endomorphic, 2, "endomorphic bucket: Transform + Observe");
5295        assert_eq!(diffusive, 2, "diffusive bucket: Fork + Broadcast");
5296        assert_eq!(
5297            convergent, 4,
5298            "convergent bucket: Join + Gate + Select + Reduce"
5299        );
5300        assert_eq!(
5301            endomorphic + diffusive + convergent,
5302            ConvergencePointType::ALL.len() as u32
5303        );
5304    }
5305
5306    /// ARITY-PAIR ⇔ BUCKET CONTRACT: the `(input_arity, output_arity)`
5307    /// projection names the same topology partition as the
5308    /// `is_endomorphic` / `is_diffusive` / `is_convergent` predicate
5309    /// triple. `(One, One) ⇒ endomorphic`; `(One, Many) ⇒ diffusive`;
5310    /// `(Many, One) ⇒ convergent`. The impossible `(Many, Many)`
5311    /// bucket is pinned empty here — a `(Many, Many)` point would
5312    /// have no convergence semantics (many independent inputs
5313    /// replicated across many independent outputs) and every future
5314    /// DAG-composition validator would have to special-case it. This
5315    /// seal is the bridge that lets a future graph validator dispatch
5316    /// on either projection (arity pair OR bucket predicates) without
5317    /// drift — and a future variant that wants `(Many, Many)` must
5318    /// extend the bucket carving deliberately rather than silently
5319    /// shipping a fourth topology class.
5320    #[test]
5321    fn convergence_point_type_arity_pair_agrees_with_bucket() {
5322        for t in ConvergencePointType::ALL {
5323            match (t.input_arity(), t.output_arity()) {
5324                (Arity::One, Arity::One) => assert!(
5325                    t.is_endomorphic(),
5326                    "{t:?} has (One, One) arity but is not endomorphic"
5327                ),
5328                (Arity::One, Arity::Many) => assert!(
5329                    t.is_diffusive(),
5330                    "{t:?} has (One, Many) arity but is not diffusive"
5331                ),
5332                (Arity::Many, Arity::One) => assert!(
5333                    t.is_convergent(),
5334                    "{t:?} has (Many, One) arity but is not convergent"
5335                ),
5336                (Arity::Many, Arity::Many) => panic!(
5337                    "{t:?} has (Many, Many) arity — pinned empty; \
5338                     extend the topology carving before adding a variant here"
5339                ),
5340            }
5341        }
5342    }
5343
5344    /// BRIDGE ROUND-TRIP CONTRACT: every variant survives the
5345    /// CRD-facing (`PascalCase`) ↔ tatara-core (`snake_case`)
5346    /// `From` hop. Today the bridge is two hand-written 8-arm
5347    /// matches in this file; pinning the round-trip over `ALL`
5348    /// means a future variant added without extending the bridge
5349    /// fails here at one site instead of drifting between the CRD
5350    /// wire format and the
5351    /// `core::ConvergencePointType` selector axis that
5352    /// `compliance_binding::PointSelector::ByType` already
5353    /// dispatches against.
5354    #[test]
5355    fn convergence_point_type_bridge_roundtrip_over_all() {
5356        for t in ConvergencePointType::ALL {
5357            let core_t: core::ConvergencePointType = t.into();
5358            let back: ConvergencePointType = core_t.into();
5359            assert_eq!(back, t, "bridge round-trip failed for {t:?}");
5360        }
5361    }
5362
5363    // ── closed-set algebra contracts for Arity ───────────────────
5364
5365    /// `ALL` is the source of truth — pin its closure so a variant
5366    /// added without an `ALL` entry fails here. The arity is asserted
5367    /// by the `[Self; 2]` array type itself.
5368    #[test]
5369    fn arity_all_is_unique_and_complete() {
5370        let mut seen = std::collections::HashSet::new();
5371        for a in Arity::ALL {
5372            assert!(seen.insert(a), "duplicate variant in ALL: {a:?}");
5373        }
5374        assert_eq!(seen.len(), Arity::ALL.len());
5375    }
5376
5377    /// The Display impl IS `as_str` — pinning this lets future
5378    /// callers reach for either projection without drift. No serde
5379    /// matching here because `Arity` is a typed projection, not a
5380    /// CRD-facing enum — it never crosses the wire. Routed through
5381    /// the substrate-wide [`crate::tagged_union::assert_display_matches_label`]
5382    /// primitive so the sweep body lives at ONE substrate site rather
5383    /// than restated per-implementor. Also exercised through the
5384    /// substrate-wide `every_production_display_impl_binds_through_the_testkit_primitive`
5385    /// sweep so a per-crate test-site drop cannot silently disable the
5386    /// check.
5387    #[test]
5388    fn arity_display_matches_as_str() {
5389        crate::tagged_union::assert_display_matches_label::<Arity>();
5390    }
5391
5392    /// PREDICATE CONTRACT: `is_one` is true exactly for `Arity::One`.
5393    /// The disjointness against `Many` is structural (only two
5394    /// variants) but pinning the codomain here means a future
5395    /// `Arity::Zero` variant must declare its own `is_one` arm
5396    /// deliberately rather than silently defaulting through a
5397    /// non-closed-set match.
5398    #[test]
5399    fn arity_is_one_predicate_truth_table() {
5400        assert!(Arity::One.is_one());
5401        assert!(!Arity::Many.is_one());
5402    }
5403
5404    /// PREDICATE CONTRACT: `is_many` is true exactly for `Arity::Many`
5405    /// — the antisymmetric image of `is_one` on the current two-
5406    /// variant closed set. Pins the codomain here means a future
5407    /// `Arity::Zero` (or any other) variant must declare its own
5408    /// `is_many` arm deliberately rather than silently defaulting
5409    /// through a non-closed-set match.
5410    #[test]
5411    fn arity_is_many_predicate_truth_table() {
5412        assert!(!Arity::One.is_many());
5413        assert!(Arity::Many.is_many());
5414    }
5415
5416    /// BINARY XOR PARTITION pin — for every [`Arity`] variant, EXACTLY
5417    /// ONE of `is_one` / `is_many` holds. Structural twin of the
5418    /// optimization-direction axis
5419    /// (`optimization_direction_prefers_lower_xor_prefers_higher`),
5420    /// the calm axis
5421    /// (`calm_classification_monotone_xor_requires_coordination`), and
5422    /// the data axis (`data_classification_public_xor_restricted`) —
5423    /// all four binary XOR partitions publish their two derived-
5424    /// nullary-bool projections as complementary XOR pairs at ONE
5425    /// site each so the closed set carves into disjoint buckets by
5426    /// construction. A future variant that returned `true` for both
5427    /// (single AND multi — a category error) or `false` for both (an
5428    /// inert cardinality with no edge count: a hypothetical `Zero`
5429    /// sink sentinel MUST answer `false` on BOTH here, forcing the
5430    /// author to add a third derived-nullary predicate on the closed
5431    /// set deliberately rather than silently bucketing it onto an
5432    /// existing cardinality) would fail here, forcing the author to
5433    /// extend either the predicates or the [`Arity`] enum
5434    /// deliberately.
5435    #[test]
5436    fn arity_is_one_xor_is_many_over_all() {
5437        for a in Arity::ALL {
5438            assert!(
5439                a.is_one() ^ a.is_many(),
5440                "{a:?}: is_one() XOR is_many() must hold",
5441            );
5442        }
5443    }
5444
5445    /// COVERAGE CONTRACT: every [`Arity`] variant lands in exactly one
5446    /// of two cardinality buckets — single (`One`) or multi (`Many`).
5447    /// Pins the two buckets at their declared cardinalities (1, 1 —
5448    /// sum to `ALL.len()`) so a future variant lands somewhere
5449    /// deliberately. Structural mirror of
5450    /// `optimization_direction_buckets_cover_every_variant` on the
5451    /// sibling optimization-direction axis.
5452    #[test]
5453    fn arity_buckets_cover_every_variant() {
5454        let mut single = 0u32;
5455        let mut multi = 0u32;
5456        for a in Arity::ALL {
5457            if a.is_one() {
5458                single += 1;
5459            } else {
5460                multi += 1;
5461            }
5462        }
5463        assert_eq!(single, 1, "single-edge bucket: One");
5464        assert_eq!(multi, 1, "multi-edge bucket: Many");
5465        assert_eq!(single + multi, Arity::ALL.len() as u32);
5466    }
5467
5468    // ── closed-set algebra contracts for SubstrateType
5469    //    (ALL × as_str × FromStr × predicate triple × bridge) ─────────
5470
5471    /// Structural well-formedness of [`SubstrateType`] as a
5472    /// [`tatara_lisp::ClosedSet`] implementor — see
5473    /// [`convergence_point_type_is_well_formed_closed_set`] for the
5474    /// canonical lift narrative. Replaces
5475    /// `substrate_type_all_is_unique_and_complete` +
5476    /// `substrate_type_roundtrip_via_as_str` + the empty-input arm
5477    /// of `unknown_substrate_type_errors`.
5478    #[test]
5479    fn substrate_type_is_well_formed_closed_set() {
5480        tatara_closed_set::assert_closed_set_well_formed::<SubstrateType>();
5481    }
5482
5483    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
5484    /// output verbatim for every variant. A future variant rename
5485    /// (or an `as_str` arm typo) lands here at one site, instead of
5486    /// drifting between the typed surface, the CRD enum, and the
5487    /// YAML wire format the reconciler reads from
5488    /// `spec.classification.substrate`.
5489    #[test]
5490    fn substrate_type_as_str_matches_serde() {
5491        crate::tagged_union::assert_label_matches_serde_serialization::<SubstrateType>();
5492    }
5493
5494    /// The Display impl IS `as_str` — pinning this lets future
5495    /// callers reach for either projection without drift. Any
5496    /// operator-facing `substrate={kind}` diagnostic that composes
5497    /// through Display inherits the canonical wire-format string
5498    /// automatically.
5499    #[test]
5500    fn substrate_type_display_matches_as_str() {
5501        crate::tagged_union::assert_display_matches_label::<SubstrateType>();
5502    }
5503
5504    /// `FromStr` rejects strings outside the canonical projection —
5505    /// lowercased / typo / cross-axis-leaked — and the error echoes
5506    /// the input verbatim so the operator-facing diagnostic surfaces
5507    /// the bad value, not a normalized form. The empty-input arm is
5508    /// pinned by [`substrate_type_is_well_formed_closed_set`] via
5509    /// the `tatara_lisp::ClosedSet` testkit; the cases here pin the
5510    /// verbatim-echo contract on the [`UnknownSubstrateType`]
5511    /// newtype, which the trait's `make_unknown` can't see.
5512    #[test]
5513    fn unknown_substrate_type_errors() {
5514        for bad in [
5515            "compute",  // lowercased
5516            "COMPUTE",  // uppercased
5517            "Computte", // typo
5518            "Database", "Steady",   // PoolPhase-axis leak
5519            "Pii",      // DataClassification-axis leak
5520            "Attested", // ProcessPhase-axis leak
5521            "Gate",     // ConvergencePointType-axis leak
5522            "Monotone", // CalmClassification-axis leak
5523            "PromQL",   // ConditionKind-axis leak
5524        ] {
5525            let err = SubstrateType::from_str(bad).unwrap_err();
5526            assert_eq!(err.0, bad, "error payload should echo input verbatim");
5527        }
5528    }
5529
5530    // `unknown_substrate_type_message_matches_substrate_convention`
5531    // removed — clause (5) of
5532    // `tatara_closed_set::assert_closed_set_well_formed::<SubstrateType>()`
5533    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
5534    // shape generically (called from
5535    // `substrate_type_is_well_formed_closed_set` above); the
5536    // `SET_LABEL` projection is pinned by
5537    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
5538
5539    /// TRUTH-TABLE CONTRACT: the predicate triple agrees with the
5540    /// documented per-variant plane role. Pinning this table at one
5541    /// site means any future compliance-baseline selector reads the
5542    /// same projection that the reconciler stamps on the CRD.
5543    #[test]
5544    fn substrate_type_predicate_truth_tables() {
5545        // Resource plane: you allocate budgets from it.
5546        for t in [
5547            SubstrateType::Financial,
5548            SubstrateType::Compute,
5549            SubstrateType::Network,
5550            SubstrateType::Storage,
5551        ] {
5552            assert!(t.is_resource(), "{t:?} should be a resource substrate");
5553            assert!(!t.is_policy(), "{t:?} should not be a policy substrate");
5554            assert!(
5555                !t.is_telemetry(),
5556                "{t:?} should not be a telemetry substrate"
5557            );
5558        }
5559
5560        // Policy plane: it gates access for other workloads.
5561        for t in [
5562            SubstrateType::Security,
5563            SubstrateType::Identity,
5564            SubstrateType::Regulatory,
5565        ] {
5566            assert!(!t.is_resource(), "{t:?} should not be a resource substrate");
5567            assert!(t.is_policy(), "{t:?} should be a policy substrate");
5568            assert!(
5569                !t.is_telemetry(),
5570                "{t:?} should not be a telemetry substrate"
5571            );
5572        }
5573
5574        // Telemetry plane: it observes other workloads.
5575        assert!(!SubstrateType::Observability.is_resource());
5576        assert!(!SubstrateType::Observability.is_policy());
5577        assert!(SubstrateType::Observability.is_telemetry());
5578    }
5579
5580    /// COVERAGE CONTRACT: every variant lands in *exactly one* of
5581    /// the three plane buckets — resource, policy, or telemetry.
5582    /// Pins the three buckets at their declared cardinalities (4,
5583    /// 3, 1 — sum to `ALL.len()`) so a future variant lands
5584    /// somewhere deliberately. No variant returns true from more
5585    /// than one predicate; no variant returns false from all three.
5586    #[test]
5587    fn substrate_type_buckets_cover_every_variant() {
5588        let mut resource = 0u32;
5589        let mut policy = 0u32;
5590        let mut telemetry = 0u32;
5591        for t in SubstrateType::ALL {
5592            let buckets = [t.is_resource(), t.is_policy(), t.is_telemetry()];
5593            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
5594            assert_eq!(
5595                hits, 1,
5596                "{t:?} landed in {hits} buckets: {buckets:?} (must be exactly one)"
5597            );
5598            if t.is_resource() {
5599                resource += 1;
5600            }
5601            if t.is_policy() {
5602                policy += 1;
5603            }
5604            if t.is_telemetry() {
5605                telemetry += 1;
5606            }
5607        }
5608        assert_eq!(
5609            resource, 4,
5610            "resource bucket: Financial + Compute + Network + Storage"
5611        );
5612        assert_eq!(policy, 3, "policy bucket: Security + Identity + Regulatory");
5613        assert_eq!(telemetry, 1, "telemetry bucket: Observability");
5614        assert_eq!(
5615            resource + policy + telemetry,
5616            SubstrateType::ALL.len() as u32
5617        );
5618    }
5619
5620    /// BRIDGE ROUND-TRIP CONTRACT: every variant survives the
5621    /// CRD-facing (`PascalCase`) ↔ tatara-core (`snake_case`)
5622    /// `From` hop. Today the bridge is two hand-written 8-arm
5623    /// matches in this file; pinning the round-trip over `ALL`
5624    /// means a future variant added without extending the bridge
5625    /// fails here at one site instead of drifting between the CRD
5626    /// wire format and the `core::SubstrateType` selector axis
5627    /// that `compliance_binding::PointSelector::BySubstrate`
5628    /// already dispatches against.
5629    #[test]
5630    fn substrate_type_bridge_roundtrip_over_all() {
5631        for t in SubstrateType::ALL {
5632            let core_t: core::SubstrateType = t.into();
5633            let back: SubstrateType = core_t.into();
5634            assert_eq!(back, t, "bridge round-trip failed for {t:?}");
5635        }
5636    }
5637
5638    // ── closed-set algebra contracts for CalmClassification
5639    //    (ALL × as_str × FromStr × requires_coordination × bridge) ─────
5640
5641    /// Structural well-formedness of [`CalmClassification`] as a
5642    /// [`tatara_lisp::ClosedSet`] implementor — see
5643    /// [`convergence_point_type_is_well_formed_closed_set`] for the
5644    /// canonical lift narrative. Replaces
5645    /// `calm_classification_all_is_unique_and_complete` +
5646    /// `calm_classification_roundtrip_via_as_str` + the empty-input
5647    /// arm of `unknown_calm_classification_errors`.
5648    #[test]
5649    fn calm_classification_is_well_formed_closed_set() {
5650        tatara_closed_set::assert_closed_set_well_formed::<CalmClassification>();
5651    }
5652
5653    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
5654    /// output verbatim for every variant. A future variant rename
5655    /// (or an `as_str` arm typo) lands here at one site, instead of
5656    /// drifting between the typed surface, the CRD enum, and the
5657    /// YAML wire format the reconciler reads from
5658    /// `spec.classification.calm`.
5659    #[test]
5660    fn calm_classification_as_str_matches_serde() {
5661        crate::tagged_union::assert_label_matches_serde_serialization::<CalmClassification>();
5662    }
5663
5664    /// The Display impl IS `as_str` — pinning this lets future
5665    /// callers reach for either projection without drift. Any
5666    /// operator-facing `calm={kind}` diagnostic that composes
5667    /// through Display inherits the canonical wire-format string
5668    /// automatically.
5669    #[test]
5670    fn calm_classification_display_matches_as_str() {
5671        crate::tagged_union::assert_display_matches_label::<CalmClassification>();
5672    }
5673
5674    /// `FromStr` rejects strings outside the canonical projection —
5675    /// lowercased / typo / cross-axis-leaked — and the error echoes
5676    /// the input verbatim so the operator-facing diagnostic surfaces
5677    /// the bad value, not a normalized form. The empty-input arm is
5678    /// pinned by [`calm_classification_is_well_formed_closed_set`]
5679    /// via the `tatara_lisp::ClosedSet` testkit; the cases here pin
5680    /// the verbatim-echo contract on the
5681    /// [`UnknownCalmClassification`] newtype, which the trait's
5682    /// `make_unknown` can't see.
5683    #[test]
5684    fn unknown_calm_classification_errors() {
5685        for bad in [
5686            "monotone",     // lowercased
5687            "MONOTONE",     // uppercased
5688            "Mono",         // typo
5689            "non_monotone", // core's snake_case form (must not cross axes)
5690            "non-monotone", // dashed
5691            "Monotonic",    // close-typo
5692            "Steady",       // PoolPhase-axis leak
5693            "Pii",          // DataClassification-axis leak
5694            "Attested",     // ProcessPhase-axis leak
5695            "Compute",      // SubstrateType-axis leak
5696            "Gate",         // ConvergencePointType-axis leak
5697            "PromQL",       // ConditionKind-axis leak
5698        ] {
5699            let err = CalmClassification::from_str(bad).unwrap_err();
5700            assert_eq!(err.0, bad, "error payload should echo input verbatim");
5701        }
5702    }
5703
5704    // `unknown_calm_classification_message_matches_substrate_convention`
5705    // removed — clause (5) of
5706    // `tatara_closed_set::assert_closed_set_well_formed::<CalmClassification>()`
5707    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
5708    // shape generically (called from
5709    // `calm_classification_is_well_formed_closed_set` above); the
5710    // `SET_LABEL` projection is pinned by
5711    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
5712
5713    /// CALM-THEOREM TRUTH-TABLE CONTRACT: `requires_coordination`
5714    /// implements the biconditional half of Hellerstein's CALM
5715    /// theorem — `Monotone ⇒ false` and `NonMonotone ⇒ true`.
5716    /// Pinning this table at one site means any future reconciler
5717    /// dispatch that picks between Raft writes and gossip
5718    /// propagation reads the same projection the lattice ordering
5719    /// (`Monotone ≤ NonMonotone`) does. A future variant that
5720    /// flipped this mapping would have to renumber every consumer
5721    /// deliberately rather than silently shipping a non-monotone
5722    /// operation onto the no-coordination path.
5723    #[test]
5724    fn calm_classification_requires_coordination_truth_table() {
5725        assert!(!CalmClassification::Monotone.requires_coordination());
5726        assert!(CalmClassification::NonMonotone.requires_coordination());
5727    }
5728
5729    /// COVERAGE CONTRACT: every variant lands in exactly one of two
5730    /// coordination buckets — no-coordination (`Monotone`) or
5731    /// requires-coordination (`NonMonotone`). Pins the two buckets
5732    /// at their declared cardinalities (1, 1 — sum to `ALL.len()`)
5733    /// so a future variant lands somewhere deliberately. The
5734    /// biconditional structure of the CALM theorem makes this
5735    /// partition exhaustive by construction.
5736    #[test]
5737    fn calm_classification_buckets_cover_every_variant() {
5738        let mut no_coord = 0u32;
5739        let mut coord = 0u32;
5740        for c in CalmClassification::ALL {
5741            if c.requires_coordination() {
5742                coord += 1;
5743            } else {
5744                no_coord += 1;
5745            }
5746        }
5747        assert_eq!(no_coord, 1, "no-coordination bucket: Monotone");
5748        assert_eq!(coord, 1, "requires-coordination bucket: NonMonotone");
5749        assert_eq!(no_coord + coord, CalmClassification::ALL.len() as u32);
5750    }
5751
5752    /// DEFAULT-AGREEMENT CONTRACT: `CalmClassification::default()`
5753    /// returns `Monotone` (the variant tagged `#[default]`) AND that
5754    /// variant lands in the no-coordination bucket. A future
5755    /// `#[default]` rename without flipping the predicate fails
5756    /// here — the default for an under-specified Process must
5757    /// remain the no-coordination side so that an unannotated
5758    /// Process can't silently demand Raft writes the reconciler
5759    /// isn't configured to provide.
5760    #[test]
5761    fn calm_classification_default_is_monotone_no_coordination() {
5762        let c = CalmClassification::default();
5763        assert_eq!(c, CalmClassification::Monotone);
5764        assert!(!c.requires_coordination());
5765    }
5766
5767    /// CALM-THEOREM POSITIVE-FRAMING TRUTH-TABLE CONTRACT:
5768    /// `is_monotone` implements the antisymmetric partner of
5769    /// `requires_coordination` — `Monotone ⇒ true` and
5770    /// `NonMonotone ⇒ false`. Pinning this table at one site means
5771    /// any future consumer asking the positive CALM framing "can
5772    /// this Process participate in gossip-only writes?" reads the
5773    /// same projection the lattice ordering and the antisymmetric
5774    /// `requires_coordination` peer read. A future variant that
5775    /// flipped this mapping would have to renumber every consumer
5776    /// deliberately rather than silently promoting a non-monotone
5777    /// operation onto the gossip path.
5778    #[test]
5779    fn calm_classification_is_monotone_truth_table() {
5780        assert!(CalmClassification::Monotone.is_monotone());
5781        assert!(!CalmClassification::NonMonotone.is_monotone());
5782    }
5783
5784    /// XOR PARTITION CONTRACT: for every [`CalmClassification`]
5785    /// variant, EXACTLY ONE of `is_monotone` /
5786    /// `requires_coordination` is true — the two predicates carve
5787    /// the closed set into COMPLEMENTARY buckets (monotone ↔ no
5788    /// coordination; non-monotone ↔ requires coordination), the
5789    /// biconditional half of Hellerstein's CALM theorem as a
5790    /// closed-set-driven proof. A future variant that returned
5791    /// `true` for both (a monotone operation that nonetheless
5792    /// requires coordination — a category error under CALM) or
5793    /// `false` for both (an inert variant with no monotonicity
5794    /// classification — nothing to dispatch on) would fail here,
5795    /// forcing the author to extend either the predicates or the
5796    /// [`CalmClassification`] enum deliberately. Structural twin of
5797    /// [`horizon_kind_terminate_xor_requires_metric_axes`] on the
5798    /// horizon axis — both binary closed sets publish their two
5799    /// derived-nullary-bool projections as complementary XOR pairs
5800    /// at ONE site each so the axis carves into disjoint buckets
5801    /// by construction.
5802    #[test]
5803    fn calm_classification_monotone_xor_requires_coordination() {
5804        for c in CalmClassification::ALL {
5805            assert!(
5806                c.is_monotone() ^ c.requires_coordination(),
5807                "{c:?}: is_monotone() XOR requires_coordination() must hold",
5808            );
5809        }
5810    }
5811
5812    /// BRIDGE ROUND-TRIP CONTRACT: every variant survives the
5813    /// CRD-facing (`PascalCase`) ↔ tatara-core (`snake_case`)
5814    /// `From` hop. Today the bridge is two hand-written 2-arm
5815    /// matches in this file; pinning the round-trip over `ALL`
5816    /// means a future variant added without extending the bridge
5817    /// fails here at one site instead of drifting between the CRD
5818    /// wire format and the `core::CalmClassification` selector
5819    /// axis. Closes the asymmetry that pre-lift had a
5820    /// `From<CalmClassification> for core::CalmClassification`
5821    /// forward bridge but no reverse — symmetric to every other
5822    /// classification-axis bridge in this file.
5823    #[test]
5824    fn calm_classification_bridge_roundtrip_over_all() {
5825        for c in CalmClassification::ALL {
5826            let core_c: core::CalmClassification = c.into();
5827            let back: CalmClassification = core_c.into();
5828            assert_eq!(back, c, "bridge round-trip failed for {c:?}");
5829        }
5830    }
5831
5832    // ── closed-set algebra contracts for OptimizationDirection
5833    //    (ALL × as_str × FromStr × prefers_lower × is_improvement) ───
5834
5835    /// Structural well-formedness of [`OptimizationDirection`] as a
5836    /// [`tatara_lisp::ClosedSet`] implementor — see
5837    /// [`convergence_point_type_is_well_formed_closed_set`] for the
5838    /// canonical lift narrative. Replaces
5839    /// `optimization_direction_all_is_unique_and_complete` +
5840    /// `optimization_direction_roundtrip_via_as_str` + the empty-
5841    /// input arm of `unknown_optimization_direction_errors`.
5842    #[test]
5843    fn optimization_direction_is_well_formed_closed_set() {
5844        tatara_closed_set::assert_closed_set_well_formed::<OptimizationDirection>();
5845    }
5846
5847    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
5848    /// output verbatim for every variant. A future variant rename
5849    /// (or an `as_str` arm typo) lands here at one site, instead of
5850    /// drifting between the typed surface, the CRD enum, and the
5851    /// YAML wire format the reconciler reads from
5852    /// `spec.classification.horizon.direction`.
5853    #[test]
5854    fn optimization_direction_as_str_matches_serde() {
5855        crate::tagged_union::assert_label_matches_serde_serialization::<OptimizationDirection>();
5856    }
5857
5858    /// The Display impl IS `as_str` — pinning this lets future
5859    /// callers reach for either projection without drift. Any
5860    /// operator-facing `direction={kind}` diagnostic that composes
5861    /// through Display inherits the canonical wire-format string
5862    /// automatically.
5863    #[test]
5864    fn optimization_direction_display_matches_as_str() {
5865        crate::tagged_union::assert_display_matches_label::<OptimizationDirection>();
5866    }
5867
5868    /// `FromStr` rejects strings outside the canonical projection —
5869    /// lowercased / typo / cross-axis-leaked — and the error echoes
5870    /// the input verbatim so the operator-facing diagnostic surfaces
5871    /// the bad value, not a normalized form. The empty-input arm is
5872    /// pinned by [`optimization_direction_is_well_formed_closed_set`]
5873    /// via the `tatara_lisp::ClosedSet` testkit; the cases here pin
5874    /// the verbatim-echo contract on the
5875    /// [`UnknownOptimizationDirection`] newtype, which the trait's
5876    /// `make_unknown` can't see.
5877    #[test]
5878    fn unknown_optimization_direction_errors() {
5879        for bad in [
5880            "minimize", // lowercased
5881            "MINIMIZE", // uppercased
5882            "Minimze",  // typo
5883            "Lower",    // synonym, not canonical
5884            "Higher",   // synonym, not canonical
5885            "Asc",      // wire-leak from sort-order axis
5886            "Desc",     // wire-leak from sort-order axis
5887            "Bounded",  // HorizonKind-axis leak
5888            "Monotone", // CalmClassification-axis leak
5889            "Steady",   // PoolPhase-axis leak
5890            "Pii",      // DataClassification-axis leak
5891            "Attested", // ProcessPhase-axis leak
5892            "Compute",  // SubstrateType-axis leak
5893            "Gate",     // ConvergencePointType-axis leak
5894            "PromQL",   // ConditionKind-axis leak
5895        ] {
5896            let err = OptimizationDirection::from_str(bad).unwrap_err();
5897            assert_eq!(err.0, bad, "error payload should echo input verbatim");
5898        }
5899    }
5900
5901    // `unknown_optimization_direction_message_matches_substrate_convention`
5902    // removed — clause (5) of
5903    // `tatara_closed_set::assert_closed_set_well_formed::<OptimizationDirection>()`
5904    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
5905    // shape generically (called from
5906    // `optimization_direction_is_well_formed_closed_set` above); the
5907    // `SET_LABEL` projection is pinned by
5908    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
5909
5910    /// TRUTH-TABLE CONTRACT: `prefers_lower` is the boolean
5911    /// partition `Minimize ⇒ true`, `Maximize ⇒ false`. Pinning this
5912    /// table at one site means any future dispatch on per-direction
5913    /// polarity (rate-window evaluator, breathe-band regression
5914    /// detector) reads the same projection rather than re-deriving
5915    /// from the variant name. Mirrors
5916    /// [`CalmClassification::requires_coordination`]'s truth-table
5917    /// shape.
5918    #[test]
5919    fn optimization_direction_prefers_lower_truth_table() {
5920        assert!(OptimizationDirection::Minimize.prefers_lower());
5921        assert!(!OptimizationDirection::Maximize.prefers_lower());
5922    }
5923
5924    /// POSITIVE-FRAMING TRUTH-TABLE CONTRACT: `prefers_higher`
5925    /// implements the antisymmetric partner of `prefers_lower` —
5926    /// `Minimize ⇒ false` and `Maximize ⇒ true`. Pinning this table
5927    /// at one site means any future consumer asking the positive
5928    /// higher-is-better framing ("does this direction reward
5929    /// throughput / coverage / revenue rate?") reads the same
5930    /// projection every asymptotic-health probe writes. Mirrors
5931    /// [`CalmClassification::is_monotone`]'s positive-framing shape
5932    /// on the sibling binary closed set.
5933    #[test]
5934    fn optimization_direction_prefers_higher_truth_table() {
5935        assert!(!OptimizationDirection::Minimize.prefers_higher());
5936        assert!(OptimizationDirection::Maximize.prefers_higher());
5937    }
5938
5939    /// XOR PARTITION CONTRACT: for every [`OptimizationDirection`]
5940    /// variant, EXACTLY ONE of `prefers_lower` / `prefers_higher` is
5941    /// true — the two predicates carve the closed set into
5942    /// COMPLEMENTARY buckets (lower-is-better ↔ higher-is-better),
5943    /// the exact binary partition already sealed on the sibling
5944    /// [`CalmClassification`] axis by
5945    /// `calm_classification_monotone_xor_requires_coordination` and
5946    /// on the sibling [`DataClassification`] axis (through the
5947    /// projection layer) by `data_classification_public_xor_restricted`,
5948    /// now lifted to the two-variant optimization-direction axis. A
5949    /// future variant that returned `true` for both (lower AND higher —
5950    /// a category error) or `false` for both (an inert direction with
5951    /// no polarity — nothing to dispatch on: a hypothetical `Stabilize`
5952    /// sentinel MUST answer `false` on BOTH here, forcing the author
5953    /// to add a third derived-nullary predicate on the closed set
5954    /// deliberately rather than silently bucketing it onto an existing
5955    /// polarity) would fail here, forcing the author to extend either
5956    /// the predicates or the [`OptimizationDirection`] enum deliberately.
5957    /// Structural twin of `calm_classification_monotone_xor_requires_coordination`
5958    /// and `data_classification_public_xor_restricted` on the sibling
5959    /// calm + data axes — all three binary XOR partitions publish
5960    /// their two derived-nullary-bool projections as complementary
5961    /// XOR pairs at ONE site each so the axis carves into disjoint
5962    /// buckets by construction.
5963    #[test]
5964    fn optimization_direction_prefers_lower_xor_prefers_higher() {
5965        for d in OptimizationDirection::ALL {
5966            assert!(
5967                d.prefers_lower() ^ d.prefers_higher(),
5968                "{d:?}: prefers_lower() XOR prefers_higher() must hold",
5969            );
5970        }
5971    }
5972
5973    /// COVERAGE CONTRACT: every variant lands in exactly one of two
5974    /// polarity buckets — prefers-lower (`Minimize`) or
5975    /// prefers-higher (`Maximize`). Pins the two buckets at their
5976    /// declared cardinalities (1, 1 — sum to `ALL.len()`) so a
5977    /// future variant lands somewhere deliberately.
5978    #[test]
5979    fn optimization_direction_buckets_cover_every_variant() {
5980        let mut lower = 0u32;
5981        let mut higher = 0u32;
5982        for d in OptimizationDirection::ALL {
5983            if d.prefers_lower() {
5984                lower += 1;
5985            } else {
5986                higher += 1;
5987            }
5988        }
5989        assert_eq!(lower, 1, "prefers-lower bucket: Minimize");
5990        assert_eq!(higher, 1, "prefers-higher bucket: Maximize");
5991        assert_eq!(lower + higher, OptimizationDirection::ALL.len() as u32);
5992    }
5993
5994    /// LOAD-BEARING TRUTH-TABLE: `is_improvement` answers "is `after`
5995    /// strictly better than `before` under this direction?" for the
5996    /// canonical samples. Pins the strict-improvement semantic at
5997    /// one site so a future rate-window evaluator or breathe-band
5998    /// regression detector reads the same projection that the
5999    /// asymptotic-health probe writes.
6000    #[test]
6001    fn optimization_direction_is_improvement_truth_table() {
6002        // Minimize: lower-is-better
6003        assert!(OptimizationDirection::Minimize.is_improvement(10.0, 5.0));
6004        assert!(!OptimizationDirection::Minimize.is_improvement(5.0, 10.0));
6005
6006        // Maximize: higher-is-better
6007        assert!(OptimizationDirection::Maximize.is_improvement(5.0, 10.0));
6008        assert!(!OptimizationDirection::Maximize.is_improvement(10.0, 5.0));
6009    }
6010
6011    /// NO-OP CONTRACT: a sample equal to the previous one is NOT an
6012    /// improvement under either direction. Pinning this guarantees
6013    /// a flatlined rate-window evaluator doesn't silently keep
6014    /// claiming "still improving" forever and skipping the
6015    /// healthy-rate-threshold gate.
6016    #[test]
6017    fn optimization_direction_no_op_is_not_improvement() {
6018        for d in OptimizationDirection::ALL {
6019            assert!(
6020                !d.is_improvement(7.0, 7.0),
6021                "{d:?}: equal samples must not count as improvement",
6022            );
6023            assert!(
6024                !d.is_improvement(0.0, 0.0),
6025                "{d:?}: zero/zero must not count as improvement",
6026            );
6027        }
6028    }
6029
6030    /// NaN CONTRACT: NaN on either operand short-circuits to `false`
6031    /// (no improvement claim from indeterminate data) via the
6032    /// standard `PartialOrd` behavior. Without this, a rate-window
6033    /// evaluator that sampled a NaN partway through (a transient
6034    /// metric-scrape failure) would either panic on an `Ord`
6035    /// comparison or — worse — silently claim improvement on the
6036    /// next valid sample by treating NaN as the worst case.
6037    #[test]
6038    fn optimization_direction_nan_is_not_improvement() {
6039        let nan = f64::NAN;
6040        for d in OptimizationDirection::ALL {
6041            assert!(
6042                !d.is_improvement(nan, 1.0),
6043                "{d:?}: NaN before must not count as improvement",
6044            );
6045            assert!(
6046                !d.is_improvement(1.0, nan),
6047                "{d:?}: NaN after must not count as improvement",
6048            );
6049            assert!(
6050                !d.is_improvement(nan, nan),
6051                "{d:?}: NaN/NaN must not count as improvement",
6052            );
6053        }
6054    }
6055
6056    /// ANTISYMMETRY CONTRACT: for distinct finite samples,
6057    /// `is_improvement(a, b)` xor `is_improvement(b, a)` —
6058    /// exactly one direction of the pair counts as improvement.
6059    /// This is the algebraic shape every asymptotic-health
6060    /// rate-window evaluator depends on to avoid double-counting
6061    /// an improvement as a regression on the reverse traversal.
6062    /// A future variant that returned `true` for both directions
6063    /// (or `false` for both, the equal-sample case) would FAIL
6064    /// here, forcing the author to extend the consumer dispatch
6065    /// deliberately.
6066    #[test]
6067    fn optimization_direction_is_improvement_is_antisymmetric() {
6068        let pairs = [(1.0_f64, 2.0_f64), (0.0, 100.0), (-3.5, 3.5), (1e9, 1e-9)];
6069        for d in OptimizationDirection::ALL {
6070            for (a, b) in pairs {
6071                assert!(a != b, "test fixture requires distinct samples");
6072                assert!(
6073                    d.is_improvement(a, b) ^ d.is_improvement(b, a),
6074                    "{d:?}: antisymmetry violated on ({a}, {b})",
6075                );
6076            }
6077        }
6078    }
6079
6080    /// DEFAULT-AGREEMENT CONTRACT:
6081    /// `OptimizationDirection::default()` returns `Minimize` (the
6082    /// variant tagged `#[default]`), AND that variant lands in the
6083    /// prefers-lower bucket. A future `#[default]` rename without
6084    /// flipping the predicate fails here — `Minimize` is the
6085    /// canonical default for distributed-systems asymptotic
6086    /// optimization (cost / latency / error rate), so an
6087    /// unannotated metric must not silently flip the rate-window
6088    /// evaluator's polarity. This is also the same value the
6089    /// `Horizon → ConvergenceHorizon` bridge falls back to when
6090    /// `direction` is unset, so pinning the default here pins the
6091    /// bridge's behavior at one site.
6092    #[test]
6093    fn optimization_direction_default_is_minimize_prefers_lower() {
6094        let d = OptimizationDirection::default();
6095        assert_eq!(d, OptimizationDirection::Minimize);
6096        assert!(d.prefers_lower());
6097    }
6098
6099    /// BRIDGE ROUND-TRIP CONTRACT: every variant survives the
6100    /// CRD-facing (`PascalCase`) ↔ tatara-core (`snake_case`)
6101    /// `From` hop. Pre-lift the bridge was a one-way
6102    /// `From<OptimizationDirection> for core::OptimizationDirection`
6103    /// with no reverse — asymmetric to every other classification-
6104    /// axis bridge in this file. Pinning the round-trip over `ALL`
6105    /// means a future variant added without extending the bridge
6106    /// fails here at one site instead of drifting between the CRD
6107    /// wire format and `core::OptimizationDirection`.
6108    #[test]
6109    fn optimization_direction_bridge_roundtrip_over_all() {
6110        for d in OptimizationDirection::ALL {
6111            let core_d: core::OptimizationDirection = d.into();
6112            let back: OptimizationDirection = core_d.into();
6113            assert_eq!(back, d, "bridge round-trip failed for {d:?}");
6114        }
6115    }
6116
6117    // ── closed-set algebra contracts for HorizonKind
6118    //    (ALL × as_str × FromStr × terminates × requires_metric_axes) ──
6119
6120    /// Structural well-formedness of [`HorizonKind`] as a
6121    /// [`tatara_lisp::ClosedSet`] implementor — see
6122    /// [`convergence_point_type_is_well_formed_closed_set`] for the
6123    /// canonical lift narrative. Replaces
6124    /// `horizon_kind_all_is_unique_and_complete` +
6125    /// `horizon_kind_roundtrip_via_as_str` + the empty-input arm of
6126    /// `unknown_horizon_kind_errors`.
6127    #[test]
6128    fn horizon_kind_is_well_formed_closed_set() {
6129        tatara_closed_set::assert_closed_set_well_formed::<HorizonKind>();
6130    }
6131
6132    /// CANONICAL-KEY CONTRACT: `as_str` matches serde's PascalCase
6133    /// output verbatim for every variant. A future variant rename
6134    /// (or an `as_str` arm typo) lands here at one site, instead of
6135    /// drifting between the typed surface, the CRD enum, and the
6136    /// YAML wire format the reconciler stamps on
6137    /// `spec.classification.horizon.kind`.
6138    #[test]
6139    fn horizon_kind_as_str_matches_serde() {
6140        crate::tagged_union::assert_label_matches_serde_serialization::<HorizonKind>();
6141    }
6142
6143    /// The Display impl IS `as_str` — pinning this lets future
6144    /// callers reach for either projection without drift. Any
6145    /// operator-facing `horizon.kind={kind}` diagnostic that
6146    /// composes through Display inherits the canonical wire-format
6147    /// string automatically.
6148    #[test]
6149    fn horizon_kind_display_matches_as_str() {
6150        crate::tagged_union::assert_display_matches_label::<HorizonKind>();
6151    }
6152
6153    /// `FromStr` rejects strings outside the canonical projection —
6154    /// lowercased / typo / cross-axis-leaked — and the error echoes
6155    /// the input verbatim so the operator-facing diagnostic surfaces
6156    /// the bad value, not a normalized form. The empty-input arm is
6157    /// pinned by [`horizon_kind_is_well_formed_closed_set`] via the
6158    /// `tatara_lisp::ClosedSet` testkit; the cases here pin the
6159    /// verbatim-echo contract on the [`UnknownHorizonKind`] newtype,
6160    /// which the trait's `make_unknown` can't see.
6161    #[test]
6162    fn unknown_horizon_kind_errors() {
6163        for bad in [
6164            "bounded",   // lowercased
6165            "BOUNDED",   // uppercased
6166            "Boundd",    // typo
6167            "Finite",    // synonym, not canonical
6168            "Perpetual", // synonym, not canonical
6169            "Infinite",  // synonym, not canonical
6170            "Minimize",  // OptimizationDirection-axis leak
6171            "Monotone",  // CalmClassification-axis leak
6172            "Pii",       // DataClassification-axis leak
6173            "Steady",    // PoolPhase-axis leak
6174            "Attested",  // ProcessPhase-axis leak
6175            "Compute",   // SubstrateType-axis leak
6176            "Gate",      // ConvergencePointType-axis leak
6177            "PromQL",    // ConditionKind-axis leak
6178        ] {
6179            let err = HorizonKind::from_str(bad).unwrap_err();
6180            assert_eq!(err.0, bad, "error payload should echo input verbatim");
6181        }
6182    }
6183
6184    // `unknown_horizon_kind_message_matches_substrate_convention`
6185    // removed — clause (5) of
6186    // `tatara_closed_set::assert_closed_set_well_formed::<HorizonKind>()`
6187    // verifies the substrate-wide `"unknown {SET_LABEL}: {input}"`
6188    // shape generically (called from
6189    // `horizon_kind_is_well_formed_closed_set` above); the
6190    // `SET_LABEL` projection is pinned by
6191    // `tatara_lisp_derive::pascal_to_spaced_lowercase_tests`.
6192
6193    /// LOAD-BEARING TRUTH-TABLE: `terminates` is the boolean
6194    /// partition `Bounded ⇒ true`, `Asymptotic ⇒ false`. Pinning
6195    /// this table at one site means any future scheduler asking
6196    /// "will this Process reach `Reaped` via natural termination?"
6197    /// reads the same projection that the lattice ordering encodes
6198    /// (Bounded ≤ Asymptotic BECAUSE the bounded horizon strictly
6199    /// refines the asymptotic one by also terminating).
6200    #[test]
6201    fn horizon_kind_terminates_truth_table() {
6202        assert!(HorizonKind::Bounded.terminates());
6203        assert!(!HorizonKind::Asymptotic.terminates());
6204    }
6205
6206    /// LOAD-BEARING TRUTH-TABLE: `requires_metric_axes` is the
6207    /// boolean partition `Bounded ⇒ false`, `Asymptotic ⇒ true` —
6208    /// the typed image of the optionality the [`Horizon`] struct
6209    /// encodes via its three `Option<…>` fields (`metric`,
6210    /// `direction`, `healthy_rate_threshold`). The implicit
6211    /// "Asymptotic only" invariant in the field docs is now a
6212    /// checkable per-kind predicate. Pinning this table at one site
6213    /// means any future horizon-shape validator (CRD admission,
6214    /// `tatara-check` form linter, Lisp authoring-time predicate)
6215    /// reads the same projection.
6216    #[test]
6217    fn horizon_kind_requires_metric_axes_truth_table() {
6218        assert!(!HorizonKind::Bounded.requires_metric_axes());
6219        assert!(HorizonKind::Asymptotic.requires_metric_axes());
6220    }
6221
6222    /// COVERAGE CONTRACT: every variant lands in exactly one of two
6223    /// termination buckets — terminating (`Bounded`) or perpetual
6224    /// (`Asymptotic`). Pins the two buckets at their declared
6225    /// cardinalities (1, 1 — sum to `ALL.len()`) so a future variant
6226    /// lands somewhere deliberately.
6227    #[test]
6228    fn horizon_kind_buckets_cover_every_variant() {
6229        let mut terminating = 0u32;
6230        let mut perpetual = 0u32;
6231        for k in HorizonKind::ALL {
6232            if k.terminates() {
6233                terminating += 1;
6234            } else {
6235                perpetual += 1;
6236            }
6237        }
6238        assert_eq!(terminating, 1, "terminating bucket: Bounded");
6239        assert_eq!(perpetual, 1, "perpetual bucket: Asymptotic");
6240        assert_eq!(terminating + perpetual, HorizonKind::ALL.len() as u32);
6241    }
6242
6243    /// ANTISYMMETRY CONTRACT: for every variant, exactly one of
6244    /// `(terminates, requires_metric_axes)` is true — the two
6245    /// predicates carve the variants into complementary buckets
6246    /// (terminating ↔ no metric axes; perpetual ↔ requires metric
6247    /// axes). A future variant that returned `true` for both (a
6248    /// terminating horizon that nonetheless tracks an asymptotic
6249    /// metric) or `false` for both (an inert horizon with no
6250    /// termination AND no metric signal — there'd be nothing to
6251    /// observe) would fail here, forcing the author to extend
6252    /// either the predicates or the [`Horizon`] struct's
6253    /// optionality contract deliberately.
6254    #[test]
6255    fn horizon_kind_terminate_xor_requires_metric_axes() {
6256        for k in HorizonKind::ALL {
6257            assert!(
6258                k.terminates() ^ k.requires_metric_axes(),
6259                "{k:?}: terminates() XOR requires_metric_axes() must hold",
6260            );
6261        }
6262    }
6263
6264    /// DEFAULT-AGREEMENT CONTRACT: `HorizonKind::default()` returns
6265    /// `Bounded` (the variant tagged `#[default]`), AND that
6266    /// variant lands in the terminating bucket. A future
6267    /// `#[default]` rename without flipping the predicate fails
6268    /// here — `Bounded` is the canonical default for a convergence
6269    /// horizon (a point with no asymptotic axes declared should
6270    /// terminate naturally, not silently flip into a perpetual
6271    /// rate-window evaluator with zero threshold). This is also
6272    /// the same value `Horizon::default()` carries, so pinning the
6273    /// default here pins the struct-default behavior at one site.
6274    #[test]
6275    fn horizon_kind_default_is_bounded_terminates() {
6276        let k = HorizonKind::default();
6277        assert_eq!(k, HorizonKind::Bounded);
6278        assert!(k.terminates());
6279        assert!(!k.requires_metric_axes());
6280    }
6281
6282    /// HORIZON ↔ KIND AGREEMENT: every variant in `HorizonKind::ALL`
6283    /// composes with the existing [`Horizon::bounded`] /
6284    /// [`Horizon::asymptotic`] constructors to produce a `Horizon`
6285    /// whose `kind` matches AND whose `Option<…>` fields agree
6286    /// with `requires_metric_axes`. Pins the implicit contract
6287    /// between the kind discriminator and the optionality at one
6288    /// site — a future kind added without extending either the
6289    /// constructors or `requires_metric_axes` fails here before
6290    /// drifting between the typed surface and the documented
6291    /// "Asymptotic only" field invariant.
6292    #[test]
6293    fn horizon_kind_agrees_with_struct_optionality() {
6294        let bounded = Horizon::bounded();
6295        assert_eq!(bounded.kind, HorizonKind::Bounded);
6296        assert!(!bounded.kind.requires_metric_axes());
6297        assert!(bounded.metric.is_none());
6298        assert!(bounded.direction.is_none());
6299        assert!(bounded.healthy_rate_threshold.is_none());
6300
6301        let asymp = Horizon::asymptotic("p99_latency", OptimizationDirection::Minimize, 0.1);
6302        assert_eq!(asymp.kind, HorizonKind::Asymptotic);
6303        assert!(asymp.kind.requires_metric_axes());
6304        assert!(asymp.metric.is_some());
6305        assert!(asymp.direction.is_some());
6306        assert!(asymp.healthy_rate_threshold.is_some());
6307    }
6308
6309    // ── scalar-carrier presence probe on Classification × ConvergencePointType ──
6310    //
6311    // Fail-before-pass-after granularity: [`Classification::has_point_type`]
6312    // did not exist before this commit — every consumer of the
6313    // `(Classification, ConvergencePointType) -> bool` scalar-carrier
6314    // probe shape restated the `classification.point_type == kind`
6315    // equality body at its own callsite. Post-lift the shape lives at
6316    // ONE substrate owner and every downstream (the `point-type-<kind>`
6317    // require-tag family in `tatara-check`, future audit dispatchers
6318    // walking [`ConvergencePointType::ALL`], any future CRD-facing
6319    // closed-set discriminator on a required scalar `ProcessSpec` field
6320    // such as `has_substrate`/`has_calm`/`has_data_classification`)
6321    // binds through the SAME `has(kind)` shape the Option-slot
6322    // (`Intent::has`, `Lifetime::has`), slice-level
6323    // (`ConditionSliceExt::has_kind`, `DependsOnSliceExt::has_must_reach`,
6324    // `ComplianceBindingSliceExt::has_verification_phase`,
6325    // `ExportSpecSliceExt::has_{when,channel_kind,report_format,artifact_kind}`),
6326    // and prior scalar-carrier
6327    // (`SignalPolicy::has_sighup_strategy`,
6328    // `EncapsulatesSpec::has_mode`) peers publish.
6329
6330    /// DIAGONAL — for every [`ConvergencePointType`] variant, a
6331    /// [`Classification`] whose `point_type` field is set to that
6332    /// variant returns `true` from `has_point_type` on that same
6333    /// variant AND `false` on every other variant. Sweep the
6334    /// [`ConvergencePointType::ALL`] × ALL cross so a regression that
6335    /// hard-coded the arm to a single variant (silently returning
6336    /// `true` on every populated classification regardless of query
6337    /// kind) or wired the equality to a fixed unrelated field fails
6338    /// HERE at the substrate primitive before landing at the
6339    /// operator-facing checks.lisp surface.
6340    #[test]
6341    fn classification_has_point_type_returns_true_iff_variant_matches() {
6342        for populated in ConvergencePointType::ALL {
6343            let c = Classification::gate_compute_with_axis(populated);
6344            for query in ConvergencePointType::ALL {
6345                assert_eq!(
6346                    c.has_point_type(query),
6347                    query == populated,
6348                    "point_type={populated:?}: query {query:?} classification drifted",
6349                );
6350            }
6351        }
6352    }
6353
6354    /// GATE-COMPUTE BASELINE — the workspace-baseline
6355    /// [`Classification::gate_compute`] shape carries
6356    /// `point_type: Gate`, so `has_point_type` returns `true` on
6357    /// [`ConvergencePointType::Gate`] and `false` on every other of
6358    /// the eight variants. Pins the composition of the substrate's
6359    /// baseline-constructor primitive with the scalar-carrier
6360    /// presence probe — a regression that flipped
6361    /// `gate_compute().point_type` off `Gate` (or wired
6362    /// `has_point_type` to a fixed variant answer) fails here at ONE
6363    /// narrow site before drifting across every unadorned ephemeral
6364    /// env (`default_ephemeral_class`) and every downstream test
6365    /// fixture that keys assertions on the shape.
6366    #[test]
6367    fn classification_gate_compute_has_point_type_gate_only() {
6368        let c = Classification::gate_compute();
6369        for kind in ConvergencePointType::ALL {
6370            let expected = kind == ConvergencePointType::Gate;
6371            assert_eq!(
6372                c.has_point_type(kind),
6373                expected,
6374                "gate_compute (point_type=Gate) must return {expected} for {kind:?}",
6375            );
6376        }
6377    }
6378
6379    // ── scalar-carrier presence probe on Classification × SubstrateType ──
6380    //
6381    // Fail-before-pass-after granularity: [`Classification::has_substrate`]
6382    // did not exist before this commit — every consumer of the
6383    // `(Classification, SubstrateType) -> bool` scalar-carrier probe
6384    // shape restated the `classification.substrate == kind` equality
6385    // body at its own callsite. Post-lift the shape lives at ONE
6386    // substrate owner and every downstream (the `substrate-<kind>`
6387    // require-tag family in `tatara-check`, future audit dispatchers
6388    // walking [`SubstrateType::ALL`], any future CRD-facing closed-set
6389    // discriminator on a required scalar `ProcessSpec` field such as
6390    // `has_calm`/`has_data_classification`) binds through the SAME
6391    // `has(kind)` shape the Option-slot (`Intent::has`, `Lifetime::has`),
6392    // slice-level (`ConditionSliceExt::has_kind`,
6393    // `DependsOnSliceExt::has_must_reach`,
6394    // `ComplianceBindingSliceExt::has_verification_phase`,
6395    // `ExportSpecSliceExt::has_{when,channel_kind,report_format,artifact_kind}`),
6396    // and prior scalar-carrier
6397    // (`SignalPolicy::has_sighup_strategy`,
6398    // `EncapsulatesSpec::has_mode`, `Classification::has_point_type`)
6399    // peers publish.
6400
6401    /// DIAGONAL — for every [`SubstrateType`] variant, a
6402    /// [`Classification`] whose `substrate` field is set to that
6403    /// variant returns `true` from `has_substrate` on that same
6404    /// variant AND `false` on every other variant. Sweep the
6405    /// [`SubstrateType::ALL`] × ALL cross so a regression that
6406    /// hard-coded the arm to a single variant (silently returning
6407    /// `true` on every populated classification regardless of query
6408    /// kind) or wired the equality to a fixed unrelated field (a
6409    /// stray probe on `classification.point_type`) fails HERE at the
6410    /// substrate primitive before landing at the operator-facing
6411    /// checks.lisp surface.
6412    #[test]
6413    fn classification_has_substrate_returns_true_iff_variant_matches() {
6414        for populated in SubstrateType::ALL {
6415            let c = Classification::gate_compute_with_axis(populated);
6416            for query in SubstrateType::ALL {
6417                assert_eq!(
6418                    c.has_substrate(query),
6419                    query == populated,
6420                    "substrate={populated:?}: query {query:?} classification drifted",
6421                );
6422            }
6423        }
6424    }
6425
6426    /// GATE-COMPUTE BASELINE — the workspace-baseline
6427    /// [`Classification::gate_compute`] shape carries
6428    /// `substrate: Compute`, so `has_substrate` returns `true` on
6429    /// [`SubstrateType::Compute`] and `false` on every other of the
6430    /// eight variants. Pins the composition of the substrate's
6431    /// baseline-constructor primitive with the fourth scalar-carrier
6432    /// presence probe — a regression that flipped
6433    /// `gate_compute().substrate` off `Compute` (or wired
6434    /// `has_substrate` to a fixed variant answer, or crossed the
6435    /// wires to `point_type`) fails here at ONE narrow site before
6436    /// drifting across every unadorned ephemeral env
6437    /// (`default_ephemeral_class`) and every downstream test fixture
6438    /// that keys assertions on the shape. Byte-symmetric with the
6439    /// peer `classification_gate_compute_has_point_type_gate_only`
6440    /// pin on the third scalar-carrier — the two co-tenants on the
6441    /// (required-parent × required-scalar-child) corner walk their
6442    /// own required axis independently.
6443    #[test]
6444    fn classification_gate_compute_has_substrate_compute_only() {
6445        let c = Classification::gate_compute();
6446        for kind in SubstrateType::ALL {
6447            let expected = kind == SubstrateType::Compute;
6448            assert_eq!(
6449                c.has_substrate(kind),
6450                expected,
6451                "gate_compute (substrate=Compute) must return {expected} for {kind:?}",
6452            );
6453        }
6454    }
6455
6456    /// TWO-AXIS INDEPENDENCE — the two co-tenants on the (required-
6457    /// parent × required-scalar-child) corner of the presence-probe
6458    /// algebra ([`Classification::has_point_type`] and
6459    /// [`Classification::has_substrate`]) probe distinct required
6460    /// scalar slots on the SAME [`Classification`] parent, so a
6461    /// carrier with `point_type: Fork` AND `substrate: Storage`
6462    /// answers `true` on both fine tags simultaneously and `false`
6463    /// on every off-diagonal probe of either axis. Pins the two
6464    /// probes' independence at ONE narrow site — a regression that
6465    /// collapsed either onto the other's field (a stray probe of
6466    /// `has_substrate` reading `self.point_type`, or of
6467    /// `has_point_type` reading `self.substrate`) would fail HERE
6468    /// before landing at any consumer. The audit `every Fork-topology
6469    /// Storage-plane point handles SIGHUP by Restart` composes this
6470    /// exact two-axis conjunction on the required scalars of the
6471    /// six-axis classification lattice.
6472    #[test]
6473    fn classification_has_point_type_and_has_substrate_are_independent() {
6474        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
6475            .with_axis(SubstrateType::Storage);
6476        assert!(c.has_point_type(ConvergencePointType::Fork));
6477        assert!(c.has_substrate(SubstrateType::Storage));
6478        assert!(!c.has_point_type(ConvergencePointType::Gate));
6479        assert!(!c.has_substrate(SubstrateType::Compute));
6480        // Cross-wiring probe: `has_point_type(Storage-as-if-Point)` and
6481        // `has_substrate(Fork-as-if-Substrate)` cannot even typecheck
6482        // — the closed-set enums are disjoint types — but a stray
6483        // implementation reading the WRONG required field would flip
6484        // both diagonal answers off. The four asserts above pin the
6485        // independence at ONE narrow site.
6486    }
6487
6488    // ── scalar-carrier presence probe on Classification × CalmClassification ──
6489    //
6490    // Fail-before-pass-after granularity: [`Classification::has_calm`]
6491    // did not exist before this commit — every consumer of the
6492    // `(Classification, CalmClassification) -> bool` scalar-carrier
6493    // probe shape restated the `classification.calm == kind` equality
6494    // body at its own callsite. Post-lift the shape lives at ONE
6495    // substrate owner and every downstream (the `calm-<kind>`
6496    // require-tag family in `tatara-check`, future audit dispatchers
6497    // walking [`CalmClassification::ALL`], any future CRD-facing
6498    // closed-set discriminator on a defaulted scalar `ProcessSpec`
6499    // field such as `has_data_classification`) binds through the SAME
6500    // `has(kind)` shape the Option-slot (`Intent::has`, `Lifetime::has`),
6501    // slice-level (`ConditionSliceExt::has_kind`,
6502    // `DependsOnSliceExt::has_must_reach`,
6503    // `ComplianceBindingSliceExt::has_verification_phase`,
6504    // `ExportSpecSliceExt::has_{when,channel_kind,report_format,artifact_kind}`),
6505    // and prior scalar-carrier
6506    // (`SignalPolicy::has_sighup_strategy`,
6507    // `EncapsulatesSpec::has_mode`, `Classification::has_point_type`,
6508    // `Classification::has_substrate`) peers publish. FIRST occupant
6509    // on the (required-parent × defaulted-scalar-child) corner of the
6510    // presence-probe algebra — a fresh corner distinct from all four
6511    // prior scalar-carrier peers.
6512
6513    /// DIAGONAL — for every [`CalmClassification`] variant, a
6514    /// [`Classification`] whose `calm` field is set to that variant
6515    /// returns `true` from `has_calm` on that same variant AND
6516    /// `false` on every other variant. Sweep the
6517    /// [`CalmClassification::ALL`] × ALL cross so a regression that
6518    /// hard-coded the arm to a single variant (silently returning
6519    /// `true` on every populated classification regardless of query
6520    /// kind) or wired the equality to a fixed unrelated field (a
6521    /// stray probe on `classification.point_type` or
6522    /// `classification.substrate`) fails HERE at the substrate
6523    /// primitive before landing at the operator-facing checks.lisp
6524    /// surface.
6525    #[test]
6526    fn classification_has_calm_returns_true_iff_variant_matches() {
6527        for populated in CalmClassification::ALL {
6528            let c = Classification::gate_compute_with_axis(populated);
6529            for query in CalmClassification::ALL {
6530                assert_eq!(
6531                    c.has_calm(query),
6532                    query == populated,
6533                    "calm={populated:?}: query {query:?} classification drifted",
6534                );
6535            }
6536        }
6537    }
6538
6539    /// GATE-COMPUTE BASELINE — the workspace-baseline
6540    /// [`Classification::gate_compute`] shape carries
6541    /// `calm: CalmClassification::default()` which is
6542    /// [`CalmClassification::Monotone`] via `#[default]`, so
6543    /// `has_calm` returns `true` on [`CalmClassification::Monotone`]
6544    /// and `false` on [`CalmClassification::NonMonotone`]. Pins the
6545    /// composition of the substrate's baseline-constructor primitive
6546    /// with the FIFTH scalar-carrier presence probe AND the sibling-
6547    /// default correspondence documented on [`Classification::gate_compute`]
6548    /// (which pins the three defaulted axes to the sibling closed-set
6549    /// defaults `HorizonKind::Bounded` / `CalmClassification::Monotone`
6550    /// / `DataClassification::Internal`) — a regression that flipped
6551    /// `gate_compute().calm` off `Monotone` (or promoted a different
6552    /// variant to `#[default]` on the closed set, or wired `has_calm`
6553    /// to a fixed variant answer, or crossed the wires to
6554    /// `point_type` / `substrate`) fails here at ONE narrow site
6555    /// before drifting across every unadorned ephemeral env
6556    /// (`default_ephemeral_class`) and every downstream test fixture
6557    /// that keys assertions on the shape. FIRST occupant on the
6558    /// (required-parent × defaulted-scalar-child) corner — locks the
6559    /// corner's characteristic "default-arm short-circuit" property
6560    /// at ONE narrow classifier site: a bare classification answers
6561    /// `true` on the default variant (distinct from the
6562    /// required-child corner peers, where a bare classification must
6563    /// name a variant deliberately to answer `true`).
6564    #[test]
6565    fn classification_gate_compute_has_calm_monotone_only() {
6566        let c = Classification::gate_compute();
6567        for kind in CalmClassification::ALL {
6568            let expected = kind == CalmClassification::Monotone;
6569            assert_eq!(
6570                c.has_calm(kind),
6571                expected,
6572                "gate_compute (calm=Monotone) must return {expected} for {kind:?}",
6573            );
6574        }
6575    }
6576
6577    /// THREE-AXIS INDEPENDENCE — the three co-tenants on the
6578    /// [`Classification`] parent
6579    /// ([`Classification::has_point_type`] +
6580    /// [`Classification::has_substrate`] on the (required-parent ×
6581    /// required-scalar-child) corner AND [`Classification::has_calm`]
6582    /// on the fresh (required-parent × defaulted-scalar-child)
6583    /// corner) probe distinct scalar slots on the SAME parent, so a
6584    /// carrier with `point_type: Fork` AND `substrate: Storage` AND
6585    /// `calm: NonMonotone` answers `true` on all three fine tags
6586    /// simultaneously and `false` on every off-diagonal probe of any
6587    /// axis. Pins the three probes' independence at ONE narrow site
6588    /// — a regression that collapsed any of the three onto another's
6589    /// field (a stray probe of `has_calm` reading `self.point_type`
6590    /// or `self.substrate`, or of either required-axis probe reading
6591    /// `self.calm`) would fail HERE before landing at any consumer.
6592    /// The audit `every Fork-topology Storage-plane NonMonotone-CALM
6593    /// point declares a Raft-guarded write path` composes this exact
6594    /// three-axis conjunction on the required + defaulted scalars of
6595    /// the six-axis classification lattice.
6596    #[test]
6597    fn classification_has_point_type_and_has_substrate_and_has_calm_are_independent() {
6598        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
6599            .with_axis(SubstrateType::Storage)
6600            .with_axis(CalmClassification::NonMonotone);
6601        assert!(c.has_point_type(ConvergencePointType::Fork));
6602        assert!(c.has_substrate(SubstrateType::Storage));
6603        assert!(c.has_calm(CalmClassification::NonMonotone));
6604        assert!(!c.has_point_type(ConvergencePointType::Gate));
6605        assert!(!c.has_substrate(SubstrateType::Compute));
6606        assert!(!c.has_calm(CalmClassification::Monotone));
6607    }
6608
6609    // ── scalar-carrier presence probe on Classification × DataClassification ──
6610    //
6611    // Fail-before-pass-after granularity:
6612    // [`Classification::has_data_classification`] did not exist before
6613    // this commit — every consumer of the
6614    // `(Classification, DataClassification) -> bool` scalar-carrier
6615    // probe shape would have to restate the
6616    // `classification.data_classification == kind` equality body at
6617    // its own callsite. Post-lift the shape lives at ONE substrate
6618    // owner and every downstream (the `data-classification-<kind>`
6619    // require-tag family in `tatara-check`, future audit dispatchers
6620    // walking [`DataClassification::ALL`], any future CRD-facing
6621    // closed-set discriminator on a defaulted scalar `ProcessSpec`
6622    // field) binds through the SAME `has(kind)` shape the four prior
6623    // scalar-carrier peers on [`Classification`]
6624    // ([`Classification::has_point_type`],
6625    // [`Classification::has_substrate`],
6626    // [`Classification::has_calm`]) plus
6627    // [`crate::spec::SignalPolicy::has_sighup_strategy`] and
6628    // [`crate::encapsulates::EncapsulatesSpec::has_mode`] publish.
6629    // SECOND occupant on the (required-parent × defaulted-scalar-
6630    // child) corner of the presence-probe algebra after
6631    // [`Classification::has_calm`] opened it — pins the corner as a
6632    // proven-repeatable primitive shape rather than a single-example
6633    // curiosity and closes the four-scalar-carrier corner-coverage
6634    // contract on the six-axis classification lattice.
6635
6636    /// DIAGONAL — for every [`DataClassification`] variant, a
6637    /// [`Classification`] whose `data_classification` field is set to
6638    /// that variant returns `true` from `has_data_classification` on
6639    /// that same variant AND `false` on every other variant. Sweep
6640    /// the [`DataClassification::ALL`] × ALL cross so a regression
6641    /// that hard-coded the arm to a single variant (silently returning
6642    /// `true` on every populated classification regardless of query
6643    /// kind) or wired the equality to a fixed unrelated field (a
6644    /// stray probe on `classification.point_type` /
6645    /// `classification.substrate` / `classification.calm`) fails HERE
6646    /// at the substrate primitive before landing at the operator-
6647    /// facing checks.lisp surface.
6648    #[test]
6649    fn classification_has_data_classification_returns_true_iff_variant_matches() {
6650        for populated in DataClassification::ALL {
6651            let c = Classification::gate_compute_with_axis(populated);
6652            for query in DataClassification::ALL {
6653                assert_eq!(
6654                    c.has_data_classification(query),
6655                    query == populated,
6656                    "data_classification={populated:?}: query {query:?} classification drifted",
6657                );
6658            }
6659        }
6660    }
6661
6662    /// GATE-COMPUTE BASELINE — the workspace-baseline
6663    /// [`Classification::gate_compute`] shape carries
6664    /// `data_classification: DataClassification::default()` which is
6665    /// [`DataClassification::Internal`] via `#[default]`, so
6666    /// `has_data_classification` returns `true` on
6667    /// [`DataClassification::Internal`] and `false` on every other
6668    /// variant ([`DataClassification::Public`],
6669    /// [`DataClassification::Confidential`],
6670    /// [`DataClassification::Pii`], [`DataClassification::Phi`],
6671    /// [`DataClassification::Pci`]). Pins the composition of the
6672    /// substrate's baseline-constructor primitive with the SIXTH
6673    /// scalar-carrier presence probe AND the sibling-default
6674    /// correspondence documented on [`Classification::gate_compute`]
6675    /// (which pins the three defaulted axes to the sibling closed-set
6676    /// defaults `HorizonKind::Bounded` / `CalmClassification::Monotone`
6677    /// / `DataClassification::Internal`) — a regression that flipped
6678    /// `gate_compute().data_classification` off `Internal` (or
6679    /// promoted a different variant to `#[default]` on the closed
6680    /// set, or wired `has_data_classification` to a fixed variant
6681    /// answer, or crossed the wires to `point_type` / `substrate` /
6682    /// `calm`) fails here at ONE narrow site before drifting across
6683    /// every unadorned ephemeral env (`default_ephemeral_class`) and
6684    /// every downstream test fixture that keys assertions on the
6685    /// shape. SECOND occupant on the (required-parent × defaulted-
6686    /// scalar-child) corner — pins the corner's characteristic
6687    /// "default-arm short-circuit" property on its second occupant
6688    /// (peer to `classification_gate_compute_has_calm_monotone_only`
6689    /// which pins the same shape on the corner's first occupant).
6690    #[test]
6691    fn classification_gate_compute_has_data_classification_internal_only() {
6692        let c = Classification::gate_compute();
6693        for kind in DataClassification::ALL {
6694            let expected = kind == DataClassification::Internal;
6695            assert_eq!(
6696                c.has_data_classification(kind),
6697                expected,
6698                "gate_compute (data_classification=Internal) must return {expected} for {kind:?}",
6699            );
6700        }
6701    }
6702
6703    /// FOUR-AXIS INDEPENDENCE — the four scalar-carrier co-tenants
6704    /// on the [`Classification`] parent
6705    /// ([`Classification::has_point_type`] plus
6706    /// [`Classification::has_substrate`] on the (required-parent ×
6707    /// required-scalar-child) corner AND [`Classification::has_calm`]
6708    /// plus [`Classification::has_data_classification`] on the
6709    /// (required-parent × defaulted-scalar-child) corner) probe
6710    /// distinct scalar slots on the SAME parent, so a carrier with
6711    /// `point_type: Fork` AND `substrate: Storage` AND
6712    /// `calm: NonMonotone` AND `data_classification: Pii` answers
6713    /// `true` on all four fine tags simultaneously and `false` on
6714    /// every off-diagonal probe of any axis. Pins the four probes'
6715    /// independence at ONE narrow site — a regression that collapsed
6716    /// any of the four onto another's field (a stray probe of
6717    /// `has_data_classification` reading `self.point_type` /
6718    /// `self.substrate` / `self.calm`, or of any prior probe reading
6719    /// `self.data_classification`) would fail HERE before landing at
6720    /// any consumer. The audit `every Fork-topology Storage-plane
6721    /// NonMonotone-CALM Pii-classification point declares a
6722    /// Raft-guarded write path AND a downstream PII-scrub sink`
6723    /// composes this exact four-axis conjunction on the required +
6724    /// defaulted scalars of the six-axis classification lattice.
6725    /// Closes the four-scalar-carrier corner-coverage contract on
6726    /// [`Classification`] — its two required-scalar-child slots
6727    /// (`point_type`, `substrate`) AND its two defaulted-scalar-
6728    /// child slots (`calm`, `data_classification`) all publish
6729    /// independent presence probes through the same shape.
6730    #[test]
6731    fn classification_four_scalar_carrier_probes_are_independent() {
6732        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
6733            .with_axis(SubstrateType::Storage)
6734            .with_axis(CalmClassification::NonMonotone)
6735            .with_axis(DataClassification::Pii);
6736        assert!(c.has_point_type(ConvergencePointType::Fork));
6737        assert!(c.has_substrate(SubstrateType::Storage));
6738        assert!(c.has_calm(CalmClassification::NonMonotone));
6739        assert!(c.has_data_classification(DataClassification::Pii));
6740        assert!(!c.has_point_type(ConvergencePointType::Gate));
6741        assert!(!c.has_substrate(SubstrateType::Compute));
6742        assert!(!c.has_calm(CalmClassification::Monotone));
6743        assert!(!c.has_data_classification(DataClassification::Internal));
6744        assert!(!c.has_data_classification(DataClassification::Public));
6745        assert!(!c.has_data_classification(DataClassification::Phi));
6746    }
6747
6748    // ── nested-struct-scalar-carrier presence probe on Classification × HorizonKind ──
6749    //
6750    // Fail-before-pass-after granularity:
6751    // [`Classification::has_horizon_kind`] did not exist before this
6752    // commit — every consumer of the `(Classification, HorizonKind) ->
6753    // bool` two-hop `self.horizon.kind == kind` probe shape would have
6754    // to restate the nested-struct field walk at its own callsite.
6755    // Post-lift the shape lives at ONE substrate owner and every
6756    // downstream (the `horizon-<kind>` require-tag family in
6757    // `tatara-check`, future audit dispatchers walking
6758    // [`HorizonKind::ALL`], any future CRD-facing nested-struct-scalar
6759    // discriminator on `ProcessSpec`) binds through the SAME
6760    // `has(kind)` shape the four prior scalar-carrier peers on
6761    // [`Classification`] ([`Classification::has_point_type`],
6762    // [`Classification::has_substrate`], [`Classification::has_calm`],
6763    // [`Classification::has_data_classification`]) plus
6764    // [`crate::spec::SignalPolicy::has_sighup_strategy`] and
6765    // [`crate::encapsulates::EncapsulatesSpec::has_mode`] publish.
6766    // FIRST occupant on the (required-parent × nested-struct-scalar-
6767    // child) corner of the presence-probe algebra — a fresh corner
6768    // distinct from the four corner-property-exhaustive scalar-carrier
6769    // peers on [`Classification`] (whose bodies read a closed-set
6770    // discriminator directly off a scalar slot without an intermediate
6771    // struct hop).
6772
6773    /// DIAGONAL — for every [`HorizonKind`] variant, a
6774    /// [`Classification`] whose `horizon.kind` field is set to that
6775    /// variant returns `true` from `has_horizon_kind` on that same
6776    /// variant AND `false` on every other variant. Sweep the
6777    /// [`HorizonKind::ALL`] × ALL cross so a regression that
6778    /// hard-coded the arm to a single variant (silently returning
6779    /// `true` on every populated classification regardless of query
6780    /// kind) or wired the equality to a fixed unrelated field (a
6781    /// stray probe on `classification.point_type` /
6782    /// `classification.substrate` / `classification.calm` /
6783    /// `classification.data_classification`, or a direct probe on the
6784    /// nested [`Horizon`] struct that ignored the discriminator arm)
6785    /// fails HERE at the substrate primitive before landing at the
6786    /// operator-facing checks.lisp surface. The nested-struct hop
6787    /// distinguishes this corner from the four scalar-carrier peers:
6788    /// the probe walks `self.horizon.kind` not `self.<field>`, so a
6789    /// regression that mis-routed the field walk (a stray
6790    /// `self.horizon == kind` that could not typecheck, or a stray
6791    /// `self.horizon.direction == kind` that would trip a different
6792    /// closed-set discriminator) fails at the compiler before the
6793    /// runtime diagonal even runs.
6794    #[test]
6795    fn classification_has_horizon_kind_returns_true_iff_variant_matches() {
6796        for populated in HorizonKind::ALL {
6797            let c = Classification::gate_compute_with_axis(populated);
6798            for query in HorizonKind::ALL {
6799                assert_eq!(
6800                    c.has_horizon_kind(query),
6801                    query == populated,
6802                    "horizon.kind={populated:?}: query {query:?} classification drifted",
6803                );
6804            }
6805        }
6806    }
6807
6808    /// GATE-COMPUTE BASELINE — the workspace-baseline
6809    /// [`Classification::gate_compute`] shape carries
6810    /// `horizon: Horizon::default()` whose `kind` field defaults to
6811    /// [`HorizonKind::Bounded`] via `#[default]`, so `has_horizon_kind`
6812    /// returns `true` on [`HorizonKind::Bounded`] and `false` on
6813    /// [`HorizonKind::Asymptotic`]. Pins the composition of the
6814    /// substrate's baseline-constructor primitive with the SEVENTH
6815    /// presence-probe peer AND the sibling-default correspondence
6816    /// documented on [`Classification::gate_compute`] (which pins the
6817    /// three defaulted axes to the sibling closed-set defaults
6818    /// `HorizonKind::Bounded` / `CalmClassification::Monotone` /
6819    /// `DataClassification::Internal`) — a regression that flipped
6820    /// `Horizon::default().kind` off `Bounded` (or promoted
6821    /// `Asymptotic` to `#[default]` on [`HorizonKind`], or wired
6822    /// `has_horizon_kind` to a fixed variant answer, or crossed the
6823    /// wires through the wrong nested struct) fails here at ONE
6824    /// narrow site before drifting across every unadorned ephemeral
6825    /// env (`default_ephemeral_class`) and every downstream test
6826    /// fixture that keys assertions on the shape. FIRST occupant on
6827    /// the (required-parent × nested-struct-scalar-child) corner —
6828    /// locks the corner's characteristic "default-arm short-circuit
6829    /// reaches through the nested struct's own default" property at
6830    /// ONE narrow site.
6831    #[test]
6832    fn classification_gate_compute_has_horizon_kind_bounded_only() {
6833        let c = Classification::gate_compute();
6834        for kind in HorizonKind::ALL {
6835            let expected = kind == HorizonKind::Bounded;
6836            assert_eq!(
6837                c.has_horizon_kind(kind),
6838                expected,
6839                "gate_compute (horizon.kind=Bounded) must return {expected} for {kind:?}",
6840            );
6841        }
6842    }
6843
6844    /// FIVE-AXIS INDEPENDENCE — the FIVE presence-probe co-tenants on
6845    /// the [`Classification`] parent
6846    /// ([`Classification::has_point_type`] plus
6847    /// [`Classification::has_substrate`] on the (required-parent ×
6848    /// required-scalar-child) corner AND
6849    /// [`Classification::has_calm`] plus
6850    /// [`Classification::has_data_classification`] on the (required-
6851    /// parent × defaulted-scalar-child) corner AND
6852    /// [`Classification::has_horizon_kind`] on the fresh (required-
6853    /// parent × nested-struct-scalar-child) corner) probe distinct
6854    /// slots on the SAME parent, so a carrier with `point_type: Fork`
6855    /// AND `substrate: Storage` AND `calm: NonMonotone` AND
6856    /// `data_classification: Pii` AND `horizon.kind: Asymptotic`
6857    /// answers `true` on all five fine tags simultaneously and
6858    /// `false` on every off-diagonal probe of any axis. Pins the five
6859    /// probes' independence at ONE narrow site — a regression that
6860    /// collapsed any of the five onto another's field (a stray probe
6861    /// of `has_horizon_kind` reading `self.point_type` /
6862    /// `self.substrate` / `self.calm` / `self.data_classification`,
6863    /// or of any prior probe reading through `self.horizon.kind`)
6864    /// would fail HERE before landing at any consumer. The audit
6865    /// `every Fork-topology Storage-plane NonMonotone-CALM
6866    /// Pii-classification Asymptotic-horizon point declares a
6867    /// Raft-guarded write path AND a downstream PII-scrub sink AND a
6868    /// rate-window healthy-threshold metric` composes this exact
6869    /// five-axis conjunction on the five classification-axis
6870    /// discriminators of the six-axis classification lattice — opens
6871    /// the five-way corner-coverage contract on [`Classification`],
6872    /// straddling THREE distinct corners of the (parent-shape ×
6873    /// child-shape) algebra (the required-child corner
6874    /// `has_point_type` + `has_substrate` share, the defaulted-child
6875    /// corner `has_calm` + `has_data_classification` share, and the
6876    /// nested-struct-child corner `has_horizon_kind` opens).
6877    #[test]
6878    fn classification_five_presence_probes_are_independent() {
6879        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
6880            .with_axis(SubstrateType::Storage)
6881            .with_axis(CalmClassification::NonMonotone)
6882            .with_axis(DataClassification::Pii)
6883            .with_axis(HorizonKind::Asymptotic);
6884        assert!(c.has_point_type(ConvergencePointType::Fork));
6885        assert!(c.has_substrate(SubstrateType::Storage));
6886        assert!(c.has_calm(CalmClassification::NonMonotone));
6887        assert!(c.has_data_classification(DataClassification::Pii));
6888        assert!(c.has_horizon_kind(HorizonKind::Asymptotic));
6889        assert!(!c.has_point_type(ConvergencePointType::Gate));
6890        assert!(!c.has_substrate(SubstrateType::Compute));
6891        assert!(!c.has_calm(CalmClassification::Monotone));
6892        assert!(!c.has_data_classification(DataClassification::Internal));
6893        assert!(!c.has_horizon_kind(HorizonKind::Bounded));
6894    }
6895
6896    // ── nested-struct-Option-scalar-carrier presence probe on Classification × OptimizationDirection ──
6897    //
6898    // Fail-before-pass-after granularity:
6899    // [`Classification::has_optimization_direction`] did not exist
6900    // before this commit — every consumer of the
6901    // `(Classification, OptimizationDirection) -> bool` two-hop
6902    // `self.horizon.direction.unwrap_or_default() == kind` probe
6903    // shape would have to restate the nested-struct-Option field
6904    // walk at its own callsite. Post-lift the shape lives at ONE
6905    // substrate owner and every downstream (the
6906    // `optimization-direction-<kind>` require-tag family in
6907    // `tatara-check`, future audit dispatchers walking
6908    // [`OptimizationDirection::ALL`], any future CRD-facing nested-
6909    // struct-Option-scalar discriminator on `ProcessSpec`) binds
6910    // through the SAME `has(kind)` shape the six prior presence
6911    // probes on [`Classification`] plus its cousins on
6912    // [`crate::spec::SignalPolicy`] and
6913    // [`crate::encapsulates::EncapsulatesSpec`] publish. SECOND
6914    // occupant on the (required-parent × nested-struct-scalar-
6915    // child) corner of the presence-probe algebra — the FIRST
6916    // occupant [`Classification::has_horizon_kind`] read the nested
6917    // scalar `horizon.kind: HorizonKind` DIRECTLY; this probe adds
6918    // the `Option`-hop through `direction: Option<OptimizationDirection>`
6919    // via `Option::unwrap_or_default`, pinning the corner as a
6920    // proven-repeatable primitive shape rather than a single-example
6921    // curiosity.
6922
6923    /// DIAGONAL — for every [`OptimizationDirection`] variant, a
6924    /// [`Classification`] whose `horizon.direction` field is set to
6925    /// `Some(that variant)` returns `true` from
6926    /// `has_optimization_direction` on that same variant AND
6927    /// `false` on every other variant. Sweep the
6928    /// [`OptimizationDirection::ALL`] × ALL cross so a regression
6929    /// that hard-coded the arm to a single variant (silently
6930    /// returning `true` on every populated classification regardless
6931    /// of query kind) or wired the equality to a fixed unrelated
6932    /// field (a stray probe on `classification.point_type` /
6933    /// `classification.substrate` / `classification.calm` /
6934    /// `classification.data_classification` /
6935    /// `classification.horizon.kind`, or a direct probe on the
6936    /// nested [`Horizon`] struct that ignored the `direction` arm)
6937    /// fails HERE at the substrate primitive before landing at the
6938    /// operator-facing checks.lisp surface. The `Option`-hop
6939    /// distinguishes this method from the direct-nested-scalar
6940    /// peer [`Classification::has_horizon_kind`]: the probe walks
6941    /// `self.horizon.direction.unwrap_or_default()` not
6942    /// `self.horizon.kind`, so a regression that mis-routed the
6943    /// field walk (a stray `self.horizon.kind == kind` that could
6944    /// not typecheck, or a stray `self.horizon == kind` that also
6945    /// could not typecheck) fails at the compiler before the
6946    /// runtime diagonal even runs.
6947    #[test]
6948    fn classification_has_optimization_direction_returns_true_iff_variant_matches() {
6949        for populated in OptimizationDirection::ALL {
6950            let c = Classification::gate_compute_with_axis(HorizonKind::Asymptotic)
6951                .with_axis(populated);
6952            for query in OptimizationDirection::ALL {
6953                assert_eq!(
6954                    c.has_optimization_direction(query),
6955                    query == populated,
6956                    "horizon.direction=Some({populated:?}): query {query:?} classification drifted",
6957                );
6958            }
6959        }
6960    }
6961
6962    /// GATE-COMPUTE BASELINE — the workspace-baseline
6963    /// [`Classification::gate_compute`] shape carries
6964    /// `horizon: Horizon::default()` whose `direction` field defaults
6965    /// to `None`. Under [`Option::unwrap_or_default`] the probe
6966    /// answers as if the field were `OptimizationDirection::default()`
6967    /// = [`OptimizationDirection::Minimize`] via `#[default]`, so
6968    /// `has_optimization_direction` returns `true` on
6969    /// [`OptimizationDirection::Minimize`] and `false` on
6970    /// [`OptimizationDirection::Maximize`]. Pins the composition of
6971    /// the substrate's baseline-constructor primitive with the
6972    /// EIGHTH presence-probe peer AND the closed-set-default
6973    /// correspondence documented on [`OptimizationDirection`] —
6974    /// a regression that flipped `OptimizationDirection::default()`
6975    /// off `Minimize` (which would silently invert every unadorned
6976    /// `Asymptotic` Process's rate-window evaluator polarity), or
6977    /// wired `has_optimization_direction` to a fixed variant answer,
6978    /// or crossed the wires through the wrong nested struct or the
6979    /// wrong Option-slot, fails here at ONE narrow site before
6980    /// drifting across every unadorned ephemeral env
6981    /// (`default_ephemeral_class`) and every downstream test fixture
6982    /// that keys assertions on the shape. SECOND occupant on the
6983    /// (required-parent × nested-struct-scalar-child) corner —
6984    /// locks the corner's Option-hop default-arm short-circuit
6985    /// property at ONE narrow site (the Option `None` folds onto
6986    /// the closed set's `#[default]` via `unwrap_or_default`,
6987    /// mirroring the direct-nested-scalar's default-arm short-
6988    /// circuit through the nested struct's own default).
6989    #[test]
6990    fn classification_gate_compute_has_optimization_direction_minimize_only() {
6991        let c = Classification::gate_compute();
6992        for kind in OptimizationDirection::ALL {
6993            let expected = kind == OptimizationDirection::Minimize;
6994            assert_eq!(
6995                c.has_optimization_direction(kind),
6996                expected,
6997                "gate_compute (horizon.direction=None ⇒ default Minimize) must return {expected} for {kind:?}",
6998            );
6999        }
7000    }
7001
7002    /// SIX-AXIS INDEPENDENCE — the SIX presence-probe co-tenants on
7003    /// the [`Classification`] parent
7004    /// ([`Classification::has_point_type`] plus
7005    /// [`Classification::has_substrate`] on the (required-parent ×
7006    /// required-scalar-child) corner AND
7007    /// [`Classification::has_calm`] plus
7008    /// [`Classification::has_data_classification`] on the (required-
7009    /// parent × defaulted-scalar-child) corner AND
7010    /// [`Classification::has_horizon_kind`] plus
7011    /// [`Classification::has_optimization_direction`] on the
7012    /// (required-parent × nested-struct-scalar-child) corner) probe
7013    /// distinct slots on the SAME parent, so a carrier with
7014    /// `point_type: Fork` AND `substrate: Storage` AND
7015    /// `calm: NonMonotone` AND `data_classification: Pii` AND
7016    /// `horizon.kind: Asymptotic` AND
7017    /// `horizon.direction: Some(Maximize)` answers `true` on all six
7018    /// fine tags simultaneously and `false` on every off-diagonal
7019    /// probe of any axis. Pins the six probes' independence at ONE
7020    /// narrow site — a regression that collapsed any of the six
7021    /// onto another's field (a stray probe of
7022    /// `has_optimization_direction` reading `self.point_type` /
7023    /// `self.substrate` / `self.calm` /
7024    /// `self.data_classification` / `self.horizon.kind`, or of any
7025    /// prior probe reading through `self.horizon.direction`) would
7026    /// fail HERE before landing at any consumer. The audit
7027    /// `every Fork-topology Storage-plane NonMonotone-CALM
7028    /// Pii-classification Asymptotic-horizon Maximize-direction
7029    /// point declares a rate-window healthy-threshold metric and a
7030    /// throughput-oriented SLO` composes this exact six-axis
7031    /// conjunction on the six classification-axis discriminators of
7032    /// the six-axis classification lattice — populates the six-way
7033    /// corner-coverage contract on [`Classification`], now
7034    /// straddling THREE distinct corners of the (parent-shape ×
7035    /// child-shape) algebra with TWO co-tenants each on the
7036    /// nested-struct-child corner: direct-nested-scalar
7037    /// (`has_horizon_kind`) and Option-nested-scalar
7038    /// (`has_optimization_direction`).
7039    #[test]
7040    fn classification_six_presence_probes_are_independent() {
7041        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork)
7042            .with_axis(SubstrateType::Storage)
7043            .with_axis(CalmClassification::NonMonotone)
7044            .with_axis(DataClassification::Pii)
7045            .with_axis(HorizonKind::Asymptotic)
7046            .with_axis(OptimizationDirection::Maximize);
7047        assert!(c.has_point_type(ConvergencePointType::Fork));
7048        assert!(c.has_substrate(SubstrateType::Storage));
7049        assert!(c.has_calm(CalmClassification::NonMonotone));
7050        assert!(c.has_data_classification(DataClassification::Pii));
7051        assert!(c.has_horizon_kind(HorizonKind::Asymptotic));
7052        assert!(c.has_optimization_direction(OptimizationDirection::Maximize));
7053        assert!(!c.has_point_type(ConvergencePointType::Gate));
7054        assert!(!c.has_substrate(SubstrateType::Compute));
7055        assert!(!c.has_calm(CalmClassification::Monotone));
7056        assert!(!c.has_data_classification(DataClassification::Internal));
7057        assert!(!c.has_horizon_kind(HorizonKind::Bounded));
7058        assert!(!c.has_optimization_direction(OptimizationDirection::Minimize));
7059    }
7060
7061    // ── derived-typed-projection presence probe on Classification × Arity ──
7062    //
7063    // Fail-before-pass-after granularity:
7064    // [`Classification::has_input_arity`] did not exist before this
7065    // commit — every consumer of the `(Classification, Arity) -> bool`
7066    // two-hop `self.point_type.input_arity() == kind` probe shape
7067    // would have to restate the derived-typed-projection walk at its
7068    // own callsite. Post-lift the shape lives at ONE substrate owner
7069    // and every downstream (the `input-arity-<kind>` require-tag
7070    // family in `tatara-check`, future DAG-composition validators
7071    // walking [`Arity::ALL`], any future consumer keying on the
7072    // input-edge cardinality of a Process's convergence point) binds
7073    // through the SAME `has(kind)` shape the two prior nested-struct-
7074    // scalar-child peers on [`Classification`]
7075    // ([`Classification::has_horizon_kind`] and
7076    // [`Classification::has_optimization_direction`]) publish. FIRST
7077    // occupant of the DERIVED-TYPED-PROJECTION variant on the
7078    // (required-parent × nested-struct-scalar-child) corner — widening
7079    // the corner from "raw discriminator only" to "raw discriminator
7080    // OR typed projection over the child", mirroring the derived-typed-
7081    // projection precedent
7082    // [`crate::export::ExportSpecSliceExt::has_report_payload_shape`]
7083    // set on the (Option-parent × Vec-child × nested-Option-carrier ×
7084    // derived-typed-projection) corner.
7085
7086    /// PROJECTION-TRUTH-TABLE — for every [`ConvergencePointType`]
7087    /// variant, `has_input_arity` on a [`Classification`] whose
7088    /// `point_type` field is set to that variant returns `true` on
7089    /// EXACTLY the [`Arity`] variant that
7090    /// [`ConvergencePointType::input_arity`] projects to (and `false`
7091    /// on every other variant). Sweep the
7092    /// [`ConvergencePointType::ALL`] × [`Arity::ALL`] cross so a
7093    /// regression that (a) probed [`ConvergencePointType`] directly
7094    /// (dropping the `.input_arity()` call, silently answering `true`
7095    /// on the populated slot only when the query happens to name the
7096    /// same variant), (b) inverted the projection (`One ↔ Many`), (c)
7097    /// crossed the wires with the sibling
7098    /// [`ConvergencePointType::output_arity`] projection (which
7099    /// disagrees on the fan-out arms), (d) hard-coded the arm to a
7100    /// single [`Arity`] (silently returning `true` for every
7101    /// populated classification regardless of query kind), or (e)
7102    /// wired the equality to a fixed unrelated field fails HERE at
7103    /// the substrate primitive before landing at the operator-facing
7104    /// checks.lisp surface. The projection's many-to-one shape is
7105    /// pinned SYMMETRICALLY on both sides of the cross: `Transform`,
7106    /// `Fork`, `Broadcast`, `Observe` populated arms answer `true`
7107    /// only for `Arity::One`; `Join`, `Gate`, `Select`, `Reduce`
7108    /// populated arms answer `true` only for `Arity::Many`.
7109    #[test]
7110    fn classification_has_input_arity_returns_true_iff_projection_matches_per_kind() {
7111        for populated in ConvergencePointType::ALL {
7112            let c = Classification::gate_compute_with_axis(populated);
7113            let expected_arity = populated.input_arity();
7114            for query in Arity::ALL {
7115                assert_eq!(
7116                    c.has_input_arity(query),
7117                    query == expected_arity,
7118                    "point_type={populated:?} → input_arity={expected_arity:?}: query {query:?} classification drifted",
7119                );
7120            }
7121        }
7122    }
7123
7124    /// GATE-COMPUTE BASELINE — the workspace-baseline
7125    /// [`Classification::gate_compute`] shape carries
7126    /// `point_type: ConvergencePointType::Gate`, and
7127    /// [`ConvergencePointType::input_arity`] projects `Gate → Many`,
7128    /// so `has_input_arity` returns `true` on [`Arity::Many`] and
7129    /// `false` on [`Arity::One`]. Pins the composition of the
7130    /// substrate's baseline-constructor primitive with this
7131    /// presence-probe peer and the sibling-projection correspondence
7132    /// (which pins `Gate` to the fan-in `Many` bucket at ONE
7133    /// projection site) — a regression that flipped `Gate`'s
7134    /// `input_arity` bucket (silently mis-classifying every Gate as a
7135    /// `One`-input point at every downstream DAG-composition
7136    /// validator + this require-tag family), or that wired
7137    /// `has_input_arity` to a fixed arity answer, or that crossed the
7138    /// wires with `output_arity` (which sends `Gate → One`, the
7139    /// opposite bucket) fails here at ONE narrow site before drifting
7140    /// across every downstream fixture that keys assertions on the
7141    /// shape. FIRST derived-typed-projection occupant on the
7142    /// (required-parent × nested-struct-scalar-child) corner — locks
7143    /// the corner's characteristic "projection propagates through a
7144    /// bucket collapse consistently" property at ONE narrow site.
7145    #[test]
7146    fn classification_gate_compute_has_input_arity_many_only() {
7147        let c = Classification::gate_compute();
7148        for kind in Arity::ALL {
7149            let expected = kind == Arity::Many;
7150            assert_eq!(
7151                c.has_input_arity(kind),
7152                expected,
7153                "gate_compute (point_type=Gate → input_arity=Many) must return {expected} for {kind:?}",
7154            );
7155        }
7156    }
7157
7158    /// SIBLING-INDEPENDENCE — the peer scalar-carrier
7159    /// [`Classification::has_point_type`] and the peer derived-typed-
7160    /// projection [`Classification::has_input_arity`] read the SAME
7161    /// underlying slot (`self.point_type`) but through different
7162    /// closed sets ([`ConvergencePointType::ALL`] vs.
7163    /// [`Arity::ALL`]) — the arity probe is a many-to-one collapse of
7164    /// the point-type probe through
7165    /// [`ConvergencePointType::input_arity`]. A carrier with
7166    /// `point_type: Fork` MUST simultaneously answer
7167    /// `has_point_type(Fork) = true` AND
7168    /// `has_input_arity(One) = true` (Fork's input_arity projection),
7169    /// AND simultaneously answer
7170    /// `has_point_type(Broadcast) = false` (different variant, same
7171    /// bucket) AND `has_input_arity(Many) = false` (opposite bucket).
7172    /// Pins the projection-composition contract at ONE narrow site —
7173    /// a regression that (a) collapsed `has_input_arity` onto
7174    /// `has_point_type` (silently answering `true` only when the
7175    /// query names the raw point type, an out-of-vocabulary Arity
7176    /// query), (b) collapsed `has_point_type` onto `has_input_arity`
7177    /// (silently answering `true` for every point-type in the same
7178    /// arity bucket), or (c) swapped the projection direction fails
7179    /// HERE at the substrate before landing at any consumer. Peer of
7180    /// the [`crate::export::ExportSpecSliceExt`]'s
7181    /// SAME-CARRIER PROJECTION-COEXISTENCE pins on the
7182    /// `Option<TestReportSource>` nested-Option carrier
7183    /// (`has_report_format` vs. `has_report_payload_shape`) — the
7184    /// same "one carrier, two probes at different projection depths"
7185    /// contract pinned on the (required-parent × nested-struct-
7186    /// scalar-child) corner rather than on the (Option-parent ×
7187    /// Vec-child × nested-Option-carrier) corner.
7188    #[test]
7189    fn classification_has_input_arity_and_has_point_type_coexist_via_projection() {
7190        let c = Classification::gate_compute_with_axis(ConvergencePointType::Fork);
7191        assert!(c.has_point_type(ConvergencePointType::Fork));
7192        assert!(c.has_input_arity(Arity::One));
7193        assert!(!c.has_point_type(ConvergencePointType::Broadcast));
7194        assert!(!c.has_input_arity(Arity::Many));
7195    }
7196
7197    // ── second derived-typed-projection presence probe on Classification × Arity ──
7198    //
7199    // Fail-before-pass-after granularity:
7200    // [`Classification::has_output_arity`] did not exist before this
7201    // commit — every consumer of the `(Classification, Arity) -> bool`
7202    // two-hop `self.point_type.output_arity() == kind` probe shape
7203    // would have to restate the derived-typed-projection walk at its
7204    // own callsite. Post-lift the shape lives at ONE substrate owner
7205    // and every downstream (the `output-arity-<kind>` require-tag
7206    // family in `tatara-check`, future DAG-composition validators
7207    // walking [`Arity::ALL`] on the fan-out side, any future consumer
7208    // keying on the output-edge cardinality of a Process's convergence
7209    // point) binds through the SAME `has(kind)` shape the peer input-
7210    // side probe [`Classification::has_input_arity`] publishes. SECOND
7211    // occupant of the DERIVED-TYPED-PROJECTION variant on the
7212    // (required-parent × nested-struct-scalar-child) corner — closing
7213    // the DAG-composition arity pair by mirroring `has_input_arity`
7214    // through the sibling [`ConvergencePointType::output_arity`]
7215    // projection.
7216
7217    /// PROJECTION-TRUTH-TABLE — for every [`ConvergencePointType`]
7218    /// variant, `has_output_arity` on a [`Classification`] whose
7219    /// `point_type` field is set to that variant returns `true` on
7220    /// EXACTLY the [`Arity`] variant that
7221    /// [`ConvergencePointType::output_arity`] projects to (and `false`
7222    /// on every other variant). Sweep the
7223    /// [`ConvergencePointType::ALL`] × [`Arity::ALL`] cross so a
7224    /// regression that (a) probed [`ConvergencePointType`] directly
7225    /// (dropping the `.output_arity()` call, silently answering `true`
7226    /// on the populated slot only when the query happens to name the
7227    /// same variant), (b) inverted the projection (`One ↔ Many`), (c)
7228    /// crossed the wires with the sibling
7229    /// [`ConvergencePointType::input_arity`] projection (which
7230    /// disagrees on the diffusive `Fork | Broadcast → Many` output vs.
7231    /// `Fork | Broadcast → One` input, AND on the convergent `Join |
7232    /// Gate | Select | Reduce → One` output vs. `Many` input), (d)
7233    /// hard-coded the arm to a single [`Arity`] (silently returning
7234    /// `true` for every populated classification regardless of query
7235    /// kind), or (e) wired the equality to a fixed unrelated field
7236    /// fails HERE at the substrate primitive before landing at the
7237    /// operator-facing checks.lisp surface. The projection's many-to-
7238    /// one shape is pinned SYMMETRICALLY on both sides of the cross:
7239    /// `Fork`, `Broadcast` populated arms answer `true` only for
7240    /// `Arity::Many`; every other variant answers `true` only for
7241    /// `Arity::One`.
7242    #[test]
7243    fn classification_has_output_arity_returns_true_iff_projection_matches_per_kind() {
7244        for populated in ConvergencePointType::ALL {
7245            let c = Classification::gate_compute_with_axis(populated);
7246            let expected_arity = populated.output_arity();
7247            for query in Arity::ALL {
7248                assert_eq!(
7249                    c.has_output_arity(query),
7250                    query == expected_arity,
7251                    "point_type={populated:?} → output_arity={expected_arity:?}: query {query:?} classification drifted",
7252                );
7253            }
7254        }
7255    }
7256
7257    /// GATE-COMPUTE BASELINE — the workspace-baseline
7258    /// [`Classification::gate_compute`] shape carries
7259    /// `point_type: ConvergencePointType::Gate`, and
7260    /// [`ConvergencePointType::output_arity`] projects `Gate → One`,
7261    /// so `has_output_arity` returns `true` on [`Arity::One`] and
7262    /// `false` on [`Arity::Many`] — the MIRROR of the peer
7263    /// [`Self::has_input_arity`] baseline (`Gate → input_arity = Many`),
7264    /// which pins the convergent `(Many, One)` bucket at ONE
7265    /// projection pair site. Pins the composition of the substrate's
7266    /// baseline-constructor primitive with this presence-probe peer
7267    /// and the sibling-projection correspondence (which pins `Gate` to
7268    /// the fan-in `Many` input × fan-out `One` output cell) — a
7269    /// regression that flipped `Gate`'s `output_arity` bucket
7270    /// (silently mis-classifying every Gate as a `Many`-output point
7271    /// at every downstream DAG-composition validator + this
7272    /// require-tag family), or that wired `has_output_arity` to a
7273    /// fixed arity answer, or that crossed the wires with
7274    /// `input_arity` (which sends `Gate → Many`, the opposite bucket)
7275    /// fails here at ONE narrow site before drifting across every
7276    /// downstream fixture that keys assertions on the shape.
7277    #[test]
7278    fn classification_gate_compute_has_output_arity_one_only() {
7279        let c = Classification::gate_compute();
7280        for kind in Arity::ALL {
7281            let expected = kind == Arity::One;
7282            assert_eq!(
7283                c.has_output_arity(kind),
7284                expected,
7285                "gate_compute (point_type=Gate → output_arity=One) must return {expected} for {kind:?}",
7286            );
7287        }
7288    }
7289
7290    /// CROSS-PROJECTION COEXISTENCE — the peer input-side probe
7291    /// [`Classification::has_input_arity`] and the output-side probe
7292    /// [`Classification::has_output_arity`] read the SAME underlying
7293    /// slot (`self.point_type`) through the SAME closed set
7294    /// ([`Arity::ALL`]) but through DIFFERENT typed projections
7295    /// ([`ConvergencePointType::input_arity`] vs.
7296    /// [`ConvergencePointType::output_arity`]). A carrier with
7297    /// `point_type: Fork` (the diffusive `(One, Many)` cell) MUST
7298    /// simultaneously answer `has_input_arity(One) = true` AND
7299    /// `has_output_arity(Many) = true` (Fork's arity pair), AND
7300    /// simultaneously answer `has_input_arity(Many) = false` AND
7301    /// `has_output_arity(One) = false` (opposite buckets). A carrier
7302    /// with `point_type: Transform` (the endomorphic `(One, One)`
7303    /// cell) MUST answer both probes with `Arity::One = true` — the
7304    /// two projections AGREE in the endomorphic bucket. A carrier with
7305    /// `point_type: Gate` (the convergent `(Many, One)` cell) MUST
7306    /// answer `has_input_arity(Many) = true` AND
7307    /// `has_output_arity(One) = true` — the mirror of the Fork case.
7308    /// Pins the projection-composition contract at ONE narrow site —
7309    /// a regression that (a) collapsed `has_output_arity` onto
7310    /// `has_input_arity` (silently answering the input arity for
7311    /// every output query on Fork/Broadcast/Join/Gate/Select/Reduce,
7312    /// the six variants where the two projections disagree), (b)
7313    /// swapped the projection direction (`Fork → (Many, One)` instead
7314    /// of `(One, Many)`), or (c) drifted the topology-bucket contract
7315    /// (silently mis-classifying Fork as endomorphic) fails HERE at
7316    /// the substrate before landing at any consumer. THIS is the DAG-
7317    /// composition arity pair pinned at ONE narrow site — the exact
7318    /// property `convergence_point_type_arity_pair_agrees_with_bucket`
7319    /// pins on the source projection functions themselves.
7320    #[test]
7321    fn classification_has_input_arity_and_has_output_arity_pin_dag_composition_pair() {
7322        let fork = Classification::gate_compute_with_axis(ConvergencePointType::Fork);
7323        assert!(fork.has_input_arity(Arity::One));
7324        assert!(fork.has_output_arity(Arity::Many));
7325        assert!(!fork.has_input_arity(Arity::Many));
7326        assert!(!fork.has_output_arity(Arity::One));
7327
7328        let transform = Classification::gate_compute_with_axis(ConvergencePointType::Transform);
7329        assert!(transform.has_input_arity(Arity::One));
7330        assert!(transform.has_output_arity(Arity::One));
7331        assert!(!transform.has_input_arity(Arity::Many));
7332        assert!(!transform.has_output_arity(Arity::Many));
7333
7334        let gate = Classification::gate_compute();
7335        assert!(gate.has_input_arity(Arity::Many));
7336        assert!(gate.has_output_arity(Arity::One));
7337        assert!(!gate.has_input_arity(Arity::One));
7338        assert!(!gate.has_output_arity(Arity::Many));
7339    }
7340
7341    // ── Classification::horizon_terminates substrate pins ─────────────
7342    //
7343    // Fail-before-pass-after granularity: [`Classification::horizon_terminates`]
7344    // did not exist before this commit — the `(Classification) -> bool`
7345    // derived-nullary-boolean walk over the nested [`Horizon`] slot's
7346    // [`HorizonKind::terminates`] projection had no substrate owner.
7347    // Post-lift the shape lives at ONE substrate primitive and every
7348    // downstream (the `terminating-horizon` fixed tag in
7349    // `tatara-check`, the [`crate::ephemeral::EphemeralSpec::horizon_terminates`]
7350    // peer, future scheduler / termination-shape validators) composes
7351    // against the SAME `horizon_terminates()` shape rather than
7352    // restating the `classification.horizon.kind.terminates()` chain
7353    // at its own callsite.
7354
7355    /// PER-VARIANT pin — for every [`HorizonKind`] variant, a
7356    /// [`Classification`] whose `horizon.kind` field carries that
7357    /// variant returns `horizon_terminates()` matching the closed
7358    /// set's own [`HorizonKind::terminates`] truth table. Sweep
7359    /// [`HorizonKind::ALL`] so a regression that (a) hard-coded the
7360    /// method body to a fixed answer (silently returning `true`
7361    /// regardless of the stored variant, silently rejecting every
7362    /// Asymptotic Process's scheduler-facing termination check), (b)
7363    /// inverted the projection (silently promoting Asymptotic to
7364    /// "terminates"), or (c) crossed the wires with the antisymmetric
7365    /// partner [`HorizonKind::requires_metric_axes`] fails HERE at
7366    /// the substrate primitive before drifting through the
7367    /// `terminating-horizon` fixed tag or the peer ephemeral surface.
7368    #[test]
7369    fn classification_horizon_terminates_matches_horizon_kind_projection() {
7370        for populated in HorizonKind::ALL {
7371            let c = Classification::gate_compute_with_axis(populated);
7372            assert_eq!(
7373                c.horizon_terminates(),
7374                populated.terminates(),
7375                "horizon.kind={populated:?}: horizon_terminates() drift from HorizonKind::terminates()",
7376            );
7377        }
7378    }
7379
7380    /// GATE-COMPUTE BASELINE — the workspace-baseline
7381    /// [`Classification::gate_compute`] shape carries
7382    /// `horizon: Horizon::default()` whose `kind` field defaults to
7383    /// [`HorizonKind::Bounded`] via `#[default]`, and
7384    /// [`HorizonKind::Bounded::terminates`] projects `true`, so
7385    /// `horizon_terminates()` returns `true`. Pins the default-arm
7386    /// short-circuit through TWO layers of `Default` (`Horizon`'s +
7387    /// `HorizonKind`'s) at ONE narrow site — a regression that
7388    /// promoted [`HorizonKind::Asymptotic`] to `#[default]`, or that
7389    /// swapped `Horizon::default`'s stored `kind`, or that wired
7390    /// [`HorizonKind::Bounded`] to `terminates() = false` would fail
7391    /// HERE before drifting through every unadorned Process's
7392    /// scheduler-facing termination answer.
7393    #[test]
7394    fn classification_gate_compute_horizon_terminates_is_true() {
7395        let c = Classification::gate_compute();
7396        assert!(
7397            c.horizon_terminates(),
7398            "gate_compute (horizon.kind=Bounded → terminates=true) baseline",
7399        );
7400    }
7401
7402    /// ANTISYMMETRY pin — [`HorizonKind::terminates`] XOR
7403    /// [`HorizonKind::requires_metric_axes`] holds on every variant
7404    /// (pinned by `horizon_kind_terminate_xor_requires_metric_axes`
7405    /// on the closed set itself); this composition-level test walks
7406    /// the same XOR contract through THIS derived-nullary predicate
7407    /// to prove the composition is faithful — a
7408    /// [`Classification`] answering `horizon_terminates() = true`
7409    /// implies its horizon does NOT require metric axes and vice
7410    /// versa. Pins the composition-level XOR at ONE narrow site so
7411    /// a regression that crossed the wires (`horizon_terminates`
7412    /// silently composed [`HorizonKind::requires_metric_axes`]
7413    /// instead of [`HorizonKind::terminates`]) surfaces here rather
7414    /// than at every downstream consumer that trusts the shape.
7415    #[test]
7416    fn classification_horizon_terminates_xor_horizon_kind_requires_metric_axes() {
7417        for kind in HorizonKind::ALL {
7418            let c = Classification::gate_compute_with_axis(kind);
7419            assert!(
7420                c.horizon_terminates() ^ kind.requires_metric_axes(),
7421                "{kind:?}: horizon_terminates() XOR requires_metric_axes() must hold",
7422            );
7423        }
7424    }
7425
7426    // ── Classification::horizon_requires_metric_axes substrate pins ──
7427    //
7428    // Fail-before-pass-after granularity: [`Classification::horizon_requires_metric_axes`]
7429    // did not exist before this commit — the `(Classification) -> bool`
7430    // derived-nullary-boolean walk over the nested [`Horizon`] slot's
7431    // [`HorizonKind::requires_metric_axes`] projection had no substrate
7432    // owner. Post-lift the shape lives at ONE substrate primitive and
7433    // every downstream (the `metric-axes-required` fixed tag in
7434    // `tatara-check`, the [`crate::ephemeral::EphemeralSpec::horizon_requires_metric_axes`]
7435    // peer, future scheduler / metric-provisioning validators)
7436    // composes against the SAME `horizon_requires_metric_axes()` shape
7437    // rather than restating the
7438    // `classification.horizon.kind.requires_metric_axes()` chain at
7439    // its own callsite.
7440
7441    /// PER-VARIANT pin — for every [`HorizonKind`] variant, a
7442    /// [`Classification`] whose `horizon.kind` field carries that
7443    /// variant returns `horizon_requires_metric_axes()` matching the
7444    /// closed set's own [`HorizonKind::requires_metric_axes`] truth
7445    /// table. Sweep [`HorizonKind::ALL`] so a regression that (a)
7446    /// hard-coded the method body to a fixed answer, (b) inverted the
7447    /// projection, or (c) crossed the wires with the antisymmetric
7448    /// partner [`HorizonKind::terminates`] fails HERE at the substrate
7449    /// primitive before drifting through the `metric-axes-required`
7450    /// fixed tag or the peer ephemeral surface.
7451    #[test]
7452    fn classification_horizon_requires_metric_axes_matches_horizon_kind_projection() {
7453        for populated in HorizonKind::ALL {
7454            let c = Classification::gate_compute_with_axis(populated);
7455            assert_eq!(
7456                c.horizon_requires_metric_axes(),
7457                populated.requires_metric_axes(),
7458                "horizon.kind={populated:?}: horizon_requires_metric_axes() drift from HorizonKind::requires_metric_axes()",
7459            );
7460        }
7461    }
7462
7463    /// GATE-COMPUTE BASELINE — the workspace-baseline
7464    /// [`Classification::gate_compute`] shape carries
7465    /// `horizon: Horizon::default()` whose `kind` field defaults to
7466    /// [`HorizonKind::Bounded`] via `#[default]`, and
7467    /// [`HorizonKind::Bounded::requires_metric_axes`] projects `false`,
7468    /// so `horizon_requires_metric_axes()` returns `false`. Pins the
7469    /// default-arm short-circuit through TWO layers of `Default`
7470    /// (`Horizon`'s + `HorizonKind`'s) at ONE narrow site — a
7471    /// regression that promoted [`HorizonKind::Asymptotic`] to
7472    /// `#[default]`, or that swapped `Horizon::default`'s stored
7473    /// `kind`, or that wired [`HorizonKind::Bounded`] to
7474    /// `requires_metric_axes() = true`, would fail HERE before
7475    /// drifting through every unadorned Process's metric-provisioning
7476    /// answer. Mirror image of
7477    /// `classification_gate_compute_horizon_terminates_is_true`.
7478    #[test]
7479    fn classification_gate_compute_horizon_requires_metric_axes_is_false() {
7480        let c = Classification::gate_compute();
7481        assert!(
7482            !c.horizon_requires_metric_axes(),
7483            "gate_compute (horizon.kind=Bounded → requires_metric_axes=false) baseline",
7484        );
7485    }
7486
7487    /// BINARY XOR PARTITION pin — for every [`HorizonKind`] variant,
7488    /// EXACTLY ONE of [`Classification::horizon_terminates`] and
7489    /// [`Classification::horizon_requires_metric_axes`] returns `true`
7490    /// on a [`Classification`] whose `horizon.kind` field carries that
7491    /// variant. CLOSES the horizon axis into the FULL binary XOR
7492    /// partition contract sealed on the closed set by
7493    /// `horizon_kind_terminate_xor_requires_metric_axes` AND now
7494    /// composed through the parent-composed layer as a substrate-wide
7495    /// theorem. Binary counterpart of the ternary XOR partitions
7496    /// sealed on the sibling `point_type` and `substrate` axes by
7497    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`
7498    /// and
7499    /// `classification_substrate_probes_form_three_way_xor_partition_over_all`
7500    /// — where those axes carve the closed set into THREE disjoint
7501    /// buckets, the horizon axis carves into TWO. Structural twin of
7502    /// the calm-axis and data-axis binary XOR partitions
7503    /// `classification_calm_probes_form_binary_xor_partition_over_all`
7504    /// and
7505    /// `classification_data_probes_form_binary_xor_partition_over_all`
7506    /// on the sibling axes — this pin is the FIFTH (and final)
7507    /// classification axis to reach the closed XOR partition landmark
7508    /// on the (parent × derived-nullary-bool) corner, promoting the
7509    /// axis-closure milestone from a proven-repeatable quadruple
7510    /// (`point_type` + `substrate` ternary; `calm` + `data` binary)
7511    /// to a proven-repeatable QUINTUPLE that spans every axis of
7512    /// [`Classification`]. Rewritten from the earlier binary-XOR-only
7513    /// form (walked as `a ^ b`) into the canonical bucket-array
7514    /// `hits == 1` shape shared with the calm/data partitions so
7515    /// downstream N-ary consumers (audit dispatchers, coverage
7516    /// checkers) walk every axis through the SAME contract. A
7517    /// regression that crossed the wires between the two parent-
7518    /// composed probes (one probe silently composing the wrong
7519    /// closed-set arm) fails HERE rather than at every downstream
7520    /// consumer that trusts the two probes partition the horizon
7521    /// slot into disjoint buckets whose union covers every variant.
7522    #[test]
7523    fn classification_horizon_probes_form_binary_xor_partition_over_all() {
7524        for populated in HorizonKind::ALL {
7525            let c = Classification::gate_compute_with_axis(populated);
7526            let buckets = [c.horizon_terminates(), c.horizon_requires_metric_axes()];
7527            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
7528            assert_eq!(
7529                hits, 1,
7530                "horizon.kind={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
7531            );
7532        }
7533    }
7534
7535    // ── Classification::calm_requires_coordination substrate pins ────
7536    //
7537    // Fail-before-pass-after granularity: [`Classification::calm_requires_coordination`]
7538    // did not exist before this commit — the `(Classification) -> bool`
7539    // derived-nullary-boolean walk over the scalar [`CalmClassification`]
7540    // slot's [`CalmClassification::requires_coordination`] projection
7541    // had no substrate owner. Post-lift the shape lives at ONE
7542    // substrate primitive and every downstream (the
7543    // `coordination-required` fixed tag in `tatara-check`, the
7544    // [`crate::ephemeral::EphemeralSpec::calm_requires_coordination`]
7545    // peer, future scheduler / coordination-mode validators) composes
7546    // against the SAME `calm_requires_coordination()` shape rather than
7547    // restating the `classification.calm.requires_coordination()` chain
7548    // at its own callsite. THIRD occupant of the (parent × derived-
7549    // nullary-bool) corner across TWO closed-set axes (`HorizonKind`,
7550    // `CalmClassification`), pinning the corner as a proven-repeatable
7551    // primitive shape rather than a single-axis curiosity.
7552
7553    /// PER-VARIANT pin — for every [`CalmClassification`] variant, a
7554    /// [`Classification`] whose `calm` field carries that variant
7555    /// returns `calm_requires_coordination()` matching the closed
7556    /// set's own [`CalmClassification::requires_coordination`] truth
7557    /// table. Sweep [`CalmClassification::ALL`] so a regression that
7558    /// (a) hard-coded the method body to a fixed answer (silently
7559    /// returning `true` regardless of the stored variant, silently
7560    /// forcing every Monotone Process onto the Raft coordination path
7561    /// and eliminating the CALM theorem's practical dividend), (b)
7562    /// inverted the projection (silently promoting Monotone to
7563    /// "requires coordination"), or (c) crossed the wires with a
7564    /// sibling classification-axis probe fails HERE at the substrate
7565    /// primitive before drifting through the `coordination-required`
7566    /// fixed tag or the peer ephemeral surface.
7567    #[test]
7568    fn classification_calm_requires_coordination_matches_calm_classification_projection() {
7569        for populated in CalmClassification::ALL {
7570            let c = Classification::gate_compute_with_axis(populated);
7571            assert_eq!(
7572                c.calm_requires_coordination(),
7573                populated.requires_coordination(),
7574                "calm={populated:?}: calm_requires_coordination() drift from CalmClassification::requires_coordination()",
7575            );
7576        }
7577    }
7578
7579    /// GATE-COMPUTE BASELINE — the workspace-baseline
7580    /// [`Classification::gate_compute`] shape carries
7581    /// `calm: CalmClassification::default()` which defaults to
7582    /// [`CalmClassification::Monotone`] via `#[default]`, and
7583    /// [`CalmClassification::Monotone::requires_coordination`] projects
7584    /// `false`, so `calm_requires_coordination()` returns `false`. Pins
7585    /// the default-arm short-circuit through ONE layer of `Default`
7586    /// (`CalmClassification`'s) at ONE narrow site — a regression that
7587    /// promoted [`CalmClassification::NonMonotone`] to `#[default]`, or
7588    /// that wired [`CalmClassification::Monotone`] to
7589    /// `requires_coordination() = true`, would fail HERE before
7590    /// drifting through every unadorned Process's scheduler-facing
7591    /// coordination-mode answer. Distinct from the two sibling
7592    /// `horizon_*` gate-compute-baseline pins by ONE structural
7593    /// degree: those short-circuit through TWO layers of `Default`
7594    /// (`Horizon`'s + `HorizonKind`'s); this pin walks ONE layer of
7595    /// `Default` because [`Classification::calm`] is a scalar rather
7596    /// than a nested-struct wrapper.
7597    #[test]
7598    fn classification_gate_compute_calm_requires_coordination_is_false() {
7599        let c = Classification::gate_compute();
7600        assert!(
7601            !c.calm_requires_coordination(),
7602            "gate_compute (calm=Monotone → requires_coordination=false) baseline",
7603        );
7604    }
7605
7606    // ── Classification::data_is_regulated substrate pins ─────────────
7607    //
7608    // Fail-before-pass-after granularity: [`Classification::data_is_regulated`]
7609    // did not exist before this commit — the `(Classification) -> bool`
7610    // derived-nullary-boolean walk over the scalar [`DataClassification`]
7611    // slot's [`DataClassification::is_regulated`] projection had no
7612    // substrate owner. Post-lift the shape lives at ONE substrate
7613    // primitive and every downstream (the `data-regulated` fixed tag
7614    // in `tatara-check`, the
7615    // [`crate::ephemeral::EphemeralSpec::data_is_regulated`] peer,
7616    // future compliance-baseline / regulatory-regime validators)
7617    // composes against the SAME `data_is_regulated()` shape rather
7618    // than restating the
7619    // `classification.data_classification.is_regulated()` chain at
7620    // its own callsite. FOURTH occupant of the (parent × derived-
7621    // nullary-bool) corner across THREE closed-set axes
7622    // (`HorizonKind`, `CalmClassification`, `DataClassification`),
7623    // pinning the corner as a proven-repeatable primitive shape
7624    // across the substrate's three defaulted-child classification-
7625    // axis closed sets rather than a two-axis curiosity. SECOND
7626    // direct-scalar peer on the corner after
7627    // [`Self::calm_requires_coordination`] opened the direct-scalar
7628    // sub-corner variant.
7629
7630    /// PER-VARIANT pin — for every [`DataClassification`] variant, a
7631    /// [`Classification`] whose `data_classification` field carries
7632    /// that variant returns `data_is_regulated()` matching the closed
7633    /// set's own [`DataClassification::is_regulated`] truth table.
7634    /// Sweep [`DataClassification::ALL`] so a regression that (a)
7635    /// hard-coded the method body to a fixed answer (silently
7636    /// stamping every Process as regulated, silently forcing
7637    /// compliance-baseline overlays that only apply to PII/PHI/PCI
7638    /// onto every unadorned Process), (b) inverted the projection
7639    /// (silently downgrading regulated Pii/Phi/Pci to unregulated),
7640    /// or (c) crossed the wires with the sibling
7641    /// [`DataClassification::is_restricted`] projection (which
7642    /// disagrees on the two `Internal | Confidential` variants) fails
7643    /// HERE at the substrate primitive before drifting through the
7644    /// `data-regulated` fixed tag or the peer ephemeral surface.
7645    #[test]
7646    fn classification_data_is_regulated_matches_data_classification_projection() {
7647        for populated in DataClassification::ALL {
7648            let c = Classification::gate_compute_with_axis(populated);
7649            assert_eq!(
7650                c.data_is_regulated(),
7651                populated.is_regulated(),
7652                "data_classification={populated:?}: data_is_regulated() drift from DataClassification::is_regulated()",
7653            );
7654        }
7655    }
7656
7657    /// GATE-COMPUTE BASELINE — the workspace-baseline
7658    /// [`Classification::gate_compute`] shape carries
7659    /// `data_classification: DataClassification::default()` which
7660    /// defaults to [`DataClassification::Internal`] via `#[default]`,
7661    /// and [`DataClassification::Internal::is_regulated`] projects
7662    /// `false`, so `data_is_regulated()` returns `false`. Pins the
7663    /// default-arm short-circuit through ONE layer of `Default`
7664    /// (`DataClassification`'s) at ONE narrow site — a regression
7665    /// that promoted [`DataClassification::Pii`] (or any other
7666    /// regulated variant) to `#[default]`, or that wired
7667    /// [`DataClassification::Internal`] to `is_regulated() = true`,
7668    /// would fail HERE before drifting through every unadorned
7669    /// Process's compliance-baseline answer. Byte-for-byte
7670    /// structural peer of the sibling
7671    /// `classification_gate_compute_calm_requires_coordination_is_false`
7672    /// on the classification-data axis — same ONE-layer-of-Default
7673    /// short-circuit shape distinct from the two horizon-axis
7674    /// baselines which walk TWO layers of `Default`.
7675    #[test]
7676    fn classification_gate_compute_data_is_regulated_is_false() {
7677        let c = Classification::gate_compute();
7678        assert!(
7679            !c.data_is_regulated(),
7680            "gate_compute (data_classification=Internal → is_regulated=false) baseline",
7681        );
7682    }
7683
7684    // ── Classification::data_is_restricted substrate pins ────────────
7685    //
7686    // Fail-before-pass-after granularity: [`Classification::data_is_restricted`]
7687    // did not exist before this commit — the `(Classification) -> bool`
7688    // derived-nullary-boolean walk over the scalar [`DataClassification`]
7689    // slot's [`DataClassification::is_restricted`] projection had no
7690    // substrate owner. Post-lift the shape lives at ONE substrate
7691    // primitive and every downstream (the `data-restricted` fixed tag
7692    // in `tatara-check`, the
7693    // [`crate::ephemeral::EphemeralSpec::data_is_restricted`] peer,
7694    // future compliance-baseline / access-control-mandatory validators)
7695    // composes against the SAME `data_is_restricted()` shape rather
7696    // than restating the
7697    // `classification.data_classification.is_restricted()` chain at
7698    // its own callsite. FIFTH occupant of the (parent × derived-
7699    // nullary-bool) corner across THREE closed-set axes and the SECOND
7700    // occupant on the classification-data axis, pinning the axis as
7701    // a proven-repeatable structural sub-corner across TWO sibling
7702    // closed-set projections (`is_regulated` / `is_restricted`).
7703    // THIRD direct-scalar peer on the corner and the FIRST corner peer
7704    // whose gate-compute baseline projects to `true` rather than
7705    // `false` (mirror-image of the `Bounded`-default
7706    // `horizon_terminates` baseline on the nested-struct sub-corner).
7707
7708    /// PER-VARIANT pin — for every [`DataClassification`] variant, a
7709    /// [`Classification`] whose `data_classification` field carries
7710    /// that variant returns `data_is_restricted()` matching the closed
7711    /// set's own [`DataClassification::is_restricted`] truth table.
7712    /// Sweep [`DataClassification::ALL`] so a regression that (a)
7713    /// hard-coded the method body to a fixed answer, (b) inverted the
7714    /// projection (silently promoting `Public` to restricted), or
7715    /// (c) crossed the wires with the sibling
7716    /// [`DataClassification::is_regulated`] projection (which
7717    /// disagrees on the two `Internal | Confidential` variants) fails
7718    /// HERE at the substrate primitive before drifting through the
7719    /// `data-restricted` fixed tag or the peer ephemeral surface.
7720    #[test]
7721    fn classification_data_is_restricted_matches_data_classification_projection() {
7722        for populated in DataClassification::ALL {
7723            let c = Classification::gate_compute_with_axis(populated);
7724            assert_eq!(
7725                c.data_is_restricted(),
7726                populated.is_restricted(),
7727                "data_classification={populated:?}: data_is_restricted() drift from DataClassification::is_restricted()",
7728            );
7729        }
7730    }
7731
7732    /// GATE-COMPUTE BASELINE — the workspace-baseline
7733    /// [`Classification::gate_compute`] shape carries
7734    /// `data_classification: DataClassification::default()` which
7735    /// defaults to [`DataClassification::Internal`] via `#[default]`,
7736    /// and [`DataClassification::Internal::is_restricted`] projects
7737    /// `true`, so `data_is_restricted()` returns `true`. Pins the
7738    /// default-arm short-circuit through ONE layer of `Default` at
7739    /// ONE narrow site — a regression that promoted
7740    /// [`DataClassification::Public`] to `#[default]`, or that wired
7741    /// [`DataClassification::Internal`] to `is_restricted() = false`,
7742    /// would fail HERE before drifting through every unadorned
7743    /// Process's access-control-mandatory answer. FIRST direct-scalar
7744    /// corner peer whose gate-compute baseline projects to `true`
7745    /// (`data_is_regulated` / `calm_requires_coordination` both
7746    /// project `false` on the same defaulted parent), mirror-image of
7747    /// the nested-struct sub-corner where
7748    /// `classification_gate_compute_horizon_terminates_is_true`
7749    /// pins the `Bounded`-default `true` baseline.
7750    #[test]
7751    fn classification_gate_compute_data_is_restricted_is_true() {
7752        let c = Classification::gate_compute();
7753        assert!(
7754            c.data_is_restricted(),
7755            "gate_compute (data_classification=Internal → is_restricted=true) baseline",
7756        );
7757    }
7758
7759    /// COMPOSED IMPLICATION pin — the substrate-primitive-level
7760    /// counterpart of
7761    /// `data_classification_regulated_implies_restricted` at the
7762    /// [`Classification`] parent site: for every
7763    /// [`DataClassification`] variant, a [`Classification`] carrying
7764    /// that variant answers `data_is_regulated() ⇒
7765    /// data_is_restricted()` — regulated data is by construction
7766    /// restricted at the parent-composed derived-nullary-boolean
7767    /// projection, not just at the closed-set primitives. Pins the
7768    /// implication contract at the SAME substrate site that composes
7769    /// each side of the pair, so a regression that (a) reversed the
7770    /// [`Classification::data_is_regulated`] arm, (b) reversed the
7771    /// [`Classification::data_is_restricted`] arm, or (c) crossed
7772    /// their wires while the closed-set primitives stayed intact
7773    /// fails HERE. FIRST corner-peer pair on the workspace-wide
7774    /// (parent × derived-nullary-bool) corner whose two projections
7775    /// carry a non-trivial closed-set-internal implication
7776    /// relationship — a future compliance-baseline auto-selector
7777    /// binds through the parent-composed contract rather than
7778    /// restating the closed-set-primitive contract at the callsite.
7779    #[test]
7780    fn classification_data_is_regulated_implies_data_is_restricted_over_all() {
7781        for populated in DataClassification::ALL {
7782            let c = Classification::gate_compute_with_axis(populated);
7783            assert!(
7784                !c.data_is_regulated() || c.data_is_restricted(),
7785                "data_classification={populated:?}: data_is_regulated ⇒ data_is_restricted violated",
7786            );
7787        }
7788    }
7789
7790    // ── Classification::point_is_endomorphic substrate pins ──────────
7791    //
7792    // Fail-before-pass-after granularity: [`Classification::point_is_endomorphic`]
7793    // did not exist before this commit — the `(Classification) -> bool`
7794    // derived-nullary-boolean walk over the scalar [`ConvergencePointType`]
7795    // slot's [`ConvergencePointType::is_endomorphic`] projection had no
7796    // substrate owner. Post-lift the shape lives at ONE substrate
7797    // primitive and every downstream (the `endomorphic-point` fixed
7798    // tag in `tatara-check`, the
7799    // [`crate::ephemeral::EphemeralSpec::point_is_endomorphic`] peer,
7800    // future DAG composition / edge-cardinality validators) composes
7801    // against the SAME `point_is_endomorphic()` shape rather than
7802    // restating the `classification.point_type.is_endomorphic()` chain
7803    // at its own callsite. SIXTH occupant of the (parent × derived-
7804    // nullary-bool) corner across FOUR closed-set axes, and the FIRST
7805    // occupant threading the `point_type` axis, pinning the axis as a
7806    // proven-repeatable structural sub-corner rather than a horizon /
7807    // calm / data curiosity. FIRST direct-scalar corner peer whose
7808    // parent-composed baseline is NOT a substrate-`#[default]` short-
7809    // circuit — [`ConvergencePointType`] has no `impl Default`, so the
7810    // [`Classification::gate_compute`] baseline's `false` answer comes
7811    // from the chosen `point_type: Gate` field rather than a
7812    // defaulted-chain projection.
7813
7814    /// PER-VARIANT pin — for every [`ConvergencePointType`] variant, a
7815    /// [`Classification`] whose `point_type` field carries that variant
7816    /// returns `point_is_endomorphic()` matching the closed set's own
7817    /// [`ConvergencePointType::is_endomorphic`] truth table. Sweep
7818    /// [`ConvergencePointType::ALL`] so a regression that (a)
7819    /// hard-coded the method body to a fixed answer, (b) inverted the
7820    /// projection, or (c) crossed the wires with a sibling closed-set
7821    /// projection ([`ConvergencePointType::is_diffusive`] /
7822    /// [`ConvergencePointType::is_convergent`]) fails HERE at the
7823    /// substrate primitive before drifting through the
7824    /// `endomorphic-point` fixed tag or the peer ephemeral surface.
7825    #[test]
7826    fn classification_point_is_endomorphic_matches_point_type_projection() {
7827        for populated in ConvergencePointType::ALL {
7828            let c = Classification::gate_compute_with_axis(populated);
7829            assert_eq!(
7830                c.point_is_endomorphic(),
7831                populated.is_endomorphic(),
7832                "point_type={populated:?}: point_is_endomorphic() drift from ConvergencePointType::is_endomorphic()",
7833            );
7834        }
7835    }
7836
7837    /// GATE-COMPUTE BASELINE — the workspace-baseline
7838    /// [`Classification::gate_compute`] shape carries
7839    /// `point_type: ConvergencePointType::Gate` deliberately (NOT via
7840    /// `#[default]` — [`ConvergencePointType`] has no `impl Default`),
7841    /// and [`ConvergencePointType::Gate::is_endomorphic`] projects
7842    /// `false` (Gate is N→1 convergent, not 1→1 endomorphic), so
7843    /// `point_is_endomorphic()` returns `false`. Pins the baseline's
7844    /// chosen-field answer at ONE narrow site — a regression that
7845    /// promoted [`ConvergencePointType::Transform`] to the gate-compute
7846    /// baseline (silently retargeting every unadorned Process's
7847    /// topology bucket), or that wired [`ConvergencePointType::Gate`]
7848    /// to `is_endomorphic() = true`, would fail HERE before drifting
7849    /// through every unadorned Process's DAG-composition answer.
7850    /// FIRST direct-scalar corner peer whose parent-composed baseline
7851    /// is a chosen-field answer (not a substrate-`#[default]` short-
7852    /// circuit): distinct from the two `horizon_*` baselines (which
7853    /// short-circuit through TWO layers of `Default`), the sibling
7854    /// `calm_requires_coordination` baseline (ONE layer of `Default`),
7855    /// and the two `data_is_*` baselines (ONE layer of `Default`).
7856    #[test]
7857    fn classification_gate_compute_point_is_endomorphic_is_false() {
7858        let c = Classification::gate_compute();
7859        assert!(
7860            !c.point_is_endomorphic(),
7861            "gate_compute (point_type=Gate → is_endomorphic=false) baseline",
7862        );
7863    }
7864
7865    // ── Classification::point_is_diffusive substrate pins ───────────
7866    //
7867    // Fail-before-pass-after granularity: [`Classification::point_is_diffusive`]
7868    // did not exist before this commit — the `(Classification) -> bool`
7869    // derived-nullary-boolean walk over the scalar [`ConvergencePointType`]
7870    // slot's [`ConvergencePointType::is_diffusive`] projection had no
7871    // substrate owner. Post-lift the shape lives at ONE substrate
7872    // primitive and every downstream (the `diffusive-point` fixed tag
7873    // in `tatara-check`, the
7874    // [`crate::ephemeral::EphemeralSpec::point_is_diffusive`] peer,
7875    // future DAG composition / edge-cardinality validators) composes
7876    // against the SAME `point_is_diffusive()` shape. SEVENTH occupant
7877    // of the (parent × derived-nullary-bool) corner and SECOND
7878    // occupant threading the `point_type` axis, promoting that axis
7879    // from a proven-repeatable one-off (endomorphic alone) to a
7880    // proven-repeatable pair. FIRST corner-peer pair on the
7881    // `point_type` axis whose two projections carry a non-trivial
7882    // closed-set-internal MUTEX relationship (`point_is_endomorphic ⇒
7883    // ¬point_is_diffusive`), distinct from the sibling `data` axis
7884    // corner-peer pair whose two projections carry a non-trivial
7885    // implication (`data_is_regulated ⇒ data_is_restricted`).
7886
7887    /// PER-VARIANT pin — for every [`ConvergencePointType`] variant, a
7888    /// [`Classification`] whose `point_type` field carries that variant
7889    /// returns `point_is_diffusive()` matching the closed set's own
7890    /// [`ConvergencePointType::is_diffusive`] truth table. Sweep
7891    /// [`ConvergencePointType::ALL`] so a regression that (a)
7892    /// hard-coded the method body to a fixed answer, (b) inverted the
7893    /// projection, or (c) crossed the wires with a sibling closed-set
7894    /// projection ([`ConvergencePointType::is_endomorphic`] /
7895    /// [`ConvergencePointType::is_convergent`]) fails HERE at the
7896    /// substrate primitive before drifting through the
7897    /// `diffusive-point` fixed tag or the peer ephemeral surface.
7898    #[test]
7899    fn classification_point_is_diffusive_matches_point_type_projection() {
7900        for populated in ConvergencePointType::ALL {
7901            let c = Classification::gate_compute_with_axis(populated);
7902            assert_eq!(
7903                c.point_is_diffusive(),
7904                populated.is_diffusive(),
7905                "point_type={populated:?}: point_is_diffusive() drift from ConvergencePointType::is_diffusive()",
7906            );
7907        }
7908    }
7909
7910    /// GATE-COMPUTE BASELINE — the workspace-baseline
7911    /// [`Classification::gate_compute`] shape carries
7912    /// `point_type: ConvergencePointType::Gate` deliberately (NOT via
7913    /// `#[default]` — [`ConvergencePointType`] has no `impl Default`),
7914    /// and [`ConvergencePointType::Gate::is_diffusive`] projects
7915    /// `false` (Gate is N→1 convergent, not 1→N diffusive), so
7916    /// `point_is_diffusive()` returns `false`. Pins the baseline's
7917    /// chosen-field answer at ONE narrow site — a regression that
7918    /// promoted [`ConvergencePointType::Fork`] to the gate-compute
7919    /// baseline, or that wired [`ConvergencePointType::Gate`] to
7920    /// `is_diffusive() = true`, would fail HERE before drifting
7921    /// through every unadorned Process's DAG-composition answer.
7922    /// SECOND direct-scalar corner peer whose parent-composed baseline
7923    /// is a chosen-field answer (peer of
7924    /// `classification_gate_compute_point_is_endomorphic_is_false`).
7925    #[test]
7926    fn classification_gate_compute_point_is_diffusive_is_false() {
7927        let c = Classification::gate_compute();
7928        assert!(
7929            !c.point_is_diffusive(),
7930            "gate_compute (point_type=Gate → is_diffusive=false) baseline",
7931        );
7932    }
7933
7934    /// MUTEX pin — [`Classification::point_is_endomorphic`] AND
7935    /// [`Classification::point_is_diffusive`] are NEVER simultaneously
7936    /// true for ANY [`ConvergencePointType`] variant, since the closed
7937    /// set's own `is_endomorphic` / `is_diffusive` / `is_convergent`
7938    /// triple carves it into THREE disjoint buckets (sealed on the
7939    /// closed set by
7940    /// `convergence_point_type_buckets_cover_every_variant`). Sweep
7941    /// [`ConvergencePointType::ALL`] so a regression that crossed the
7942    /// wires between the two corner peers at the parent-composed layer
7943    /// (one probe silently composing the wrong closed-set arm) fails
7944    /// HERE rather than at every downstream consumer that trusts the
7945    /// two probes partition the point-type slot into disjoint buckets.
7946    /// FIRST corner-peer pair on the workspace-wide (parent × derived-
7947    /// nullary-bool) corner whose two projections carry a non-trivial
7948    /// closed-set-internal MUTEX relationship (distinct from the
7949    /// sibling `data`-axis IMPLICATION pair sealed by
7950    /// `classification_data_is_regulated_implies_data_is_restricted_over_all`
7951    /// — that pair contains one bucket in another; this pair
7952    /// disjointly partitions two buckets of a three-way carving).
7953    /// When [`Classification::point_is_convergent`] lands the mutex
7954    /// closes into the full three-way XOR partition contract
7955    /// `point_is_endomorphic ⊕ point_is_diffusive ⊕
7956    /// point_is_convergent` composed through this corner as a
7957    /// substrate-wide theorem.
7958    #[test]
7959    fn classification_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all() {
7960        for populated in ConvergencePointType::ALL {
7961            let c = Classification::gate_compute_with_axis(populated);
7962            assert!(
7963                !(c.point_is_endomorphic() && c.point_is_diffusive()),
7964                "point_type={populated:?}: point_is_endomorphic AND point_is_diffusive both true (mutex violated)",
7965            );
7966        }
7967    }
7968
7969    // ── Classification::point_is_convergent substrate pins ──────────
7970    //
7971    // Fail-before-pass-after granularity: [`Classification::point_is_convergent`]
7972    // did not exist before this commit — the `(Classification) -> bool`
7973    // derived-nullary-boolean walk over the scalar [`ConvergencePointType`]
7974    // slot's [`ConvergencePointType::is_convergent`] projection had no
7975    // substrate owner. Post-lift the shape lives at ONE substrate
7976    // primitive and every downstream (the `convergent-point` fixed
7977    // tag in `tatara-check`, the
7978    // [`crate::ephemeral::EphemeralSpec::point_is_convergent`] peer,
7979    // future DAG composition / edge-cardinality validators) composes
7980    // against the SAME `point_is_convergent()` shape. EIGHTH occupant
7981    // of the (parent × derived-nullary-bool) corner and THIRD
7982    // occupant threading the `point_type` axis, closing the axis into
7983    // a proven-repeatable three-peer sub-corner. CLOSES the mutex
7984    // pair [`Self::point_is_endomorphic`] / [`Self::point_is_diffusive`]
7985    // into the FULL three-way XOR partition contract on the axis.
7986
7987    /// PER-VARIANT pin — for every [`ConvergencePointType`] variant, a
7988    /// [`Classification`] whose `point_type` field carries that variant
7989    /// returns `point_is_convergent()` matching the closed set's own
7990    /// [`ConvergencePointType::is_convergent`] truth table. Sweep
7991    /// [`ConvergencePointType::ALL`] so a regression that (a)
7992    /// hard-coded the method body to a fixed answer, (b) inverted the
7993    /// projection, or (c) crossed the wires with a sibling closed-set
7994    /// projection ([`ConvergencePointType::is_endomorphic`] /
7995    /// [`ConvergencePointType::is_diffusive`]) fails HERE at the
7996    /// substrate primitive before drifting through the
7997    /// `convergent-point` fixed tag or the peer ephemeral surface.
7998    #[test]
7999    fn classification_point_is_convergent_matches_point_type_projection() {
8000        for populated in ConvergencePointType::ALL {
8001            let c = Classification::gate_compute_with_axis(populated);
8002            assert_eq!(
8003                c.point_is_convergent(),
8004                populated.is_convergent(),
8005                "point_type={populated:?}: point_is_convergent() drift from ConvergencePointType::is_convergent()",
8006            );
8007        }
8008    }
8009
8010    /// GATE-COMPUTE BASELINE — the workspace-baseline
8011    /// [`Classification::gate_compute`] shape carries
8012    /// `point_type: ConvergencePointType::Gate` deliberately (NOT via
8013    /// `#[default]` — [`ConvergencePointType`] has no `impl Default`),
8014    /// and [`ConvergencePointType::Gate::is_convergent`] projects
8015    /// `true` (Gate is the canonical N→1 convergent barrier), so
8016    /// `point_is_convergent()` returns `true`. Pins the baseline's
8017    /// chosen-field answer at ONE narrow site — a regression that
8018    /// promoted [`ConvergencePointType::Transform`] to the gate-compute
8019    /// baseline (silently retargeting every unadorned Process's
8020    /// topology bucket), or that wired [`ConvergencePointType::Gate`]
8021    /// to `is_convergent() = false`, would fail HERE before drifting
8022    /// through every unadorned Process's DAG-composition answer.
8023    /// FIRST direct-scalar corner peer whose parent-composed
8024    /// gate-compute baseline projects `true` — mirror-inverted from
8025    /// the two sibling `point_is_endomorphic` /
8026    /// `point_is_diffusive` baselines which both project `false`.
8027    #[test]
8028    fn classification_gate_compute_point_is_convergent_is_true() {
8029        let c = Classification::gate_compute();
8030        assert!(
8031            c.point_is_convergent(),
8032            "gate_compute (point_type=Gate → is_convergent=true) baseline",
8033        );
8034    }
8035
8036    /// THREE-WAY XOR PARTITION pin — for every
8037    /// [`ConvergencePointType`] variant, EXACTLY ONE of
8038    /// [`Classification::point_is_endomorphic`],
8039    /// [`Classification::point_is_diffusive`], and
8040    /// [`Classification::point_is_convergent`] returns `true` on a
8041    /// [`Classification`] carrying that variant. Closes the mutex pair
8042    /// `classification_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`
8043    /// into the FULL ternary XOR partition contract sealed on the
8044    /// closed set by `convergence_point_type_buckets_cover_every_variant`
8045    /// AND now composed through the parent-composed layer as a
8046    /// substrate-wide theorem. Ternary lift of the closed-set XOR
8047    /// pair `terminates ^ requires_metric_axes` that already composes
8048    /// through this corner today — where the `horizon` axis carves
8049    /// its closed set into TWO non-empty buckets, the `point_type`
8050    /// axis carves into THREE non-empty buckets. A regression that
8051    /// crossed the wires between any two of the three parent-composed
8052    /// probes (one probe silently composing the wrong closed-set arm)
8053    /// fails HERE rather than at every downstream consumer that
8054    /// trusts the three probes partition the point-type slot into
8055    /// disjoint buckets whose union covers every variant.
8056    #[test]
8057    fn classification_point_type_probes_form_three_way_xor_partition_over_all() {
8058        for populated in ConvergencePointType::ALL {
8059            let c = Classification::gate_compute_with_axis(populated);
8060            let buckets = [
8061                c.point_is_endomorphic(),
8062                c.point_is_diffusive(),
8063                c.point_is_convergent(),
8064            ];
8065            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
8066            assert_eq!(
8067                hits, 1,
8068                "point_type={populated:?}: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
8069            );
8070        }
8071    }
8072
8073    // ── Classification::substrate_is_resource substrate pins ────────
8074    //
8075    // Fail-before-pass-after granularity: [`Classification::substrate_is_resource`]
8076    // did not exist before this commit — the `(Classification) -> bool`
8077    // derived-nullary-boolean walk over the scalar [`SubstrateType`]
8078    // slot's [`SubstrateType::is_resource`] projection had no
8079    // substrate owner. Post-lift the shape lives at ONE substrate
8080    // primitive and every downstream (the `resource-substrate` fixed
8081    // tag in `tatara-check`, the
8082    // [`crate::ephemeral::EphemeralSpec::substrate_is_resource`]
8083    // peer, future plane-baseline / compliance-baseline selectors)
8084    // composes against the SAME `substrate_is_resource()` shape.
8085    // NINTH occupant of the (parent × derived-nullary-bool) corner
8086    // and FIRST occupant threading the classification-`substrate`
8087    // axis — opens the fourth of six classification axes on the
8088    // corner after `horizon`, `calm`, `data_classification`, and
8089    // `point_type`.
8090
8091    /// PER-VARIANT pin — for every [`SubstrateType`] variant, a
8092    /// [`Classification`] whose `substrate` field carries that
8093    /// variant returns `substrate_is_resource()` matching the closed
8094    /// set's own [`SubstrateType::is_resource`] truth table. Sweep
8095    /// [`SubstrateType::ALL`] so a regression that (a) hard-coded
8096    /// the method body to a fixed answer, (b) inverted the
8097    /// projection, or (c) crossed the wires with a sibling closed-
8098    /// set projection ([`SubstrateType::is_policy`] /
8099    /// [`SubstrateType::is_telemetry`]) fails HERE at the substrate
8100    /// primitive before drifting through the `resource-substrate`
8101    /// fixed tag or the peer ephemeral surface.
8102    #[test]
8103    fn classification_substrate_is_resource_matches_substrate_projection() {
8104        for populated in SubstrateType::ALL {
8105            let c = Classification::gate_compute_with_axis(populated);
8106            assert_eq!(
8107                c.substrate_is_resource(),
8108                populated.is_resource(),
8109                "substrate={populated:?}: substrate_is_resource() drift from SubstrateType::is_resource()",
8110            );
8111        }
8112    }
8113
8114    /// GATE-COMPUTE BASELINE — the workspace-baseline
8115    /// [`Classification::gate_compute`] shape carries
8116    /// `substrate: SubstrateType::Compute` deliberately (NOT via
8117    /// `#[default]` — [`SubstrateType`] has no `impl Default`), and
8118    /// [`SubstrateType::Compute::is_resource`] projects `true`
8119    /// (Compute is a resource-plane substrate you allocate budgets
8120    /// from), so `substrate_is_resource()` returns `true`. Pins the
8121    /// baseline's chosen-field answer at ONE narrow site — a
8122    /// regression that promoted [`SubstrateType::Security`] (or any
8123    /// non-resource plane) to the gate-compute baseline (silently
8124    /// retargeting every unadorned Process's plane bucket), or that
8125    /// wired [`SubstrateType::Compute`] to `is_resource() = false`,
8126    /// would fail HERE before drifting through every unadorned
8127    /// Process's plane-baseline answer. Structural peer of
8128    /// `classification_gate_compute_point_is_convergent_is_true`:
8129    /// both walk direct-scalar chosen fields with `true` baseline
8130    /// answers (mirror-aligned with each other, mirror-inverted from
8131    /// the two other `point_type`-axis peers whose baselines answer
8132    /// `false`).
8133    #[test]
8134    fn classification_gate_compute_substrate_is_resource_is_true() {
8135        let c = Classification::gate_compute();
8136        assert!(
8137            c.substrate_is_resource(),
8138            "gate_compute (substrate=Compute → is_resource=true) baseline",
8139        );
8140    }
8141
8142    // ── Classification::substrate_is_policy substrate pins ──────────
8143    //
8144    // Fail-before-pass-after granularity: [`Classification::substrate_is_policy`]
8145    // did not exist before this commit — the `(Classification) -> bool`
8146    // derived-nullary-boolean walk over the scalar [`SubstrateType`]
8147    // slot's [`SubstrateType::is_policy`] projection had no
8148    // substrate owner. Post-lift the shape lives at ONE substrate
8149    // primitive and every downstream (the `policy-substrate` fixed
8150    // tag in `tatara-check`, the
8151    // [`crate::ephemeral::EphemeralSpec::substrate_is_policy`] peer,
8152    // future plane-baseline / compliance-baseline selectors)
8153    // composes against the SAME `substrate_is_policy()` shape.
8154    // TENTH occupant of the (parent × derived-nullary-bool) corner
8155    // and SECOND occupant threading the classification-`substrate`
8156    // axis, promoting that axis from a proven-repeatable one-off
8157    // (`substrate_is_resource` alone) to a proven-repeatable pair.
8158    // FIRST substrate-axis corner-peer pair carrying a non-trivial
8159    // closed-set-internal MUTEX relationship
8160    // (`substrate_is_resource ⇒ ¬substrate_is_policy`).
8161
8162    /// PER-VARIANT pin — for every [`SubstrateType`] variant, a
8163    /// [`Classification`] whose `substrate` field carries that
8164    /// variant returns `substrate_is_policy()` matching the closed
8165    /// set's own [`SubstrateType::is_policy`] truth table. Sweep
8166    /// [`SubstrateType::ALL`] so a regression that (a) hard-coded
8167    /// the method body to a fixed answer, (b) inverted the
8168    /// projection, or (c) crossed the wires with a sibling closed-
8169    /// set projection ([`SubstrateType::is_resource`] /
8170    /// [`SubstrateType::is_telemetry`]) fails HERE at the substrate
8171    /// primitive before drifting through the `policy-substrate`
8172    /// fixed tag or the peer ephemeral surface.
8173    #[test]
8174    fn classification_substrate_is_policy_matches_substrate_projection() {
8175        for populated in SubstrateType::ALL {
8176            let c = Classification::gate_compute_with_axis(populated);
8177            assert_eq!(
8178                c.substrate_is_policy(),
8179                populated.is_policy(),
8180                "substrate={populated:?}: substrate_is_policy() drift from SubstrateType::is_policy()",
8181            );
8182        }
8183    }
8184
8185    /// GATE-COMPUTE BASELINE — the workspace-baseline
8186    /// [`Classification::gate_compute`] shape carries
8187    /// `substrate: SubstrateType::Compute` deliberately (NOT via
8188    /// `#[default]` — [`SubstrateType`] has no `impl Default`), and
8189    /// [`SubstrateType::Compute::is_policy`] projects `false`
8190    /// (Compute is a resource-plane substrate, not a policy plane),
8191    /// so `substrate_is_policy()` returns `false`. Pins the
8192    /// baseline's chosen-field answer at ONE narrow site — a
8193    /// regression that promoted [`SubstrateType::Security`] (or any
8194    /// policy plane) to the gate-compute baseline, or that wired
8195    /// [`SubstrateType::Compute`] to `is_policy() = true`, would
8196    /// fail HERE before drifting through every unadorned Process's
8197    /// plane-baseline answer. Mirror-inverted from the sibling
8198    /// `classification_gate_compute_substrate_is_resource_is_true`
8199    /// baseline (both walk the SAME chosen `substrate: Compute`
8200    /// field, so `is_resource = true` ⇒ `is_policy = false` on the
8201    /// closed set's disjoint plane partition).
8202    #[test]
8203    fn classification_gate_compute_substrate_is_policy_is_false() {
8204        let c = Classification::gate_compute();
8205        assert!(
8206            !c.substrate_is_policy(),
8207            "gate_compute (substrate=Compute → is_policy=false) baseline",
8208        );
8209    }
8210
8211    /// MUTEX pin — [`Classification::substrate_is_resource`] AND
8212    /// [`Classification::substrate_is_policy`] are NEVER simultaneously
8213    /// true for ANY [`SubstrateType`] variant, since the closed set's
8214    /// own `is_resource` / `is_policy` / `is_telemetry` triple carves
8215    /// it into THREE disjoint buckets (sealed on the closed set by
8216    /// `substrate_type_buckets_cover_every_variant`). Sweep
8217    /// [`SubstrateType::ALL`] so a regression that crossed the wires
8218    /// between the two corner peers at the parent-composed layer (one
8219    /// probe silently composing the wrong closed-set arm) fails HERE
8220    /// rather than at every downstream consumer that trusts the two
8221    /// probes partition the substrate slot into disjoint buckets.
8222    /// FIRST substrate-axis corner-peer pair whose two projections
8223    /// carry a non-trivial closed-set-internal MUTEX relationship —
8224    /// structural twin of the sibling `point_type`-axis MUTEX pair
8225    /// sealed by
8226    /// `classification_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`.
8227    /// When [`Classification::substrate_is_telemetry`] lands the
8228    /// mutex closes into the full three-way XOR partition contract
8229    /// `substrate_is_resource ⊕ substrate_is_policy ⊕ substrate_is_telemetry`
8230    /// composed through this corner as a substrate-wide theorem.
8231    #[test]
8232    fn classification_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all() {
8233        for populated in SubstrateType::ALL {
8234            let c = Classification::gate_compute_with_axis(populated);
8235            assert!(
8236                !(c.substrate_is_resource() && c.substrate_is_policy()),
8237                "substrate={populated:?}: substrate_is_resource AND substrate_is_policy both true (mutex violated)",
8238            );
8239        }
8240    }
8241
8242    // ── Classification::substrate_is_telemetry substrate pins ───────
8243    //
8244    // Fail-before-pass-after granularity: [`Classification::substrate_is_telemetry`]
8245    // did not exist before this commit — the `(Classification) -> bool`
8246    // derived-nullary-boolean walk over the scalar [`SubstrateType`]
8247    // slot's [`SubstrateType::is_telemetry`] projection had no
8248    // substrate owner. Post-lift the shape lives at ONE substrate
8249    // primitive and every downstream (the `telemetry-substrate` fixed
8250    // tag in `tatara-check`, the
8251    // [`crate::ephemeral::EphemeralSpec::substrate_is_telemetry`]
8252    // peer, future plane-baseline / compliance-baseline selectors)
8253    // composes against the SAME `substrate_is_telemetry()` shape.
8254    // ELEVENTH occupant of the (parent × derived-nullary-bool) corner
8255    // and THIRD occupant threading the classification-`substrate`
8256    // axis — CLOSES the substrate axis on the corner into the FULL
8257    // three-way XOR partition contract
8258    // `substrate_is_resource ⊕ substrate_is_policy ⊕ substrate_is_telemetry`
8259    // sealed on the closed set by
8260    // `substrate_type_buckets_cover_every_variant` and composed
8261    // through the parent-composed layer by
8262    // `classification_substrate_probes_form_three_way_xor_partition_over_all`.
8263
8264    /// PER-VARIANT pin — for every [`SubstrateType`] variant, a
8265    /// [`Classification`] whose `substrate` field carries that
8266    /// variant returns `substrate_is_telemetry()` matching the closed
8267    /// set's own [`SubstrateType::is_telemetry`] truth table. Sweep
8268    /// [`SubstrateType::ALL`] so a regression that (a) hard-coded
8269    /// the method body to a fixed answer, (b) inverted the
8270    /// projection, or (c) crossed the wires with a sibling closed-
8271    /// set projection ([`SubstrateType::is_resource`] /
8272    /// [`SubstrateType::is_policy`]) fails HERE at the substrate
8273    /// primitive before drifting through the `telemetry-substrate`
8274    /// fixed tag or the peer ephemeral surface.
8275    #[test]
8276    fn classification_substrate_is_telemetry_matches_substrate_projection() {
8277        for populated in SubstrateType::ALL {
8278            let c = Classification::gate_compute_with_axis(populated);
8279            assert_eq!(
8280                c.substrate_is_telemetry(),
8281                populated.is_telemetry(),
8282                "substrate={populated:?}: substrate_is_telemetry() drift from SubstrateType::is_telemetry()",
8283            );
8284        }
8285    }
8286
8287    /// GATE-COMPUTE BASELINE — the workspace-baseline
8288    /// [`Classification::gate_compute`] shape carries
8289    /// `substrate: SubstrateType::Compute` deliberately (NOT via
8290    /// `#[default]` — [`SubstrateType`] has no `impl Default`), and
8291    /// [`SubstrateType::Compute::is_telemetry`] projects `false`
8292    /// (Compute is a resource-plane substrate, not a telemetry
8293    /// plane), so `substrate_is_telemetry()` returns `false`. Pins
8294    /// the baseline's chosen-field answer at ONE narrow site — a
8295    /// regression that promoted [`SubstrateType::Observability`] to
8296    /// the gate-compute baseline, or that wired
8297    /// [`SubstrateType::Compute`] to `is_telemetry() = true`, would
8298    /// fail HERE before drifting through every unadorned Process's
8299    /// plane-baseline answer. Mirror-inverted from the sibling
8300    /// `classification_gate_compute_substrate_is_resource_is_true`
8301    /// baseline (both walk the SAME chosen `substrate: Compute`
8302    /// field, so `is_resource = true` ⇒ `is_telemetry = false` on the
8303    /// closed set's disjoint plane partition), aligned with the
8304    /// sibling `substrate_is_policy` baseline's `false`.
8305    #[test]
8306    fn classification_gate_compute_substrate_is_telemetry_is_false() {
8307        let c = Classification::gate_compute();
8308        assert!(
8309            !c.substrate_is_telemetry(),
8310            "gate_compute (substrate=Compute → is_telemetry=false) baseline",
8311        );
8312    }
8313
8314    /// MUTEX pin — [`Classification::substrate_is_resource`] AND
8315    /// [`Classification::substrate_is_telemetry`] are NEVER
8316    /// simultaneously true for ANY [`SubstrateType`] variant, since
8317    /// the closed set's own `is_resource` / `is_policy` /
8318    /// `is_telemetry` triple carves it into THREE disjoint buckets
8319    /// (sealed on the closed set by
8320    /// `substrate_type_buckets_cover_every_variant`). Second
8321    /// substrate-axis corner-peer MUTEX pin — peer of
8322    /// `classification_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
8323    /// on a sibling closed-set projection.
8324    #[test]
8325    fn classification_substrate_is_resource_and_substrate_is_telemetry_are_mutex_over_all() {
8326        for populated in SubstrateType::ALL {
8327            let c = Classification::gate_compute_with_axis(populated);
8328            assert!(
8329                !(c.substrate_is_resource() && c.substrate_is_telemetry()),
8330                "substrate={populated:?}: substrate_is_resource AND substrate_is_telemetry both true (mutex violated)",
8331            );
8332        }
8333    }
8334
8335    /// MUTEX pin — [`Classification::substrate_is_policy`] AND
8336    /// [`Classification::substrate_is_telemetry`] are NEVER
8337    /// simultaneously true for ANY [`SubstrateType`] variant. Third
8338    /// substrate-axis corner-peer MUTEX pin — completes the three
8339    /// pairwise MUTEX relations on the substrate axis alongside
8340    /// `classification_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
8341    /// and
8342    /// `classification_substrate_is_resource_and_substrate_is_telemetry_are_mutex_over_all`.
8343    #[test]
8344    fn classification_substrate_is_policy_and_substrate_is_telemetry_are_mutex_over_all() {
8345        for populated in SubstrateType::ALL {
8346            let c = Classification::gate_compute_with_axis(populated);
8347            assert!(
8348                !(c.substrate_is_policy() && c.substrate_is_telemetry()),
8349                "substrate={populated:?}: substrate_is_policy AND substrate_is_telemetry both true (mutex violated)",
8350            );
8351        }
8352    }
8353
8354    /// THREE-WAY XOR PARTITION pin — for every [`SubstrateType`]
8355    /// variant, EXACTLY ONE of
8356    /// [`Classification::substrate_is_resource`],
8357    /// [`Classification::substrate_is_policy`], and
8358    /// [`Classification::substrate_is_telemetry`] returns `true` on
8359    /// a [`Classification`] carrying that variant. CLOSES the three
8360    /// pairwise MUTEX pins on the substrate axis
8361    /// (`substrate_is_resource ⇒ ¬substrate_is_policy`,
8362    /// `substrate_is_resource ⇒ ¬substrate_is_telemetry`,
8363    /// `substrate_is_policy ⇒ ¬substrate_is_telemetry`) into the FULL
8364    /// ternary XOR partition contract sealed on the closed set by
8365    /// `substrate_type_buckets_cover_every_variant` AND now composed
8366    /// through the parent-composed layer as a substrate-wide theorem.
8367    /// Structural twin of the sibling `point_type`-axis ternary lift
8368    /// sealed on this surface by
8369    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`.
8370    /// A regression that crossed the wires between any two of the
8371    /// three parent-composed probes (one probe silently composing the
8372    /// wrong closed-set arm) fails HERE rather than at every
8373    /// downstream consumer that trusts the three probes partition the
8374    /// substrate slot into disjoint buckets whose union covers every
8375    /// variant.
8376    #[test]
8377    fn classification_substrate_probes_form_three_way_xor_partition_over_all() {
8378        for populated in SubstrateType::ALL {
8379            let c = Classification::gate_compute_with_axis(populated);
8380            let buckets = [
8381                c.substrate_is_resource(),
8382                c.substrate_is_policy(),
8383                c.substrate_is_telemetry(),
8384            ];
8385            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
8386            assert_eq!(
8387                hits, 1,
8388                "substrate={populated:?}: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
8389            );
8390        }
8391    }
8392
8393    // ── Classification::calm_is_monotone substrate pins ─────────────
8394    //
8395    // Fail-before-pass-after granularity: [`Classification::calm_is_monotone`]
8396    // did not exist before this commit — the `(Classification) -> bool`
8397    // derived-nullary-boolean walk over the scalar [`CalmClassification`]
8398    // slot's [`CalmClassification::is_monotone`] projection had no
8399    // substrate owner. Post-lift the shape lives at ONE substrate
8400    // primitive and every downstream (the `monotone-calm` fixed tag
8401    // in `tatara-check`, the
8402    // [`crate::ephemeral::EphemeralSpec::calm_is_monotone`] peer,
8403    // future scheduler / gossip-eligibility validators asking the
8404    // positive CALM framing) composes against the SAME
8405    // `calm_is_monotone()` shape rather than restating either
8406    // `!self.calm_requires_coordination()` or the
8407    // `self.calm.is_monotone()` chain at its own callsite. TWELFTH
8408    // occupant of the (parent × derived-nullary-bool) corner and
8409    // SECOND occupant threading the classification-`calm` axis —
8410    // CLOSES the calm axis on the corner into the FULL binary XOR
8411    // partition contract `calm_is_monotone ⊕ calm_requires_coordination`
8412    // sealed on the closed set by
8413    // `calm_classification_monotone_xor_requires_coordination` and
8414    // composed through the parent-composed layer by
8415    // `classification_calm_probes_form_binary_xor_partition_over_all`.
8416
8417    /// PER-VARIANT pin — for every [`CalmClassification`] variant, a
8418    /// [`Classification`] whose `calm` field carries that variant
8419    /// returns `calm_is_monotone()` matching the closed set's own
8420    /// [`CalmClassification::is_monotone`] truth table. Sweep
8421    /// [`CalmClassification::ALL`] so a regression that (a) hard-
8422    /// coded the method body to a fixed answer (silently returning
8423    /// `true` regardless of the stored variant, silently marking
8424    /// every Process as gossip-eligible and shipping non-monotone
8425    /// operations onto the no-coordination path), (b) inverted the
8426    /// projection (silently promoting NonMonotone to "monotone"),
8427    /// or (c) crossed the wires with a sibling classification-axis
8428    /// probe fails HERE at the substrate primitive before drifting
8429    /// through the `monotone-calm` fixed tag or the peer ephemeral
8430    /// surface.
8431    #[test]
8432    fn classification_calm_is_monotone_matches_calm_classification_projection() {
8433        for populated in CalmClassification::ALL {
8434            let c = Classification::gate_compute_with_axis(populated);
8435            assert_eq!(
8436                c.calm_is_monotone(),
8437                populated.is_monotone(),
8438                "calm={populated:?}: calm_is_monotone() drift from CalmClassification::is_monotone()",
8439            );
8440        }
8441    }
8442
8443    /// GATE-COMPUTE BASELINE — the workspace-baseline
8444    /// [`Classification::gate_compute`] shape carries
8445    /// `calm: CalmClassification::default()` which defaults to
8446    /// [`CalmClassification::Monotone`] via `#[default]`, and
8447    /// [`CalmClassification::Monotone::is_monotone`] projects `true`,
8448    /// so `calm_is_monotone()` returns `true`. Pins the default-arm
8449    /// short-circuit through ONE layer of `Default`
8450    /// (`CalmClassification`'s) at ONE narrow site — a regression
8451    /// that promoted [`CalmClassification::NonMonotone`] to
8452    /// `#[default]`, or that wired [`CalmClassification::Monotone`]
8453    /// to `is_monotone() = false`, would fail HERE before drifting
8454    /// through every unadorned Process's positive-CALM-framing
8455    /// answer. Mirror-inverted from the sibling
8456    /// `classification_gate_compute_calm_requires_coordination_is_false`
8457    /// baseline (both walk the SAME defaulted `calm` field, so
8458    /// `requires_coordination = false` ⇒ `is_monotone = true` on the
8459    /// closed set's disjoint XOR partition).
8460    #[test]
8461    fn classification_gate_compute_calm_is_monotone_is_true() {
8462        let c = Classification::gate_compute();
8463        assert!(
8464            c.calm_is_monotone(),
8465            "gate_compute (calm=Monotone → is_monotone=true) baseline",
8466        );
8467    }
8468
8469    /// MUTEX pin — [`Classification::calm_requires_coordination`] AND
8470    /// [`Classification::calm_is_monotone`] are NEVER simultaneously
8471    /// true for ANY [`CalmClassification`] variant, since the closed
8472    /// set's own `is_monotone` / `requires_coordination` pair carves
8473    /// it into TWO disjoint buckets sealed on the closed set by
8474    /// `calm_classification_monotone_xor_requires_coordination`.
8475    /// FIRST calm-axis corner-peer MUTEX pin — the calm axis's
8476    /// counterpart to the sibling substrate-axis
8477    /// `classification_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
8478    /// on a binary (rather than ternary) closed set.
8479    #[test]
8480    fn classification_calm_requires_coordination_and_calm_is_monotone_are_mutex_over_all() {
8481        for populated in CalmClassification::ALL {
8482            let c = Classification::gate_compute_with_axis(populated);
8483            assert!(
8484                !(c.calm_requires_coordination() && c.calm_is_monotone()),
8485                "calm={populated:?}: calm_requires_coordination AND calm_is_monotone both true (mutex violated)",
8486            );
8487        }
8488    }
8489
8490    /// BINARY XOR PARTITION pin — for every [`CalmClassification`]
8491    /// variant, EXACTLY ONE of
8492    /// [`Classification::calm_is_monotone`] and
8493    /// [`Classification::calm_requires_coordination`] returns `true`
8494    /// on a [`Classification`] carrying that variant. CLOSES the
8495    /// calm-axis MUTEX pin
8496    /// (`calm_requires_coordination ⇒ ¬calm_is_monotone`) into the
8497    /// FULL binary XOR partition contract sealed on the closed set
8498    /// by `calm_classification_monotone_xor_requires_coordination`
8499    /// AND now composed through the parent-composed layer as a
8500    /// substrate-wide theorem. Binary counterpart of the ternary XOR
8501    /// partitions sealed on the sibling `point_type` and `substrate`
8502    /// axes by
8503    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`
8504    /// and
8505    /// `classification_substrate_probes_form_three_way_xor_partition_over_all`
8506    /// — where those axes carve the closed set into THREE disjoint
8507    /// buckets, the calm axis carves into TWO. Structural twin of
8508    /// the closed-set-layer binary XOR
8509    /// `horizon_kind_terminate_xor_requires_metric_axes` on the
8510    /// sibling horizon axis, lifted through the parent-composed
8511    /// layer to make the calm axis the THIRD classification axis to
8512    /// reach a closed XOR partition landmark on this corner. A
8513    /// regression that crossed the wires between the two parent-
8514    /// composed probes (one probe silently composing the wrong
8515    /// closed-set arm) fails HERE rather than at every downstream
8516    /// consumer that trusts the two probes partition the calm slot
8517    /// into disjoint buckets whose union covers every variant.
8518    #[test]
8519    fn classification_calm_probes_form_binary_xor_partition_over_all() {
8520        for populated in CalmClassification::ALL {
8521            let c = Classification::gate_compute_with_axis(populated);
8522            let buckets = [c.calm_is_monotone(), c.calm_requires_coordination()];
8523            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
8524            assert_eq!(
8525                hits, 1,
8526                "calm={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
8527            );
8528        }
8529    }
8530
8531    // ── Classification::data_is_public substrate pins ───────────────
8532    //
8533    // Fail-before-pass-after granularity: [`Classification::data_is_public`]
8534    // did not exist before this commit — the `(Classification) -> bool`
8535    // derived-nullary-boolean walk over the scalar [`DataClassification`]
8536    // slot's [`DataClassification::is_public`] projection had no
8537    // substrate owner. Post-lift the shape lives at ONE substrate
8538    // primitive and every downstream (the `public-data` fixed tag
8539    // in `tatara-check`, the
8540    // [`crate::ephemeral::EphemeralSpec::data_is_public`] peer,
8541    // future compliance-baseline / audit-log-optional validators
8542    // reading the positive distribution framing) composes against the
8543    // SAME `data_is_public()` shape rather than restating either
8544    // `!self.data_is_restricted()` or the `self.data_classification.is_public()`
8545    // chain at its own callsite. THIRTEENTH occupant of the (parent ×
8546    // derived-nullary-bool) corner and THIRD occupant threading the
8547    // classification-`data_classification` axis — CLOSES the data axis
8548    // on the corner into the FULL binary XOR partition contract
8549    // `data_is_public ⊕ data_is_restricted` sealed on the closed set
8550    // by `data_classification_public_xor_restricted` and composed
8551    // through the parent-composed layer by
8552    // `classification_data_probes_form_binary_xor_partition_over_all`.
8553
8554    /// PER-VARIANT pin — for every [`DataClassification`] variant, a
8555    /// [`Classification`] whose `data_classification` field carries
8556    /// that variant returns `data_is_public()` matching the closed
8557    /// set's own [`DataClassification::is_public`] truth table. Sweep
8558    /// [`DataClassification::ALL`] so a regression that (a) hard-
8559    /// coded the method body to a fixed answer (silently returning
8560    /// `true` regardless of the stored variant, silently promoting
8561    /// every dataset onto the freely-distributable path and shipping
8562    /// PII/PHI/PCI content past every compliance gate), (b) inverted
8563    /// the projection (silently demoting `Public` to access-controlled),
8564    /// or (c) crossed the wires with a sibling classification-axis
8565    /// probe fails HERE at the substrate primitive before drifting
8566    /// through the `public-data` fixed tag or the peer ephemeral
8567    /// surface.
8568    #[test]
8569    fn classification_data_is_public_matches_data_classification_projection() {
8570        for populated in DataClassification::ALL {
8571            let c = Classification::gate_compute_with_axis(populated);
8572            assert_eq!(
8573                c.data_is_public(),
8574                populated.is_public(),
8575                "data_classification={populated:?}: data_is_public() drift from DataClassification::is_public()",
8576            );
8577        }
8578    }
8579
8580    /// GATE-COMPUTE BASELINE — the workspace-baseline
8581    /// [`Classification::gate_compute`] shape carries
8582    /// `data_classification: DataClassification::default()` which
8583    /// defaults to [`DataClassification::Internal`] via `#[default]`,
8584    /// and [`DataClassification::Internal::is_public`] projects
8585    /// `false`, so `data_is_public()` returns `false`. Pins the
8586    /// default-arm short-circuit through ONE layer of `Default`
8587    /// ([`DataClassification`]'s) at ONE narrow site — a regression
8588    /// that promoted [`DataClassification::Public`] to `#[default]`
8589    /// (silently ballooning the workspace's default compliance
8590    /// posture from access-controlled to publicly-distributable), or
8591    /// that wired [`DataClassification::Internal`] to
8592    /// `is_public() = true`, would fail HERE before drifting through
8593    /// every unadorned Process's positive-distribution-framing
8594    /// answer. Mirror-inverted from the sibling
8595    /// `classification_gate_compute_data_is_restricted_is_true`
8596    /// baseline (both walk the SAME defaulted `data_classification`
8597    /// field, so `is_restricted = true` ⇒ `is_public = false` on the
8598    /// closed set's disjoint XOR partition).
8599    #[test]
8600    fn classification_gate_compute_data_is_public_is_false() {
8601        let c = Classification::gate_compute();
8602        assert!(
8603            !c.data_is_public(),
8604            "gate_compute (data_classification=Internal → is_public=false) baseline",
8605        );
8606    }
8607
8608    /// MUTEX pin — [`Classification::data_is_regulated`] AND
8609    /// [`Classification::data_is_public`] are NEVER simultaneously
8610    /// true for ANY [`DataClassification`] variant, since the closed
8611    /// set's own `is_public` / `is_regulated` pair carves it into
8612    /// disjoint buckets sealed by
8613    /// `data_classification_regulated_implies_not_public`. FIRST
8614    /// substrate-composed antisymmetric MUTEX pin against the
8615    /// positive-distribution framing: complementary to
8616    /// `data_is_regulated ⇒ data_is_restricted` on the sibling
8617    /// projection, this seals `data_is_regulated ⇒ ¬data_is_public`
8618    /// at the parent-composed layer, closing the closed-set-internal
8619    /// implication into the substrate primitive's own contract.
8620    #[test]
8621    fn classification_data_is_regulated_and_data_is_public_are_mutex_over_all() {
8622        for populated in DataClassification::ALL {
8623            let c = Classification::gate_compute_with_axis(populated);
8624            assert!(
8625                !(c.data_is_regulated() && c.data_is_public()),
8626                "data_classification={populated:?}: data_is_regulated AND data_is_public both true (mutex violated)",
8627            );
8628        }
8629    }
8630
8631    /// BINARY XOR PARTITION pin — for every [`DataClassification`]
8632    /// variant, EXACTLY ONE of [`Classification::data_is_public`] and
8633    /// [`Classification::data_is_restricted`] returns `true` on a
8634    /// [`Classification`] carrying that variant. CLOSES the data-axis
8635    /// MUTEX pin (`data_is_regulated ⇒ ¬data_is_public`) into the
8636    /// FULL binary XOR partition contract sealed on the closed set
8637    /// by `data_classification_public_xor_restricted` AND now
8638    /// composed through the parent-composed layer as a substrate-wide
8639    /// theorem. Binary counterpart of the ternary XOR partitions
8640    /// sealed on the sibling `point_type` and `substrate` axes by
8641    /// `classification_point_type_probes_form_three_way_xor_partition_over_all`
8642    /// and
8643    /// `classification_substrate_probes_form_three_way_xor_partition_over_all`
8644    /// — where those axes carve the closed set into THREE disjoint
8645    /// buckets, the data axis carves into TWO. Structural twin of
8646    /// the calm-axis binary XOR partition
8647    /// `classification_calm_probes_form_binary_xor_partition_over_all`
8648    /// on the sibling calm axis — both bind a two-bucket (positive-
8649    /// framing/negative-framing) closed-set partition through the
8650    /// parent-composed layer. A regression that crossed the wires
8651    /// between the two parent-composed probes (one probe silently
8652    /// composing the wrong closed-set arm) fails HERE rather than at
8653    /// every downstream consumer that trusts the two probes partition
8654    /// the data slot into disjoint buckets whose union covers every
8655    /// variant.
8656    #[test]
8657    fn classification_data_probes_form_binary_xor_partition_over_all() {
8658        for populated in DataClassification::ALL {
8659            let c = Classification::gate_compute_with_axis(populated);
8660            let buckets = [c.data_is_public(), c.data_is_restricted()];
8661            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
8662            assert_eq!(
8663                hits, 1,
8664                "data_classification={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
8665            );
8666        }
8667    }
8668
8669    // ── Classification::direction_prefers_lower substrate pins ──────
8670    //
8671    // Fail-before-pass-after granularity:
8672    // [`Classification::direction_prefers_lower`] did not exist before
8673    // this commit — the `(Classification) -> bool` derived-nullary-
8674    // boolean walk over the [`Horizon::direction`] slot's
8675    // [`OptimizationDirection::prefers_lower`] projection had no
8676    // substrate owner. Post-lift the shape lives at ONE substrate
8677    // primitive and every downstream (the `prefers-lower-direction`
8678    // fixed tag in `tatara-check`, the
8679    // [`crate::ephemeral::EphemeralSpec::direction_prefers_lower`]
8680    // peer, future asymptotic-health rate-window / regression-detector
8681    // evaluators keying on the optimization-polarity) composes against
8682    // the SAME `direction_prefers_lower()` shape rather than restating
8683    // the `self.horizon.direction.unwrap_or_default().prefers_lower()`
8684    // chain at its own callsite. FOURTEENTH occupant of the (parent ×
8685    // derived-nullary-bool) corner and FIRST occupant threading the
8686    // classification-`horizon.direction` axis — opens the SIXTH
8687    // classification axis into the fixed-tag algebra.
8688
8689    /// PER-VARIANT pin — for every [`OptimizationDirection`] variant, a
8690    /// [`Classification`] whose `horizon.direction` slot carries
8691    /// `Some(variant)` returns `direction_prefers_lower()` matching
8692    /// the closed set's own [`OptimizationDirection::prefers_lower`]
8693    /// truth table. Sweep [`OptimizationDirection::ALL`] so a regression
8694    /// that (a) hard-coded the method body to a fixed answer (silently
8695    /// returning `true` regardless of the stored variant, silently
8696    /// keeping every Process on the lower-is-better path and inverting
8697    /// every rate-window evaluator that expected Maximize polarity),
8698    /// (b) inverted the projection (silently promoting `Maximize` to
8699    /// "prefers lower"), (c) dropped the `.unwrap_or_default()` hop
8700    /// (defaulting a `None` slot to a fixed `false` rather than the
8701    /// closed-set-level `Minimize.prefers_lower() = true`), or
8702    /// (d) crossed the wires with a sibling classification-axis probe
8703    /// fails HERE at the substrate primitive before drifting through
8704    /// the `prefers-lower-direction` fixed tag or the peer ephemeral
8705    /// surface.
8706    #[test]
8707    fn classification_direction_prefers_lower_matches_optimization_direction_projection() {
8708        for populated in OptimizationDirection::ALL {
8709            let c = Classification::gate_compute_with_axis(populated);
8710            assert_eq!(
8711                c.direction_prefers_lower(),
8712                populated.prefers_lower(),
8713                "horizon.direction={populated:?}: direction_prefers_lower() drift from OptimizationDirection::prefers_lower()",
8714            );
8715        }
8716    }
8717
8718    /// GATE-COMPUTE BASELINE — the workspace-baseline
8719    /// [`Classification::gate_compute`] shape carries
8720    /// `horizon: Horizon::default()` whose `direction` field is `None`,
8721    /// so `self.horizon.direction.unwrap_or_default()` defaults to
8722    /// [`OptimizationDirection::Minimize`] via `#[default]`, and
8723    /// [`OptimizationDirection::Minimize::prefers_lower`] projects
8724    /// `true`, so `direction_prefers_lower()` returns `true`. Pins the
8725    /// default-arm short-circuit through TWO layers of `Default`
8726    /// ([`Horizon::default`] → `direction: None`; then
8727    /// [`OptimizationDirection::default = Minimize`]) at ONE narrow
8728    /// site — a regression that promoted [`OptimizationDirection::Maximize`]
8729    /// to `#[default]` (silently flipping every unadorned Process's
8730    /// rate-window evaluator polarity), that wired `Minimize` to
8731    /// `prefers_lower() = false`, or that dropped the
8732    /// `.unwrap_or_default()` hop (silently defaulting `None` to
8733    /// `false` rather than to the closed-set-level `Minimize` baseline),
8734    /// would fail HERE before drifting through every unadorned Process's
8735    /// optimization-polarity answer.
8736    #[test]
8737    fn classification_gate_compute_direction_prefers_lower_is_true() {
8738        let c = Classification::gate_compute();
8739        assert!(
8740            c.direction_prefers_lower(),
8741            "gate_compute (horizon.direction=None → unwrap_or_default=Minimize → prefers_lower=true) baseline",
8742        );
8743    }
8744
8745    // ── Classification::direction_prefers_higher substrate pins ─────
8746    //
8747    // Fail-before-pass-after granularity:
8748    // [`Classification::direction_prefers_higher`] did not exist before
8749    // this commit — the positive higher-is-better framing peer of
8750    // [`Classification::direction_prefers_lower`] had no substrate
8751    // owner. Post-lift the shape lives at ONE substrate primitive and
8752    // every downstream (the `prefers-higher-direction` fixed tag in
8753    // `tatara-check`, the
8754    // [`crate::ephemeral::EphemeralSpec::direction_prefers_higher`]
8755    // peer, future asymptotic-health rate-window / regression-detector
8756    // evaluators keying on the higher-is-better polarity) composes
8757    // against the SAME `direction_prefers_higher()` shape rather than
8758    // restating either `!self.direction_prefers_lower()` or the
8759    // `self.horizon.direction.unwrap_or_default().prefers_higher()`
8760    // chain at its own callsite. FIFTEENTH occupant of the (parent ×
8761    // derived-nullary-bool) corner and SECOND occupant threading the
8762    // classification-`horizon.direction` axis — CLOSES the axis on the
8763    // corner into the FULL binary XOR partition contract
8764    // `direction_prefers_lower ⊕ direction_prefers_higher` sealed on
8765    // the closed set by
8766    // `optimization_direction_prefers_lower_xor_prefers_higher` and
8767    // composed through the parent-composed layer by
8768    // `classification_direction_probes_form_binary_xor_partition_over_all`.
8769    // ALL SIX classification axes (horizon, calm, data, point,
8770    // substrate, optimization-direction) now have their partitions
8771    // closed at the corner.
8772
8773    /// PER-VARIANT pin — for every [`OptimizationDirection`] variant, a
8774    /// [`Classification`] whose `horizon.direction` slot carries
8775    /// `Some(variant)` returns `direction_prefers_higher()` matching
8776    /// the closed set's own [`OptimizationDirection::prefers_higher`]
8777    /// truth table. Sweep [`OptimizationDirection::ALL`] so a
8778    /// regression that (a) hard-coded the method body to a fixed
8779    /// answer (silently returning `false` regardless of the stored
8780    /// variant, silently keeping every Process on the lower-is-better
8781    /// path and inverting every rate-window evaluator that expected
8782    /// Maximize polarity), (b) inverted the projection (silently
8783    /// promoting `Minimize` to "prefers higher"), (c) dropped the
8784    /// `.unwrap_or_default()` hop (defaulting a `None` slot to a
8785    /// fixed `true` rather than the closed-set-level
8786    /// `Minimize.prefers_higher() = false`), or (d) crossed the wires
8787    /// with a sibling classification-axis probe fails HERE at the
8788    /// substrate primitive before drifting through the
8789    /// `prefers-higher-direction` fixed tag or the peer ephemeral
8790    /// surface.
8791    #[test]
8792    fn classification_direction_prefers_higher_matches_optimization_direction_projection() {
8793        for populated in OptimizationDirection::ALL {
8794            let c = Classification::gate_compute_with_axis(populated);
8795            assert_eq!(
8796                c.direction_prefers_higher(),
8797                populated.prefers_higher(),
8798                "horizon.direction={populated:?}: direction_prefers_higher() drift from OptimizationDirection::prefers_higher()",
8799            );
8800        }
8801    }
8802
8803    /// GATE-COMPUTE BASELINE — the workspace-baseline
8804    /// [`Classification::gate_compute`] shape carries
8805    /// `horizon: Horizon::default()` whose `direction` field is `None`,
8806    /// so `self.horizon.direction.unwrap_or_default()` defaults to
8807    /// [`OptimizationDirection::Minimize`] via `#[default]`, and
8808    /// [`OptimizationDirection::Minimize::prefers_higher`] projects
8809    /// `false`, so `direction_prefers_higher()` returns `false`. Pins
8810    /// the default-arm short-circuit through TWO layers of `Default`
8811    /// ([`Horizon::default`] → `direction: None`; then
8812    /// [`OptimizationDirection::default = Minimize`]) at ONE narrow
8813    /// site — a regression that promoted [`OptimizationDirection::Maximize`]
8814    /// to `#[default]` (silently flipping every unadorned Process's
8815    /// rate-window evaluator polarity onto the higher-is-better path),
8816    /// that wired `Minimize` to `prefers_higher() = true`, or that
8817    /// dropped the `.unwrap_or_default()` hop (silently defaulting
8818    /// `None` to `true` rather than the closed-set-level `Minimize`
8819    /// baseline) would fail HERE before drifting through every
8820    /// unadorned Process's optimization-polarity answer. Mirror-
8821    /// inverted from the sibling
8822    /// `classification_gate_compute_direction_prefers_lower_is_true`
8823    /// baseline (both walk the SAME defaulted `horizon.direction`
8824    /// slot, so `prefers_lower = true` ⇒ `prefers_higher = false` on
8825    /// the closed set's disjoint XOR partition).
8826    #[test]
8827    fn classification_gate_compute_direction_prefers_higher_is_false() {
8828        let c = Classification::gate_compute();
8829        assert!(
8830            !c.direction_prefers_higher(),
8831            "gate_compute (horizon.direction=None → unwrap_or_default=Minimize → prefers_higher=false) baseline",
8832        );
8833    }
8834
8835    /// MUTEX pin — [`Classification::direction_prefers_lower`] AND
8836    /// [`Classification::direction_prefers_higher`] are NEVER
8837    /// simultaneously true for ANY [`OptimizationDirection`] variant,
8838    /// since the closed set's own `prefers_lower` / `prefers_higher`
8839    /// pair carves it into disjoint buckets sealed by
8840    /// `optimization_direction_prefers_lower_xor_prefers_higher`.
8841    /// Substrate-composed antisymmetric MUTEX pin against the
8842    /// positive higher-is-better framing peer at the parent-composed
8843    /// layer.
8844    #[test]
8845    fn classification_direction_prefers_lower_and_prefers_higher_are_mutex_over_all() {
8846        for populated in OptimizationDirection::ALL {
8847            let c = Classification::gate_compute_with_axis(populated);
8848            assert!(
8849                !(c.direction_prefers_lower() && c.direction_prefers_higher()),
8850                "horizon.direction={populated:?}: direction_prefers_lower AND direction_prefers_higher both true (mutex violated)",
8851            );
8852        }
8853    }
8854
8855    /// BINARY XOR PARTITION pin — for every [`OptimizationDirection`]
8856    /// variant, EXACTLY ONE of [`Classification::direction_prefers_lower`]
8857    /// and [`Classification::direction_prefers_higher`] returns `true`
8858    /// on a [`Classification`] carrying that variant on its
8859    /// `horizon.direction` slot. CLOSES the optimization-direction
8860    /// axis into the FULL binary XOR partition contract sealed on the
8861    /// closed set by
8862    /// `optimization_direction_prefers_lower_xor_prefers_higher` and
8863    /// composed through the parent-composed layer as a substrate-wide
8864    /// theorem — the SIXTH (and final) classification axis to reach
8865    /// the parent-composed binary XOR partition landmark at this
8866    /// corner. Structural twin of the calm-axis binary XOR partition
8867    /// `classification_calm_probes_form_binary_xor_partition_over_all`
8868    /// and the data-axis binary XOR partition
8869    /// `classification_data_probes_form_binary_xor_partition_over_all`
8870    /// on the sibling calm + data axes — all three binary XOR
8871    /// partitions publish their two derived-nullary-bool projections
8872    /// as complementary XOR pairs at ONE site each so the axis carves
8873    /// into disjoint buckets by construction. A regression that
8874    /// crossed the wires between the two parent-composed probes (one
8875    /// probe silently composing the wrong closed-set arm) fails HERE
8876    /// rather than at every downstream consumer that trusts the two
8877    /// probes partition the direction slot into disjoint buckets
8878    /// whose union covers every variant.
8879    #[test]
8880    fn classification_direction_probes_form_binary_xor_partition_over_all() {
8881        for populated in OptimizationDirection::ALL {
8882            let c = Classification::gate_compute_with_axis(populated);
8883            let buckets = [c.direction_prefers_lower(), c.direction_prefers_higher()];
8884            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
8885            assert_eq!(
8886                hits, 1,
8887                "horizon.direction={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
8888            );
8889        }
8890    }
8891
8892    // ── Classification::input_arity_is_one / input_arity_is_many
8893    //    substrate pins ─────────────────────────────────────────────────
8894    //
8895    // Fail-before-pass-after granularity:
8896    // [`Classification::input_arity_is_one`] and
8897    // [`Classification::input_arity_is_many`] did not exist before this
8898    // commit — the input-arity axis, previously reachable only through
8899    // the parameterized [`Classification::has_input_arity`] probe, had
8900    // no derived-nullary-bool corner occupant. Post-lift the two
8901    // shapes live at ONE substrate primitive each and every future
8902    // downstream (the `single-input-arity` / `multi-input-arity` fixed
8903    // tags in `tatara-check`, DAG composition validators, an ephemeral
8904    // surface peer through [`crate::ephemeral::EphemeralSpec::resolved_classification`])
8905    // composes against the SAME shape rather than restating either
8906    // `self.point_type.input_arity().is_one()` or
8907    // `self.has_input_arity(Arity::One)` at its own callsite.
8908    // SIXTEENTH + SEVENTEENTH occupants of the (parent × derived-
8909    // nullary-bool) corner and FIRST + SECOND occupants threading the
8910    // classification-`point_type`-derived input-arity axis — CLOSE the
8911    // SEVENTH classification axis into the FULL binary XOR partition
8912    // contract `input_arity_is_one ⊕ input_arity_is_many` sealed on
8913    // the closed set by `arity_is_one_xor_is_many_over_all` and
8914    // composed through the parent-composed layer by
8915    // `classification_input_arity_probes_form_binary_xor_partition_over_all`.
8916
8917    /// PER-VARIANT pin — for every [`ConvergencePointType`] variant, a
8918    /// [`Classification`] whose `point_type` slot carries that variant
8919    /// returns `input_arity_is_one()` matching the closed set's own
8920    /// [`ConvergencePointType::input_arity`] projection composed with
8921    /// [`Arity::is_one`]. Sweep [`ConvergencePointType::ALL`] so a
8922    /// regression that (a) hard-coded the method body to a fixed
8923    /// answer, (b) inverted the projection (silently promoting the
8924    /// multi-input variants to "single-input"), (c) crossed the wires
8925    /// with [`ConvergencePointType::output_arity`] (which disagrees
8926    /// on the four `Fork | Broadcast | Join | Gate | Select | Reduce`
8927    /// arms), or (d) dropped the `.is_one()` hop (silently returning
8928    /// the raw [`Arity`] variant discriminant) fails HERE before
8929    /// drifting through every future downstream that trusts the
8930    /// derived-nullary shape.
8931    #[test]
8932    fn classification_input_arity_is_one_matches_input_arity_projection() {
8933        for kind in ConvergencePointType::ALL {
8934            let mut c = Classification::gate_compute();
8935            c.point_type = kind;
8936            assert_eq!(
8937                c.input_arity_is_one(),
8938                kind.input_arity().is_one(),
8939                "point_type={kind:?}: input_arity_is_one() drift from ConvergencePointType::input_arity().is_one()",
8940            );
8941        }
8942    }
8943
8944    /// PER-VARIANT pin — antisymmetric peer of the sibling
8945    /// `classification_input_arity_is_one_matches_input_arity_projection`.
8946    /// For every [`ConvergencePointType`] variant, a
8947    /// [`Classification`] whose `point_type` slot carries that variant
8948    /// returns `input_arity_is_many()` matching
8949    /// [`ConvergencePointType::input_arity`] composed with
8950    /// [`Arity::is_many`]. Regressions matching the sibling
8951    /// per-variant pin's shape fail HERE for the multi-input side of
8952    /// the axis.
8953    #[test]
8954    fn classification_input_arity_is_many_matches_input_arity_projection() {
8955        for kind in ConvergencePointType::ALL {
8956            let mut c = Classification::gate_compute();
8957            c.point_type = kind;
8958            assert_eq!(
8959                c.input_arity_is_many(),
8960                kind.input_arity().is_many(),
8961                "point_type={kind:?}: input_arity_is_many() drift from ConvergencePointType::input_arity().is_many()",
8962            );
8963        }
8964    }
8965
8966    /// GATE-COMPUTE BASELINE — the workspace-baseline
8967    /// [`Classification::gate_compute`] carries `point_type: Gate`;
8968    /// [`ConvergencePointType::Gate::input_arity`] projects to
8969    /// [`Arity::Many`], so `input_arity_is_one()` returns `false` on
8970    /// the baseline. Pins the closed-set-driven default arm at ONE
8971    /// narrow site — a regression that promoted a different
8972    /// [`ConvergencePointType`] variant to the workspace-wide
8973    /// baseline, that flipped `Gate.input_arity()` from `Many` to
8974    /// `One`, or that inverted the `is_one()` projection would fail
8975    /// HERE before drifting through every unadorned Process's
8976    /// input-arity answer.
8977    #[test]
8978    fn classification_gate_compute_input_arity_is_one_is_false() {
8979        let c = Classification::gate_compute();
8980        assert!(
8981            !c.input_arity_is_one(),
8982            "gate_compute (point_type=Gate → input_arity=Many → is_one=false) baseline",
8983        );
8984    }
8985
8986    /// GATE-COMPUTE BASELINE — the antisymmetric mirror of the
8987    /// sibling `_input_arity_is_one_is_false` pin: `Gate.input_arity()
8988    /// = Many`, so `input_arity_is_many()` returns `true` on the
8989    /// baseline. Together with the sibling pin the two seal the
8990    /// input-arity slot's default-arm answer on the workspace-wide
8991    /// baseline as a binary XOR partition — a regression breaking
8992    /// either bucket's default-arm answer fails HERE.
8993    #[test]
8994    fn classification_gate_compute_input_arity_is_many_is_true() {
8995        let c = Classification::gate_compute();
8996        assert!(
8997            c.input_arity_is_many(),
8998            "gate_compute (point_type=Gate → input_arity=Many → is_many=true) baseline",
8999        );
9000    }
9001
9002    /// SUBSTRATE-COMPOSED MUTEX pin — for every
9003    /// [`ConvergencePointType`] variant, both predicates are NEVER
9004    /// simultaneously `true` on a [`Classification`] carrying that
9005    /// variant on its `point_type` slot. A regression that broke the
9006    /// disjointness (either predicate silently answering `true` for
9007    /// both single AND multi input variants) fails HERE.
9008    #[test]
9009    fn classification_input_arity_is_one_and_is_many_are_mutex_over_all() {
9010        for kind in ConvergencePointType::ALL {
9011            let mut c = Classification::gate_compute();
9012            c.point_type = kind;
9013            assert!(
9014                !(c.input_arity_is_one() && c.input_arity_is_many()),
9015                "point_type={kind:?}: input_arity_is_one AND input_arity_is_many both true (mutex violated)",
9016            );
9017        }
9018    }
9019
9020    /// BINARY XOR PARTITION pin — for every [`ConvergencePointType`]
9021    /// variant, EXACTLY ONE of [`Classification::input_arity_is_one`]
9022    /// and [`Classification::input_arity_is_many`] returns `true` on
9023    /// a [`Classification`] carrying that variant on its `point_type`
9024    /// slot. CLOSES the input-arity axis (the SEVENTH classification
9025    /// axis) into the FULL binary XOR partition contract sealed on
9026    /// the closed set by `arity_is_one_xor_is_many_over_all` and
9027    /// composed through the parent-composed layer as a substrate-wide
9028    /// theorem. Structural twin of the calm-axis binary XOR partition
9029    /// (`classification_calm_probes_form_binary_xor_partition_over_all`),
9030    /// the data-axis binary XOR partition
9031    /// (`classification_data_probes_form_binary_xor_partition_over_all`),
9032    /// and the optimization-direction-axis binary XOR partition
9033    /// (`classification_direction_probes_form_binary_xor_partition_over_all`)
9034    /// on the sibling axes — all four binary XOR partitions publish
9035    /// their two derived-nullary-bool projections as complementary
9036    /// XOR pairs at ONE site each so the axis carves into disjoint
9037    /// buckets by construction. A regression that crossed the wires
9038    /// between the two parent-composed probes (one probe silently
9039    /// composing the wrong closed-set arm) fails HERE rather than at
9040    /// every future downstream consumer that trusts the two probes
9041    /// partition the input-arity projection into disjoint buckets
9042    /// whose union covers every [`ConvergencePointType`] variant.
9043    #[test]
9044    fn classification_input_arity_probes_form_binary_xor_partition_over_all() {
9045        for kind in ConvergencePointType::ALL {
9046            let mut c = Classification::gate_compute();
9047            c.point_type = kind;
9048            let buckets = [c.input_arity_is_one(), c.input_arity_is_many()];
9049            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
9050            assert_eq!(
9051                hits, 1,
9052                "point_type={kind:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
9053            );
9054        }
9055    }
9056
9057    // ── Classification::output_arity_is_one / output_arity_is_many
9058    //    substrate pins ─────────────────────────────────────────────────
9059    //
9060    // Fail-before-pass-after granularity:
9061    // [`Classification::output_arity_is_one`] and
9062    // [`Classification::output_arity_is_many`] did not exist before this
9063    // commit — the output-arity axis, previously reachable only through
9064    // the parameterized [`Classification::has_output_arity`] probe, had
9065    // no derived-nullary-bool corner occupant. Post-lift the two shapes
9066    // live at ONE substrate primitive each and every future downstream
9067    // (the `single-output-arity` / `multi-output-arity` fixed tags in
9068    // `tatara-check`, DAG composition validators, an ephemeral surface
9069    // peer through
9070    // [`crate::ephemeral::EphemeralSpec::resolved_classification`])
9071    // composes against the SAME shape rather than restating either
9072    // `self.point_type.output_arity().is_one()` or
9073    // `self.has_output_arity(Arity::One)` at its own callsite.
9074    // EIGHTEENTH + NINETEENTH occupants of the (parent × derived-
9075    // nullary-bool) corner and FIRST + SECOND occupants threading the
9076    // classification-`point_type`-derived output-arity axis — CLOSE the
9077    // EIGHTH classification axis into the FULL binary XOR partition
9078    // contract `output_arity_is_one ⊕ output_arity_is_many` sealed on
9079    // the closed set by `arity_is_one_xor_is_many_over_all` and
9080    // composed through the parent-composed layer by
9081    // `classification_output_arity_probes_form_binary_xor_partition_over_all`.
9082
9083    /// PER-VARIANT pin — for every [`ConvergencePointType`] variant, a
9084    /// [`Classification`] whose `point_type` slot carries that variant
9085    /// returns `output_arity_is_one()` matching the closed set's own
9086    /// [`ConvergencePointType::output_arity`] projection composed with
9087    /// [`Arity::is_one`]. Sweep [`ConvergencePointType::ALL`] so a
9088    /// regression that (a) hard-coded the method body to a fixed
9089    /// answer, (b) inverted the projection (silently demoting the
9090    /// multi-output variants `Fork | Broadcast` into the single-output
9091    /// bucket), (c) crossed the wires with
9092    /// [`ConvergencePointType::input_arity`] (which disagrees on the
9093    /// six `Fork | Broadcast | Join | Gate | Select | Reduce` arms —
9094    /// six of eight variants), or (d) dropped the `.is_one()` hop
9095    /// (silently returning the raw [`Arity`] variant discriminant)
9096    /// fails HERE before drifting through every future downstream
9097    /// that trusts the derived-nullary shape.
9098    #[test]
9099    fn classification_output_arity_is_one_matches_output_arity_projection() {
9100        for kind in ConvergencePointType::ALL {
9101            let mut c = Classification::gate_compute();
9102            c.point_type = kind;
9103            assert_eq!(
9104                c.output_arity_is_one(),
9105                kind.output_arity().is_one(),
9106                "point_type={kind:?}: output_arity_is_one() drift from ConvergencePointType::output_arity().is_one()",
9107            );
9108        }
9109    }
9110
9111    /// PER-VARIANT pin — antisymmetric peer of the sibling
9112    /// `classification_output_arity_is_one_matches_output_arity_projection`.
9113    /// For every [`ConvergencePointType`] variant, a
9114    /// [`Classification`] whose `point_type` slot carries that variant
9115    /// returns `output_arity_is_many()` matching
9116    /// [`ConvergencePointType::output_arity`] composed with
9117    /// [`Arity::is_many`]. Regressions matching the sibling per-variant
9118    /// pin's shape fail HERE for the multi-output side of the axis.
9119    #[test]
9120    fn classification_output_arity_is_many_matches_output_arity_projection() {
9121        for kind in ConvergencePointType::ALL {
9122            let mut c = Classification::gate_compute();
9123            c.point_type = kind;
9124            assert_eq!(
9125                c.output_arity_is_many(),
9126                kind.output_arity().is_many(),
9127                "point_type={kind:?}: output_arity_is_many() drift from ConvergencePointType::output_arity().is_many()",
9128            );
9129        }
9130    }
9131
9132    /// GATE-COMPUTE BASELINE — the workspace-baseline
9133    /// [`Classification::gate_compute`] carries `point_type: Gate`;
9134    /// [`ConvergencePointType::Gate::output_arity`] projects to
9135    /// [`Arity::One`], so `output_arity_is_one()` returns `true` on
9136    /// the baseline. Pins the closed-set-driven default arm at ONE
9137    /// narrow site — a regression that promoted a different
9138    /// [`ConvergencePointType`] variant to the workspace-wide
9139    /// baseline, that flipped `Gate.output_arity()` from `One` to
9140    /// `Many`, or that inverted the `is_one()` projection would fail
9141    /// HERE before drifting through every unadorned Process's
9142    /// output-arity answer. NOTE the workspace-baseline answer FLIPS
9143    /// between the input-arity and output-arity axes on the exact
9144    /// same baseline: `input_arity_is_one` is `false` on
9145    /// `gate_compute` (`Gate.input_arity() = Many`), but
9146    /// `output_arity_is_one` is `true` — direct evidence the two axes
9147    /// carve the closed set into structurally different partitions.
9148    #[test]
9149    fn classification_gate_compute_output_arity_is_one_is_true() {
9150        let c = Classification::gate_compute();
9151        assert!(
9152            c.output_arity_is_one(),
9153            "gate_compute (point_type=Gate → output_arity=One → is_one=true) baseline",
9154        );
9155    }
9156
9157    /// GATE-COMPUTE BASELINE — the antisymmetric mirror of the sibling
9158    /// `_output_arity_is_one_is_true` pin: `Gate.output_arity() = One`,
9159    /// so `output_arity_is_many()` returns `false` on the baseline.
9160    /// Together with the sibling pin the two seal the output-arity
9161    /// slot's default-arm answer on the workspace-wide baseline as a
9162    /// binary XOR partition — a regression breaking either bucket's
9163    /// default-arm answer fails HERE.
9164    #[test]
9165    fn classification_gate_compute_output_arity_is_many_is_false() {
9166        let c = Classification::gate_compute();
9167        assert!(
9168            !c.output_arity_is_many(),
9169            "gate_compute (point_type=Gate → output_arity=One → is_many=false) baseline",
9170        );
9171    }
9172
9173    /// SUBSTRATE-COMPOSED MUTEX pin — for every
9174    /// [`ConvergencePointType`] variant, both predicates are NEVER
9175    /// simultaneously `true` on a [`Classification`] carrying that
9176    /// variant on its `point_type` slot. A regression that broke the
9177    /// disjointness (either predicate silently answering `true` for
9178    /// both single AND multi output variants) fails HERE.
9179    #[test]
9180    fn classification_output_arity_is_one_and_is_many_are_mutex_over_all() {
9181        for kind in ConvergencePointType::ALL {
9182            let mut c = Classification::gate_compute();
9183            c.point_type = kind;
9184            assert!(
9185                !(c.output_arity_is_one() && c.output_arity_is_many()),
9186                "point_type={kind:?}: output_arity_is_one AND output_arity_is_many both true (mutex violated)",
9187            );
9188        }
9189    }
9190
9191    /// BINARY XOR PARTITION pin — for every [`ConvergencePointType`]
9192    /// variant, EXACTLY ONE of [`Classification::output_arity_is_one`]
9193    /// and [`Classification::output_arity_is_many`] returns `true` on
9194    /// a [`Classification`] carrying that variant on its `point_type`
9195    /// slot. CLOSES the output-arity axis (the EIGHTH classification
9196    /// axis) into the FULL binary XOR partition contract sealed on
9197    /// the closed set by `arity_is_one_xor_is_many_over_all` and
9198    /// composed through the parent-composed layer as a substrate-wide
9199    /// theorem. Structural twin of the input-arity binary XOR partition
9200    /// (`classification_input_arity_probes_form_binary_xor_partition_over_all`),
9201    /// the calm-axis binary XOR partition
9202    /// (`classification_calm_probes_form_binary_xor_partition_over_all`),
9203    /// the data-axis binary XOR partition
9204    /// (`classification_data_probes_form_binary_xor_partition_over_all`),
9205    /// and the optimization-direction-axis binary XOR partition
9206    /// (`classification_direction_probes_form_binary_xor_partition_over_all`)
9207    /// on the sibling axes — all five binary XOR partitions publish
9208    /// their two derived-nullary-bool projections as complementary
9209    /// XOR pairs at ONE site each so the axis carves into disjoint
9210    /// buckets by construction. A regression that crossed the wires
9211    /// between the two parent-composed probes (one probe silently
9212    /// composing the wrong closed-set arm) fails HERE rather than at
9213    /// every future downstream consumer that trusts the two probes
9214    /// partition the output-arity projection into disjoint buckets
9215    /// whose union covers every [`ConvergencePointType`] variant.
9216    #[test]
9217    fn classification_output_arity_probes_form_binary_xor_partition_over_all() {
9218        for kind in ConvergencePointType::ALL {
9219            let mut c = Classification::gate_compute();
9220            c.point_type = kind;
9221            let buckets = [c.output_arity_is_one(), c.output_arity_is_many()];
9222            let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
9223            assert_eq!(
9224                hits, 1,
9225                "point_type={kind:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
9226            );
9227        }
9228    }
9229
9230    /// DISTINCTNESS pin — the input-arity and output-arity axes carve
9231    /// the eight-variant [`ConvergencePointType`] closed set into
9232    /// DISTINCT partitions. Six of the eight variants disagree between
9233    /// [`Classification::input_arity_is_one`] and
9234    /// [`Classification::output_arity_is_one`] (the six non-endomorphic
9235    /// variants `Fork | Broadcast | Join | Gate | Select | Reduce`
9236    /// — the four multi-input-single-output arms and the two
9237    /// single-input-multi-output arms), and only the two endomorphic
9238    /// variants (`Transform | Observe` — both `(One, One)`) agree.
9239    /// Pins the axis-distinctness invariant at ONE narrow site — a
9240    /// regression that (a) collapsed the two axes onto the same
9241    /// projection (silently reading `output_arity` as an alias for
9242    /// `input_arity`), (b) copy-pasted `input_arity_is_one`'s body
9243    /// verbatim onto `output_arity_is_one`, or (c) crossed the
9244    /// projection wires between the sibling `is_one` / `is_many`
9245    /// closed-set predicates would fail HERE by shrinking the six-arm
9246    /// disagreement to zero (identical axes) rather than at every
9247    /// future downstream that trusts the two axes name distinct
9248    /// closed-set partitions. Structural anchor for the compounding
9249    /// insight: opening a SECOND derived-typed-projection axis
9250    /// (`ConvergencePointType::output_arity`) on the corner is
9251    /// substantive precisely because it disagrees on 75% of the
9252    /// closed set with the FIRST derived-typed-projection axis
9253    /// (`ConvergencePointType::input_arity`).
9254    #[test]
9255    fn classification_input_arity_and_output_arity_disagree_on_six_of_eight_variants() {
9256        let mut disagreements = 0u32;
9257        for kind in ConvergencePointType::ALL {
9258            let mut c = Classification::gate_compute();
9259            c.point_type = kind;
9260            if c.input_arity_is_one() != c.output_arity_is_one() {
9261                disagreements += 1;
9262            }
9263        }
9264        assert_eq!(
9265            disagreements, 6,
9266            "input_arity_is_one and output_arity_is_one must disagree on exactly six of {} ConvergencePointType variants (the six non-endomorphic arms Fork|Broadcast|Join|Gate|Select|Reduce)",
9267            ConvergencePointType::ALL.len(),
9268        );
9269    }
9270}