tatara_process/ephemeral.rs
1//! `EphemeralSpec` — the operator-facing typed surface for ephemeral
2//! Aplicacao installations.
3//!
4//! `EphemeralSpec` is *sugar* on top of `ProcessSpec`. The compounding move
5//! is to keep one wire format (`Process`, the Unix-process CRD) and let
6//! ephemeral envs be a Process with `:intent (:aplicacao …)` +
7//! `:lifetime (:ephemeral …)`. This struct gives that combination a
8//! dedicated `(defephemeral …)` keyword and a typed `From` bridge so
9//! authoring stays first-class without forking the CRD.
10//!
11//! Lisp authoring:
12//! ```lisp
13//! (defephemeral closed-loop-attest
14//! :aplicacao (:chart-ref "oci://ghcr.io/pleme-io/charts/lareira-demo-app"
15//! :version "0.5.5"
16//! :profile "all-in-one"
17//! :values-overlay (:cluster (:name "ephemeral-test-01")
18//! :persistence false))
19//! :ttl "1h"
20//! :teardown OnAttested
21//! :postconditions
22//! ((:kind HelmReleaseReleased
23//! :params (:name "demo-app-consolidated"
24//! :namespace "demo-test"))
25//! (:kind ClosedLoopAuth
26//! :params (:issuer (:service "demo-app-issuer" :port 8080)
27//! :consumer (:service "demo-app-gateway" :port 8000)
28//! :probeImage "ghcr.io/pleme-io/closed-loop-probe:0.1.0"))))
29//! ```
30
31use std::borrow::Cow;
32
33use schemars::JsonSchema;
34use serde::{Deserialize, Serialize};
35use tatara_lisp::DeriveTataraDomain;
36
37use crate::boundary::{Boundary, Condition, ConditionKind, ConditionSliceExt};
38use crate::classification::{
39 Arity, CalmClassification, Classification, ClassificationAxis, ConvergencePointType,
40 DataClassification, HorizonKind, OptimizationDirection, SubstrateType,
41};
42use crate::crd::ProcessSpec;
43use crate::export::{ExportSpec, ExportSpecSliceExt};
44use crate::intent::{AplicacaoIntent, Intent};
45use crate::lifetime::{EphemeralLifetime, Lifetime, TeardownPolicy};
46use crate::phase::ProcessPhase;
47use crate::routing::{RoutingForm, RoutingSpec};
48
49/// `EphemeralSpec` — typed wrapper that authors `(defephemeral …)`.
50///
51/// Lowers to a `ProcessSpec` via `From<EphemeralSpec>` — the bridge is
52/// pure-typed, no string substitution. Defaults to `point_type = Gate`,
53/// `substrate = Compute`, `data_classification = Internal` — every field
54/// can be overridden via the full `(defpoint …)` form when the operator
55/// needs the lower-level surface.
56#[derive(DeriveTataraDomain, Clone, Debug, Serialize, Deserialize, JsonSchema)]
57#[serde(rename_all = "camelCase")]
58#[tatara(keyword = "defephemeral")]
59pub struct EphemeralSpec {
60 /// The Aplicacao chart + profile + overlay to install.
61 pub aplicacao: AplicacaoIntent,
62
63 /// TTL — `humantime` duration (`"1h"`, `"30m"`).
64 #[serde(default = "crate::lifetime::default_ephemeral_ttl")]
65 pub ttl: String,
66
67 /// When the ephemeral Process auto-terminates.
68 #[serde(default)]
69 pub teardown: TeardownPolicy,
70
71 /// Cluster-wide concurrency budget across ephemeral Processes sharing
72 /// the same `:aplicacao :chart-ref`. `0` = no cap.
73 #[serde(default = "crate::lifetime::default_ephemeral_max_concurrent")]
74 pub max_concurrent: u32,
75
76 /// Boundary postconditions evaluated before reaching `Attested`.
77 /// Typically `HelmReleaseReleased` plus one or more `ClosedLoopAuth`
78 /// / `JobAttested` checks for test suites + closed-loop probes.
79 #[serde(default)]
80 pub postconditions: Vec<Condition>,
81
82 /// Optional boundary preconditions (Namespace, Issuer, PullSecret
83 /// readiness etc.).
84 #[serde(default)]
85 pub preconditions: Vec<Condition>,
86
87 /// VERIFY-phase timeout. Empty = controller default.
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub verify_timeout: Option<String>,
90
91 /// Optional Process classification override. When omitted, defaults
92 /// to `Gate / Compute / Internal / Bounded / NonMonotone`.
93 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub classification: Option<Classification>,
95
96 /// Optional parent PID path.
97 #[serde(default, skip_serializing_if = "Option::is_none")]
98 pub parent: Option<String>,
99
100 /// Declared exports — sugar that propagates through to
101 /// `lifetime.ephemeral.exports` on the lowered `ProcessSpec`.
102 /// Default empty = zero-trace ephemeral (nothing survives
103 /// teardown). See [`crate::export`] for the full type.
104 #[serde(default, skip_serializing_if = "Vec::is_empty")]
105 pub exports: Vec<ExportSpec>,
106
107 /// Routing template — DNS + Ingress declarations inherited by
108 /// the materialized `ProcessSpec`. When set on a pool's
109 /// `template`, every member receives the same shape; each
110 /// member's content-hash form differs by its own canonical
111 /// spec (which differs across members by slot index).
112 /// See [`crate::routing`].
113 #[serde(default, skip_serializing_if = "Option::is_none")]
114 pub routing: Option<RoutingSpec>,
115}
116
117// `default_ttl` + `default_max_concurrent` bindings for the two serde
118// `#[serde(default = "…")]` slots above route through the ONE
119// substrate owner [`crate::lifetime::default_ephemeral_ttl`] +
120// [`crate::lifetime::default_ephemeral_max_concurrent`] — peer of
121// the [`EphemeralLifetime`] serde-default slots on the SAME
122// workspace-canonical "ephemeral wire-form defaults" axis.
123// Pre-lift both slots carried their own private
124// `fn default_*` shims that returned bytewise-identical `"1h"` /
125// `1` values as the peer [`EphemeralLifetime`] slots — one of THREE
126// (TTL) and TWO (max-concurrent) restatements past the ★★ PRIME-
127// DIRECTIVE ≥ 2 duplication threshold. See the substrate owner's
128// doc-comment for the full migration rationale.
129
130impl EphemeralSpec {
131 /// True iff at least one [`Condition`] in
132 /// `preconditions ∪ postconditions` carries the given
133 /// [`ConditionKind`] — the peer of
134 /// [`crate::boundary::Boundary::has_condition_kind`] on the
135 /// [`EphemeralSpec`] surface.
136 ///
137 /// # Semantics — byte-identical to [`Boundary::has_condition_kind`]
138 ///
139 /// The two condition vectors are unioned: a caller asking "does this
140 /// ephemeral spec name a `ClosedLoopAuth` predicate anywhere" doesn't
141 /// care whether the operator authored it on the pre- or post-
142 /// condition side. A spec with the given kind on ONLY preconditions
143 /// returns `true`; a spec with the given kind on ONLY postconditions
144 /// returns `true`; a spec with neither returns `false`.
145 ///
146 /// Both halves compose through the SAME slice-level substrate
147 /// primitive [`ConditionSliceExt::has_kind`] that
148 /// [`Boundary::has_condition_kind`] walks — so a regression at the
149 /// per-slice presence probe fails at that primitive's tests rather
150 /// than as silent drift at either struct-level union caller.
151 ///
152 /// # Sibling to [`Boundary::has_condition_kind`]
153 ///
154 /// Same shape, same axis, same body — [`Boundary::has_condition_kind`]
155 /// composes `preconditions ∪ postconditions` on the point-domain
156 /// [`ProcessSpec`]'s nested [`Boundary`] slot;
157 /// [`Self::has_condition_kind`] composes the SAME union on
158 /// [`EphemeralSpec`]'s direct pre/post fields. `EphemeralSpec` has no
159 /// nested [`Boundary`] struct — the pre/post condition vectors are
160 /// stored directly on the sugar-surface type — so a byte-identical
161 /// inherent method here lets the ephemeral require-tag surface in
162 /// `tatara-reconciler::bin::tatara-check` publish a `condition-<kind>`
163 /// closed-set prefix family byte-for-byte symmetrical with the point
164 /// surface's family via [`Boundary::has_condition_kind`].
165 ///
166 /// # Compounding
167 ///
168 /// The ephemeral require-tag classifier composes this primitive with
169 /// the closed-set `FromStr` autoderived on [`ConditionKind`] through
170 /// the `strip_and_classify_prefixed_kind` substrate to publish a
171 /// fifth closed-set-driven prefix family across the workspace-wide
172 /// require-tag algebra (peer of `intent-<kind>` / `lifetime-<kind>` /
173 /// `condition-<kind>` / `must-reach-<kind>` on the point surface). A
174 /// future [`ConditionKind`] variant added to `ALL` reaches BOTH
175 /// surfaces' `condition-<kind>` prefix families through the SAME
176 /// closed-set walk with no per-caller edit — the two-surface
177 /// symmetry means adding a variant on the closed set publishes it in
178 /// lockstep across every downstream consumer.
179 ///
180 /// A future normalization at the presence-probe shape (a widened
181 /// return carrying the matching Condition ref, a debug-build
182 /// assertion on pre/post drift, a fleet-wide warn on redundant
183 /// duplicates) lands at the ONE slice-level substrate primitive
184 /// [`ConditionSliceExt::has_kind`] both this method and
185 /// [`Boundary::has_condition_kind`] compose against — so the two
186 /// struct-level union methods stay symmetric by construction.
187 ///
188 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
189 /// proofs — the union body composes the SAME slice-level substrate
190 /// primitive on both this ephemeral surface and the point-domain
191 /// [`Boundary`] surface). THEORY.md §VI.1 (generation over
192 /// composition — a future [`ConditionKind`] variant added to `ALL`
193 /// reaches both `condition-<kind>` require-tag surfaces mechanically
194 /// through the SAME closed-set walk).
195 #[must_use]
196 pub fn has_condition_kind(&self, kind: ConditionKind) -> bool {
197 self.has_precondition_kind(kind) || self.has_postcondition_kind(kind)
198 }
199
200 /// True iff at least one [`Condition`] in `self.preconditions`
201 /// carries the given [`ConditionKind`] — the precondition-side arm
202 /// of the (precondition, postcondition, condition-union) triad on
203 /// [`EphemeralSpec`], sibling to [`Self::has_postcondition_kind`]
204 /// and half-composition of [`Self::has_condition_kind`].
205 ///
206 /// Thin typed delegate to [`ConditionSliceExt::has_kind`] over
207 /// [`Self::preconditions`]. Peer of
208 /// [`crate::boundary::Boundary::has_precondition_kind`] on the
209 /// point-domain surface — both peers compose against the SAME
210 /// slice-level substrate primitive
211 /// ([`crate::boundary::ConditionSliceExt::has_kind`]) so a
212 /// regression at the per-slice presence probe fails at that
213 /// primitive's tests rather than as silent drift at either
214 /// struct-level half-slice arm.
215 ///
216 /// # Why lift
217 ///
218 /// See [`crate::boundary::Boundary::has_precondition_kind`] for
219 /// the full rationale — the two surfaces (point + ephemeral)
220 /// publish their `precondition-<kind>` / `postcondition-<kind>`
221 /// require-tag prefix families byte-for-byte symmetrical, each
222 /// through its own struct-level half-slice arm. Post-lift the
223 /// (precondition, postcondition, condition-union) triad lives at
224 /// ONE typed algebra surface per struct rather than at a mixed
225 /// (union-arm-via-method, half-slice-arms-via-direct-field-access)
226 /// asymmetry on the ephemeral side.
227 ///
228 /// # Semantics — byte-identical to the point-domain peer
229 ///
230 /// Returns `true` iff `self.preconditions.iter().any(|c| c.kind ==
231 /// kind)`. Ignores `self.postconditions` — an operator who
232 /// authored the kind on ONLY postconditions gets `false` from this
233 /// probe and `true` from [`Self::has_postcondition_kind`]. The two
234 /// half-slice arms partition the (kind, side) matrix exhaustively
235 /// across the four states (kind absent both, pre-only, post-only,
236 /// both).
237 #[must_use]
238 pub fn has_precondition_kind(&self, kind: ConditionKind) -> bool {
239 self.preconditions.has_kind(kind)
240 }
241
242 /// True iff at least one [`Condition`] in `self.postconditions`
243 /// carries the given [`ConditionKind`] — the postcondition-side arm
244 /// of the (precondition, postcondition, condition-union) triad on
245 /// [`EphemeralSpec`], sibling to [`Self::has_precondition_kind`]
246 /// and half-composition of [`Self::has_condition_kind`].
247 ///
248 /// Thin typed delegate to [`ConditionSliceExt::has_kind`] over
249 /// [`Self::postconditions`]. Peer of
250 /// [`crate::boundary::Boundary::has_postcondition_kind`] on the
251 /// point-domain surface. See [`Self::has_precondition_kind`] for
252 /// the full rationale — both half-slice arms share ONE lift
253 /// motivation, ONE fail-before-pass-after composition-law pin, and
254 /// ONE two-surface parity contract with the point-domain
255 /// [`crate::boundary::Boundary`] peer methods.
256 #[must_use]
257 pub fn has_postcondition_kind(&self, kind: ConditionKind) -> bool {
258 self.postconditions.has_kind(kind)
259 }
260
261 /// Returns the first [`Condition`] in
262 /// `preconditions ∪ postconditions` carrying the given
263 /// [`ConditionKind`], searching preconditions first — the peer of
264 /// [`crate::boundary::Boundary::find_condition_kind`] on the
265 /// [`EphemeralSpec`] sugar surface.
266 ///
267 /// # Semantics — byte-identical to [`Boundary::find_condition_kind`]
268 ///
269 /// Walks `self.preconditions` first, then `self.postconditions`:
270 /// a kind authored on BOTH sides returns the precondition-side
271 /// [`Condition`]. Composition law:
272 /// `find_condition_kind(K) == find_precondition_kind(K).or_else(||
273 /// find_postcondition_kind(K))`, pinned as a first-class typed
274 /// invariant. Both halves compose through the SAME slice-level
275 /// substrate primitive [`crate::boundary::ConditionSliceExt::find_kind`]
276 /// that [`Boundary::find_condition_kind`] walks — so a regression
277 /// at the per-slice walk fails at that primitive's tests rather
278 /// than as silent drift at either struct-level widened caller.
279 ///
280 /// # Sibling to [`Self::has_condition_kind`]
281 ///
282 /// Same axis, one refinement wider: `has_condition_kind` collapses
283 /// the return to a `bool` (`find_condition_kind(k).is_some()`);
284 /// this method returns the matching `&Condition` so consumers can
285 /// read [`Condition::params`] at the presence-probe callsite
286 /// without re-walking the two condition vectors. Pinned by the
287 /// composition law
288 /// `has_condition_kind(K) == find_condition_kind(K).is_some()`.
289 ///
290 /// # Compounding
291 ///
292 /// A future diagnostic consumer on the ephemeral surface (an
293 /// operator-facing "closed-loop-auth matched with
294 /// params.probeImage=X" message emitted by the ephemeral require-
295 /// tag classifier, a coherence check on the ephemeral surface that
296 /// verifies "every `ClosedLoopAuth` postcondition carries a non-
297 /// empty `probeImage`", an editor completion listing params-keys
298 /// per present ephemeral kind) reaches for the matching
299 /// [`Condition`] through this ONE method rather than re-walking
300 /// the two vectors at the callsite. Byte-for-byte peer of the
301 /// point-domain widened triad on [`Boundary`], so the two-surface
302 /// parity contract now covers both refinements (bool via has,
303 /// `&Condition` via find) on the condition axis.
304 ///
305 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
306 /// preserves proofs — the widened union body composes the SAME
307 /// slice-level substrate primitive on both this ephemeral surface
308 /// and the point-domain [`Boundary`] surface). THEORY.md §VI.1
309 /// (generation over composition — a future [`ConditionKind`]
310 /// variant added to `ALL` reaches both surfaces' widened triads
311 /// mechanically through the SAME closed-set walk).
312 #[must_use]
313 pub fn find_condition_kind(&self, kind: ConditionKind) -> Option<&Condition> {
314 self.find_precondition_kind(kind)
315 .or_else(|| self.find_postcondition_kind(kind))
316 }
317
318 /// Returns the first [`Condition`] in [`Self::preconditions`]
319 /// carrying the given [`ConditionKind`], or `None` — the
320 /// precondition-side arm of the (precondition, postcondition,
321 /// condition-union) widened triad on [`EphemeralSpec`]. Thin typed
322 /// delegate to [`crate::boundary::ConditionSliceExt::find_kind`]
323 /// over [`Self::preconditions`].
324 ///
325 /// Peer of [`crate::boundary::Boundary::find_precondition_kind`]
326 /// on the point-domain surface — both peers compose against the
327 /// SAME slice-level substrate primitive so a regression at the
328 /// per-slice walk fails at that primitive's tests rather than as
329 /// silent drift at either struct-level widened half-slice arm.
330 /// Byte-identical semantics to [`Self::has_precondition_kind`]
331 /// with a widened `Option<&Condition>` return rather than a
332 /// `bool`.
333 #[must_use]
334 pub fn find_precondition_kind(&self, kind: ConditionKind) -> Option<&Condition> {
335 self.preconditions.find_kind(kind)
336 }
337
338 /// Returns the first [`Condition`] in [`Self::postconditions`]
339 /// carrying the given [`ConditionKind`], or `None` — the
340 /// postcondition-side arm of the (precondition, postcondition,
341 /// condition-union) widened triad on [`EphemeralSpec`]. Thin typed
342 /// delegate to [`crate::boundary::ConditionSliceExt::find_kind`]
343 /// over [`Self::postconditions`].
344 ///
345 /// Peer of [`crate::boundary::Boundary::find_postcondition_kind`]
346 /// on the point-domain surface. See [`Self::find_precondition_kind`]
347 /// for the full rationale — the two methods share ONE lift
348 /// motivation, ONE fail-before-pass-after composition-law pin, and
349 /// ONE two-surface parity contract with the point-domain
350 /// [`crate::boundary::Boundary`] widened peer methods.
351 #[must_use]
352 pub fn find_postcondition_kind(&self, kind: ConditionKind) -> Option<&Condition> {
353 self.postconditions.find_kind(kind)
354 }
355
356 /// Returns an iterator over every [`Condition`] in
357 /// `preconditions ∪ postconditions` carrying the given
358 /// [`ConditionKind`], walking preconditions first — the peer of
359 /// [`crate::boundary::Boundary::iter_condition_kind`] on the
360 /// [`EphemeralSpec`] sugar surface.
361 ///
362 /// # Semantics — byte-identical to [`Boundary::iter_condition_kind`]
363 ///
364 /// Chains [`Self::iter_precondition_kind`] with
365 /// [`Self::iter_postcondition_kind`] via [`Iterator::chain`]:
366 /// yields every precondition-side match in slice order, then
367 /// every postcondition-side match in slice order. Composition
368 /// law:
369 /// `find_condition_kind(K) == iter_condition_kind(K).next()`,
370 /// pinned as a first-class typed invariant. Both halves compose
371 /// through the SAME slice-level substrate primitive
372 /// [`crate::boundary::ConditionSliceExt::iter_kind`] that
373 /// [`Boundary::iter_condition_kind`] chains — so a regression at
374 /// the per-slice walk fails at that primitive's tests rather than
375 /// as silent drift at either struct-level widened caller.
376 ///
377 /// # Sibling to [`Self::find_condition_kind`]
378 ///
379 /// Same axis, one refinement wider: `find_condition_kind`
380 /// collapses the return to the FIRST match; this method yields
381 /// every match across both sides. Byte-for-byte peer of the
382 /// point-domain widened triad on [`Boundary`], so the two-surface
383 /// parity contract now covers three refinements (bool via has,
384 /// `&Condition` via find, `impl Iterator<Item = &Condition>` via
385 /// iter) on the condition axis.
386 ///
387 /// # Compounding
388 ///
389 /// A future ephemeral-surface coherence check that enforces
390 /// "each [`ConditionKind`] appears at most once across
391 /// preconditions ∪ postconditions" reads
392 /// `spec.iter_condition_kind(k).nth(1).is_none()` at ONE call
393 /// site. A future ephemeral require-tag classifier arm that
394 /// counts matches (a hypothetical `condition-count-<kind>` prefix
395 /// family that surfaces multiplicity to the operator) reaches
396 /// this ONE method through `spec.iter_condition_kind(k).count()`.
397 ///
398 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
399 /// preserves proofs — the widened stream body composes the SAME
400 /// slice-level substrate primitive on both this ephemeral surface
401 /// and the point-domain [`Boundary`] surface). THEORY.md §VI.1
402 /// (generation over composition — a future [`ConditionKind`]
403 /// variant added to `ALL` reaches both surfaces' iterator triads
404 /// mechanically through the SAME closed-set walk).
405 pub fn iter_condition_kind(
406 &self,
407 kind: ConditionKind,
408 ) -> std::iter::Chain<crate::boundary::KindMatches<'_>, crate::boundary::KindMatches<'_>> {
409 self.iter_precondition_kind(kind)
410 .chain(self.iter_postcondition_kind(kind))
411 }
412
413 /// Returns an iterator over every [`Condition`] in
414 /// [`Self::preconditions`] carrying the given [`ConditionKind`]
415 /// — the precondition-side arm of the (precondition,
416 /// postcondition, condition-union) iterator triad on
417 /// [`EphemeralSpec`]. Thin typed delegate to
418 /// [`crate::boundary::ConditionSliceExt::iter_kind`] over
419 /// [`Self::preconditions`].
420 ///
421 /// Peer of [`crate::boundary::Boundary::iter_precondition_kind`]
422 /// on the point-domain surface — both peers compose against the
423 /// SAME slice-level substrate primitive so a regression at the
424 /// per-slice walk fails at that primitive's tests rather than as
425 /// silent drift at either struct-level widened half-slice arm.
426 /// Byte-identical semantics to [`Self::find_precondition_kind`]
427 /// with a widened stream return rather than only the first match.
428 pub fn iter_precondition_kind(&self, kind: ConditionKind) -> crate::boundary::KindMatches<'_> {
429 self.preconditions.iter_kind(kind)
430 }
431
432 /// Returns an iterator over every [`Condition`] in
433 /// [`Self::postconditions`] carrying the given [`ConditionKind`]
434 /// — the postcondition-side arm of the (precondition,
435 /// postcondition, condition-union) iterator triad on
436 /// [`EphemeralSpec`]. Thin typed delegate to
437 /// [`crate::boundary::ConditionSliceExt::iter_kind`] over
438 /// [`Self::postconditions`].
439 ///
440 /// Peer of [`crate::boundary::Boundary::iter_postcondition_kind`]
441 /// on the point-domain surface. See
442 /// [`Self::iter_precondition_kind`] for the full rationale — the
443 /// two methods share ONE lift motivation, ONE fail-before-
444 /// pass-after composition-law pin, and ONE two-surface parity
445 /// contract with the point-domain [`crate::boundary::Boundary`]
446 /// widened peer methods.
447 pub fn iter_postcondition_kind(&self, kind: ConditionKind) -> crate::boundary::KindMatches<'_> {
448 self.postconditions.iter_kind(kind)
449 }
450
451 /// Number of [`Condition`]s in `preconditions ∪ postconditions`
452 /// carrying the given [`ConditionKind`] — the peer of
453 /// [`crate::boundary::Boundary::count_condition_kind`] on the
454 /// [`EphemeralSpec`] sugar surface.
455 ///
456 /// # Semantics — byte-identical to [`Boundary::count_condition_kind`]
457 ///
458 /// Composed as
459 /// `count_precondition_kind(k) + count_postcondition_kind(k)` —
460 /// the SUM-composed arm on the presence-probe algebra (distinct
461 /// from `has_condition_kind`'s `||`, `find_condition_kind`'s
462 /// `or_else`, and `iter_condition_kind`'s `Chain`). Composition
463 /// law `count_condition_kind(K) == iter_condition_kind(K).count()`
464 /// pinned as a first-class typed invariant. Both halves compose
465 /// through the SAME slice-level substrate primitive
466 /// [`crate::boundary::ConditionSliceExt::count_kind`] that
467 /// [`Boundary::count_condition_kind`] sums — so a regression at
468 /// the per-slice count fails at that primitive's tests rather
469 /// than as silent drift at either struct-level widened caller.
470 ///
471 /// # Sibling to [`Self::iter_condition_kind`]
472 ///
473 /// Same axis, one refinement lower on the cardinality projection:
474 /// `iter_condition_kind` yields the whole match stream; this
475 /// method collapses that stream to its cardinality. Byte-for-byte
476 /// peer of the point-domain count triad on [`Boundary`], so the
477 /// two-surface parity contract now covers four refinements (bool
478 /// via has, `&Condition` via find, `impl Iterator<Item =
479 /// &Condition>` via iter, `usize` via count) on the condition
480 /// axis.
481 ///
482 /// # Compounding
483 ///
484 /// A future ephemeral-surface coherence check that enforces
485 /// "each [`ConditionKind`] appears at most once across
486 /// preconditions ∪ postconditions" reads
487 /// `spec.count_condition_kind(k) <= 1` at ONE call site. A future
488 /// ephemeral require-tag classifier arm that surfaces multiplicity
489 /// to the operator (a hypothetical `condition-count-<kind>` prefix
490 /// family that publishes the raw cardinality on the ephemeral
491 /// surface, an operator-facing "3 ClosedLoopAuth postconditions
492 /// matched" message) reaches this ONE method rather than restating
493 /// the `.iter_condition_kind(k).count()` chain body at the
494 /// callsite.
495 ///
496 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
497 /// preserves proofs — the scalar cardinality body composes the
498 /// SAME slice-level substrate primitive on both this ephemeral
499 /// surface and the point-domain [`Boundary`] surface). THEORY.md
500 /// §VI.1 (generation over composition — a future
501 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
502 /// count triads mechanically through the SAME closed-set walk).
503 #[must_use]
504 pub fn count_condition_kind(&self, kind: ConditionKind) -> usize {
505 self.count_precondition_kind(kind) + self.count_postcondition_kind(kind)
506 }
507
508 /// Number of [`Condition`]s in [`Self::preconditions`] carrying
509 /// the given [`ConditionKind`] — the precondition-side arm of the
510 /// (precondition, postcondition, condition-union) count triad on
511 /// [`EphemeralSpec`]. Thin typed delegate to
512 /// [`crate::boundary::ConditionSliceExt::count_kind`] over
513 /// [`Self::preconditions`].
514 ///
515 /// Peer of [`crate::boundary::Boundary::count_precondition_kind`]
516 /// on the point-domain surface — both peers compose against the
517 /// SAME slice-level substrate primitive so a regression at the
518 /// per-slice count fails at that primitive's tests rather than as
519 /// silent drift at either struct-level count arm.
520 #[must_use]
521 pub fn count_precondition_kind(&self, kind: ConditionKind) -> usize {
522 self.preconditions.count_kind(kind)
523 }
524
525 /// Number of [`Condition`]s in [`Self::postconditions`] carrying
526 /// the given [`ConditionKind`] — the postcondition-side arm of
527 /// the (precondition, postcondition, condition-union) count triad
528 /// on [`EphemeralSpec`]. Thin typed delegate to
529 /// [`crate::boundary::ConditionSliceExt::count_kind`] over
530 /// [`Self::postconditions`].
531 ///
532 /// Peer of [`crate::boundary::Boundary::count_postcondition_kind`]
533 /// on the point-domain surface. See
534 /// [`Self::count_precondition_kind`] for the full rationale — the
535 /// two methods share ONE lift motivation, ONE fail-before-
536 /// pass-after composition-law pin, and ONE two-surface parity
537 /// contract with the point-domain [`crate::boundary::Boundary`]
538 /// count peer methods.
539 #[must_use]
540 pub fn count_postcondition_kind(&self, kind: ConditionKind) -> usize {
541 self.postconditions.count_kind(kind)
542 }
543
544 /// The set of [`ConditionKind`] variants appearing at least once in
545 /// `preconditions ∪ postconditions`, projected in
546 /// [`ConditionKind::ALL`] order — the peer of
547 /// [`crate::boundary::Boundary::distinct_condition_kinds`] on the
548 /// [`EphemeralSpec`] sugar surface.
549 ///
550 /// # Semantics — byte-identical to [`crate::boundary::Boundary::distinct_condition_kinds`]
551 ///
552 /// Composed as `ConditionKind::ALL.into_iter().filter(|k|
553 /// self.has_condition_kind(*k)).collect()` — the ONE closed-set-
554 /// inversion arm on the presence-probe algebra (distinct in axis
555 /// from the four point-probe arms `has_condition_kind` /
556 /// `find_condition_kind` / `iter_condition_kind` /
557 /// `count_condition_kind` which fix a [`ConditionKind`] and vary
558 /// the return type). Equivalent to the set-union of
559 /// [`Self::distinct_precondition_kinds`] and
560 /// [`Self::distinct_postcondition_kinds`] projected in canonical
561 /// [`ConditionKind::ALL`] order.
562 ///
563 /// # Peer on the point surface — [`crate::boundary::Boundary::distinct_condition_kinds`]
564 ///
565 /// Same signature `(&Self) -> Vec<ConditionKind>`, same closed-set-
566 /// inversion body, on the point-domain [`crate::boundary::Boundary`]
567 /// nested-slot carrier. Both methods compose against the SAME
568 /// slice-level substrate primitive
569 /// [`crate::boundary::ConditionSliceExt::distinct_kinds`] via the
570 /// two-slice union composed through [`Self::has_condition_kind`] —
571 /// a regression at the per-slice walk fails at that primitive's
572 /// tests rather than as silent drift at either struct-level union
573 /// caller.
574 ///
575 /// # Sibling to the four point-probe refinements
576 ///
577 /// FIFTH refinement on the ephemeral-surface presence-probe algebra,
578 /// distinct in axis from the other four. The composition law
579 /// `distinct_condition_kinds().contains(&k) == has_condition_kind(k)`
580 /// for every `k ∈ ConditionKind::ALL` binds the closed-set-inversion
581 /// probe to the point probe at the (precondition, postcondition,
582 /// condition-union) triad. The two-surface parity contract now
583 /// covers FIVE refinements (bool / `&Condition` / `impl Iterator` /
584 /// `usize` / `Vec<ConditionKind>` closed-set-inversion) on the
585 /// condition axis, byte-for-byte peer of the point-domain triad on
586 /// [`crate::boundary::Boundary`].
587 ///
588 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
589 /// proofs — the closed-set-inversion aggregate composes the SAME
590 /// slice-level substrate primitive on both this ephemeral surface
591 /// and the point-domain [`crate::boundary::Boundary`] surface).
592 /// THEORY.md §VI.1 (generation over composition — a future
593 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
594 /// distinct-set triads mechanically through the SAME closed-set
595 /// walk).
596 #[must_use]
597 pub fn distinct_condition_kinds(&self) -> Vec<ConditionKind> {
598 ConditionKind::ALL
599 .into_iter()
600 .filter(|k| self.has_condition_kind(*k))
601 .collect()
602 }
603
604 /// The set of [`ConditionKind`] variants appearing at least once in
605 /// [`Self::preconditions`], projected in [`ConditionKind::ALL`]
606 /// order — the precondition-side arm of the (precondition,
607 /// postcondition, condition-union) distinct-set triad on
608 /// [`EphemeralSpec`]. Thin typed delegate to
609 /// [`crate::boundary::ConditionSliceExt::distinct_kinds`] over
610 /// [`Self::preconditions`].
611 ///
612 /// Peer of [`crate::boundary::Boundary::distinct_precondition_kinds`]
613 /// on the point-domain surface — both peers compose against the
614 /// SAME slice-level substrate primitive so a regression at the
615 /// per-slice closed-set walk fails at that primitive's tests
616 /// rather than as silent drift at either struct-level arm.
617 #[must_use]
618 pub fn distinct_precondition_kinds(&self) -> Vec<ConditionKind> {
619 self.preconditions.distinct_kinds()
620 }
621
622 /// The set of [`ConditionKind`] variants appearing at least once in
623 /// [`Self::postconditions`], projected in [`ConditionKind::ALL`]
624 /// order — the postcondition-side arm of the (precondition,
625 /// postcondition, condition-union) distinct-set triad on
626 /// [`EphemeralSpec`]. Thin typed delegate to
627 /// [`crate::boundary::ConditionSliceExt::distinct_kinds`] over
628 /// [`Self::postconditions`].
629 ///
630 /// Peer of [`crate::boundary::Boundary::distinct_postcondition_kinds`]
631 /// on the point-domain surface. See
632 /// [`Self::distinct_precondition_kinds`] for the full rationale —
633 /// the two methods share ONE lift motivation, ONE fail-before-
634 /// pass-after composition-law pin, and ONE two-surface parity
635 /// contract with the point-domain
636 /// [`crate::boundary::Boundary`] distinct-set peer methods.
637 #[must_use]
638 pub fn distinct_postcondition_kinds(&self) -> Vec<ConditionKind> {
639 self.postconditions.distinct_kinds()
640 }
641
642 /// Zero-allocation iterator peer of [`Self::distinct_condition_kinds`]
643 /// — the condition-union arm of the (precondition, postcondition,
644 /// condition-union) closed-set-inversion iterator triad on
645 /// [`EphemeralSpec`]. Byte-identical to
646 /// [`crate::boundary::Boundary::iter_distinct_condition_kinds`] on the
647 /// point-domain surface. Walks [`ConditionKind::ALL`] in canonical
648 /// order and yields every [`ConditionKind`] appearing at least once in
649 /// `preconditions ∪ postconditions`, WITHOUT materializing an
650 /// intermediate `Vec<ConditionKind>`.
651 pub fn iter_distinct_condition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
652 ConditionKind::ALL
653 .iter()
654 .copied()
655 .filter(|&k| self.has_condition_kind(k))
656 }
657
658 /// Zero-allocation iterator peer of
659 /// [`Self::distinct_precondition_kinds`] — the precondition-side arm
660 /// of the (precondition, postcondition, condition-union) closed-set-
661 /// inversion iterator triad on [`EphemeralSpec`]. Thin typed delegate
662 /// to [`crate::boundary::ConditionSliceExt::iter_distinct_kinds`] over
663 /// [`Self::preconditions`].
664 pub fn iter_distinct_precondition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
665 self.preconditions.iter_distinct_kinds()
666 }
667
668 /// Zero-allocation iterator peer of
669 /// [`Self::distinct_postcondition_kinds`] — the postcondition-side
670 /// arm of the (precondition, postcondition, condition-union) closed-
671 /// set-inversion iterator triad on [`EphemeralSpec`]. Thin typed
672 /// delegate to
673 /// [`crate::boundary::ConditionSliceExt::iter_distinct_kinds`] over
674 /// [`Self::postconditions`].
675 pub fn iter_distinct_postcondition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
676 self.postconditions.iter_distinct_kinds()
677 }
678
679 /// Scalar cardinality of the [`ConditionKind`] set appearing at
680 /// least once in `preconditions ∪ postconditions` — the peer of
681 /// [`crate::boundary::Boundary::distinct_condition_kind_count`] on
682 /// the [`EphemeralSpec`] sugar surface.
683 ///
684 /// # Composed body — byte-identical to
685 /// [`crate::boundary::Boundary::distinct_condition_kind_count`]
686 ///
687 /// `ConditionKind::ALL.iter().filter(|k|
688 /// self.has_condition_kind(**k)).count()` — the scalar cardinality
689 /// projection of [`Self::distinct_condition_kinds`] onto its
690 /// `.len()`, without materializing the intermediate
691 /// `Vec<ConditionKind>`. Byte-identical to the peer method on the
692 /// point-domain [`crate::boundary::Boundary`] surface — both
693 /// compose against the SAME slice-level substrate primitive
694 /// [`crate::boundary::ConditionSliceExt::distinct_kind_count`] via
695 /// the two-slice union composed through [`Self::has_condition_kind`]
696 /// so a regression at the per-slice closed-set walk fails at that
697 /// primitive's tests rather than as silent drift at either
698 /// struct-level scalar-cardinality caller.
699 ///
700 /// # Sibling to [`Self::distinct_condition_kinds`]
701 ///
702 /// Scalar projection of the closed-set-inversion widened primitive
703 /// on the ephemeral-union surface — where `distinct_condition_kinds`
704 /// returns the SET, `distinct_condition_kind_count` collapses it to
705 /// its cardinality. The two-surface parity contract now covers SIX
706 /// refinements (bool / `&Condition` / `impl Iterator` / `usize` /
707 /// `Vec<ConditionKind>` closed-set-inversion / `usize` scalar
708 /// cardinality of the closed-set-inversion) on the condition axis,
709 /// byte-for-byte peer of the point-domain triad on
710 /// [`crate::boundary::Boundary`].
711 ///
712 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
713 /// proofs — the scalar cardinality composes the SAME closed-set
714 /// walk on both this ephemeral surface and the point-domain
715 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
716 /// (generation over composition — a future [`ConditionKind`] variant
717 /// added to `ALL` reaches both surfaces' distinct-kind-count triads
718 /// mechanically through the SAME closed-set walk).
719 #[must_use]
720 pub fn distinct_condition_kind_count(&self) -> usize {
721 ConditionKind::ALL
722 .iter()
723 .filter(|k| self.has_condition_kind(**k))
724 .count()
725 }
726
727 /// Scalar cardinality of the [`ConditionKind`] set appearing at
728 /// least once in [`Self::preconditions`] — the precondition-side
729 /// arm of the (precondition, postcondition, condition-union)
730 /// distinct-kind-count triad on [`EphemeralSpec`]. Thin typed
731 /// delegate to
732 /// [`crate::boundary::ConditionSliceExt::distinct_kind_count`]
733 /// over [`Self::preconditions`].
734 ///
735 /// Peer of
736 /// [`crate::boundary::Boundary::distinct_precondition_kind_count`]
737 /// on the point-domain surface — both peers compose against the
738 /// SAME slice-level substrate primitive so a regression at the
739 /// per-slice closed-set walk fails at that primitive's tests rather
740 /// than as silent drift at either struct-level arm.
741 #[must_use]
742 pub fn distinct_precondition_kind_count(&self) -> usize {
743 self.preconditions.distinct_kind_count()
744 }
745
746 /// Scalar cardinality of the [`ConditionKind`] set appearing at
747 /// least once in [`Self::postconditions`] — the postcondition-side
748 /// arm of the (precondition, postcondition, condition-union)
749 /// distinct-kind-count triad on [`EphemeralSpec`]. Thin typed
750 /// delegate to
751 /// [`crate::boundary::ConditionSliceExt::distinct_kind_count`]
752 /// over [`Self::postconditions`].
753 ///
754 /// Peer of
755 /// [`crate::boundary::Boundary::distinct_postcondition_kind_count`]
756 /// on the point-domain surface. See
757 /// [`Self::distinct_precondition_kind_count`] for the full rationale
758 /// — the two methods share ONE lift motivation, ONE fail-before-
759 /// pass-after composition-law pin, and ONE two-surface parity
760 /// contract with the point-domain
761 /// [`crate::boundary::Boundary`] distinct-kind-count peer methods.
762 #[must_use]
763 pub fn distinct_postcondition_kind_count(&self) -> usize {
764 self.postconditions.distinct_kind_count()
765 }
766
767 /// The set of [`ConditionKind`] variants that do NOT appear in
768 /// `preconditions ∪ postconditions`, projected in
769 /// [`ConditionKind::ALL`] order — the closed-set-inversion
770 /// COMPLEMENT of [`Self::distinct_condition_kinds`] on the
771 /// (precondition, postcondition, condition-union) missing-set triad.
772 /// Byte-identical peer of
773 /// [`crate::boundary::Boundary::missing_condition_kinds`] on the
774 /// ephemeral sugar surface.
775 ///
776 /// # Composed body — byte-identical to
777 /// [`crate::boundary::Boundary::missing_condition_kinds`]
778 ///
779 /// `ConditionKind::ALL.into_iter().filter(|k|
780 /// !self.has_condition_kind(*k)).collect()` — a thin projection
781 /// over the closed set composed against the two-slice union
782 /// primitive [`Self::has_condition_kind`] under a negated
783 /// predicate. Equivalent to the SET-INTERSECTION of
784 /// [`Self::missing_precondition_kinds`] and
785 /// [`Self::missing_postcondition_kinds`] projected in canonical
786 /// [`ConditionKind::ALL`] order (the union-composition law pinned
787 /// by [`crate::assert_surface_union_composition_laws`]).
788 ///
789 /// # Peer on the point surface — [`crate::boundary::Boundary::missing_condition_kinds`]
790 ///
791 /// Same signature `(&Self) -> Vec<ConditionKind>`, same closed-set-
792 /// complement body, on the point-domain [`crate::boundary::Boundary`]
793 /// nested-slot carrier. Both methods compose against the SAME
794 /// slice-level substrate primitive
795 /// [`crate::boundary::ConditionSliceExt::missing_kinds`] via the
796 /// two-slice union composed through [`Self::has_condition_kind`] —
797 /// a regression at the per-slice walk fails at that primitive's
798 /// tests rather than as silent drift at either struct-level
799 /// complement caller.
800 ///
801 /// # Sibling to [`Self::distinct_condition_kinds`]
802 ///
803 /// SIXTH refinement on the ephemeral-surface presence-probe algebra,
804 /// on the SAME closed-set-inversion axis as `distinct_condition_kinds`
805 /// but under a NEGATED point-probe. The two-surface parity contract
806 /// now covers SEVEN refinements (bool / `&Condition` /
807 /// `impl Iterator` / `usize` / `Vec<ConditionKind>` closed-set-
808 /// inversion / `usize` scalar cardinality of the closed-set-
809 /// inversion / `Vec<ConditionKind>` closed-set-complement) on the
810 /// condition axis, byte-for-byte peer of the point-domain triad on
811 /// [`crate::boundary::Boundary`].
812 ///
813 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
814 /// preserves proofs — the closed-set complement composes the SAME
815 /// closed-set walk on both this ephemeral surface and the point-
816 /// domain [`crate::boundary::Boundary`] surface).
817 /// THEORY.md §VI.1 (generation over composition — a future
818 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
819 /// missing-set triads mechanically through the SAME closed-set walk).
820 #[must_use]
821 pub fn missing_condition_kinds(&self) -> Vec<ConditionKind> {
822 ConditionKind::ALL
823 .into_iter()
824 .filter(|k| !self.has_condition_kind(*k))
825 .collect()
826 }
827
828 /// The set of [`ConditionKind`] variants that do NOT appear in
829 /// [`Self::preconditions`], projected in [`ConditionKind::ALL`]
830 /// order — the precondition-side arm of the (precondition,
831 /// postcondition, condition-union) missing-set triad on
832 /// [`EphemeralSpec`]. Thin typed delegate to
833 /// [`crate::boundary::ConditionSliceExt::missing_kinds`] over
834 /// [`Self::preconditions`].
835 ///
836 /// Peer of [`crate::boundary::Boundary::missing_precondition_kinds`]
837 /// on the point-domain surface — both peers compose against the
838 /// SAME slice-level substrate primitive so a regression at the
839 /// per-slice closed-set walk fails at that primitive's tests
840 /// rather than as silent drift at either struct-level arm.
841 #[must_use]
842 pub fn missing_precondition_kinds(&self) -> Vec<ConditionKind> {
843 self.preconditions.missing_kinds()
844 }
845
846 /// The set of [`ConditionKind`] variants that do NOT appear in
847 /// [`Self::postconditions`], projected in [`ConditionKind::ALL`]
848 /// order — the postcondition-side arm of the (precondition,
849 /// postcondition, condition-union) missing-set triad on
850 /// [`EphemeralSpec`]. Thin typed delegate to
851 /// [`crate::boundary::ConditionSliceExt::missing_kinds`] over
852 /// [`Self::postconditions`].
853 ///
854 /// Peer of [`crate::boundary::Boundary::missing_postcondition_kinds`]
855 /// on the point-domain surface. See
856 /// [`Self::missing_precondition_kinds`] for the full rationale —
857 /// the two methods share ONE lift motivation, ONE fail-before-
858 /// pass-after composition-law pin, and ONE two-surface parity
859 /// contract with the point-domain
860 /// [`crate::boundary::Boundary`] missing-set peer methods.
861 #[must_use]
862 pub fn missing_postcondition_kinds(&self) -> Vec<ConditionKind> {
863 self.postconditions.missing_kinds()
864 }
865
866 /// Zero-allocation iterator peer of [`Self::missing_condition_kinds`]
867 /// — the condition-union arm of the (precondition, postcondition,
868 /// condition-union) closed-set-complement iterator triad on
869 /// [`EphemeralSpec`]. Byte-identical to
870 /// [`crate::boundary::Boundary::iter_missing_condition_kinds`] on the
871 /// point-domain surface. Walks [`ConditionKind::ALL`] in canonical
872 /// order and yields every [`ConditionKind`] that does NOT appear in
873 /// `preconditions ∪ postconditions`, WITHOUT materializing an
874 /// intermediate `Vec<ConditionKind>`.
875 pub fn iter_missing_condition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
876 ConditionKind::ALL
877 .iter()
878 .copied()
879 .filter(|&k| !self.has_condition_kind(k))
880 }
881
882 /// Zero-allocation iterator peer of
883 /// [`Self::missing_precondition_kinds`] — the precondition-side arm
884 /// of the (precondition, postcondition, condition-union) closed-set-
885 /// complement iterator triad on [`EphemeralSpec`]. Thin typed delegate
886 /// to [`crate::boundary::ConditionSliceExt::iter_missing_kinds`] over
887 /// [`Self::preconditions`].
888 pub fn iter_missing_precondition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
889 self.preconditions.iter_missing_kinds()
890 }
891
892 /// Zero-allocation iterator peer of
893 /// [`Self::missing_postcondition_kinds`] — the postcondition-side arm
894 /// of the (precondition, postcondition, condition-union) closed-set-
895 /// complement iterator triad on [`EphemeralSpec`]. Thin typed delegate
896 /// to [`crate::boundary::ConditionSliceExt::iter_missing_kinds`] over
897 /// [`Self::postconditions`].
898 pub fn iter_missing_postcondition_kinds(&self) -> impl Iterator<Item = ConditionKind> + '_ {
899 self.postconditions.iter_missing_kinds()
900 }
901
902 /// Scalar cardinality of the [`ConditionKind`] set NOT appearing in
903 /// `preconditions ∪ postconditions` — the peer of
904 /// [`crate::boundary::Boundary::missing_condition_kind_count`] on
905 /// the [`EphemeralSpec`] sugar surface.
906 ///
907 /// # Composed body — byte-identical to
908 /// [`crate::boundary::Boundary::missing_condition_kind_count`]
909 ///
910 /// `ConditionKind::ALL.iter().filter(|k|
911 /// !self.has_condition_kind(**k)).count()` — the scalar cardinality
912 /// projection of [`Self::missing_condition_kinds`] onto its
913 /// `.len()`, without materializing the intermediate
914 /// `Vec<ConditionKind>`. Byte-identical to the peer method on the
915 /// point-domain [`crate::boundary::Boundary`] surface — both
916 /// compose against the SAME slice-level substrate primitive
917 /// [`crate::boundary::ConditionSliceExt::missing_kind_count`] via
918 /// the two-slice union composed through [`Self::has_condition_kind`]
919 /// so a regression at the per-slice negated closed-set walk fails
920 /// at that primitive's tests rather than as silent drift at either
921 /// struct-level scalar-cardinality caller.
922 ///
923 /// # Sibling to [`Self::missing_condition_kinds`]
924 ///
925 /// Scalar projection of the closed-set-complement widened primitive
926 /// on the ephemeral-union surface — where `missing_condition_kinds`
927 /// returns the SET, `missing_condition_kind_count` collapses it to
928 /// its cardinality. The two-surface parity contract now covers
929 /// EIGHT refinements (bool / `&Condition` / `impl Iterator` /
930 /// `usize` / `Vec<ConditionKind>` closed-set-inversion / `usize`
931 /// scalar cardinality of the closed-set-inversion /
932 /// `Vec<ConditionKind>` closed-set-complement / `usize` scalar
933 /// cardinality of the closed-set-complement) on the condition axis,
934 /// byte-for-byte peer of the point-domain triad on
935 /// [`crate::boundary::Boundary`].
936 ///
937 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
938 /// proofs — the scalar cardinality composes the SAME closed-set
939 /// walk under negation on both this ephemeral surface and the
940 /// point-domain [`crate::boundary::Boundary`] surface).
941 /// THEORY.md §VI.1 (generation over composition — a future
942 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
943 /// missing-kind-count triads mechanically through the SAME
944 /// closed-set walk).
945 #[must_use]
946 pub fn missing_condition_kind_count(&self) -> usize {
947 ConditionKind::ALL
948 .iter()
949 .filter(|k| !self.has_condition_kind(**k))
950 .count()
951 }
952
953 /// Scalar cardinality of the [`ConditionKind`] set NOT appearing in
954 /// [`Self::preconditions`] — the precondition-side arm of the
955 /// (precondition, postcondition, condition-union) missing-kind-count
956 /// triad on [`EphemeralSpec`]. Thin typed delegate to
957 /// [`crate::boundary::ConditionSliceExt::missing_kind_count`] over
958 /// [`Self::preconditions`].
959 ///
960 /// Peer of
961 /// [`crate::boundary::Boundary::missing_precondition_kind_count`]
962 /// on the point-domain surface — both peers compose against the
963 /// SAME slice-level substrate primitive so a regression at the
964 /// per-slice negated closed-set walk fails at that primitive's tests
965 /// rather than as silent drift at either struct-level arm.
966 #[must_use]
967 pub fn missing_precondition_kind_count(&self) -> usize {
968 self.preconditions.missing_kind_count()
969 }
970
971 /// Scalar cardinality of the [`ConditionKind`] set NOT appearing in
972 /// [`Self::postconditions`] — the postcondition-side arm of the
973 /// (precondition, postcondition, condition-union) missing-kind-count
974 /// triad on [`EphemeralSpec`]. Thin typed delegate to
975 /// [`crate::boundary::ConditionSliceExt::missing_kind_count`] over
976 /// [`Self::postconditions`].
977 ///
978 /// Peer of
979 /// [`crate::boundary::Boundary::missing_postcondition_kind_count`]
980 /// on the point-domain surface. See
981 /// [`Self::missing_precondition_kind_count`] for the full rationale
982 /// — the two methods share ONE lift motivation, ONE fail-before-
983 /// pass-after composition-law pin, and ONE two-surface parity
984 /// contract with the point-domain
985 /// [`crate::boundary::Boundary`] missing-kind-count peer methods.
986 #[must_use]
987 pub fn missing_postcondition_kind_count(&self) -> usize {
988 self.postconditions.missing_kind_count()
989 }
990
991 /// Earliest [`ConditionKind::ALL`] entry present in
992 /// `preconditions ∪ postconditions`, or `None` when neither side
993 /// populates any variant — the peer of
994 /// [`crate::boundary::Boundary::first_distinct_condition_kind`]
995 /// on the [`EphemeralSpec`] sugar surface.
996 ///
997 /// # Composed body — byte-identical to
998 /// [`crate::boundary::Boundary::first_distinct_condition_kind`]
999 ///
1000 /// `ConditionKind::ALL.iter().copied().find(|k|
1001 /// self.has_condition_kind(*k))` — the earliest-element scalar
1002 /// projection of [`Self::distinct_condition_kinds`] onto its first
1003 /// entry, without materializing the intermediate
1004 /// `Vec<ConditionKind>`. Byte-identical to the peer method on the
1005 /// point-domain [`crate::boundary::Boundary`] surface — both
1006 /// compose against the SAME slice-level substrate primitive
1007 /// [`crate::boundary::ConditionSliceExt::first_distinct_kind`] via
1008 /// the two-slice union composed through
1009 /// [`Self::has_condition_kind`] so a regression at the per-slice
1010 /// short-circuit walk fails at that primitive's tests rather than
1011 /// as silent drift at either struct-level earliest-element caller.
1012 ///
1013 /// # Sibling to [`Self::distinct_condition_kinds`]
1014 ///
1015 /// Third scalar projection of the closed-set-inversion widened
1016 /// primitive on the ephemeral-union surface. The two-surface
1017 /// parity contract now covers NINE refinements on the condition
1018 /// axis (bool / `&Condition` / `impl Iterator` / `usize` /
1019 /// `Vec<ConditionKind>` closed-set-inversion / `usize` scalar
1020 /// cardinality of the closed-set-inversion / `Vec<ConditionKind>`
1021 /// closed-set-complement / `usize` scalar cardinality of the
1022 /// closed-set-complement / `Option<ConditionKind>` earliest-element
1023 /// scalar of the closed-set-inversion), byte-for-byte peer of the
1024 /// point-domain triad on [`crate::boundary::Boundary`].
1025 ///
1026 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1027 /// preserves proofs — the earliest-element projection composes the
1028 /// SAME closed-set walk on both this ephemeral surface and the
1029 /// point-domain [`crate::boundary::Boundary`] surface under short-
1030 /// circuit semantics). THEORY.md §VI.1 (generation over composition
1031 /// — a future [`ConditionKind`] variant added to `ALL` reaches both
1032 /// surfaces' first-distinct-kind triads mechanically through the
1033 /// SAME closed-set walk).
1034 #[must_use]
1035 pub fn first_distinct_condition_kind(&self) -> Option<ConditionKind> {
1036 ConditionKind::ALL
1037 .iter()
1038 .copied()
1039 .find(|k| self.has_condition_kind(*k))
1040 }
1041
1042 /// Earliest [`ConditionKind::ALL`] entry present in
1043 /// [`Self::preconditions`], or `None` when preconditions carry no
1044 /// matching kind — the precondition-side arm of the (precondition,
1045 /// postcondition, condition-union) first-distinct-kind triad on
1046 /// [`EphemeralSpec`]. Thin typed delegate to
1047 /// [`crate::boundary::ConditionSliceExt::first_distinct_kind`]
1048 /// over [`Self::preconditions`].
1049 ///
1050 /// Peer of
1051 /// [`crate::boundary::Boundary::first_distinct_precondition_kind`]
1052 /// on the point-domain surface — both peers compose against the
1053 /// SAME slice-level substrate primitive so a regression at the
1054 /// per-slice short-circuit walk fails at that primitive's tests
1055 /// rather than as silent drift at either struct-level arm.
1056 #[must_use]
1057 pub fn first_distinct_precondition_kind(&self) -> Option<ConditionKind> {
1058 self.preconditions.first_distinct_kind()
1059 }
1060
1061 /// Earliest [`ConditionKind::ALL`] entry present in
1062 /// [`Self::postconditions`], or `None` when postconditions carry
1063 /// no matching kind — the postcondition-side arm of the
1064 /// (precondition, postcondition, condition-union) first-distinct-
1065 /// kind triad on [`EphemeralSpec`]. Thin typed delegate to
1066 /// [`crate::boundary::ConditionSliceExt::first_distinct_kind`]
1067 /// over [`Self::postconditions`].
1068 ///
1069 /// Peer of
1070 /// [`crate::boundary::Boundary::first_distinct_postcondition_kind`]
1071 /// on the point-domain surface. See
1072 /// [`Self::first_distinct_precondition_kind`] for the full
1073 /// rationale — the two methods share ONE lift motivation, ONE
1074 /// fail-before-pass-after composition-law pin, and ONE two-surface
1075 /// parity contract with the point-domain
1076 /// [`crate::boundary::Boundary`] first-distinct-kind peer methods.
1077 #[must_use]
1078 pub fn first_distinct_postcondition_kind(&self) -> Option<ConditionKind> {
1079 self.postconditions.first_distinct_kind()
1080 }
1081
1082 /// Earliest [`ConditionKind::ALL`] entry ABSENT from
1083 /// `preconditions ∪ postconditions`, or `None` when the union
1084 /// carries every variant — the peer of
1085 /// [`crate::boundary::Boundary::first_missing_condition_kind`]
1086 /// on the [`EphemeralSpec`] sugar surface.
1087 ///
1088 /// # Composed body — byte-identical to
1089 /// [`crate::boundary::Boundary::first_missing_condition_kind`]
1090 ///
1091 /// `ConditionKind::ALL.iter().copied().find(|k|
1092 /// !self.has_condition_kind(*k))` — the earliest-element scalar
1093 /// projection of [`Self::missing_condition_kinds`] onto its first
1094 /// entry under a NEGATED predicate. Byte-identical to the peer
1095 /// method on the point-domain [`crate::boundary::Boundary`]
1096 /// surface — both compose against the SAME slice-level substrate
1097 /// primitive [`crate::boundary::ConditionSliceExt::first_missing_kind`]
1098 /// via the two-slice union composed through
1099 /// [`Self::has_condition_kind`] so a regression at the per-slice
1100 /// negated short-circuit walk fails at that primitive's tests
1101 /// rather than as silent drift at either struct-level earliest-
1102 /// element caller.
1103 ///
1104 /// # Sibling to [`Self::missing_condition_kinds`]
1105 ///
1106 /// Third scalar projection of the closed-set-complement widened
1107 /// primitive on the ephemeral-union surface. The two-surface
1108 /// parity contract now covers TEN refinements on the condition
1109 /// axis (the nine listed at [`Self::first_distinct_condition_kind`]
1110 /// plus `Option<ConditionKind>` earliest-element scalar of the
1111 /// closed-set-complement), byte-for-byte peer of the point-domain
1112 /// triad on [`crate::boundary::Boundary`].
1113 ///
1114 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1115 /// preserves proofs — the complement-earliest-element projection
1116 /// composes the SAME closed-set walk on both this ephemeral
1117 /// surface and the point-domain [`crate::boundary::Boundary`]
1118 /// surface under short-circuit semantics with a negated predicate).
1119 /// THEORY.md §VI.1 (generation over composition — a future
1120 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
1121 /// first-missing-kind triads mechanically through the SAME closed-
1122 /// set walk).
1123 #[must_use]
1124 pub fn first_missing_condition_kind(&self) -> Option<ConditionKind> {
1125 ConditionKind::ALL
1126 .iter()
1127 .copied()
1128 .find(|k| !self.has_condition_kind(*k))
1129 }
1130
1131 /// Earliest [`ConditionKind::ALL`] entry ABSENT from
1132 /// [`Self::preconditions`], or `None` when preconditions carry
1133 /// every variant — the precondition-side arm of the (precondition,
1134 /// postcondition, condition-union) first-missing-kind triad on
1135 /// [`EphemeralSpec`]. Thin typed delegate to
1136 /// [`crate::boundary::ConditionSliceExt::first_missing_kind`]
1137 /// over [`Self::preconditions`].
1138 ///
1139 /// Peer of
1140 /// [`crate::boundary::Boundary::first_missing_precondition_kind`]
1141 /// on the point-domain surface — both peers compose against the
1142 /// SAME slice-level substrate primitive so a regression at the
1143 /// per-slice negated short-circuit walk fails at that primitive's
1144 /// tests rather than as silent drift at either struct-level arm.
1145 #[must_use]
1146 pub fn first_missing_precondition_kind(&self) -> Option<ConditionKind> {
1147 self.preconditions.first_missing_kind()
1148 }
1149
1150 /// Earliest [`ConditionKind::ALL`] entry ABSENT from
1151 /// [`Self::postconditions`], or `None` when postconditions carry
1152 /// every variant — the postcondition-side arm of the (precondition,
1153 /// postcondition, condition-union) first-missing-kind triad on
1154 /// [`EphemeralSpec`]. Thin typed delegate to
1155 /// [`crate::boundary::ConditionSliceExt::first_missing_kind`]
1156 /// over [`Self::postconditions`].
1157 ///
1158 /// Peer of
1159 /// [`crate::boundary::Boundary::first_missing_postcondition_kind`]
1160 /// on the point-domain surface. See
1161 /// [`Self::first_missing_precondition_kind`] for the full
1162 /// rationale — the two methods share ONE lift motivation, ONE
1163 /// fail-before-pass-after composition-law pin, and ONE two-surface
1164 /// parity contract with the point-domain
1165 /// [`crate::boundary::Boundary`] first-missing-kind peer methods.
1166 #[must_use]
1167 pub fn first_missing_postcondition_kind(&self) -> Option<ConditionKind> {
1168 self.postconditions.first_missing_kind()
1169 }
1170
1171 /// Latest [`ConditionKind::ALL`] entry present in
1172 /// `preconditions ∪ postconditions`, or `None` when neither side
1173 /// populates any variant — the peer of
1174 /// [`crate::boundary::Boundary::last_distinct_condition_kind`]
1175 /// on the [`EphemeralSpec`] sugar surface.
1176 ///
1177 /// # Composed body — byte-identical to
1178 /// [`crate::boundary::Boundary::last_distinct_condition_kind`]
1179 ///
1180 /// `ConditionKind::ALL.iter().rev().copied().find(|k|
1181 /// self.has_condition_kind(*k))` — the latest-element scalar
1182 /// projection of [`Self::distinct_condition_kinds`] onto its last
1183 /// entry via a REVERSED closed-set walk, without materializing
1184 /// the intermediate `Vec<ConditionKind>`. Byte-identical to the
1185 /// peer method on the point-domain [`crate::boundary::Boundary`]
1186 /// surface — both compose against the SAME slice-level substrate
1187 /// primitive [`crate::boundary::ConditionSliceExt::last_distinct_kind`]
1188 /// via the two-slice union composed through
1189 /// [`Self::has_condition_kind`] so a regression at the per-slice
1190 /// REVERSED short-circuit walk fails at that primitive's tests
1191 /// rather than as silent drift at either struct-level latest-
1192 /// element caller.
1193 ///
1194 /// # Sibling to [`Self::first_distinct_condition_kind`] /
1195 /// [`Self::distinct_condition_kinds`]
1196 ///
1197 /// Time-reversed scalar peer of the earliest-element projection
1198 /// under the SAME two-slice union predicate. The two-surface
1199 /// parity contract now covers ELEVEN refinements on the condition
1200 /// axis (the nine listed at `first_distinct_condition_kind` plus
1201 /// `Option<ConditionKind>` earliest-element scalar of the closed-
1202 /// set-complement (`first_missing_*_kind`), plus this
1203 /// `Option<ConditionKind>` latest-element scalar of the closed-
1204 /// set-inversion (`last_distinct_*_kind`)). Byte-for-byte peer of
1205 /// the point-domain triad on [`crate::boundary::Boundary`].
1206 ///
1207 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1208 /// preserves proofs — the latest-element projection composes the
1209 /// SAME reversed closed-set walk on both this ephemeral surface
1210 /// and the point-domain [`crate::boundary::Boundary`] surface
1211 /// under short-circuit semantics). THEORY.md §VI.1 (generation
1212 /// over composition — a future [`ConditionKind`] variant added to
1213 /// `ALL` reaches both surfaces' last-distinct-kind triads
1214 /// mechanically through the SAME reversed closed-set walk).
1215 #[must_use]
1216 pub fn last_distinct_condition_kind(&self) -> Option<ConditionKind> {
1217 ConditionKind::ALL
1218 .iter()
1219 .rev()
1220 .copied()
1221 .find(|k| self.has_condition_kind(*k))
1222 }
1223
1224 /// Latest [`ConditionKind::ALL`] entry present in
1225 /// [`Self::preconditions`], or `None` when preconditions carry no
1226 /// matching kind — the precondition-side arm of the (precondition,
1227 /// postcondition, condition-union) last-distinct-kind triad on
1228 /// [`EphemeralSpec`]. Thin typed delegate to
1229 /// [`crate::boundary::ConditionSliceExt::last_distinct_kind`]
1230 /// over [`Self::preconditions`].
1231 ///
1232 /// Peer of
1233 /// [`crate::boundary::Boundary::last_distinct_precondition_kind`]
1234 /// on the point-domain surface — both peers compose against the
1235 /// SAME slice-level substrate primitive so a regression at the
1236 /// per-slice REVERSED short-circuit walk fails at that primitive's
1237 /// tests rather than as silent drift at either struct-level arm.
1238 #[must_use]
1239 pub fn last_distinct_precondition_kind(&self) -> Option<ConditionKind> {
1240 self.preconditions.last_distinct_kind()
1241 }
1242
1243 /// Latest [`ConditionKind::ALL`] entry present in
1244 /// [`Self::postconditions`], or `None` when postconditions carry
1245 /// no matching kind — the postcondition-side arm of the
1246 /// (precondition, postcondition, condition-union) last-distinct-
1247 /// kind triad on [`EphemeralSpec`]. Thin typed delegate to
1248 /// [`crate::boundary::ConditionSliceExt::last_distinct_kind`]
1249 /// over [`Self::postconditions`].
1250 ///
1251 /// Peer of
1252 /// [`crate::boundary::Boundary::last_distinct_postcondition_kind`]
1253 /// on the point-domain surface. See
1254 /// [`Self::last_distinct_precondition_kind`] for the full
1255 /// rationale — the two methods share ONE lift motivation, ONE
1256 /// fail-before-pass-after composition-law pin, and ONE two-surface
1257 /// parity contract with the point-domain
1258 /// [`crate::boundary::Boundary`] last-distinct-kind peer methods.
1259 #[must_use]
1260 pub fn last_distinct_postcondition_kind(&self) -> Option<ConditionKind> {
1261 self.postconditions.last_distinct_kind()
1262 }
1263
1264 /// Latest [`ConditionKind::ALL`] entry ABSENT from
1265 /// `preconditions ∪ postconditions`, or `None` when the union
1266 /// carries every variant — the peer of
1267 /// [`crate::boundary::Boundary::last_missing_condition_kind`]
1268 /// on the [`EphemeralSpec`] sugar surface.
1269 ///
1270 /// # Composed body — byte-identical to
1271 /// [`crate::boundary::Boundary::last_missing_condition_kind`]
1272 ///
1273 /// `ConditionKind::ALL.iter().rev().copied().find(|k|
1274 /// !self.has_condition_kind(*k))` — the latest-element scalar
1275 /// projection of [`Self::missing_condition_kinds`] onto its last
1276 /// entry via a REVERSED closed-set walk under a NEGATED
1277 /// predicate. Byte-identical to the peer method on the point-
1278 /// domain [`crate::boundary::Boundary`] surface — both compose
1279 /// against the SAME slice-level substrate primitive
1280 /// [`crate::boundary::ConditionSliceExt::last_missing_kind`] via
1281 /// the two-slice union composed through
1282 /// [`Self::has_condition_kind`] so a regression at the per-slice
1283 /// negated REVERSED short-circuit walk fails at that primitive's
1284 /// tests rather than as silent drift at either struct-level
1285 /// latest-element caller.
1286 ///
1287 /// # Sibling to [`Self::first_missing_condition_kind`] /
1288 /// [`Self::missing_condition_kinds`]
1289 ///
1290 /// Time-reversed scalar peer of the earliest-element projection
1291 /// under the SAME negated two-slice union predicate. The two-
1292 /// surface parity contract now covers TWELVE refinements on the
1293 /// condition axis (the ten listed at `first_missing_condition_kind`
1294 /// plus `Option<ConditionKind>` latest-element scalar of the
1295 /// closed-set-inversion (`last_distinct_*_kind`), plus this
1296 /// `Option<ConditionKind>` latest-element scalar of the closed-
1297 /// set-complement). Byte-for-byte peer of the point-domain triad
1298 /// on [`crate::boundary::Boundary`].
1299 ///
1300 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1301 /// preserves proofs — the complement-latest-element projection
1302 /// composes the SAME reversed closed-set walk on both this
1303 /// ephemeral surface and the point-domain
1304 /// [`crate::boundary::Boundary`] surface under short-circuit
1305 /// semantics with a negated predicate). THEORY.md §VI.1
1306 /// (generation over composition — a future [`ConditionKind`]
1307 /// variant added to `ALL` reaches both surfaces' last-missing-kind
1308 /// triads mechanically through the SAME reversed closed-set walk).
1309 #[must_use]
1310 pub fn last_missing_condition_kind(&self) -> Option<ConditionKind> {
1311 ConditionKind::ALL
1312 .iter()
1313 .rev()
1314 .copied()
1315 .find(|k| !self.has_condition_kind(*k))
1316 }
1317
1318 /// Latest [`ConditionKind::ALL`] entry ABSENT from
1319 /// [`Self::preconditions`], or `None` when preconditions carry
1320 /// every variant — the precondition-side arm of the (precondition,
1321 /// postcondition, condition-union) last-missing-kind triad on
1322 /// [`EphemeralSpec`]. Thin typed delegate to
1323 /// [`crate::boundary::ConditionSliceExt::last_missing_kind`]
1324 /// over [`Self::preconditions`].
1325 ///
1326 /// Peer of
1327 /// [`crate::boundary::Boundary::last_missing_precondition_kind`]
1328 /// on the point-domain surface — both peers compose against the
1329 /// SAME slice-level substrate primitive so a regression at the
1330 /// per-slice negated REVERSED short-circuit walk fails at that
1331 /// primitive's tests rather than as silent drift at either
1332 /// struct-level arm.
1333 #[must_use]
1334 pub fn last_missing_precondition_kind(&self) -> Option<ConditionKind> {
1335 self.preconditions.last_missing_kind()
1336 }
1337
1338 /// Latest [`ConditionKind::ALL`] entry ABSENT from
1339 /// [`Self::postconditions`], or `None` when postconditions carry
1340 /// every variant — the postcondition-side arm of the
1341 /// (precondition, postcondition, condition-union) last-missing-
1342 /// kind triad on [`EphemeralSpec`]. Thin typed delegate to
1343 /// [`crate::boundary::ConditionSliceExt::last_missing_kind`]
1344 /// over [`Self::postconditions`].
1345 ///
1346 /// Peer of
1347 /// [`crate::boundary::Boundary::last_missing_postcondition_kind`]
1348 /// on the point-domain surface. See
1349 /// [`Self::last_missing_precondition_kind`] for the full
1350 /// rationale — the two methods share ONE lift motivation, ONE
1351 /// fail-before-pass-after composition-law pin, and ONE two-surface
1352 /// parity contract with the point-domain
1353 /// [`crate::boundary::Boundary`] last-missing-kind peer methods.
1354 #[must_use]
1355 pub fn last_missing_postcondition_kind(&self) -> Option<ConditionKind> {
1356 self.postconditions.last_missing_kind()
1357 }
1358
1359 /// `true` iff `preconditions ∪ postconditions` carries every
1360 /// [`ConditionKind::ALL`] variant at least once — the peer of
1361 /// [`crate::boundary::Boundary::is_condition_kind_saturated`] on
1362 /// the [`EphemeralSpec`] sugar surface.
1363 ///
1364 /// # Composed body — byte-identical to
1365 /// [`crate::boundary::Boundary::is_condition_kind_saturated`]
1366 ///
1367 /// `ConditionKind::ALL.iter().all(|k| self.has_condition_kind(*k))`
1368 /// — the saturation-endpoint projection of
1369 /// [`Self::missing_condition_kinds`] onto its emptiness test via
1370 /// a SHORT-CIRCUITING closed-set walk under the two-slice union
1371 /// primitive [`Self::has_condition_kind`]. Byte-identical to the
1372 /// peer method on the point-domain [`crate::boundary::Boundary`]
1373 /// surface — both compose against the SAME slice-level substrate
1374 /// primitive [`crate::boundary::ConditionSliceExt::is_kind_saturated`]
1375 /// via the two-slice union so a regression at the per-slice `all`
1376 /// short-circuit fails at that primitive's tests rather than as
1377 /// silent drift at either struct-level saturation caller.
1378 ///
1379 /// # Sibling to [`Self::missing_condition_kinds`] /
1380 /// [`Self::missing_condition_kind_count`]
1381 ///
1382 /// Boolean saturation-endpoint peer of the widened and scalar
1383 /// closed-set-complement primitives on the ephemeral-union
1384 /// surface — where those primitives return the SET and its
1385 /// cardinality, `is_condition_kind_saturated` collapses the
1386 /// scalar to its zero-arm Boolean projection.
1387 ///
1388 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1389 /// preserves proofs — the saturation-endpoint projection composes
1390 /// the SAME closed-set walk on both this ephemeral surface and the
1391 /// point-domain [`crate::boundary::Boundary`] surface under
1392 /// short-circuit semantics). THEORY.md §VI.1 (generation over
1393 /// composition — a future [`ConditionKind`] variant added to `ALL`
1394 /// reaches both surfaces' saturation-predicate triads mechanically
1395 /// through the SAME closed-set walk).
1396 #[must_use]
1397 pub fn is_condition_kind_saturated(&self) -> bool {
1398 ConditionKind::ALL
1399 .iter()
1400 .all(|k| self.has_condition_kind(*k))
1401 }
1402
1403 /// `true` iff [`Self::preconditions`] carries every
1404 /// [`ConditionKind::ALL`] variant at least once — the precondition-
1405 /// side arm of the (precondition, postcondition, condition-union)
1406 /// saturation-predicate triad on [`EphemeralSpec`]. Thin typed
1407 /// delegate to
1408 /// [`crate::boundary::ConditionSliceExt::is_kind_saturated`] over
1409 /// [`Self::preconditions`].
1410 ///
1411 /// Peer of
1412 /// [`crate::boundary::Boundary::is_precondition_kind_saturated`]
1413 /// on the point-domain surface — both peers compose against the
1414 /// SAME slice-level substrate primitive so a regression at the
1415 /// per-slice `all` short-circuit fails at that primitive's tests
1416 /// rather than as silent drift at either struct-level arm.
1417 #[must_use]
1418 pub fn is_precondition_kind_saturated(&self) -> bool {
1419 self.preconditions.is_kind_saturated()
1420 }
1421
1422 /// `true` iff [`Self::postconditions`] carries every
1423 /// [`ConditionKind::ALL`] variant at least once — the postcondition-
1424 /// side arm of the (precondition, postcondition, condition-union)
1425 /// saturation-predicate triad on [`EphemeralSpec`]. Thin typed
1426 /// delegate to
1427 /// [`crate::boundary::ConditionSliceExt::is_kind_saturated`] over
1428 /// [`Self::postconditions`].
1429 ///
1430 /// Peer of
1431 /// [`crate::boundary::Boundary::is_postcondition_kind_saturated`]
1432 /// on the point-domain surface. See
1433 /// [`Self::is_precondition_kind_saturated`] for the full rationale
1434 /// — the two methods share ONE lift motivation, ONE fail-before-
1435 /// pass-after composition-law pin, and ONE two-surface parity
1436 /// contract with the point-domain
1437 /// [`crate::boundary::Boundary`] saturation-predicate peer methods.
1438 #[must_use]
1439 pub fn is_postcondition_kind_saturated(&self) -> bool {
1440 self.postconditions.is_kind_saturated()
1441 }
1442
1443 /// `true` iff `preconditions ∪ postconditions` is MISSING at least
1444 /// one [`ConditionKind::ALL`] variant — the peer of
1445 /// [`crate::boundary::Boundary::has_any_missing_condition_kind`] on
1446 /// the [`EphemeralSpec`] sugar surface.
1447 ///
1448 /// # Composed body — byte-identical to
1449 /// [`crate::boundary::Boundary::has_any_missing_condition_kind`]
1450 ///
1451 /// `!self.is_condition_kind_saturated()` — the at-least-one
1452 /// halfspace projection of [`Self::missing_condition_kinds`] onto
1453 /// its non-emptiness test via a SHORT-CIRCUITING closed-set walk
1454 /// under the two-slice union primitive [`Self::has_condition_kind`]
1455 /// negated. Byte-identical to the peer method on the point-domain
1456 /// [`crate::boundary::Boundary`] surface — both compose against the
1457 /// SAME slice-level substrate primitive
1458 /// [`crate::boundary::ConditionSliceExt::has_any_missing_kind`] via
1459 /// the two-slice union so a regression at the per-slice `all`
1460 /// short-circuit under negation fails at that primitive's tests
1461 /// rather than as silent drift at either struct-level at-least-
1462 /// one halfspace caller.
1463 ///
1464 /// # Sibling to [`Self::missing_condition_kinds`] /
1465 /// [`Self::missing_condition_kind_count`]
1466 ///
1467 /// Boolean at-least-one halfspace peer of the widened and scalar
1468 /// closed-set-complement primitives on the ephemeral-union
1469 /// surface — where those primitives return the SET and its
1470 /// cardinality, `has_any_missing_condition_kind` collapses either
1471 /// to its `>= 1` halfspace Boolean.
1472 ///
1473 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1474 /// preserves proofs — the at-least-one halfspace projection
1475 /// composes the SAME closed-set walk under negation on both this
1476 /// ephemeral surface and the point-domain
1477 /// [`crate::boundary::Boundary`] surface under short-circuit
1478 /// semantics). THEORY.md §VI.1 (generation over composition — a
1479 /// future [`ConditionKind`] variant added to `ALL` reaches both
1480 /// surfaces' at-least-one halfspace triads mechanically through
1481 /// the SAME closed-set walk).
1482 #[must_use]
1483 pub fn has_any_missing_condition_kind(&self) -> bool {
1484 !self.is_condition_kind_saturated()
1485 }
1486
1487 /// `true` iff [`Self::preconditions`] is MISSING at least one
1488 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
1489 /// the (precondition, postcondition, condition-union) at-least-
1490 /// one halfspace triad on [`EphemeralSpec`]. Thin typed delegate
1491 /// to [`crate::boundary::ConditionSliceExt::has_any_missing_kind`]
1492 /// over [`Self::preconditions`].
1493 ///
1494 /// Peer of
1495 /// [`crate::boundary::Boundary::has_any_missing_precondition_kind`]
1496 /// on the point-domain surface — both peers compose against the
1497 /// SAME slice-level substrate primitive so a regression at the
1498 /// per-slice `all` short-circuit under negation fails at that
1499 /// primitive's tests rather than as silent drift at either
1500 /// struct-level arm.
1501 #[must_use]
1502 pub fn has_any_missing_precondition_kind(&self) -> bool {
1503 self.preconditions.has_any_missing_kind()
1504 }
1505
1506 /// `true` iff [`Self::postconditions`] is MISSING at least one
1507 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
1508 /// the (precondition, postcondition, condition-union) at-least-
1509 /// one halfspace triad on [`EphemeralSpec`]. Thin typed delegate
1510 /// to [`crate::boundary::ConditionSliceExt::has_any_missing_kind`]
1511 /// over [`Self::postconditions`].
1512 ///
1513 /// Peer of
1514 /// [`crate::boundary::Boundary::has_any_missing_postcondition_kind`]
1515 /// on the point-domain surface. See
1516 /// [`Self::has_any_missing_precondition_kind`] for the full
1517 /// rationale — the two methods share ONE lift motivation, ONE
1518 /// fail-before-pass-after composition-law pin, and ONE two-surface
1519 /// parity contract with the point-domain
1520 /// [`crate::boundary::Boundary`] at-least-one halfspace peer
1521 /// methods.
1522 #[must_use]
1523 pub fn has_any_missing_postcondition_kind(&self) -> bool {
1524 self.postconditions.has_any_missing_kind()
1525 }
1526
1527 /// `true` iff `preconditions ∪ postconditions` carries at least one
1528 /// [`ConditionKind::ALL`] variant — the peer of
1529 /// [`crate::boundary::Boundary::has_any_distinct_condition_kind`]
1530 /// on the [`EphemeralSpec`] sugar surface.
1531 ///
1532 /// # Composed body — byte-identical to
1533 /// [`crate::boundary::Boundary::has_any_distinct_condition_kind`]
1534 ///
1535 /// `ConditionKind::ALL.iter().copied().any(|k|
1536 /// self.has_condition_kind(k))` — the at-least-one halfspace
1537 /// projection of [`Self::distinct_condition_kinds`] onto its non-
1538 /// emptiness test via a SHORT-CIRCUITING closed-set walk under the
1539 /// two-slice union primitive [`Self::has_condition_kind`]. Byte-
1540 /// identical to the peer method on the point-domain
1541 /// [`crate::boundary::Boundary`] surface — both compose against
1542 /// the SAME slice-level substrate primitive
1543 /// [`crate::boundary::ConditionSliceExt::has_any_distinct_kind`]
1544 /// via the two-slice union so a regression at the per-slice `any`
1545 /// short-circuit fails at that primitive's tests rather than as
1546 /// silent drift at either struct-level at-least-one halfspace
1547 /// caller.
1548 ///
1549 /// # Sibling to [`Self::distinct_condition_kinds`] /
1550 /// [`Self::distinct_condition_kind_count`]
1551 ///
1552 /// Boolean at-least-one halfspace peer of the widened and scalar
1553 /// closed-set-inversion primitives on the ephemeral-union
1554 /// surface — where those primitives return the SET and its
1555 /// cardinality, `has_any_distinct_condition_kind` collapses either
1556 /// to its `>= 1` halfspace Boolean.
1557 ///
1558 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1559 /// preserves proofs — the at-least-one halfspace projection
1560 /// composes the SAME closed-set walk on both this ephemeral
1561 /// surface and the point-domain [`crate::boundary::Boundary`]
1562 /// surface under short-circuit semantics). THEORY.md §VI.1
1563 /// (generation over composition — a future [`ConditionKind`]
1564 /// variant added to `ALL` reaches both surfaces' at-least-one
1565 /// halfspace triads mechanically through the SAME closed-set
1566 /// walk).
1567 #[must_use]
1568 pub fn has_any_distinct_condition_kind(&self) -> bool {
1569 ConditionKind::ALL
1570 .iter()
1571 .copied()
1572 .any(|k| self.has_condition_kind(k))
1573 }
1574
1575 /// `true` iff [`Self::preconditions`] carries at least one
1576 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
1577 /// the (precondition, postcondition, condition-union) at-least-
1578 /// one halfspace triad on [`EphemeralSpec`] on the closed-set-
1579 /// inversion axis. Thin typed delegate to
1580 /// [`crate::boundary::ConditionSliceExt::has_any_distinct_kind`]
1581 /// over [`Self::preconditions`].
1582 ///
1583 /// Peer of
1584 /// [`crate::boundary::Boundary::has_any_distinct_precondition_kind`]
1585 /// on the point-domain surface — both peers compose against the
1586 /// SAME slice-level substrate primitive so a regression at the
1587 /// per-slice `any` short-circuit fails at that primitive's tests
1588 /// rather than as silent drift at either struct-level arm.
1589 #[must_use]
1590 pub fn has_any_distinct_precondition_kind(&self) -> bool {
1591 self.preconditions.has_any_distinct_kind()
1592 }
1593
1594 /// `true` iff [`Self::postconditions`] carries at least one
1595 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
1596 /// the (precondition, postcondition, condition-union) at-least-
1597 /// one halfspace triad on [`EphemeralSpec`] on the closed-set-
1598 /// inversion axis. Thin typed delegate to
1599 /// [`crate::boundary::ConditionSliceExt::has_any_distinct_kind`]
1600 /// over [`Self::postconditions`].
1601 ///
1602 /// Peer of
1603 /// [`crate::boundary::Boundary::has_any_distinct_postcondition_kind`]
1604 /// on the point-domain surface. See
1605 /// [`Self::has_any_distinct_precondition_kind`] for the full
1606 /// rationale — the two methods share ONE lift motivation, ONE
1607 /// fail-before-pass-after composition-law pin, and ONE two-surface
1608 /// parity contract with the point-domain
1609 /// [`crate::boundary::Boundary`] at-least-one halfspace peer
1610 /// methods.
1611 #[must_use]
1612 pub fn has_any_distinct_postcondition_kind(&self) -> bool {
1613 self.postconditions.has_any_distinct_kind()
1614 }
1615
1616 /// `true` iff `preconditions ∪ postconditions` carries EXACTLY
1617 /// ONE [`ConditionKind::ALL`] variant — the union arm of the
1618 /// (precondition, postcondition, condition-union) cardinality-
1619 /// mid-endpoint triad on [`EphemeralSpec`] closing the singleton-
1620 /// coverage arm on the closed-set-inversion axis on the union of
1621 /// the two condition slots. The Boolean cardinality-mid-endpoint
1622 /// fast-path peer of [`Self::has_any_distinct_condition_kind`]
1623 /// (≥1 halfspace) on the union axis: where the at-least-one
1624 /// halfspace predicate answers "is ANY kind covered by the
1625 /// union?", `has_unique_distinct_condition_kind` answers "is
1626 /// EXACTLY ONE kind covered by the union?".
1627 ///
1628 /// Composed body: constructs a two-step-short-circuit walk over
1629 /// [`ConditionKind::ALL`] under the [`Self::has_condition_kind`]
1630 /// union primitive — the first covered union arm surfaces, then
1631 /// the walk short-circuits at the second. Byte-for-byte peer of
1632 /// [`crate::boundary::ConditionSliceExt::has_unique_distinct_kind`]
1633 /// one slice-layer down, lifted to compose against
1634 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
1635 /// against a single slice's `has_kind`.
1636 ///
1637 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_unique_distinct_condition_kind`]
1638 ///
1639 /// Byte-identical signature `(&Self) -> bool`, byte-identical
1640 /// two-step short-circuit body composed against the point-domain
1641 /// surface's own union primitive. Both methods compose against
1642 /// the SAME slice-level substrate primitive
1643 /// [`crate::boundary::ConditionSliceExt::has_unique_distinct_kind`]
1644 /// via the two-slice union — a regression at the per-slice
1645 /// singleton-coverage walk fails at that primitive's tests rather
1646 /// than as silent drift at either struct-level singleton-coverage
1647 /// caller.
1648 ///
1649 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1650 /// preserves proofs — the cardinality-mid-endpoint projection on
1651 /// the closed-set-inversion axis composes the SAME two-step
1652 /// short-circuit walk on both this ephemeral surface and the
1653 /// point-domain [`crate::boundary::Boundary`] surface). THEORY.md
1654 /// §VI.1 (generation over composition — a new [`ConditionKind`]
1655 /// variant reaches both surfaces' cardinality-mid-endpoint triads
1656 /// mechanically through the delegated union primitive).
1657 #[must_use]
1658 pub fn has_unique_distinct_condition_kind(&self) -> bool {
1659 let mut it = ConditionKind::ALL
1660 .iter()
1661 .copied()
1662 .filter(|k| self.has_condition_kind(*k));
1663 it.next().is_some() && it.next().is_none()
1664 }
1665
1666 /// `true` iff [`Self::preconditions`] carries EXACTLY ONE
1667 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
1668 /// the (precondition, postcondition, condition-union)
1669 /// cardinality-mid-endpoint triad on [`EphemeralSpec`] on the
1670 /// closed-set-inversion axis. Thin typed delegate to
1671 /// [`crate::boundary::ConditionSliceExt::has_unique_distinct_kind`]
1672 /// over [`Self::preconditions`].
1673 ///
1674 /// Peer of
1675 /// [`crate::boundary::Boundary::has_unique_distinct_precondition_kind`]
1676 /// on the point-domain surface — both peers compose against the
1677 /// SAME slice-level substrate primitive so a regression at the
1678 /// per-slice two-step short-circuit walk fails at that primitive's
1679 /// tests rather than as silent drift at either struct-level arm.
1680 #[must_use]
1681 pub fn has_unique_distinct_precondition_kind(&self) -> bool {
1682 self.preconditions.has_unique_distinct_kind()
1683 }
1684
1685 /// `true` iff [`Self::postconditions`] carries EXACTLY ONE
1686 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
1687 /// the (precondition, postcondition, condition-union)
1688 /// cardinality-mid-endpoint triad on [`EphemeralSpec`] on the
1689 /// closed-set-inversion axis. Thin typed delegate to
1690 /// [`crate::boundary::ConditionSliceExt::has_unique_distinct_kind`]
1691 /// over [`Self::postconditions`].
1692 ///
1693 /// Peer of
1694 /// [`crate::boundary::Boundary::has_unique_distinct_postcondition_kind`]
1695 /// on the point-domain surface. See
1696 /// [`Self::has_unique_distinct_precondition_kind`] for the full
1697 /// rationale — the two methods share ONE lift motivation, ONE
1698 /// fail-before-pass-after composition-law pin, and ONE two-surface
1699 /// parity contract with the point-domain
1700 /// [`crate::boundary::Boundary`] cardinality-mid-endpoint peer
1701 /// methods.
1702 #[must_use]
1703 pub fn has_unique_distinct_postcondition_kind(&self) -> bool {
1704 self.postconditions.has_unique_distinct_kind()
1705 }
1706
1707 /// The SOLE [`ConditionKind::ALL`] variant covered by
1708 /// `preconditions ∪ postconditions`, or `None` when the union
1709 /// covers 0 or ≥ 2 kinds — the peer of
1710 /// [`crate::boundary::Boundary::unique_distinct_condition_kind`]
1711 /// on the [`EphemeralSpec`] sugar surface.
1712 ///
1713 /// # Composed body — byte-identical to
1714 /// [`crate::boundary::Boundary::unique_distinct_condition_kind`]
1715 ///
1716 /// A two-step-short-circuit walk over [`ConditionKind::ALL`] under
1717 /// the [`Self::has_condition_kind`] union primitive — pull the
1718 /// first hit; return `Some(first)` iff the second hit is [`None`],
1719 /// else `None`. Byte-identical to the peer method on the point-
1720 /// domain [`crate::boundary::Boundary`] surface — both compose
1721 /// against the SAME slice-level substrate primitive
1722 /// [`crate::boundary::ConditionSliceExt::unique_distinct_kind`]
1723 /// via the two-slice union so a regression at the per-slice
1724 /// singleton-coverage witnessing walk fails at that primitive's
1725 /// tests rather than as silent drift at either struct-level
1726 /// singleton-coverage caller.
1727 ///
1728 /// # Sibling to [`Self::has_unique_distinct_condition_kind`]
1729 ///
1730 /// Witnessing scalar peer of the Boolean cardinality-mid-endpoint
1731 /// predicate at the SAME two-step short-circuit shape — where
1732 /// `has_unique_distinct_condition_kind` returns `true` iff the
1733 /// union covers exactly one kind, `unique_distinct_condition_kind`
1734 /// returns `Some(k)` naming that SOLE covered kind (composition
1735 /// law `unique_distinct_condition_kind().is_some() ==
1736 /// has_unique_distinct_condition_kind()` binds the two).
1737 ///
1738 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1739 /// preserves proofs — the exactly-one-hit witnessing projection
1740 /// composes the SAME two-step short-circuit walk on both this
1741 /// ephemeral surface and the point-domain
1742 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
1743 /// (generation over composition — a future [`ConditionKind`]
1744 /// variant added to `ALL` reaches both surfaces' unique-distinct-
1745 /// kind triads mechanically through the SAME two-step short-
1746 /// circuit walk).
1747 #[must_use]
1748 pub fn unique_distinct_condition_kind(&self) -> Option<ConditionKind> {
1749 let mut it = ConditionKind::ALL
1750 .iter()
1751 .copied()
1752 .filter(|k| self.has_condition_kind(*k));
1753 let first = it.next()?;
1754 match it.next() {
1755 None => Some(first),
1756 Some(_) => None,
1757 }
1758 }
1759
1760 /// The SOLE [`ConditionKind::ALL`] variant covered by
1761 /// [`Self::preconditions`], or `None` when preconditions cover 0
1762 /// or ≥ 2 kinds — the precondition-side arm of the (precondition,
1763 /// postcondition, condition-union) exactly-one-hit witnessing
1764 /// triad on [`EphemeralSpec`] on the closed-set-inversion axis.
1765 /// Thin typed delegate to
1766 /// [`crate::boundary::ConditionSliceExt::unique_distinct_kind`]
1767 /// over [`Self::preconditions`].
1768 ///
1769 /// Peer of
1770 /// [`crate::boundary::Boundary::unique_distinct_precondition_kind`]
1771 /// on the point-domain surface — both peers compose against the
1772 /// SAME slice-level substrate primitive so a regression at the
1773 /// per-slice two-step short-circuit witnessing walk fails at that
1774 /// primitive's tests rather than as silent drift at either
1775 /// struct-level arm.
1776 #[must_use]
1777 pub fn unique_distinct_precondition_kind(&self) -> Option<ConditionKind> {
1778 self.preconditions.unique_distinct_kind()
1779 }
1780
1781 /// The SOLE [`ConditionKind::ALL`] variant covered by
1782 /// [`Self::postconditions`], or `None` when postconditions cover
1783 /// 0 or ≥ 2 kinds — the postcondition-side arm of the
1784 /// (precondition, postcondition, condition-union) exactly-one-hit
1785 /// witnessing triad on [`EphemeralSpec`] on the closed-set-
1786 /// inversion axis. Thin typed delegate to
1787 /// [`crate::boundary::ConditionSliceExt::unique_distinct_kind`]
1788 /// over [`Self::postconditions`].
1789 ///
1790 /// Peer of
1791 /// [`crate::boundary::Boundary::unique_distinct_postcondition_kind`]
1792 /// on the point-domain surface. See
1793 /// [`Self::unique_distinct_precondition_kind`] for the full
1794 /// rationale — the two methods share ONE lift motivation, ONE
1795 /// fail-before-pass-after composition-law pin, and ONE two-
1796 /// surface parity contract with the point-domain
1797 /// [`crate::boundary::Boundary`] unique-distinct-kind peer methods.
1798 #[must_use]
1799 pub fn unique_distinct_postcondition_kind(&self) -> Option<ConditionKind> {
1800 self.postconditions.unique_distinct_kind()
1801 }
1802
1803 /// `true` iff `preconditions ∪ postconditions` COVERS AT LEAST
1804 /// TWO [`ConditionKind::ALL`] variants — the union arm of the
1805 /// (precondition, postcondition, condition-union) cardinality-
1806 /// many-arm triad on [`EphemeralSpec`] closing the "≥ 2 kinds
1807 /// covered" arm on the union of the two condition slots. The
1808 /// Boolean cardinality many-arm fast-path peer of
1809 /// [`Self::has_unique_distinct_condition_kind`] (=1 arm) and
1810 /// [`Self::has_any_distinct_condition_kind`] (≥1 halfspace):
1811 /// closes the {0, 1, ≥2} trichotomy on the distinct axis at the
1812 /// ephemeral union struct layer.
1813 ///
1814 /// Composed body: constructs a two-step-short-circuit walk over
1815 /// [`ConditionKind::ALL`] under the [`Self::has_condition_kind`]
1816 /// union primitive — pulls up to two hits off the filtered
1817 /// iterator; the primitive returns `true` iff BOTH the first and
1818 /// the second are [`Some`]. Byte-for-byte peer of
1819 /// [`crate::boundary::ConditionSliceExt::has_multiple_distinct_kinds`]
1820 /// one slice-layer down, lifted to compose against
1821 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
1822 /// against a single slice's `has_kind`.
1823 ///
1824 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_multiple_distinct_condition_kind`]
1825 ///
1826 /// Byte-identical signature `(&Self) -> bool`, byte-identical
1827 /// two-step short-circuit body composed against the point-domain
1828 /// surface's own union primitive. Both methods compose against
1829 /// the SAME slice-level substrate primitive
1830 /// [`crate::boundary::ConditionSliceExt::has_multiple_distinct_kinds`]
1831 /// via the two-slice union — a regression at the per-slice many-
1832 /// arm walk fails at that primitive's tests rather than as silent
1833 /// drift at either struct-level many-distinct caller.
1834 ///
1835 /// # Sibling to [`Self::distinct_condition_kinds`] /
1836 /// [`Self::distinct_condition_kind_count`]
1837 ///
1838 /// Cardinality-many-arm Boolean projection of the widened +
1839 /// scalar closed-set-inversion primitives on the ephemeral-union
1840 /// surface — where those primitives return the FULL distinct SET
1841 /// (a `Vec` of every present kind) and its cardinality (a `usize`
1842 /// in `0..=ConditionKind::ALL.len()`),
1843 /// `has_multiple_distinct_condition_kind` collapses either the
1844 /// widened primitive to its ≥ 2-length Boolean or the scalar to
1845 /// its `>= 2` cardinality-many-arm Boolean. Strictly cheaper than
1846 /// either widened primitive on every arm with `≥ 2` distinct kinds
1847 /// because the walk short-circuits at the second distinct kind
1848 /// rather than allocating the closed-set-inversion scan or walking
1849 /// every slot to build the scalar cardinality.
1850 ///
1851 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1852 /// preserves proofs — the cardinality-many-arm projection on the
1853 /// distinct axis composes the SAME two-step short-circuit walk
1854 /// under a two-slice union on both this ephemeral surface and the
1855 /// point-domain [`crate::boundary::Boundary`] surface). THEORY.md
1856 /// §VI.1 (generation over composition — a new [`ConditionKind`]
1857 /// variant reaches both surfaces' cardinality-many-arm triads
1858 /// mechanically through the delegated union primitive).
1859 #[must_use]
1860 pub fn has_multiple_distinct_condition_kind(&self) -> bool {
1861 let mut it = ConditionKind::ALL
1862 .iter()
1863 .copied()
1864 .filter(|k| self.has_condition_kind(*k));
1865 it.next().is_some() && it.next().is_some()
1866 }
1867
1868 /// `true` iff [`Self::preconditions`] carries AT LEAST TWO
1869 /// [`ConditionKind::ALL`] variants — the precondition-side arm of
1870 /// the (precondition, postcondition, condition-union) cardinality-
1871 /// many-arm triad on [`EphemeralSpec`] on the closed-set-inversion
1872 /// axis. Thin typed delegate to
1873 /// [`crate::boundary::ConditionSliceExt::has_multiple_distinct_kinds`]
1874 /// over [`Self::preconditions`].
1875 ///
1876 /// Peer of
1877 /// [`crate::boundary::Boundary::has_multiple_distinct_precondition_kind`]
1878 /// on the point-domain surface — both peers compose against the
1879 /// SAME slice-level substrate primitive so a regression at the
1880 /// per-slice two-step short-circuit walk fails at that primitive's
1881 /// tests rather than as silent drift at either struct-level arm.
1882 #[must_use]
1883 pub fn has_multiple_distinct_precondition_kind(&self) -> bool {
1884 self.preconditions.has_multiple_distinct_kinds()
1885 }
1886
1887 /// `true` iff [`Self::postconditions`] carries AT LEAST TWO
1888 /// [`ConditionKind::ALL`] variants — the postcondition-side arm of
1889 /// the (precondition, postcondition, condition-union) cardinality-
1890 /// many-arm triad on [`EphemeralSpec`] on the closed-set-inversion
1891 /// axis. Thin typed delegate to
1892 /// [`crate::boundary::ConditionSliceExt::has_multiple_distinct_kinds`]
1893 /// over [`Self::postconditions`].
1894 ///
1895 /// Peer of
1896 /// [`crate::boundary::Boundary::has_multiple_distinct_postcondition_kind`]
1897 /// on the point-domain surface. See
1898 /// [`Self::has_multiple_distinct_precondition_kind`] for the full
1899 /// rationale — the two methods share ONE lift motivation, ONE
1900 /// fail-before-pass-after composition-law pin, and ONE two-surface
1901 /// parity contract with the point-domain
1902 /// [`crate::boundary::Boundary`] cardinality-many-arm peer
1903 /// methods.
1904 #[must_use]
1905 pub fn has_multiple_distinct_postcondition_kind(&self) -> bool {
1906 self.postconditions.has_multiple_distinct_kinds()
1907 }
1908
1909 /// `true` iff `preconditions ∪ postconditions` carries AT MOST ONE
1910 /// [`ConditionKind::ALL`] variant — the union arm of the
1911 /// (precondition, postcondition, condition-union) cardinality
1912 /// "≤ 1" triad on [`EphemeralSpec`] closing the "at most one kind
1913 /// covered" arm on the union of the two condition slots on the
1914 /// closed-set-inversion axis. The Boolean cardinality "≤ 1"
1915 /// negation peer of [`Self::has_multiple_distinct_condition_kind`]
1916 /// (≥ 2 many-arm) under the definitional negation
1917 /// `!has_multiple_distinct_condition_kind`, and the trichotomy-
1918 /// union peer of `!has_any_distinct_condition_kind` (=0 empty-
1919 /// endpoint) OR [`Self::has_unique_distinct_condition_kind`] (=1
1920 /// mid-endpoint) — names the arrangement space where the ephemeral
1921 /// spec is EMPTY-OR-SINGLETON on the union (zero or exactly one
1922 /// kind present across the union of the two slices).
1923 ///
1924 /// Composed body: `!self.has_multiple_distinct_condition_kind()`
1925 /// — a definitional negation of the many-arm union primitive.
1926 /// Short-circuits transitively through
1927 /// [`Self::has_multiple_distinct_condition_kind`]'s two-step
1928 /// short-circuit walk over [`ConditionKind::ALL`] under
1929 /// [`Self::has_condition_kind`]. Byte-for-byte peer of
1930 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_distinct_kind`]
1931 /// one slice-layer down, lifted to compose against
1932 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
1933 /// against a single slice's `has_kind`.
1934 ///
1935 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_at_most_one_distinct_condition_kind`]
1936 ///
1937 /// Byte-identical signature `(&Self) -> bool`, byte-identical
1938 /// definitional-negation body composed against the point-domain
1939 /// surface's own many-arm union primitive. Both methods compose
1940 /// against the SAME slice-level substrate primitive
1941 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_distinct_kind`]
1942 /// via the two-slice union — a regression at the per-slice "≤ 1"
1943 /// negation fails at that primitive's tests rather than as silent
1944 /// drift at either struct-level empty-or-singleton caller.
1945 ///
1946 /// # Sibling to [`Self::distinct_condition_kinds`] /
1947 /// [`Self::distinct_condition_kind_count`]
1948 ///
1949 /// Cardinality "≤ 1" Boolean projection of the widened + scalar
1950 /// closed-set-inversion primitives on the ephemeral-union
1951 /// surface — where those primitives return the FULL distinct SET
1952 /// (a `Vec` of every present kind) and its cardinality (a `usize`
1953 /// in `0..=ConditionKind::ALL.len()`),
1954 /// `has_at_most_one_distinct_condition_kind` collapses either the
1955 /// widened primitive to its `≤ 1`-length Boolean or the scalar
1956 /// to its `<= 1` cardinality-negation Boolean. Strictly cheaper
1957 /// than either widened primitive on every arm because the
1958 /// underlying many-arm walk short-circuits at the second distinct
1959 /// kind — a subsequent bit-flip surfaces at ONE substrate call
1960 /// with no allocation.
1961 ///
1962 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
1963 /// preserves proofs — the cardinality "≤ 1" projection on the
1964 /// distinct axis composes the SAME definitional negation of the
1965 /// many-arm two-step short-circuit walk on both this ephemeral
1966 /// surface and the point-domain [`crate::boundary::Boundary`]
1967 /// surface). THEORY.md §VI.1 (generation over composition — a
1968 /// new [`ConditionKind`] variant reaches both surfaces'
1969 /// cardinality "≤ 1" triads mechanically through the delegated
1970 /// union primitive).
1971 #[must_use]
1972 pub fn has_at_most_one_distinct_condition_kind(&self) -> bool {
1973 !self.has_multiple_distinct_condition_kind()
1974 }
1975
1976 /// `true` iff [`Self::preconditions`] carries AT MOST ONE
1977 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
1978 /// the (precondition, postcondition, condition-union) cardinality
1979 /// "≤ 1" triad on [`EphemeralSpec`]. Thin typed delegate to
1980 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_distinct_kind`]
1981 /// over [`Self::preconditions`].
1982 ///
1983 /// Peer of
1984 /// [`crate::boundary::Boundary::has_at_most_one_distinct_precondition_kind`]
1985 /// on the point-domain surface — both peers compose against the
1986 /// SAME slice-level substrate primitive so a regression at the
1987 /// per-slice "≤ 1" negation fails at that primitive's tests
1988 /// rather than as silent drift at either struct-level arm.
1989 #[must_use]
1990 pub fn has_at_most_one_distinct_precondition_kind(&self) -> bool {
1991 self.preconditions.has_at_most_one_distinct_kind()
1992 }
1993
1994 /// `true` iff [`Self::postconditions`] carries AT MOST ONE
1995 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
1996 /// the (precondition, postcondition, condition-union) cardinality
1997 /// "≤ 1" triad on [`EphemeralSpec`]. Thin typed delegate to
1998 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_distinct_kind`]
1999 /// over [`Self::postconditions`].
2000 ///
2001 /// Peer of
2002 /// [`crate::boundary::Boundary::has_at_most_one_distinct_postcondition_kind`]
2003 /// on the point-domain surface. See
2004 /// [`Self::has_at_most_one_distinct_precondition_kind`] for the
2005 /// full rationale — the two methods share ONE lift motivation,
2006 /// ONE fail-before-pass-after composition-law pin, and ONE two-
2007 /// surface parity contract with the point-domain
2008 /// [`crate::boundary::Boundary`] cardinality "≤ 1" peer methods.
2009 #[must_use]
2010 pub fn has_at_most_one_distinct_postcondition_kind(&self) -> bool {
2011 self.postconditions.has_at_most_one_distinct_kind()
2012 }
2013
2014 /// `true` iff `preconditions ∪ postconditions` carries NO
2015 /// [`ConditionKind::ALL`] variant — the peer of
2016 /// [`crate::boundary::Boundary::is_condition_kind_empty`] on the
2017 /// [`EphemeralSpec`] sugar surface. Names the cardinality zero-
2018 /// endpoint on the closed-set-inversion axis at the union struct
2019 /// layer.
2020 ///
2021 /// # Composed body — byte-identical to
2022 /// [`crate::boundary::Boundary::is_condition_kind_empty`]
2023 ///
2024 /// `!self.has_any_distinct_condition_kind()` — a definitional
2025 /// negation of the at-least-one halfspace union primitive. Byte-
2026 /// identical to the peer method on the point-domain
2027 /// [`crate::boundary::Boundary`] surface — both compose against
2028 /// the SAME slice-level substrate primitive
2029 /// [`crate::boundary::ConditionSliceExt::is_kind_empty`] via the
2030 /// two-slice union so a regression at the per-slice zero-endpoint
2031 /// short-circuit fails at that primitive's tests rather than as
2032 /// silent drift at either struct-level empty caller.
2033 ///
2034 /// # Sibling to [`Self::is_condition_kind_saturated`]
2035 ///
2036 /// Axis-parity mirror of the closed-set-complement saturation-
2037 /// endpoint peer at the union struct layer — where
2038 /// `is_condition_kind_saturated` tests "every kind PRESENT across
2039 /// the union", this primitive tests "no kind PRESENT across the
2040 /// union". Both name a cardinality-endpoint on their respective
2041 /// axis under the same union struct layer.
2042 ///
2043 /// # Sibling to [`Self::distinct_condition_kinds`] /
2044 /// [`Self::distinct_condition_kind_count`]
2045 ///
2046 /// Cardinality zero-endpoint Boolean projection of the widened +
2047 /// scalar closed-set-inversion primitives on the ephemeral-union
2048 /// surface — where those primitives return the FULL distinct SET
2049 /// and its cardinality, `is_condition_kind_empty` collapses either
2050 /// the widened primitive to its emptiness Boolean or the scalar to
2051 /// its `== 0` cardinality-endpoint Boolean.
2052 ///
2053 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2054 /// preserves proofs — the cardinality zero-endpoint projection on
2055 /// the distinct axis composes the SAME definitional negation of
2056 /// the at-least-one halfspace short-circuit walk on both this
2057 /// ephemeral surface and the point-domain
2058 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
2059 /// (generation over composition — a new [`ConditionKind`] variant
2060 /// reaches both surfaces' cardinality zero-endpoint triads
2061 /// mechanically through the delegated union primitive).
2062 #[must_use]
2063 pub fn is_condition_kind_empty(&self) -> bool {
2064 !self.has_any_distinct_condition_kind()
2065 }
2066
2067 /// `true` iff [`Self::preconditions`] carries NO
2068 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
2069 /// the (precondition, postcondition, condition-union) cardinality
2070 /// zero-endpoint triad on [`EphemeralSpec`]. Thin typed delegate to
2071 /// [`crate::boundary::ConditionSliceExt::is_kind_empty`] over
2072 /// [`Self::preconditions`].
2073 ///
2074 /// Peer of
2075 /// [`crate::boundary::Boundary::is_precondition_kind_empty`] on the
2076 /// point-domain surface — both peers compose against the SAME
2077 /// slice-level substrate primitive so a regression at the per-slice
2078 /// zero-endpoint short-circuit fails at that primitive's tests
2079 /// rather than as silent drift at either struct-level arm.
2080 #[must_use]
2081 pub fn is_precondition_kind_empty(&self) -> bool {
2082 self.preconditions.is_kind_empty()
2083 }
2084
2085 /// `true` iff [`Self::postconditions`] carries NO
2086 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
2087 /// the (precondition, postcondition, condition-union) cardinality
2088 /// zero-endpoint triad on [`EphemeralSpec`]. Thin typed delegate to
2089 /// [`crate::boundary::ConditionSliceExt::is_kind_empty`] over
2090 /// [`Self::postconditions`].
2091 ///
2092 /// Peer of
2093 /// [`crate::boundary::Boundary::is_postcondition_kind_empty`] on
2094 /// the point-domain surface. See
2095 /// [`Self::is_precondition_kind_empty`] for the full rationale —
2096 /// the two methods share ONE lift motivation, ONE fail-before-pass-
2097 /// after composition-law pin, and ONE two-surface parity contract
2098 /// with the point-domain [`crate::boundary::Boundary`] cardinality
2099 /// zero-endpoint peer methods.
2100 #[must_use]
2101 pub fn is_postcondition_kind_empty(&self) -> bool {
2102 self.postconditions.is_kind_empty()
2103 }
2104
2105 /// `true` iff `preconditions ∪ postconditions` carries AT LEAST ONE
2106 /// [`ConditionKind::ALL`] variant AND is MISSING AT LEAST ONE
2107 /// [`ConditionKind::ALL`] variant — the peer of
2108 /// [`crate::boundary::Boundary::is_condition_kind_partially_covered`]
2109 /// on the [`EphemeralSpec`] sugar surface. Names the parent-state
2110 /// middle-arm on the closed-set partition at the union struct
2111 /// layer, closing the trichotomy (empty, partially covered,
2112 /// saturated) alongside [`Self::is_condition_kind_empty`] and
2113 /// [`Self::is_condition_kind_saturated`].
2114 ///
2115 /// # Composed body — byte-identical to
2116 /// [`crate::boundary::Boundary::is_condition_kind_partially_covered`]
2117 ///
2118 /// `self.has_any_distinct_condition_kind() && self.has_any_missing_condition_kind()`
2119 /// — the paired at-least-one-halfspace composition. Byte-identical
2120 /// to the peer method on the point-domain
2121 /// [`crate::boundary::Boundary`] surface — both compose against the
2122 /// SAME slice-level substrate primitive
2123 /// [`crate::boundary::ConditionSliceExt::is_kind_partially_covered`]
2124 /// via the two-slice union so a regression at the per-slice fused
2125 /// short-circuit walk fails at that primitive's tests rather than
2126 /// as silent drift at either struct-level middle-arm caller.
2127 ///
2128 /// # Sibling to [`Self::is_condition_kind_empty`] / [`Self::is_condition_kind_saturated`]
2129 ///
2130 /// Third and final arm of the parent-state trichotomy on the
2131 /// closed-set partition at the ephemeral-union struct layer,
2132 /// closing the natural partition alongside `is_condition_kind_empty`
2133 /// (=0 zero-endpoint on the distinct axis) and
2134 /// `is_condition_kind_saturated` (=0 zero-endpoint on the missing
2135 /// axis). Every ephemeral spec satisfies EXACTLY ONE of the three
2136 /// Boolean projections on any `N ≥ 1` closed set.
2137 ///
2138 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2139 /// preserves proofs — the parent-state middle-arm projection
2140 /// composes the SAME paired-halfspace body on both this ephemeral
2141 /// surface and the point-domain [`crate::boundary::Boundary`]
2142 /// surface). THEORY.md §VI.1 (generation over composition — a new
2143 /// [`ConditionKind`] variant reaches both surfaces' parent-state
2144 /// middle-arm triads mechanically through the delegated union
2145 /// primitive).
2146 #[must_use]
2147 pub fn is_condition_kind_partially_covered(&self) -> bool {
2148 self.has_any_distinct_condition_kind() && self.has_any_missing_condition_kind()
2149 }
2150
2151 /// `true` iff [`Self::preconditions`] carries AT LEAST ONE
2152 /// [`ConditionKind::ALL`] variant AND is MISSING AT LEAST ONE
2153 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
2154 /// the (precondition, postcondition, condition-union) parent-state
2155 /// middle-arm triad on [`EphemeralSpec`]. Thin typed delegate to
2156 /// [`crate::boundary::ConditionSliceExt::is_kind_partially_covered`]
2157 /// over [`Self::preconditions`].
2158 ///
2159 /// Peer of
2160 /// [`crate::boundary::Boundary::is_precondition_kind_partially_covered`]
2161 /// on the point-domain surface — both peers compose against the
2162 /// SAME slice-level substrate primitive so a regression at the
2163 /// per-slice fused short-circuit walk fails at that primitive's
2164 /// tests rather than as silent drift at either struct-level arm.
2165 #[must_use]
2166 pub fn is_precondition_kind_partially_covered(&self) -> bool {
2167 self.preconditions.is_kind_partially_covered()
2168 }
2169
2170 /// `true` iff [`Self::postconditions`] carries AT LEAST ONE
2171 /// [`ConditionKind::ALL`] variant AND is MISSING AT LEAST ONE
2172 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
2173 /// the (precondition, postcondition, condition-union) parent-state
2174 /// middle-arm triad on [`EphemeralSpec`]. Thin typed delegate to
2175 /// [`crate::boundary::ConditionSliceExt::is_kind_partially_covered`]
2176 /// over [`Self::postconditions`].
2177 ///
2178 /// Peer of
2179 /// [`crate::boundary::Boundary::is_postcondition_kind_partially_covered`]
2180 /// on the point-domain surface. See
2181 /// [`Self::is_precondition_kind_partially_covered`] for the full
2182 /// rationale — the two methods share ONE lift motivation, ONE
2183 /// fail-before-pass-after composition-law pin, and ONE two-surface
2184 /// parity contract with the point-domain
2185 /// [`crate::boundary::Boundary`] parent-state middle-arm peer
2186 /// methods.
2187 #[must_use]
2188 pub fn is_postcondition_kind_partially_covered(&self) -> bool {
2189 self.postconditions.is_kind_partially_covered()
2190 }
2191
2192 /// `true` iff `preconditions ∪ postconditions` is MISSING EXACTLY
2193 /// ONE [`ConditionKind::ALL`] variant — the union arm of the
2194 /// (precondition, postcondition, condition-union) cardinality-
2195 /// mid-endpoint triad on [`EphemeralSpec`] closing the near-
2196 /// saturation-endpoint on the union of the two condition slots.
2197 /// The Boolean cardinality-mid-endpoint fast-path peer of
2198 /// [`Self::is_condition_kind_saturated`]: where the saturation-
2199 /// endpoint predicate answers "is the union covered by every ALL
2200 /// variant?", `has_unique_missing_condition_kind` answers "is the
2201 /// union one kind away from covered?".
2202 ///
2203 /// Composed body: constructs a two-step-short-circuit walk over
2204 /// [`ConditionKind::ALL`] under the [`Self::has_condition_kind`]
2205 /// union primitive negated — the first missing union arm surfaces,
2206 /// then the walk short-circuits at the second. Byte-for-byte peer
2207 /// of
2208 /// [`crate::boundary::ConditionSliceExt::has_unique_missing_kind`]
2209 /// one slice-layer down, lifted to compose against
2210 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
2211 /// against a single slice's `has_kind`.
2212 ///
2213 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_unique_missing_condition_kind`]
2214 ///
2215 /// Byte-identical signature `(&Self) -> bool`, byte-identical
2216 /// two-step short-circuit body composed against the point-domain
2217 /// surface's own union primitive. Both methods compose against
2218 /// the SAME slice-level substrate primitive
2219 /// [`crate::boundary::ConditionSliceExt::has_unique_missing_kind`]
2220 /// via the two-slice union — a regression at the per-slice
2221 /// near-saturation-endpoint walk fails at that primitive's tests
2222 /// rather than as silent drift at either struct-level near-
2223 /// saturation caller.
2224 ///
2225 /// # Sibling to [`Self::missing_condition_kinds`] /
2226 /// [`Self::missing_condition_kind_count`]
2227 ///
2228 /// Cardinality-mid-endpoint Boolean projection of the widened +
2229 /// scalar closed-set-complement primitives on the ephemeral-union
2230 /// surface — where those primitives return the FULL missing SET
2231 /// (a `Vec` of every absent kind) and its cardinality (a `usize`
2232 /// in `0..=ConditionKind::ALL.len()`),
2233 /// `has_unique_missing_condition_kind` collapses either the
2234 /// widened primitive to its unit-length Boolean or the scalar to
2235 /// its `== 1` cardinality-mid-endpoint Boolean. Strictly cheaper
2236 /// than either widened primitive on every arm with `≥ 2` missing
2237 /// kinds because the negation short-circuits at the second
2238 /// missing kind rather than allocating the closed-set-complement
2239 /// scan or walking every slot to build the scalar cardinality.
2240 ///
2241 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2242 /// preserves proofs — the cardinality-mid-endpoint projection on
2243 /// the missing axis composes the SAME two-step short-circuit walk
2244 /// under a two-slice union negation on both this ephemeral
2245 /// surface and the point-domain
2246 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
2247 /// (generation over composition — a new [`ConditionKind`]
2248 /// variant reaches both surfaces' cardinality-mid-endpoint triads
2249 /// mechanically through the delegated union primitive).
2250 #[must_use]
2251 pub fn has_unique_missing_condition_kind(&self) -> bool {
2252 let mut it = ConditionKind::ALL
2253 .iter()
2254 .copied()
2255 .filter(|k| !self.has_condition_kind(*k));
2256 it.next().is_some() && it.next().is_none()
2257 }
2258
2259 /// `true` iff [`Self::preconditions`] is MISSING EXACTLY ONE
2260 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
2261 /// the (precondition, postcondition, condition-union)
2262 /// cardinality-mid-endpoint triad on [`EphemeralSpec`]. Thin
2263 /// typed delegate to
2264 /// [`crate::boundary::ConditionSliceExt::has_unique_missing_kind`]
2265 /// over [`Self::preconditions`].
2266 ///
2267 /// Peer of
2268 /// [`crate::boundary::Boundary::has_unique_missing_precondition_kind`]
2269 /// on the point-domain surface — both peers compose against the
2270 /// SAME slice-level substrate primitive so a regression at the
2271 /// per-slice two-step short-circuit walk under negation fails at
2272 /// that primitive's tests rather than as silent drift at either
2273 /// struct-level arm.
2274 #[must_use]
2275 pub fn has_unique_missing_precondition_kind(&self) -> bool {
2276 self.preconditions.has_unique_missing_kind()
2277 }
2278
2279 /// `true` iff [`Self::postconditions`] is MISSING EXACTLY ONE
2280 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
2281 /// the (precondition, postcondition, condition-union)
2282 /// cardinality-mid-endpoint triad on [`EphemeralSpec`]. Thin
2283 /// typed delegate to
2284 /// [`crate::boundary::ConditionSliceExt::has_unique_missing_kind`]
2285 /// over [`Self::postconditions`].
2286 ///
2287 /// Peer of
2288 /// [`crate::boundary::Boundary::has_unique_missing_postcondition_kind`]
2289 /// on the point-domain surface. See
2290 /// [`Self::has_unique_missing_precondition_kind`] for the full
2291 /// rationale — the two methods share ONE lift motivation, ONE
2292 /// fail-before-pass-after composition-law pin, and ONE two-surface
2293 /// parity contract with the point-domain
2294 /// [`crate::boundary::Boundary`] cardinality-mid-endpoint peer
2295 /// methods.
2296 #[must_use]
2297 pub fn has_unique_missing_postcondition_kind(&self) -> bool {
2298 self.postconditions.has_unique_missing_kind()
2299 }
2300
2301 /// The SOLE [`ConditionKind::ALL`] variant ABSENT from
2302 /// `preconditions ∪ postconditions`, or `None` when the union is
2303 /// missing 0 or ≥ 2 kinds — the peer of
2304 /// [`crate::boundary::Boundary::unique_missing_condition_kind`]
2305 /// on the [`EphemeralSpec`] sugar surface.
2306 ///
2307 /// # Composed body — byte-identical to
2308 /// [`crate::boundary::Boundary::unique_missing_condition_kind`]
2309 ///
2310 /// A two-step-short-circuit walk over [`ConditionKind::ALL`] under
2311 /// a NEGATED [`Self::has_condition_kind`] union primitive — pull
2312 /// the first hit; return `Some(first)` iff the second hit is
2313 /// [`None`], else `None`. Byte-identical to the peer method on the
2314 /// point-domain [`crate::boundary::Boundary`] surface — both
2315 /// compose against the SAME slice-level substrate primitive
2316 /// [`crate::boundary::ConditionSliceExt::unique_missing_kind`] via
2317 /// the two-slice union so a regression at the per-slice near-
2318 /// saturation witnessing walk fails at that primitive's tests
2319 /// rather than as silent drift at either struct-level near-
2320 /// saturation caller.
2321 ///
2322 /// # Sibling to [`Self::has_unique_missing_condition_kind`]
2323 ///
2324 /// Witnessing scalar peer of the Boolean cardinality-mid-endpoint
2325 /// predicate on the missing axis at the SAME two-step short-
2326 /// circuit shape — where `has_unique_missing_condition_kind`
2327 /// returns `true` iff the union is one kind AWAY from covered,
2328 /// `unique_missing_condition_kind` returns `Some(k)` naming that
2329 /// SOLE remaining hole (composition law
2330 /// `unique_missing_condition_kind().is_some() ==
2331 /// has_unique_missing_condition_kind()` binds the two).
2332 ///
2333 /// # Compounding
2334 ///
2335 /// An operator-facing "one dependency still unfulfilled: X" gap-
2336 /// analysis diagnostic on an ephemeral env reads
2337 /// `spec.unique_missing_condition_kind()` at ONE call site — the
2338 /// WITNESS + the exactly-one predicate composed at ONE short-
2339 /// circuit walk, rather than pairing the Boolean
2340 /// [`Self::has_unique_missing_condition_kind`] with
2341 /// [`Self::first_missing_condition_kind`] at TWO independent
2342 /// walks.
2343 ///
2344 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2345 /// preserves proofs — the complement-exactly-one-hit witnessing
2346 /// projection composes the SAME two-step short-circuit walk on
2347 /// both this ephemeral surface and the point-domain
2348 /// [`crate::boundary::Boundary`] surface under a negated predicate).
2349 /// THEORY.md §VI.1 (generation over composition — a future
2350 /// [`ConditionKind`] variant added to `ALL` reaches both surfaces'
2351 /// unique-missing-kind triads mechanically through the SAME two-
2352 /// step short-circuit walk).
2353 #[must_use]
2354 pub fn unique_missing_condition_kind(&self) -> Option<ConditionKind> {
2355 let mut it = ConditionKind::ALL
2356 .iter()
2357 .copied()
2358 .filter(|k| !self.has_condition_kind(*k));
2359 let first = it.next()?;
2360 match it.next() {
2361 None => Some(first),
2362 Some(_) => None,
2363 }
2364 }
2365
2366 /// The SOLE [`ConditionKind::ALL`] variant ABSENT from
2367 /// [`Self::preconditions`], or `None` when preconditions are
2368 /// missing 0 or ≥ 2 kinds — the precondition-side arm of the
2369 /// (precondition, postcondition, condition-union) exactly-one-
2370 /// missing witnessing triad on [`EphemeralSpec`]. Thin typed
2371 /// delegate to
2372 /// [`crate::boundary::ConditionSliceExt::unique_missing_kind`]
2373 /// over [`Self::preconditions`].
2374 ///
2375 /// Peer of
2376 /// [`crate::boundary::Boundary::unique_missing_precondition_kind`]
2377 /// on the point-domain surface — both peers compose against the
2378 /// SAME slice-level substrate primitive so a regression at the
2379 /// per-slice two-step short-circuit witnessing walk under negation
2380 /// fails at that primitive's tests rather than as silent drift at
2381 /// either struct-level arm.
2382 #[must_use]
2383 pub fn unique_missing_precondition_kind(&self) -> Option<ConditionKind> {
2384 self.preconditions.unique_missing_kind()
2385 }
2386
2387 /// The SOLE [`ConditionKind::ALL`] variant ABSENT from
2388 /// [`Self::postconditions`], or `None` when postconditions are
2389 /// missing 0 or ≥ 2 kinds — the postcondition-side arm of the
2390 /// (precondition, postcondition, condition-union) exactly-one-
2391 /// missing witnessing triad on [`EphemeralSpec`]. Thin typed
2392 /// delegate to
2393 /// [`crate::boundary::ConditionSliceExt::unique_missing_kind`]
2394 /// over [`Self::postconditions`].
2395 ///
2396 /// Peer of
2397 /// [`crate::boundary::Boundary::unique_missing_postcondition_kind`]
2398 /// on the point-domain surface. See
2399 /// [`Self::unique_missing_precondition_kind`] for the full
2400 /// rationale — the two methods share ONE lift motivation, ONE
2401 /// fail-before-pass-after composition-law pin, and ONE two-surface
2402 /// parity contract with the point-domain
2403 /// [`crate::boundary::Boundary`] unique-missing-kind peer methods.
2404 #[must_use]
2405 pub fn unique_missing_postcondition_kind(&self) -> Option<ConditionKind> {
2406 self.postconditions.unique_missing_kind()
2407 }
2408
2409 /// `true` iff `preconditions ∪ postconditions` is MISSING AT
2410 /// LEAST TWO [`ConditionKind::ALL`] variants — the union arm of
2411 /// the (precondition, postcondition, condition-union) cardinality-
2412 /// many-arm triad on [`EphemeralSpec`] closing the "≥ 2 holes
2413 /// remaining" arm on the union of the two condition slots. The
2414 /// Boolean cardinality many-arm fast-path peer of
2415 /// [`Self::has_unique_missing_condition_kind`] (=1 arm) and
2416 /// [`Self::is_condition_kind_saturated`] (=0 arm): closes the
2417 /// {0, 1, ≥2} trichotomy on the missing axis at the ephemeral
2418 /// union struct layer.
2419 ///
2420 /// Composed body: constructs a two-step-short-circuit walk over
2421 /// [`ConditionKind::ALL`] under the [`Self::has_condition_kind`]
2422 /// union primitive negated — pulls up to two hits off the
2423 /// filtered iterator; the primitive returns `true` iff BOTH the
2424 /// first and the second are [`Some`]. Byte-for-byte peer of
2425 /// [`crate::boundary::ConditionSliceExt::has_multiple_missing_kinds`]
2426 /// one slice-layer down, lifted to compose against
2427 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
2428 /// against a single slice's `has_kind`.
2429 ///
2430 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_multiple_missing_condition_kind`]
2431 ///
2432 /// Byte-identical signature `(&Self) -> bool`, byte-identical
2433 /// two-step short-circuit body composed against the point-domain
2434 /// surface's own union primitive. Both methods compose against
2435 /// the SAME slice-level substrate primitive
2436 /// [`crate::boundary::ConditionSliceExt::has_multiple_missing_kinds`]
2437 /// via the two-slice union — a regression at the per-slice many-
2438 /// arm walk fails at that primitive's tests rather than as silent
2439 /// drift at either struct-level many-missing caller.
2440 ///
2441 /// # Sibling to [`Self::missing_condition_kinds`] /
2442 /// [`Self::missing_condition_kind_count`]
2443 ///
2444 /// Cardinality-many-arm Boolean projection of the widened +
2445 /// scalar closed-set-complement primitives on the ephemeral-union
2446 /// surface — where those primitives return the FULL missing SET
2447 /// (a `Vec` of every absent kind) and its cardinality (a `usize`
2448 /// in `0..=ConditionKind::ALL.len()`),
2449 /// `has_multiple_missing_condition_kind` collapses either the
2450 /// widened primitive to its ≥ 2-length Boolean or the scalar to
2451 /// its `>= 2` cardinality-many-arm Boolean. Strictly cheaper than
2452 /// either widened primitive on every arm with `≥ 2` missing kinds
2453 /// because the negation short-circuits at the second missing kind
2454 /// rather than allocating the closed-set-complement scan or
2455 /// walking every slot to build the scalar cardinality.
2456 ///
2457 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2458 /// preserves proofs — the cardinality-many-arm projection on the
2459 /// missing axis composes the SAME two-step short-circuit walk
2460 /// under a two-slice union negation on both this ephemeral
2461 /// surface and the point-domain
2462 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
2463 /// (generation over composition — a new [`ConditionKind`]
2464 /// variant reaches both surfaces' cardinality-many-arm triads
2465 /// mechanically through the delegated union primitive).
2466 #[must_use]
2467 pub fn has_multiple_missing_condition_kind(&self) -> bool {
2468 let mut it = ConditionKind::ALL
2469 .iter()
2470 .copied()
2471 .filter(|k| !self.has_condition_kind(*k));
2472 it.next().is_some() && it.next().is_some()
2473 }
2474
2475 /// `true` iff [`Self::preconditions`] is MISSING AT LEAST TWO
2476 /// [`ConditionKind::ALL`] variants — the precondition-side arm of
2477 /// the (precondition, postcondition, condition-union) cardinality-
2478 /// many-arm triad on [`EphemeralSpec`]. Thin typed delegate to
2479 /// [`crate::boundary::ConditionSliceExt::has_multiple_missing_kinds`]
2480 /// over [`Self::preconditions`].
2481 ///
2482 /// Peer of
2483 /// [`crate::boundary::Boundary::has_multiple_missing_precondition_kind`]
2484 /// on the point-domain surface — both peers compose against the
2485 /// SAME slice-level substrate primitive so a regression at the
2486 /// per-slice two-step short-circuit walk under negation fails at
2487 /// that primitive's tests rather than as silent drift at either
2488 /// struct-level arm.
2489 #[must_use]
2490 pub fn has_multiple_missing_precondition_kind(&self) -> bool {
2491 self.preconditions.has_multiple_missing_kinds()
2492 }
2493
2494 /// `true` iff [`Self::postconditions`] is MISSING AT LEAST TWO
2495 /// [`ConditionKind::ALL`] variants — the postcondition-side arm of
2496 /// the (precondition, postcondition, condition-union) cardinality-
2497 /// many-arm triad on [`EphemeralSpec`]. Thin typed delegate to
2498 /// [`crate::boundary::ConditionSliceExt::has_multiple_missing_kinds`]
2499 /// over [`Self::postconditions`].
2500 ///
2501 /// Peer of
2502 /// [`crate::boundary::Boundary::has_multiple_missing_postcondition_kind`]
2503 /// on the point-domain surface. See
2504 /// [`Self::has_multiple_missing_precondition_kind`] for the full
2505 /// rationale — the two methods share ONE lift motivation, ONE
2506 /// fail-before-pass-after composition-law pin, and ONE two-surface
2507 /// parity contract with the point-domain
2508 /// [`crate::boundary::Boundary`] cardinality-many-arm peer
2509 /// methods.
2510 #[must_use]
2511 pub fn has_multiple_missing_postcondition_kind(&self) -> bool {
2512 self.postconditions.has_multiple_missing_kinds()
2513 }
2514
2515 /// `true` iff `preconditions ∪ postconditions` is MISSING AT MOST
2516 /// ONE [`ConditionKind::ALL`] variant — the union arm of the
2517 /// (precondition, postcondition, condition-union) cardinality
2518 /// "≤ 1" triad on [`EphemeralSpec`] closing the "at most one hole
2519 /// remaining" arm on the union of the two condition slots. The
2520 /// Boolean cardinality "≤ 1" negation peer of
2521 /// [`Self::has_multiple_missing_condition_kind`] (≥ 2 many-arm)
2522 /// under the definitional negation
2523 /// `!has_multiple_missing_condition_kind`, and the trichotomy-
2524 /// union peer of [`Self::is_condition_kind_saturated`] (=0
2525 /// zero-arm) OR [`Self::has_unique_missing_condition_kind`] (=1
2526 /// mid-endpoint) — names the arrangement space where the
2527 /// ephemeral spec is SATURATED-OR-NEAR-SATURATED on the union
2528 /// (zero or exactly one kind missing across the union of the two
2529 /// slices).
2530 ///
2531 /// Composed body: `!self.has_multiple_missing_condition_kind()`
2532 /// — a definitional negation of the many-arm union primitive.
2533 /// Short-circuits transitively through
2534 /// [`Self::has_multiple_missing_condition_kind`]'s two-step short-
2535 /// circuit walk over [`ConditionKind::ALL`] under negated
2536 /// [`Self::has_condition_kind`]. Byte-for-byte peer of
2537 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_missing_kind`]
2538 /// one slice-layer down, lifted to compose against
2539 /// [`Self::has_condition_kind`]'s pre-OR-post union rather than
2540 /// against a single slice's `has_kind`.
2541 ///
2542 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_at_most_one_missing_condition_kind`]
2543 ///
2544 /// Byte-identical signature `(&Self) -> bool`, byte-identical
2545 /// definitional-negation body composed against the point-domain
2546 /// surface's own many-arm union primitive. Both methods compose
2547 /// against the SAME slice-level substrate primitive
2548 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_missing_kind`]
2549 /// via the two-slice union — a regression at the per-slice "≤ 1"
2550 /// negation fails at that primitive's tests rather than as silent
2551 /// drift at either struct-level near-saturation-or-saturated
2552 /// caller.
2553 ///
2554 /// # Sibling to [`Self::missing_condition_kinds`] /
2555 /// [`Self::missing_condition_kind_count`]
2556 ///
2557 /// Cardinality "≤ 1" Boolean projection of the widened + scalar
2558 /// closed-set-complement primitives on the ephemeral-union
2559 /// surface — where those primitives return the FULL missing SET
2560 /// (a `Vec` of every absent kind) and its cardinality (a `usize`
2561 /// in `0..=ConditionKind::ALL.len()`),
2562 /// `has_at_most_one_missing_condition_kind` collapses either the
2563 /// widened primitive to its `≤ 1`-length Boolean or the scalar
2564 /// to its `<= 1` cardinality-negation Boolean. Strictly cheaper
2565 /// than either widened primitive on every arm because the
2566 /// underlying many-arm walk short-circuits at the second missing
2567 /// kind — a subsequent bit-flip surfaces at ONE substrate call
2568 /// with no allocation.
2569 ///
2570 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2571 /// preserves proofs — the cardinality "≤ 1" projection on the
2572 /// missing axis composes the SAME definitional negation of the
2573 /// many-arm two-step short-circuit walk on both this ephemeral
2574 /// surface and the point-domain [`crate::boundary::Boundary`]
2575 /// surface). THEORY.md §VI.1 (generation over composition — a
2576 /// new [`ConditionKind`] variant reaches both surfaces'
2577 /// cardinality "≤ 1" triads mechanically through the delegated
2578 /// union primitive).
2579 #[must_use]
2580 pub fn has_at_most_one_missing_condition_kind(&self) -> bool {
2581 !self.has_multiple_missing_condition_kind()
2582 }
2583
2584 /// `true` iff [`Self::preconditions`] is MISSING AT MOST ONE
2585 /// [`ConditionKind::ALL`] variant — the precondition-side arm of
2586 /// the (precondition, postcondition, condition-union) cardinality
2587 /// "≤ 1" triad on [`EphemeralSpec`]. Thin typed delegate to
2588 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_missing_kind`]
2589 /// over [`Self::preconditions`].
2590 ///
2591 /// Peer of
2592 /// [`crate::boundary::Boundary::has_at_most_one_missing_precondition_kind`]
2593 /// on the point-domain surface — both peers compose against the
2594 /// SAME slice-level substrate primitive so a regression at the
2595 /// per-slice "≤ 1" negation fails at that primitive's tests
2596 /// rather than as silent drift at either struct-level arm.
2597 #[must_use]
2598 pub fn has_at_most_one_missing_precondition_kind(&self) -> bool {
2599 self.preconditions.has_at_most_one_missing_kind()
2600 }
2601
2602 /// `true` iff [`Self::postconditions`] is MISSING AT MOST ONE
2603 /// [`ConditionKind::ALL`] variant — the postcondition-side arm of
2604 /// the (precondition, postcondition, condition-union) cardinality
2605 /// "≤ 1" triad on [`EphemeralSpec`]. Thin typed delegate to
2606 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_missing_kind`]
2607 /// over [`Self::postconditions`].
2608 ///
2609 /// Peer of
2610 /// [`crate::boundary::Boundary::has_at_most_one_missing_postcondition_kind`]
2611 /// on the point-domain surface. See
2612 /// [`Self::has_at_most_one_missing_precondition_kind`] for the
2613 /// full rationale — the two methods share ONE lift motivation,
2614 /// ONE fail-before-pass-after composition-law pin, and ONE two-
2615 /// surface parity contract with the point-domain
2616 /// [`crate::boundary::Boundary`] cardinality "≤ 1" peer methods.
2617 #[must_use]
2618 pub fn has_at_most_one_missing_postcondition_kind(&self) -> bool {
2619 self.postconditions.has_at_most_one_missing_kind()
2620 }
2621
2622 /// `true` iff `preconditions ∪ postconditions` carries NO
2623 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2624 /// — the peer of
2625 /// [`crate::boundary::Boundary::lacks_condition_kind`] on the
2626 /// [`EphemeralSpec`] sugar surface.
2627 ///
2628 /// # Composed body — byte-identical to
2629 /// [`crate::boundary::Boundary::lacks_condition_kind`]
2630 ///
2631 /// `!self.has_condition_kind(kind)` — the definitional negation of
2632 /// the two-slice union primitive [`Self::has_condition_kind`].
2633 /// Byte-identical to the peer method on the point-domain
2634 /// [`crate::boundary::Boundary`] surface — both compose against
2635 /// the SAME slice-level substrate primitive
2636 /// [`crate::boundary::ConditionSliceExt::lacks_kind`] via the
2637 /// two-slice union so a regression at the per-slice negation
2638 /// fails at that primitive's tests rather than as silent drift at
2639 /// either struct-level complement caller.
2640 ///
2641 /// # Sibling to [`Self::missing_condition_kinds`] /
2642 /// [`Self::missing_condition_kind_count`]
2643 ///
2644 /// Per-kind Boolean projection of the widened + scalar closed-set-
2645 /// complement primitives on the ephemeral-union surface — where
2646 /// those primitives return the FULL missing SET (a `Vec` of every
2647 /// absent kind) and its cardinality (a `usize`),
2648 /// `lacks_condition_kind` collapses the missing SET to its
2649 /// per-kind membership Boolean for ONE addressed kind. Strictly
2650 /// cheaper than reaching for the widened primitive on every
2651 /// per-kind question because the negation short-circuits through
2652 /// [`Self::has_condition_kind`] rather than allocating the
2653 /// closed-set-complement scan.
2654 ///
2655 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2656 /// preserves proofs — the per-kind closed-set-complement
2657 /// projection composes the SAME two-slice union negation on both
2658 /// this ephemeral surface and the point-domain
2659 /// [`crate::boundary::Boundary`] surface under definitional
2660 /// negation). THEORY.md §VI.1 (generation over composition — a
2661 /// future [`ConditionKind`] variant reaches both surfaces'
2662 /// per-kind-complement triads mechanically through the delegated
2663 /// union primitive).
2664 #[must_use]
2665 pub fn lacks_condition_kind(&self, kind: ConditionKind) -> bool {
2666 !self.has_condition_kind(kind)
2667 }
2668
2669 /// `true` iff [`Self::preconditions`] carries NO
2670 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2671 /// — the precondition-side arm of the (precondition, postcondition,
2672 /// condition-union) per-kind-complement triad on [`EphemeralSpec`].
2673 /// Thin typed delegate to
2674 /// [`crate::boundary::ConditionSliceExt::lacks_kind`] over
2675 /// [`Self::preconditions`].
2676 ///
2677 /// Peer of
2678 /// [`crate::boundary::Boundary::lacks_precondition_kind`] on the
2679 /// point-domain surface — both peers compose against the SAME
2680 /// slice-level substrate primitive so a regression at the
2681 /// per-slice negation fails at that primitive's tests rather than
2682 /// as silent drift at either struct-level arm.
2683 #[must_use]
2684 pub fn lacks_precondition_kind(&self, kind: ConditionKind) -> bool {
2685 self.preconditions.lacks_kind(kind)
2686 }
2687
2688 /// `true` iff [`Self::postconditions`] carries NO
2689 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2690 /// — the postcondition-side arm of the (precondition, postcondition,
2691 /// condition-union) per-kind-complement triad on [`EphemeralSpec`].
2692 /// Thin typed delegate to
2693 /// [`crate::boundary::ConditionSliceExt::lacks_kind`] over
2694 /// [`Self::postconditions`].
2695 ///
2696 /// Peer of
2697 /// [`crate::boundary::Boundary::lacks_postcondition_kind`] on the
2698 /// point-domain surface. See [`Self::lacks_precondition_kind`] for
2699 /// the full rationale — the two methods share ONE lift motivation,
2700 /// ONE fail-before-pass-after composition-law pin, and ONE
2701 /// two-surface parity contract with the point-domain
2702 /// [`crate::boundary::Boundary`] per-kind-complement peer methods.
2703 #[must_use]
2704 pub fn lacks_postcondition_kind(&self, kind: ConditionKind) -> bool {
2705 self.postconditions.lacks_kind(kind)
2706 }
2707
2708 /// `true` iff `preconditions ∪ postconditions` carries at least
2709 /// one [`crate::boundary::Condition`] with the given
2710 /// [`ConditionKind`] AND carries no [`crate::boundary::Condition`]
2711 /// whose kind is anything OTHER than `kind` — the union arm of
2712 /// the (precondition, postcondition, condition-union) kind-scoped
2713 /// strict-refinement triad on [`EphemeralSpec`], byte-for-byte
2714 /// peer of the point-domain
2715 /// [`crate::boundary::Boundary::has_only_condition_kind`] under
2716 /// the same fused-closed-set-walk body.
2717 ///
2718 /// # Composed body
2719 ///
2720 /// A FUSED short-circuit closed-set walk over
2721 /// [`ConditionKind::ALL`] under [`Self::has_condition_kind`] that
2722 /// returns `false` at the EARLIEST kind whose presence spans
2723 /// either slice's populated set and is NOT `kind`, and returns
2724 /// `true` iff the sweep completes with `kind` seen as the sole
2725 /// distinct populated kind. Strictly cheaper than the widened
2726 /// composition
2727 /// `self.distinct_condition_kinds() == vec![kind]` (which
2728 /// allocates the distinct-kind Vec before the equality test) or
2729 /// the (pre, post) AND-of-strict-refinement
2730 /// `self.preconditions.has_only_kind(kind)
2731 /// && self.postconditions.has_only_kind(kind)` (which is TOO
2732 /// STRICT — a single-slice-populated arrangement whose empty side
2733 /// returns `false` fails this AND but IS well-formed on the
2734 /// union).
2735 ///
2736 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::has_only_condition_kind`]
2737 ///
2738 /// Byte-identical signature `(&Self, ConditionKind) -> bool`,
2739 /// byte-identical fused-closed-set-walk body, on the point-domain
2740 /// surface whose pre/post condition vectors live inside a
2741 /// [`crate::boundary::Boundary`] slot. Both methods compose
2742 /// against the SAME slice-level substrate primitive
2743 /// [`crate::boundary::ConditionSliceExt::has_only_kind`] via the
2744 /// two-slice union composed through [`Self::has_condition_kind`]
2745 /// — a regression at the per-slice fused walk fails at that
2746 /// primitive's tests rather than as silent drift at either
2747 /// struct-level kind-scoped-strict-refinement caller.
2748 ///
2749 /// # Compounding
2750 ///
2751 /// A future coherence check verifying "every ephemeral spec whose
2752 /// postconditions carry ONLY `ClosedLoopAuth` (no `JobAttested`,
2753 /// no `Cel`, ...) is a well-formed closed-loop probe" reads
2754 /// `spec.has_only_condition_kind(ConditionKind::ClosedLoopAuth)`
2755 /// at ONE call site rather than restating either widened
2756 /// composition. A `has-only-<kind>` require-tag classifier arm on
2757 /// the ephemeral surface reaches this primitive at ONE substrate
2758 /// call — byte-for-byte peer of the tagged-union
2759 /// `has-only-<kind>` classifier one struct-layer up under the
2760 /// SAME fused short-circuit walk shape.
2761 ///
2762 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2763 /// preserves proofs — the kind-scoped strict-refinement projection
2764 /// composes the SAME fused short-circuit closed-set walk under
2765 /// [`Self::has_condition_kind`] on both this ephemeral surface
2766 /// and the point-domain [`crate::boundary::Boundary`] surface).
2767 /// THEORY.md §VI.1 (generation over composition — a future
2768 /// [`ConditionKind`] variant reaches both surfaces' kind-scoped
2769 /// strict-refinement triads mechanically through the delegated
2770 /// union primitive).
2771 #[must_use]
2772 pub fn has_only_condition_kind(&self, kind: ConditionKind) -> bool {
2773 let mut saw_kind = false;
2774 for k in ConditionKind::ALL {
2775 if !self.has_condition_kind(k) {
2776 continue;
2777 }
2778 if k == kind {
2779 saw_kind = true;
2780 } else {
2781 return false;
2782 }
2783 }
2784 saw_kind
2785 }
2786
2787 /// `true` iff [`Self::preconditions`] carries at least one
2788 /// [`crate::boundary::Condition`] with the given
2789 /// [`ConditionKind`] AND carries no
2790 /// [`crate::boundary::Condition`] whose kind is anything OTHER
2791 /// than `kind` — the precondition-side arm of the (precondition,
2792 /// postcondition, condition-union) kind-scoped strict-refinement
2793 /// triad on [`EphemeralSpec`]. Thin typed delegate to
2794 /// [`crate::boundary::ConditionSliceExt::has_only_kind`] over
2795 /// [`Self::preconditions`].
2796 ///
2797 /// Peer of
2798 /// [`crate::boundary::Boundary::has_only_precondition_kind`] on
2799 /// the point-domain surface — both peers compose against the SAME
2800 /// slice-level substrate primitive so a regression at the per-
2801 /// slice fused walk fails at that primitive's tests rather than
2802 /// as silent drift at either struct-level arm.
2803 #[must_use]
2804 pub fn has_only_precondition_kind(&self, kind: ConditionKind) -> bool {
2805 self.preconditions.has_only_kind(kind)
2806 }
2807
2808 /// `true` iff [`Self::postconditions`] carries at least one
2809 /// [`crate::boundary::Condition`] with the given
2810 /// [`ConditionKind`] AND carries no
2811 /// [`crate::boundary::Condition`] whose kind is anything OTHER
2812 /// than `kind` — the postcondition-side arm of the (precondition,
2813 /// postcondition, condition-union) kind-scoped strict-refinement
2814 /// triad on [`EphemeralSpec`]. Thin typed delegate to
2815 /// [`crate::boundary::ConditionSliceExt::has_only_kind`] over
2816 /// [`Self::postconditions`].
2817 ///
2818 /// Peer of
2819 /// [`crate::boundary::Boundary::has_only_postcondition_kind`] on
2820 /// the point-domain surface. See [`Self::has_only_precondition_kind`]
2821 /// for the full rationale — the two methods share ONE lift
2822 /// motivation, ONE fail-before-pass-after composition-law pin,
2823 /// and ONE two-surface parity contract with the point-domain
2824 /// [`crate::boundary::Boundary`] kind-scoped-strict-refinement
2825 /// peer methods.
2826 #[must_use]
2827 pub fn has_only_postcondition_kind(&self, kind: ConditionKind) -> bool {
2828 self.postconditions.has_only_kind(kind)
2829 }
2830
2831 /// `true` iff `preconditions ∪ postconditions` carries NO
2832 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2833 /// AND carries at least one [`crate::boundary::Condition`] for
2834 /// every OTHER [`ConditionKind`] — the union arm of the
2835 /// (precondition, postcondition, condition-union) kind-scoped
2836 /// strict-refinement-on-missing triad on [`EphemeralSpec`], byte-
2837 /// for-byte peer of the point-domain
2838 /// [`crate::boundary::Boundary::lacks_only_condition_kind`] under
2839 /// the same fused-closed-set-walk body on the missing axis.
2840 ///
2841 /// # Composed body
2842 ///
2843 /// A FUSED short-circuit closed-set walk over
2844 /// [`ConditionKind::ALL`] under [`Self::has_condition_kind`] that
2845 /// skips every populated kind, returns `false` at the EARLIEST
2846 /// kind whose absence spans both slices' missing sets and is NOT
2847 /// `kind`, and returns `true` iff the sweep completes with `kind`
2848 /// seen as the sole missing kind. Strictly cheaper than the
2849 /// widened composition
2850 /// `self.missing_condition_kinds() == vec![kind]` (which allocates
2851 /// the missing-kind Vec before the equality test) or the
2852 /// (pre AND post) AND-of-strict-refinement
2853 /// `self.preconditions.lacks_only_kind(kind)
2854 /// && self.postconditions.lacks_only_kind(kind)` (which is TOO
2855 /// STRICT — a single-slice-populated arrangement whose empty side
2856 /// returns `false` fails this AND but IS well-formed on the
2857 /// union).
2858 ///
2859 /// # Peer on the point-domain surface — [`crate::boundary::Boundary::lacks_only_condition_kind`]
2860 ///
2861 /// Byte-identical signature `(&Self, ConditionKind) -> bool`,
2862 /// byte-identical fused-closed-set-walk body under complement, on
2863 /// the point-domain surface whose pre/post condition vectors live
2864 /// inside a [`crate::boundary::Boundary`] slot. Both methods
2865 /// compose against the SAME slice-level substrate primitive
2866 /// [`crate::boundary::ConditionSliceExt::lacks_only_kind`] via
2867 /// the two-slice union composed through
2868 /// [`Self::has_condition_kind`] — a regression at the per-slice
2869 /// fused walk under complement fails at that primitive's tests
2870 /// rather than as silent drift at either struct-level kind-scoped-
2871 /// strict-refinement-on-missing caller.
2872 ///
2873 /// # Compounding
2874 ///
2875 /// A future coherence check verifying "every partially-attested
2876 /// ephemeral closed-loop probe is missing ONLY the
2877 /// `ClosedLoopAuth` postcondition" reads
2878 /// `spec.lacks_only_condition_kind(ConditionKind::ClosedLoopAuth)`
2879 /// at ONE call site rather than restating either widened
2880 /// composition. A `lacks-only-<kind>` require-tag classifier arm
2881 /// on the ephemeral surface reaches this primitive at ONE
2882 /// substrate call — byte-for-byte peer of the tagged-union
2883 /// `lacks-only-<kind>` classifier one struct-layer up under the
2884 /// SAME fused short-circuit walk shape.
2885 ///
2886 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
2887 /// preserves proofs — the kind-scoped strict-refinement projection
2888 /// on the missing axis composes the SAME fused short-circuit
2889 /// closed-set walk under [`Self::has_condition_kind`] on both this
2890 /// ephemeral surface and the point-domain
2891 /// [`crate::boundary::Boundary`] surface). THEORY.md §VI.1
2892 /// (generation over composition — a future [`ConditionKind`]
2893 /// variant reaches both surfaces' kind-scoped-strict-refinement-
2894 /// on-missing triads mechanically through the delegated union
2895 /// primitive).
2896 #[must_use]
2897 pub fn lacks_only_condition_kind(&self, kind: ConditionKind) -> bool {
2898 let mut saw_kind = false;
2899 for k in ConditionKind::ALL {
2900 if self.has_condition_kind(k) {
2901 continue;
2902 }
2903 if k == kind {
2904 saw_kind = true;
2905 } else {
2906 return false;
2907 }
2908 }
2909 saw_kind
2910 }
2911
2912 /// `true` iff [`Self::preconditions`] carries NO
2913 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2914 /// AND carries at least one [`crate::boundary::Condition`] for
2915 /// every OTHER [`ConditionKind`] — the precondition-side arm of
2916 /// the (precondition, postcondition, condition-union) kind-scoped-
2917 /// strict-refinement-on-missing triad on [`EphemeralSpec`]. Thin
2918 /// typed delegate to
2919 /// [`crate::boundary::ConditionSliceExt::lacks_only_kind`] over
2920 /// [`Self::preconditions`].
2921 ///
2922 /// Peer of
2923 /// [`crate::boundary::Boundary::lacks_only_precondition_kind`] on
2924 /// the point-domain surface — both peers compose against the SAME
2925 /// slice-level substrate primitive so a regression at the per-
2926 /// slice fused walk under complement fails at that primitive's
2927 /// tests rather than as silent drift at either struct-level arm.
2928 #[must_use]
2929 pub fn lacks_only_precondition_kind(&self, kind: ConditionKind) -> bool {
2930 self.preconditions.lacks_only_kind(kind)
2931 }
2932
2933 /// `true` iff [`Self::postconditions`] carries NO
2934 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
2935 /// AND carries at least one [`crate::boundary::Condition`] for
2936 /// every OTHER [`ConditionKind`] — the postcondition-side arm of
2937 /// the (precondition, postcondition, condition-union) kind-scoped-
2938 /// strict-refinement-on-missing triad on [`EphemeralSpec`]. Thin
2939 /// typed delegate to
2940 /// [`crate::boundary::ConditionSliceExt::lacks_only_kind`] over
2941 /// [`Self::postconditions`].
2942 ///
2943 /// Peer of
2944 /// [`crate::boundary::Boundary::lacks_only_postcondition_kind`] on
2945 /// the point-domain surface. See [`Self::lacks_only_precondition_kind`]
2946 /// for the full rationale — the two methods share ONE lift
2947 /// motivation, ONE fail-before-pass-after composition-law pin,
2948 /// and ONE two-surface parity contract with the point-domain
2949 /// [`crate::boundary::Boundary`] kind-scoped-strict-refinement-
2950 /// on-missing peer methods.
2951 #[must_use]
2952 pub fn lacks_only_postcondition_kind(&self, kind: ConditionKind) -> bool {
2953 self.postconditions.lacks_only_kind(kind)
2954 }
2955
2956 /// `true` iff `preconditions ∪ postconditions` carries AT LEAST
2957 /// TWO [`crate::boundary::Condition`] values with the given
2958 /// [`ConditionKind`] — the union arm of the (precondition,
2959 /// postcondition, condition-union) per-kind cardinality "≥ 2"
2960 /// many-arm triad on [`EphemeralSpec`]. Composes a two-step-
2961 /// short-circuit walk over the chained per-kind iterator
2962 /// [`Self::iter_condition_kind`], which itself chains
2963 /// [`crate::boundary::ConditionSliceExt::iter_kind`] over
2964 /// [`Self::preconditions`] then [`Self::postconditions`].
2965 ///
2966 /// Peer of
2967 /// [`crate::boundary::Boundary::has_multiple_of_condition_kind`]
2968 /// on the point-domain surface — both peers compose against the
2969 /// SAME slice-level substrate primitive
2970 /// [`crate::boundary::ConditionSliceExt::has_multiple_of_kind`]
2971 /// via the two-slice chain, so a regression at the per-slice
2972 /// two-step short-circuit walk fails at that primitive's tests
2973 /// rather than as silent drift at either struct-level arm.
2974 #[must_use]
2975 pub fn has_multiple_of_condition_kind(&self, kind: ConditionKind) -> bool {
2976 let mut it = self.iter_condition_kind(kind);
2977 it.next().is_some() && it.next().is_some()
2978 }
2979
2980 /// `true` iff [`Self::preconditions`] carries AT LEAST TWO
2981 /// [`crate::boundary::Condition`] values with the given
2982 /// [`ConditionKind`] — the precondition-side arm of the
2983 /// (precondition, postcondition, condition-union) per-kind
2984 /// cardinality "≥ 2" many-arm triad on [`EphemeralSpec`]. Thin
2985 /// typed delegate to
2986 /// [`crate::boundary::ConditionSliceExt::has_multiple_of_kind`]
2987 /// over [`Self::preconditions`].
2988 ///
2989 /// Peer of
2990 /// [`crate::boundary::Boundary::has_multiple_of_precondition_kind`]
2991 /// on the point-domain surface — both peers compose against the
2992 /// SAME slice-level substrate primitive so a regression at the
2993 /// per-slice two-step short-circuit walk fails at that
2994 /// primitive's tests rather than as silent drift at either
2995 /// struct-level arm.
2996 #[must_use]
2997 pub fn has_multiple_of_precondition_kind(&self, kind: ConditionKind) -> bool {
2998 self.preconditions.has_multiple_of_kind(kind)
2999 }
3000
3001 /// `true` iff [`Self::postconditions`] carries AT LEAST TWO
3002 /// [`crate::boundary::Condition`] values with the given
3003 /// [`ConditionKind`] — the postcondition-side arm of the
3004 /// (precondition, postcondition, condition-union) per-kind
3005 /// cardinality "≥ 2" many-arm triad on [`EphemeralSpec`]. Thin
3006 /// typed delegate to
3007 /// [`crate::boundary::ConditionSliceExt::has_multiple_of_kind`]
3008 /// over [`Self::postconditions`].
3009 ///
3010 /// Peer of
3011 /// [`crate::boundary::Boundary::has_multiple_of_postcondition_kind`]
3012 /// on the point-domain surface. See
3013 /// [`Self::has_multiple_of_precondition_kind`] for the full
3014 /// rationale — the two methods share ONE lift motivation, ONE
3015 /// fail-before-pass-after composition-law pin, and ONE two-
3016 /// surface parity contract with the point-domain
3017 /// [`crate::boundary::Boundary`] per-kind-many-arm peer methods.
3018 #[must_use]
3019 pub fn has_multiple_of_postcondition_kind(&self, kind: ConditionKind) -> bool {
3020 self.postconditions.has_multiple_of_kind(kind)
3021 }
3022
3023 /// `true` iff `preconditions ∪ postconditions` carries EXACTLY
3024 /// ONE [`crate::boundary::Condition`] with the given
3025 /// [`ConditionKind`] — the union arm of the (precondition,
3026 /// postcondition, condition-union) per-kind cardinality "= 1"
3027 /// mid-endpoint triad on [`EphemeralSpec`]. Composes a two-step-
3028 /// short-circuit walk over the chained per-kind iterator
3029 /// [`Self::iter_condition_kind`], which itself chains
3030 /// [`crate::boundary::ConditionSliceExt::iter_kind`] over
3031 /// [`Self::preconditions`] then [`Self::postconditions`].
3032 ///
3033 /// Peer of
3034 /// [`crate::boundary::Boundary::has_unique_of_condition_kind`]
3035 /// on the point-domain surface — both peers compose against the
3036 /// SAME slice-level substrate primitive
3037 /// [`crate::boundary::ConditionSliceExt::has_unique_of_kind`]
3038 /// via the two-slice chain, so a regression at the per-slice
3039 /// two-step short-circuit walk fails at that primitive's tests
3040 /// rather than as silent drift at either struct-level arm.
3041 /// Middle arm of the {= 0, = 1, ≥ 2} per-kind cardinality
3042 /// Boolean trichotomy at the union level; alongside
3043 /// [`Self::lacks_condition_kind`] (= 0) and
3044 /// [`Self::has_multiple_of_condition_kind`] (≥ 2), the three
3045 /// Booleans PARTITION every non-negative multiplicity.
3046 #[must_use]
3047 pub fn has_unique_of_condition_kind(&self, kind: ConditionKind) -> bool {
3048 let mut it = self.iter_condition_kind(kind);
3049 it.next().is_some() && it.next().is_none()
3050 }
3051
3052 /// `true` iff [`Self::preconditions`] carries EXACTLY ONE
3053 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
3054 /// — the precondition-side arm of the (precondition,
3055 /// postcondition, condition-union) per-kind cardinality "= 1"
3056 /// mid-endpoint triad on [`EphemeralSpec`]. Thin typed delegate
3057 /// to [`crate::boundary::ConditionSliceExt::has_unique_of_kind`]
3058 /// over [`Self::preconditions`].
3059 ///
3060 /// Peer of
3061 /// [`crate::boundary::Boundary::has_unique_of_precondition_kind`]
3062 /// on the point-domain surface — both peers compose against the
3063 /// SAME slice-level substrate primitive so a regression at the
3064 /// per-slice two-step short-circuit walk fails at that
3065 /// primitive's tests rather than as silent drift at either
3066 /// struct-level arm.
3067 #[must_use]
3068 pub fn has_unique_of_precondition_kind(&self, kind: ConditionKind) -> bool {
3069 self.preconditions.has_unique_of_kind(kind)
3070 }
3071
3072 /// `true` iff [`Self::postconditions`] carries EXACTLY ONE
3073 /// [`crate::boundary::Condition`] with the given [`ConditionKind`]
3074 /// — the postcondition-side arm of the (precondition,
3075 /// postcondition, condition-union) per-kind cardinality "= 1"
3076 /// mid-endpoint triad on [`EphemeralSpec`]. Thin typed delegate
3077 /// to [`crate::boundary::ConditionSliceExt::has_unique_of_kind`]
3078 /// over [`Self::postconditions`].
3079 ///
3080 /// Peer of
3081 /// [`crate::boundary::Boundary::has_unique_of_postcondition_kind`]
3082 /// on the point-domain surface. See
3083 /// [`Self::has_unique_of_precondition_kind`] for the full
3084 /// rationale — the two methods share ONE lift motivation, ONE
3085 /// fail-before-pass-after composition-law pin, and ONE two-
3086 /// surface parity contract with the point-domain
3087 /// [`crate::boundary::Boundary`] per-kind-mid-endpoint peer
3088 /// methods.
3089 #[must_use]
3090 pub fn has_unique_of_postcondition_kind(&self, kind: ConditionKind) -> bool {
3091 self.postconditions.has_unique_of_kind(kind)
3092 }
3093
3094 /// `true` iff `preconditions ∪ postconditions` carries AT MOST
3095 /// ONE [`crate::boundary::Condition`] with the given
3096 /// [`ConditionKind`] — the union arm of the (precondition,
3097 /// postcondition, condition-union) per-kind cardinality "≤ 1"
3098 /// negation triad on [`EphemeralSpec`]. Closes the {= 0, = 1,
3099 /// ≥ 1, ≥ 2, ≤ 1} Boolean-cardinality grid on the per-kind axis
3100 /// at the union level on the ephemeral sugar surface alongside
3101 /// its sibling [`Self::has_multiple_of_condition_kind`] (≥ 2
3102 /// many-arm) under the definitional negation
3103 /// `!(≥ 2) == (≤ 1)`. Composes against the chained per-kind
3104 /// iterator [`Self::iter_condition_kind`] via the definitional
3105 /// negation `!self.has_multiple_of_condition_kind(kind)`.
3106 ///
3107 /// Peer of
3108 /// [`crate::boundary::Boundary::has_at_most_one_of_condition_kind`]
3109 /// on the point-domain surface — both peers compose against the
3110 /// SAME slice-level substrate primitive
3111 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_of_kind`]
3112 /// via the two-slice chain, so a regression at the per-slice
3113 /// definitional-negation walk fails at that primitive's tests
3114 /// rather than as silent drift at either struct-level arm.
3115 /// Trichotomy-union arm of the per-kind Boolean tetrachotomy
3116 /// on the ephemeral union: alongside `lacks_condition_kind`
3117 /// (= 0) and `has_unique_of_condition_kind` (= 1),
3118 /// `has_at_most_one_of_condition_kind` equals their disjunction
3119 /// (`lacks ∨ has_unique`) on every arm, byte-for-byte with
3120 /// `!has_multiple_of_condition_kind`.
3121 #[must_use]
3122 pub fn has_at_most_one_of_condition_kind(&self, kind: ConditionKind) -> bool {
3123 !self.has_multiple_of_condition_kind(kind)
3124 }
3125
3126 /// `true` iff [`Self::preconditions`] carries AT MOST ONE
3127 /// [`crate::boundary::Condition`] with the given
3128 /// [`ConditionKind`] — the precondition-side arm of the
3129 /// (precondition, postcondition, condition-union) per-kind
3130 /// cardinality "≤ 1" negation triad on [`EphemeralSpec`]. Thin
3131 /// typed delegate to
3132 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_of_kind`]
3133 /// over [`Self::preconditions`].
3134 ///
3135 /// Peer of
3136 /// [`crate::boundary::Boundary::has_at_most_one_of_precondition_kind`]
3137 /// on the point-domain surface — both peers compose against the
3138 /// SAME slice-level substrate primitive so a regression at the
3139 /// per-slice definitional-negation walk fails at that
3140 /// primitive's tests rather than as silent drift at either
3141 /// struct-level arm.
3142 #[must_use]
3143 pub fn has_at_most_one_of_precondition_kind(&self, kind: ConditionKind) -> bool {
3144 self.preconditions.has_at_most_one_of_kind(kind)
3145 }
3146
3147 /// `true` iff [`Self::postconditions`] carries AT MOST ONE
3148 /// [`crate::boundary::Condition`] with the given
3149 /// [`ConditionKind`] — the postcondition-side arm of the
3150 /// (precondition, postcondition, condition-union) per-kind
3151 /// cardinality "≤ 1" negation triad on [`EphemeralSpec`]. Thin
3152 /// typed delegate to
3153 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_of_kind`]
3154 /// over [`Self::postconditions`].
3155 ///
3156 /// Peer of
3157 /// [`crate::boundary::Boundary::has_at_most_one_of_postcondition_kind`]
3158 /// on the point-domain surface. See
3159 /// [`Self::has_at_most_one_of_precondition_kind`] for the full
3160 /// rationale — the two methods share ONE lift motivation, ONE
3161 /// fail-before-pass-after composition-law pin, and ONE two-
3162 /// surface parity contract with the point-domain
3163 /// [`crate::boundary::Boundary`] per-kind-"≤ 1" peer methods.
3164 #[must_use]
3165 pub fn has_at_most_one_of_postcondition_kind(&self, kind: ConditionKind) -> bool {
3166 self.postconditions.has_at_most_one_of_kind(kind)
3167 }
3168
3169 /// Returns the unique [`crate::boundary::Condition`] with the
3170 /// given [`ConditionKind`] in `preconditions ∪ postconditions`,
3171 /// or [`None`] if zero or `≥ 2` such conditions exist — the
3172 /// union arm of the (precondition, postcondition, condition-
3173 /// union) `Option<&Condition>`-witnessing peer of the Boolean
3174 /// [`Self::has_unique_of_condition_kind`] on the per-kind
3175 /// cardinality "= 1" mid-endpoint at the ephemeral surface.
3176 /// Composed body: a two-step short-circuit walk over the chained
3177 /// per-kind iterator [`Self::iter_condition_kind`]. Byte-for-
3178 /// byte peer of [`crate::boundary::Boundary::unique_of_condition_kind`]
3179 /// on the point-domain surface — both compose against the SAME
3180 /// slice-level substrate primitive
3181 /// [`crate::boundary::ConditionSliceExt::unique_of_kind`] via
3182 /// the two-slice chain.
3183 #[must_use]
3184 pub fn unique_of_condition_kind(
3185 &self,
3186 kind: ConditionKind,
3187 ) -> Option<&crate::boundary::Condition> {
3188 let mut it = self.iter_condition_kind(kind);
3189 let first = it.next()?;
3190 match it.next() {
3191 None => Some(first),
3192 Some(_) => None,
3193 }
3194 }
3195
3196 /// Returns the unique [`crate::boundary::Condition`] with the
3197 /// given [`ConditionKind`] in [`Self::preconditions`], or
3198 /// [`None`] — the precondition-side arm of the (precondition,
3199 /// postcondition, condition-union) `Option<&Condition>`-
3200 /// witnessing peer triad on [`EphemeralSpec`]. Thin typed
3201 /// delegate to [`crate::boundary::ConditionSliceExt::unique_of_kind`]
3202 /// over [`Self::preconditions`]. Peer of
3203 /// [`crate::boundary::Boundary::unique_of_precondition_kind`] on
3204 /// the point-domain surface — both compose against the SAME
3205 /// slice-level substrate primitive.
3206 #[must_use]
3207 pub fn unique_of_precondition_kind(
3208 &self,
3209 kind: ConditionKind,
3210 ) -> Option<&crate::boundary::Condition> {
3211 self.preconditions.unique_of_kind(kind)
3212 }
3213
3214 /// Returns the unique [`crate::boundary::Condition`] with the
3215 /// given [`ConditionKind`] in [`Self::postconditions`], or
3216 /// [`None`] — the postcondition-side arm of the (precondition,
3217 /// postcondition, condition-union) `Option<&Condition>`-
3218 /// witnessing peer triad on [`EphemeralSpec`]. Thin typed
3219 /// delegate to [`crate::boundary::ConditionSliceExt::unique_of_kind`]
3220 /// over [`Self::postconditions`]. Peer of
3221 /// [`crate::boundary::Boundary::unique_of_postcondition_kind`]
3222 /// on the point-domain surface. See
3223 /// [`Self::unique_of_precondition_kind`] for the full rationale —
3224 /// the two methods share ONE lift motivation, ONE fail-before-
3225 /// pass-after composition-law pin, and ONE two-surface parity
3226 /// contract with the point-domain
3227 /// [`crate::boundary::Boundary`] per-kind witness peer methods.
3228 #[must_use]
3229 pub fn unique_of_postcondition_kind(
3230 &self,
3231 kind: ConditionKind,
3232 ) -> Option<&crate::boundary::Condition> {
3233 self.postconditions.unique_of_kind(kind)
3234 }
3235
3236 /// Returns the LAST [`crate::boundary::Condition`] with the given
3237 /// [`ConditionKind`] in `preconditions ∪ postconditions`, or
3238 /// [`None`] when no match exists — the union arm of the
3239 /// (precondition, postcondition, condition-union) latest-position
3240 /// `Option<&Condition>`-witnessing peer of
3241 /// [`Self::find_condition_kind`] on the per-kind axis at the
3242 /// ephemeral surface. Composed body:
3243 /// `self.iter_condition_kind(kind).last()` — one walk over the
3244 /// pre-then-post chain that yields the terminal element. Byte-
3245 /// for-byte peer of [`crate::boundary::Boundary::last_condition_kind`]
3246 /// on the point-domain surface — both compose against the SAME
3247 /// slice-level substrate primitive
3248 /// [`crate::boundary::ConditionSliceExt::last_of_kind`] via the
3249 /// two-slice chain.
3250 #[must_use]
3251 pub fn last_condition_kind(&self, kind: ConditionKind) -> Option<&crate::boundary::Condition> {
3252 self.iter_condition_kind(kind).last()
3253 }
3254
3255 /// Returns the LAST [`crate::boundary::Condition`] with the given
3256 /// [`ConditionKind`] in [`Self::preconditions`], or [`None`] —
3257 /// the precondition-side arm of the (precondition, postcondition,
3258 /// condition-union) latest-position `Option<&Condition>`-witnessing
3259 /// peer triad on [`EphemeralSpec`]. Thin typed delegate to
3260 /// [`crate::boundary::ConditionSliceExt::last_of_kind`] over
3261 /// [`Self::preconditions`]. Peer of
3262 /// [`crate::boundary::Boundary::last_precondition_kind`] on the
3263 /// point-domain surface — both compose against the SAME slice-
3264 /// level substrate primitive.
3265 #[must_use]
3266 pub fn last_precondition_kind(
3267 &self,
3268 kind: ConditionKind,
3269 ) -> Option<&crate::boundary::Condition> {
3270 self.preconditions.last_of_kind(kind)
3271 }
3272
3273 /// Returns the LAST [`crate::boundary::Condition`] with the given
3274 /// [`ConditionKind`] in [`Self::postconditions`], or [`None`] —
3275 /// the postcondition-side arm of the (precondition, postcondition,
3276 /// condition-union) latest-position `Option<&Condition>`-witnessing
3277 /// peer triad on [`EphemeralSpec`]. Thin typed delegate to
3278 /// [`crate::boundary::ConditionSliceExt::last_of_kind`] over
3279 /// [`Self::postconditions`]. Peer of
3280 /// [`crate::boundary::Boundary::last_postcondition_kind`] on the
3281 /// point-domain surface. See [`Self::last_precondition_kind`] for
3282 /// the full rationale — the two methods share ONE lift motivation,
3283 /// ONE fail-before-pass-after composition-law pin, and ONE two-
3284 /// surface parity contract with the point-domain
3285 /// [`crate::boundary::Boundary`] per-kind latest-witness peer
3286 /// methods.
3287 #[must_use]
3288 pub fn last_postcondition_kind(
3289 &self,
3290 kind: ConditionKind,
3291 ) -> Option<&crate::boundary::Condition> {
3292 self.postconditions.last_of_kind(kind)
3293 }
3294
3295 /// Returns every [`crate::boundary::Condition`] with the given
3296 /// [`ConditionKind`] in `preconditions ∪ postconditions`, in walk
3297 /// order (precondition-slot matches first, postcondition-slot
3298 /// matches next), as a `Vec<&Condition>` — the union arm of the
3299 /// (precondition, postcondition, condition-union) materialized
3300 /// `Vec`-witnessing peer of [`Self::iter_condition_kind`] on the
3301 /// per-kind axis at the ephemeral surface. Composed body:
3302 /// `self.iter_condition_kind(kind).collect()` — one walk over
3303 /// the pre-then-post chain that materializes the whole match
3304 /// stream into a nameable owning collection. Byte-for-byte peer
3305 /// of [`crate::boundary::Boundary::all_of_condition_kind`] on
3306 /// the point-domain surface — both compose against the SAME
3307 /// slice-level substrate primitive
3308 /// [`crate::boundary::ConditionSliceExt::all_of_kind`] via the
3309 /// two-slice chain.
3310 #[must_use]
3311 pub fn all_of_condition_kind(&self, kind: ConditionKind) -> Vec<&crate::boundary::Condition> {
3312 self.iter_condition_kind(kind).collect()
3313 }
3314
3315 /// Returns every [`crate::boundary::Condition`] with the given
3316 /// [`ConditionKind`] in [`Self::preconditions`], in slice order,
3317 /// as a `Vec<&Condition>` — the precondition-side arm of the
3318 /// (precondition, postcondition, condition-union) materialized
3319 /// `Vec`-witnessing peer triad on [`EphemeralSpec`]. Thin typed
3320 /// delegate to [`crate::boundary::ConditionSliceExt::all_of_kind`]
3321 /// over [`Self::preconditions`]. Peer of
3322 /// [`crate::boundary::Boundary::all_of_precondition_kind`] on the
3323 /// point-domain surface — both compose against the SAME slice-
3324 /// level substrate primitive.
3325 #[must_use]
3326 pub fn all_of_precondition_kind(
3327 &self,
3328 kind: ConditionKind,
3329 ) -> Vec<&crate::boundary::Condition> {
3330 self.preconditions.all_of_kind(kind)
3331 }
3332
3333 /// Returns every [`crate::boundary::Condition`] with the given
3334 /// [`ConditionKind`] in [`Self::postconditions`], in slice order,
3335 /// as a `Vec<&Condition>` — the postcondition-side arm of the
3336 /// (precondition, postcondition, condition-union) materialized
3337 /// `Vec`-witnessing peer triad on [`EphemeralSpec`]. Thin typed
3338 /// delegate to [`crate::boundary::ConditionSliceExt::all_of_kind`]
3339 /// over [`Self::postconditions`]. Peer of
3340 /// [`crate::boundary::Boundary::all_of_postcondition_kind`] on
3341 /// the point-domain surface. See [`Self::all_of_precondition_kind`]
3342 /// for the full rationale — the two methods share ONE lift
3343 /// motivation, ONE fail-before-pass-after composition-law pin,
3344 /// and ONE two-surface parity contract with the point-domain
3345 /// [`crate::boundary::Boundary`] per-kind materialized-witness
3346 /// peer methods.
3347 #[must_use]
3348 pub fn all_of_postcondition_kind(
3349 &self,
3350 kind: ConditionKind,
3351 ) -> Vec<&crate::boundary::Condition> {
3352 self.postconditions.all_of_kind(kind)
3353 }
3354
3355 /// Returns the slice index of the FIRST
3356 /// [`crate::boundary::Condition`] carrying the given
3357 /// [`ConditionKind`] in `preconditions ∪ postconditions`, walking
3358 /// preconditions first — the union arm of the (precondition,
3359 /// postcondition, condition-union) index-domain peer of
3360 /// [`Self::find_condition_kind`] on the per-kind axis at the
3361 /// ephemeral surface. Composed body:
3362 /// `self.position_of_precondition_kind(k).or_else(||
3363 /// self.position_of_postcondition_kind(k))` — the returned
3364 /// [`usize`] refers to the slice whose half-arm produced the hit
3365 /// ([`Self::preconditions`] if the precondition-side arm yielded
3366 /// `Some`, otherwise [`Self::postconditions`]). Byte-for-byte
3367 /// peer of [`crate::boundary::Boundary::position_of_condition_kind`]
3368 /// on the point-domain surface — both compose against the SAME
3369 /// slice-level substrate primitive
3370 /// [`crate::boundary::ConditionSliceExt::position_of_kind`] via the
3371 /// two half-slice arms.
3372 #[must_use]
3373 pub fn position_of_condition_kind(&self, kind: ConditionKind) -> Option<usize> {
3374 self.position_of_precondition_kind(kind)
3375 .or_else(|| self.position_of_postcondition_kind(kind))
3376 }
3377
3378 /// Returns the slice index of the FIRST
3379 /// [`crate::boundary::Condition`] in [`Self::preconditions`]
3380 /// carrying the given [`ConditionKind`], or `None` — the
3381 /// precondition-side arm of the (precondition, postcondition,
3382 /// condition-union) index-domain peer triad on [`EphemeralSpec`].
3383 /// Thin typed delegate to
3384 /// [`crate::boundary::ConditionSliceExt::position_of_kind`] over
3385 /// [`Self::preconditions`]. Peer of
3386 /// [`crate::boundary::Boundary::position_of_precondition_kind`] on
3387 /// the point-domain surface — both compose against the SAME
3388 /// slice-level substrate primitive.
3389 #[must_use]
3390 pub fn position_of_precondition_kind(&self, kind: ConditionKind) -> Option<usize> {
3391 self.preconditions.position_of_kind(kind)
3392 }
3393
3394 /// Returns the slice index of the FIRST
3395 /// [`crate::boundary::Condition`] in [`Self::postconditions`]
3396 /// carrying the given [`ConditionKind`], or `None` — the
3397 /// postcondition-side arm of the (precondition, postcondition,
3398 /// condition-union) index-domain peer triad on [`EphemeralSpec`].
3399 /// Thin typed delegate to
3400 /// [`crate::boundary::ConditionSliceExt::position_of_kind`] over
3401 /// [`Self::postconditions`]. Peer of
3402 /// [`crate::boundary::Boundary::position_of_postcondition_kind`]
3403 /// on the point-domain surface. See
3404 /// [`Self::position_of_precondition_kind`] for the full rationale
3405 /// — the two methods share ONE lift motivation, ONE fail-before-
3406 /// pass-after composition-law pin, and ONE two-surface parity
3407 /// contract with the point-domain [`crate::boundary::Boundary`]
3408 /// index-domain peer methods.
3409 #[must_use]
3410 pub fn position_of_postcondition_kind(&self, kind: ConditionKind) -> Option<usize> {
3411 self.postconditions.position_of_kind(kind)
3412 }
3413
3414 /// True iff this ephemeral spec's stored [`TeardownPolicy`] equals
3415 /// `kind` — the substrate primitive that owns the
3416 /// (`&EphemeralSpec`, [`TeardownPolicy`]) → `bool` presence-probe
3417 /// shape on the sugar-surface type.
3418 ///
3419 /// # Peer to [`crate::lifetime::EphemeralLifetime::has_teardown_policy`]
3420 ///
3421 /// [`EphemeralLifetime::has_teardown_policy`] carries the same
3422 /// `(&self, TeardownPolicy) -> bool` signature on the point-surface
3423 /// carrier ([`ProcessSpec`]'s nested [`crate::lifetime::Lifetime`]
3424 /// slot reached through
3425 /// [`crate::lifetime::Lifetime::resolved_ephemeral`]); this peer
3426 /// composes byte-identical `==` semantics on
3427 /// [`EphemeralSpec`]'s direct `teardown: TeardownPolicy` scalar
3428 /// slot, so both surfaces' `teardown-policy-<kind>` require-tag
3429 /// families ([`crate::lifetime::EphemeralLifetime::has_teardown_policy`]
3430 /// on the point surface, this peer on the ephemeral surface) route
3431 /// through the SAME scalar `==` shape. A future normalization at
3432 /// the probe shape (a widened return carrying a `TerminatePolicy`
3433 /// disambiguator, a debug-build assertion on operator-set vs
3434 /// defaulted overrides, a fleet-wide warn on `Never` combined with
3435 /// short TTLs) lands at ONE site per surface and every downstream
3436 /// `teardown-policy-<kind>` require-tag family + closed-set audit
3437 /// dispatcher picks it up mechanically.
3438 ///
3439 /// # Semantics — VARIANT match, not POPULATED slot
3440 ///
3441 /// [`EphemeralSpec::teardown`] is a required, defaulted scalar
3442 /// ([`TeardownPolicy::Always`] via `#[default]`); there is no
3443 /// absent state to detect. `has_teardown_policy(kind)` returns
3444 /// `true` iff `self.teardown == kind`. On a hand-authored
3445 /// [`EphemeralSpec`] that omits `:teardown` from the
3446 /// `(defephemeral …)` form (or a Rust builder that reaches
3447 /// [`TeardownPolicy::default`]) the probe returns `true` for
3448 /// [`TeardownPolicy::Always`] and `false` for every other variant
3449 /// — distinct from the Option-slot axis where a default carrier
3450 /// returns `false` for EVERY kind. An operator who left
3451 /// `:teardown` at the substrate default IS configured for
3452 /// `Always`, and a `:requires (teardown-policy-Always)` check
3453 /// should pass; only an operator who deliberately overrode the
3454 /// policy to `OnAttested` / `OnFailed` / `Never` fails the tag on
3455 /// this axis.
3456 ///
3457 /// # Corner — (required-scalar-child)
3458 ///
3459 /// Fresh corner on the ephemeral surface's presence-probe algebra:
3460 /// [`EphemeralSpec`] has no Option-parent hop between the sugar
3461 /// struct and the `teardown` scalar (the point surface reaches
3462 /// [`crate::lifetime::EphemeralLifetime::teardown_policy`]
3463 /// through the Option-parent `resolved_ephemeral()` gate), so the
3464 /// probe body is a bare scalar `==` on a required field. Distinct
3465 /// from [`Self::has_condition_kind`] on this same surface, which
3466 /// walks a `Vec<Condition>` slice-child.
3467 ///
3468 /// # Compounding
3469 ///
3470 /// The ephemeral require-tag classifier composes this primitive
3471 /// with the closed-set `FromStr` autoderived on [`TeardownPolicy`]
3472 /// through the `strip_and_classify_prefixed_kind` substrate to
3473 /// publish a `teardown-policy-<kind>` prefix family byte-for-byte
3474 /// symmetrical with the point surface's family via
3475 /// [`crate::lifetime::EphemeralLifetime::has_teardown_policy`]. A
3476 /// future fifth [`TeardownPolicy`] variant added to `ALL` (a
3477 /// hypothetical `OnTimeout` for "tear down only on TTL expiry")
3478 /// reaches BOTH surfaces' `teardown-policy-<kind>` prefix families
3479 /// through the SAME closed-set walk with no per-caller edit — the
3480 /// two-surface symmetry means adding a variant on the closed set
3481 /// publishes it in lockstep across every downstream consumer.
3482 ///
3483 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
3484 /// preserves proofs — the scalar-carrier presence-probe body lives
3485 /// at ONE substrate site per surface so every downstream
3486 /// (`teardown-policy-<kind>` require-tag families on both surfaces
3487 /// in tatara-check, closed-set audit dispatchers, future variant
3488 /// additions on [`TeardownPolicy`]) binds through the SAME
3489 /// `has(kind)` shape rather than restating the `<eph>.teardown ==
3490 /// kind` closure body at each call site). THEORY.md §VI.1
3491 /// (generation over composition — a future variant lands at ONE
3492 /// `ALL` entry + one `as_str` arm on the closed set and the probe
3493 /// picks it up mechanically without further per-consumer edits).
3494 #[must_use]
3495 pub fn has_teardown_policy(&self, kind: TeardownPolicy) -> bool {
3496 self.teardown == kind
3497 }
3498
3499 /// Derived-bool-predicate presence probe on the stored
3500 /// [`Self::teardown`] slot — `true` iff this ephemeral sugar's
3501 /// [`TeardownPolicy`] would auto-SIGTERM the Process on the
3502 /// queried [`ProcessPhase`] transition (as read through
3503 /// [`TeardownPolicy::should_teardown_on`]).
3504 ///
3505 /// # Sibling to [`crate::lifetime::EphemeralLifetime::has_teardown_firing_on`]
3506 ///
3507 /// Same shape, same axis, one refinement lower: the point-surface
3508 /// peer on [`crate::lifetime::EphemeralLifetime`] composes the SAME
3509 /// [`TeardownPolicy::should_teardown_on`] predicate against the
3510 /// SAME stored `teardown_policy` slot; this method composes the
3511 /// same predicate against the sugar surface's flattened
3512 /// [`Self::teardown`] slot. Both bodies delegate to the ONE
3513 /// substrate owner [`TeardownPolicy::should_teardown_on`], so a
3514 /// regression at the (policy, phase) → bool truth table surfaces
3515 /// at THAT primitive's tests rather than as silent drift at
3516 /// either struct-level caller.
3517 ///
3518 /// # Corner — (required-scalar-parent × derived-bool-predicate-child)
3519 ///
3520 /// [`EphemeralSpec::teardown`] is a required, defaulted scalar
3521 /// ([`TeardownPolicy::Always`] via `#[default]`); there is no
3522 /// Option-parent hop between the sugar struct and the `teardown`
3523 /// scalar (the point surface reaches
3524 /// [`crate::lifetime::EphemeralLifetime::teardown_policy`]
3525 /// through the Option-parent `resolved_ephemeral()` gate). The
3526 /// probe body is a bare predicate application on a required
3527 /// field. Distinct from [`Self::has_teardown_policy`] on this
3528 /// same surface, which reads the raw stored variant for equality
3529 /// (`self.teardown == kind`) rather than the derived firing-arm
3530 /// predicate against a [`ProcessPhase`] argument.
3531 ///
3532 /// # Compounding
3533 ///
3534 /// The ephemeral require-tag classifier composes this primitive
3535 /// with the closed-set [`crate::phase::ProcessPhase`]'s
3536 /// autoderived `FromStr` through the
3537 /// `strip_and_classify_prefixed_kind` substrate to publish a
3538 /// `teardown-fires-on-<phase>` prefix family byte-for-byte
3539 /// symmetrical with the point surface's family via
3540 /// [`crate::lifetime::EphemeralLifetime::has_teardown_firing_on`].
3541 /// A future fifth [`TeardownPolicy`] variant added to `ALL` (a
3542 /// hypothetical `OnTimeout` for "tear down only on TTL expiry")
3543 /// reaches BOTH surfaces' `teardown-fires-on-<phase>` prefix
3544 /// families through the SAME
3545 /// [`TeardownPolicy::should_teardown_on`] match with no per-
3546 /// caller edit — the two-surface symmetry means adding a variant
3547 /// on the closed set publishes it in lockstep across every
3548 /// downstream consumer.
3549 ///
3550 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
3551 /// preserves proofs — the derived-bool-predicate presence-probe
3552 /// body lives at ONE substrate site per surface, both composing
3553 /// the SAME [`TeardownPolicy::should_teardown_on`] projection, so
3554 /// every downstream (`teardown-fires-on-<phase>` require-tag
3555 /// families on both surfaces in tatara-check, closed-set audit
3556 /// dispatchers, future variant additions on either
3557 /// [`TeardownPolicy`] or [`crate::phase::ProcessPhase`]) binds
3558 /// through the SAME `has_teardown_firing_on(phase)` shape rather
3559 /// than restating the `<eph>.teardown.should_teardown_on(phase)`
3560 /// closure body at each call site). THEORY.md §VI.1 (generation
3561 /// over composition — a future variant lands at ONE `ALL` entry +
3562 /// one `as_str` arm + one `should_teardown_on` arm on the closed
3563 /// set and the probe picks it up mechanically without further
3564 /// per-consumer edits).
3565 #[must_use]
3566 pub const fn has_teardown_firing_on(&self, phase: ProcessPhase) -> bool {
3567 self.teardown.should_teardown_on(phase)
3568 }
3569
3570 /// Resolve the operator-authored [`Self::classification`] slot to
3571 /// the concrete [`Classification`] the point surface sees, filling
3572 /// `None` through the same [`default_ephemeral_class`] baseline the
3573 /// `From<EphemeralSpec> for ProcessSpec` lowering uses when the
3574 /// operator omits `:classification` from the `(defephemeral …)`
3575 /// form. Returns [`Cow::Borrowed`] on the populated arm (zero
3576 /// allocation), else [`Cow::Owned`] with the workspace-baseline
3577 /// `(Gate, Compute, Bounded, Monotone, Internal)` value the sibling
3578 /// primitive [`Classification::gate_compute`] owns.
3579 ///
3580 /// # ONE substrate primitive for `Option<Classification>` resolution
3581 ///
3582 /// This is the ONE `EphemeralSpec`-inherent primitive that owns the
3583 /// `Option<Classification>` → resolved-[`Classification`] walk.
3584 /// Every downstream classification-axis presence probe on the
3585 /// [`EphemeralSpec`] surface ([`Self::has_point_type`],
3586 /// [`Self::has_substrate`], [`Self::has_calm`],
3587 /// [`Self::has_data_classification`], [`Self::has_horizon_kind`],
3588 /// [`Self::has_optimization_direction`], [`Self::has_input_arity`],
3589 /// [`Self::has_output_arity`]) routes through THIS
3590 /// primitive so the "`None` fills through
3591 /// [`default_ephemeral_class`]" resolution lives at ONE site rather
3592 /// than being restated in each per-axis probe body. A future
3593 /// regression on the fill-through (a shift from the `(Gate,
3594 /// Compute, …)` baseline to a different `default_ephemeral_class`
3595 /// body, a shift from the `Option`-carrier shape to a
3596 /// serde-defaulted required-field carrier, an eventual audit hook
3597 /// naming the resolved-vs-authored provenance) lands at ONE site
3598 /// and every downstream axis-probe on the ephemeral surface picks
3599 /// it up mechanically.
3600 ///
3601 /// # Sibling to the `From<EphemeralSpec>` lowering
3602 ///
3603 /// The lowering `From<EphemeralSpec> for ProcessSpec` fills
3604 /// [`ProcessSpec::classification`] through the SAME
3605 /// `.unwrap_or_else(default_ephemeral_class)` walk that this
3606 /// primitive owns on the borrow-friendly `Cow` return. Both sites
3607 /// resolve the same operator-authored slot through the same default
3608 /// so a future two-surface parity contract on the classification
3609 /// axes (`point-type-<kind>` on both surfaces, `substrate-<kind>`
3610 /// on both surfaces, …) reads identically through the sibling
3611 /// point-surface probe [`Classification::has_<axis>`] on the
3612 /// lowered `ProcessSpec` and through THIS primitive on the same
3613 /// authored [`EphemeralSpec`].
3614 ///
3615 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3616 /// preserves proofs; the `Option<Classification>` resolution body
3617 /// lives at ONE substrate primitive on the ephemeral surface so
3618 /// every downstream classification-axis probe binds through the
3619 /// SAME `resolved_classification()` shape rather than restating
3620 /// the `self.classification.as_ref().unwrap_or(&default_…)`
3621 /// closure body at each callsite. THEORY.md §VI.1 — generation
3622 /// over composition; a future classification-axis peer
3623 /// (`has_substrate`, `has_calm`, …) lands as ONE inherent method
3624 /// that delegates through the resolver's `has_<axis>(kind)` call
3625 /// on the sibling [`Classification`] closed-set primitive with no
3626 /// per-axis restatement of the fill-through logic.
3627 #[must_use]
3628 pub fn resolved_classification(&self) -> Cow<'_, Classification> {
3629 match &self.classification {
3630 Some(c) => Cow::Borrowed(c),
3631 None => Cow::Owned(default_ephemeral_class()),
3632 }
3633 }
3634
3635 /// Overlay a single [`ClassificationAxis`] variant onto this
3636 /// ephemeral spec's authored [`Self::classification`] slot, filling
3637 /// `None` through [`Classification::gate_compute`] before the
3638 /// overlay so the resulting slot carries `Some(_)` regardless of
3639 /// the pre-call state. Fluent chaining primitive: the peer of
3640 /// [`ProcessSpec::gate_compute_with_axis`] (fresh-spec × axis
3641 /// overlay) and [`Classification::with_axis`] (arbitrary-base ×
3642 /// axis overlay) on the ephemeral sugar surface.
3643 ///
3644 /// # Substrate ergonomics
3645 ///
3646 /// Pre-lift the four-line shape `let mut classification =
3647 /// Classification::gate_compute(); classification.<axis> =
3648 /// populated; let spec = EphemeralSpec { classification:
3649 /// Some(classification), ..ephemeral_fixture() };` (and its newer
3650 /// three-line peer `let classification =
3651 /// Classification::gate_compute_with_axis(populated); let spec =
3652 /// EphemeralSpec { classification: Some(classification),
3653 /// ..ephemeral_fixture() };`) recurred at THIRTY-SIX hand-authored
3654 /// callsites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger
3655 /// inside `tatara-reconciler::bin::tatara-check`'s
3656 /// `evaluate_ephemeral_require_tag_*` classifier-facing test
3657 /// module. Post-lift each callsite reads
3658 /// `let spec = ephemeral_fixture().with_classification_axis(populated);`
3659 /// — one line, one immutable binding, and every per-axis loop
3660 /// dispatches its per-iteration axis mutation through the SAME
3661 /// [`ClassificationAxis::overlay`] trait rather than by directly
3662 /// poking a `classification.<axis>` field or restating the
3663 /// `Some(_)` wrap.
3664 ///
3665 /// # Fluent chaining semantics
3666 ///
3667 /// * `EphemeralSpec { classification: None, .. }
3668 /// .with_classification_axis(axis)` produces
3669 /// `EphemeralSpec { classification:
3670 /// Some(Classification::gate_compute_with_axis(axis)), .. }` —
3671 /// the `None`-arm short-circuit fills through
3672 /// [`Classification::gate_compute`] identically to the sibling
3673 /// [`Self::resolved_classification`] resolver on the read side.
3674 /// * `EphemeralSpec { classification: Some(prior), .. }
3675 /// .with_classification_axis(axis)` produces
3676 /// `EphemeralSpec { classification: Some(prior.with_axis(axis)),
3677 /// .. }` — the axis overlay composes onto the existing carrier
3678 /// via [`ClassificationAxis::overlay`], preserving every other
3679 /// axis slot on `prior`. Chained calls
3680 /// `.with_classification_axis(a).with_classification_axis(b)`
3681 /// compose arbitrary N-axis conjunctions on the ephemeral
3682 /// sugar surface with the same order-independence guarantee
3683 /// [`Classification::with_axis`] carries on distinct-slot axes.
3684 ///
3685 /// # Sibling to [`ProcessSpec::gate_compute_with_axis`]
3686 ///
3687 /// Same (spec-carrier × axis) shape, one refinement lower on
3688 /// the composition-depth axis: `ProcessSpec::gate_compute_with_axis`
3689 /// owns the (fresh-`gate_compute_defaults`-spec × axis-overlay)
3690 /// construction on the point-surface carrier;
3691 /// [`Self::with_classification_axis`] owns the
3692 /// (arbitrary-`EphemeralSpec` × axis-overlay-onto-authored-classification)
3693 /// construction on the ephemeral sugar-surface carrier. Both
3694 /// primitives compose through the SAME
3695 /// [`ClassificationAxis::overlay`] trait so a regression on any
3696 /// axis's overlay surfaces at both composer owners' pin sets
3697 /// simultaneously.
3698 ///
3699 /// # Compounding
3700 ///
3701 /// A future SIXTH classification axis lands as ONE peer
3702 /// `impl ClassificationAxis` — every ephemeral-surface fixture
3703 /// that binds through this primitive picks up the sixth axis
3704 /// mechanically without a `classification.<new-axis> = value;`
3705 /// restatement per site. A future audit dispatcher walking the
3706 /// (ephemeral-surface × axis-loop) shape (per-axis matrix
3707 /// generator, closed-set-sweep sagas, per-axis-XOR-partition-
3708 /// witness synthesis on the ephemeral side) binds through the
3709 /// SAME composer regardless of which axis it targets. Directly
3710 /// benefits the P1 caixa-tatara renderer target
3711 /// (`(defaplicacao …)` → `Process` mechanical lowering test
3712 /// fixtures that construct authored classifications through the
3713 /// ephemeral sugar surface) and future ephemeral-surface XOR-
3714 /// partition landmark tests peer to the point-surface pins in
3715 /// `tatara-check.rs`.
3716 ///
3717 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3718 /// preserves proofs; the [`ClassificationAxis::overlay`] trait
3719 /// owns the axis-dispatch proof at ONE site and this primitive
3720 /// extends the ONE-site guarantee to the (ephemeral-spec ×
3721 /// authored-classification × axis-overlay) construction shape.
3722 /// THEORY.md §VI.1 — generation over composition; the 3-to-4-line
3723 /// hand-authored classification-then-wrap shape recurred at ≥ 36
3724 /// hand-authored callsites past the ★★ PRIME-DIRECTIVE ≥ 2
3725 /// duplication threshold and is lifted onto ONE substrate owner
3726 /// here.
3727 #[must_use]
3728 pub fn with_classification_axis<A: ClassificationAxis>(mut self, axis: A) -> Self {
3729 let mut c = self
3730 .classification
3731 .take()
3732 .unwrap_or_else(Classification::gate_compute);
3733 axis.overlay(&mut c);
3734 self.classification = Some(c);
3735 self
3736 }
3737
3738 /// True iff the resolved [`Classification`] carries the given
3739 /// [`ConvergencePointType`] on its `point_type` slot — byte-for-
3740 /// byte peer of [`Classification::has_point_type`] wrapped through
3741 /// the [`Self::resolved_classification`] resolver so an
3742 /// operator-omitted `:classification` slot reads as the
3743 /// [`default_ephemeral_class`] baseline the sibling
3744 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
3745 ///
3746 /// # Two-surface parity contract
3747 ///
3748 /// A given [`EphemeralSpec`] classifies identically through this
3749 /// primitive AND through
3750 /// `<eph.clone().into::<ProcessSpec>>().classification.has_point_type(kind)`
3751 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
3752 /// resolver on this side and the `.unwrap_or_else(...)` fill on
3753 /// the lowering side both dereference the same
3754 /// `default_ephemeral_class()` value on `None` and the same
3755 /// authored value on `Some(_)`. This means the ephemeral-surface
3756 /// `point-type-<kind>` `:requires` family in
3757 /// `tatara-reconciler::bin::tatara-check` publishes the SAME
3758 /// truth on the SAME authored spec as the point-surface family
3759 /// on the mechanically-lowered `ProcessSpec`.
3760 ///
3761 /// # Sibling to the seven other classification axes
3762 ///
3763 /// FIRST classification-axis peer on the [`EphemeralSpec`]
3764 /// surface. Six future sibling axes on the SAME `Cow`-resolver
3765 /// carrier ([`Self::has_substrate`] opened the SECOND,
3766 /// [`Self::has_calm`] the THIRD,
3767 /// [`Self::has_data_classification`] the FOURTH,
3768 /// [`Self::has_horizon_kind`] the FIFTH,
3769 /// [`Self::has_optimization_direction`] the SIXTH; then
3770 /// `has_input_arity`, `has_output_arity`) land as one-line
3771 /// wrappers around the SAME resolver + the sibling
3772 /// [`Classification`] closed-set primitive, so a future variant
3773 /// added to [`ConvergencePointType`] (or any of the seven other
3774 /// closed sets) reaches BOTH surfaces' `<axis>-<kind>` prefix
3775 /// families through the SAME closed-set walk with no per-caller
3776 /// edit.
3777 ///
3778 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3779 /// preserves proofs; the classification-axis presence-probe body
3780 /// composes ONE resolver primitive
3781 /// ([`Self::resolved_classification`]) with ONE closed-set
3782 /// primitive ([`Classification::has_point_type`]) so every
3783 /// downstream (`point-type-<kind>` require-tag families on both
3784 /// surfaces in tatara-check, closed-set audit dispatchers, future
3785 /// variant additions on [`ConvergencePointType`]) binds through
3786 /// the SAME `has(kind)` shape rather than restating either the
3787 /// resolver walk or the closed-set equality at the callsite.
3788 #[must_use]
3789 pub fn has_point_type(&self, kind: ConvergencePointType) -> bool {
3790 self.resolved_classification().has_point_type(kind)
3791 }
3792
3793 /// True iff the resolved [`Classification`] carries the given
3794 /// [`SubstrateType`] on its `substrate` slot — byte-for-byte peer
3795 /// of [`Classification::has_substrate`] wrapped through the
3796 /// [`Self::resolved_classification`] resolver so an operator-
3797 /// omitted `:classification` slot reads as the
3798 /// [`default_ephemeral_class`] baseline the sibling
3799 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
3800 ///
3801 /// # Two-surface parity contract
3802 ///
3803 /// A given [`EphemeralSpec`] classifies identically through this
3804 /// primitive AND through
3805 /// `<eph.clone().into::<ProcessSpec>>().classification.has_substrate(kind)`
3806 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
3807 /// resolver on this side and the `.unwrap_or_else(...)` fill on
3808 /// the lowering side both dereference the same
3809 /// `default_ephemeral_class()` value on `None` and the same
3810 /// authored value on `Some(_)`. This means the ephemeral-surface
3811 /// `substrate-<kind>` `:requires` family in
3812 /// `tatara-reconciler::bin::tatara-check` publishes the SAME
3813 /// truth on the SAME authored spec as the point-surface family
3814 /// on the mechanically-lowered `ProcessSpec`.
3815 ///
3816 /// # SECOND classification-axis peer on the ephemeral surface
3817 ///
3818 /// Peer of [`Self::has_point_type`] — both route through the SAME
3819 /// [`Self::resolved_classification`] resolver, so the operator-
3820 /// omitted `:classification` slot's fill-through logic lives at
3821 /// ONE substrate primitive rather than being restated in each
3822 /// per-axis probe body. Five future sibling axes on the SAME
3823 /// `Cow`-resolver carrier ([`Self::has_calm`] opened the THIRD,
3824 /// [`Self::has_data_classification`] the FOURTH,
3825 /// [`Self::has_horizon_kind`] the FIFTH,
3826 /// [`Self::has_optimization_direction`] the SIXTH; then
3827 /// `has_input_arity`, `has_output_arity`) land as one-line
3828 /// wrappers around the SAME resolver + the sibling
3829 /// [`Classification`] closed-set primitive, so a future variant
3830 /// added to [`SubstrateType`] (or any of the six other closed
3831 /// sets) reaches BOTH surfaces' `<axis>-<kind>` prefix families
3832 /// through the SAME closed-set walk with no per-caller edit.
3833 ///
3834 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3835 /// preserves proofs; the classification-axis presence-probe body
3836 /// composes ONE resolver primitive
3837 /// ([`Self::resolved_classification`]) with ONE closed-set
3838 /// primitive ([`Classification::has_substrate`]) so every
3839 /// downstream (`substrate-<kind>` require-tag families on both
3840 /// surfaces in tatara-check, closed-set audit dispatchers, future
3841 /// variant additions on [`SubstrateType`]) binds through the
3842 /// SAME `has(kind)` shape rather than restating either the
3843 /// resolver walk or the closed-set equality at the callsite.
3844 #[must_use]
3845 pub fn has_substrate(&self, kind: SubstrateType) -> bool {
3846 self.resolved_classification().has_substrate(kind)
3847 }
3848
3849 /// True iff the resolved [`Classification`] carries the given
3850 /// [`CalmClassification`] on its `calm` slot — byte-for-byte peer
3851 /// of [`Classification::has_calm`] wrapped through the
3852 /// [`Self::resolved_classification`] resolver so an operator-
3853 /// omitted `:classification` slot reads as the
3854 /// [`default_ephemeral_class`] baseline the sibling
3855 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
3856 ///
3857 /// # Two-surface parity contract
3858 ///
3859 /// A given [`EphemeralSpec`] classifies identically through this
3860 /// primitive AND through
3861 /// `<eph.clone().into::<ProcessSpec>>().classification.has_calm(kind)`
3862 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
3863 /// resolver on this side and the `.unwrap_or_else(...)` fill on
3864 /// the lowering side both dereference the same
3865 /// `default_ephemeral_class()` value on `None` and the same
3866 /// authored value on `Some(_)`. This means the ephemeral-surface
3867 /// `calm-<kind>` `:requires` family in
3868 /// `tatara-reconciler::bin::tatara-check` publishes the SAME
3869 /// truth on the SAME authored spec as the point-surface family
3870 /// on the mechanically-lowered `ProcessSpec`.
3871 ///
3872 /// # THIRD classification-axis peer on the ephemeral surface
3873 ///
3874 /// Peer of [`Self::has_point_type`] and [`Self::has_substrate`] —
3875 /// all three route through the SAME
3876 /// [`Self::resolved_classification`] resolver, so the operator-
3877 /// omitted `:classification` slot's fill-through logic lives at
3878 /// ONE substrate primitive rather than being restated in each
3879 /// per-axis probe body. FIRST occupant on the (Option-parent ×
3880 /// DEFAULTED-scalar-child × operator-resolvable-baseline) corner
3881 /// of the ephemeral-surface presence-probe algebra — distinct
3882 /// from the (Option-parent × NON-DEFAULT-scalar-child) corner
3883 /// the first two classification-axis peers opened, since
3884 /// [`CalmClassification`] carries `#[default] = Monotone` on the
3885 /// closed set. The default-arm short-circuit on the absent-
3886 /// classification arm reads `true` on the [`CalmClassification`]
3887 /// child's `#[default]` variant precisely because BOTH the parent
3888 /// Option's fill-through baseline (`default_ephemeral_class`) AND
3889 /// the child's own `#[default]` land on the SAME variant
3890 /// ([`CalmClassification::Monotone`]) — a two-defaults
3891 /// composition property distinct from the NON-DEFAULT-scalar
3892 /// peers, whose absent-classification arm defaults through a
3893 /// specific chosen baseline (`ConvergencePointType::Gate`,
3894 /// `SubstrateType::Compute`) rather than through the child's own
3895 /// `#[default]`. Four future sibling axes on the SAME
3896 /// `Cow`-resolver carrier ([`Self::has_data_classification`]
3897 /// opened the FOURTH, [`Self::has_horizon_kind`] the FIFTH,
3898 /// [`Self::has_optimization_direction`] the SIXTH; then
3899 /// `has_input_arity`, `has_output_arity`) land as one-line
3900 /// wrappers around the SAME resolver + the sibling
3901 /// [`Classification`] closed-set primitive, so a future variant
3902 /// added to [`CalmClassification`] (or any of the five other
3903 /// closed sets) reaches BOTH surfaces' `<axis>-<kind>` prefix
3904 /// families through the SAME closed-set walk with no per-caller
3905 /// edit.
3906 ///
3907 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3908 /// preserves proofs; the classification-axis presence-probe body
3909 /// composes ONE resolver primitive
3910 /// ([`Self::resolved_classification`]) with ONE closed-set
3911 /// primitive ([`Classification::has_calm`]) so every downstream
3912 /// (`calm-<kind>` require-tag families on both surfaces in
3913 /// tatara-check, closed-set audit dispatchers, future variant
3914 /// additions on [`CalmClassification`]) binds through the SAME
3915 /// `has(kind)` shape rather than restating either the resolver
3916 /// walk or the closed-set equality at the callsite.
3917 #[must_use]
3918 pub fn has_calm(&self, kind: CalmClassification) -> bool {
3919 self.resolved_classification().has_calm(kind)
3920 }
3921
3922 /// True iff the resolved [`Classification`] carries the given
3923 /// [`DataClassification`] on its `data_classification` slot —
3924 /// byte-for-byte peer of [`Classification::has_data_classification`]
3925 /// wrapped through the [`Self::resolved_classification`] resolver
3926 /// so an operator-omitted `:classification` slot reads as the
3927 /// [`default_ephemeral_class`] baseline the sibling
3928 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
3929 ///
3930 /// # Two-surface parity contract
3931 ///
3932 /// A given [`EphemeralSpec`] classifies identically through this
3933 /// primitive AND through
3934 /// `<eph.clone().into::<ProcessSpec>>().classification.has_data_classification(kind)`
3935 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
3936 /// resolver on this side and the `.unwrap_or_else(...)` fill on
3937 /// the lowering side both dereference the same
3938 /// `default_ephemeral_class()` value on `None` and the same
3939 /// authored value on `Some(_)`. This means the ephemeral-surface
3940 /// `data-classification-<kind>` `:requires` family in
3941 /// `tatara-reconciler::bin::tatara-check` publishes the SAME
3942 /// truth on the SAME authored spec as the point-surface family
3943 /// on the mechanically-lowered `ProcessSpec`.
3944 ///
3945 /// # FOURTH classification-axis peer on the ephemeral surface
3946 ///
3947 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`], and
3948 /// [`Self::has_calm`] — all four route through the SAME
3949 /// [`Self::resolved_classification`] resolver, so the operator-
3950 /// omitted `:classification` slot's fill-through logic lives at
3951 /// ONE substrate primitive rather than being restated in each
3952 /// per-axis probe body. SECOND occupant on the (Option-parent ×
3953 /// DEFAULTED-scalar-child × operator-resolvable-baseline) corner
3954 /// of the ephemeral-surface presence-probe algebra alongside
3955 /// [`Self::has_calm`] — both probe REQUIRED [`Classification`]
3956 /// sub-slots whose child closed set carries its own `#[default]`
3957 /// ([`DataClassification::Internal`] here,
3958 /// [`CalmClassification::Monotone`] on the peer), so the
3959 /// default-arm short-circuit on the absent-classification arm
3960 /// reads `true` on the [`DataClassification`] child's
3961 /// `#[default]` variant precisely because BOTH the parent
3962 /// Option's fill-through baseline (`default_ephemeral_class`)
3963 /// AND the child's own `#[default]` land on the SAME variant
3964 /// ([`DataClassification::Internal`]). The two-defaults
3965 /// composition property now walks TWO independent defaulted-
3966 /// scalar-child slots on the SAME ephemeral resolver — a
3967 /// regression that promoted a different [`DataClassification`]
3968 /// variant to `#[default]` (or wired the arm to a fixed variant
3969 /// answer) fails HERE at ONE narrow substrate site before
3970 /// drifting through every unadorned ephemeral spec's baseline
3971 /// data-classification answer. Distinct from the FIRST + SECOND
3972 /// peers on the (Option-parent × NON-DEFAULT-scalar-child)
3973 /// corner, whose absent-classification arm defaults through a
3974 /// specific chosen baseline (`ConvergencePointType::Gate`,
3975 /// `SubstrateType::Compute`) rather than through the child's own
3976 /// `#[default]`. Four future sibling axes on the SAME
3977 /// `Cow`-resolver carrier ([`Self::has_horizon_kind`] opened the
3978 /// FIFTH, [`Self::has_optimization_direction`] the SIXTH; then
3979 /// `has_input_arity`, `has_output_arity`) land as one-line
3980 /// wrappers around the SAME resolver + the sibling
3981 /// [`Classification`] closed-set primitive, so a future variant
3982 /// added to [`DataClassification`] (or any of the four other
3983 /// closed sets) reaches BOTH surfaces' `<axis>-<kind>` prefix
3984 /// families through the SAME closed-set walk with no per-caller
3985 /// edit.
3986 ///
3987 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
3988 /// preserves proofs; the classification-axis presence-probe body
3989 /// composes ONE resolver primitive
3990 /// ([`Self::resolved_classification`]) with ONE closed-set
3991 /// primitive ([`Classification::has_data_classification`]) so
3992 /// every downstream (`data-classification-<kind>` require-tag
3993 /// families on both surfaces in tatara-check, closed-set audit
3994 /// dispatchers, future variant additions on
3995 /// [`DataClassification`]) binds through the SAME `has(kind)`
3996 /// shape rather than restating either the resolver walk or the
3997 /// closed-set equality at the callsite.
3998 #[must_use]
3999 pub fn has_data_classification(&self, kind: DataClassification) -> bool {
4000 self.resolved_classification().has_data_classification(kind)
4001 }
4002
4003 /// True iff the resolved [`Classification`]'s nested [`Horizon`]
4004 /// carries the given [`HorizonKind`] discriminator on its
4005 /// `horizon.kind` slot — byte-for-byte peer of
4006 /// [`Classification::has_horizon_kind`] wrapped through the
4007 /// [`Self::resolved_classification`] resolver so an operator-
4008 /// omitted `:classification` slot reads as the
4009 /// [`default_ephemeral_class`] baseline the sibling
4010 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
4011 ///
4012 /// # Two-surface parity contract
4013 ///
4014 /// A given [`EphemeralSpec`] classifies identically through this
4015 /// primitive AND through
4016 /// `<eph.clone().into::<ProcessSpec>>().classification.has_horizon_kind(kind)`
4017 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
4018 /// resolver on this side and the `.unwrap_or_else(...)` fill on
4019 /// the lowering side both dereference the same
4020 /// `default_ephemeral_class()` value on `None` and the same
4021 /// authored value on `Some(_)`. This means the ephemeral-surface
4022 /// `horizon-<kind>` `:requires` family in
4023 /// `tatara-reconciler::bin::tatara-check` publishes the SAME
4024 /// truth on the SAME authored spec as the point-surface family
4025 /// on the mechanically-lowered `ProcessSpec`.
4026 ///
4027 /// # FIFTH classification-axis peer on the ephemeral surface
4028 ///
4029 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`],
4030 /// [`Self::has_calm`], and [`Self::has_data_classification`] — all
4031 /// five route through the SAME [`Self::resolved_classification`]
4032 /// resolver, so the operator-omitted `:classification` slot's
4033 /// fill-through logic lives at ONE substrate primitive rather
4034 /// than being restated in each per-axis probe body. OPENS a fresh
4035 /// (Option-parent × NESTED-STRUCT-scalar-child ×
4036 /// operator-resolvable-baseline) corner on the ephemeral-surface
4037 /// presence-probe algebra — the four prior peers on this surface
4038 /// all read the closed-set discriminator DIRECTLY off a scalar
4039 /// [`Classification`] slot (`point_type`, `substrate`, `calm`,
4040 /// `data_classification`); this probe instead threads through a
4041 /// NESTED-STRUCT intermediary ([`Horizon`], the defaulted nested
4042 /// struct owning the `horizon` axis) to reach a scalar
4043 /// [`HorizonKind`] discriminator on `horizon.kind`. The
4044 /// default-arm short-circuit on the absent-classification arm
4045 /// reads `true` on the [`HorizonKind`] child's `#[default]`
4046 /// variant precisely because BOTH the parent Option's fill-
4047 /// through baseline ([`default_ephemeral_class`], which fills
4048 /// `horizon: Horizon::default()`) AND the child's own `#[default]`
4049 /// land on the SAME variant ([`HorizonKind::Bounded`]). A
4050 /// regression that dropped `#[default]` on [`HorizonKind`], or
4051 /// promoted `Asymptotic` to `#[default]`, or wired the arm to a
4052 /// fixed variant answer, or crossed the wires through the wrong
4053 /// nested struct fails HERE at ONE narrow substrate site before
4054 /// drifting through every unadorned ephemeral spec's baseline
4055 /// horizon answer. Distinct from the FIRST + SECOND peers on the
4056 /// (Option-parent × NON-DEFAULT-scalar-child) corner
4057 /// (`has_point_type`, `has_substrate`) whose absent-classification
4058 /// arm defaults through a specific chosen baseline
4059 /// (`ConvergencePointType::Gate`, `SubstrateType::Compute`), AND
4060 /// distinct from the THIRD + FOURTH peers on the (Option-parent ×
4061 /// DEFAULTED-scalar-child) corner (`has_calm`,
4062 /// `has_data_classification`) which reach a defaulted scalar
4063 /// DIRECTLY off the parent without a nested-struct hop. Three
4064 /// future sibling axes on the SAME `Cow`-resolver carrier
4065 /// ([`Self::has_optimization_direction`] opened the SIXTH; then
4066 /// `has_input_arity`, `has_output_arity`) land as one-line
4067 /// wrappers around the SAME resolver + the sibling
4068 /// [`Classification`] closed-set primitive, so a future variant
4069 /// added to [`HorizonKind`] (or any of the three other closed
4070 /// sets) reaches BOTH surfaces' `<axis>-<kind>` prefix families
4071 /// through the SAME closed-set walk with no per-caller edit.
4072 ///
4073 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4074 /// preserves proofs; the classification-axis presence-probe body
4075 /// composes ONE resolver primitive
4076 /// ([`Self::resolved_classification`]) with ONE closed-set
4077 /// primitive ([`Classification::has_horizon_kind`]) so every
4078 /// downstream (`horizon-<kind>` require-tag families on both
4079 /// surfaces in tatara-check, closed-set audit dispatchers, future
4080 /// variant additions on [`HorizonKind`]) binds through the SAME
4081 /// `has(kind)` shape rather than restating either the resolver
4082 /// walk or the closed-set equality at the callsite.
4083 #[must_use]
4084 pub fn has_horizon_kind(&self, kind: HorizonKind) -> bool {
4085 self.resolved_classification().has_horizon_kind(kind)
4086 }
4087
4088 /// True iff the resolved [`Classification`]'s nested [`Horizon`]
4089 /// carries the given [`OptimizationDirection`] discriminator on its
4090 /// `horizon.direction` slot (with the substrate
4091 /// `Option::unwrap_or_default` treating `None` as the closed set's
4092 /// `#[default] Minimize`) — byte-for-byte peer of
4093 /// [`Classification::has_optimization_direction`] wrapped through
4094 /// the [`Self::resolved_classification`] resolver so an operator-
4095 /// omitted `:classification` slot reads as the
4096 /// [`default_ephemeral_class`] baseline the sibling
4097 /// `From<EphemeralSpec> for ProcessSpec` lowering fills.
4098 ///
4099 /// # Two-surface parity contract
4100 ///
4101 /// A given [`EphemeralSpec`] classifies identically through this
4102 /// primitive AND through
4103 /// `<eph.clone().into::<ProcessSpec>>().classification.has_optimization_direction(kind)`
4104 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
4105 /// resolver on this side and the `.unwrap_or_else(...)` fill on
4106 /// the lowering side both dereference the same
4107 /// `default_ephemeral_class()` value on `None` and the same
4108 /// authored value on `Some(_)`, and the sibling
4109 /// [`Classification::has_optimization_direction`] applies the same
4110 /// `Option::unwrap_or_default` collapse on the inner
4111 /// `horizon.direction` slot on both sides. This means the
4112 /// ephemeral-surface `optimization-direction-<kind>` `:requires`
4113 /// family in `tatara-reconciler::bin::tatara-check` publishes the
4114 /// SAME truth on the SAME authored spec as the point-surface
4115 /// family on the mechanically-lowered `ProcessSpec`.
4116 ///
4117 /// # SIXTH classification-axis peer on the ephemeral surface
4118 ///
4119 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`],
4120 /// [`Self::has_calm`], [`Self::has_data_classification`], and
4121 /// [`Self::has_horizon_kind`] — all six route through the SAME
4122 /// [`Self::resolved_classification`] resolver, so the operator-
4123 /// omitted `:classification` slot's fill-through logic lives at
4124 /// ONE substrate primitive rather than being restated in each per-
4125 /// axis probe body. SECOND occupant on the (Option-parent ×
4126 /// NESTED-STRUCT-scalar-child × operator-resolvable-baseline)
4127 /// corner alongside [`Self::has_horizon_kind`] — both probes thread
4128 /// through the SAME nested [`Horizon`] intermediary to reach a
4129 /// scalar discriminator on the six-axis classification lattice, but
4130 /// this method additionally traverses an `Option`-slot with
4131 /// `unwrap_or_default` so a Process filled through
4132 /// [`crate::classification::Horizon::default`] (leaves `direction:
4133 /// None`) still reads `true` on the closed set's default arm
4134 /// ([`OptimizationDirection::Minimize`]). The corner therefore
4135 /// admits BOTH direct nested-scalar shapes ([`Self::has_horizon_kind`]
4136 /// walks `horizon.kind: HorizonKind` directly) AND Option-nested-
4137 /// scalar shapes (this method walks `horizon.direction:
4138 /// Option<OptimizationDirection>` through `unwrap_or_default`),
4139 /// pinning the corner as a proven-repeatable primitive shape on the
4140 /// ephemeral surface rather than a single-example curiosity. The
4141 /// two-defaults composition property (parent Option's fill-through
4142 /// baseline via `default_ephemeral_class` AND child's closed-set
4143 /// `#[default]` land on the SAME variant) reaches through TWO
4144 /// hops here: the parent Option's `.unwrap_or_else(default_…)`
4145 /// AND the inner Option's `.unwrap_or_default()` both dereference
4146 /// to the same [`OptimizationDirection::Minimize`] baseline the
4147 /// closed set publishes. A regression that flipped
4148 /// [`OptimizationDirection`]'s `#[default]` off `Minimize` (which
4149 /// would silently invert every unadorned `Asymptotic` Process's
4150 /// rate-window evaluator polarity), or that dropped the resolver
4151 /// hop, or that wired the arm to a fixed variant answer, fails
4152 /// HERE at ONE narrow substrate site before drifting through every
4153 /// unadorned ephemeral spec's baseline direction answer. Two future
4154 /// sibling axes on the SAME `Cow`-resolver carrier
4155 /// (`has_input_arity`, `has_output_arity`) land as one-line
4156 /// wrappers around the SAME resolver + the sibling
4157 /// [`Classification`] closed-set primitive, so a future variant
4158 /// added to [`OptimizationDirection`] (or any of the two other
4159 /// closed sets) reaches BOTH surfaces' `<axis>-<kind>` prefix
4160 /// families through the SAME closed-set walk with no per-caller
4161 /// edit.
4162 ///
4163 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4164 /// preserves proofs; the classification-axis presence-probe body
4165 /// composes ONE resolver primitive
4166 /// ([`Self::resolved_classification`]) with ONE closed-set
4167 /// primitive ([`Classification::has_optimization_direction`]) so
4168 /// every downstream (`optimization-direction-<kind>` require-tag
4169 /// families on both surfaces in tatara-check, closed-set audit
4170 /// dispatchers, future variant additions on
4171 /// [`OptimizationDirection`]) binds through the SAME `has(kind)`
4172 /// shape rather than restating either the resolver walk or the
4173 /// closed-set equality plus the nested-struct-Option-hop at the
4174 /// callsite.
4175 #[must_use]
4176 pub fn has_optimization_direction(&self, kind: OptimizationDirection) -> bool {
4177 self.resolved_classification()
4178 .has_optimization_direction(kind)
4179 }
4180
4181 /// True iff the resolved [`Classification`]'s nested
4182 /// [`ConvergencePointType`] projects (via the many-to-one
4183 /// [`ConvergencePointType::input_arity`] typed projection) to the
4184 /// given [`Arity`] discriminator — byte-for-byte peer of
4185 /// [`Classification::has_input_arity`] wrapped through the
4186 /// [`Self::resolved_classification`] resolver so an operator-omitted
4187 /// `:classification` slot reads as the [`default_ephemeral_class`]
4188 /// baseline the sibling `From<EphemeralSpec> for ProcessSpec`
4189 /// lowering fills.
4190 ///
4191 /// # Two-surface parity contract
4192 ///
4193 /// A given [`EphemeralSpec`] classifies identically through this
4194 /// primitive AND through
4195 /// `<eph.clone().into::<ProcessSpec>>().classification.has_input_arity(kind)`
4196 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
4197 /// resolver on this side and the `.unwrap_or_else(...)` fill on the
4198 /// lowering side both dereference the same
4199 /// `default_ephemeral_class()` value on `None` and the same
4200 /// authored value on `Some(_)`, and the sibling
4201 /// [`Classification::has_input_arity`] applies the same
4202 /// `point_type.input_arity()` typed projection on both sides. This
4203 /// means the ephemeral-surface `input-arity-<kind>` `:requires`
4204 /// family in `tatara-reconciler::bin::tatara-check` publishes the
4205 /// SAME truth on the SAME authored spec as the point-surface family
4206 /// on the mechanically-lowered `ProcessSpec`.
4207 ///
4208 /// # SEVENTH classification-axis peer on the ephemeral surface — first via a derived-typed-projection
4209 ///
4210 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`],
4211 /// [`Self::has_calm`], [`Self::has_data_classification`],
4212 /// [`Self::has_horizon_kind`], and
4213 /// [`Self::has_optimization_direction`] — all seven route through
4214 /// the SAME [`Self::resolved_classification`] resolver, so the
4215 /// operator-omitted `:classification` slot's fill-through logic
4216 /// lives at ONE substrate primitive rather than being restated in
4217 /// each per-axis probe body. FIRST occupant on the (Option-parent ×
4218 /// NESTED-STRUCT-scalar-child × derived-typed-projection) corner on
4219 /// the ephemeral surface — byte-for-byte symmetric with the
4220 /// derived-typed-projection precedent set by
4221 /// [`Classification::has_input_arity`] on the point surface: THAT
4222 /// peer routes through [`ConvergencePointType::input_arity`] on a
4223 /// required [`Classification`] carrier; THIS peer routes through the
4224 /// SAME projection on the `Cow`-resolver carrier so the resolver
4225 /// walk composes with the projection at ONE substrate site rather
4226 /// than being restated per surface. Distinct from the SIXTH peer
4227 /// [`Self::has_optimization_direction`] (which walks
4228 /// `horizon.direction` through an `Option::unwrap_or_default`
4229 /// collapse to reach a defaulted scalar child) and the FIFTH peer
4230 /// [`Self::has_horizon_kind`] (which walks `horizon.kind` DIRECTLY
4231 /// as a scalar without any typed-projection hop) on ONE dimension:
4232 /// this probe threads through the many-to-one closed-set typed
4233 /// projection [`ConvergencePointType::input_arity`] (`Transform |
4234 /// Fork | Broadcast | Observe → One`, `Join | Gate | Select |
4235 /// Reduce → Many`) so the child's closed set ([`Arity`]) is REACHED
4236 /// THROUGH a projection layer, not read raw off a scalar. The
4237 /// corner therefore admits three ephemeral-surface traversal
4238 /// shapes through the SAME `resolved_classification().<field>`
4239 /// walk: direct-nested-scalar
4240 /// ([`Self::has_horizon_kind`] reads `horizon.kind: HorizonKind`
4241 /// directly), Option-nested-scalar
4242 /// ([`Self::has_optimization_direction`] reads `horizon.direction:
4243 /// Option<OptimizationDirection>` through `unwrap_or_default`), and
4244 /// derived-typed-projection (this method reads
4245 /// `point_type.input_arity(): Arity` through a many-to-one
4246 /// projection). The co-tenant derived-typed-projection axis on the
4247 /// SAME `Cow`-resolver carrier ([`Self::has_output_arity`]) lands as
4248 /// a one-line wrapper around the SAME resolver + the sibling
4249 /// [`Classification`] closed-set primitive, so a future variant
4250 /// added to [`Arity`] or to [`ConvergencePointType`] reaches BOTH
4251 /// surfaces' `<axis>-<kind>` prefix families through the SAME
4252 /// closed-set walk with no per-caller edit.
4253 ///
4254 /// # Semantics — VARIANT match on the projected image
4255 ///
4256 /// [`Arity`] carries no `Default` impl (the 2-arm bare enum with no
4257 /// `#[default]`), so exactly ONE of the two arms answers `true` per
4258 /// well-formed [`EphemeralSpec`], with no default-arm short-circuit
4259 /// shortcut. The absent-`:classification` baseline
4260 /// [`default_ephemeral_class`] fills `point_type: Gate`, and
4261 /// [`ConvergencePointType::input_arity`] projects `Gate → Many`, so
4262 /// the ephemeral sugar surface's `input-arity-Many` require-tag
4263 /// reads `true` on every operator-authored spec that omits the
4264 /// `:classification` slot — pinning the workspace's convergent-by-
4265 /// default point posture on the input side. The many-to-one
4266 /// projection shape means the answer is invariant under intra-
4267 /// bucket point-type swaps (`Transform ↔ Fork ↔ Broadcast ↔
4268 /// Observe` all keep `input-arity-One = true`) and flips at bucket
4269 /// boundaries (`Transform ↔ Join` flips `input-arity-One` from
4270 /// `true` to `false`). A regression that dropped the resolver hop,
4271 /// probed [`ConvergencePointType`] directly (dropping the
4272 /// `.input_arity()` call), inverted the projection (`One ↔ Many`),
4273 /// or crossed the wires with the sibling
4274 /// [`ConvergencePointType::output_arity`] projection fails HERE at
4275 /// ONE narrow substrate site before drifting through every
4276 /// unadorned ephemeral spec's baseline input-arity answer.
4277 ///
4278 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4279 /// preserves proofs; the classification-axis presence-probe body
4280 /// composes ONE resolver primitive
4281 /// ([`Self::resolved_classification`]) with ONE closed-set primitive
4282 /// ([`Classification::has_input_arity`]) so every downstream
4283 /// (`input-arity-<kind>` require-tag families on both surfaces in
4284 /// tatara-check, closed-set audit dispatchers, future variant
4285 /// additions on [`Arity`] or on [`ConvergencePointType`]) binds
4286 /// through the SAME `has(kind)` shape rather than restating either
4287 /// the resolver walk or the closed-set equality plus the typed-
4288 /// projection hop at the callsite.
4289 #[must_use]
4290 pub fn has_input_arity(&self, kind: Arity) -> bool {
4291 self.resolved_classification().has_input_arity(kind)
4292 }
4293
4294 /// True iff the resolved [`Classification`]'s nested
4295 /// [`ConvergencePointType`] projects (via the many-to-one
4296 /// [`ConvergencePointType::output_arity`] typed projection) to the
4297 /// given [`Arity`] discriminator — byte-for-byte peer of
4298 /// [`Classification::has_output_arity`] wrapped through the
4299 /// [`Self::resolved_classification`] resolver so an operator-omitted
4300 /// `:classification` slot reads as the [`default_ephemeral_class`]
4301 /// baseline the sibling `From<EphemeralSpec> for ProcessSpec`
4302 /// lowering fills.
4303 ///
4304 /// # Two-surface parity contract
4305 ///
4306 /// A given [`EphemeralSpec`] classifies identically through this
4307 /// primitive AND through
4308 /// `<eph.clone().into::<ProcessSpec>>().classification.has_output_arity(kind)`
4309 /// on the lowered `ProcessSpec` — the `Cow<'_, Classification>`
4310 /// resolver on this side and the `.unwrap_or_else(...)` fill on the
4311 /// lowering side both dereference the same
4312 /// `default_ephemeral_class()` value on `None` and the same
4313 /// authored value on `Some(_)`, and the sibling
4314 /// [`Classification::has_output_arity`] applies the same
4315 /// `point_type.output_arity()` typed projection on both sides. This
4316 /// means the ephemeral-surface `output-arity-<kind>` `:requires`
4317 /// family in `tatara-reconciler::bin::tatara-check` publishes the
4318 /// SAME truth on the SAME authored spec as the point-surface family
4319 /// on the mechanically-lowered `ProcessSpec`.
4320 ///
4321 /// # EIGHTH classification-axis peer — closes the ephemeral-side DAG-composition arity pair
4322 ///
4323 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`],
4324 /// [`Self::has_calm`], [`Self::has_data_classification`],
4325 /// [`Self::has_horizon_kind`], [`Self::has_optimization_direction`],
4326 /// and [`Self::has_input_arity`] — all eight route through the SAME
4327 /// [`Self::resolved_classification`] resolver, so the operator-
4328 /// omitted `:classification` slot's fill-through logic lives at ONE
4329 /// substrate primitive rather than being restated in each per-axis
4330 /// probe body. SECOND occupant on the (Option-parent × NESTED-
4331 /// STRUCT-scalar-child × derived-typed-projection) corner on the
4332 /// ephemeral surface — co-tenant with [`Self::has_input_arity`] on
4333 /// the SAME `point_type` scalar carrier through the SAME [`Arity`]
4334 /// closed set but through the sibling many-to-one typed projection
4335 /// [`ConvergencePointType::output_arity`] (`Transform | Join | Gate
4336 /// | Select | Reduce | Observe → One`, `Fork | Broadcast → Many`).
4337 /// Closes the DAG-composition arity pair on the ephemeral side —
4338 /// the two projections DISAGREE on the diffusive arms `Fork |
4339 /// Broadcast` (input `One` vs. output `Many`) and on the convergent
4340 /// arms `Join | Gate | Select | Reduce` (input `Many` vs. output
4341 /// `One`), and AGREE on the endomorphic arms `Transform | Observe`
4342 /// (both `One`). Byte-for-byte symmetric with the DAG-composition
4343 /// arity pair on the point surface ([`Classification::has_input_arity`] +
4344 /// [`Classification::has_output_arity`]) — THAT pair walks a required
4345 /// [`Classification`] carrier; THIS pair walks the SAME projection
4346 /// pair on the `Cow`-resolver carrier so the resolver walk composes
4347 /// with the projection at ONE substrate site rather than being
4348 /// restated per surface.
4349 ///
4350 /// # Semantics — VARIANT match on the projected image
4351 ///
4352 /// [`Arity`] carries no `Default` impl (the 2-arm bare enum with no
4353 /// `#[default]`), so exactly ONE of the two arms answers `true` per
4354 /// well-formed [`EphemeralSpec`], with no default-arm short-circuit
4355 /// shortcut. The absent-`:classification` baseline
4356 /// [`default_ephemeral_class`] fills `point_type: Gate`, and
4357 /// [`ConvergencePointType::output_arity`] projects `Gate → One`, so
4358 /// the ephemeral sugar surface's `output-arity-One` require-tag
4359 /// reads `true` on every operator-authored spec that omits the
4360 /// `:classification` slot — pinning the workspace's convergent-by-
4361 /// default point posture on the output side. The many-to-one
4362 /// projection shape means the answer is invariant under intra-
4363 /// bucket point-type swaps (`Fork ↔ Broadcast` both keep
4364 /// `output-arity-Many = true`; `Transform ↔ Join ↔ Gate ↔ Select ↔
4365 /// Reduce ↔ Observe` all keep `output-arity-One = true`) and flips
4366 /// at bucket boundaries (`Fork ↔ Transform` flips `output-arity-
4367 /// Many` from `true` to `false`). A regression that dropped the
4368 /// resolver hop, probed [`ConvergencePointType`] directly (dropping
4369 /// the `.output_arity()` call), inverted the projection (`One ↔
4370 /// Many`), or crossed the wires with the sibling
4371 /// [`ConvergencePointType::input_arity`] projection fails HERE at
4372 /// ONE narrow substrate site before drifting through every
4373 /// unadorned ephemeral spec's baseline output-arity answer.
4374 ///
4375 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4376 /// preserves proofs; the classification-axis presence-probe body
4377 /// composes ONE resolver primitive
4378 /// ([`Self::resolved_classification`]) with ONE closed-set primitive
4379 /// ([`Classification::has_output_arity`]) so every downstream
4380 /// (`output-arity-<kind>` require-tag families on both surfaces in
4381 /// tatara-check, closed-set audit dispatchers, future variant
4382 /// additions on [`Arity`] or on [`ConvergencePointType`]) binds
4383 /// through the SAME `has(kind)` shape rather than restating either
4384 /// the resolver walk or the closed-set equality plus the typed-
4385 /// projection hop at the callsite.
4386 #[must_use]
4387 pub fn has_output_arity(&self, kind: Arity) -> bool {
4388 self.resolved_classification().has_output_arity(kind)
4389 }
4390
4391 /// Derived-boolean predicate — does this ephemeral spec's
4392 /// resolved [`Classification`]'s [`Horizon`] project to `true`
4393 /// under [`crate::classification::HorizonKind::terminates`]?
4394 /// Byte-for-byte peer of
4395 /// [`Classification::horizon_terminates`] wrapped through the
4396 /// [`Self::resolved_classification`] resolver so an operator-
4397 /// omitted `:classification` slot on `(defephemeral …)` still
4398 /// answers via the substrate default. The ONE ephemeral-surface
4399 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4400 /// derived-nullary-boolean walk on the classification-horizon
4401 /// axis.
4402 ///
4403 /// # Two-surface parity — resolver hop + Classification primitive
4404 ///
4405 /// Peer of [`Self::has_point_type`], [`Self::has_substrate`],
4406 /// [`Self::has_calm`], [`Self::has_data_classification`],
4407 /// [`Self::has_horizon_kind`],
4408 /// [`Self::has_optimization_direction`],
4409 /// [`Self::has_input_arity`], and [`Self::has_output_arity`] on
4410 /// the (resolver-hop × [`Classification`] presence primitive)
4411 /// axis: all nine methods route through the SAME
4412 /// [`Self::resolved_classification`] resolver, and each composes
4413 /// against ONE [`Classification`] primitive. This method
4414 /// distinguishes itself by targeting the [`Classification`]
4415 /// primitive [`Classification::horizon_terminates`] which is the
4416 /// FIRST derived-nullary-boolean (no closed-set argument)
4417 /// primitive on the [`Classification`] surface — every prior
4418 /// peer probe on [`Classification`] admits a closed-set `kind`
4419 /// argument and answers a variant-equality question, while this
4420 /// probe collapses [`HorizonKind::ALL`] onto a single boolean
4421 /// via the closed set's own [`HorizonKind::terminates`]
4422 /// predicate.
4423 ///
4424 /// # Semantics — resolver hop + derived-nullary-boolean
4425 ///
4426 /// `horizon_terminates()` returns `true` iff
4427 /// `self.resolved_classification().horizon_terminates()`. The
4428 /// resolver returns the authored [`Classification`] when
4429 /// present and the substrate default
4430 /// [`Classification::gate_compute`] on absence. Because
4431 /// [`Classification::gate_compute`] uses [`Horizon::default`]
4432 /// (whose `kind` field defaults to [`HorizonKind::Bounded`] via
4433 /// `#[default]`), a bare ephemeral spec with no `:classification`
4434 /// slot answers `true` — the default-arm short-circuit
4435 /// propagates through THREE layers of `Default`
4436 /// ([`Classification::gate_compute`] → [`Horizon::default`] →
4437 /// [`HorizonKind::default`]) to this predicate's answer, matching
4438 /// the default-arm shortcut every prior defaulted-child probe
4439 /// on this surface publishes. A regression that dropped the
4440 /// resolver hop, probed [`Classification::has_horizon_kind`]
4441 /// directly (dropping the `.terminates()` projection), or
4442 /// crossed the wires with the antisymmetric partner
4443 /// [`HorizonKind::requires_metric_axes`] fails HERE at ONE
4444 /// narrow substrate site before drifting through every
4445 /// unadorned ephemeral spec's baseline horizon-terminates
4446 /// answer.
4447 ///
4448 /// # Compounding
4449 ///
4450 /// The ephemeral require-tag classifier composes this primitive
4451 /// as a fixed tag `terminating-horizon` on
4452 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
4453 /// surface's `terminating-horizon` fixed tag on
4454 /// `POINT_FIXED_TAG_ARMS` via [`Classification::horizon_terminates`]
4455 /// directly. The two-surface parity contract holds by
4456 /// construction: both surfaces route through the SAME
4457 /// [`Classification::horizon_terminates`] primitive after the
4458 /// ephemeral surface pays ONE resolver hop — a future
4459 /// [`HorizonKind`] variant or a future normalization at the
4460 /// substrate primitive lands at ONE site and both surfaces'
4461 /// `terminating-horizon` fixed tags inherit the shift
4462 /// mechanically. A future co-tenant peer on this surface (a
4463 /// hypothetical `horizon_requires_metric_axes` composing the
4464 /// antisymmetric partner [`HorizonKind::requires_metric_axes`]
4465 /// through the SAME resolver hop) lands as ONE peer inherent
4466 /// method with the same nullary-derived body.
4467 ///
4468 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4469 /// preserves proofs; the classification-axis derived-nullary-
4470 /// boolean probe body composes ONE resolver primitive
4471 /// ([`Self::resolved_classification`]) with ONE
4472 /// [`Classification`] primitive
4473 /// ([`Classification::horizon_terminates`]) so every downstream
4474 /// (`terminating-horizon` fixed tags on both surfaces in
4475 /// tatara-check, future scheduler / termination-shape
4476 /// validators, future variant additions on [`HorizonKind`])
4477 /// binds through the SAME `horizon_terminates()` shape rather
4478 /// than restating either the resolver walk or the closed-set
4479 /// projection composition at the callsite. THEORY.md §VI.1 —
4480 /// generation over composition; a future [`HorizonKind`]
4481 /// variant lands at ONE `ALL` entry + ONE `terminates` arm on
4482 /// the closed set and both surfaces pick it up mechanically.
4483 #[must_use]
4484 pub fn horizon_terminates(&self) -> bool {
4485 self.resolved_classification().horizon_terminates()
4486 }
4487
4488 /// Derived-boolean predicate — does this ephemeral spec's
4489 /// resolved [`Classification`]'s [`Horizon`] project to `true`
4490 /// under [`crate::classification::HorizonKind::requires_metric_axes`]?
4491 /// Byte-for-byte peer of
4492 /// [`Classification::horizon_requires_metric_axes`] wrapped
4493 /// through the [`Self::resolved_classification`] resolver so an
4494 /// operator-omitted `:classification` slot on `(defephemeral …)`
4495 /// still answers via the substrate default. The ONE ephemeral-
4496 /// surface substrate primitive that owns the
4497 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on
4498 /// the metric-axes-required question over the classification-
4499 /// horizon axis.
4500 ///
4501 /// # Antisymmetric peer of [`Self::horizon_terminates`]
4502 ///
4503 /// Byte-for-byte antisymmetric peer of [`Self::horizon_terminates`]
4504 /// via the SAME [`Self::resolved_classification`] resolver hop
4505 /// and the SAME closed set [`crate::classification::HorizonKind`]:
4506 /// [`Self::horizon_terminates`] composes
4507 /// [`Classification::horizon_terminates`] (walking
4508 /// [`crate::classification::HorizonKind::terminates`]); this
4509 /// method composes the ANTISYMMETRIC partner
4510 /// [`Classification::horizon_requires_metric_axes`] (walking
4511 /// [`crate::classification::HorizonKind::requires_metric_axes`]).
4512 /// The closed set pins the XOR contract
4513 /// `terminates() ^ requires_metric_axes()` on every variant, so
4514 /// exactly ONE of these two ephemeral-surface derived-nullary
4515 /// probes answers `true` per resolved [`Classification`] and the
4516 /// two probes together partition the resolver's output space into
4517 /// two disjoint buckets on every ephemeral spec — authored or
4518 /// defaulted.
4519 ///
4520 /// # Semantics — resolver hop + derived-nullary-boolean
4521 ///
4522 /// `horizon_requires_metric_axes()` returns `true` iff
4523 /// `self.resolved_classification().horizon_requires_metric_axes()`.
4524 /// The resolver returns the authored [`Classification`] when
4525 /// present and the substrate default
4526 /// [`Classification::gate_compute`] on absence. Because
4527 /// [`Classification::gate_compute`] uses [`Horizon::default`]
4528 /// (whose `kind` field defaults to
4529 /// [`crate::classification::HorizonKind::Bounded`] via
4530 /// `#[default]`), a bare ephemeral spec with no `:classification`
4531 /// slot answers `false` — the default-arm short-circuit
4532 /// propagates through THREE layers of `Default`
4533 /// ([`Classification::gate_compute`] → [`Horizon::default`] →
4534 /// [`crate::classification::HorizonKind::default`]) to this
4535 /// predicate's answer, the mirror image of
4536 /// [`Self::horizon_terminates`]'s default-arm `true` answer. A
4537 /// regression that dropped the resolver hop, probed
4538 /// [`Classification::has_horizon_kind`] directly (dropping the
4539 /// `.requires_metric_axes()` projection), or crossed the wires
4540 /// with the antisymmetric partner
4541 /// [`crate::classification::HorizonKind::terminates`] fails HERE
4542 /// at ONE narrow substrate site before drifting through every
4543 /// unadorned ephemeral spec's baseline metric-provisioning
4544 /// answer.
4545 ///
4546 /// # Compounding
4547 ///
4548 /// The ephemeral require-tag classifier composes this primitive
4549 /// as a fixed tag `metric-axes-required` on
4550 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
4551 /// surface's `metric-axes-required` fixed tag on
4552 /// `POINT_FIXED_TAG_ARMS` via
4553 /// [`Classification::horizon_requires_metric_axes`] directly. The
4554 /// two-surface parity contract holds by construction: both
4555 /// surfaces route through the SAME
4556 /// [`Classification::horizon_requires_metric_axes`] primitive
4557 /// after the ephemeral surface pays ONE resolver hop — a future
4558 /// [`crate::classification::HorizonKind`] variant or a future
4559 /// normalization at the substrate primitive lands at ONE site and
4560 /// both surfaces' `metric-axes-required` fixed tags inherit the
4561 /// shift mechanically.
4562 ///
4563 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4564 /// preserves proofs; the classification-axis derived-nullary-
4565 /// boolean probe body composes ONE resolver primitive
4566 /// ([`Self::resolved_classification`]) with ONE
4567 /// [`Classification`] primitive
4568 /// ([`Classification::horizon_requires_metric_axes`]) so every
4569 /// downstream (`metric-axes-required` fixed tags on both
4570 /// surfaces in tatara-check, future scheduler / metric-
4571 /// provisioning validators, future variant additions on
4572 /// [`crate::classification::HorizonKind`]) binds through the
4573 /// SAME `horizon_requires_metric_axes()` shape rather than
4574 /// restating either the resolver walk or the closed-set
4575 /// projection composition at the callsite. THEORY.md §VI.1 —
4576 /// generation over composition; a future
4577 /// [`crate::classification::HorizonKind`] variant lands at ONE
4578 /// `ALL` entry + ONE `requires_metric_axes` arm on the closed
4579 /// set and both surfaces pick it up mechanically.
4580 #[must_use]
4581 pub fn horizon_requires_metric_axes(&self) -> bool {
4582 self.resolved_classification()
4583 .horizon_requires_metric_axes()
4584 }
4585
4586 /// Derived-boolean predicate — does this ephemeral spec's
4587 /// resolved [`Classification`]'s [`crate::classification::CalmClassification`]
4588 /// project to `true` under
4589 /// [`crate::classification::CalmClassification::requires_coordination`]?
4590 /// Byte-for-byte peer of
4591 /// [`Classification::calm_requires_coordination`] wrapped through
4592 /// the [`Self::resolved_classification`] resolver so an operator-
4593 /// omitted `:classification` slot on `(defephemeral …)` still
4594 /// answers via the substrate default. The ONE ephemeral-surface
4595 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4596 /// derived-nullary-boolean walk on the coordination-required
4597 /// question over the classification-calm axis.
4598 ///
4599 /// # Third derived-nullary-boolean peer on the ephemeral surface
4600 ///
4601 /// Peer of [`Self::horizon_terminates`] and
4602 /// [`Self::horizon_requires_metric_axes`] on the ephemeral
4603 /// surface's (resolver-hop × derived-nullary-bool) shape — the
4604 /// FIRST peer threading the classification-calm axis rather than
4605 /// the classification-horizon axis. Distinct from both prior
4606 /// derived-nullary peers by ONE structural degree at the underlying
4607 /// [`Classification`] primitive: [`Self::horizon_terminates`] +
4608 /// [`Self::horizon_requires_metric_axes`] both walk the nested
4609 /// `.horizon.kind` sub-slot's derived projection, while this probe
4610 /// walks the direct scalar `.calm` field's derived projection.
4611 /// The resolver-hop shape is byte-identical.
4612 ///
4613 /// # Semantics — resolver hop + derived-nullary-boolean
4614 ///
4615 /// `calm_requires_coordination()` returns `true` iff
4616 /// `self.resolved_classification().calm_requires_coordination()`.
4617 /// The resolver returns the authored [`Classification`] when
4618 /// present and the substrate default
4619 /// [`Classification::gate_compute`] on absence. Because
4620 /// [`Classification::gate_compute`] carries
4621 /// [`crate::classification::CalmClassification::default = Monotone`],
4622 /// a bare ephemeral spec with no `:classification` slot answers
4623 /// `false` — the default-arm short-circuit propagates through TWO
4624 /// layers of `Default` ([`Classification::gate_compute`] →
4625 /// [`crate::classification::CalmClassification::default`]) to this
4626 /// predicate's answer. Distinct from the two `horizon_*` peers on
4627 /// this surface, which short-circuit through THREE layers of
4628 /// `Default` ([`Classification::gate_compute`] → [`Horizon::default`]
4629 /// → [`HorizonKind::default`]) because the horizon axis has a
4630 /// nested-struct wrapper between the classification field and the
4631 /// closed-set discriminator. A regression that dropped the
4632 /// resolver hop, probed [`Classification::has_calm`] directly
4633 /// (dropping the `.requires_coordination()` projection), or
4634 /// inverted the projection (silently promoting the Monotone
4635 /// baseline to "requires coordination") fails HERE at ONE narrow
4636 /// substrate site before drifting through every unadorned
4637 /// ephemeral spec's baseline coordination-mode answer.
4638 ///
4639 /// # Compounding
4640 ///
4641 /// The ephemeral require-tag classifier composes this primitive
4642 /// as a fixed tag `coordination-required` on
4643 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
4644 /// surface's `coordination-required` fixed tag on
4645 /// `POINT_FIXED_TAG_ARMS` via
4646 /// [`Classification::calm_requires_coordination`] directly. The
4647 /// two-surface parity contract holds by construction: both
4648 /// surfaces route through the SAME
4649 /// [`Classification::calm_requires_coordination`] primitive after
4650 /// the ephemeral surface pays ONE resolver hop — a future
4651 /// [`crate::classification::CalmClassification`] variant or a
4652 /// future normalization at the substrate primitive lands at ONE
4653 /// site and both surfaces' `coordination-required` fixed tags
4654 /// inherit the shift mechanically.
4655 ///
4656 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4657 /// preserves proofs; the classification-axis derived-nullary-
4658 /// boolean probe body composes ONE resolver primitive
4659 /// ([`Self::resolved_classification`]) with ONE
4660 /// [`Classification`] primitive
4661 /// ([`Classification::calm_requires_coordination`]) so every
4662 /// downstream (`coordination-required` fixed tags on both
4663 /// surfaces in tatara-check, future scheduler / coordination-mode
4664 /// validators, future variant additions on
4665 /// [`crate::classification::CalmClassification`]) binds through
4666 /// the SAME `calm_requires_coordination()` shape rather than
4667 /// restating either the resolver walk or the closed-set
4668 /// projection composition at the callsite. THEORY.md §VI.1 —
4669 /// generation over composition; a future
4670 /// [`crate::classification::CalmClassification`] variant lands at
4671 /// ONE `ALL` entry + ONE `requires_coordination` arm on the
4672 /// closed set and both surfaces pick it up mechanically.
4673 #[must_use]
4674 pub fn calm_requires_coordination(&self) -> bool {
4675 self.resolved_classification().calm_requires_coordination()
4676 }
4677
4678 /// Derived-boolean predicate — does this ephemeral spec's
4679 /// resolved [`Classification`]'s [`crate::classification::DataClassification`]
4680 /// project to `true` under
4681 /// [`crate::classification::DataClassification::is_regulated`]?
4682 /// Byte-for-byte peer of
4683 /// [`Classification::data_is_regulated`] wrapped through the
4684 /// [`Self::resolved_classification`] resolver so an operator-
4685 /// omitted `:classification` slot on `(defephemeral …)` still
4686 /// answers via the substrate default. The ONE ephemeral-surface
4687 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4688 /// derived-nullary-boolean walk on the regulated-data question
4689 /// over the classification-data axis.
4690 ///
4691 /// # Fourth derived-nullary-boolean peer on the ephemeral surface
4692 ///
4693 /// Peer of [`Self::horizon_terminates`],
4694 /// [`Self::horizon_requires_metric_axes`], and
4695 /// [`Self::calm_requires_coordination`] on the ephemeral surface's
4696 /// (resolver-hop × derived-nullary-bool) shape — the FIRST peer
4697 /// threading the classification-data axis rather than the horizon
4698 /// or calm axes. Structural byte-for-byte peer of
4699 /// [`Self::calm_requires_coordination`]: both walk a DIRECT scalar
4700 /// closed-set field's derived projection on the resolved
4701 /// [`Classification`] (`.calm.requires_coordination()` /
4702 /// `.data_classification.is_regulated()`) — TWO layers of
4703 /// `Default` short-circuit ([`Classification::gate_compute`] →
4704 /// the direct scalar child's `#[default]`) — distinct from the
4705 /// two `horizon_*` peers which walk a NESTED-STRUCT projection
4706 /// (`.horizon.kind`) with THREE layers of `Default`. The resolver-
4707 /// hop shape is byte-identical across all four peers.
4708 ///
4709 /// # Semantics — resolver hop + derived-nullary-boolean
4710 ///
4711 /// `data_is_regulated()` returns `true` iff
4712 /// `self.resolved_classification().data_is_regulated()`. The
4713 /// resolver returns the authored [`Classification`] when present
4714 /// and the substrate default [`Classification::gate_compute`] on
4715 /// absence. Because [`Classification::gate_compute`] carries
4716 /// [`crate::classification::DataClassification::default = Internal`],
4717 /// a bare ephemeral spec with no `:classification` slot answers
4718 /// `false` — the default-arm short-circuit propagates through TWO
4719 /// layers of `Default` ([`Classification::gate_compute`] →
4720 /// [`crate::classification::DataClassification::default`]) to
4721 /// this predicate's answer, mirror-image of
4722 /// [`Self::calm_requires_coordination`]'s Monotone-default
4723 /// short-circuit through the same structural depth. Distinct
4724 /// from the two `horizon_*` peers on this surface which short-
4725 /// circuit through THREE layers of `Default` because the horizon
4726 /// axis has a nested-struct wrapper. A regression that dropped
4727 /// the resolver hop, probed [`Classification::has_data_classification`]
4728 /// directly (dropping the `.is_regulated()` projection), or
4729 /// inverted the projection (silently promoting the Internal
4730 /// baseline to "regulated") fails HERE at ONE narrow substrate
4731 /// site before drifting through every unadorned ephemeral spec's
4732 /// baseline regulatory-regime answer.
4733 ///
4734 /// # Compounding
4735 ///
4736 /// The ephemeral require-tag classifier composes this primitive
4737 /// as a fixed tag `data-regulated` on `EPHEMERAL_FIXED_TAG_ARMS`
4738 /// — byte-for-byte peer of the point surface's `data-regulated`
4739 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
4740 /// [`Classification::data_is_regulated`] directly. The two-
4741 /// surface parity contract holds by construction: both surfaces
4742 /// route through the SAME
4743 /// [`Classification::data_is_regulated`] primitive after the
4744 /// ephemeral surface pays ONE resolver hop — a future
4745 /// [`crate::classification::DataClassification`] variant or a
4746 /// future normalization at the substrate primitive lands at ONE
4747 /// site and both surfaces' `data-regulated` fixed tags inherit
4748 /// the shift mechanically.
4749 ///
4750 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4751 /// preserves proofs; the classification-data-axis derived-nullary-
4752 /// boolean probe body composes ONE resolver primitive
4753 /// ([`Self::resolved_classification`]) with ONE
4754 /// [`Classification`] primitive
4755 /// ([`Classification::data_is_regulated`]) so every downstream
4756 /// (`data-regulated` fixed tags on both surfaces in tatara-check,
4757 /// future compliance-baseline / regulatory-regime validators,
4758 /// future variant additions on
4759 /// [`crate::classification::DataClassification`]) binds through
4760 /// the SAME `data_is_regulated()` shape rather than restating
4761 /// either the resolver walk or the closed-set projection
4762 /// composition at the callsite. THEORY.md §VI.1 — generation
4763 /// over composition; a future
4764 /// [`crate::classification::DataClassification`] variant lands
4765 /// at ONE `ALL` entry + ONE `is_regulated` arm on the closed set
4766 /// and both surfaces pick it up mechanically.
4767 #[must_use]
4768 pub fn data_is_regulated(&self) -> bool {
4769 self.resolved_classification().data_is_regulated()
4770 }
4771
4772 /// Derived-boolean predicate — does this ephemeral spec's
4773 /// resolved [`Classification`]'s [`crate::classification::DataClassification`]
4774 /// project to `true` under
4775 /// [`crate::classification::DataClassification::is_restricted`]?
4776 /// Byte-for-byte peer of
4777 /// [`Classification::data_is_restricted`] wrapped through the
4778 /// [`Self::resolved_classification`] resolver so an operator-
4779 /// omitted `:classification` slot on `(defephemeral …)` still
4780 /// answers via the substrate default. The ONE ephemeral-surface
4781 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4782 /// derived-nullary-boolean walk on the restricted-data question
4783 /// over the classification-data axis.
4784 ///
4785 /// # Fifth derived-nullary-boolean peer on the ephemeral surface
4786 ///
4787 /// Peer of [`Self::horizon_terminates`],
4788 /// [`Self::horizon_requires_metric_axes`],
4789 /// [`Self::calm_requires_coordination`], and
4790 /// [`Self::data_is_regulated`] on the ephemeral surface's
4791 /// (resolver-hop × derived-nullary-bool) shape — the SECOND peer
4792 /// threading the classification-data axis after
4793 /// [`Self::data_is_regulated`] opened it, pinning the data axis
4794 /// as a proven-repeatable structural sub-corner across TWO sibling
4795 /// closed-set projections (`is_regulated` / `is_restricted`).
4796 /// Structural byte-for-byte peer of
4797 /// [`Self::data_is_regulated`]: both walk the SAME DIRECT scalar
4798 /// closed-set field's derived projection on the resolved
4799 /// [`Classification`] (`.data_classification.is_regulated()` /
4800 /// `.is_restricted()`) — TWO layers of `Default` short-circuit
4801 /// ([`Classification::gate_compute`] → [`crate::classification::DataClassification::default = Internal`])
4802 /// — distinct from the two `horizon_*` peers which walk a NESTED-
4803 /// STRUCT projection (`.horizon.kind`) with THREE layers of
4804 /// `Default`. The resolver-hop shape is byte-identical across all
4805 /// five peers.
4806 ///
4807 /// # Semantics — resolver hop + derived-nullary-boolean
4808 ///
4809 /// `data_is_restricted()` returns `true` iff
4810 /// `self.resolved_classification().data_is_restricted()`. The
4811 /// resolver returns the authored [`Classification`] when present
4812 /// and the substrate default [`Classification::gate_compute`] on
4813 /// absence. Because [`Classification::gate_compute`] carries
4814 /// [`crate::classification::DataClassification::default = Internal`],
4815 /// a bare ephemeral spec with no `:classification` slot answers
4816 /// `true` — the default-arm short-circuit propagates through TWO
4817 /// layers of `Default` ([`Classification::gate_compute`] →
4818 /// [`crate::classification::DataClassification::default`]) to
4819 /// this predicate's answer. FIRST direct-scalar ephemeral-surface
4820 /// peer whose absent-classification default answers `true`, not
4821 /// `false` (`data_is_regulated` and `calm_requires_coordination`
4822 /// both project `false` on the same absent classification),
4823 /// mirror-image of [`Self::horizon_terminates`]'s `Bounded`-default
4824 /// `true` baseline on the nested-struct sub-corner. A regression
4825 /// that dropped the resolver hop, probed
4826 /// [`Classification::has_data_classification`] directly (dropping
4827 /// the `.is_restricted()` projection), or inverted the projection
4828 /// (silently demoting the Internal baseline to "unrestricted")
4829 /// fails HERE at ONE narrow substrate site before drifting
4830 /// through every unadorned ephemeral spec's baseline access-
4831 /// control-mandatory answer.
4832 ///
4833 /// # Compounding
4834 ///
4835 /// The ephemeral require-tag classifier composes this primitive
4836 /// as a fixed tag `data-restricted` on `EPHEMERAL_FIXED_TAG_ARMS`
4837 /// — byte-for-byte peer of the point surface's `data-restricted`
4838 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
4839 /// [`Classification::data_is_restricted`] directly. The two-
4840 /// surface parity contract holds by construction: both surfaces
4841 /// route through the SAME
4842 /// [`Classification::data_is_restricted`] primitive after the
4843 /// ephemeral surface pays ONE resolver hop — a future
4844 /// [`crate::classification::DataClassification`] variant or a
4845 /// future normalization at the substrate primitive lands at ONE
4846 /// site and both surfaces' `data-restricted` fixed tags inherit
4847 /// the shift mechanically. The closed-set-internal implication
4848 /// `is_regulated() ⇒ is_restricted()` composes through the
4849 /// resolver hop to
4850 /// `data_is_regulated() ⇒ data_is_restricted()` at this surface
4851 /// too.
4852 ///
4853 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4854 /// preserves proofs; the classification-data-axis derived-nullary-
4855 /// boolean probe body composes ONE resolver primitive
4856 /// ([`Self::resolved_classification`]) with ONE
4857 /// [`Classification`] primitive
4858 /// ([`Classification::data_is_restricted`]) so every downstream
4859 /// (`data-restricted` fixed tags on both surfaces in tatara-check,
4860 /// future compliance-baseline / access-control-mandatory
4861 /// validators, future variant additions on
4862 /// [`crate::classification::DataClassification`]) binds through
4863 /// the SAME `data_is_restricted()` shape rather than restating
4864 /// either the resolver walk or the closed-set projection
4865 /// composition at the callsite. THEORY.md §VI.1 — generation
4866 /// over composition; a future
4867 /// [`crate::classification::DataClassification`] variant lands
4868 /// at ONE `ALL` entry + ONE `is_restricted` arm on the closed set
4869 /// and both surfaces pick it up mechanically.
4870 #[must_use]
4871 pub fn data_is_restricted(&self) -> bool {
4872 self.resolved_classification().data_is_restricted()
4873 }
4874
4875 /// Derived-boolean predicate — does this ephemeral spec's
4876 /// resolved [`Classification`]'s
4877 /// [`crate::classification::ConvergencePointType`] project to
4878 /// `true` under
4879 /// [`crate::classification::ConvergencePointType::is_endomorphic`]?
4880 /// Byte-for-byte peer of
4881 /// [`Classification::point_is_endomorphic`] wrapped through the
4882 /// [`Self::resolved_classification`] resolver so an operator-
4883 /// omitted `:classification` slot on `(defephemeral …)` still
4884 /// answers via the substrate default. The ONE ephemeral-surface
4885 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4886 /// derived-nullary-boolean walk on the 1→1 topology-bucket
4887 /// question over the classification-`point_type` axis.
4888 ///
4889 /// # Sixth derived-nullary-boolean peer on the ephemeral surface
4890 ///
4891 /// Peer of [`Self::horizon_terminates`],
4892 /// [`Self::horizon_requires_metric_axes`],
4893 /// [`Self::calm_requires_coordination`],
4894 /// [`Self::data_is_regulated`], and [`Self::data_is_restricted`]
4895 /// on the ephemeral surface's (resolver-hop × derived-nullary-bool)
4896 /// shape — the FIRST peer threading the classification-`point_type`
4897 /// axis after the two `horizon_*`, one `calm_*`, and two `data_*`
4898 /// peers populated the horizon, calm, and data axes. Direct-scalar
4899 /// peer of the sibling `data_*` and `calm_*` arms but distinct by
4900 /// ONE structural degree at the underlying [`Classification`]
4901 /// primitive: [`crate::classification::ConvergencePointType`] has
4902 /// NO [`Default`] impl, so the absent-`:classification` baseline
4903 /// answers `false` via the resolver's substrate default
4904 /// [`Classification::gate_compute`] carrying its chosen
4905 /// `point_type: Gate` field (not via a `#[default]` short-circuit
4906 /// on the point-type axis itself). The resolver-hop shape is
4907 /// byte-identical across all six peers.
4908 ///
4909 /// # Semantics — resolver hop + derived-nullary-boolean
4910 ///
4911 /// `point_is_endomorphic()` returns `true` iff
4912 /// `self.resolved_classification().point_is_endomorphic()`. The
4913 /// resolver returns the authored [`Classification`] when present
4914 /// and the substrate default [`Classification::gate_compute`] on
4915 /// absence. Because [`Classification::gate_compute`] carries
4916 /// [`crate::classification::ConvergencePointType::Gate`] (a
4917 /// convergent barrier point, not a 1→1 endomorphism), a bare
4918 /// ephemeral spec with no `:classification` slot answers `false`.
4919 /// A regression that dropped the resolver hop, probed the wrong
4920 /// closed-set arm, or inverted the projection fails HERE at ONE
4921 /// narrow substrate site before drifting through every unadorned
4922 /// ephemeral spec's DAG-composition answer.
4923 ///
4924 /// # Compounding
4925 ///
4926 /// The ephemeral require-tag classifier composes this primitive
4927 /// as a fixed tag `endomorphic-point` on
4928 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
4929 /// surface's `endomorphic-point` fixed tag on
4930 /// `POINT_FIXED_TAG_ARMS` via
4931 /// [`Classification::point_is_endomorphic`] directly. The two-
4932 /// surface parity contract holds by construction: both surfaces
4933 /// route through the SAME
4934 /// [`Classification::point_is_endomorphic`] primitive after the
4935 /// ephemeral surface pays ONE resolver hop — a future
4936 /// [`crate::classification::ConvergencePointType`] variant or a
4937 /// future normalization at the substrate primitive lands at ONE
4938 /// site and both surfaces' `endomorphic-point` fixed tags inherit
4939 /// the shift mechanically. Sibling projections
4940 /// [`crate::classification::ConvergencePointType::is_diffusive`]
4941 /// and [`crate::classification::ConvergencePointType::is_convergent`]
4942 /// compose byte-identically as future seventh + eighth ephemeral-
4943 /// surface peers; when all three land the three-way partition
4944 /// contract sealed on the closed set by
4945 /// `convergence_point_type_buckets_cover_every_variant` composes
4946 /// through the resolver-hop layer as a substrate-wide theorem.
4947 ///
4948 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
4949 /// preserves proofs; the classification-`point_type`-axis derived-
4950 /// nullary-boolean probe body composes ONE resolver primitive
4951 /// ([`Self::resolved_classification`]) with ONE
4952 /// [`Classification`] primitive
4953 /// ([`Classification::point_is_endomorphic`]) so every downstream
4954 /// (`endomorphic-point` fixed tags on both surfaces in tatara-check,
4955 /// future DAG composition / edge-cardinality validators, future
4956 /// variant additions on
4957 /// [`crate::classification::ConvergencePointType`]) binds through
4958 /// the SAME `point_is_endomorphic()` shape rather than restating
4959 /// either the resolver walk or the closed-set projection
4960 /// composition at the callsite. THEORY.md §VI.1 — generation over
4961 /// composition; a future
4962 /// [`crate::classification::ConvergencePointType`] variant lands
4963 /// at ONE `ALL` entry + ONE `is_endomorphic` arm on the closed
4964 /// set and both surfaces pick it up mechanically.
4965 #[must_use]
4966 pub fn point_is_endomorphic(&self) -> bool {
4967 self.resolved_classification().point_is_endomorphic()
4968 }
4969
4970 /// Derived-boolean predicate — does this ephemeral spec's
4971 /// resolved [`Classification`]'s
4972 /// [`crate::classification::ConvergencePointType`] project to
4973 /// `true` under
4974 /// [`crate::classification::ConvergencePointType::is_diffusive`]?
4975 /// Byte-for-byte peer of
4976 /// [`Classification::point_is_diffusive`] wrapped through the
4977 /// [`Self::resolved_classification`] resolver so an operator-
4978 /// omitted `:classification` slot on `(defephemeral …)` still
4979 /// answers via the substrate default. The ONE ephemeral-surface
4980 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
4981 /// derived-nullary-boolean walk on the 1→N fan-out topology-bucket
4982 /// question over the classification-`point_type` axis.
4983 ///
4984 /// # Seventh derived-nullary-boolean peer on the ephemeral surface
4985 ///
4986 /// Peer of [`Self::horizon_terminates`],
4987 /// [`Self::horizon_requires_metric_axes`],
4988 /// [`Self::calm_requires_coordination`],
4989 /// [`Self::data_is_regulated`], [`Self::data_is_restricted`], and
4990 /// [`Self::point_is_endomorphic`] on the ephemeral surface's
4991 /// (resolver-hop × derived-nullary-bool) shape — the SEVENTH peer
4992 /// overall and the SECOND peer threading the classification-
4993 /// `point_type` axis. Direct-scalar peer of
4994 /// [`Self::point_is_endomorphic`]: both compose the SAME resolver
4995 /// hop and the SAME closed-set carrier through the SAME chosen-
4996 /// field baseline discipline (`Gate.is_diffusive() = false`,
4997 /// mirror-image of `Gate.is_endomorphic() = false`). The
4998 /// resolver-hop shape is byte-identical across all seven peers.
4999 ///
5000 /// # Semantics — resolver hop + derived-nullary-boolean
5001 ///
5002 /// `point_is_diffusive()` returns `true` iff
5003 /// `self.resolved_classification().point_is_diffusive()`. The
5004 /// resolver returns the authored [`Classification`] when present
5005 /// and the substrate default [`Classification::gate_compute`] on
5006 /// absence. Because [`Classification::gate_compute`] carries
5007 /// [`crate::classification::ConvergencePointType::Gate`] (a
5008 /// convergent barrier, not a fan-out), a bare ephemeral spec with
5009 /// no `:classification` slot answers `false`. A regression that
5010 /// dropped the resolver hop, probed the wrong closed-set arm, or
5011 /// inverted the projection fails HERE at ONE narrow substrate
5012 /// site before drifting through every unadorned ephemeral spec's
5013 /// DAG-composition answer.
5014 ///
5015 /// # Compounding — first ephemeral-surface corner-peer mutex on the `point_type` axis
5016 ///
5017 /// The ephemeral require-tag classifier composes this primitive
5018 /// as a fixed tag `diffusive-point` on `EPHEMERAL_FIXED_TAG_ARMS`
5019 /// — byte-for-byte peer of the point surface's `diffusive-point`
5020 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
5021 /// [`Classification::point_is_diffusive`] directly. The two-
5022 /// surface parity contract holds by construction: both surfaces
5023 /// route through the SAME
5024 /// [`Classification::point_is_diffusive`] primitive after the
5025 /// ephemeral surface pays ONE resolver hop. FIRST ephemeral-
5026 /// surface corner-peer pair on the `point_type` axis (with
5027 /// [`Self::point_is_endomorphic`]) whose two projections carry a
5028 /// non-trivial closed-set-internal MUTEX relationship
5029 /// (`point_is_endomorphic ⇒ ¬point_is_diffusive`), distinct from
5030 /// the sibling `data`-axis ephemeral corner-peer pair whose two
5031 /// projections carry a non-trivial IMPLICATION relationship. When
5032 /// the third sibling [`Self::point_is_convergent`] lands, the
5033 /// mutex closes into the full three-way XOR partition composed
5034 /// through the resolver-hop layer as a substrate-wide theorem.
5035 ///
5036 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5037 /// preserves proofs; the classification-`point_type`-axis derived-
5038 /// nullary-boolean probe body composes ONE resolver primitive
5039 /// ([`Self::resolved_classification`]) with ONE
5040 /// [`Classification`] primitive
5041 /// ([`Classification::point_is_diffusive`]) so every downstream
5042 /// (`diffusive-point` fixed tags on both surfaces in tatara-check,
5043 /// future DAG composition / edge-cardinality validators, future
5044 /// variant additions on
5045 /// [`crate::classification::ConvergencePointType`]) binds through
5046 /// the SAME `point_is_diffusive()` shape rather than restating
5047 /// either the resolver walk or the closed-set projection
5048 /// composition at the callsite. THEORY.md §VI.1 — generation over
5049 /// composition; a future
5050 /// [`crate::classification::ConvergencePointType`] variant lands
5051 /// at ONE `ALL` entry + ONE `is_diffusive` arm on the closed set
5052 /// and both surfaces pick it up mechanically.
5053 #[must_use]
5054 pub fn point_is_diffusive(&self) -> bool {
5055 self.resolved_classification().point_is_diffusive()
5056 }
5057
5058 /// Derived-boolean predicate — does this ephemeral spec's
5059 /// resolved [`Classification`]'s
5060 /// [`crate::classification::ConvergencePointType`] project to
5061 /// `true` under
5062 /// [`crate::classification::ConvergencePointType::is_convergent`]?
5063 /// Byte-for-byte peer of
5064 /// [`Classification::point_is_convergent`] wrapped through the
5065 /// [`Self::resolved_classification`] resolver so an operator-
5066 /// omitted `:classification` slot on `(defephemeral …)` still
5067 /// answers via the substrate default. The ONE ephemeral-surface
5068 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
5069 /// derived-nullary-boolean walk on the N→1 fan-in topology-bucket
5070 /// question over the classification-`point_type` axis.
5071 ///
5072 /// # Eighth derived-nullary-boolean peer on the ephemeral surface
5073 ///
5074 /// Peer of [`Self::horizon_terminates`],
5075 /// [`Self::horizon_requires_metric_axes`],
5076 /// [`Self::calm_requires_coordination`],
5077 /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
5078 /// [`Self::point_is_endomorphic`], and [`Self::point_is_diffusive`]
5079 /// on the ephemeral surface's (resolver-hop × derived-nullary-
5080 /// bool) shape — the EIGHTH peer overall and the THIRD peer
5081 /// threading the classification-`point_type` axis. Direct-scalar
5082 /// peer of [`Self::point_is_endomorphic`] and
5083 /// [`Self::point_is_diffusive`]: the three compose the SAME
5084 /// resolver hop and the SAME closed-set carrier through the SAME
5085 /// chosen-field baseline discipline, but the answer flips on the
5086 /// baseline — `Gate.is_convergent() = true`, so an ephemeral spec
5087 /// with no `:classification` slot answers `true` HERE (mirror-
5088 /// inverted from the two sibling probes which answer `false`).
5089 /// The resolver-hop shape is byte-identical across all eight
5090 /// peers.
5091 ///
5092 /// # Semantics — resolver hop + derived-nullary-boolean
5093 ///
5094 /// `point_is_convergent()` returns `true` iff
5095 /// `self.resolved_classification().point_is_convergent()`. The
5096 /// resolver returns the authored [`Classification`] when present
5097 /// and the substrate default [`Classification::gate_compute`] on
5098 /// absence. Because [`Classification::gate_compute`] carries
5099 /// [`crate::classification::ConvergencePointType::Gate`] (the
5100 /// canonical convergent barrier), a bare ephemeral spec with no
5101 /// `:classification` slot answers `true` — a regression that
5102 /// dropped the resolver hop, probed the wrong closed-set arm, or
5103 /// inverted the projection fails HERE at ONE narrow substrate
5104 /// site before drifting through every unadorned ephemeral spec's
5105 /// DAG-composition answer.
5106 ///
5107 /// # Compounding — closes the three-way XOR partition on the ephemeral surface
5108 ///
5109 /// The ephemeral require-tag classifier composes this primitive
5110 /// as a fixed tag `convergent-point` on `EPHEMERAL_FIXED_TAG_ARMS`
5111 /// — byte-for-byte peer of the point surface's `convergent-point`
5112 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
5113 /// [`Classification::point_is_convergent`] directly. The two-
5114 /// surface parity contract holds by construction: both surfaces
5115 /// route through the SAME
5116 /// [`Classification::point_is_convergent`] primitive after the
5117 /// ephemeral surface pays ONE resolver hop. THIRD ephemeral-
5118 /// surface peer on the `point_type` axis closing the mutex pair
5119 /// [`Self::point_is_endomorphic`] / [`Self::point_is_diffusive`]
5120 /// into the FULL three-way XOR partition contract composed
5121 /// through the resolver-hop layer as a substrate-wide theorem.
5122 ///
5123 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5124 /// preserves proofs; the classification-`point_type`-axis derived-
5125 /// nullary-boolean probe body composes ONE resolver primitive
5126 /// ([`Self::resolved_classification`]) with ONE
5127 /// [`Classification`] primitive
5128 /// ([`Classification::point_is_convergent`]) so every downstream
5129 /// (`convergent-point` fixed tags on both surfaces in tatara-check,
5130 /// future DAG composition / edge-cardinality validators, future
5131 /// variant additions on
5132 /// [`crate::classification::ConvergencePointType`]) binds through
5133 /// the SAME `point_is_convergent()` shape rather than restating
5134 /// either the resolver walk or the closed-set projection
5135 /// composition at the callsite. THEORY.md §VI.1 — generation over
5136 /// composition; a future
5137 /// [`crate::classification::ConvergencePointType`] variant lands
5138 /// at ONE `ALL` entry + ONE `is_convergent` arm on the closed set
5139 /// and both surfaces pick it up mechanically.
5140 #[must_use]
5141 pub fn point_is_convergent(&self) -> bool {
5142 self.resolved_classification().point_is_convergent()
5143 }
5144
5145 /// Derived-boolean predicate — does this ephemeral spec's
5146 /// resolved [`Classification`]'s
5147 /// [`crate::classification::SubstrateType`] project to `true`
5148 /// under [`crate::classification::SubstrateType::is_resource`]?
5149 /// Byte-for-byte peer of
5150 /// [`Classification::substrate_is_resource`] wrapped through the
5151 /// [`Self::resolved_classification`] resolver so an operator-
5152 /// omitted `:classification` slot on `(defephemeral …)` still
5153 /// answers via the substrate default. The ONE ephemeral-surface
5154 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
5155 /// derived-nullary-boolean walk on the resource-plane bucket
5156 /// question over the classification-`substrate` axis.
5157 ///
5158 /// # Ninth derived-nullary-boolean peer on the ephemeral surface
5159 ///
5160 /// Peer of [`Self::horizon_terminates`],
5161 /// [`Self::horizon_requires_metric_axes`],
5162 /// [`Self::calm_requires_coordination`],
5163 /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
5164 /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
5165 /// and [`Self::point_is_convergent`] on the ephemeral surface's
5166 /// (resolver-hop × derived-nullary-bool) shape — the NINTH peer
5167 /// overall and the FIRST peer threading the classification-
5168 /// `substrate` axis (the fourth of six classification axes
5169 /// participating on this corner, after `horizon`, `calm`,
5170 /// `data_classification`, and `point_type`). The resolver-hop
5171 /// shape is byte-identical across all nine peers.
5172 ///
5173 /// # Semantics — resolver hop + derived-nullary-boolean
5174 ///
5175 /// `substrate_is_resource()` returns `true` iff
5176 /// `self.resolved_classification().substrate_is_resource()`. The
5177 /// resolver returns the authored [`Classification`] when present
5178 /// and the substrate default [`Classification::gate_compute`] on
5179 /// absence. Because [`Classification::gate_compute`] carries
5180 /// [`crate::classification::SubstrateType::Compute`] (the
5181 /// canonical resource-plane substrate), a bare ephemeral spec
5182 /// with no `:classification` slot answers `true` — a regression
5183 /// that dropped the resolver hop, probed the wrong closed-set
5184 /// arm, or inverted the projection fails HERE at ONE narrow
5185 /// substrate site before drifting through every unadorned
5186 /// ephemeral spec's plane-baseline answer.
5187 ///
5188 /// # Compounding — opens the substrate axis on the ephemeral surface
5189 ///
5190 /// The ephemeral require-tag classifier composes this primitive
5191 /// as a fixed tag `resource-substrate` on
5192 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5193 /// surface's `resource-substrate` fixed tag on
5194 /// `POINT_FIXED_TAG_ARMS` via
5195 /// [`Classification::substrate_is_resource`] directly. The two-
5196 /// surface parity contract holds by construction: both surfaces
5197 /// route through the SAME
5198 /// [`Classification::substrate_is_resource`] primitive after the
5199 /// ephemeral surface pays ONE resolver hop. FIRST ephemeral-
5200 /// surface peer on the `substrate` axis — future sibling
5201 /// projections [`crate::classification::SubstrateType::is_policy`]
5202 /// and [`crate::classification::SubstrateType::is_telemetry`]
5203 /// compose byte-identically as future tenth + eleventh peers,
5204 /// closing the axis into a proven-repeatable three-peer sub-
5205 /// corner exactly as the `point_type` axis was closed on this
5206 /// surface by
5207 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`.
5208 ///
5209 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5210 /// preserves proofs; the classification-`substrate`-axis derived-
5211 /// nullary-boolean probe body composes ONE resolver primitive
5212 /// ([`Self::resolved_classification`]) with ONE
5213 /// [`Classification`] primitive
5214 /// ([`Classification::substrate_is_resource`]) so every
5215 /// downstream (`resource-substrate` fixed tags on both surfaces
5216 /// in tatara-check, future plane-baseline / compliance-baseline
5217 /// selectors, future variant additions on
5218 /// [`crate::classification::SubstrateType`]) binds through the
5219 /// SAME `substrate_is_resource()` shape rather than restating
5220 /// either the resolver walk or the closed-set projection
5221 /// composition at the callsite. THEORY.md §VI.1 — generation
5222 /// over composition; a future
5223 /// [`crate::classification::SubstrateType`] variant lands at ONE
5224 /// `ALL` entry + ONE `is_resource` arm on the closed set and
5225 /// both surfaces pick it up mechanically.
5226 #[must_use]
5227 pub fn substrate_is_resource(&self) -> bool {
5228 self.resolved_classification().substrate_is_resource()
5229 }
5230
5231 /// Derived-boolean predicate — does this ephemeral spec's
5232 /// resolved [`Classification`]'s
5233 /// [`crate::classification::SubstrateType`] project to `true`
5234 /// under [`crate::classification::SubstrateType::is_policy`]?
5235 /// Byte-for-byte peer of
5236 /// [`Classification::substrate_is_policy`] wrapped through the
5237 /// [`Self::resolved_classification`] resolver so an operator-
5238 /// omitted `:classification` slot on `(defephemeral …)` still
5239 /// answers via the substrate default. The ONE ephemeral-surface
5240 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
5241 /// derived-nullary-boolean walk on the policy-plane bucket
5242 /// question over the classification-`substrate` axis.
5243 ///
5244 /// # Tenth derived-nullary-boolean peer on the ephemeral surface
5245 ///
5246 /// Peer of [`Self::horizon_terminates`],
5247 /// [`Self::horizon_requires_metric_axes`],
5248 /// [`Self::calm_requires_coordination`],
5249 /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
5250 /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
5251 /// [`Self::point_is_convergent`], and
5252 /// [`Self::substrate_is_resource`] on the ephemeral surface's
5253 /// (resolver-hop × derived-nullary-bool) shape — the TENTH peer
5254 /// overall and the SECOND peer threading the classification-
5255 /// `substrate` axis, promoting that axis on this surface from a
5256 /// proven-repeatable one-off to a proven-repeatable pair.
5257 /// FIRST ephemeral-surface substrate-axis corner-peer pair
5258 /// carrying a non-trivial closed-set-internal MUTEX relationship
5259 /// (`substrate_is_resource ⇒ ¬substrate_is_policy`), structural
5260 /// twin of the sibling `point_type`-axis MUTEX pair sealed on
5261 /// this surface by
5262 /// `ephemeral_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`.
5263 /// The resolver-hop shape is byte-identical across all ten peers.
5264 ///
5265 /// # Semantics — resolver hop + derived-nullary-boolean
5266 ///
5267 /// `substrate_is_policy()` returns `true` iff
5268 /// `self.resolved_classification().substrate_is_policy()`. The
5269 /// resolver returns the authored [`Classification`] when present
5270 /// and the substrate default [`Classification::gate_compute`] on
5271 /// absence. Because [`Classification::gate_compute`] carries
5272 /// [`crate::classification::SubstrateType::Compute`] (the
5273 /// canonical resource-plane substrate, NOT a policy plane), a
5274 /// bare ephemeral spec with no `:classification` slot answers
5275 /// `false` — a regression that dropped the resolver hop, probed
5276 /// the wrong closed-set arm, or inverted the projection fails
5277 /// HERE at ONE narrow substrate site before drifting through
5278 /// every unadorned ephemeral spec's plane-baseline answer.
5279 ///
5280 /// # Compounding — second substrate-axis peer on the ephemeral surface
5281 ///
5282 /// The ephemeral require-tag classifier composes this primitive
5283 /// as a fixed tag `policy-substrate` on
5284 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5285 /// surface's `policy-substrate` fixed tag on
5286 /// `POINT_FIXED_TAG_ARMS` via
5287 /// [`Classification::substrate_is_policy`] directly. The two-
5288 /// surface parity contract holds by construction: both surfaces
5289 /// route through the SAME
5290 /// [`Classification::substrate_is_policy`] primitive after the
5291 /// ephemeral surface pays ONE resolver hop. SECOND ephemeral-
5292 /// surface peer on the `substrate` axis — sibling projection
5293 /// [`crate::classification::SubstrateType::is_telemetry`]
5294 /// composes byte-identically as a future eleventh peer, closing
5295 /// the axis into a proven-repeatable three-peer sub-corner
5296 /// exactly as the `point_type` axis was closed on this surface
5297 /// by
5298 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`.
5299 ///
5300 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5301 /// preserves proofs; the classification-`substrate`-axis derived-
5302 /// nullary-boolean probe body composes ONE resolver primitive
5303 /// ([`Self::resolved_classification`]) with ONE
5304 /// [`Classification`] primitive
5305 /// ([`Classification::substrate_is_policy`]) so every
5306 /// downstream (`policy-substrate` fixed tags on both surfaces
5307 /// in tatara-check, future plane-baseline / compliance-baseline
5308 /// selectors, future variant additions on
5309 /// [`crate::classification::SubstrateType`]) binds through the
5310 /// SAME `substrate_is_policy()` shape rather than restating
5311 /// either the resolver walk or the closed-set projection
5312 /// composition at the callsite. THEORY.md §VI.1 — generation
5313 /// over composition; a future
5314 /// [`crate::classification::SubstrateType`] variant lands at ONE
5315 /// `ALL` entry + ONE `is_policy` arm on the closed set and
5316 /// both surfaces pick it up mechanically.
5317 #[must_use]
5318 pub fn substrate_is_policy(&self) -> bool {
5319 self.resolved_classification().substrate_is_policy()
5320 }
5321
5322 /// Derived-boolean predicate — does this ephemeral spec's
5323 /// resolved [`Classification`]'s
5324 /// [`crate::classification::SubstrateType`] project to `true`
5325 /// under [`crate::classification::SubstrateType::is_telemetry`]?
5326 /// Byte-for-byte peer of
5327 /// [`Classification::substrate_is_telemetry`] wrapped through
5328 /// the [`Self::resolved_classification`] resolver so an operator-
5329 /// omitted `:classification` slot on `(defephemeral …)` still
5330 /// answers via the substrate default. The ONE ephemeral-surface
5331 /// substrate primitive that owns the `(&EphemeralSpec) -> bool`
5332 /// derived-nullary-boolean walk on the telemetry-plane bucket
5333 /// question over the classification-`substrate` axis.
5334 ///
5335 /// # Eleventh derived-nullary-boolean peer on the ephemeral surface — CLOSES the substrate axis
5336 ///
5337 /// Peer of [`Self::horizon_terminates`],
5338 /// [`Self::horizon_requires_metric_axes`],
5339 /// [`Self::calm_requires_coordination`],
5340 /// [`Self::data_is_regulated`], [`Self::data_is_restricted`],
5341 /// [`Self::point_is_endomorphic`], [`Self::point_is_diffusive`],
5342 /// [`Self::point_is_convergent`], [`Self::substrate_is_resource`],
5343 /// and [`Self::substrate_is_policy`] on the ephemeral surface's
5344 /// (resolver-hop × derived-nullary-bool) shape — the ELEVENTH
5345 /// peer overall and the THIRD peer threading the classification-
5346 /// `substrate` axis. This peer CLOSES the substrate axis on the
5347 /// ephemeral surface into the FULL three-way XOR partition
5348 /// contract `substrate_is_resource ⊕ substrate_is_policy ⊕
5349 /// substrate_is_telemetry` — sealed on this surface by
5350 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`,
5351 /// the resolver-hop peer of the parent-composed
5352 /// `classification_substrate_probes_form_three_way_xor_partition_over_all`.
5353 /// Structural twin of the sibling `point_type`-axis ternary lift
5354 /// sealed on this surface by
5355 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`.
5356 /// The resolver-hop shape is byte-identical across all eleven
5357 /// peers.
5358 ///
5359 /// # Semantics — resolver hop + derived-nullary-boolean
5360 ///
5361 /// `substrate_is_telemetry()` returns `true` iff
5362 /// `self.resolved_classification().substrate_is_telemetry()`.
5363 /// The resolver returns the authored [`Classification`] when
5364 /// present and the substrate default [`Classification::gate_compute`]
5365 /// on absence. Because [`Classification::gate_compute`] carries
5366 /// [`crate::classification::SubstrateType::Compute`] (the
5367 /// canonical resource-plane substrate, NOT a telemetry plane),
5368 /// a bare ephemeral spec with no `:classification` slot answers
5369 /// `false` — a regression that dropped the resolver hop, probed
5370 /// the wrong closed-set arm, or inverted the projection fails
5371 /// HERE at ONE narrow substrate site before drifting through
5372 /// every unadorned ephemeral spec's plane-baseline answer.
5373 ///
5374 /// # Compounding — CLOSES the substrate axis on the ephemeral surface
5375 ///
5376 /// The ephemeral require-tag classifier composes this primitive
5377 /// as a fixed tag `telemetry-substrate` on
5378 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5379 /// surface's `telemetry-substrate` fixed tag on
5380 /// `POINT_FIXED_TAG_ARMS` via
5381 /// [`Classification::substrate_is_telemetry`] directly. The two-
5382 /// surface parity contract holds by construction: both surfaces
5383 /// route through the SAME
5384 /// [`Classification::substrate_is_telemetry`] primitive after the
5385 /// ephemeral surface pays ONE resolver hop. THIRD ephemeral-
5386 /// surface peer on the `substrate` axis — closes the axis into a
5387 /// proven-repeatable three-peer sub-corner exactly as the
5388 /// `point_type` axis was closed on this surface by
5389 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`.
5390 ///
5391 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5392 /// preserves proofs; the classification-`substrate`-axis derived-
5393 /// nullary-boolean probe body composes ONE resolver primitive
5394 /// ([`Self::resolved_classification`]) with ONE
5395 /// [`Classification`] primitive
5396 /// ([`Classification::substrate_is_telemetry`]) so every
5397 /// downstream (`telemetry-substrate` fixed tags on both surfaces
5398 /// in tatara-check, future plane-baseline / compliance-baseline
5399 /// selectors, future variant additions on
5400 /// [`crate::classification::SubstrateType`]) binds through the
5401 /// SAME `substrate_is_telemetry()` shape rather than restating
5402 /// either the resolver walk or the closed-set projection
5403 /// composition at the callsite. THEORY.md §VI.1 — generation
5404 /// over composition; a future
5405 /// [`crate::classification::SubstrateType`] variant lands at ONE
5406 /// `ALL` entry + ONE `is_telemetry` arm on the closed set and
5407 /// both surfaces pick it up mechanically.
5408 #[must_use]
5409 pub fn substrate_is_telemetry(&self) -> bool {
5410 self.resolved_classification().substrate_is_telemetry()
5411 }
5412
5413 /// Derived-boolean predicate — does this ephemeral spec's
5414 /// resolved [`Classification`]'s
5415 /// [`crate::classification::CalmClassification`] project to `true`
5416 /// under [`crate::classification::CalmClassification::is_monotone`]?
5417 /// Byte-for-byte peer of [`Classification::calm_is_monotone`]
5418 /// wrapped through the [`Self::resolved_classification`] resolver
5419 /// so an operator-omitted `:classification` slot on
5420 /// `(defephemeral …)` still answers via the substrate default.
5421 /// The ONE ephemeral-surface substrate primitive that owns the
5422 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5423 /// CALM-monotone-plane question — the positive framing peer of
5424 /// [`Self::calm_requires_coordination`].
5425 ///
5426 /// # Twelfth derived-nullary-boolean peer on the ephemeral surface — CLOSES the calm axis
5427 ///
5428 /// Peer of [`Self::horizon_terminates`],
5429 /// [`Self::horizon_requires_metric_axes`],
5430 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5431 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5432 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5433 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5434 /// and [`Self::substrate_is_telemetry`] on the ephemeral
5435 /// surface's (resolver-hop × derived-nullary-bool) shape — the
5436 /// TWELFTH peer overall and the SECOND peer threading the
5437 /// classification-`calm` axis. This peer CLOSES the calm axis
5438 /// on the ephemeral surface into the FULL binary XOR partition
5439 /// contract `calm_is_monotone ⊕ calm_requires_coordination` —
5440 /// sealed on this surface by
5441 /// `ephemeral_calm_probes_form_binary_xor_partition_over_all`,
5442 /// the resolver-hop peer of the parent-composed
5443 /// `classification_calm_probes_form_binary_xor_partition_over_all`.
5444 /// Structural twin of the sibling horizon-axis binary XOR
5445 /// sealed on the closed set by
5446 /// `horizon_kind_terminate_xor_requires_metric_axes`, lifted
5447 /// through the resolver hop to the ephemeral surface. The
5448 /// resolver-hop shape is byte-identical across all twelve peers.
5449 ///
5450 /// # Semantics — resolver hop + derived-nullary-boolean
5451 ///
5452 /// `calm_is_monotone()` returns `true` iff
5453 /// `self.resolved_classification().calm_is_monotone()`. The
5454 /// resolver returns the authored [`Classification`] when present
5455 /// and the substrate default [`Classification::gate_compute`] on
5456 /// absence. Because [`Classification::gate_compute`] carries
5457 /// [`crate::classification::CalmClassification::default =
5458 /// Monotone`] via `#[default]`, a bare ephemeral spec with no
5459 /// `:classification` slot answers `true` — every unadorned
5460 /// `(defephemeral …)` reads as gossip-eligible under the
5461 /// positive CALM framing, safe under Hellerstein's theorem
5462 /// (monotone operations distribute without coordination). A
5463 /// regression that dropped the resolver hop, probed the wrong
5464 /// closed-set arm, or inverted the projection fails HERE at ONE
5465 /// narrow substrate site before drifting through every
5466 /// unadorned ephemeral spec's positive-CALM-framing answer.
5467 /// Mirror-inverted from the sibling
5468 /// `calm_requires_coordination_probes_false_on_absent_classification`
5469 /// (both walk the SAME defaulted `calm` field, so
5470 /// `requires_coordination = false` ⇒ `is_monotone = true` on the
5471 /// closed set's disjoint XOR partition).
5472 ///
5473 /// # Compounding — CLOSES the calm axis on the ephemeral surface
5474 ///
5475 /// The ephemeral require-tag classifier composes this primitive
5476 /// as a fixed tag `monotone-calm` on `EPHEMERAL_FIXED_TAG_ARMS`
5477 /// — byte-for-byte peer of the point surface's `monotone-calm`
5478 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
5479 /// [`Classification::calm_is_monotone`] directly. The two-
5480 /// surface parity contract holds by construction: both surfaces
5481 /// route through the SAME [`Classification::calm_is_monotone`]
5482 /// primitive after the ephemeral surface pays ONE resolver hop.
5483 /// SECOND ephemeral-surface peer on the `calm` axis — CLOSES the
5484 /// axis into a proven-repeatable two-peer sub-corner exactly as
5485 /// the `horizon` axis is closed on the closed-set layer by
5486 /// `horizon_kind_terminate_xor_requires_metric_axes`.
5487 ///
5488 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5489 /// preserves proofs; the classification-`calm`-axis derived-
5490 /// nullary-boolean probe body composes ONE resolver primitive
5491 /// ([`Self::resolved_classification`]) with ONE
5492 /// [`Classification`] primitive
5493 /// ([`Classification::calm_is_monotone`]) so every downstream
5494 /// (`monotone-calm` fixed tags on both surfaces in tatara-check,
5495 /// future scheduler / gossip-eligibility validators reading the
5496 /// positive CALM framing, future variant additions on
5497 /// [`crate::classification::CalmClassification`]) binds through
5498 /// the SAME `calm_is_monotone()` shape rather than restating
5499 /// either the resolver walk or the closed-set projection
5500 /// composition at the callsite. THEORY.md §VI.1 — generation
5501 /// over composition; a future
5502 /// [`crate::classification::CalmClassification`] variant lands
5503 /// at ONE `ALL` entry + ONE `is_monotone` arm on the closed set
5504 /// and both surfaces pick it up mechanically.
5505 #[must_use]
5506 pub fn calm_is_monotone(&self) -> bool {
5507 self.resolved_classification().calm_is_monotone()
5508 }
5509
5510 /// Derived-boolean predicate — does this ephemeral spec's
5511 /// resolved [`Classification`]'s
5512 /// [`crate::classification::DataClassification`] project to `true`
5513 /// under [`crate::classification::DataClassification::is_public`]?
5514 /// Byte-for-byte peer of [`Classification::data_is_public`]
5515 /// wrapped through the [`Self::resolved_classification`] resolver
5516 /// so an operator-omitted `:classification` slot on
5517 /// `(defephemeral …)` still answers via the substrate default.
5518 /// The ONE ephemeral-surface substrate primitive that owns the
5519 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5520 /// freely-distributable-data question — the positive framing peer
5521 /// of [`Self::data_is_restricted`].
5522 ///
5523 /// # Thirteenth derived-nullary-boolean peer on the ephemeral surface — CLOSES the data axis
5524 ///
5525 /// Peer of [`Self::horizon_terminates`],
5526 /// [`Self::horizon_requires_metric_axes`],
5527 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5528 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5529 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5530 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5531 /// [`Self::substrate_is_telemetry`], and [`Self::calm_is_monotone`]
5532 /// on the ephemeral surface's (resolver-hop × derived-nullary-bool)
5533 /// shape — the THIRTEENTH peer overall and the THIRD peer
5534 /// threading the classification-`data_classification` axis. This
5535 /// peer CLOSES the data axis on the ephemeral surface into the
5536 /// FULL binary XOR partition contract
5537 /// `data_is_public ⊕ data_is_restricted` — sealed on this surface
5538 /// by `ephemeral_data_probes_form_binary_xor_partition_over_all`,
5539 /// the resolver-hop peer of the parent-composed
5540 /// `classification_data_probes_form_binary_xor_partition_over_all`.
5541 /// Structural twin of the sibling calm-axis binary XOR sealed on
5542 /// this surface by
5543 /// `ephemeral_calm_probes_form_binary_xor_partition_over_all`,
5544 /// lifted through the resolver hop from the six-variant data-axis
5545 /// closed set to the ephemeral surface. The resolver-hop shape is
5546 /// byte-identical across all thirteen peers.
5547 ///
5548 /// # Semantics — resolver hop + derived-nullary-boolean
5549 ///
5550 /// `data_is_public()` returns `true` iff
5551 /// `self.resolved_classification().data_is_public()`. The
5552 /// resolver returns the authored [`Classification`] when present
5553 /// and the substrate default [`Classification::gate_compute`] on
5554 /// absence. Because [`Classification::gate_compute`] carries
5555 /// [`crate::classification::DataClassification::default =
5556 /// Internal`] via `#[default]`, a bare ephemeral spec with no
5557 /// `:classification` slot answers `false` — every unadorned
5558 /// `(defephemeral …)` reads as access-controlled by default (safe
5559 /// under compliance baseline: an operator must deliberately opt
5560 /// the dataset into public distribution rather than the substrate
5561 /// silently promoting an unadorned Process onto the freely-
5562 /// distributable path). A regression that dropped the resolver
5563 /// hop, probed the wrong closed-set arm, or inverted the
5564 /// projection fails HERE at ONE narrow substrate site before
5565 /// drifting through every unadorned ephemeral spec's positive-
5566 /// distribution-framing answer. Mirror-inverted from the sibling
5567 /// `data_is_restricted_probes_true_on_absent_classification`
5568 /// (both walk the SAME defaulted `data_classification` field, so
5569 /// `is_restricted = true` ⇒ `is_public = false` on the closed
5570 /// set's disjoint XOR partition).
5571 ///
5572 /// # Compounding — CLOSES the data axis on the ephemeral surface
5573 ///
5574 /// The ephemeral require-tag classifier composes this primitive
5575 /// as a fixed tag `public-data` on `EPHEMERAL_FIXED_TAG_ARMS`
5576 /// — byte-for-byte peer of the point surface's `public-data`
5577 /// fixed tag on `POINT_FIXED_TAG_ARMS` via
5578 /// [`Classification::data_is_public`] directly. The two-
5579 /// surface parity contract holds by construction: both surfaces
5580 /// route through the SAME [`Classification::data_is_public`]
5581 /// primitive after the ephemeral surface pays ONE resolver hop.
5582 /// THIRD ephemeral-surface peer on the `data_classification` axis
5583 /// — CLOSES the axis into a proven-repeatable three-peer sub-
5584 /// corner (data_is_regulated, data_is_restricted, data_is_public)
5585 /// whose complementary XOR partition seals on the closed set by
5586 /// `data_classification_public_xor_restricted` and composes
5587 /// through the resolver hop as a substrate-wide theorem.
5588 ///
5589 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5590 /// preserves proofs; the classification-`data_classification`-axis
5591 /// derived-nullary-boolean probe body composes ONE resolver
5592 /// primitive ([`Self::resolved_classification`]) with ONE
5593 /// [`Classification`] primitive
5594 /// ([`Classification::data_is_public`]) so every downstream
5595 /// (`public-data` fixed tags on both surfaces in tatara-check,
5596 /// future compliance-baseline / audit-log-optional validators
5597 /// reading the positive distribution framing, future variant
5598 /// additions on
5599 /// [`crate::classification::DataClassification`]) binds through
5600 /// the SAME `data_is_public()` shape rather than restating either
5601 /// the resolver walk or the closed-set projection composition at
5602 /// the callsite. THEORY.md §VI.1 — generation over composition; a
5603 /// future [`crate::classification::DataClassification`] variant
5604 /// lands at ONE `ALL` entry + ONE `is_public` arm on the closed
5605 /// set and both surfaces pick it up mechanically.
5606 #[must_use]
5607 pub fn data_is_public(&self) -> bool {
5608 self.resolved_classification().data_is_public()
5609 }
5610
5611 /// Derived-boolean predicate — does this ephemeral spec's resolved
5612 /// [`Classification`]'s
5613 /// [`crate::classification::Horizon::direction`] slot (defaulted
5614 /// through [`crate::classification::OptimizationDirection::default =
5615 /// Minimize`] on absence) project to `true` under
5616 /// [`crate::classification::OptimizationDirection::prefers_lower`]?
5617 /// Byte-for-byte peer of
5618 /// [`crate::classification::Classification::direction_prefers_lower`]
5619 /// wrapped through the [`Self::resolved_classification`] resolver so
5620 /// an operator-omitted `:classification` slot on
5621 /// `(defephemeral …)` still answers via the substrate default. The
5622 /// ONE ephemeral-surface substrate primitive that owns the
5623 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5624 /// lower-is-better optimization-polarity question.
5625 ///
5626 /// # Fourteenth derived-nullary-boolean peer on the ephemeral surface — opens the optimization-direction axis
5627 ///
5628 /// Peer of the thirteen prior nullary-boolean substrate primitives
5629 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
5630 /// [`Self::horizon_requires_metric_axes`],
5631 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5632 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5633 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5634 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5635 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
5636 /// [`Self::data_is_public`]) on the ephemeral surface's
5637 /// (resolver-hop × derived-nullary-bool) shape — the FOURTEENTH
5638 /// peer overall and the FIRST peer threading the classification-
5639 /// `horizon.direction` axis on this surface. Opens the SIXTH
5640 /// classification axis into the ephemeral fixed-tag algebra after
5641 /// the horizon, calm, data, point, and substrate axes. The
5642 /// resolver-hop shape is byte-identical across all fourteen peers.
5643 ///
5644 /// # Semantics — resolver hop + derived-nullary-boolean
5645 ///
5646 /// `direction_prefers_lower()` returns `true` iff
5647 /// `self.resolved_classification().direction_prefers_lower()`. The
5648 /// resolver returns the authored [`Classification`] when present
5649 /// and the substrate default [`Classification::gate_compute`] on
5650 /// absence. Because [`Classification::gate_compute`] carries
5651 /// `horizon: Horizon::default()` whose `direction` field is `None`,
5652 /// and [`crate::classification::OptimizationDirection::default =
5653 /// Minimize`] projects `prefers_lower = true`, a bare ephemeral
5654 /// spec with no `:classification` slot answers `true` — every
5655 /// unadorned `(defephemeral …)` reads as lower-is-better under the
5656 /// substrate polarity default (safe under the asymptotic-health
5657 /// rate-window evaluator's convention: an operator must
5658 /// deliberately opt into Maximize polarity rather than the
5659 /// substrate silently flipping every unadorned Process onto the
5660 /// higher-is-better path). A regression that dropped the resolver
5661 /// hop, probed the wrong closed-set arm, or inverted the projection
5662 /// fails HERE at ONE narrow substrate site before drifting through
5663 /// every unadorned ephemeral spec's rate-window evaluator polarity.
5664 ///
5665 /// # Compounding — opens the optimization-direction axis on the ephemeral surface
5666 ///
5667 /// The ephemeral require-tag classifier composes this primitive as
5668 /// a fixed tag `prefers-lower-direction` on
5669 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5670 /// surface's `prefers-lower-direction` fixed tag on
5671 /// `POINT_FIXED_TAG_ARMS` via
5672 /// [`Classification::direction_prefers_lower`] directly. The
5673 /// two-surface parity contract holds by construction: both surfaces
5674 /// route through the SAME [`Classification::direction_prefers_lower`]
5675 /// primitive after the ephemeral surface pays ONE resolver hop.
5676 /// A future antisymmetric peer (`direction_prefers_higher`) closes
5677 /// the binary XOR partition on this axis — mirror of the calm-axis
5678 /// (`monotone-calm ⊕ coordination-required`) and data-axis
5679 /// (`public-data ⊕ data-restricted`) closures on this surface.
5680 ///
5681 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5682 /// preserves proofs; the classification-`horizon.direction`-axis
5683 /// derived-nullary-boolean probe body composes ONE resolver
5684 /// primitive ([`Self::resolved_classification`]) with ONE
5685 /// [`Classification`] primitive
5686 /// ([`Classification::direction_prefers_lower`]) so every
5687 /// downstream (the `prefers-lower-direction` fixed tags on both
5688 /// surfaces in tatara-check, future asymptotic-health rate-window
5689 /// / regression-detector evaluators, future variant additions on
5690 /// [`crate::classification::OptimizationDirection`]) binds through
5691 /// the SAME `direction_prefers_lower()` shape rather than restating
5692 /// either the resolver walk or the closed-set projection
5693 /// composition at the callsite. THEORY.md §VI.1 — generation over
5694 /// composition; a future
5695 /// [`crate::classification::OptimizationDirection`] variant lands
5696 /// at ONE `ALL` entry + ONE `prefers_lower` arm on the closed set
5697 /// and both surfaces pick it up mechanically.
5698 #[must_use]
5699 pub fn direction_prefers_lower(&self) -> bool {
5700 self.resolved_classification().direction_prefers_lower()
5701 }
5702
5703 /// POSITIVE-FRAMING PEER of [`Self::direction_prefers_lower`] —
5704 /// does this ephemeral spec's resolved [`Classification`]'s
5705 /// [`crate::classification::Horizon::direction`] slot (defaulted
5706 /// through [`crate::classification::OptimizationDirection::default =
5707 /// Minimize`] on absence) project to `true` under
5708 /// [`crate::classification::OptimizationDirection::prefers_higher`]?
5709 /// Byte-for-byte peer of
5710 /// [`crate::classification::Classification::direction_prefers_higher`]
5711 /// wrapped through the [`Self::resolved_classification`] resolver
5712 /// so an operator-omitted `:classification` slot on
5713 /// `(defephemeral …)` still answers via the substrate default. The
5714 /// ONE ephemeral-surface substrate primitive that owns the
5715 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5716 /// higher-is-better optimization-polarity question.
5717 ///
5718 /// # Fifteenth derived-nullary-boolean peer on the ephemeral surface — CLOSES the optimization-direction axis
5719 ///
5720 /// Peer of the fourteen prior nullary-boolean substrate primitives
5721 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
5722 /// [`Self::horizon_requires_metric_axes`],
5723 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5724 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5725 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5726 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5727 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
5728 /// [`Self::data_is_public`], [`Self::direction_prefers_lower`]) on
5729 /// the ephemeral surface's (resolver-hop × derived-nullary-bool)
5730 /// shape — the FIFTEENTH peer overall and the SECOND peer
5731 /// threading the classification-`horizon.direction` axis on this
5732 /// surface. CLOSES the SIXTH classification axis into a binary XOR
5733 /// partition on the ephemeral surface after the horizon, calm,
5734 /// data, point, and substrate axes — completing the axis-coverage
5735 /// milestone on this surface: ALL SIX classification axes now
5736 /// have their partitions closed at the ephemeral-surface derived-
5737 /// nullary corner. The resolver-hop shape is byte-identical across
5738 /// all fifteen peers.
5739 ///
5740 /// # Semantics — resolver hop + derived-nullary-boolean
5741 ///
5742 /// `direction_prefers_higher()` returns `true` iff
5743 /// `self.resolved_classification().direction_prefers_higher()`.
5744 /// The resolver returns the authored [`Classification`] when
5745 /// present and the substrate default
5746 /// [`Classification::gate_compute`] on absence. Because
5747 /// [`Classification::gate_compute`] carries `horizon:
5748 /// Horizon::default()` whose `direction` field is `None`, and
5749 /// [`crate::classification::OptimizationDirection::default =
5750 /// Minimize`] projects `prefers_higher = false`, a bare ephemeral
5751 /// spec with no `:classification` slot answers `false` — every
5752 /// unadorned `(defephemeral …)` reads as lower-is-better under the
5753 /// substrate polarity default (safe under the asymptotic-health
5754 /// rate-window evaluator's convention: an operator must
5755 /// deliberately opt into Maximize polarity rather than the
5756 /// substrate silently flipping every unadorned Process onto the
5757 /// higher-is-better path). A regression that dropped the resolver
5758 /// hop, probed the wrong closed-set arm, or inverted the
5759 /// projection fails HERE at ONE narrow substrate site before
5760 /// drifting through every unadorned ephemeral spec's rate-window
5761 /// evaluator polarity.
5762 ///
5763 /// # Compounding — CLOSES the optimization-direction axis on the ephemeral surface
5764 ///
5765 /// The ephemeral require-tag classifier composes this primitive as
5766 /// a fixed tag `prefers-higher-direction` on
5767 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5768 /// surface's `prefers-higher-direction` fixed tag on
5769 /// `POINT_FIXED_TAG_ARMS` via
5770 /// [`Classification::direction_prefers_higher`] directly. The
5771 /// two-surface parity contract holds by construction: both
5772 /// surfaces route through the SAME
5773 /// [`Classification::direction_prefers_higher`] primitive after
5774 /// the ephemeral surface pays ONE resolver hop. SECOND
5775 /// optimization-direction-axis peer CLOSES the axis into the FULL
5776 /// binary XOR partition contract on this surface — the resolver-
5777 /// hop peer of the parent-composed
5778 /// `classification_direction_probes_form_binary_xor_partition_over_all`,
5779 /// mirror of the calm-axis (`monotone-calm ⊕ coordination-required`)
5780 /// and data-axis (`public-data ⊕ data-restricted`) closures on
5781 /// this surface.
5782 ///
5783 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5784 /// preserves proofs; the classification-`horizon.direction`-axis
5785 /// derived-nullary-boolean probe body composes ONE resolver
5786 /// primitive ([`Self::resolved_classification`]) with ONE
5787 /// [`Classification`] primitive
5788 /// ([`Classification::direction_prefers_higher`]) so every
5789 /// downstream (the `prefers-higher-direction` fixed tags on both
5790 /// surfaces in tatara-check, future asymptotic-health rate-window
5791 /// / regression-detector evaluators, future variant additions on
5792 /// [`crate::classification::OptimizationDirection`]) binds through
5793 /// the SAME `direction_prefers_higher()` shape rather than
5794 /// restating either the resolver walk or the closed-set projection
5795 /// composition at the callsite. THEORY.md §VI.1 — generation over
5796 /// composition; a future
5797 /// [`crate::classification::OptimizationDirection`] variant lands
5798 /// at ONE `ALL` entry + ONE `prefers_higher` arm on the closed set
5799 /// and both surfaces pick it up mechanically.
5800 #[must_use]
5801 pub fn direction_prefers_higher(&self) -> bool {
5802 self.resolved_classification().direction_prefers_higher()
5803 }
5804
5805 /// Derived-boolean predicate — does this ephemeral spec's resolved
5806 /// [`Classification`]'s `point_type` slot project to `Arity::One`
5807 /// under
5808 /// [`crate::classification::ConvergencePointType::input_arity`]?
5809 /// Byte-for-byte peer of
5810 /// [`crate::classification::Classification::input_arity_is_one`]
5811 /// wrapped through the [`Self::resolved_classification`] resolver
5812 /// so an operator-omitted `:classification` slot on
5813 /// `(defephemeral …)` still answers via the substrate default. The
5814 /// ONE ephemeral-surface substrate primitive that owns the
5815 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5816 /// single-input side of the DAG-composition input-arity projection.
5817 ///
5818 /// # Sixteenth derived-nullary-boolean peer on the ephemeral surface — opens the input-arity axis
5819 ///
5820 /// Peer of the fifteen prior nullary-boolean substrate primitives
5821 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
5822 /// [`Self::horizon_requires_metric_axes`],
5823 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5824 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5825 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5826 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5827 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
5828 /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
5829 /// [`Self::direction_prefers_higher`]) on the ephemeral surface's
5830 /// (resolver-hop × derived-nullary-bool) shape — the SIXTEENTH
5831 /// peer overall and the FIRST peer threading the classification-
5832 /// `point_type`-derived input-arity axis on this surface. Opens
5833 /// the SEVENTH classification axis into the ephemeral fixed-tag
5834 /// algebra after the horizon, calm, data, point-type, substrate,
5835 /// and optimization-direction axes. First peer on the derived-
5836 /// typed-projection stratum of the ephemeral surface — composes
5837 /// an extra closed-set-level projection hop
5838 /// ([`crate::classification::ConvergencePointType::input_arity`])
5839 /// compared to the sibling `point_is_*` triple that walks the raw
5840 /// `point_type` slot through the resolver. The resolver-hop shape
5841 /// is byte-identical across all sixteen peers.
5842 ///
5843 /// # Semantics — resolver hop + derived-nullary-boolean
5844 ///
5845 /// `input_arity_is_one()` returns `true` iff
5846 /// `self.resolved_classification().input_arity_is_one()`. The
5847 /// resolver returns the authored [`Classification`] when present
5848 /// and the substrate default [`Classification::gate_compute`] on
5849 /// absence. Because [`Classification::gate_compute`] carries
5850 /// `point_type: Gate` and `Gate.input_arity() = Many`, a bare
5851 /// ephemeral spec with no `:classification` slot answers `false` —
5852 /// every unadorned `(defephemeral …)` lands in the multi-input
5853 /// bucket under the substrate default (`Gate` gates a
5854 /// many-to-one bucket dispatch, so the single-input bucket only
5855 /// applies to operator-authored specs on the `Transform | Fork |
5856 /// Broadcast | Observe` arms). A regression that dropped the
5857 /// resolver hop, probed the wrong closed-set arm, or crossed the
5858 /// wires with the sibling
5859 /// [`crate::classification::ConvergencePointType::output_arity`]
5860 /// projection (which disagrees on six of the eight variants) fails
5861 /// HERE at ONE narrow substrate site before drifting through
5862 /// every unadorned ephemeral spec's DAG-composition input-arity
5863 /// audit.
5864 ///
5865 /// # Compounding — opens the input-arity axis on the ephemeral surface
5866 ///
5867 /// The ephemeral require-tag classifier will compose this
5868 /// primitive as a fixed tag `single-input-arity` on
5869 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5870 /// surface's `single-input-arity` fixed tag on
5871 /// `POINT_FIXED_TAG_ARMS` via
5872 /// [`Classification::input_arity_is_one`] directly. The
5873 /// two-surface parity contract holds by construction: both
5874 /// surfaces route through the SAME
5875 /// [`Classification::input_arity_is_one`] primitive after the
5876 /// ephemeral surface pays ONE resolver hop. A future antisymmetric
5877 /// peer ([`Self::input_arity_is_many`]) closes the binary XOR
5878 /// partition on this axis — mirror of the calm-axis
5879 /// (`monotone-calm ⊕ coordination-required`), data-axis
5880 /// (`public-data ⊕ data-restricted`), and optimization-direction-
5881 /// axis (`prefers-lower-direction ⊕ prefers-higher-direction`)
5882 /// closures on this surface.
5883 ///
5884 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5885 /// preserves proofs; the classification-`point_type`-derived
5886 /// input-arity-axis derived-nullary-boolean probe body composes
5887 /// ONE resolver primitive ([`Self::resolved_classification`])
5888 /// with ONE [`Classification`] primitive
5889 /// ([`Classification::input_arity_is_one`]) so every downstream
5890 /// (the future `single-input-arity` fixed tag on the ephemeral
5891 /// surface in tatara-check, future DAG-composition input-arity
5892 /// validators keying on the single-input framing, future variant
5893 /// additions on
5894 /// [`crate::classification::ConvergencePointType`]) binds through
5895 /// the SAME `input_arity_is_one()` shape rather than restating
5896 /// either the resolver walk or the two-hop closed-set projection
5897 /// composition at the callsite. THEORY.md §VI.1 — generation over
5898 /// composition; a future
5899 /// [`crate::classification::ConvergencePointType`] variant lands
5900 /// at ONE `ALL` entry + ONE `input_arity` arm on the closed set
5901 /// and both surfaces pick it up mechanically.
5902 #[must_use]
5903 pub fn input_arity_is_one(&self) -> bool {
5904 self.resolved_classification().input_arity_is_one()
5905 }
5906
5907 /// ANTISYMMETRIC PEER of [`Self::input_arity_is_one`] — does
5908 /// this ephemeral spec's resolved [`Classification`]'s `point_type`
5909 /// slot project to `Arity::Many` under
5910 /// [`crate::classification::ConvergencePointType::input_arity`]?
5911 /// Byte-for-byte peer of
5912 /// [`crate::classification::Classification::input_arity_is_many`]
5913 /// wrapped through the [`Self::resolved_classification`] resolver
5914 /// so an operator-omitted `:classification` slot on
5915 /// `(defephemeral …)` still answers via the substrate default. The
5916 /// ONE ephemeral-surface substrate primitive that owns the
5917 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
5918 /// multi-input side of the DAG-composition input-arity projection.
5919 ///
5920 /// # Seventeenth derived-nullary-boolean peer on the ephemeral surface — CLOSES the input-arity axis
5921 ///
5922 /// Peer of the sixteen prior nullary-boolean substrate primitives
5923 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
5924 /// [`Self::horizon_requires_metric_axes`],
5925 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
5926 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
5927 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
5928 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
5929 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
5930 /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
5931 /// [`Self::direction_prefers_higher`], [`Self::input_arity_is_one`])
5932 /// on the ephemeral surface's (resolver-hop × derived-nullary-
5933 /// bool) shape — the SEVENTEENTH peer overall and the SECOND peer
5934 /// threading the classification-`point_type`-derived input-arity
5935 /// axis on this surface. CLOSES the SEVENTH classification axis
5936 /// into the FULL binary XOR partition contract
5937 /// `input_arity_is_one ⊕ input_arity_is_many` on the ephemeral
5938 /// surface — the resolver-hop peer of the parent-composed
5939 /// `classification_input_arity_probes_form_binary_xor_partition_over_all`.
5940 /// The resolver-hop shape is byte-identical across all seventeen
5941 /// peers.
5942 ///
5943 /// # Semantics — resolver hop + derived-nullary-boolean
5944 ///
5945 /// `input_arity_is_many()` returns `true` iff
5946 /// `self.resolved_classification().input_arity_is_many()`. The
5947 /// resolver returns the authored [`Classification`] when present
5948 /// and the substrate default [`Classification::gate_compute`] on
5949 /// absence. Because [`Classification::gate_compute`] carries
5950 /// `point_type: Gate` and `Gate.input_arity() = Many`, a bare
5951 /// ephemeral spec with no `:classification` slot answers `true` —
5952 /// every unadorned `(defephemeral …)` lands in the multi-input
5953 /// bucket under the substrate default. Direct antisymmetric
5954 /// mirror of [`Self::input_arity_is_one`] on the SAME resolver
5955 /// walk + SAME projection through the SAME closed set.
5956 ///
5957 /// # Compounding — CLOSES the input-arity axis on the ephemeral surface
5958 ///
5959 /// The ephemeral require-tag classifier will compose this
5960 /// primitive as a fixed tag `multi-input-arity` on
5961 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
5962 /// surface's `multi-input-arity` fixed tag on
5963 /// `POINT_FIXED_TAG_ARMS` via
5964 /// [`Classification::input_arity_is_many`] directly. The
5965 /// two-surface parity contract holds by construction: both
5966 /// surfaces route through the SAME
5967 /// [`Classification::input_arity_is_many`] primitive after the
5968 /// ephemeral surface pays ONE resolver hop. SECOND input-arity-
5969 /// axis peer CLOSES the axis into the FULL binary XOR partition
5970 /// contract on this surface — the resolver-hop peer of the
5971 /// parent-composed
5972 /// `classification_input_arity_probes_form_binary_xor_partition_over_all`,
5973 /// mirror of the calm-axis (`monotone-calm ⊕
5974 /// coordination-required`), data-axis (`public-data ⊕
5975 /// data-restricted`), and optimization-direction-axis
5976 /// (`prefers-lower-direction ⊕ prefers-higher-direction`)
5977 /// closures on this surface — the SEVENTH classification axis to
5978 /// reach the closed XOR partition landmark on the ephemeral
5979 /// resolver-hop surface, opening the derived-typed-projection
5980 /// stratum on this surface for the first time.
5981 ///
5982 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
5983 /// preserves proofs; the classification-`point_type`-derived
5984 /// input-arity-axis derived-nullary-boolean probe body composes
5985 /// ONE resolver primitive ([`Self::resolved_classification`])
5986 /// with ONE [`Classification`] primitive
5987 /// ([`Classification::input_arity_is_many`]) so every downstream
5988 /// (the future `multi-input-arity` fixed tag on the ephemeral
5989 /// surface in tatara-check, future DAG-composition input-arity
5990 /// validators keying on the multi-input framing, future variant
5991 /// additions on
5992 /// [`crate::classification::ConvergencePointType`]) binds through
5993 /// the SAME `input_arity_is_many()` shape rather than restating
5994 /// either `!self.input_arity_is_one()` or the two-hop
5995 /// `self.resolved_classification().point_type.input_arity().is_many()`
5996 /// chain at each callsite. THEORY.md §VI.1 — generation over
5997 /// composition; a future
5998 /// [`crate::classification::ConvergencePointType`] variant lands
5999 /// at ONE `ALL` entry + ONE `input_arity` arm on the closed set
6000 /// and both surfaces pick it up mechanically.
6001 #[must_use]
6002 pub fn input_arity_is_many(&self) -> bool {
6003 self.resolved_classification().input_arity_is_many()
6004 }
6005
6006 /// Derived-boolean predicate — does this ephemeral spec's resolved
6007 /// [`Classification`]'s `point_type` slot project to `Arity::One`
6008 /// under
6009 /// [`crate::classification::ConvergencePointType::output_arity`]?
6010 /// Byte-for-byte peer of
6011 /// [`crate::classification::Classification::output_arity_is_one`]
6012 /// wrapped through the [`Self::resolved_classification`] resolver
6013 /// so an operator-omitted `:classification` slot on
6014 /// `(defephemeral …)` still answers via the substrate default. The
6015 /// ONE ephemeral-surface substrate primitive that owns the
6016 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
6017 /// single-output side of the DAG-composition output-arity projection.
6018 ///
6019 /// # Eighteenth derived-nullary-boolean peer on the ephemeral surface — opens the output-arity axis
6020 ///
6021 /// Peer of the seventeen prior nullary-boolean substrate primitives
6022 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
6023 /// [`Self::horizon_requires_metric_axes`],
6024 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
6025 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
6026 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
6027 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
6028 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
6029 /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
6030 /// [`Self::direction_prefers_higher`], [`Self::input_arity_is_one`],
6031 /// [`Self::input_arity_is_many`]) on the ephemeral surface's
6032 /// (resolver-hop × derived-nullary-bool) shape — the EIGHTEENTH
6033 /// peer overall and the FIRST peer threading the classification-
6034 /// `point_type`-derived OUTPUT-arity axis on this surface. Opens
6035 /// the EIGHTH classification axis into the ephemeral fixed-tag
6036 /// algebra after the horizon, calm, data, point-type, substrate,
6037 /// optimization-direction, and input-arity axes. SECOND peer on
6038 /// the derived-typed-projection stratum of the ephemeral surface
6039 /// (after [`Self::input_arity_is_one`]) — composes an extra
6040 /// closed-set-level projection hop
6041 /// ([`crate::classification::ConvergencePointType::output_arity`])
6042 /// compared to the sibling `point_is_*` triple that walks the raw
6043 /// `point_type` slot through the resolver. The resolver-hop shape
6044 /// is byte-identical across all eighteen peers.
6045 ///
6046 /// # Distinctness from the input-arity axis
6047 ///
6048 /// The input-arity and output-arity axes carve the eight-variant
6049 /// [`crate::classification::ConvergencePointType`] closed set into
6050 /// DISTINCT partitions — six of the eight variants (`Fork |
6051 /// Broadcast | Join | Gate | Select | Reduce`) DISAGREE between the
6052 /// two projections, and only the two endomorphic variants
6053 /// (`Transform | Observe` — both `(One, One)`) agree. The ephemeral
6054 /// resolver-hop surface inherits this distinctness verbatim: the
6055 /// absent-classification baseline (`gate_compute` → `point_type:
6056 /// Gate`) FLIPS between the two axes — `input_arity_is_one` is
6057 /// `false` on the baseline but `output_arity_is_one` is `true`.
6058 /// So `output_arity_is_one` is NOT a redundant restatement of
6059 /// `input_arity_is_one` even after both wrap through the SAME
6060 /// resolver.
6061 ///
6062 /// # Semantics — resolver hop + derived-nullary-boolean
6063 ///
6064 /// `output_arity_is_one()` returns `true` iff
6065 /// `self.resolved_classification().output_arity_is_one()`. The
6066 /// resolver returns the authored [`Classification`] when present
6067 /// and the substrate default [`Classification::gate_compute`] on
6068 /// absence. Because [`Classification::gate_compute`] carries
6069 /// `point_type: Gate` and `Gate.output_arity() = One`, a bare
6070 /// ephemeral spec with no `:classification` slot answers `true` —
6071 /// every unadorned `(defephemeral …)` lands in the single-output
6072 /// bucket under the substrate default (`Gate` gates a many-to-one
6073 /// bucket dispatch, so the multi-output bucket only applies to
6074 /// operator-authored specs on the `Fork | Broadcast` arms). A
6075 /// regression that dropped the resolver hop, probed the wrong
6076 /// closed-set arm, or crossed the wires with the sibling
6077 /// [`crate::classification::ConvergencePointType::input_arity`]
6078 /// projection (which disagrees on six of the eight variants) fails
6079 /// HERE at ONE narrow substrate site before drifting through every
6080 /// unadorned ephemeral spec's DAG-composition output-arity audit.
6081 ///
6082 /// # Compounding — opens the output-arity axis on the ephemeral surface
6083 ///
6084 /// The ephemeral require-tag classifier will compose this
6085 /// primitive as a fixed tag `single-output-arity` on
6086 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
6087 /// surface's `single-output-arity` fixed tag on
6088 /// `POINT_FIXED_TAG_ARMS` via
6089 /// [`Classification::output_arity_is_one`] directly. The
6090 /// two-surface parity contract holds by construction: both
6091 /// surfaces route through the SAME
6092 /// [`Classification::output_arity_is_one`] primitive after the
6093 /// ephemeral surface pays ONE resolver hop. A future antisymmetric
6094 /// peer ([`Self::output_arity_is_many`]) closes the binary XOR
6095 /// partition on this axis — mirror of the input-arity-axis
6096 /// (`input_arity_is_one ⊕ input_arity_is_many`), the calm-axis
6097 /// (`monotone-calm ⊕ coordination-required`), the data-axis
6098 /// (`public-data ⊕ data-restricted`), and the optimization-
6099 /// direction-axis (`prefers-lower-direction ⊕
6100 /// prefers-higher-direction`) closures on this surface,
6101 /// completing the DAG-composition arity PAIR on the ephemeral
6102 /// derived-typed-projection stratum.
6103 ///
6104 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
6105 /// preserves proofs; the classification-`point_type`-derived
6106 /// output-arity-axis derived-nullary-boolean probe body composes
6107 /// ONE resolver primitive ([`Self::resolved_classification`])
6108 /// with ONE [`Classification`] primitive
6109 /// ([`Classification::output_arity_is_one`]) so every downstream
6110 /// (the future `single-output-arity` fixed tag on the ephemeral
6111 /// surface in tatara-check, future DAG-composition output-arity
6112 /// validators keying on the single-output framing, future variant
6113 /// additions on
6114 /// [`crate::classification::ConvergencePointType`]) binds through
6115 /// the SAME `output_arity_is_one()` shape rather than restating
6116 /// either the resolver walk or the two-hop closed-set projection
6117 /// composition at the callsite. THEORY.md §VI.1 — generation over
6118 /// composition; a future
6119 /// [`crate::classification::ConvergencePointType`] variant lands
6120 /// at ONE `ALL` entry + ONE `output_arity` arm on the closed set
6121 /// and both surfaces pick it up mechanically.
6122 #[must_use]
6123 pub fn output_arity_is_one(&self) -> bool {
6124 self.resolved_classification().output_arity_is_one()
6125 }
6126
6127 /// ANTISYMMETRIC PEER of [`Self::output_arity_is_one`] — does
6128 /// this ephemeral spec's resolved [`Classification`]'s `point_type`
6129 /// slot project to `Arity::Many` under
6130 /// [`crate::classification::ConvergencePointType::output_arity`]?
6131 /// Byte-for-byte peer of
6132 /// [`crate::classification::Classification::output_arity_is_many`]
6133 /// wrapped through the [`Self::resolved_classification`] resolver
6134 /// so an operator-omitted `:classification` slot on
6135 /// `(defephemeral …)` still answers via the substrate default. The
6136 /// ONE ephemeral-surface substrate primitive that owns the
6137 /// `(&EphemeralSpec) -> bool` derived-nullary-boolean walk on the
6138 /// multi-output side of the DAG-composition output-arity projection.
6139 ///
6140 /// # Nineteenth derived-nullary-boolean peer on the ephemeral surface — CLOSES the output-arity axis
6141 ///
6142 /// Peer of the eighteen prior nullary-boolean substrate primitives
6143 /// on [`EphemeralSpec`] ([`Self::horizon_terminates`],
6144 /// [`Self::horizon_requires_metric_axes`],
6145 /// [`Self::calm_requires_coordination`], [`Self::data_is_regulated`],
6146 /// [`Self::data_is_restricted`], [`Self::point_is_endomorphic`],
6147 /// [`Self::point_is_diffusive`], [`Self::point_is_convergent`],
6148 /// [`Self::substrate_is_resource`], [`Self::substrate_is_policy`],
6149 /// [`Self::substrate_is_telemetry`], [`Self::calm_is_monotone`],
6150 /// [`Self::data_is_public`], [`Self::direction_prefers_lower`],
6151 /// [`Self::direction_prefers_higher`], [`Self::input_arity_is_one`],
6152 /// [`Self::input_arity_is_many`], [`Self::output_arity_is_one`])
6153 /// on the ephemeral surface's (resolver-hop × derived-nullary-
6154 /// bool) shape — the NINETEENTH peer overall and the SECOND peer
6155 /// threading the classification-`point_type`-derived OUTPUT-arity
6156 /// axis on this surface. CLOSES the EIGHTH classification axis
6157 /// into the FULL binary XOR partition contract
6158 /// `output_arity_is_one ⊕ output_arity_is_many` on the ephemeral
6159 /// surface — the resolver-hop peer of the parent-composed
6160 /// `classification_output_arity_probes_form_binary_xor_partition_over_all`.
6161 /// The resolver-hop shape is byte-identical across all nineteen
6162 /// peers. Completes the DAG-composition arity PAIR on the
6163 /// ephemeral derived-typed-projection stratum
6164 /// (`input_arity_is_{one,many}` + `output_arity_is_{one,many}` on
6165 /// the SAME resolver walk through the SAME closed set).
6166 ///
6167 /// # Semantics — resolver hop + derived-nullary-boolean
6168 ///
6169 /// `output_arity_is_many()` returns `true` iff
6170 /// `self.resolved_classification().output_arity_is_many()`. The
6171 /// resolver returns the authored [`Classification`] when present
6172 /// and the substrate default [`Classification::gate_compute`] on
6173 /// absence. Because [`Classification::gate_compute`] carries
6174 /// `point_type: Gate` and `Gate.output_arity() = One`, a bare
6175 /// ephemeral spec with no `:classification` slot answers `false` —
6176 /// every unadorned `(defephemeral …)` lands in the single-output
6177 /// bucket under the substrate default. Direct antisymmetric
6178 /// mirror of [`Self::output_arity_is_one`] on the SAME resolver
6179 /// walk + SAME projection through the SAME closed set.
6180 ///
6181 /// # Compounding — CLOSES the output-arity axis on the ephemeral surface
6182 ///
6183 /// The ephemeral require-tag classifier will compose this
6184 /// primitive as a fixed tag `multi-output-arity` on
6185 /// `EPHEMERAL_FIXED_TAG_ARMS` — byte-for-byte peer of the point
6186 /// surface's `multi-output-arity` fixed tag on
6187 /// `POINT_FIXED_TAG_ARMS` via
6188 /// [`Classification::output_arity_is_many`] directly. The
6189 /// two-surface parity contract holds by construction: both
6190 /// surfaces route through the SAME
6191 /// [`Classification::output_arity_is_many`] primitive after the
6192 /// ephemeral surface pays ONE resolver hop. SECOND output-arity-
6193 /// axis peer CLOSES the axis into the FULL binary XOR partition
6194 /// contract on this surface — the resolver-hop peer of the
6195 /// parent-composed
6196 /// `classification_output_arity_probes_form_binary_xor_partition_over_all`,
6197 /// mirror of the input-arity-axis (`input_arity_is_one ⊕
6198 /// input_arity_is_many`), the calm-axis (`monotone-calm ⊕
6199 /// coordination-required`), the data-axis (`public-data ⊕
6200 /// data-restricted`), and the optimization-direction-axis
6201 /// (`prefers-lower-direction ⊕ prefers-higher-direction`)
6202 /// closures on this surface — the EIGHTH classification axis to
6203 /// reach the closed XOR partition landmark on the ephemeral
6204 /// resolver-hop surface, completing the DAG-composition arity
6205 /// PAIR on the derived-typed-projection stratum of this surface.
6206 ///
6207 /// Theory anchor: THEORY.md §II.1 invariant 5 — composition
6208 /// preserves proofs; the classification-`point_type`-derived
6209 /// output-arity-axis derived-nullary-boolean probe body composes
6210 /// ONE resolver primitive ([`Self::resolved_classification`])
6211 /// with ONE [`Classification`] primitive
6212 /// ([`Classification::output_arity_is_many`]) so every downstream
6213 /// (the future `multi-output-arity` fixed tag on the ephemeral
6214 /// surface in tatara-check, future DAG-composition output-arity
6215 /// validators keying on the multi-output framing, future variant
6216 /// additions on
6217 /// [`crate::classification::ConvergencePointType`]) binds through
6218 /// the SAME `output_arity_is_many()` shape rather than restating
6219 /// either `!self.output_arity_is_one()` or the two-hop
6220 /// `self.resolved_classification().point_type.output_arity().is_many()`
6221 /// chain at each callsite. THEORY.md §VI.1 — generation over
6222 /// composition; a future
6223 /// [`crate::classification::ConvergencePointType`] variant lands
6224 /// at ONE `ALL` entry + ONE `output_arity` arm on the closed set
6225 /// and both surfaces pick it up mechanically.
6226 #[must_use]
6227 pub fn output_arity_is_many(&self) -> bool {
6228 self.resolved_classification().output_arity_is_many()
6229 }
6230
6231 /// True iff this ephemeral spec's [`Self::routing`] slot is
6232 /// populated AND the inner [`RoutingSpec`]'s derived
6233 /// [`RoutingForm`] equals `kind` — the substrate primitive that
6234 /// owns the (`&EphemeralSpec`, [`RoutingForm`]) → `bool` presence-
6235 /// probe shape on the sugar-surface type.
6236 ///
6237 /// # Peer to [`crate::routing::RoutingSpec::has_form`]
6238 ///
6239 /// [`RoutingSpec::has_form`] carries the same `(&self, RoutingForm)
6240 /// -> bool` signature on the inner routing carrier reached through
6241 /// the Option gate; this peer composes byte-identical semantics on
6242 /// [`EphemeralSpec`]'s direct `routing: Option<RoutingSpec>` slot,
6243 /// so both surfaces' `routing-form-<kind>` require-tag families
6244 /// route through the SAME `RoutingSpec::has_form` primitive. A
6245 /// future normalization at the probe shape (a widened return
6246 /// carrying the derived [`RoutingForm`] variant, a debug-build
6247 /// assertion on operator-set vs defaulted overrides on the
6248 /// `stable_name_claim` bool, a fleet-wide warn on `Stable`
6249 /// combined with content-hashed hostnames) lands at ONE site per
6250 /// surface and every downstream `routing-form-<kind>` require-tag
6251 /// family + closed-set audit dispatcher picks it up mechanically.
6252 ///
6253 /// # Semantics — Option-gated derived-scalar match
6254 ///
6255 /// [`EphemeralSpec::routing`] is an `Option<RoutingSpec>`: `None`
6256 /// on an in-cluster-only ephemeral env (no per-instance edges
6257 /// declared), `Some(_)` when the operator authored the
6258 /// `:routing (…)` slot. `has_routing_form(kind)` returns `true`
6259 /// iff the slot is `Some(spec)` AND `spec.has_form(kind)` — the
6260 /// Option-parent gate short-circuits `false` on `None` regardless
6261 /// of `kind`, and the reachable arm reads the DERIVED
6262 /// [`RoutingForm`] through the ONE substrate composer
6263 /// [`RoutingForm::from_is_stable`] over the child
6264 /// `stable_name_claim` bool (a `false` default projects to
6265 /// [`RoutingForm::Instance`], a `true` operator override projects
6266 /// to [`RoutingForm::Stable`]).
6267 ///
6268 /// # Corner — (Option-parent × derived-scalar-child)
6269 ///
6270 /// SAME corner as the point surface's `routing-form-<kind>`
6271 /// family (via [`crate::routing::RoutingSpec::has_form`] reached
6272 /// through `spec.routing.as_ref().is_some_and(|r| r.has_form(k))`)
6273 /// — both surfaces' Option-parent hop threads through the SAME
6274 /// `Option<RoutingSpec>` field name on their respective sugar
6275 /// structs. The [`From<EphemeralSpec>`] lowering copies
6276 /// `e.routing → ProcessSpec::routing` byte-for-byte at the
6277 /// [`From`] impl in this module (see the `routing: e.routing`
6278 /// line), so the SAME `Option<RoutingSpec>` reaches both
6279 /// surfaces' `routing-form-<kind>` families through the SAME
6280 /// [`RoutingSpec::has_form`] walk. Distinct from
6281 /// [`Self::has_teardown_policy`] on this same surface, which
6282 /// walks a required-scalar-child through no Option-parent hop.
6283 ///
6284 /// # Compounding
6285 ///
6286 /// The ephemeral require-tag classifier composes this primitive
6287 /// with the closed-set `FromStr` autoderived on [`RoutingForm`]
6288 /// through the `strip_and_classify_prefixed_kind` substrate to
6289 /// publish a `routing-form-<kind>` prefix family byte-for-byte
6290 /// symmetrical with the point surface's family via
6291 /// [`crate::routing::RoutingSpec::has_form`]. A future third
6292 /// [`RoutingForm`] variant added to `ALL` (a hypothetical
6293 /// `Anchored` for "hold the claim only for a specific
6294 /// generation") reaches BOTH surfaces' `routing-form-<kind>`
6295 /// prefix families through the SAME closed-set walk with no
6296 /// per-caller edit — the two-surface symmetry means adding a
6297 /// variant on the closed set publishes it in lockstep across
6298 /// every downstream consumer.
6299 ///
6300 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition
6301 /// preserves proofs — the Option-gated derived-scalar-carrier
6302 /// presence-probe body lives at ONE substrate site per surface
6303 /// so every downstream (`routing-form-<kind>` require-tag families
6304 /// on both surfaces in tatara-check, closed-set audit dispatchers,
6305 /// future variant additions on [`RoutingForm`]) binds through the
6306 /// SAME `has(kind)` shape rather than restating the
6307 /// `spec.routing.as_ref().is_some_and(|r| r.has_form(kind))`
6308 /// closure body at each call site). THEORY.md §VI.1 (generation
6309 /// over composition — a future variant lands at ONE `ALL` entry +
6310 /// one `as_str` arm on the closed set and the probe picks it up
6311 /// mechanically without further per-consumer edits).
6312 #[must_use]
6313 pub fn has_routing_form(&self, kind: RoutingForm) -> bool {
6314 self.routing.as_ref().is_some_and(|r| r.has_form(kind))
6315 }
6316
6317 /// True iff at least one declared export in `self.exports` would
6318 /// fire on the given terminal-reached [`ProcessPhase`] — the peer
6319 /// of [`crate::lifetime::EphemeralLifetime::has_applicable_exports`]
6320 /// on the [`EphemeralSpec`] surface.
6321 ///
6322 /// # Semantics — byte-identical to [`crate::lifetime::EphemeralLifetime::has_applicable_exports`]
6323 ///
6324 /// Both surfaces walk the SAME slice-level substrate primitive
6325 /// [`ExportSpecSliceExt::has_applicable_at`] on their respective
6326 /// `Vec<ExportSpec>` slot: [`EphemeralSpec`]'s `exports` field is
6327 /// copied byte-for-byte into `EphemeralLifetime::exports` at the
6328 /// `From<EphemeralSpec>` lowering, so a `has_applicable_exports_at`
6329 /// query on the authored ephemeral spec answers identically to a
6330 /// `has_applicable_exports` query on the lowered `EphemeralLifetime`.
6331 /// A regression at the compound `(when, phase) → fires_on(phase)`
6332 /// walk fails at [`ExportSpecSliceExt::has_applicable_at`]'s tests
6333 /// rather than as silent drift at either surface's inherent method.
6334 ///
6335 /// # Sibling to [`crate::lifetime::EphemeralLifetime::has_applicable_exports`]
6336 ///
6337 /// Same shape, same axis, same body — the point-domain surface
6338 /// composes through `spec.lifetime.resolved_ephemeral().is_some_and(
6339 /// |e| e.exports.has_applicable_at(phase))`; the ephemeral sugar
6340 /// surface reads `self.exports.has_applicable_at(phase)` directly
6341 /// because `EphemeralSpec` stores `exports: Vec<ExportSpec>` as a
6342 /// top-level field. Both routes bind through THIS ONE slice-level
6343 /// primitive so a future normalization (widening the trigger from
6344 /// a stored discriminator to a computed predicate, adding a phase
6345 /// that composes across multiple trigger arms, threading a
6346 /// per-export justification back for editor tooltips) lands at ONE
6347 /// site and every downstream inherits the shift by construction.
6348 ///
6349 /// # Compounding
6350 ///
6351 /// The ephemeral require-tag classifier composes this primitive
6352 /// with the closed-set [`ProcessPhase`]'s autoderived `FromStr`
6353 /// through the `strip_and_classify_prefixed_kind` substrate to
6354 /// publish an `exports-fire-on-<phase>` closed-set prefix family
6355 /// byte-for-byte symmetrical with the point surface's family via
6356 /// `spec.lifetime.resolved_ephemeral().is_some_and(|e|
6357 /// e.exports.has_applicable_at(phase))`. A future twelfth
6358 /// [`ProcessPhase`] variant reaches BOTH surfaces' prefix families
6359 /// through the ONE [`crate::export::ExportTrigger::fires_on`]
6360 /// exhaustive match — either the new phase inherits a per-trigger
6361 /// fire rule at that single substrate site or it collapses to
6362 /// `false` for every trigger (the current non-terminal tail),
6363 /// without a per-caller edit anywhere else.
6364 ///
6365 /// A future normalization at the compound `(when, phase) →
6366 /// fires_on(phase)` walk (a widening that returns the applicable
6367 /// exports themselves rather than a bool, a debug-build assertion
6368 /// on redundant `Always`-triggered exports coexisting with an
6369 /// `OnAttested` peer, a fleet-wide warn on empty-export ephemerals
6370 /// declaring `OnAttested` postconditions) lands at the ONE
6371 /// slice-level substrate primitive [`ExportSpecSliceExt::has_applicable_at`]
6372 /// both this method and [`crate::lifetime::EphemeralLifetime::has_applicable_exports`]
6373 /// compose against — so the two struct-level union methods stay
6374 /// symmetric by construction.
6375 ///
6376 /// Theory anchor: THEORY.md §II.1 invariant 5 (composition preserves
6377 /// proofs — the walk composes the SAME slice-level substrate
6378 /// primitive on both this ephemeral surface and the
6379 /// [`crate::lifetime::EphemeralLifetime`] surface, so a regression
6380 /// at the compound `(when, phase) → fires_on(phase)` chain fails
6381 /// at ONE site rather than as silent drift between the two peers).
6382 /// THEORY.md §VI.1 (generation over composition — a future
6383 /// [`ProcessPhase`] variant or a future [`crate::export::ExportTrigger`]
6384 /// variant reaches both `exports-fire-on-<phase>` require-tag
6385 /// surfaces mechanically through the SAME closed-set walk).
6386 #[must_use]
6387 pub fn has_applicable_exports_at(&self, phase: ProcessPhase) -> bool {
6388 self.exports.has_applicable_at(phase)
6389 }
6390}
6391
6392impl From<EphemeralSpec> for ProcessSpec {
6393 fn from(e: EphemeralSpec) -> Self {
6394 let classification = e.classification.unwrap_or_else(default_ephemeral_class);
6395 let mut spec = Self {
6396 identity: crate::spec::IdentitySpec {
6397 parent: e.parent,
6398 name_override: None,
6399 },
6400 classification,
6401 intent: Intent {
6402 aplicacao: Some(e.aplicacao),
6403 ..Intent::default()
6404 },
6405 boundary: Boundary {
6406 preconditions: e.preconditions,
6407 postconditions: e.postconditions,
6408 timeout: e.verify_timeout,
6409 },
6410 compliance: Default::default(),
6411 depends_on: vec![],
6412 signals: Default::default(),
6413 // Routes through the ONE substrate composer
6414 // [`Lifetime::ephemeral`] — pre-lift this was one of
6415 // ELEVEN+ hand-authored `Lifetime { ephemeral: Some(<e>),
6416 // .. }` sites past the ★★ PRIME-DIRECTIVE ≥ 2 threshold.
6417 // See the composer's doc-comment for the full migration
6418 // rationale.
6419 lifetime: Lifetime::ephemeral(EphemeralLifetime {
6420 ttl: e.ttl,
6421 teardown_policy: e.teardown,
6422 max_concurrent: e.max_concurrent,
6423 exports: e.exports,
6424 }),
6425 // R5 — propagate routing template (None = no edges).
6426 routing: e.routing,
6427 // EncapsulatesSpec isn't exposed via EphemeralSpec sugar;
6428 // operators wanting Adopt/Observe author the full
6429 // (defpoint …) form. Sugar path stays greenfield-Manage.
6430 encapsulates: None,
6431 suspended: false,
6432 };
6433 // Belt-and-suspenders: make sure exactly-one Intent invariant holds.
6434 spec.intent.nix = None;
6435 spec.intent.flux = None;
6436 spec.intent.lisp = None;
6437 spec.intent.container = None;
6438 spec.intent.guest = None;
6439 spec
6440 }
6441}
6442
6443fn default_ephemeral_class() -> Classification {
6444 // Delegates through the substrate `(Gate, Compute)` baseline owner
6445 // so the shape lives at ONE workspace-wide site — see
6446 // [`Classification::gate_compute`] for the pre-lift ten-callsite
6447 // duplication history and the sibling-default correspondence
6448 // pinned there.
6449 Classification::gate_compute()
6450}
6451
6452/// Compile a `(defephemeral …)` Lisp source into named `EphemeralSpec` values.
6453pub fn compile_ephemeral_source(
6454 src: &str,
6455) -> tatara_lisp::Result<Vec<tatara_lisp::NamedDefinition<EphemeralSpec>>> {
6456 tatara_lisp::compile_named::<EphemeralSpec>(src)
6457}
6458
6459#[cfg(test)]
6460mod tests {
6461 use super::*;
6462 use crate::boundary::{assert_slice_refinement_composition_laws, ConditionKind};
6463 use crate::classification::{
6464 Arity, CalmClassification, ConvergencePointType, DataClassification, Horizon, HorizonKind,
6465 OptimizationDirection, SubstrateType,
6466 };
6467 use crate::intent::IntentVariant;
6468 use crate::lifetime::LifetimeVariant;
6469
6470 /// LANDMARK PIN — the (ephemeral-surface test-fixture ×
6471 /// [`Classification::gate_compute_with_axis`] on horizon-nested
6472 /// axes) sweep equivalence. Nine ephemeral-surface probe-sweep
6473 /// tests in this module (`has_horizon_kind_*`,
6474 /// `has_optimization_direction_*`, `horizon_terminates_*`,
6475 /// `horizon_requires_metric_axes_*`, `horizon_terminates_xor_*`)
6476 /// pre-sweep restated the SAME `let mut c =
6477 /// Classification::gate_compute(); c.horizon = Horizon { <slot>:
6478 /// populated, ..Horizon::default() }` five-line fixture at each
6479 /// callsite, mutating exactly ONE horizon-nested slot to
6480 /// `populated`; post-sweep each callsite reads
6481 /// [`Classification::gate_compute_with_axis(populated)`] — one
6482 /// line — and the four-baseline-slot restatement lives at ONE
6483 /// substrate primitive. This pin asserts byte-parity between the
6484 /// pre-sweep hand-authored `Horizon` struct-literal shape (both
6485 /// the [`HorizonKind::kind`] mutation shape AND the
6486 /// [`OptimizationDirection`]-into-`Some(_)` mutation shape) and
6487 /// the post-sweep composer output on every variant of each closed
6488 /// set, so a regression that either (a) changed
6489 /// [`ClassificationAxis for HorizonKind`] to stomp a non-`kind`
6490 /// sub-slot, (b) changed [`ClassificationAxis for OptimizationDirection`]
6491 /// to drop the `Some(...)` wrap, or (c) reintroduced a whole-
6492 /// `Horizon`-reset shape that dropped a sibling sub-slot would
6493 /// fail HERE at ONE landmark site before landing at the peer
6494 /// probe-sweep pins that use the composer.
6495 ///
6496 /// Byte-for-byte peer of the sibling landmark
6497 /// `with_axis_optimization_direction_overlay_wraps_variant_in_some`
6498 /// on the point-surface classification-module tests — this pin
6499 /// carries the same substrate contract through to the ephemeral-
6500 /// surface tests that consume the composer.
6501 #[test]
6502 fn gate_compute_with_axis_on_horizon_nested_axes_matches_hand_authored_shape() {
6503 for kind in HorizonKind::ALL {
6504 let via_composer = Classification::gate_compute_with_axis(kind);
6505 let mut via_hand_authored = Classification::gate_compute();
6506 via_hand_authored.horizon = Horizon {
6507 kind,
6508 ..Horizon::default()
6509 };
6510 assert_eq!(
6511 via_composer, via_hand_authored,
6512 "HorizonKind::{kind:?}: composer vs pre-sweep hand-authored struct-literal drift",
6513 );
6514 }
6515 for direction in OptimizationDirection::ALL {
6516 let via_composer = Classification::gate_compute_with_axis(direction);
6517 let mut via_hand_authored = Classification::gate_compute();
6518 via_hand_authored.horizon = Horizon {
6519 direction: Some(direction),
6520 ..Horizon::default()
6521 };
6522 assert_eq!(
6523 via_composer, via_hand_authored,
6524 "OptimizationDirection::{direction:?}: composer vs pre-sweep hand-authored struct-literal drift",
6525 );
6526 }
6527 }
6528
6529 /// Primitive-owner pin — `EphemeralSpec::with_classification_axis`
6530 /// on a `classification: None` carrier produces an ephemeral spec
6531 /// whose `classification` slot is
6532 /// `Some(Classification::gate_compute_with_axis(axis))` byte-for-
6533 /// byte on every axis-variant, and preserves every non-
6534 /// classification slot at its pre-call value. A regression that
6535 /// (a) failed to wrap the composed [`Classification`] in `Some(_)`
6536 /// on the `None`-arm, (b) mutated a sibling slot on `EphemeralSpec`
6537 /// through the axis overlay, or (c) picked a different `None`-arm
6538 /// fill-through than the sibling
6539 /// [`Self::resolved_classification`] resolver would fail HERE.
6540 #[test]
6541 fn with_classification_axis_on_none_arm_fills_through_gate_compute() {
6542 fn baseline() -> EphemeralSpec {
6543 EphemeralSpec {
6544 aplicacao: demo_overlay(),
6545 ttl: "2h".into(),
6546 teardown: TeardownPolicy::OnAttested,
6547 max_concurrent: 3,
6548 postconditions: vec![],
6549 preconditions: vec![],
6550 verify_timeout: Some("30m".into()),
6551 classification: None,
6552 parent: Some("seph.1".into()),
6553 exports: vec![],
6554 routing: None,
6555 }
6556 }
6557 // Direct-scalar axes: composer output matches
6558 // `Classification::gate_compute_with_axis(axis)` byte-for-byte,
6559 // wrapped in `Some(_)`.
6560 for kind in ConvergencePointType::ALL {
6561 let via_composer = baseline().with_classification_axis(kind);
6562 assert_eq!(
6563 via_composer.classification,
6564 Some(Classification::gate_compute_with_axis(kind)),
6565 "ConvergencePointType::{kind:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6566 );
6567 }
6568 for kind in SubstrateType::ALL {
6569 let via_composer = baseline().with_classification_axis(kind);
6570 assert_eq!(
6571 via_composer.classification,
6572 Some(Classification::gate_compute_with_axis(kind)),
6573 "SubstrateType::{kind:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6574 );
6575 }
6576 for kind in CalmClassification::ALL {
6577 let via_composer = baseline().with_classification_axis(kind);
6578 assert_eq!(
6579 via_composer.classification,
6580 Some(Classification::gate_compute_with_axis(kind)),
6581 "CalmClassification::{kind:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6582 );
6583 }
6584 for kind in DataClassification::ALL {
6585 let via_composer = baseline().with_classification_axis(kind);
6586 assert_eq!(
6587 via_composer.classification,
6588 Some(Classification::gate_compute_with_axis(kind)),
6589 "DataClassification::{kind:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6590 );
6591 }
6592 // Horizon-nested axes: same shape through the trait's
6593 // sub-slot overlay.
6594 for kind in HorizonKind::ALL {
6595 let via_composer = baseline().with_classification_axis(kind);
6596 assert_eq!(
6597 via_composer.classification,
6598 Some(Classification::gate_compute_with_axis(kind)),
6599 "HorizonKind::{kind:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6600 );
6601 }
6602 for direction in OptimizationDirection::ALL {
6603 let via_composer = baseline().with_classification_axis(direction);
6604 assert_eq!(
6605 via_composer.classification,
6606 Some(Classification::gate_compute_with_axis(direction)),
6607 "OptimizationDirection::{direction:?}: composer vs gate_compute_with_axis Some(_) drift on None-arm",
6608 );
6609 }
6610 // Non-classification slots: every one preserved byte-for-byte
6611 // across the overlay on every axis. Compare through JSON
6612 // round-trip since `AplicacaoIntent` / `ExportSpec` /
6613 // `RoutingSpec` do not carry `PartialEq`.
6614 for kind in ConvergencePointType::ALL {
6615 let via_composer = baseline().with_classification_axis(kind);
6616 let baseline_ref = baseline();
6617 assert_eq!(
6618 serde_json::to_string(&via_composer.aplicacao).unwrap(),
6619 serde_json::to_string(&baseline_ref.aplicacao).unwrap(),
6620 "aplicacao slot drifted under axis overlay for kind={kind:?}",
6621 );
6622 assert_eq!(via_composer.ttl, baseline_ref.ttl);
6623 assert_eq!(via_composer.teardown, baseline_ref.teardown);
6624 assert_eq!(via_composer.max_concurrent, baseline_ref.max_concurrent);
6625 assert_eq!(
6626 via_composer.postconditions.len(),
6627 baseline_ref.postconditions.len()
6628 );
6629 assert_eq!(
6630 via_composer.preconditions.len(),
6631 baseline_ref.preconditions.len()
6632 );
6633 assert_eq!(via_composer.verify_timeout, baseline_ref.verify_timeout);
6634 assert_eq!(via_composer.parent, baseline_ref.parent);
6635 assert_eq!(via_composer.exports.len(), baseline_ref.exports.len());
6636 assert!(via_composer.routing.is_none());
6637 }
6638 }
6639
6640 /// Primitive-owner pin —
6641 /// `EphemeralSpec::with_classification_axis` on a
6642 /// `classification: Some(prior)` carrier composes the axis
6643 /// overlay onto `prior` via [`ClassificationAxis::overlay`],
6644 /// preserving every OTHER axis slot on `prior`. Distinct from the
6645 /// `None`-arm pin above: the `Some(prior)` arm does NOT reset
6646 /// through [`Classification::gate_compute`], and consecutive
6647 /// `.with_classification_axis(...)` calls compose arbitrary
6648 /// N-axis conjunctions on the ephemeral surface with the same
6649 /// order-independence guarantee [`Classification::with_axis`]
6650 /// carries on distinct-slot axes.
6651 #[test]
6652 fn with_classification_axis_on_some_arm_chains_onto_prior() {
6653 fn baseline() -> EphemeralSpec {
6654 EphemeralSpec {
6655 aplicacao: demo_overlay(),
6656 ttl: "1h".into(),
6657 teardown: TeardownPolicy::Always,
6658 max_concurrent: 0,
6659 postconditions: vec![],
6660 preconditions: vec![],
6661 verify_timeout: None,
6662 classification: None,
6663 parent: None,
6664 exports: vec![],
6665 routing: None,
6666 }
6667 }
6668 // Prior authored point_type = Fork; overlay substrate = Storage
6669 // preserves the Fork point_type on the composed classification.
6670 let seeded = baseline().with_classification_axis(ConvergencePointType::Fork);
6671 let composed = seeded.with_classification_axis(SubstrateType::Storage);
6672 let classification = composed
6673 .classification
6674 .as_ref()
6675 .expect("with_classification_axis populates Some(_)");
6676 assert_eq!(classification.point_type, ConvergencePointType::Fork);
6677 assert_eq!(classification.substrate, SubstrateType::Storage);
6678 // Order independence on distinct-slot axes: swapping the axis
6679 // chain reads the SAME final classification.
6680 let forward = baseline()
6681 .with_classification_axis(ConvergencePointType::Fork)
6682 .with_classification_axis(SubstrateType::Storage)
6683 .with_classification_axis(CalmClassification::NonMonotone)
6684 .with_classification_axis(DataClassification::Pii)
6685 .classification
6686 .unwrap();
6687 let reverse = baseline()
6688 .with_classification_axis(DataClassification::Pii)
6689 .with_classification_axis(CalmClassification::NonMonotone)
6690 .with_classification_axis(SubstrateType::Storage)
6691 .with_classification_axis(ConvergencePointType::Fork)
6692 .classification
6693 .unwrap();
6694 assert_eq!(
6695 forward, reverse,
6696 "with_classification_axis chain must be order-independent on distinct-slot axes",
6697 );
6698 // Nested horizon-sub-slot overlays compose onto the same
6699 // carrier without stomping each other: the (kind, direction)
6700 // pair rides both chains.
6701 let paired = baseline()
6702 .with_classification_axis(HorizonKind::Asymptotic)
6703 .with_classification_axis(OptimizationDirection::Maximize)
6704 .classification
6705 .unwrap();
6706 assert_eq!(paired.horizon.kind, HorizonKind::Asymptotic);
6707 assert_eq!(
6708 paired.horizon.direction,
6709 Some(OptimizationDirection::Maximize)
6710 );
6711 }
6712
6713 /// Primitive-owner pin —
6714 /// `EphemeralSpec::with_classification_axis` composes byte-for-
6715 /// byte with the pre-sweep hand-authored two-shape callsite
6716 /// pattern that recurred at ~36 sites in
6717 /// `tatara-reconciler::bin::tatara-check`: either
6718 /// `let mut c = Classification::gate_compute(); c.<axis> =
6719 /// populated; EphemeralSpec { classification: Some(c), ..
6720 /// baseline }`, or the newer `let c =
6721 /// Classification::gate_compute_with_axis(populated); EphemeralSpec
6722 /// { classification: Some(c), ..baseline }`. Both restated
6723 /// pre-sweep shapes classify identically to
6724 /// `baseline.with_classification_axis(populated)` on every
6725 /// [`ClassificationAxis`] impl. A regression that drifted the
6726 /// composer body away from the pre-sweep shape (a stray reset of a
6727 /// non-classification slot, a stomping of a nested horizon sub-
6728 /// slot on the direct-scalar axes) fails HERE at ONE landmark site
6729 /// before drifting through the ~36 swept callsites in tatara-
6730 /// check.rs.
6731 #[test]
6732 fn with_classification_axis_matches_pre_sweep_hand_authored_shape() {
6733 fn baseline() -> EphemeralSpec {
6734 EphemeralSpec {
6735 aplicacao: demo_overlay(),
6736 ttl: "1h".into(),
6737 teardown: TeardownPolicy::Always,
6738 max_concurrent: 0,
6739 postconditions: vec![],
6740 preconditions: vec![],
6741 verify_timeout: None,
6742 classification: None,
6743 parent: None,
6744 exports: vec![],
6745 routing: None,
6746 }
6747 }
6748 // Direct-scalar axes: `<eph>.with_classification_axis(kind)`
6749 // matches the pre-sweep two-shape callsite pattern on every
6750 // ConvergencePointType variant.
6751 for kind in ConvergencePointType::ALL {
6752 let via_composer = baseline().with_classification_axis(kind);
6753 let mut hand_classification = Classification::gate_compute();
6754 hand_classification.point_type = kind;
6755 let via_hand = EphemeralSpec {
6756 classification: Some(hand_classification),
6757 ..baseline()
6758 };
6759 assert_eq!(
6760 via_composer.classification, via_hand.classification,
6761 "ConvergencePointType::{kind:?}: composer vs pre-sweep hand-authored classification drift",
6762 );
6763 }
6764 for kind in SubstrateType::ALL {
6765 let via_composer = baseline().with_classification_axis(kind);
6766 let mut hand_classification = Classification::gate_compute();
6767 hand_classification.substrate = kind;
6768 let via_hand = EphemeralSpec {
6769 classification: Some(hand_classification),
6770 ..baseline()
6771 };
6772 assert_eq!(
6773 via_composer.classification, via_hand.classification,
6774 "SubstrateType::{kind:?}: composer vs pre-sweep hand-authored classification drift",
6775 );
6776 }
6777 for kind in CalmClassification::ALL {
6778 let via_composer = baseline().with_classification_axis(kind);
6779 let mut hand_classification = Classification::gate_compute();
6780 hand_classification.calm = kind;
6781 let via_hand = EphemeralSpec {
6782 classification: Some(hand_classification),
6783 ..baseline()
6784 };
6785 assert_eq!(
6786 via_composer.classification, via_hand.classification,
6787 "CalmClassification::{kind:?}: composer vs pre-sweep hand-authored classification drift",
6788 );
6789 }
6790 for kind in DataClassification::ALL {
6791 let via_composer = baseline().with_classification_axis(kind);
6792 let mut hand_classification = Classification::gate_compute();
6793 hand_classification.data_classification = kind;
6794 let via_hand = EphemeralSpec {
6795 classification: Some(hand_classification),
6796 ..baseline()
6797 };
6798 assert_eq!(
6799 via_composer.classification, via_hand.classification,
6800 "DataClassification::{kind:?}: composer vs pre-sweep hand-authored classification drift",
6801 );
6802 }
6803 // Horizon-nested axes: composer matches the newer
6804 // `gate_compute_with_axis` shape used on the horizon-nested
6805 // sweep sites in tatara-check.rs.
6806 for kind in HorizonKind::ALL {
6807 let via_composer = baseline().with_classification_axis(kind);
6808 let via_hand = EphemeralSpec {
6809 classification: Some(Classification::gate_compute_with_axis(kind)),
6810 ..baseline()
6811 };
6812 assert_eq!(
6813 via_composer.classification, via_hand.classification,
6814 "HorizonKind::{kind:?}: composer vs pre-sweep gate_compute_with_axis Some(_) drift",
6815 );
6816 }
6817 for direction in OptimizationDirection::ALL {
6818 let via_composer = baseline().with_classification_axis(direction);
6819 let via_hand = EphemeralSpec {
6820 classification: Some(Classification::gate_compute_with_axis(direction)),
6821 ..baseline()
6822 };
6823 assert_eq!(
6824 via_composer.classification, via_hand.classification,
6825 "OptimizationDirection::{direction:?}: composer vs pre-sweep gate_compute_with_axis Some(_) drift",
6826 );
6827 }
6828 }
6829
6830 fn demo_overlay() -> AplicacaoIntent {
6831 AplicacaoIntent {
6832 chart_ref: "oci://ghcr.io/pleme-io/charts/lareira-demo-app".into(),
6833 version: "0.5.5".into(),
6834 profile: "all-in-one".into(),
6835 values_overlay: serde_json::json!({
6836 "cluster": { "name": "ephemeral-test-01", "namespace": "demo-test" },
6837 "data": { "mysql": { "persistence": { "enabled": false } } },
6838 "compliance": { "overlays": [] }
6839 }),
6840 release_name: Some("demo-app-consolidated".into()),
6841 target_namespace: Some("demo-test".into()),
6842 install_timeout: Some("25m".into()),
6843 }
6844 }
6845
6846 #[test]
6847 fn defaults_resolve_for_ephemeral_spec() {
6848 let e = EphemeralSpec {
6849 aplicacao: demo_overlay(),
6850 ttl: crate::lifetime::default_ephemeral_ttl(),
6851 teardown: TeardownPolicy::default(),
6852 max_concurrent: crate::lifetime::default_ephemeral_max_concurrent(),
6853 postconditions: vec![],
6854 preconditions: vec![],
6855 verify_timeout: None,
6856 classification: None,
6857 parent: None,
6858 exports: vec![],
6859 routing: None,
6860 };
6861 let ps: ProcessSpec = e.into();
6862 // Intent must resolve to Aplicacao.
6863 match ps.intent.variant().unwrap() {
6864 IntentVariant::Aplicacao(a) => {
6865 assert_eq!(a.profile, "all-in-one");
6866 assert_eq!(a.install_timeout.as_deref(), Some("25m"));
6867 }
6868 other => panic!("expected Aplicacao, got {other:?}"),
6869 }
6870 // Lifetime must resolve to Ephemeral with defaults.
6871 match ps.lifetime.variant().unwrap() {
6872 LifetimeVariant::Ephemeral(e) => {
6873 assert_eq!(e.ttl, "1h");
6874 assert_eq!(e.teardown_policy, TeardownPolicy::Always);
6875 }
6876 other => panic!("expected ephemeral, got {other:?}"),
6877 }
6878 // Default classification gates the Process at Compute/Internal.
6879 assert_eq!(ps.classification.point_type, ConvergencePointType::Gate);
6880 assert_eq!(ps.classification.substrate, SubstrateType::Compute);
6881 }
6882
6883 #[test]
6884 fn ephemeral_lisp_round_trip() {
6885 let src = r#"
6886 (defephemeral closed-loop-attest
6887 :aplicacao (:chart-ref "oci://ghcr.io/pleme-io/charts/lareira-demo-app"
6888 :version "0.5.5"
6889 :profile "all-in-one"
6890 :values-overlay (:cluster (:name "ephemeral-test-01")
6891 :data (:mysql (:persistence (:enabled #f)))
6892 :compliance (:overlays []))
6893 :release-name "demo-app-consolidated"
6894 :target-namespace "demo-test"
6895 :install-timeout "25m")
6896 :ttl "1h"
6897 :teardown OnAttested
6898 :max-concurrent 1
6899 :postconditions
6900 ((:kind HelmReleaseReleased
6901 :params (:name "demo-app-consolidated"
6902 :namespace "demo-test"))
6903 (:kind ClosedLoopAuth
6904 :params (:issuer (:service "demo-app-issuer" :port 8080)
6905 :consumer (:service "demo-app-gateway" :port 8000)
6906 :probeImage "ghcr.io/pleme-io/closed-loop-probe:0.1.0"))))
6907 "#;
6908 let defs = compile_ephemeral_source(src).expect("compile");
6909 assert_eq!(defs.len(), 1);
6910 let d = &defs[0];
6911 assert_eq!(d.name, "closed-loop-attest");
6912
6913 // Aplicacao body landed correctly.
6914 assert_eq!(
6915 d.spec.aplicacao.chart_ref,
6916 "oci://ghcr.io/pleme-io/charts/lareira-demo-app"
6917 );
6918 assert_eq!(d.spec.aplicacao.profile, "all-in-one");
6919 assert_eq!(
6920 d.spec.aplicacao.target_namespace.as_deref(),
6921 Some("demo-test")
6922 );
6923 // values-overlay JSON is preserved.
6924 assert_eq!(
6925 d.spec.aplicacao.values_overlay["cluster"]["name"],
6926 "ephemeral-test-01"
6927 );
6928 // Boolean #f is preserved as a typed JSON bool (not the string "false").
6929 // tatara-lisp uses Scheme syntax for bools — `#t` / `#f`.
6930 assert_eq!(
6931 d.spec.aplicacao.values_overlay["data"]["mysql"]["persistence"]["enabled"],
6932 false
6933 );
6934
6935 // Lifetime knobs.
6936 assert_eq!(d.spec.ttl, "1h");
6937 assert_eq!(d.spec.teardown, TeardownPolicy::OnAttested);
6938 assert_eq!(d.spec.max_concurrent, 1);
6939
6940 // Two postconditions, both typed.
6941 assert_eq!(d.spec.postconditions.len(), 2);
6942 assert_eq!(
6943 d.spec.postconditions[0].kind,
6944 ConditionKind::HelmReleaseReleased
6945 );
6946 assert_eq!(d.spec.postconditions[1].kind, ConditionKind::ClosedLoopAuth);
6947
6948 // Lowers to ProcessSpec with the right shape.
6949 let ps: ProcessSpec = d.spec.clone().into();
6950 assert!(matches!(
6951 ps.intent.variant().unwrap(),
6952 IntentVariant::Aplicacao(_)
6953 ));
6954 assert!(matches!(
6955 ps.lifetime.variant().unwrap(),
6956 LifetimeVariant::Ephemeral(_)
6957 ));
6958 assert_eq!(ps.boundary.postconditions.len(), 2);
6959 }
6960
6961 /// End-to-end: the `:exports` slot on `(defephemeral …)` compiles
6962 /// into typed `ExportSpec` values via the Universal-Deserialize
6963 /// fallthrough — no per-domain keyword handlers needed.
6964 ///
6965 /// Receipts (empty-body source) is exercised via the Rust serde
6966 /// path only (see `export::tests::export_spec_serde_round_trip`).
6967 /// tatara-lisp's empty-kw-form `(:)` currently parses as a single-
6968 /// element array rather than a JSON `{}`; the same limitation
6969 /// affects `(:permanent)` on Lifetime. Tracked: extend the reader
6970 /// to accept `(:foo (:))` ⇒ `{"foo": {}}` as a typed-empty form,
6971 /// then re-enable Receipts here.
6972 #[test]
6973 fn exports_lisp_round_trip() {
6974 use crate::export::{ArtifactVariant, ChannelVariant, ExportTrigger, ReportFormat};
6975 let src = r#"
6976 (defephemeral closed-loop-attest
6977 :aplicacao (:chart-ref "oci://x"
6978 :version "1.0.0"
6979 :profile "minimal"
6980 :values-overlay ())
6981 :ttl "30m"
6982 :teardown OnAttested
6983 :exports
6984 ((:source (:test-report (:configmap "junit-results"
6985 :key "junit.xml"
6986 :format Junit))
6987 :channel (:nats-subject (:subject "pleme.pleme-dev.ephemeral.r1.test-report"
6988 :stream "EPHEMERAL_TEST_REPORTS"))
6989 :when OnAttested)
6990 (:source (:test-report (:configmap "junit-results"
6991 :key "junit.xml"
6992 :format Junit))
6993 :channel (:http-event (:signal-type "test-report"))
6994 :when Always)
6995 (:source (:run-marker (:labels (:run-id "r1" :phase "end")))
6996 :channel (:http-event (:signal-type "ephemeral-marker"))
6997 :when Always)))
6998 "#;
6999 let defs = compile_ephemeral_source(src).expect("compile");
7000 assert_eq!(defs.len(), 1);
7001 let d = &defs[0];
7002 assert_eq!(d.spec.exports.len(), 3);
7003
7004 // First export — TestReport → NATS subject + OnAttested
7005 let r = &d.spec.exports[0];
7006 match r.source.variant().unwrap() {
7007 ArtifactVariant::TestReport(tr) => {
7008 assert_eq!(tr.configmap, "junit-results");
7009 assert_eq!(tr.format, ReportFormat::Junit);
7010 }
7011 other => panic!("expected TestReport, got {other:?}"),
7012 }
7013 match r.channel.variant().unwrap() {
7014 ChannelVariant::NatsSubject(n) => {
7015 assert_eq!(n.subject, "pleme.pleme-dev.ephemeral.r1.test-report");
7016 assert_eq!(n.stream, "EPHEMERAL_TEST_REPORTS");
7017 }
7018 other => panic!("expected NatsSubject, got {other:?}"),
7019 }
7020 assert_eq!(r.when, ExportTrigger::OnAttested);
7021
7022 // Second export — TestReport → HTTP + Always
7023 let t = &d.spec.exports[1];
7024 match t.channel.variant().unwrap() {
7025 ChannelVariant::HttpEvent(h) => assert_eq!(h.signal_type, "test-report"),
7026 other => panic!("expected HttpEvent, got {other:?}"),
7027 }
7028 assert_eq!(t.when, ExportTrigger::Always);
7029
7030 // Third export — RunMarker (BTreeMap<String,String> round-trip).
7031 // tatara-lisp lowercases + normalizes keyword keys before
7032 // handing off to serde_json — kebab `:run-id` may land as
7033 // either `run-id` or `runId` depending on the reader path.
7034 // Accept either; the round-trip property under test is
7035 // "label survives compile" not "exact case-form".
7036 let m = &d.spec.exports[2];
7037 match m.source.variant().unwrap() {
7038 ArtifactVariant::RunMarker(rm) => {
7039 assert_eq!(rm.labels.len(), 2);
7040 let run_id = rm
7041 .labels
7042 .get("run-id")
7043 .or_else(|| rm.labels.get("runId"))
7044 .or_else(|| rm.labels.get("run_id"))
7045 .expect("run-id label present under some normalization");
7046 assert_eq!(run_id, "r1");
7047 assert_eq!(rm.labels.get("phase").map(String::as_str), Some("end"));
7048 }
7049 other => panic!("expected RunMarker, got {other:?}"),
7050 }
7051
7052 // Lowered ProcessSpec carries the exports through unchanged.
7053 let ps: ProcessSpec = d.spec.clone().into();
7054 assert_eq!(ps.lifetime.ephemeral.as_ref().unwrap().exports.len(), 3);
7055 }
7056
7057 // ── EphemeralSpec::has_condition_kind substrate pins ─────────────
7058 //
7059 // Fail-before-pass-after granularity:
7060 // `EphemeralSpec::has_condition_kind` did not exist before this
7061 // commit — the (preconditions ∪ postconditions .iter().any(|c|
7062 // c.kind == K)) union-probe shape lived at ONE struct-level site
7063 // (`Boundary::has_condition_kind` on the point surface's nested
7064 // [`Boundary`] slot). The lift adds the peer inherent method on the
7065 // [`EphemeralSpec`] sugar-surface so both struct-level union
7066 // callers compose against the SAME slice-level substrate primitive
7067 // [`ConditionSliceExt::has_kind`] in lockstep. A regression that
7068 // (a) hard-coded the arm to a single kind, (b) dropped the pre-
7069 // condition side of the OR (a re-inheritance of the pre-lift
7070 // ephemeral `closed-loop-auth` post-only shape at the union-tag
7071 // level), or (c) probed the wrong slot fails HERE at the substrate
7072 // primitive rather than as silent operator-facing drift at the
7073 // ephemeral `condition-<kind>` require-tag surface.
7074
7075 fn empty_ephemeral() -> EphemeralSpec {
7076 EphemeralSpec {
7077 aplicacao: AplicacaoIntent::chart_only("oci://ghcr.io/x", "1"),
7078 ttl: "1h".into(),
7079 teardown: TeardownPolicy::Always,
7080 max_concurrent: 0,
7081 postconditions: vec![],
7082 preconditions: vec![],
7083 verify_timeout: None,
7084 classification: None,
7085 parent: None,
7086 exports: vec![],
7087 routing: None,
7088 }
7089 }
7090
7091 fn cond(kind: ConditionKind) -> Condition {
7092 Condition {
7093 kind,
7094 params: serde_json::json!({}),
7095 }
7096 }
7097
7098 /// EMPTY-SPEC pin — a default [`EphemeralSpec`] (empty
7099 /// preconditions, empty postconditions) returns `false` for EVERY
7100 /// [`ConditionKind`]. Sweep `ConditionKind::ALL` so a new variant
7101 /// added without a matching arm in the presence probe surfaces at
7102 /// rustc's exhaustiveness gate on the ALL literal (arity forced by
7103 /// `[Self; 8]`) rather than as a silent false-positive at every
7104 /// downstream `condition-<kind>` ephemeral require-tag callsite.
7105 /// Byte-for-byte peer of
7106 /// `has_condition_kind_returns_false_on_empty_boundary_for_every_kind`
7107 /// on the [`Boundary`] surface.
7108 #[test]
7109 fn has_condition_kind_returns_false_on_empty_ephemeral_for_every_kind() {
7110 let spec = empty_ephemeral();
7111 for kind in ConditionKind::ALL {
7112 assert!(
7113 !spec.has_condition_kind(kind),
7114 "empty ephemeral spec must return false for {kind:?}",
7115 );
7116 }
7117 }
7118
7119 /// POSTCONDITION-only pin — an ephemeral spec that carries the
7120 /// kind on ONLY postconditions returns `true` for that kind,
7121 /// `false` for every other variant. Sweep the ALL × ALL cross so
7122 /// a regression that hard-coded the arm to a single kind or
7123 /// probed the wrong slot fails HERE at the substrate primitive.
7124 #[test]
7125 fn has_condition_kind_reads_ephemeral_postconditions_per_kind() {
7126 for populated in ConditionKind::ALL {
7127 let mut spec = empty_ephemeral();
7128 spec.postconditions.push(cond(populated));
7129 for query in ConditionKind::ALL {
7130 let expected = query == populated;
7131 assert_eq!(
7132 spec.has_condition_kind(query),
7133 expected,
7134 "ephemeral postcondition populated={populated:?}: \
7135 query {query:?} drifted",
7136 );
7137 }
7138 }
7139 }
7140
7141 /// PRECONDITION-only pin — mirrors the postcondition sweep on the
7142 /// other half of the union. Locks the union semantics on both
7143 /// halves separately so a regression that dropped the pre-
7144 /// condition side of the OR fails here even though the
7145 /// postcondition-side pin above passes.
7146 #[test]
7147 fn has_condition_kind_reads_ephemeral_preconditions_per_kind() {
7148 for populated in ConditionKind::ALL {
7149 let mut spec = empty_ephemeral();
7150 spec.preconditions.push(cond(populated));
7151 for query in ConditionKind::ALL {
7152 let expected = query == populated;
7153 assert_eq!(
7154 spec.has_condition_kind(query),
7155 expected,
7156 "ephemeral precondition populated={populated:?}: \
7157 query {query:?} drifted",
7158 );
7159 }
7160 }
7161 }
7162
7163 /// UNION pin — a kind that appears on preconditions returns
7164 /// `true` even when postconditions carries a DIFFERENT kind, and
7165 /// vice versa. Pins the OR-composition of the two halves so a
7166 /// regression that collapsed the union to an intersection (AND)
7167 /// silently reclassifies pre-only or post-only kinds as absent.
7168 /// Byte-for-byte peer of
7169 /// `has_condition_kind_unions_pre_and_post_condition_arms` on the
7170 /// [`Boundary`] surface.
7171 #[test]
7172 fn has_condition_kind_unions_pre_and_post_ephemeral_condition_arms() {
7173 let mut spec = empty_ephemeral();
7174 spec.preconditions
7175 .push(cond(ConditionKind::KustomizationHealthy));
7176 spec.postconditions
7177 .push(cond(ConditionKind::ClosedLoopAuth));
7178 assert!(
7179 spec.has_condition_kind(ConditionKind::KustomizationHealthy),
7180 "pre-only kind must resolve through the union",
7181 );
7182 assert!(
7183 spec.has_condition_kind(ConditionKind::ClosedLoopAuth),
7184 "post-only kind must resolve through the union",
7185 );
7186 assert!(
7187 !spec.has_condition_kind(ConditionKind::PromQL),
7188 "an absent kind must return false even with populated halves",
7189 );
7190 }
7191
7192 /// COMPOSITION pin — [`EphemeralSpec::has_condition_kind`] equals
7193 /// the OR of the two slice-level probes on the pre/post fields.
7194 /// The struct-level union body composes ONLY [`ConditionSliceExt::has_kind`]
7195 /// on each half; a regression that inlined a wide-net predicate
7196 /// (`.iter().any(|c| c.kind != kind).not()`, an `all` instead of
7197 /// `any`) drifts from the slice-level primitive here. Byte-for-
7198 /// byte peer of the
7199 /// `boundary_has_condition_kind_equals_or_of_half_slice_probes`
7200 /// composition pin on the [`Boundary`] surface.
7201 #[test]
7202 fn ephemeral_has_condition_kind_equals_or_of_half_slice_probes() {
7203 // Sweep every ConditionKind on both halves independently so the
7204 // cross of half-slice probes reaches the OR-composition body
7205 // exhaustively.
7206 for populated in ConditionKind::ALL {
7207 let mut spec = empty_ephemeral();
7208 spec.preconditions.push(cond(populated));
7209 spec.postconditions.push(cond(ConditionKind::PromQL));
7210 for query in ConditionKind::ALL {
7211 let via_or_of_halves =
7212 spec.preconditions.has_kind(query) || spec.postconditions.has_kind(query);
7213 assert_eq!(
7214 spec.has_condition_kind(query),
7215 via_or_of_halves,
7216 "populated={populated:?} query={query:?}: struct-level \
7217 union drifted from OR of slice-level probes",
7218 );
7219 }
7220 }
7221 }
7222
7223 // ── EphemeralSpec::has_(pre|post)condition_kind substrate pins ──
7224 //
7225 // Fail-before-pass-after granularity: the two half-slice arms did
7226 // not exist on the ephemeral surface before this commit — the
7227 // ephemeral require-tag classifier in `tatara-check` and the
7228 // `closed-loop-auth` fixed-tag arm reached
7229 // `spec.postconditions.has_kind(K)` through direct field access,
7230 // asymmetric with the union-arm [`EphemeralSpec::has_condition_kind`]
7231 // that already routed through the named struct method. The lift
7232 // closes the (precondition, postcondition, union) triad on the
7233 // ephemeral sugar surface so a future normalization at the
7234 // presence-probe shape lands at ONE site per surface for all
7235 // three arms.
7236
7237 /// EMPTY-SPEC pin — an ephemeral spec with no preconditions and
7238 /// no postconditions returns `false` for EVERY [`ConditionKind`]
7239 /// on both half-slice arms. Sweep `ConditionKind::ALL` so a new
7240 /// variant added without a matching arm surfaces at rustc's
7241 /// exhaustiveness gate on the ALL literal (arity forced by the
7242 /// closed-set array) rather than as a silent false-positive at
7243 /// every downstream require-tag callsite on the ephemeral
7244 /// surface.
7245 #[test]
7246 fn ephemeral_has_precondition_and_postcondition_kind_return_false_on_empty_spec() {
7247 let spec = empty_ephemeral();
7248 for kind in ConditionKind::ALL {
7249 assert!(
7250 !spec.has_precondition_kind(kind),
7251 "empty ephemeral must return false on precondition arm for {kind:?}",
7252 );
7253 assert!(
7254 !spec.has_postcondition_kind(kind),
7255 "empty ephemeral must return false on postcondition arm for {kind:?}",
7256 );
7257 }
7258 }
7259
7260 /// SLICE-SELECTIVITY pin (precondition arm) — an ephemeral spec
7261 /// with a kind on the precondition side ONLY resolves `true` at
7262 /// [`EphemeralSpec::has_precondition_kind`] and `false` at
7263 /// [`EphemeralSpec::has_postcondition_kind`]. Locks the (side-
7264 /// select, kind-select) partition so a regression that pointed
7265 /// the precondition arm at `self.postconditions` (a copy-paste
7266 /// from the sibling arm during the lift) surfaces HERE.
7267 #[test]
7268 fn ephemeral_has_precondition_kind_reads_preconditions_slice_only() {
7269 for populated in ConditionKind::ALL {
7270 let mut spec = empty_ephemeral();
7271 spec.preconditions.push(cond(populated));
7272 for query in ConditionKind::ALL {
7273 let expected_pre = query == populated;
7274 assert_eq!(
7275 spec.has_precondition_kind(query),
7276 expected_pre,
7277 "precondition-only populated={populated:?}: query {query:?} \
7278 drifted on ephemeral precondition arm",
7279 );
7280 assert!(
7281 !spec.has_postcondition_kind(query),
7282 "precondition-only populated={populated:?}: query {query:?} must \
7283 return false on ephemeral postcondition arm (postconditions is empty)",
7284 );
7285 }
7286 }
7287 }
7288
7289 /// SLICE-SELECTIVITY pin (postcondition arm) — mirror of the
7290 /// precondition-only sweep on the other half. Locks the
7291 /// postcondition arm's binding to `self.postconditions` so a
7292 /// regression that pointed it at `self.preconditions` fails HERE
7293 /// even though the precondition-arm pin above passes.
7294 #[test]
7295 fn ephemeral_has_postcondition_kind_reads_postconditions_slice_only() {
7296 for populated in ConditionKind::ALL {
7297 let mut spec = empty_ephemeral();
7298 spec.postconditions.push(cond(populated));
7299 for query in ConditionKind::ALL {
7300 let expected_post = query == populated;
7301 assert_eq!(
7302 spec.has_postcondition_kind(query),
7303 expected_post,
7304 "postcondition-only populated={populated:?}: query {query:?} \
7305 drifted on ephemeral postcondition arm",
7306 );
7307 assert!(
7308 !spec.has_precondition_kind(query),
7309 "postcondition-only populated={populated:?}: query {query:?} must \
7310 return false on ephemeral precondition arm (preconditions is empty)",
7311 );
7312 }
7313 }
7314 }
7315
7316 /// COMPOSITION-LAW pin — [`EphemeralSpec::has_condition_kind`]
7317 /// equals `has_precondition_kind(k) || has_postcondition_kind(k)`
7318 /// at EVERY (pre-populated, post-populated, query) triple on
7319 /// `ConditionKind::ALL`. Byte-for-byte peer of the
7320 /// `boundary_has_condition_kind_composes_precondition_and_postcondition_arms`
7321 /// composition-law pin on the [`Boundary`] surface — the
7322 /// two-surface parity contract binds the ephemeral sugar type
7323 /// and the point-domain boundary type through the SAME
7324 /// (`condition_kind = precondition_kind ∨ postcondition_kind`)
7325 /// composition, so every downstream `condition-<K>` require-tag
7326 /// classifier on either surface inherits the composition
7327 /// mechanically.
7328 #[test]
7329 fn ephemeral_has_condition_kind_composes_precondition_and_postcondition_arms() {
7330 for pre_kind in ConditionKind::ALL {
7331 for post_kind in ConditionKind::ALL {
7332 let mut spec = empty_ephemeral();
7333 spec.preconditions.push(cond(pre_kind));
7334 spec.postconditions.push(cond(post_kind));
7335 for query in ConditionKind::ALL {
7336 let via_arms =
7337 spec.has_precondition_kind(query) || spec.has_postcondition_kind(query);
7338 assert_eq!(
7339 spec.has_condition_kind(query),
7340 via_arms,
7341 "ephemeral union arm drifted from OR of half-slice arms: \
7342 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7343 );
7344 }
7345 }
7346 }
7347 }
7348
7349 /// SUBSTRATE-DELEGATION pin — the two half-slice arms on the
7350 /// ephemeral surface delegate verbatim to
7351 /// [`crate::boundary::ConditionSliceExt::has_kind`] on the
7352 /// underlying [`Vec<Condition>`] slice, no inline reimplementation.
7353 /// Sweep the full `ConditionKind::ALL` × `ConditionKind::ALL`
7354 /// cross so a regression that inlined a divergent walk at either
7355 /// arm surfaces HERE at the substrate boundary rather than as
7356 /// silent skew between the struct-level arm and the slice-level
7357 /// primitive.
7358 #[test]
7359 fn ephemeral_has_precondition_and_postcondition_kind_delegate_to_slice_has_kind() {
7360 for populated in ConditionKind::ALL {
7361 let mut spec = empty_ephemeral();
7362 spec.preconditions.push(cond(populated));
7363 spec.postconditions.push(cond(populated));
7364 for query in ConditionKind::ALL {
7365 assert_eq!(
7366 spec.has_precondition_kind(query),
7367 spec.preconditions.has_kind(query),
7368 "ephemeral precondition arm must delegate to preconditions.has_kind: \
7369 populated={populated:?} query={query:?}",
7370 );
7371 assert_eq!(
7372 spec.has_postcondition_kind(query),
7373 spec.postconditions.has_kind(query),
7374 "ephemeral postcondition arm must delegate to postconditions.has_kind: \
7375 populated={populated:?} query={query:?}",
7376 );
7377 }
7378 }
7379 }
7380
7381 // ── EphemeralSpec::find_(pre|post|)condition_kind widened triad ──
7382 //
7383 // Fail-before-pass-after granularity: the three widened
7384 // `find_*_kind` arms did not exist on the ephemeral surface before
7385 // this commit — the (widened `Option<&Condition>` return) axis
7386 // lived at ONE struct-level site (`Boundary::find_condition_kind`
7387 // on the point surface's nested [`Boundary`] slot). The lift adds
7388 // the peer inherent methods on the [`EphemeralSpec`] sugar-surface
7389 // so both struct-level widened callers compose against the SAME
7390 // slice-level substrate primitive
7391 // [`crate::boundary::ConditionSliceExt::find_kind`] in lockstep.
7392 // A regression that (a) hard-coded the arm to a single kind, (b)
7393 // reversed the walk order on the union (postcondition first), or
7394 // (c) collapsed `or_else` to `and_then` (silently narrowing the
7395 // union to an intersection) fails HERE at the substrate primitive
7396 // rather than as silent operator-facing drift at the ephemeral
7397 // require-tag surface.
7398
7399 /// EMPTY-SPEC pin (find-triad) — a default [`EphemeralSpec`]
7400 /// (empty preconditions, empty postconditions) returns `None`
7401 /// from every widened arm for EVERY [`ConditionKind`]. Sweep
7402 /// `ConditionKind::ALL` × three-arm cross so a new variant added
7403 /// without a matching arm surfaces at rustc's exhaustiveness gate
7404 /// on the ALL literal (arity forced by the closed-set array)
7405 /// rather than as a silent false-`Some` at every downstream
7406 /// widened callsite on the ephemeral surface.
7407 #[test]
7408 fn ephemeral_find_condition_kind_triad_returns_none_on_empty_spec() {
7409 let spec = empty_ephemeral();
7410 for kind in ConditionKind::ALL {
7411 assert!(
7412 spec.find_precondition_kind(kind).is_none(),
7413 "empty ephemeral must return None on precondition find arm for {kind:?}",
7414 );
7415 assert!(
7416 spec.find_postcondition_kind(kind).is_none(),
7417 "empty ephemeral must return None on postcondition find arm for {kind:?}",
7418 );
7419 assert!(
7420 spec.find_condition_kind(kind).is_none(),
7421 "empty ephemeral must return None on union find arm for {kind:?}",
7422 );
7423 }
7424 }
7425
7426 /// SUBSTRATE-DELEGATION pin (ephemeral find-triad) — the three
7427 /// widened `find_*_kind` methods on [`EphemeralSpec`] delegate
7428 /// verbatim to [`crate::boundary::ConditionSliceExt::find_kind`]
7429 /// on the underlying [`Vec<Condition>`] slices, no inline
7430 /// reimplementation. The `find_condition_kind` union walks
7431 /// preconditions first then postconditions via `Option::or_else`.
7432 /// Sweep `ConditionKind::ALL × ConditionKind::ALL × ConditionKind::ALL`
7433 /// so a regression that (a) inlined a divergent walk at either
7434 /// half-slice arm, (b) reversed the union walk order on the
7435 /// ephemeral surface only (breaking two-surface parity with
7436 /// [`crate::boundary::Boundary::find_condition_kind`]), or (c)
7437 /// collapsed `or_else` to `and_then` surfaces HERE at the substrate
7438 /// boundary. Byte-for-byte peer of the point-domain
7439 /// `find_condition_kind_triad_delegates_to_slice_find_kind` pin.
7440 #[test]
7441 fn ephemeral_find_condition_kind_triad_delegates_to_slice_find_kind() {
7442 for pre_kind in ConditionKind::ALL {
7443 for post_kind in ConditionKind::ALL {
7444 let mut spec = empty_ephemeral();
7445 spec.preconditions.push(cond(pre_kind));
7446 spec.postconditions.push(cond(post_kind));
7447 for query in ConditionKind::ALL {
7448 let via_pre = spec.preconditions.find_kind(query);
7449 let via_post = spec.postconditions.find_kind(query);
7450 assert_eq!(
7451 spec.find_precondition_kind(query).map(|c| c.kind),
7452 via_pre.map(|c| c.kind),
7453 "ephemeral precondition find arm must delegate: \
7454 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7455 );
7456 assert_eq!(
7457 spec.find_postcondition_kind(query).map(|c| c.kind),
7458 via_post.map(|c| c.kind),
7459 "ephemeral postcondition find arm must delegate: \
7460 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7461 );
7462 let expected_union = via_pre.or(via_post).map(|c| c.kind);
7463 assert_eq!(
7464 spec.find_condition_kind(query).map(|c| c.kind),
7465 expected_union,
7466 "ephemeral union find arm must equal precondition.or_else(postcondition): \
7467 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7468 );
7469 }
7470 }
7471 }
7472 }
7473
7474 /// PRECONDITION-PRECEDENCE pin (ephemeral) — a kind authored on
7475 /// BOTH sides returns the precondition-side [`Condition`] from
7476 /// `find_condition_kind`. Byte-for-byte peer of the point-domain
7477 /// `find_condition_kind_returns_precondition_side_on_dual_populated`
7478 /// pin, so the two-surface parity contract binds the walk order
7479 /// on both surfaces through ONE composition law. Uses two params-
7480 /// distinguishable [`Condition`]s so a regression on the ephemeral
7481 /// surface only that reversed the walk order surfaces at the
7482 /// returned params payload rather than silently at the presence
7483 /// bit.
7484 #[test]
7485 fn ephemeral_find_condition_kind_returns_precondition_side_on_dual_populated() {
7486 let mut spec = empty_ephemeral();
7487 spec.preconditions.push(Condition {
7488 kind: ConditionKind::ClosedLoopAuth,
7489 params: serde_json::json!({ "side": "pre" }),
7490 });
7491 spec.postconditions.push(Condition {
7492 kind: ConditionKind::ClosedLoopAuth,
7493 params: serde_json::json!({ "side": "post" }),
7494 });
7495 let hit = spec
7496 .find_condition_kind(ConditionKind::ClosedLoopAuth)
7497 .expect("dual-populated ephemeral spec must resolve Some");
7498 assert_eq!(
7499 hit.params.get("side").and_then(serde_json::Value::as_str),
7500 Some("pre"),
7501 "ephemeral find_condition_kind must walk preconditions first",
7502 );
7503 }
7504
7505 /// STRUCT-LEVEL DELEGATION pin (ephemeral has ↔ find) — the three
7506 /// [`EphemeralSpec`] `has_*_kind` arms equal their widened peers'
7507 /// `.is_some()` projection at EVERY (pre-populated, post-populated,
7508 /// query) triple on `ConditionKind::ALL`. Byte-for-byte peer of
7509 /// the point-domain
7510 /// `boundary_has_triad_equals_find_triad_is_some_projection` pin,
7511 /// so both surfaces' has/find refinement bridge stays symmetric by
7512 /// construction — a future consumer that reads
7513 /// `spec.has_condition_kind(k)` as sugar for
7514 /// `spec.find_condition_kind(k).is_some()` on either surface stays
7515 /// typed against the SAME truth table across the two-surface
7516 /// parity contract.
7517 #[test]
7518 fn ephemeral_has_triad_equals_find_triad_is_some_projection() {
7519 for pre_kind in ConditionKind::ALL {
7520 for post_kind in ConditionKind::ALL {
7521 let mut spec = empty_ephemeral();
7522 spec.preconditions.push(cond(pre_kind));
7523 spec.postconditions.push(cond(post_kind));
7524 for query in ConditionKind::ALL {
7525 assert_eq!(
7526 spec.has_precondition_kind(query),
7527 spec.find_precondition_kind(query).is_some(),
7528 "ephemeral precondition has/find bridge drifted: \
7529 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7530 );
7531 assert_eq!(
7532 spec.has_postcondition_kind(query),
7533 spec.find_postcondition_kind(query).is_some(),
7534 "ephemeral postcondition has/find bridge drifted: \
7535 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7536 );
7537 assert_eq!(
7538 spec.has_condition_kind(query),
7539 spec.find_condition_kind(query).is_some(),
7540 "ephemeral union has/find bridge drifted: \
7541 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7542 );
7543 }
7544 }
7545 }
7546 }
7547
7548 // ── EphemeralSpec::iter_(pre|post|)condition_kind widened triad ──
7549 //
7550 // Fail-before-pass-after granularity: the three widened
7551 // `iter_*_kind` arms did not exist on the ephemeral surface before
7552 // this commit — the (widened `impl Iterator<Item = &Condition>`
7553 // stream) axis lived at ONE struct-level site
7554 // (`Boundary::iter_condition_kind` on the point surface's nested
7555 // [`Boundary`] slot). The lift adds the peer inherent methods on
7556 // the [`EphemeralSpec`] sugar-surface so both struct-level widened
7557 // callers compose against the SAME slice-level substrate primitive
7558 // [`crate::boundary::ConditionSliceExt::iter_kind`] in lockstep.
7559 // A regression that (a) hard-coded the arm to a single kind, (b)
7560 // reversed the chain order on the union (postcondition first), or
7561 // (c) collapsed the chain to a `.zip(...)` (silently narrowing the
7562 // union to an intersection-by-position) fails HERE at the
7563 // substrate primitive rather than as silent operator-facing drift
7564 // at the ephemeral require-tag surface.
7565
7566 /// EMPTY-SPEC pin (iter-triad) — a default [`EphemeralSpec`]
7567 /// (empty preconditions, empty postconditions) yields nothing
7568 /// from every widened arm for EVERY [`ConditionKind`]. Sweep
7569 /// `ConditionKind::ALL` × three-arm cross so a new variant added
7570 /// without a matching arm surfaces at rustc's exhaustiveness gate
7571 /// on the ALL literal rather than as a silent phantom-yield at
7572 /// every downstream widened callsite on the ephemeral surface.
7573 #[test]
7574 fn ephemeral_iter_condition_kind_triad_yields_nothing_on_empty_spec() {
7575 let spec = empty_ephemeral();
7576 for kind in ConditionKind::ALL {
7577 assert_eq!(
7578 spec.iter_precondition_kind(kind).count(),
7579 0,
7580 "empty ephemeral must yield nothing on precondition iter arm for {kind:?}",
7581 );
7582 assert_eq!(
7583 spec.iter_postcondition_kind(kind).count(),
7584 0,
7585 "empty ephemeral must yield nothing on postcondition iter arm for {kind:?}",
7586 );
7587 assert_eq!(
7588 spec.iter_condition_kind(kind).count(),
7589 0,
7590 "empty ephemeral must yield nothing on union iter arm for {kind:?}",
7591 );
7592 }
7593 }
7594
7595 /// SUBSTRATE-DELEGATION pin (ephemeral iter-triad) — the three
7596 /// widened `iter_*_kind` methods on [`EphemeralSpec`] delegate
7597 /// verbatim to [`crate::boundary::ConditionSliceExt::iter_kind`]
7598 /// on the underlying [`Vec<Condition>`] slices, no inline
7599 /// reimplementation. The `iter_condition_kind` union chains
7600 /// preconditions first then postconditions via
7601 /// [`Iterator::chain`]. Sweep
7602 /// `ConditionKind::ALL × ConditionKind::ALL × ConditionKind::ALL`
7603 /// so a regression that (a) inlined a divergent walk at either
7604 /// half-slice arm, (b) reversed the chain order on the ephemeral
7605 /// surface only (breaking two-surface parity with
7606 /// [`crate::boundary::Boundary::iter_condition_kind`]), or (c)
7607 /// collapsed the chain to a `.zip(...)` surfaces HERE at the
7608 /// substrate boundary. Byte-for-byte peer of the point-domain
7609 /// `iter_condition_kind_triad_delegates_to_slice_iter_kind` pin.
7610 #[test]
7611 fn ephemeral_iter_condition_kind_triad_delegates_to_slice_iter_kind() {
7612 for pre_kind in ConditionKind::ALL {
7613 for post_kind in ConditionKind::ALL {
7614 let mut spec = empty_ephemeral();
7615 spec.preconditions.push(cond(pre_kind));
7616 spec.postconditions.push(cond(post_kind));
7617 for query in ConditionKind::ALL {
7618 let via_pre: Vec<_> = spec
7619 .preconditions
7620 .iter_kind(query)
7621 .map(|c| c.kind)
7622 .collect();
7623 let via_post: Vec<_> = spec
7624 .postconditions
7625 .iter_kind(query)
7626 .map(|c| c.kind)
7627 .collect();
7628 assert_eq!(
7629 spec.iter_precondition_kind(query)
7630 .map(|c| c.kind)
7631 .collect::<Vec<_>>(),
7632 via_pre,
7633 "ephemeral precondition iter arm must delegate: \
7634 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7635 );
7636 assert_eq!(
7637 spec.iter_postcondition_kind(query)
7638 .map(|c| c.kind)
7639 .collect::<Vec<_>>(),
7640 via_post,
7641 "ephemeral postcondition iter arm must delegate: \
7642 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7643 );
7644 let mut expected_union = via_pre.clone();
7645 expected_union.extend(via_post.iter().copied());
7646 assert_eq!(
7647 spec.iter_condition_kind(query)
7648 .map(|c| c.kind)
7649 .collect::<Vec<_>>(),
7650 expected_union,
7651 "ephemeral union iter arm must chain precondition ⨟ postcondition: \
7652 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7653 );
7654 }
7655 }
7656 }
7657 }
7658
7659 /// PRECONDITION-PRECEDENCE pin (ephemeral iter) — a kind
7660 /// authored on BOTH sides yields precondition-side matches
7661 /// FIRST in the union chain. Byte-for-byte peer of the
7662 /// point-domain
7663 /// `iter_condition_kind_yields_preconditions_before_postconditions_on_dual_populated`
7664 /// pin — the two-surface parity contract binds the chain order
7665 /// on both surfaces through ONE composition law. Uses two
7666 /// params-distinguishable [`Condition`]s so a regression on the
7667 /// ephemeral surface only that reversed the chain order surfaces
7668 /// at the returned params payload rather than silently at the
7669 /// count.
7670 #[test]
7671 fn ephemeral_iter_condition_kind_yields_preconditions_before_postconditions_on_dual_populated()
7672 {
7673 let mut spec = empty_ephemeral();
7674 spec.preconditions.push(Condition {
7675 kind: ConditionKind::ClosedLoopAuth,
7676 params: serde_json::json!({ "side": "pre-1" }),
7677 });
7678 spec.postconditions.push(Condition {
7679 kind: ConditionKind::ClosedLoopAuth,
7680 params: serde_json::json!({ "side": "post-1" }),
7681 });
7682 spec.postconditions.push(Condition {
7683 kind: ConditionKind::ClosedLoopAuth,
7684 params: serde_json::json!({ "side": "post-2" }),
7685 });
7686 let sides: Vec<_> = spec
7687 .iter_condition_kind(ConditionKind::ClosedLoopAuth)
7688 .map(|c| {
7689 c.params
7690 .get("side")
7691 .and_then(serde_json::Value::as_str)
7692 .unwrap_or_default()
7693 .to_owned()
7694 })
7695 .collect();
7696 assert_eq!(
7697 sides,
7698 vec!["pre-1".to_owned(), "post-1".to_owned(), "post-2".to_owned(),],
7699 "ephemeral iter_condition_kind must yield every precondition-side match before \
7700 any postcondition-side match (chain order pinned by two-surface parity)",
7701 );
7702 }
7703
7704 /// STRUCT-LEVEL DELEGATION pin (find ↔ iter on EphemeralSpec) —
7705 /// the three [`EphemeralSpec`] `find_*_kind` arms equal their
7706 /// widened peers' `.next()` projection at EVERY (pre-populated,
7707 /// post-populated, query) triple on `ConditionKind::ALL`.
7708 /// Byte-for-byte peer of the point-domain
7709 /// `boundary_find_triad_equals_iter_triad_next_projection` pin,
7710 /// so both surfaces' find/iter refinement bridge stays symmetric
7711 /// by construction across the two-surface parity contract.
7712 #[test]
7713 fn ephemeral_find_triad_equals_iter_triad_next_projection() {
7714 for pre_kind in ConditionKind::ALL {
7715 for post_kind in ConditionKind::ALL {
7716 let mut spec = empty_ephemeral();
7717 spec.preconditions.push(cond(pre_kind));
7718 spec.postconditions.push(cond(post_kind));
7719 for query in ConditionKind::ALL {
7720 assert_eq!(
7721 spec.find_precondition_kind(query).map(|c| c.kind),
7722 spec.iter_precondition_kind(query).next().map(|c| c.kind),
7723 "ephemeral precondition find/iter bridge drifted: \
7724 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7725 );
7726 assert_eq!(
7727 spec.find_postcondition_kind(query).map(|c| c.kind),
7728 spec.iter_postcondition_kind(query).next().map(|c| c.kind),
7729 "ephemeral postcondition find/iter bridge drifted: \
7730 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7731 );
7732 assert_eq!(
7733 spec.find_condition_kind(query).map(|c| c.kind),
7734 spec.iter_condition_kind(query).next().map(|c| c.kind),
7735 "ephemeral union find/iter bridge drifted: \
7736 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7737 );
7738 }
7739 }
7740 }
7741 }
7742
7743 // ── EphemeralSpec count triad — scalar cardinality peers ─────────
7744 //
7745 // Byte-for-byte peers of the point-domain `Boundary`
7746 // `count_(pre|post|)condition_kind` triad, tested at the ephemeral
7747 // sugar surface. Same SUM composition on the union arm, same
7748 // slice-level substrate delegation, same composition-law bridge
7749 // against the widened iter refinement.
7750
7751 /// EMPTY-SPEC pin (count-triad) — a default [`EphemeralSpec`]
7752 /// counts `0` from every arm of the count triad for EVERY
7753 /// [`ConditionKind`].
7754 #[test]
7755 fn ephemeral_count_condition_kind_triad_returns_zero_on_empty_spec() {
7756 let spec = empty_ephemeral();
7757 for kind in ConditionKind::ALL {
7758 assert_eq!(
7759 spec.count_precondition_kind(kind),
7760 0,
7761 "empty ephemeral must count 0 on precondition arm for {kind:?}",
7762 );
7763 assert_eq!(
7764 spec.count_postcondition_kind(kind),
7765 0,
7766 "empty ephemeral must count 0 on postcondition arm for {kind:?}",
7767 );
7768 assert_eq!(
7769 spec.count_condition_kind(kind),
7770 0,
7771 "empty ephemeral must count 0 on union arm for {kind:?}",
7772 );
7773 }
7774 }
7775
7776 /// SUBSTRATE-DELEGATION pin (ephemeral count-triad) — the three
7777 /// widened `count_*_kind` methods on [`EphemeralSpec`] delegate
7778 /// verbatim to [`crate::boundary::ConditionSliceExt::count_kind`]
7779 /// on the underlying [`Vec<Condition>`] slices. The
7780 /// `count_condition_kind` union SUMS preconditions and
7781 /// postconditions. Byte-for-byte peer of the point-domain
7782 /// `boundary_count_condition_kind_triad_delegates_and_sums_slice_count_kind`
7783 /// pin; a regression that (a) subtracted rather than summed, (b)
7784 /// collapsed the sum to [`std::cmp::max`], or (c) inlined a
7785 /// divergent count at either half-slice arm on the ephemeral
7786 /// surface only (breaking two-surface parity with [`Boundary`])
7787 /// surfaces HERE.
7788 #[test]
7789 fn ephemeral_count_condition_kind_triad_delegates_and_sums_slice_count_kind() {
7790 for pre_kind in ConditionKind::ALL {
7791 for post_kind in ConditionKind::ALL {
7792 let mut spec = empty_ephemeral();
7793 spec.preconditions.push(cond(pre_kind));
7794 spec.postconditions.push(cond(post_kind));
7795 for query in ConditionKind::ALL {
7796 let via_pre = spec.preconditions.count_kind(query);
7797 let via_post = spec.postconditions.count_kind(query);
7798 assert_eq!(
7799 spec.count_precondition_kind(query),
7800 via_pre,
7801 "ephemeral precondition count arm must delegate: \
7802 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7803 );
7804 assert_eq!(
7805 spec.count_postcondition_kind(query),
7806 via_post,
7807 "ephemeral postcondition count arm must delegate: \
7808 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7809 );
7810 assert_eq!(
7811 spec.count_condition_kind(query),
7812 via_pre + via_post,
7813 "ephemeral union count arm must SUM pre + post: \
7814 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7815 );
7816 }
7817 }
7818 }
7819 }
7820
7821 /// STRUCT-LEVEL DELEGATION pin (count ↔ iter on EphemeralSpec) —
7822 /// the three [`EphemeralSpec`] `count_*_kind` arms equal their
7823 /// widened peers' `.count()` projection at EVERY (pre-populated
7824 /// twice, post-populated, query) triple. Byte-for-byte peer of
7825 /// the point-domain
7826 /// `boundary_count_triad_equals_iter_triad_count_projection`
7827 /// pin. Uses two-preconditions authoring so the union arm's SUM
7828 /// composition witnesses a nontrivial cardinality (rather than
7829 /// coinciding with the presence bit).
7830 #[test]
7831 fn ephemeral_count_triad_equals_iter_triad_count_projection() {
7832 for pre_kind in ConditionKind::ALL {
7833 for post_kind in ConditionKind::ALL {
7834 let mut spec = empty_ephemeral();
7835 spec.preconditions.push(cond(pre_kind));
7836 spec.preconditions.push(cond(pre_kind));
7837 spec.postconditions.push(cond(post_kind));
7838 for query in ConditionKind::ALL {
7839 assert_eq!(
7840 spec.count_precondition_kind(query),
7841 spec.iter_precondition_kind(query).count(),
7842 "ephemeral precondition count/iter bridge drifted: \
7843 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7844 );
7845 assert_eq!(
7846 spec.count_postcondition_kind(query),
7847 spec.iter_postcondition_kind(query).count(),
7848 "ephemeral postcondition count/iter bridge drifted: \
7849 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7850 );
7851 assert_eq!(
7852 spec.count_condition_kind(query),
7853 spec.iter_condition_kind(query).count(),
7854 "ephemeral union count/iter bridge drifted: \
7855 pre={pre_kind:?} post={post_kind:?} query={query:?}",
7856 );
7857 }
7858 }
7859 }
7860 }
7861
7862 // ── EphemeralSpec distinct-set triad — substrate-delegation pin ──
7863 //
7864 // The (precondition, postcondition, condition-union) distinct-set
7865 // triad on [`EphemeralSpec`] delegates to the slice-level substrate
7866 // primitive [`crate::boundary::ConditionSliceExt::distinct_kinds`]
7867 // on each half-slice and composes the union via
7868 // [`Self::has_condition_kind`] over [`ConditionKind::ALL`] — byte-
7869 // for-byte peer of the point-surface distinct-set triad on
7870 // [`crate::boundary::Boundary`]. The two-surface parity contract
7871 // now covers FIVE refinements on the condition axis: the four
7872 // point-probe refinements (has / find / iter / count) AND the ONE
7873 // closed-set-inversion refinement (distinct-set) on both surfaces.
7874
7875 /// SUBSTRATE-DELEGATION pin (ephemeral surface, distinct-kind-count
7876 /// triad) — the three `distinct_*_kind_count` methods on
7877 /// [`EphemeralSpec`] delegate to the slice-level substrate
7878 /// primitive [`crate::boundary::ConditionSliceExt::distinct_kind_count`]
7879 /// over the two `Vec<Condition>` slots and compose the union
7880 /// scalar via `ConditionKind::ALL.filter(|k|
7881 /// has_condition_kind(*k)).count()`. Byte-for-byte peer of the
7882 /// point-surface pin
7883 /// `distinct_condition_kind_count_triad_delegates_to_slice_distinct_kind_count`
7884 /// on [`crate::boundary::Boundary`] — the two-surface parity
7885 /// contract now binds every downstream scalar-cardinality consumer
7886 /// on either surface to the SAME closed-set walk through ONE
7887 /// substrate rather than through per-surface `.distinct_*_kinds().len()`
7888 /// re-materializations that pay for a heap allocation.
7889 #[test]
7890 fn ephemeral_distinct_condition_kind_count_triad_delegates_and_matches_distinct_kinds_len() {
7891 // Empty spec — every arm returns 0.
7892 let spec = empty_ephemeral();
7893 for kind in ConditionKind::ALL {
7894 assert_eq!(
7895 spec.distinct_precondition_kind_count(),
7896 0,
7897 "empty ephemeral spec must return 0 on distinct_precondition_kind_count, kind={kind:?}",
7898 );
7899 assert_eq!(
7900 spec.distinct_postcondition_kind_count(),
7901 0,
7902 "empty ephemeral spec must return 0 on distinct_postcondition_kind_count, kind={kind:?}",
7903 );
7904 assert_eq!(
7905 spec.distinct_condition_kind_count(),
7906 0,
7907 "empty ephemeral spec must return 0 on distinct_condition_kind_count, kind={kind:?}",
7908 );
7909 }
7910
7911 for pre_kind in ConditionKind::ALL {
7912 for post_kind in ConditionKind::ALL {
7913 let mut spec = empty_ephemeral();
7914 spec.preconditions.push(cond(pre_kind));
7915 spec.postconditions.push(cond(post_kind));
7916
7917 assert_eq!(
7918 spec.distinct_precondition_kind_count(),
7919 spec.preconditions.distinct_kind_count(),
7920 "EphemeralSpec::distinct_precondition_kind_count must delegate verbatim to \
7921 preconditions.distinct_kind_count() for pre={pre_kind:?} post={post_kind:?}",
7922 );
7923 assert_eq!(
7924 spec.distinct_precondition_kind_count(),
7925 spec.distinct_precondition_kinds().len(),
7926 "EphemeralSpec::distinct_precondition_kind_count must equal \
7927 distinct_precondition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
7928 );
7929 assert_eq!(
7930 spec.distinct_postcondition_kind_count(),
7931 spec.postconditions.distinct_kind_count(),
7932 "EphemeralSpec::distinct_postcondition_kind_count must delegate verbatim to \
7933 postconditions.distinct_kind_count() for pre={pre_kind:?} post={post_kind:?}",
7934 );
7935 assert_eq!(
7936 spec.distinct_postcondition_kind_count(),
7937 spec.distinct_postcondition_kinds().len(),
7938 "EphemeralSpec::distinct_postcondition_kind_count must equal \
7939 distinct_postcondition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
7940 );
7941 let expected_union_count = if pre_kind == post_kind { 1 } else { 2 };
7942 assert_eq!(
7943 spec.distinct_condition_kind_count(),
7944 expected_union_count,
7945 "EphemeralSpec::distinct_condition_kind_count must count distinct union kinds \
7946 for pre={pre_kind:?} post={post_kind:?}",
7947 );
7948 assert_eq!(
7949 spec.distinct_condition_kind_count(),
7950 spec.distinct_condition_kinds().len(),
7951 "EphemeralSpec::distinct_condition_kind_count must equal \
7952 distinct_condition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
7953 );
7954 }
7955 }
7956 }
7957
7958 /// SUBSTRATE-DELEGATION pin (ephemeral surface, distinct-set triad)
7959 /// — the three `distinct_*_kinds` methods on [`EphemeralSpec`]
7960 /// delegate to the slice-level substrate primitive over the two
7961 /// `Vec<Condition>` slots and compose the union via
7962 /// `ConditionKind::ALL.filter(|k| has_condition_kind(*k))`. Byte-
7963 /// for-byte peer of the point-surface pin
7964 /// `distinct_condition_kinds_triad_delegates_to_slice_distinct_kinds`
7965 /// on [`crate::boundary::Boundary`] — the two-surface parity
7966 /// contract binds every downstream distinct-set consumer on either
7967 /// surface to the SAME closed-set-inversion primitive through ONE
7968 /// substrate rather than through per-surface re-authored sweeps.
7969 #[test]
7970 fn ephemeral_distinct_condition_kinds_triad_delegates_to_slice_distinct_kinds() {
7971 for pre_kind in ConditionKind::ALL {
7972 for post_kind in ConditionKind::ALL {
7973 let mut spec = empty_ephemeral();
7974 spec.preconditions.push(cond(pre_kind));
7975 spec.postconditions.push(cond(post_kind));
7976
7977 assert_eq!(
7978 spec.distinct_precondition_kinds(),
7979 spec.preconditions.distinct_kinds(),
7980 "EphemeralSpec::distinct_precondition_kinds must delegate verbatim to \
7981 preconditions.distinct_kinds() for pre={pre_kind:?} post={post_kind:?}",
7982 );
7983 assert_eq!(
7984 spec.distinct_postcondition_kinds(),
7985 spec.postconditions.distinct_kinds(),
7986 "EphemeralSpec::distinct_postcondition_kinds must delegate verbatim to \
7987 postconditions.distinct_kinds() for pre={pre_kind:?} post={post_kind:?}",
7988 );
7989 let expected_union: Vec<_> = ConditionKind::ALL
7990 .into_iter()
7991 .filter(|k| pre_kind == *k || post_kind == *k)
7992 .collect();
7993 assert_eq!(
7994 spec.distinct_condition_kinds(),
7995 expected_union,
7996 "EphemeralSpec::distinct_condition_kinds must equal ConditionKind::ALL-ordered \
7997 set-union of the two half-slice distinct-sets for pre={pre_kind:?} post={post_kind:?}",
7998 );
7999 }
8000 }
8001 }
8002
8003 /// SUBSTRATE-DELEGATION pin (EphemeralSpec distinct-set ITERATOR
8004 /// triad) — the three `iter_distinct_*_condition_kinds` methods on
8005 /// [`EphemeralSpec`] delegate to the slice-level substrate primitive
8006 /// [`crate::boundary::ConditionSliceExt::iter_distinct_kinds`] over
8007 /// the two `Vec<Condition>` slots and compose the union via
8008 /// `ConditionKind::ALL.iter().copied().filter(|&k|
8009 /// has_condition_kind(k))`. Byte-for-byte peer of
8010 /// `iter_distinct_condition_kinds_triad_delegates_to_slice_iter_distinct_kinds`
8011 /// on the point-domain [`crate::boundary::Boundary`] surface — both
8012 /// peers compose against the SAME slice-level iterator substrate.
8013 #[test]
8014 fn ephemeral_iter_distinct_condition_kinds_triad_delegates_to_slice_iter_distinct_kinds() {
8015 for pre_kind in ConditionKind::ALL {
8016 for post_kind in ConditionKind::ALL {
8017 let mut spec = empty_ephemeral();
8018 spec.preconditions.push(cond(pre_kind));
8019 spec.postconditions.push(cond(post_kind));
8020
8021 let pre_via_iter: Vec<_> = spec.iter_distinct_precondition_kinds().collect();
8022 assert_eq!(
8023 pre_via_iter,
8024 spec.distinct_precondition_kinds(),
8025 "EphemeralSpec::iter_distinct_precondition_kinds().collect() drifted from \
8026 distinct_precondition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8027 );
8028 let post_via_iter: Vec<_> = spec.iter_distinct_postcondition_kinds().collect();
8029 assert_eq!(
8030 post_via_iter,
8031 spec.distinct_postcondition_kinds(),
8032 "EphemeralSpec::iter_distinct_postcondition_kinds().collect() drifted from \
8033 distinct_postcondition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8034 );
8035 let union_via_iter: Vec<_> = spec.iter_distinct_condition_kinds().collect();
8036 assert_eq!(
8037 union_via_iter,
8038 spec.distinct_condition_kinds(),
8039 "EphemeralSpec::iter_distinct_condition_kinds().collect() drifted from \
8040 distinct_condition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8041 );
8042 }
8043 }
8044 }
8045
8046 /// SUBSTRATE-DELEGATION pin (EphemeralSpec missing-set ITERATOR
8047 /// triad) — the three `iter_missing_*_condition_kinds` methods on
8048 /// [`EphemeralSpec`] delegate to the slice-level substrate primitive
8049 /// [`crate::boundary::ConditionSliceExt::iter_missing_kinds`] over
8050 /// the two `Vec<Condition>` slots and compose the union via
8051 /// `ConditionKind::ALL.iter().copied().filter(|&k|
8052 /// !has_condition_kind(k))`. Peer of
8053 /// `ephemeral_iter_distinct_condition_kinds_triad_delegates_to_slice_iter_distinct_kinds`
8054 /// on the missing side under a NEGATED point-probe.
8055 #[test]
8056 fn ephemeral_iter_missing_condition_kinds_triad_delegates_to_slice_iter_missing_kinds() {
8057 let empty = empty_ephemeral();
8058 let all: Vec<_> = ConditionKind::ALL.to_vec();
8059 assert_eq!(
8060 empty.iter_missing_precondition_kinds().collect::<Vec<_>>(),
8061 all,
8062 "empty ephemeral spec must yield ConditionKind::ALL on iter_missing_precondition_kinds",
8063 );
8064 assert_eq!(
8065 empty.iter_missing_postcondition_kinds().collect::<Vec<_>>(),
8066 all,
8067 "empty ephemeral spec must yield ConditionKind::ALL on iter_missing_postcondition_kinds",
8068 );
8069 assert_eq!(
8070 empty.iter_missing_condition_kinds().collect::<Vec<_>>(),
8071 all,
8072 "empty ephemeral spec must yield ConditionKind::ALL on iter_missing_condition_kinds",
8073 );
8074
8075 for pre_kind in ConditionKind::ALL {
8076 for post_kind in ConditionKind::ALL {
8077 let mut spec = empty_ephemeral();
8078 spec.preconditions.push(cond(pre_kind));
8079 spec.postconditions.push(cond(post_kind));
8080
8081 let pre_via_iter: Vec<_> = spec.iter_missing_precondition_kinds().collect();
8082 assert_eq!(
8083 pre_via_iter,
8084 spec.missing_precondition_kinds(),
8085 "EphemeralSpec::iter_missing_precondition_kinds().collect() drifted from \
8086 missing_precondition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8087 );
8088 let post_via_iter: Vec<_> = spec.iter_missing_postcondition_kinds().collect();
8089 assert_eq!(
8090 post_via_iter,
8091 spec.missing_postcondition_kinds(),
8092 "EphemeralSpec::iter_missing_postcondition_kinds().collect() drifted from \
8093 missing_postcondition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8094 );
8095 let union_via_iter: Vec<_> = spec.iter_missing_condition_kinds().collect();
8096 assert_eq!(
8097 union_via_iter,
8098 spec.missing_condition_kinds(),
8099 "EphemeralSpec::iter_missing_condition_kinds().collect() drifted from \
8100 missing_condition_kinds() for pre={pre_kind:?} post={post_kind:?}",
8101 );
8102 }
8103 }
8104 }
8105
8106 /// SUBSTRATE-DELEGATION pin (EphemeralSpec missing-set triad) —
8107 /// the three `missing_*_kinds` methods on [`EphemeralSpec`]
8108 /// delegate to the slice-level substrate primitive
8109 /// [`crate::boundary::ConditionSliceExt::missing_kinds`] over the
8110 /// two `Vec<Condition>` slots and compose the union via
8111 /// `ConditionKind::ALL.filter(|k| !has_condition_kind(*k))`. Sweep
8112 /// `ConditionKind::ALL × ConditionKind::ALL`. Byte-for-byte peer of
8113 /// `missing_condition_kinds_triad_delegates_to_slice_missing_kinds`
8114 /// on the point-domain [`crate::boundary::Boundary`] surface —
8115 /// both peers compose against the SAME slice-level substrate
8116 /// primitive so a regression at the per-slice complement walk
8117 /// fails at that primitive's tests rather than as silent drift at
8118 /// either struct-level arm.
8119 #[test]
8120 fn ephemeral_missing_condition_kinds_triad_delegates_to_slice_missing_kinds() {
8121 // Empty ephemeral spec — every arm returns ConditionKind::ALL.
8122 let empty = empty_ephemeral();
8123 let all_kinds = ConditionKind::ALL.to_vec();
8124 assert_eq!(
8125 empty.missing_precondition_kinds(),
8126 all_kinds,
8127 "empty ephemeral spec must return ConditionKind::ALL on missing_precondition_kinds",
8128 );
8129 assert_eq!(
8130 empty.missing_postcondition_kinds(),
8131 all_kinds,
8132 "empty ephemeral spec must return ConditionKind::ALL on missing_postcondition_kinds",
8133 );
8134 assert_eq!(
8135 empty.missing_condition_kinds(),
8136 all_kinds,
8137 "empty ephemeral spec must return ConditionKind::ALL on missing_condition_kinds",
8138 );
8139
8140 for pre_kind in ConditionKind::ALL {
8141 for post_kind in ConditionKind::ALL {
8142 let mut spec = empty_ephemeral();
8143 spec.preconditions.push(cond(pre_kind));
8144 spec.postconditions.push(cond(post_kind));
8145
8146 assert_eq!(
8147 spec.missing_precondition_kinds(),
8148 spec.preconditions.missing_kinds(),
8149 "EphemeralSpec::missing_precondition_kinds must delegate verbatim to \
8150 preconditions.missing_kinds() for pre={pre_kind:?} post={post_kind:?}",
8151 );
8152 assert_eq!(
8153 spec.missing_postcondition_kinds(),
8154 spec.postconditions.missing_kinds(),
8155 "EphemeralSpec::missing_postcondition_kinds must delegate verbatim to \
8156 postconditions.missing_kinds() for pre={pre_kind:?} post={post_kind:?}",
8157 );
8158 // Union: a kind is missing from the union iff it is
8159 // missing from BOTH half-slices (SET-INTERSECTION).
8160 let expected_union: Vec<_> = ConditionKind::ALL
8161 .into_iter()
8162 .filter(|k| pre_kind != *k && post_kind != *k)
8163 .collect();
8164 assert_eq!(
8165 spec.missing_condition_kinds(),
8166 expected_union,
8167 "EphemeralSpec::missing_condition_kinds must equal ConditionKind::ALL-ordered \
8168 set-INTERSECTION of the two half-slice missing-sets for pre={pre_kind:?} post={post_kind:?}",
8169 );
8170 // Partition invariant (distinct ∪ missing == ALL, disjoint).
8171 let distinct = spec.distinct_condition_kinds();
8172 let missing = spec.missing_condition_kinds();
8173 for kind in ConditionKind::ALL {
8174 assert!(
8175 distinct.contains(&kind) ^ missing.contains(&kind),
8176 "EphemeralSpec (distinct, missing) partition violated on {kind:?} for pre={pre_kind:?} post={post_kind:?}",
8177 );
8178 }
8179 assert_eq!(
8180 distinct.len() + missing.len(),
8181 ConditionKind::ALL.len(),
8182 "EphemeralSpec (distinct, missing) cardinality partition drift for pre={pre_kind:?} post={post_kind:?}",
8183 );
8184 }
8185 }
8186 }
8187
8188 /// SUBSTRATE-DELEGATION pin (EphemeralSpec missing-kind-count triad)
8189 /// — the three `missing_*_kind_count` methods on [`EphemeralSpec`]
8190 /// delegate to the slice-level substrate primitive
8191 /// [`crate::boundary::ConditionSliceExt::missing_kind_count`] over
8192 /// the two `Vec<Condition>` slots and compose the union scalar via
8193 /// `ConditionKind::ALL.iter().filter(|k|
8194 /// !has_condition_kind(**k)).count()`. Sweep
8195 /// `ConditionKind::ALL × ConditionKind::ALL`. Byte-for-byte peer of
8196 /// `missing_condition_kind_count_triad_delegates_to_slice_missing_kind_count`
8197 /// on the point-domain [`crate::boundary::Boundary`] surface —
8198 /// both peers compose against the SAME slice-level substrate
8199 /// primitive so a regression at the per-slice negated closed-set
8200 /// walk fails at that primitive's tests rather than as silent drift
8201 /// at either struct-level scalar-cardinality arm. Also pins the
8202 /// scalar-partition invariant `distinct_kind_count +
8203 /// missing_kind_count == ConditionKind::ALL.len()` per arrangement.
8204 #[test]
8205 fn ephemeral_missing_condition_kind_count_triad_delegates_to_slice_missing_kind_count() {
8206 // Empty ephemeral spec — every arm returns ConditionKind::ALL.len().
8207 let empty = empty_ephemeral();
8208 let total = ConditionKind::ALL.len();
8209 assert_eq!(
8210 empty.missing_precondition_kind_count(),
8211 total,
8212 "empty ephemeral spec must return ConditionKind::ALL.len() on missing_precondition_kind_count",
8213 );
8214 assert_eq!(
8215 empty.missing_postcondition_kind_count(),
8216 total,
8217 "empty ephemeral spec must return ConditionKind::ALL.len() on missing_postcondition_kind_count",
8218 );
8219 assert_eq!(
8220 empty.missing_condition_kind_count(),
8221 total,
8222 "empty ephemeral spec must return ConditionKind::ALL.len() on missing_condition_kind_count",
8223 );
8224
8225 for pre_kind in ConditionKind::ALL {
8226 for post_kind in ConditionKind::ALL {
8227 let mut spec = empty_ephemeral();
8228 spec.preconditions.push(cond(pre_kind));
8229 spec.postconditions.push(cond(post_kind));
8230
8231 // Half-slice arms delegate byte-for-byte to the slice
8232 // substrate primitive.
8233 assert_eq!(
8234 spec.missing_precondition_kind_count(),
8235 spec.preconditions.missing_kind_count(),
8236 "EphemeralSpec::missing_precondition_kind_count must delegate verbatim to \
8237 preconditions.missing_kind_count() for pre={pre_kind:?} post={post_kind:?}",
8238 );
8239 assert_eq!(
8240 spec.missing_precondition_kind_count(),
8241 spec.missing_precondition_kinds().len(),
8242 "EphemeralSpec::missing_precondition_kind_count must equal \
8243 missing_precondition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
8244 );
8245 assert_eq!(
8246 spec.missing_postcondition_kind_count(),
8247 spec.postconditions.missing_kind_count(),
8248 "EphemeralSpec::missing_postcondition_kind_count must delegate verbatim to \
8249 postconditions.missing_kind_count() for pre={pre_kind:?} post={post_kind:?}",
8250 );
8251 assert_eq!(
8252 spec.missing_postcondition_kind_count(),
8253 spec.missing_postcondition_kinds().len(),
8254 "EphemeralSpec::missing_postcondition_kind_count must equal \
8255 missing_postcondition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
8256 );
8257 // Union arm equals missing_condition_kinds().len().
8258 assert_eq!(
8259 spec.missing_condition_kind_count(),
8260 spec.missing_condition_kinds().len(),
8261 "EphemeralSpec::missing_condition_kind_count must equal \
8262 missing_condition_kinds().len() for pre={pre_kind:?} post={post_kind:?}",
8263 );
8264 // Scalar-partition invariant: distinct + missing == ALL.
8265 assert_eq!(
8266 spec.distinct_condition_kind_count() + spec.missing_condition_kind_count(),
8267 ConditionKind::ALL.len(),
8268 "EphemeralSpec (distinct, missing) scalar partition drift for pre={pre_kind:?} post={post_kind:?}",
8269 );
8270 }
8271 }
8272 }
8273
8274 /// SUBSTRATE-DELEGATION pin (EphemeralSpec first-distinct-kind
8275 /// triad) — the three `first_distinct_*_kind` methods on
8276 /// [`EphemeralSpec`] delegate to the slice-level substrate primitive
8277 /// [`crate::boundary::ConditionSliceExt::first_distinct_kind`] over
8278 /// the two `Vec<Condition>` slots and compose the union via
8279 /// `ConditionKind::ALL.iter().copied().find(|k|
8280 /// has_condition_kind(*k))`. Byte-for-byte peer of
8281 /// `first_distinct_condition_kind_triad_delegates_to_slice_first_distinct_kind`
8282 /// on the point-domain [`crate::boundary::Boundary`] surface — both
8283 /// peers compose against the SAME slice-level substrate primitive
8284 /// so a regression at the per-slice short-circuit walk fails at
8285 /// that primitive's tests rather than as silent drift at either
8286 /// struct-level earliest-element arm.
8287 #[test]
8288 fn ephemeral_first_distinct_condition_kind_triad_delegates_to_slice_first_distinct_kind() {
8289 // Empty ephemeral spec — every arm returns None.
8290 let empty = empty_ephemeral();
8291 assert_eq!(
8292 empty.first_distinct_precondition_kind(),
8293 None,
8294 "empty ephemeral spec must return None on first_distinct_precondition_kind",
8295 );
8296 assert_eq!(
8297 empty.first_distinct_postcondition_kind(),
8298 None,
8299 "empty ephemeral spec must return None on first_distinct_postcondition_kind",
8300 );
8301 assert_eq!(
8302 empty.first_distinct_condition_kind(),
8303 None,
8304 "empty ephemeral spec must return None on first_distinct_condition_kind",
8305 );
8306
8307 for pre_kind in ConditionKind::ALL {
8308 for post_kind in ConditionKind::ALL {
8309 let mut spec = empty_ephemeral();
8310 spec.preconditions.push(cond(pre_kind));
8311 spec.postconditions.push(cond(post_kind));
8312
8313 assert_eq!(
8314 spec.first_distinct_precondition_kind(),
8315 spec.preconditions.first_distinct_kind(),
8316 "EphemeralSpec::first_distinct_precondition_kind must delegate verbatim to \
8317 preconditions.first_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
8318 );
8319 assert_eq!(
8320 spec.first_distinct_precondition_kind(),
8321 spec.distinct_precondition_kinds().first().copied(),
8322 "EphemeralSpec::first_distinct_precondition_kind must equal \
8323 distinct_precondition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8324 );
8325 assert_eq!(
8326 spec.first_distinct_postcondition_kind(),
8327 spec.postconditions.first_distinct_kind(),
8328 "EphemeralSpec::first_distinct_postcondition_kind must delegate verbatim to \
8329 postconditions.first_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
8330 );
8331 assert_eq!(
8332 spec.first_distinct_postcondition_kind(),
8333 spec.distinct_postcondition_kinds().first().copied(),
8334 "EphemeralSpec::first_distinct_postcondition_kind must equal \
8335 distinct_postcondition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8336 );
8337 let expected_union = ConditionKind::ALL
8338 .into_iter()
8339 .find(|k| pre_kind == *k || post_kind == *k);
8340 assert_eq!(
8341 spec.first_distinct_condition_kind(),
8342 expected_union,
8343 "EphemeralSpec::first_distinct_condition_kind must equal earliest ALL entry \
8344 populated by either half-slice for pre={pre_kind:?} post={post_kind:?}",
8345 );
8346 assert_eq!(
8347 spec.first_distinct_condition_kind(),
8348 spec.distinct_condition_kinds().first().copied(),
8349 "EphemeralSpec::first_distinct_condition_kind must equal \
8350 distinct_condition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8351 );
8352 }
8353 }
8354 }
8355
8356 /// SUBSTRATE-DELEGATION pin (EphemeralSpec first-missing-kind triad)
8357 /// — the three `first_missing_*_kind` methods on [`EphemeralSpec`]
8358 /// delegate to the slice-level substrate primitive
8359 /// [`crate::boundary::ConditionSliceExt::first_missing_kind`] over
8360 /// the two `Vec<Condition>` slots and compose the union via
8361 /// `ConditionKind::ALL.iter().copied().find(|k|
8362 /// !has_condition_kind(*k))`. Byte-for-byte peer of
8363 /// `first_missing_condition_kind_triad_delegates_to_slice_first_missing_kind`
8364 /// on the point-domain [`crate::boundary::Boundary`] surface.
8365 #[test]
8366 fn ephemeral_first_missing_condition_kind_triad_delegates_to_slice_first_missing_kind() {
8367 // Empty ephemeral spec — every arm returns Some(ConditionKind::ALL[0]).
8368 let empty = empty_ephemeral();
8369 let first = Some(ConditionKind::ALL[0]);
8370 assert_eq!(
8371 empty.first_missing_precondition_kind(),
8372 first,
8373 "empty ephemeral spec must return Some(ConditionKind::ALL[0]) on first_missing_precondition_kind",
8374 );
8375 assert_eq!(
8376 empty.first_missing_postcondition_kind(),
8377 first,
8378 "empty ephemeral spec must return Some(ConditionKind::ALL[0]) on first_missing_postcondition_kind",
8379 );
8380 assert_eq!(
8381 empty.first_missing_condition_kind(),
8382 first,
8383 "empty ephemeral spec must return Some(ConditionKind::ALL[0]) on first_missing_condition_kind",
8384 );
8385
8386 for pre_kind in ConditionKind::ALL {
8387 for post_kind in ConditionKind::ALL {
8388 let mut spec = empty_ephemeral();
8389 spec.preconditions.push(cond(pre_kind));
8390 spec.postconditions.push(cond(post_kind));
8391
8392 assert_eq!(
8393 spec.first_missing_precondition_kind(),
8394 spec.preconditions.first_missing_kind(),
8395 "EphemeralSpec::first_missing_precondition_kind must delegate verbatim to \
8396 preconditions.first_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
8397 );
8398 assert_eq!(
8399 spec.first_missing_precondition_kind(),
8400 spec.missing_precondition_kinds().first().copied(),
8401 "EphemeralSpec::first_missing_precondition_kind must equal \
8402 missing_precondition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8403 );
8404 assert_eq!(
8405 spec.first_missing_postcondition_kind(),
8406 spec.postconditions.first_missing_kind(),
8407 "EphemeralSpec::first_missing_postcondition_kind must delegate verbatim to \
8408 postconditions.first_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
8409 );
8410 assert_eq!(
8411 spec.first_missing_postcondition_kind(),
8412 spec.missing_postcondition_kinds().first().copied(),
8413 "EphemeralSpec::first_missing_postcondition_kind must equal \
8414 missing_postcondition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8415 );
8416 let expected_union = ConditionKind::ALL
8417 .into_iter()
8418 .find(|k| pre_kind != *k && post_kind != *k);
8419 assert_eq!(
8420 spec.first_missing_condition_kind(),
8421 expected_union,
8422 "EphemeralSpec::first_missing_condition_kind must equal earliest ALL entry \
8423 NOT populated by either half-slice for pre={pre_kind:?} post={post_kind:?}",
8424 );
8425 assert_eq!(
8426 spec.first_missing_condition_kind(),
8427 spec.missing_condition_kinds().first().copied(),
8428 "EphemeralSpec::first_missing_condition_kind must equal \
8429 missing_condition_kinds().first().copied() for pre={pre_kind:?} post={post_kind:?}",
8430 );
8431 }
8432 }
8433 }
8434
8435 /// SUBSTRATE-DELEGATION pin (EphemeralSpec last-distinct-kind
8436 /// triad) — the three `last_distinct_*_kind` methods on
8437 /// [`EphemeralSpec`] delegate to the slice-level substrate
8438 /// primitive [`crate::boundary::ConditionSliceExt::last_distinct_kind`]
8439 /// over the two `Vec<Condition>` slots and compose the union via
8440 /// `ConditionKind::ALL.iter().rev().copied().find(|k|
8441 /// has_condition_kind(*k))`. Byte-for-byte peer of
8442 /// `last_distinct_condition_kind_triad_delegates_to_slice_last_distinct_kind`
8443 /// on the point-domain [`crate::boundary::Boundary`] surface —
8444 /// both peers compose against the SAME slice-level substrate
8445 /// primitive so a regression at the per-slice REVERSED short-
8446 /// circuit walk fails at that primitive's tests rather than as
8447 /// silent drift at either struct-level latest-element arm.
8448 #[test]
8449 fn ephemeral_last_distinct_condition_kind_triad_delegates_to_slice_last_distinct_kind() {
8450 // Empty ephemeral spec — every arm returns None.
8451 let empty = empty_ephemeral();
8452 assert_eq!(
8453 empty.last_distinct_precondition_kind(),
8454 None,
8455 "empty ephemeral spec must return None on last_distinct_precondition_kind",
8456 );
8457 assert_eq!(
8458 empty.last_distinct_postcondition_kind(),
8459 None,
8460 "empty ephemeral spec must return None on last_distinct_postcondition_kind",
8461 );
8462 assert_eq!(
8463 empty.last_distinct_condition_kind(),
8464 None,
8465 "empty ephemeral spec must return None on last_distinct_condition_kind",
8466 );
8467
8468 for pre_kind in ConditionKind::ALL {
8469 for post_kind in ConditionKind::ALL {
8470 let mut spec = empty_ephemeral();
8471 spec.preconditions.push(cond(pre_kind));
8472 spec.postconditions.push(cond(post_kind));
8473
8474 assert_eq!(
8475 spec.last_distinct_precondition_kind(),
8476 spec.preconditions.last_distinct_kind(),
8477 "EphemeralSpec::last_distinct_precondition_kind must delegate verbatim to \
8478 preconditions.last_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
8479 );
8480 assert_eq!(
8481 spec.last_distinct_precondition_kind(),
8482 spec.distinct_precondition_kinds().last().copied(),
8483 "EphemeralSpec::last_distinct_precondition_kind must equal \
8484 distinct_precondition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8485 );
8486 assert_eq!(
8487 spec.last_distinct_postcondition_kind(),
8488 spec.postconditions.last_distinct_kind(),
8489 "EphemeralSpec::last_distinct_postcondition_kind must delegate verbatim to \
8490 postconditions.last_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
8491 );
8492 assert_eq!(
8493 spec.last_distinct_postcondition_kind(),
8494 spec.distinct_postcondition_kinds().last().copied(),
8495 "EphemeralSpec::last_distinct_postcondition_kind must equal \
8496 distinct_postcondition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8497 );
8498 let expected_union = ConditionKind::ALL
8499 .into_iter()
8500 .rev()
8501 .find(|k| pre_kind == *k || post_kind == *k);
8502 assert_eq!(
8503 spec.last_distinct_condition_kind(),
8504 expected_union,
8505 "EphemeralSpec::last_distinct_condition_kind must equal latest ALL entry \
8506 populated by either half-slice for pre={pre_kind:?} post={post_kind:?}",
8507 );
8508 assert_eq!(
8509 spec.last_distinct_condition_kind(),
8510 spec.distinct_condition_kinds().last().copied(),
8511 "EphemeralSpec::last_distinct_condition_kind must equal \
8512 distinct_condition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8513 );
8514 }
8515 }
8516 }
8517
8518 /// SUBSTRATE-DELEGATION pin (EphemeralSpec last-missing-kind triad)
8519 /// — the three `last_missing_*_kind` methods on [`EphemeralSpec`]
8520 /// delegate to the slice-level substrate primitive
8521 /// [`crate::boundary::ConditionSliceExt::last_missing_kind`] over
8522 /// the two `Vec<Condition>` slots and compose the union via
8523 /// `ConditionKind::ALL.iter().rev().copied().find(|k|
8524 /// !has_condition_kind(*k))`. Byte-for-byte peer of
8525 /// `last_missing_condition_kind_triad_delegates_to_slice_last_missing_kind`
8526 /// on the point-domain [`crate::boundary::Boundary`] surface.
8527 #[test]
8528 fn ephemeral_last_missing_condition_kind_triad_delegates_to_slice_last_missing_kind() {
8529 // Empty ephemeral spec — every arm returns Some(*ConditionKind::ALL.last().unwrap()).
8530 let empty = empty_ephemeral();
8531 let last = ConditionKind::ALL.last().copied();
8532 assert_eq!(
8533 empty.last_missing_precondition_kind(),
8534 last,
8535 "empty ephemeral spec must return Some(*ConditionKind::ALL.last().unwrap()) on last_missing_precondition_kind",
8536 );
8537 assert_eq!(
8538 empty.last_missing_postcondition_kind(),
8539 last,
8540 "empty ephemeral spec must return Some(*ConditionKind::ALL.last().unwrap()) on last_missing_postcondition_kind",
8541 );
8542 assert_eq!(
8543 empty.last_missing_condition_kind(),
8544 last,
8545 "empty ephemeral spec must return Some(*ConditionKind::ALL.last().unwrap()) on last_missing_condition_kind",
8546 );
8547
8548 for pre_kind in ConditionKind::ALL {
8549 for post_kind in ConditionKind::ALL {
8550 let mut spec = empty_ephemeral();
8551 spec.preconditions.push(cond(pre_kind));
8552 spec.postconditions.push(cond(post_kind));
8553
8554 assert_eq!(
8555 spec.last_missing_precondition_kind(),
8556 spec.preconditions.last_missing_kind(),
8557 "EphemeralSpec::last_missing_precondition_kind must delegate verbatim to \
8558 preconditions.last_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
8559 );
8560 assert_eq!(
8561 spec.last_missing_precondition_kind(),
8562 spec.missing_precondition_kinds().last().copied(),
8563 "EphemeralSpec::last_missing_precondition_kind must equal \
8564 missing_precondition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8565 );
8566 assert_eq!(
8567 spec.last_missing_postcondition_kind(),
8568 spec.postconditions.last_missing_kind(),
8569 "EphemeralSpec::last_missing_postcondition_kind must delegate verbatim to \
8570 postconditions.last_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
8571 );
8572 assert_eq!(
8573 spec.last_missing_postcondition_kind(),
8574 spec.missing_postcondition_kinds().last().copied(),
8575 "EphemeralSpec::last_missing_postcondition_kind must equal \
8576 missing_postcondition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8577 );
8578 let expected_union = ConditionKind::ALL
8579 .into_iter()
8580 .rev()
8581 .find(|k| pre_kind != *k && post_kind != *k);
8582 assert_eq!(
8583 spec.last_missing_condition_kind(),
8584 expected_union,
8585 "EphemeralSpec::last_missing_condition_kind must equal latest ALL entry \
8586 NOT populated by either half-slice for pre={pre_kind:?} post={post_kind:?}",
8587 );
8588 assert_eq!(
8589 spec.last_missing_condition_kind(),
8590 spec.missing_condition_kinds().last().copied(),
8591 "EphemeralSpec::last_missing_condition_kind must equal \
8592 missing_condition_kinds().last().copied() for pre={pre_kind:?} post={post_kind:?}",
8593 );
8594 }
8595 }
8596 }
8597
8598 // ── assert_slice_refinement_composition_laws — mirror invocations ──
8599 //
8600 // The substrate testkit primitive
8601 // [`crate::boundary::assert_slice_refinement_composition_laws`]
8602 // pins the FOUR composition laws that bind the
8603 // [`crate::boundary::ConditionSliceExt`] refinement algebra
8604 // (find ↔ iter, count ↔ iter, has ↔ find, has ↔ count) at ONE
8605 // call site per authored arrangement, sweeping
8606 // [`ConditionKind::ALL`]. The two ephemeral-surface tests below
8607 // dispatch the primitive against the two `Vec<Condition>` slots
8608 // ([`EphemeralSpec::preconditions`] +
8609 // [`EphemeralSpec::postconditions`]) authored through the
8610 // ephemeral-surface test-fixture — byte-for-byte peer of the
8611 // point-surface `slice_refinement_composition_laws_hold_across_authored_arrangements`
8612 // + `slice_refinement_composition_laws_hold_on_interleaved_duplicates`
8613 // pins on the [`crate::boundary::Boundary`] surface. Two-surface
8614 // parity contract: the substrate primitive holds on every slice
8615 // reachable through either the point-surface `.preconditions` /
8616 // `.postconditions` fields OR the ephemeral-surface's
8617 // eponymous field pair.
8618
8619 /// SUBSTRATE PANEL pin (ephemeral surface) — the substrate
8620 /// primitive [`assert_slice_refinement_composition_laws`] holds
8621 /// on both [`EphemeralSpec::preconditions`] and
8622 /// [`EphemeralSpec::postconditions`] slices for every populated-
8623 /// pair authored through the ephemeral-surface test-fixture.
8624 /// Byte-for-byte peer of
8625 /// `slice_refinement_composition_laws_hold_across_authored_arrangements`
8626 /// on the point surface.
8627 #[test]
8628 fn ephemeral_slice_refinement_composition_laws_hold_across_authored_arrangements() {
8629 let empty = empty_ephemeral();
8630 assert_slice_refinement_composition_laws(empty.preconditions.as_slice());
8631 assert_slice_refinement_composition_laws(empty.postconditions.as_slice());
8632
8633 for pre_kind in ConditionKind::ALL {
8634 for post_kind in ConditionKind::ALL {
8635 let mut spec = empty_ephemeral();
8636 spec.preconditions.push(cond(pre_kind));
8637 spec.postconditions.push(cond(post_kind));
8638 assert_slice_refinement_composition_laws(spec.preconditions.as_slice());
8639 assert_slice_refinement_composition_laws(spec.postconditions.as_slice());
8640 }
8641 }
8642
8643 for populated in ConditionKind::ALL {
8644 let mut spec = empty_ephemeral();
8645 spec.preconditions.push(cond(populated));
8646 spec.preconditions.push(cond(populated));
8647 spec.preconditions.push(cond(populated));
8648 spec.postconditions.push(cond(populated));
8649 spec.postconditions.push(cond(populated));
8650 assert_slice_refinement_composition_laws(spec.preconditions.as_slice());
8651 assert_slice_refinement_composition_laws(spec.postconditions.as_slice());
8652 }
8653 }
8654
8655 // ── assert_surface_union_composition_laws — ephemeral surface ────
8656 //
8657 // The substrate testkit macro
8658 // [`crate::assert_surface_union_composition_laws`] pins the FOUR
8659 // union composition laws (has: OR, find: or_else, iter: chain,
8660 // count: SUM) that bind the (pre, post, union) refinement triads
8661 // on the [`EphemeralSpec`] sugar-surface at ONE call site per
8662 // authored arrangement, sweeping [`ConditionKind::ALL`]. Byte-for-
8663 // byte peer of the point-surface
8664 // `boundary_surface_union_composition_laws_hold_across_authored_arrangements`
8665 // / `boundary_surface_union_composition_laws_hold_on_interleaved_duplicates`
8666 // pins on the [`crate::boundary::Boundary`] surface — the two-
8667 // surface parity contract binds every downstream `condition-<K>`
8668 // / `precondition-<K>` / `postcondition-<K>` require-tag classifier
8669 // on either surface to the SAME four union-composition operators
8670 // through ONE substrate primitive rather than through per-surface
8671 // author-time re-authored sweeps.
8672
8673 /// SUBSTRATE PANEL pin (ephemeral surface) — the substrate macro
8674 /// [`crate::assert_surface_union_composition_laws`] passes on
8675 /// [`EphemeralSpec`] for the four canonical authored arrangements
8676 /// (empty spec, precondition-only populated, postcondition-only
8677 /// populated, dual-populated sweep over `ALL × ALL`). Byte-for-byte
8678 /// peer of the point-surface
8679 /// `boundary_surface_union_composition_laws_hold_across_authored_arrangements`
8680 /// pin — the two-surface parity contract binds every union
8681 /// composition law on both surfaces to the SAME substrate
8682 /// primitive.
8683 #[test]
8684 fn ephemeral_surface_union_composition_laws_hold_across_authored_arrangements() {
8685 let empty = empty_ephemeral();
8686 crate::assert_surface_union_composition_laws!(empty);
8687
8688 for populated in ConditionKind::ALL {
8689 let mut pre_only = empty_ephemeral();
8690 pre_only.preconditions.push(cond(populated));
8691 crate::assert_surface_union_composition_laws!(pre_only);
8692
8693 let mut post_only = empty_ephemeral();
8694 post_only.postconditions.push(cond(populated));
8695 crate::assert_surface_union_composition_laws!(post_only);
8696 }
8697
8698 for pre_kind in ConditionKind::ALL {
8699 for post_kind in ConditionKind::ALL {
8700 let mut dual = empty_ephemeral();
8701 dual.preconditions.push(cond(pre_kind));
8702 dual.postconditions.push(cond(post_kind));
8703 crate::assert_surface_union_composition_laws!(dual);
8704 }
8705 }
8706 }
8707
8708 /// SUBSTRATE PANEL pin (ephemeral surface, params-distinguishable
8709 /// duplicates) — the substrate macro holds on an [`EphemeralSpec`]
8710 /// whose two half-slices each carry duplicates of the same kind at
8711 /// multiple positions interleaved with a distinct kind. Byte-for-
8712 /// byte peer of the point-surface
8713 /// `boundary_surface_union_composition_laws_hold_on_interleaved_duplicates`
8714 /// pin — the non-degenerate composition of every union arm on the
8715 /// sugar-surface binds against the SAME four monoid operators as
8716 /// the point-surface peer. A regression on the ephemeral surface
8717 /// only that (a) collapsed `find`'s `or_else` to `and_then`, (b)
8718 /// collapsed `iter`'s `chain` to `zip`, or (c) collapsed `count`'s
8719 /// SUM to `max` surfaces HERE, breaking two-surface parity.
8720 #[test]
8721 fn ephemeral_surface_union_composition_laws_hold_on_interleaved_duplicates() {
8722 let mut spec = empty_ephemeral();
8723 spec.preconditions.push(Condition {
8724 kind: ConditionKind::ClosedLoopAuth,
8725 params: serde_json::json!({ "side": "pre-1" }),
8726 });
8727 spec.preconditions.push(Condition {
8728 kind: ConditionKind::PromQL,
8729 params: serde_json::json!({ "query": "up" }),
8730 });
8731 spec.preconditions.push(Condition {
8732 kind: ConditionKind::ClosedLoopAuth,
8733 params: serde_json::json!({ "side": "pre-2" }),
8734 });
8735 spec.postconditions.push(Condition {
8736 kind: ConditionKind::PromQL,
8737 params: serde_json::json!({ "query": "healthy" }),
8738 });
8739 spec.postconditions.push(Condition {
8740 kind: ConditionKind::ClosedLoopAuth,
8741 params: serde_json::json!({ "side": "post-1" }),
8742 });
8743 crate::assert_surface_union_composition_laws!(spec);
8744 }
8745
8746 #[test]
8747 fn from_impl_clears_other_intent_variants() {
8748 // Even if someone constructs an EphemeralSpec by hand and the
8749 // resulting ProcessSpec is later mutated, the From bridge sets
8750 // every non-Aplicacao slot to None explicitly.
8751 let e = EphemeralSpec {
8752 aplicacao: demo_overlay(),
8753 ttl: "10m".into(),
8754 teardown: TeardownPolicy::Never,
8755 max_concurrent: 0,
8756 postconditions: vec![],
8757 preconditions: vec![],
8758 verify_timeout: None,
8759 classification: None,
8760 parent: Some("seph.1".into()),
8761 exports: vec![],
8762 routing: None,
8763 };
8764 let ps: ProcessSpec = e.into();
8765 assert!(ps.intent.nix.is_none());
8766 assert!(ps.intent.flux.is_none());
8767 assert!(ps.intent.lisp.is_none());
8768 assert!(ps.intent.container.is_none());
8769 assert!(ps.intent.guest.is_none());
8770 assert!(ps.intent.aplicacao.is_some());
8771 assert_eq!(ps.identity.parent.as_deref(), Some("seph.1"));
8772 }
8773
8774 // ── EphemeralSpec::has_teardown_policy substrate pins ────────────
8775 //
8776 // Fail-before-pass-after granularity:
8777 // `EphemeralSpec::has_teardown_policy` did not exist before this
8778 // commit — the (`self.teardown == kind`) scalar-carrier probe on
8779 // the sugar-surface [`EphemeralSpec`] lived only implicitly via
8780 // hand-authored comparisons at potential future call sites, with
8781 // no analogue to the peer
8782 // [`crate::lifetime::EphemeralLifetime::has_teardown_policy`] on
8783 // the point-surface carrier. The lift adds the peer inherent
8784 // method on the [`EphemeralSpec`] sugar-surface so both surfaces'
8785 // `teardown-policy-<kind>` require-tag families in
8786 // `tatara-reconciler::bin::tatara-check` compose against the SAME
8787 // scalar `==` shape in lockstep. A regression that (a) hard-coded
8788 // the arm to a single kind, (b) inverted the closed-set match
8789 // (silently returning `true` on non-matching variants), or (c)
8790 // probed the wrong slot (a stray comparison against `ttl` /
8791 // `max_concurrent`) fails HERE at the substrate primitive rather
8792 // than as silent operator-facing drift at the ephemeral
8793 // `teardown-policy-<kind>` require-tag surface.
8794
8795 /// STORED-slot pin — an ephemeral spec that carries a given
8796 /// [`TeardownPolicy`] returns `true` for that kind, `false` for
8797 /// every other variant. Sweep the [`TeardownPolicy::ALL`] × ALL
8798 /// cross so a regression that hard-coded the arm to a single kind
8799 /// or wired the closure to a fixed unrelated field fails HERE at
8800 /// the substrate primitive. Byte-for-byte peer of
8801 /// [`crate::lifetime::tests::ephemeral_lifetime_has_teardown_policy_returns_true_iff_variant_matches`]
8802 /// on the point-surface [`crate::lifetime::EphemeralLifetime`]
8803 /// carrier — the two surfaces publish identical `==` scalar
8804 /// semantics on their respective `teardown` / `teardown_policy`
8805 /// slots.
8806 #[test]
8807 fn has_teardown_policy_returns_true_iff_ephemeral_teardown_matches_per_kind() {
8808 for populated in TeardownPolicy::ALL {
8809 let mut spec = empty_ephemeral();
8810 spec.teardown = populated;
8811 for query in TeardownPolicy::ALL {
8812 let expected = query == populated;
8813 assert_eq!(
8814 spec.has_teardown_policy(query),
8815 expected,
8816 "ephemeral teardown={populated:?}: query {query:?} drifted",
8817 );
8818 }
8819 }
8820 }
8821
8822 /// DEFAULT-SLOT pin — an [`EphemeralSpec`] whose `teardown` slot
8823 /// is [`TeardownPolicy::default`] (`Always`) returns `true` for
8824 /// `Always` and `false` for every other variant. The
8825 /// (required-scalar-child) corner has no absent state — a
8826 /// hand-authored spec that omits `:teardown` from the
8827 /// `(defephemeral …)` form IS configured for `Always`, and this
8828 /// pin locks the corner's default-arm short-circuit as identical
8829 /// to the (Option-parent × defaulted-scalar-child) corner's
8830 /// reachable arm on the point surface (both return `true` on
8831 /// `Always` only). Byte-for-byte peer of
8832 /// [`crate::lifetime::tests::ephemeral_lifetime_has_teardown_policy_default_probes_always_only`]
8833 /// on the point-surface carrier.
8834 #[test]
8835 fn has_teardown_policy_default_probes_always_only_on_ephemeral() {
8836 let spec = EphemeralSpec {
8837 teardown: TeardownPolicy::default(),
8838 ..empty_ephemeral()
8839 };
8840 for kind in TeardownPolicy::ALL {
8841 let expected = kind == TeardownPolicy::Always;
8842 assert_eq!(
8843 spec.has_teardown_policy(kind),
8844 expected,
8845 "default ephemeral (teardown=Always) baseline: query {kind:?} must be {expected}",
8846 );
8847 }
8848 }
8849
8850 // ── derived-bool-predicate presence probe on EphemeralSpec ×
8851 // TeardownPolicy × ProcessPhase ──
8852 //
8853 // Fail-before-pass-after granularity:
8854 // [`EphemeralSpec::has_teardown_firing_on`] did not exist before
8855 // this commit — the ephemeral sugar surface's require-tag algebra
8856 // discriminated the teardown axis only by the RAW authored variant
8857 // (via `teardown-policy-<kind>`), never by the derived
8858 // [`ProcessPhase`] transition the stored policy fires on
8859 // ([`TeardownPolicy::should_teardown_on`]). Post-lift the shape
8860 // lives at ONE inherent method that byte-for-byte parallels
8861 // [`crate::lifetime::EphemeralLifetime::has_teardown_firing_on`]
8862 // on the point-surface carrier, and both surfaces' require-tag
8863 // classifiers publish a symmetric `teardown-fires-on-<phase>`
8864 // family through the SAME predicate.
8865
8866 /// TRUTH-TABLE DIAGONAL — for every [`TeardownPolicy`] variant,
8867 /// an [`EphemeralSpec`] whose `teardown` slot is set to that
8868 /// variant returns `has_teardown_firing_on(phase)` in agreement
8869 /// with [`TeardownPolicy::should_teardown_on`] for every
8870 /// [`ProcessPhase`] variant. Sweep [`TeardownPolicy::ALL`] ×
8871 /// [`ProcessPhase::ALL`] full cross so a regression that hard-
8872 /// coded the arm to a single policy, wired to the wrong field, or
8873 /// inverted the predicate direction fails HERE at the substrate
8874 /// primitive on the sugar surface (byte-for-byte peer of
8875 /// [`crate::lifetime::tests::ephemeral_lifetime_has_teardown_firing_on_matches_should_teardown_on_per_policy_per_phase`]
8876 /// on the point carrier).
8877 #[test]
8878 fn has_teardown_firing_on_matches_should_teardown_on_per_policy_per_phase_on_ephemeral() {
8879 for populated in TeardownPolicy::ALL {
8880 let spec = EphemeralSpec {
8881 teardown: populated,
8882 ..empty_ephemeral()
8883 };
8884 for phase in ProcessPhase::ALL {
8885 assert_eq!(
8886 spec.has_teardown_firing_on(phase),
8887 populated.should_teardown_on(phase),
8888 "teardown={populated:?}, phase={phase:?}: predicate drift from \
8889 should_teardown_on projection",
8890 );
8891 }
8892 }
8893 }
8894
8895 /// TWO-SURFACE PARITY PIN — for every [`TeardownPolicy`] variant
8896 /// and every [`ProcessPhase`] variant, the sugar-surface probe
8897 /// and the lowered point-surface probe agree. The `EphemeralSpec
8898 /// → ProcessSpec` lowering routes the stored `teardown` slot
8899 /// through the SAME [`TeardownPolicy::should_teardown_on`]
8900 /// projection on both sides, so the sugar caller and the lowered
8901 /// caller can never disagree — a regression that (a) drifted
8902 /// [`Self::teardown`] between sugar and lowered, (b) rewired
8903 /// either probe body to bypass the shared substrate primitive, or
8904 /// (c) skewed the (policy, phase) truth table between the two
8905 /// surfaces fails HERE at the two-surface boundary rather than at
8906 /// the operator-facing require-tag classifier.
8907 #[test]
8908 fn has_teardown_firing_on_matches_point_peer_through_lowered_teardown_policy() {
8909 for populated in TeardownPolicy::ALL {
8910 let sugar = EphemeralSpec {
8911 teardown: populated,
8912 ..empty_ephemeral()
8913 };
8914 let lowered: ProcessSpec = sugar.clone().into();
8915 let lowered_eph = lowered
8916 .lifetime
8917 .resolved_ephemeral()
8918 .expect("lowered spec must be ephemeral");
8919 for phase in ProcessPhase::ALL {
8920 assert_eq!(
8921 sugar.has_teardown_firing_on(phase),
8922 lowered_eph.has_teardown_firing_on(phase),
8923 "sugar-vs-lowered predicate drift for teardown={populated:?}, phase={phase:?}",
8924 );
8925 }
8926 }
8927 }
8928
8929 // ── EphemeralSpec::resolved_classification + has_point_type pins ─────
8930 //
8931 // Fail-before-pass-after granularity: `resolved_classification` and
8932 // `has_point_type` did not exist pre-lift on `impl EphemeralSpec` — every
8933 // caller wanting the resolved [`Classification`] on the ephemeral
8934 // sugar-surface (currently zero; future ephemeral-surface classification-
8935 // axis require-tag families in `tatara-reconciler::bin::tatara-check`,
8936 // typed audit hooks, documentation generators listing the ephemeral
8937 // surface's known require-tag vocabulary) restated the two-line
8938 // `self.classification.as_ref().unwrap_or(&default_ephemeral_class())`
8939 // resolver body at their site. Post-lift both callers of the resolver
8940 // (`Self::has_point_type` and every future classification-axis peer)
8941 // route through ONE inherent method that shares the fill-through with
8942 // the sibling `From<EphemeralSpec> for ProcessSpec` lowering
8943 // byte-for-byte. A regression that (a) inverted the arm (`Some` filled
8944 // through the default), (b) drifted the default from the sibling
8945 // primitive `Classification::gate_compute()`, or (c) shifted the
8946 // `Cow<'_, Classification>` return shape (a stray `.clone()` on the
8947 // populated arm) fails HERE at the substrate primitive rather than as
8948 // silent operator-facing drift at a future
8949 // `point-type-<kind>` ephemeral require-tag surface.
8950
8951 /// AUTHORED-slot pin — an [`EphemeralSpec`] whose
8952 /// [`EphemeralSpec::classification`] slot names a concrete
8953 /// [`Classification`] returns [`Cow::Borrowed`] pointing at that
8954 /// authored value from [`Self::resolved_classification`]. Pins the
8955 /// populated-arm zero-allocation contract: a caller reading past
8956 /// the resolver sees the SAME byte address the operator authored,
8957 /// so the resolver does not silently clone the authored slot on
8958 /// the populated arm.
8959 #[test]
8960 fn resolved_classification_borrows_authored_slot() {
8961 let mut spec = empty_ephemeral();
8962 let mut authored = Classification::gate_compute();
8963 authored.point_type = ConvergencePointType::Fork;
8964 spec.classification = Some(authored.clone());
8965 let resolved = spec.resolved_classification();
8966 assert!(matches!(resolved, Cow::Borrowed(_)));
8967 assert_eq!(&*resolved, &authored);
8968 }
8969
8970 /// ABSENT-slot pin — an [`EphemeralSpec`] whose
8971 /// [`EphemeralSpec::classification`] slot is `None` returns
8972 /// [`Cow::Owned`] with the SAME value the sibling
8973 /// [`default_ephemeral_class`] baseline produces. Pins the
8974 /// two-surface parity contract with `From<EphemeralSpec> for
8975 /// ProcessSpec`: both sites fill through the SAME baseline on
8976 /// `None`, so the ephemeral require-tag surface's future
8977 /// `point-type-<kind>` family reads identically on the authored
8978 /// spec and on the mechanically lowered `ProcessSpec`.
8979 #[test]
8980 fn resolved_classification_fills_default_on_absent_slot() {
8981 let spec = empty_ephemeral();
8982 assert!(spec.classification.is_none());
8983 let resolved = spec.resolved_classification();
8984 assert!(matches!(resolved, Cow::Owned(_)));
8985 assert_eq!(&*resolved, &default_ephemeral_class());
8986 }
8987
8988 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
8989 /// [`EphemeralSpec::classification`] slot names a concrete
8990 /// [`Classification`] returns `true` from
8991 /// [`Self::has_point_type`] on the authored
8992 /// [`ConvergencePointType`] slot and `false` for every other
8993 /// variant. Sweep the [`ConvergencePointType::ALL`] × ALL cross so
8994 /// a regression that hard-coded the arm to a single kind or wired
8995 /// the closure to a fixed unrelated slot fails HERE at the
8996 /// substrate primitive. Byte-for-byte peer of
8997 /// [`crate::classification::tests`]'s point-surface
8998 /// [`Classification::has_point_type`] populated-slot sweep on the
8999 /// SAME closed-set primitive.
9000 #[test]
9001 fn has_point_type_returns_true_iff_authored_classification_matches_per_kind() {
9002 for populated in ConvergencePointType::ALL {
9003 let mut classification = Classification::gate_compute();
9004 classification.point_type = populated;
9005 let mut spec = empty_ephemeral();
9006 spec.classification = Some(classification);
9007 for query in ConvergencePointType::ALL {
9008 let expected = query == populated;
9009 assert_eq!(
9010 spec.has_point_type(query),
9011 expected,
9012 "ephemeral classification.point_type={populated:?}: query {query:?} drifted",
9013 );
9014 }
9015 }
9016 }
9017
9018 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9019 /// [`EphemeralSpec::classification`] slot is `None` returns
9020 /// `true` from [`Self::has_point_type`] on
9021 /// [`ConvergencePointType::Gate`] (the `default_ephemeral_class`
9022 /// baseline's `point_type`) and `false` on every other variant.
9023 /// Pins the (Option-parent × NON-DEFAULT-scalar-child) corner's
9024 /// default-arm short-circuit: on the ephemeral sugar surface the
9025 /// parent Option is filled through the workspace baseline rather
9026 /// than reading `false` on every variant like the encapsulation-
9027 /// mode / encapsulation-target / routing-form Option-parent
9028 /// corners.
9029 #[test]
9030 fn has_point_type_probes_gate_only_on_absent_classification() {
9031 let spec = empty_ephemeral();
9032 assert!(spec.classification.is_none());
9033 for kind in ConvergencePointType::ALL {
9034 let expected = kind == ConvergencePointType::Gate;
9035 assert_eq!(
9036 spec.has_point_type(kind),
9037 expected,
9038 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9039 );
9040 }
9041 }
9042
9043 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9044 /// identically through [`Self::has_point_type`] AND through
9045 /// `<eph.clone().into::<ProcessSpec>>()`
9046 /// `.classification.has_point_type(kind)` on the mechanically-
9047 /// lowered `ProcessSpec`. Sweeps (`None` classification, `Some(_)`
9048 /// classification on every [`ConvergencePointType::ALL`] variant)
9049 /// × ALL queries so a future regression on either side of the
9050 /// resolver (a shift in the ephemeral resolver's default, a
9051 /// shift in the `From<EphemeralSpec>` lowering's fill-through)
9052 /// fails HERE at the parity boundary.
9053 #[test]
9054 fn has_point_type_matches_point_peer_through_lowered_classification() {
9055 // Absent classification: both surfaces resolve through the SAME
9056 // default and agree on every variant.
9057 let eph = empty_ephemeral();
9058 let lowered: ProcessSpec = eph.clone().into();
9059 for query in ConvergencePointType::ALL {
9060 assert_eq!(
9061 eph.has_point_type(query),
9062 lowered.classification.has_point_type(query),
9063 "None-classification parity drift on query {query:?}",
9064 );
9065 }
9066 // Authored classification: both surfaces read the same authored
9067 // value verbatim.
9068 for populated in ConvergencePointType::ALL {
9069 let mut classification = Classification::gate_compute();
9070 classification.point_type = populated;
9071 let mut eph = empty_ephemeral();
9072 eph.classification = Some(classification);
9073 let lowered: ProcessSpec = eph.clone().into();
9074 for query in ConvergencePointType::ALL {
9075 assert_eq!(
9076 eph.has_point_type(query),
9077 lowered.classification.has_point_type(query),
9078 "authored classification.point_type={populated:?}: parity drift on query {query:?}",
9079 );
9080 }
9081 }
9082 }
9083
9084 // ── EphemeralSpec::has_substrate pins ────────────────────────────
9085 //
9086 // Fail-before-pass-after granularity: [`Self::has_substrate`] did
9087 // not exist pre-lift on `impl EphemeralSpec` — every callsite went
9088 // through `.resolved_classification().substrate == kind` or through
9089 // the lowered `ProcessSpec`'s `spec.classification.has_substrate`.
9090 // Post-lift the SECOND classification-axis peer on the ephemeral
9091 // sugar surface routes through the SAME
9092 // [`Self::resolved_classification`] resolver + the sibling closed-
9093 // set primitive [`Classification::has_substrate`], so a regression
9094 // that dropped the resolver hop, inverted the `Some`/`None`
9095 // fill-through, or wired the closure to a fixed unrelated slot
9096 // fails HERE.
9097
9098 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
9099 /// [`EphemeralSpec::classification`] slot names a concrete
9100 /// [`Classification`] returns `true` from
9101 /// [`Self::has_substrate`] on the authored [`SubstrateType`] slot
9102 /// and `false` for every other variant. Sweep the
9103 /// [`SubstrateType::ALL`] × ALL cross so a regression that
9104 /// hard-coded the arm to a single kind or wired the closure to a
9105 /// fixed unrelated slot fails HERE at the substrate primitive.
9106 /// Byte-for-byte peer of the point-surface
9107 /// [`Classification::has_substrate`] populated-slot sweep on the
9108 /// SAME closed-set primitive.
9109 #[test]
9110 fn has_substrate_returns_true_iff_authored_classification_matches_per_kind() {
9111 for populated in SubstrateType::ALL {
9112 let mut classification = Classification::gate_compute();
9113 classification.substrate = populated;
9114 let mut spec = empty_ephemeral();
9115 spec.classification = Some(classification);
9116 for query in SubstrateType::ALL {
9117 let expected = query == populated;
9118 assert_eq!(
9119 spec.has_substrate(query),
9120 expected,
9121 "ephemeral classification.substrate={populated:?}: query {query:?} drifted",
9122 );
9123 }
9124 }
9125 }
9126
9127 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9128 /// [`EphemeralSpec::classification`] slot is `None` returns
9129 /// `true` from [`Self::has_substrate`] on
9130 /// [`SubstrateType::Compute`] (the `default_ephemeral_class`
9131 /// baseline's `substrate`) and `false` on every other variant.
9132 /// Pins the (Option-parent × NON-DEFAULT-scalar-child) corner's
9133 /// default-arm short-circuit on the SECOND classification-axis
9134 /// peer: on the ephemeral sugar surface the parent Option is
9135 /// filled through the workspace baseline rather than reading
9136 /// `false` on every variant like the Option-parent encapsulates /
9137 /// routing corners.
9138 #[test]
9139 fn has_substrate_probes_compute_only_on_absent_classification() {
9140 let spec = empty_ephemeral();
9141 assert!(spec.classification.is_none());
9142 for kind in SubstrateType::ALL {
9143 let expected = kind == SubstrateType::Compute;
9144 assert_eq!(
9145 spec.has_substrate(kind),
9146 expected,
9147 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9148 );
9149 }
9150 }
9151
9152 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9153 /// identically through [`Self::has_substrate`] AND through
9154 /// `<eph.clone().into::<ProcessSpec>>()`
9155 /// `.classification.has_substrate(kind)` on the mechanically-
9156 /// lowered `ProcessSpec`. Sweeps (`None` classification, `Some(_)`
9157 /// classification on every [`SubstrateType::ALL`] variant) × ALL
9158 /// queries so a future regression on either side of the resolver
9159 /// (a shift in the ephemeral resolver's default, a shift in the
9160 /// `From<EphemeralSpec>` lowering's fill-through) fails HERE at
9161 /// the parity boundary. Byte-for-byte peer of the sibling
9162 /// [`Self::has_point_type`] two-surface parity pin on the SAME
9163 /// `Cow`-resolver carrier — the SECOND classification-axis
9164 /// two-surface parity contract on the ephemeral surface.
9165 #[test]
9166 fn has_substrate_matches_point_peer_through_lowered_classification() {
9167 // Absent classification: both surfaces resolve through the SAME
9168 // default and agree on every variant.
9169 let eph = empty_ephemeral();
9170 let lowered: ProcessSpec = eph.clone().into();
9171 for query in SubstrateType::ALL {
9172 assert_eq!(
9173 eph.has_substrate(query),
9174 lowered.classification.has_substrate(query),
9175 "None-classification parity drift on query {query:?}",
9176 );
9177 }
9178 // Authored classification: both surfaces read the same authored
9179 // value verbatim.
9180 for populated in SubstrateType::ALL {
9181 let mut classification = Classification::gate_compute();
9182 classification.substrate = populated;
9183 let mut eph = empty_ephemeral();
9184 eph.classification = Some(classification);
9185 let lowered: ProcessSpec = eph.clone().into();
9186 for query in SubstrateType::ALL {
9187 assert_eq!(
9188 eph.has_substrate(query),
9189 lowered.classification.has_substrate(query),
9190 "authored classification.substrate={populated:?}: parity drift on query {query:?}",
9191 );
9192 }
9193 }
9194 }
9195
9196 // ── EphemeralSpec::has_calm pins ─────────────────────────────────
9197 //
9198 // Fail-before-pass-after granularity: [`Self::has_calm`] did not
9199 // exist pre-lift on `impl EphemeralSpec` — every callsite went
9200 // through `.resolved_classification().calm == kind` or through the
9201 // lowered `ProcessSpec`'s `spec.classification.has_calm`. Post-
9202 // lift the THIRD classification-axis peer on the ephemeral sugar
9203 // surface routes through the SAME
9204 // [`Self::resolved_classification`] resolver + the sibling closed-
9205 // set primitive [`Classification::has_calm`], so a regression that
9206 // dropped the resolver hop, inverted the `Some`/`None` fill-
9207 // through, or wired the closure to a fixed unrelated slot fails
9208 // HERE. Distinct from the FIRST + SECOND peers on the (Option-
9209 // parent × NON-DEFAULT-scalar-child) corner: the (Option-parent ×
9210 // DEFAULTED-scalar-child) corner this peer opens has BOTH the
9211 // parent fill-through baseline (`default_ephemeral_class`) AND the
9212 // child's own `#[default]` land on the SAME variant
9213 // ([`CalmClassification::Monotone`]), a two-defaults composition
9214 // property the three pins below all exercise.
9215
9216 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
9217 /// [`EphemeralSpec::classification`] slot names a concrete
9218 /// [`Classification`] returns `true` from [`Self::has_calm`] on
9219 /// the authored [`CalmClassification`] slot and `false` for every
9220 /// other variant. Sweep the [`CalmClassification::ALL`] × ALL
9221 /// cross so a regression that hard-coded the arm to a single
9222 /// kind or wired the closure to a fixed unrelated slot fails HERE
9223 /// at the substrate primitive. Byte-for-byte peer of the point-
9224 /// surface [`Classification::has_calm`] populated-slot sweep on
9225 /// the SAME closed-set primitive.
9226 #[test]
9227 fn has_calm_returns_true_iff_authored_classification_matches_per_kind() {
9228 for populated in CalmClassification::ALL {
9229 let mut classification = Classification::gate_compute();
9230 classification.calm = populated;
9231 let mut spec = empty_ephemeral();
9232 spec.classification = Some(classification);
9233 for query in CalmClassification::ALL {
9234 let expected = query == populated;
9235 assert_eq!(
9236 spec.has_calm(query),
9237 expected,
9238 "ephemeral classification.calm={populated:?}: query {query:?} drifted",
9239 );
9240 }
9241 }
9242 }
9243
9244 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9245 /// [`EphemeralSpec::classification`] slot is `None` returns
9246 /// `true` from [`Self::has_calm`] on
9247 /// [`CalmClassification::Monotone`] (the `default_ephemeral_class`
9248 /// baseline's `calm` axis AND the [`CalmClassification`] child's
9249 /// own `#[default]` variant) and `false` on every other variant.
9250 /// Pins the (Option-parent × DEFAULTED-scalar-child ×
9251 /// operator-resolvable-baseline) corner's default-arm short-
9252 /// circuit on the THIRD classification-axis peer — distinct from
9253 /// the FIRST + SECOND peers on the (Option-parent × NON-DEFAULT-
9254 /// scalar-child) corner which default through a specific chosen
9255 /// baseline ([`ConvergencePointType::Gate`],
9256 /// [`SubstrateType::Compute`]) rather than through the child's
9257 /// own `#[default]`. Two-defaults composition property: both the
9258 /// parent fill-through and the child's `#[default]` land on the
9259 /// SAME variant, so the ephemeral sugar surface's `calm-Monotone`
9260 /// require-tag reads `true` on every operator-authored spec that
9261 /// omits both the `:classification` slot AND the `:calm` sub-slot,
9262 /// pinning the workspace's monotone-by-default posture.
9263 #[test]
9264 fn has_calm_probes_monotone_only_on_absent_classification() {
9265 let spec = empty_ephemeral();
9266 assert!(spec.classification.is_none());
9267 for kind in CalmClassification::ALL {
9268 let expected = kind == CalmClassification::Monotone;
9269 assert_eq!(
9270 spec.has_calm(kind),
9271 expected,
9272 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9273 );
9274 }
9275 }
9276
9277 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9278 /// identically through [`Self::has_calm`] AND through
9279 /// `<eph.clone().into::<ProcessSpec>>()`
9280 /// `.classification.has_calm(kind)` on the mechanically-
9281 /// lowered `ProcessSpec`. Sweeps (`None` classification, `Some(_)`
9282 /// classification on every [`CalmClassification::ALL`] variant) ×
9283 /// ALL queries so a future regression on either side of the
9284 /// resolver (a shift in the ephemeral resolver's default, a shift
9285 /// in the `From<EphemeralSpec>` lowering's fill-through) fails
9286 /// HERE at the parity boundary. Byte-for-byte peer of the sibling
9287 /// [`Self::has_point_type`] + [`Self::has_substrate`] two-surface
9288 /// parity pins on the SAME `Cow`-resolver carrier — the THIRD
9289 /// classification-axis two-surface parity contract on the
9290 /// ephemeral surface, and the FIRST on the (Option-parent ×
9291 /// DEFAULTED-scalar-child) corner.
9292 #[test]
9293 fn has_calm_matches_point_peer_through_lowered_classification() {
9294 // Absent classification: both surfaces resolve through the SAME
9295 // default and agree on every variant.
9296 let eph = empty_ephemeral();
9297 let lowered: ProcessSpec = eph.clone().into();
9298 for query in CalmClassification::ALL {
9299 assert_eq!(
9300 eph.has_calm(query),
9301 lowered.classification.has_calm(query),
9302 "None-classification parity drift on query {query:?}",
9303 );
9304 }
9305 // Authored classification: both surfaces read the same authored
9306 // value verbatim.
9307 for populated in CalmClassification::ALL {
9308 let mut classification = Classification::gate_compute();
9309 classification.calm = populated;
9310 let mut eph = empty_ephemeral();
9311 eph.classification = Some(classification);
9312 let lowered: ProcessSpec = eph.clone().into();
9313 for query in CalmClassification::ALL {
9314 assert_eq!(
9315 eph.has_calm(query),
9316 lowered.classification.has_calm(query),
9317 "authored classification.calm={populated:?}: parity drift on query {query:?}",
9318 );
9319 }
9320 }
9321 }
9322
9323 // ── EphemeralSpec::has_data_classification pins ──────────────────
9324 //
9325 // Fail-before-pass-after granularity: [`Self::has_data_classification`]
9326 // did not exist pre-lift on `impl EphemeralSpec` — every callsite
9327 // went through `.resolved_classification().data_classification ==
9328 // kind` or through the lowered `ProcessSpec`'s
9329 // `spec.classification.has_data_classification`. Post-lift the
9330 // FOURTH classification-axis peer on the ephemeral sugar surface
9331 // routes through the SAME [`Self::resolved_classification`]
9332 // resolver + the sibling closed-set primitive
9333 // [`crate::classification::Classification::has_data_classification`],
9334 // so a regression that dropped the resolver hop, inverted the
9335 // `Some`/`None` fill-through, or wired the closure to a fixed
9336 // unrelated slot fails HERE. SECOND occupant on the (Option-parent
9337 // × DEFAULTED-scalar-child × operator-resolvable-baseline) corner
9338 // alongside [`Self::has_calm`]: both the parent fill-through
9339 // baseline (`default_ephemeral_class`) AND the child's own
9340 // `#[default]` land on the SAME variant
9341 // ([`DataClassification::Internal`]), a two-defaults composition
9342 // property the three pins below all exercise.
9343
9344 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
9345 /// [`EphemeralSpec::classification`] slot names a concrete
9346 /// [`Classification`] returns `true` from
9347 /// [`Self::has_data_classification`] on the authored
9348 /// [`DataClassification`] slot and `false` for every other
9349 /// variant. Sweep the [`DataClassification::ALL`] × ALL cross so
9350 /// a regression that hard-coded the arm to a single kind or
9351 /// wired the closure to a fixed unrelated slot fails HERE at the
9352 /// substrate primitive. Byte-for-byte peer of the point-surface
9353 /// [`Classification::has_data_classification`] populated-slot
9354 /// sweep on the SAME closed-set primitive.
9355 #[test]
9356 fn has_data_classification_returns_true_iff_authored_classification_matches_per_kind() {
9357 for populated in DataClassification::ALL {
9358 let mut classification = Classification::gate_compute();
9359 classification.data_classification = populated;
9360 let mut spec = empty_ephemeral();
9361 spec.classification = Some(classification);
9362 for query in DataClassification::ALL {
9363 let expected = query == populated;
9364 assert_eq!(
9365 spec.has_data_classification(query),
9366 expected,
9367 "ephemeral classification.data_classification={populated:?}: query {query:?} drifted",
9368 );
9369 }
9370 }
9371 }
9372
9373 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9374 /// [`EphemeralSpec::classification`] slot is `None` returns
9375 /// `true` from [`Self::has_data_classification`] on
9376 /// [`DataClassification::Internal`] (the `default_ephemeral_class`
9377 /// baseline's `data_classification` axis AND the
9378 /// [`DataClassification`] child's own `#[default]` variant) and
9379 /// `false` on every other variant. Pins the (Option-parent ×
9380 /// DEFAULTED-scalar-child × operator-resolvable-baseline) corner's
9381 /// default-arm short-circuit on the FOURTH classification-axis
9382 /// peer — SECOND occupant on that corner after [`Self::has_calm`]
9383 /// opened it. Two-defaults composition property: both the parent
9384 /// fill-through and the child's `#[default]` land on the SAME
9385 /// variant, so the ephemeral sugar surface's
9386 /// `data-classification-Internal` require-tag reads `true` on
9387 /// every operator-authored spec that omits both the
9388 /// `:classification` slot AND the `:data-classification` sub-slot,
9389 /// pinning the workspace's internal-by-default sensitivity posture.
9390 #[test]
9391 fn has_data_classification_probes_internal_only_on_absent_classification() {
9392 let spec = empty_ephemeral();
9393 assert!(spec.classification.is_none());
9394 for kind in DataClassification::ALL {
9395 let expected = kind == DataClassification::Internal;
9396 assert_eq!(
9397 spec.has_data_classification(kind),
9398 expected,
9399 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9400 );
9401 }
9402 }
9403
9404 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9405 /// identically through [`Self::has_data_classification`] AND
9406 /// through `<eph.clone().into::<ProcessSpec>>()`
9407 /// `.classification.has_data_classification(kind)` on the
9408 /// mechanically-lowered `ProcessSpec`. Sweeps (`None`
9409 /// classification, `Some(_)` classification on every
9410 /// [`DataClassification::ALL`] variant) × ALL queries so a
9411 /// future regression on either side of the resolver (a shift in
9412 /// the ephemeral resolver's default, a shift in the
9413 /// `From<EphemeralSpec>` lowering's fill-through) fails HERE at
9414 /// the parity boundary. Byte-for-byte peer of the sibling
9415 /// [`Self::has_point_type`] + [`Self::has_substrate`] +
9416 /// [`Self::has_calm`] two-surface parity pins on the SAME
9417 /// `Cow`-resolver carrier — the FOURTH classification-axis
9418 /// two-surface parity contract on the ephemeral surface, and the
9419 /// SECOND on the (Option-parent × DEFAULTED-scalar-child) corner.
9420 #[test]
9421 fn has_data_classification_matches_point_peer_through_lowered_classification() {
9422 // Absent classification: both surfaces resolve through the SAME
9423 // default and agree on every variant.
9424 let eph = empty_ephemeral();
9425 let lowered: ProcessSpec = eph.clone().into();
9426 for query in DataClassification::ALL {
9427 assert_eq!(
9428 eph.has_data_classification(query),
9429 lowered.classification.has_data_classification(query),
9430 "None-classification parity drift on query {query:?}",
9431 );
9432 }
9433 // Authored classification: both surfaces read the same authored
9434 // value verbatim.
9435 for populated in DataClassification::ALL {
9436 let mut classification = Classification::gate_compute();
9437 classification.data_classification = populated;
9438 let mut eph = empty_ephemeral();
9439 eph.classification = Some(classification);
9440 let lowered: ProcessSpec = eph.clone().into();
9441 for query in DataClassification::ALL {
9442 assert_eq!(
9443 eph.has_data_classification(query),
9444 lowered.classification.has_data_classification(query),
9445 "authored classification.data_classification={populated:?}: parity drift on query {query:?}",
9446 );
9447 }
9448 }
9449 }
9450
9451 // ── EphemeralSpec::has_horizon_kind pins ─────────────────────────
9452 //
9453 // Fail-before-pass-after granularity: [`Self::has_horizon_kind`]
9454 // did not exist pre-lift on `impl EphemeralSpec` — every callsite
9455 // went through `.resolved_classification().horizon.kind == kind`
9456 // or through the lowered `ProcessSpec`'s
9457 // `spec.classification.has_horizon_kind`. Post-lift the FIFTH
9458 // classification-axis peer on the ephemeral sugar surface routes
9459 // through the SAME [`Self::resolved_classification`] resolver +
9460 // the sibling closed-set primitive
9461 // [`crate::classification::Classification::has_horizon_kind`], so
9462 // a regression that dropped the resolver hop, inverted the
9463 // `Some`/`None` fill-through, or wired the closure to a fixed
9464 // unrelated slot fails HERE. OPENS a fresh (Option-parent ×
9465 // NESTED-STRUCT-scalar-child × operator-resolvable-baseline)
9466 // corner on the ephemeral surface — distinct from the four prior
9467 // scalar-carrier peers on the (Option-parent × NON-DEFAULT-scalar-
9468 // child) and (Option-parent × DEFAULTED-scalar-child) corners, all
9469 // of which reach a discriminator DIRECTLY off a scalar
9470 // [`Classification`] slot. Both the parent Option's fill-through
9471 // baseline (`default_ephemeral_class`, which fills
9472 // `horizon: Horizon::default()`) AND the child's own `#[default]`
9473 // land on the SAME variant ([`HorizonKind::Bounded`]) — a two-
9474 // defaults composition property the three pins below all
9475 // exercise.
9476
9477 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
9478 /// [`EphemeralSpec::classification`] slot names a concrete
9479 /// [`Classification`] returns `true` from
9480 /// [`Self::has_horizon_kind`] on the authored [`HorizonKind`] slot
9481 /// and `false` for every other variant. Sweep the
9482 /// [`HorizonKind::ALL`] × ALL cross so a regression that hard-
9483 /// coded the arm to a single kind or wired the closure to a
9484 /// fixed unrelated slot (e.g. reading `self.classification` as if
9485 /// it were a scalar rather than routing through
9486 /// `resolved_classification().horizon.kind`) fails HERE at the
9487 /// substrate primitive. Byte-for-byte peer of the point-surface
9488 /// [`Classification::has_horizon_kind`] populated-slot sweep on
9489 /// the SAME closed-set primitive.
9490 #[test]
9491 fn has_horizon_kind_returns_true_iff_authored_classification_matches_per_kind() {
9492 for populated in HorizonKind::ALL {
9493 let classification = Classification::gate_compute_with_axis(populated);
9494 let mut spec = empty_ephemeral();
9495 spec.classification = Some(classification);
9496 for query in HorizonKind::ALL {
9497 let expected = query == populated;
9498 assert_eq!(
9499 spec.has_horizon_kind(query),
9500 expected,
9501 "ephemeral classification.horizon.kind={populated:?}: query {query:?} drifted",
9502 );
9503 }
9504 }
9505 }
9506
9507 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9508 /// [`EphemeralSpec::classification`] slot is `None` returns
9509 /// `true` from [`Self::has_horizon_kind`] on
9510 /// [`HorizonKind::Bounded`] (the `default_ephemeral_class`
9511 /// baseline's `horizon.kind` axis AND the [`HorizonKind`] child's
9512 /// own `#[default]` variant) and `false` on every other variant.
9513 /// Pins the fresh (Option-parent × NESTED-STRUCT-scalar-child ×
9514 /// operator-resolvable-baseline) corner's default-arm short-
9515 /// circuit on the FIFTH classification-axis peer. Two-defaults
9516 /// composition property through a NESTED-STRUCT hop: both the
9517 /// parent Option's fill-through baseline
9518 /// (`default_ephemeral_class` fills `horizon: Horizon::default()`)
9519 /// AND the child's own `#[default]` (`HorizonKind::Bounded` via
9520 /// `#[default]` on the closed set) land on the SAME variant, so
9521 /// the ephemeral sugar surface's `horizon-Bounded` require-tag
9522 /// reads `true` on every operator-authored spec that omits both
9523 /// the `:classification` slot AND the `:horizon` sub-slot,
9524 /// pinning the workspace's bounded-by-default lifetime posture.
9525 #[test]
9526 fn has_horizon_kind_probes_bounded_only_on_absent_classification() {
9527 let spec = empty_ephemeral();
9528 assert!(spec.classification.is_none());
9529 for kind in HorizonKind::ALL {
9530 let expected = kind == HorizonKind::Bounded;
9531 assert_eq!(
9532 spec.has_horizon_kind(kind),
9533 expected,
9534 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9535 );
9536 }
9537 }
9538
9539 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9540 /// identically through [`Self::has_horizon_kind`] AND through
9541 /// `<eph.clone().into::<ProcessSpec>>()`
9542 /// `.classification.has_horizon_kind(kind)` on the mechanically-
9543 /// lowered `ProcessSpec`. Sweeps (`None` classification, `Some(_)`
9544 /// classification on every [`HorizonKind::ALL`] variant) × ALL
9545 /// queries so a future regression on either side of the resolver
9546 /// (a shift in the ephemeral resolver's default, a shift in the
9547 /// `From<EphemeralSpec>` lowering's fill-through) fails HERE at
9548 /// the parity boundary. Byte-for-byte peer of the sibling
9549 /// [`Self::has_point_type`] + [`Self::has_substrate`] +
9550 /// [`Self::has_calm`] + [`Self::has_data_classification`] two-
9551 /// surface parity pins on the SAME `Cow`-resolver carrier — the
9552 /// FIFTH classification-axis two-surface parity contract on the
9553 /// ephemeral surface, and the FIRST on the (Option-parent ×
9554 /// NESTED-STRUCT-scalar-child) corner.
9555 #[test]
9556 fn has_horizon_kind_matches_point_peer_through_lowered_classification() {
9557 // Absent classification: both surfaces resolve through the SAME
9558 // default and agree on every variant.
9559 let eph = empty_ephemeral();
9560 let lowered: ProcessSpec = eph.clone().into();
9561 for query in HorizonKind::ALL {
9562 assert_eq!(
9563 eph.has_horizon_kind(query),
9564 lowered.classification.has_horizon_kind(query),
9565 "None-classification parity drift on query {query:?}",
9566 );
9567 }
9568 // Authored classification: both surfaces read the same authored
9569 // value verbatim.
9570 for populated in HorizonKind::ALL {
9571 let classification = Classification::gate_compute_with_axis(populated);
9572 let mut eph = empty_ephemeral();
9573 eph.classification = Some(classification);
9574 let lowered: ProcessSpec = eph.clone().into();
9575 for query in HorizonKind::ALL {
9576 assert_eq!(
9577 eph.has_horizon_kind(query),
9578 lowered.classification.has_horizon_kind(query),
9579 "authored classification.horizon.kind={populated:?}: parity drift on query {query:?}",
9580 );
9581 }
9582 }
9583 }
9584
9585 // ── EphemeralSpec::has_optimization_direction pins ───────────────
9586 //
9587 // Fail-before-pass-after granularity:
9588 // [`Self::has_optimization_direction`] did not exist pre-lift on
9589 // `impl EphemeralSpec` — every callsite went through
9590 // `.resolved_classification().horizon.direction.unwrap_or_default() == kind`
9591 // or through the lowered `ProcessSpec`'s
9592 // `spec.classification.has_optimization_direction`. Post-lift the
9593 // SIXTH classification-axis peer on the ephemeral sugar surface
9594 // routes through the SAME [`Self::resolved_classification`]
9595 // resolver + the sibling closed-set primitive
9596 // [`crate::classification::Classification::has_optimization_direction`],
9597 // so a regression that dropped the resolver hop, inverted the
9598 // `Some`/`None` fill-through, wired the closure to a fixed
9599 // unrelated slot, or flipped [`OptimizationDirection`]'s
9600 // `#[default]` off `Minimize` fails HERE. SECOND occupant on the
9601 // (Option-parent × NESTED-STRUCT-scalar-child × operator-
9602 // resolvable-baseline) corner alongside
9603 // [`Self::has_horizon_kind`] — pinning the corner as a proven-
9604 // repeatable primitive shape on the ephemeral surface with a
9605 // second nested-struct-child probe, and DEMONSTRATING that the
9606 // corner admits both direct-scalar and Option-scalar traversals
9607 // through the SAME nested [`Horizon`] intermediary via the closed
9608 // set's `Default` on the inner `Option<OptimizationDirection>`
9609 // slot.
9610
9611 /// AUTHORED-slot VARIANT-MATCH pin — an [`EphemeralSpec`] whose
9612 /// [`EphemeralSpec::classification`] slot names a concrete
9613 /// [`Classification`] whose [`crate::classification::Horizon::direction`]
9614 /// slot carries `Some(<direction>)` returns `true` from
9615 /// [`Self::has_optimization_direction`] on the authored
9616 /// [`OptimizationDirection`] variant and `false` for every other
9617 /// variant. Sweep the [`OptimizationDirection::ALL`] × ALL cross
9618 /// so a regression that hard-coded the arm to a single kind, or
9619 /// dropped the `Option::unwrap_or_default` collapse, or wired the
9620 /// closure to a fixed unrelated slot (e.g. reading `self.horizon.kind`)
9621 /// fails HERE at the substrate primitive. Byte-for-byte peer of the
9622 /// point-surface
9623 /// [`Classification::has_optimization_direction`] populated-slot
9624 /// sweep on the SAME closed-set primitive.
9625 #[test]
9626 fn has_optimization_direction_returns_true_iff_authored_direction_matches_per_kind() {
9627 for populated in OptimizationDirection::ALL {
9628 let classification = Classification::gate_compute_with_axis(populated);
9629 let mut spec = empty_ephemeral();
9630 spec.classification = Some(classification);
9631 for query in OptimizationDirection::ALL {
9632 let expected = query == populated;
9633 assert_eq!(
9634 spec.has_optimization_direction(query),
9635 expected,
9636 "ephemeral classification.horizon.direction=Some({populated:?}): query {query:?} drifted",
9637 );
9638 }
9639 }
9640 }
9641
9642 /// ABSENT-slot DEFAULT-ARM pin — an [`EphemeralSpec`] whose
9643 /// [`EphemeralSpec::classification`] slot is `None` returns
9644 /// `true` from [`Self::has_optimization_direction`] on
9645 /// [`OptimizationDirection::Minimize`] (the `default_ephemeral_class`
9646 /// baseline fills `horizon: Horizon::default()`, which in turn
9647 /// leaves `direction: None`, and the substrate's
9648 /// `Option::unwrap_or_default` collapse then reads
9649 /// [`OptimizationDirection::Minimize`] via the closed set's
9650 /// `#[default]`) and `false` on every other variant. Pins the
9651 /// (Option-parent × NESTED-STRUCT-scalar-child × operator-
9652 /// resolvable-baseline) corner's default-arm short-circuit on the
9653 /// SIXTH classification-axis peer through TWO Option-hops: parent
9654 /// `EphemeralSpec::classification` and inner `Horizon::direction`
9655 /// both `None`, both collapsing to the closed set's `#[default]`
9656 /// [`OptimizationDirection::Minimize`]. A regression that promoted
9657 /// [`OptimizationDirection::Maximize`] to `#[default]` (silently
9658 /// inverting every unadorned Process's rate-window evaluator
9659 /// polarity), dropped `Option::unwrap_or_default`, or wired the arm
9660 /// to a fixed variant answer fails HERE.
9661 #[test]
9662 fn has_optimization_direction_probes_minimize_only_on_absent_classification() {
9663 let spec = empty_ephemeral();
9664 assert!(spec.classification.is_none());
9665 for kind in OptimizationDirection::ALL {
9666 let expected = kind == OptimizationDirection::Minimize;
9667 assert_eq!(
9668 spec.has_optimization_direction(kind),
9669 expected,
9670 "absent classification (defaults to gate_compute): query {kind:?} must be {expected}",
9671 );
9672 }
9673 }
9674
9675 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9676 /// identically through [`Self::has_optimization_direction`] AND
9677 /// through
9678 /// `<eph.clone().into::<ProcessSpec>>().classification.has_optimization_direction(kind)`
9679 /// on the mechanically-lowered `ProcessSpec`. Sweeps three arms —
9680 /// (`None` classification), (`Some(_)` classification with
9681 /// `direction: None`), and (`Some(_)` classification on every
9682 /// [`OptimizationDirection::ALL`] variant) — × ALL queries so a
9683 /// future regression on either side of the resolver (an ephemeral-
9684 /// side fill-through drift, a lowering-side `From<EphemeralSpec>`
9685 /// `unwrap_or_else(default_ephemeral_class)` drift, an inner
9686 /// `Option::unwrap_or_default` collapse drift on either side)
9687 /// fails HERE at the parity boundary. Byte-for-byte peer of the
9688 /// sibling [`Self::has_point_type`] + [`Self::has_substrate`] +
9689 /// [`Self::has_calm`] + [`Self::has_data_classification`] +
9690 /// [`Self::has_horizon_kind`] two-surface parity pins on the SAME
9691 /// `Cow`-resolver carrier — the SIXTH classification-axis two-
9692 /// surface parity contract on the ephemeral surface, and the
9693 /// SECOND on the (Option-parent × NESTED-STRUCT-scalar-child)
9694 /// corner.
9695 #[test]
9696 fn has_optimization_direction_matches_point_peer_through_lowered_classification() {
9697 // Absent classification: both surfaces resolve through the SAME
9698 // default and agree on every variant.
9699 let eph = empty_ephemeral();
9700 let lowered: ProcessSpec = eph.clone().into();
9701 for query in OptimizationDirection::ALL {
9702 assert_eq!(
9703 eph.has_optimization_direction(query),
9704 lowered.classification.has_optimization_direction(query),
9705 "None-classification parity drift on query {query:?}",
9706 );
9707 }
9708 // Authored classification with `direction: None` — the inner
9709 // Option collapses through `unwrap_or_default` on both sides,
9710 // reading `Minimize`.
9711 let mut classification = Classification::gate_compute();
9712 classification.horizon = Horizon::default();
9713 let mut eph = empty_ephemeral();
9714 eph.classification = Some(classification);
9715 let lowered: ProcessSpec = eph.clone().into();
9716 for query in OptimizationDirection::ALL {
9717 assert_eq!(
9718 eph.has_optimization_direction(query),
9719 lowered.classification.has_optimization_direction(query),
9720 "authored classification with horizon.direction=None: parity drift on query {query:?}",
9721 );
9722 }
9723 // Authored classification with `direction: Some(_)` — both
9724 // surfaces read the same authored value verbatim.
9725 for populated in OptimizationDirection::ALL {
9726 let classification = Classification::gate_compute_with_axis(populated);
9727 let mut eph = empty_ephemeral();
9728 eph.classification = Some(classification);
9729 let lowered: ProcessSpec = eph.clone().into();
9730 for query in OptimizationDirection::ALL {
9731 assert_eq!(
9732 eph.has_optimization_direction(query),
9733 lowered.classification.has_optimization_direction(query),
9734 "authored classification.horizon.direction=Some({populated:?}): parity drift on query {query:?}",
9735 );
9736 }
9737 }
9738 }
9739
9740 // ── EphemeralSpec::has_input_arity pins ──────────────────────────
9741 //
9742 // Fail-before-pass-after granularity: [`Self::has_input_arity`] did
9743 // not exist pre-lift on `impl EphemeralSpec` — every callsite went
9744 // through `.resolved_classification().point_type.input_arity() ==
9745 // kind` or through the lowered `ProcessSpec`'s
9746 // `spec.classification.has_input_arity`. Post-lift the SEVENTH
9747 // classification-axis peer on the ephemeral sugar surface routes
9748 // through the SAME [`Self::resolved_classification`] resolver + the
9749 // sibling closed-set primitive
9750 // [`crate::classification::Classification::has_input_arity`], so a
9751 // regression that dropped the resolver hop, dropped the
9752 // `.input_arity()` projection call, inverted the projection (`One
9753 // ↔ Many`), or crossed the wires with the sibling
9754 // [`ConvergencePointType::output_arity`] projection fails HERE.
9755 // OPENS the (Option-parent × NESTED-STRUCT-scalar-child ×
9756 // derived-typed-projection) corner on the ephemeral surface —
9757 // distinct from the two prior nested-scalar peers on the corner
9758 // (`has_horizon_kind` reads `horizon.kind` directly;
9759 // `has_optimization_direction` reads `horizon.direction` through an
9760 // Option collapse), both of which reach a discriminator DIRECTLY off
9761 // a scalar. This peer instead threads through a many-to-one closed-
9762 // set typed projection so the child's closed set is REACHED THROUGH
9763 // a projection layer, pinning the corner as admitting three
9764 // ephemeral-surface traversal shapes (direct-scalar, Option-scalar-
9765 // with-default, derived-typed-projection) through the SAME resolver
9766 // walk.
9767
9768 /// AUTHORED-slot PROJECTED-VARIANT pin — an [`EphemeralSpec`] whose
9769 /// [`EphemeralSpec::classification`] slot names a concrete
9770 /// [`Classification`] with an authored [`ConvergencePointType`]
9771 /// returns `true` from [`Self::has_input_arity`] on the [`Arity`]
9772 /// value the projection [`ConvergencePointType::input_arity`] maps
9773 /// the authored point-type to and `false` for every other variant.
9774 /// Sweep the [`ConvergencePointType::ALL`] × [`Arity::ALL`] cross so
9775 /// a regression that (a) dropped the projection call, (b) inverted
9776 /// the projection, (c) probed [`ConvergencePointType`] directly, or
9777 /// (d) crossed wires with [`ConvergencePointType::output_arity`]
9778 /// fails HERE at the substrate primitive. Byte-for-byte peer of the
9779 /// point-surface [`Classification::has_input_arity`] populated-slot
9780 /// sweep on the SAME closed-set primitive routed through the SAME
9781 /// projection.
9782 #[test]
9783 fn has_input_arity_returns_true_iff_authored_point_type_projects_per_kind() {
9784 for populated in ConvergencePointType::ALL {
9785 let mut classification = Classification::gate_compute();
9786 classification.point_type = populated;
9787 let mut spec = empty_ephemeral();
9788 spec.classification = Some(classification);
9789 let projected = populated.input_arity();
9790 for query in Arity::ALL {
9791 let expected = query == projected;
9792 assert_eq!(
9793 spec.has_input_arity(query),
9794 expected,
9795 "ephemeral classification.point_type={populated:?} (projects to {projected:?}): query {query:?} drifted",
9796 );
9797 }
9798 }
9799 }
9800
9801 /// ABSENT-slot PROJECTED-BASELINE pin — an [`EphemeralSpec`] whose
9802 /// [`EphemeralSpec::classification`] slot is `None` returns `true`
9803 /// from [`Self::has_input_arity`] on [`Arity::Many`] (the
9804 /// [`default_ephemeral_class`] baseline fills `point_type: Gate`,
9805 /// and [`ConvergencePointType::input_arity`] projects
9806 /// `Gate → Arity::Many`) and `false` on [`Arity::One`]. Pins the
9807 /// (Option-parent × NESTED-STRUCT-scalar-child × derived-typed-
9808 /// projection) corner's baseline projection on the SEVENTH
9809 /// classification-axis peer through a chain of TWO fill-throughs
9810 /// composed with ONE projection: the parent Option's
9811 /// `unwrap_or_else(default_ephemeral_class)` picks the substrate
9812 /// baseline, and the projection then collapses the baseline's
9813 /// point-type through the closed-set-driven many-to-one bucket
9814 /// walk. [`Arity`] carries no `#[default]`, so there is NO default-
9815 /// arm short-circuit shortcut here — the answer flows entirely
9816 /// through the projection's bucket-membership decision. A
9817 /// regression that promoted the baseline's `point_type` off `Gate`
9818 /// (silently flipping every unadorned Process's convergent-by-
9819 /// default input-side posture to endomorphic or diffusive), dropped
9820 /// the projection call, inverted the projection, or crossed wires
9821 /// with [`ConvergencePointType::output_arity`] (which would flip
9822 /// the baseline answer from `Many` to `One` for `Gate`) fails HERE.
9823 #[test]
9824 fn has_input_arity_probes_many_only_on_absent_classification() {
9825 let spec = empty_ephemeral();
9826 assert!(spec.classification.is_none());
9827 for kind in Arity::ALL {
9828 let expected = kind == Arity::Many;
9829 assert_eq!(
9830 spec.has_input_arity(kind),
9831 expected,
9832 "absent classification (defaults to gate_compute, point_type=Gate → input_arity=Many): query {kind:?} must be {expected}",
9833 );
9834 }
9835 }
9836
9837 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9838 /// identically through [`Self::has_input_arity`] AND through
9839 /// `<eph.clone().into::<ProcessSpec>>().classification.has_input_arity(kind)`
9840 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
9841 /// classification, `Some(_)` classification on every
9842 /// [`ConvergencePointType::ALL`] variant) × [`Arity::ALL`] queries
9843 /// so a future regression on either side of the resolver (a shift
9844 /// in the ephemeral resolver's default, a shift in the
9845 /// `From<EphemeralSpec>` lowering's fill-through, a projection
9846 /// drift on either side) fails HERE at the parity boundary. Byte-
9847 /// for-byte peer of the sibling [`Self::has_point_type`] +
9848 /// [`Self::has_substrate`] + [`Self::has_calm`] +
9849 /// [`Self::has_data_classification`] + [`Self::has_horizon_kind`] +
9850 /// [`Self::has_optimization_direction`] two-surface parity pins on
9851 /// the SAME `Cow`-resolver carrier — the SEVENTH classification-
9852 /// axis two-surface parity contract on the ephemeral surface, and
9853 /// the FIRST on the (Option-parent × NESTED-STRUCT-scalar-child ×
9854 /// derived-typed-projection) corner.
9855 #[test]
9856 fn has_input_arity_matches_point_peer_through_lowered_classification() {
9857 // Absent classification: both surfaces resolve through the SAME
9858 // default and agree on every variant.
9859 let eph = empty_ephemeral();
9860 let lowered: ProcessSpec = eph.clone().into();
9861 for query in Arity::ALL {
9862 assert_eq!(
9863 eph.has_input_arity(query),
9864 lowered.classification.has_input_arity(query),
9865 "None-classification parity drift on query {query:?}",
9866 );
9867 }
9868 // Authored classification: both surfaces read the same authored
9869 // point_type and route through the same projection.
9870 for populated in ConvergencePointType::ALL {
9871 let mut classification = Classification::gate_compute();
9872 classification.point_type = populated;
9873 let mut eph = empty_ephemeral();
9874 eph.classification = Some(classification);
9875 let lowered: ProcessSpec = eph.clone().into();
9876 for query in Arity::ALL {
9877 assert_eq!(
9878 eph.has_input_arity(query),
9879 lowered.classification.has_input_arity(query),
9880 "authored classification.point_type={populated:?}: parity drift on query {query:?}",
9881 );
9882 }
9883 }
9884 }
9885
9886 // ── EphemeralSpec::has_output_arity pins ─────────────────────────
9887 //
9888 // Fail-before-pass-after granularity: [`Self::has_output_arity`] did
9889 // not exist pre-lift on `impl EphemeralSpec` — every callsite went
9890 // through `.resolved_classification().point_type.output_arity() ==
9891 // kind` or through the lowered `ProcessSpec`'s
9892 // `spec.classification.has_output_arity`. Post-lift the EIGHTH
9893 // classification-axis peer on the ephemeral sugar surface routes
9894 // through the SAME [`Self::resolved_classification`] resolver + the
9895 // sibling closed-set primitive
9896 // [`crate::classification::Classification::has_output_arity`], so a
9897 // regression that dropped the resolver hop, dropped the
9898 // `.output_arity()` projection call, inverted the projection (`One
9899 // ↔ Many`), or crossed the wires with the sibling
9900 // [`ConvergencePointType::input_arity`] projection fails HERE.
9901 // CLOSES the (Option-parent × NESTED-STRUCT-scalar-child ×
9902 // derived-typed-projection) corner on the ephemeral surface as the
9903 // SECOND occupant — co-tenant with [`Self::has_input_arity`] on the
9904 // SAME `point_type` scalar carrier through the SAME [`Arity`] closed
9905 // set but through the sibling many-to-one projection, closing the
9906 // DAG-composition arity pair on the ephemeral side.
9907
9908 /// AUTHORED-slot PROJECTED-VARIANT pin — an [`EphemeralSpec`] whose
9909 /// [`EphemeralSpec::classification`] slot names a concrete
9910 /// [`Classification`] with an authored [`ConvergencePointType`]
9911 /// returns `true` from [`Self::has_output_arity`] on the [`Arity`]
9912 /// value the projection [`ConvergencePointType::output_arity`] maps
9913 /// the authored point-type to and `false` for every other variant.
9914 /// Sweep the [`ConvergencePointType::ALL`] × [`Arity::ALL`] cross so
9915 /// a regression that (a) dropped the projection call, (b) inverted
9916 /// the projection, (c) probed [`ConvergencePointType`] directly, or
9917 /// (d) crossed wires with [`ConvergencePointType::input_arity`]
9918 /// fails HERE at the substrate primitive. Byte-for-byte peer of the
9919 /// point-surface [`Classification::has_output_arity`] populated-slot
9920 /// sweep on the SAME closed-set primitive routed through the SAME
9921 /// projection.
9922 #[test]
9923 fn has_output_arity_returns_true_iff_authored_point_type_projects_per_kind() {
9924 for populated in ConvergencePointType::ALL {
9925 let mut classification = Classification::gate_compute();
9926 classification.point_type = populated;
9927 let mut spec = empty_ephemeral();
9928 spec.classification = Some(classification);
9929 let projected = populated.output_arity();
9930 for query in Arity::ALL {
9931 let expected = query == projected;
9932 assert_eq!(
9933 spec.has_output_arity(query),
9934 expected,
9935 "ephemeral classification.point_type={populated:?} (projects to {projected:?}): query {query:?} drifted",
9936 );
9937 }
9938 }
9939 }
9940
9941 /// ABSENT-slot PROJECTED-BASELINE pin — an [`EphemeralSpec`] whose
9942 /// [`EphemeralSpec::classification`] slot is `None` returns `true`
9943 /// from [`Self::has_output_arity`] on [`Arity::One`] (the
9944 /// [`default_ephemeral_class`] baseline fills `point_type: Gate`,
9945 /// and [`ConvergencePointType::output_arity`] projects
9946 /// `Gate → Arity::One`) and `false` on [`Arity::Many`]. MIRROR of
9947 /// the [`Self::has_input_arity`] baseline (`Gate → input_arity =
9948 /// Many`) — the DAG-composition arity pair projects the same `Gate`
9949 /// baseline through the two projections to opposite [`Arity`] arms,
9950 /// so this pin locks the output-side half of that pair against a
9951 /// regression that (a) promoted the baseline's `point_type` off
9952 /// `Gate` (silently flipping every unadorned Process's convergent-
9953 /// by-default output-side posture to diffusive), (b) dropped the
9954 /// projection call, (c) inverted the projection, or (d) crossed
9955 /// wires with [`ConvergencePointType::input_arity`] (which would
9956 /// flip the baseline answer from `One` to `Many` for `Gate`).
9957 #[test]
9958 fn has_output_arity_probes_one_only_on_absent_classification() {
9959 let spec = empty_ephemeral();
9960 assert!(spec.classification.is_none());
9961 for kind in Arity::ALL {
9962 let expected = kind == Arity::One;
9963 assert_eq!(
9964 spec.has_output_arity(kind),
9965 expected,
9966 "absent classification (defaults to gate_compute, point_type=Gate → output_arity=One): query {kind:?} must be {expected}",
9967 );
9968 }
9969 }
9970
9971 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
9972 /// identically through [`Self::has_output_arity`] AND through
9973 /// `<eph.clone().into::<ProcessSpec>>().classification.has_output_arity(kind)`
9974 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
9975 /// classification, `Some(_)` classification on every
9976 /// [`ConvergencePointType::ALL`] variant) × [`Arity::ALL`] queries
9977 /// so a future regression on either side of the resolver fails HERE
9978 /// at the parity boundary. Byte-for-byte peer of the seven sibling
9979 /// two-surface parity pins on the SAME `Cow`-resolver carrier — the
9980 /// EIGHTH classification-axis two-surface parity contract on the
9981 /// ephemeral surface, closing the SECOND occupant of the (Option-
9982 /// parent × NESTED-STRUCT-scalar-child × derived-typed-projection)
9983 /// corner.
9984 #[test]
9985 fn has_output_arity_matches_point_peer_through_lowered_classification() {
9986 // Absent classification: both surfaces resolve through the SAME
9987 // default and agree on every variant.
9988 let eph = empty_ephemeral();
9989 let lowered: ProcessSpec = eph.clone().into();
9990 for query in Arity::ALL {
9991 assert_eq!(
9992 eph.has_output_arity(query),
9993 lowered.classification.has_output_arity(query),
9994 "None-classification parity drift on query {query:?}",
9995 );
9996 }
9997 // Authored classification: both surfaces read the same authored
9998 // point_type and route through the same projection.
9999 for populated in ConvergencePointType::ALL {
10000 let mut classification = Classification::gate_compute();
10001 classification.point_type = populated;
10002 let mut eph = empty_ephemeral();
10003 eph.classification = Some(classification);
10004 let lowered: ProcessSpec = eph.clone().into();
10005 for query in Arity::ALL {
10006 assert_eq!(
10007 eph.has_output_arity(query),
10008 lowered.classification.has_output_arity(query),
10009 "authored classification.point_type={populated:?}: parity drift on query {query:?}",
10010 );
10011 }
10012 }
10013 }
10014
10015 /// DAG-COMPOSITION ARITY-PAIR pin — the SEVENTH
10016 /// ([`Self::has_input_arity`]) and EIGHTH
10017 /// ([`Self::has_output_arity`]) classification-axis peers on the
10018 /// ephemeral surface walk the SAME `point_type` scalar carrier
10019 /// (routed through the SAME [`Self::resolved_classification`]
10020 /// resolver) through the SAME [`Arity`] closed set but through
10021 /// DIFFERENT typed projections
10022 /// ([`ConvergencePointType::input_arity`] vs.
10023 /// [`ConvergencePointType::output_arity`]). An [`EphemeralSpec`]
10024 /// with `classification.point_type = Fork` (the diffusive `(One,
10025 /// Many)` cell) MUST simultaneously answer `has_input_arity(One)`
10026 /// true AND `has_output_arity(Many)` true AND
10027 /// `has_input_arity(Many)` false AND `has_output_arity(One)` false.
10028 /// An [`EphemeralSpec`] with `point_type = Transform` (endomorphic
10029 /// `(One, One)`) MUST answer BOTH `has_input_arity(One)` and
10030 /// `has_output_arity(One)` true — the two projections AGREE in the
10031 /// endomorphic bucket. The absent-classification baseline (Gate,
10032 /// convergent `(Many, One)`) MUST answer
10033 /// `has_input_arity(Many)` true AND `has_output_arity(One)` true —
10034 /// the mirror of the Fork case. A regression that (a) collapsed
10035 /// `has_output_arity` onto `has_input_arity`, (b) swapped the
10036 /// projection direction, or (c) drifted the topology-bucket
10037 /// contract fails HERE at ONE narrow ephemeral-surface site,
10038 /// symmetric with the point-surface DAG-composition arity-pair pin.
10039 #[test]
10040 fn has_input_arity_and_has_output_arity_pin_dag_composition_pair() {
10041 // Diffusive cell: Fork carries (input, output) = (One, Many)
10042 let mut classification = Classification::gate_compute();
10043 classification.point_type = ConvergencePointType::Fork;
10044 let mut fork = empty_ephemeral();
10045 fork.classification = Some(classification);
10046 assert!(fork.has_input_arity(Arity::One));
10047 assert!(fork.has_output_arity(Arity::Many));
10048 assert!(!fork.has_input_arity(Arity::Many));
10049 assert!(!fork.has_output_arity(Arity::One));
10050
10051 // Endomorphic cell: Transform carries (input, output) = (One, One)
10052 let mut classification = Classification::gate_compute();
10053 classification.point_type = ConvergencePointType::Transform;
10054 let mut transform = empty_ephemeral();
10055 transform.classification = Some(classification);
10056 assert!(transform.has_input_arity(Arity::One));
10057 assert!(transform.has_output_arity(Arity::One));
10058 assert!(!transform.has_input_arity(Arity::Many));
10059 assert!(!transform.has_output_arity(Arity::Many));
10060
10061 // Convergent cell: absent classification defaults to Gate,
10062 // which carries (input, output) = (Many, One).
10063 let gate = empty_ephemeral();
10064 assert!(gate.classification.is_none());
10065 assert!(gate.has_input_arity(Arity::Many));
10066 assert!(gate.has_output_arity(Arity::One));
10067 assert!(!gate.has_input_arity(Arity::One));
10068 assert!(!gate.has_output_arity(Arity::Many));
10069 }
10070
10071 // ── EphemeralSpec::horizon_terminates pins ───────────────────────
10072 //
10073 // Fail-before-pass-after granularity: `horizon_terminates` did not
10074 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
10075 // the "does this ephemeral spec's horizon terminate?" question
10076 // went through `.resolved_classification().horizon.kind.terminates()`
10077 // or through the lowered `ProcessSpec`'s
10078 // `spec.classification.horizon.kind.terminates()`. Post-lift the
10079 // NINTH classification-axis peer on the ephemeral surface routes
10080 // through the SAME [`Self::resolved_classification`] resolver +
10081 // the sibling substrate primitive
10082 // [`crate::classification::Classification::horizon_terminates`],
10083 // so the two-surface parity contract holds by construction — a
10084 // regression on either side of the resolver fails at these pins
10085 // before landing at the operator-facing `terminating-horizon`
10086 // fixed tag in `tatara-check`.
10087
10088 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10089 /// [`Classification`] carries a specific [`HorizonKind`] variant
10090 /// answers [`Self::horizon_terminates`] matching the closed
10091 /// set's own [`HorizonKind::terminates`] truth table. Sweep
10092 /// [`HorizonKind::ALL`] so a regression that (a) hard-coded the
10093 /// body to a fixed answer, (b) inverted the projection, or (c)
10094 /// crossed the wires with the antisymmetric partner
10095 /// [`HorizonKind::requires_metric_axes`] fails HERE at the
10096 /// substrate primitive before drifting through the
10097 /// `terminating-horizon` fixed tag or the peer point surface.
10098 #[test]
10099 fn horizon_terminates_returns_horizon_kind_projection_per_kind() {
10100 for populated in HorizonKind::ALL {
10101 let classification = Classification::gate_compute_with_axis(populated);
10102 let mut spec = empty_ephemeral();
10103 spec.classification = Some(classification);
10104 assert_eq!(
10105 spec.horizon_terminates(),
10106 populated.terminates(),
10107 "authored horizon.kind={populated:?}: horizon_terminates() drift",
10108 );
10109 }
10110 }
10111
10112 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10113 /// with `classification: None` routes through the
10114 /// [`Self::resolved_classification`] resolver's substrate default
10115 /// [`Classification::gate_compute`], which uses
10116 /// [`crate::classification::Horizon::default`] whose `kind`
10117 /// defaults to [`HorizonKind::Bounded`] via `#[default]`, and
10118 /// [`HorizonKind::Bounded::terminates`] projects `true`, so
10119 /// [`Self::horizon_terminates`] returns `true`. Pins the default-
10120 /// arm short-circuit through THREE layers of `Default`
10121 /// ([`Classification::gate_compute`] → [`Horizon::default`] →
10122 /// [`HorizonKind::default`]) reaching this derived-nullary
10123 /// predicate — a regression that dropped the resolver hop
10124 /// (silently answering `false` on an absent classification, as
10125 /// if the operator's absence meant "no horizon at all") fails
10126 /// HERE at ONE narrow ephemeral-surface site.
10127 #[test]
10128 fn horizon_terminates_probes_true_on_absent_classification() {
10129 let spec = empty_ephemeral();
10130 assert!(spec.classification.is_none());
10131 assert!(
10132 spec.horizon_terminates(),
10133 "absent classification (defaults to gate_compute, horizon.kind=Bounded → terminates=true)",
10134 );
10135 }
10136
10137 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10138 /// identically through [`Self::horizon_terminates`] AND through
10139 /// `<eph.clone().into::<ProcessSpec>>().classification.horizon_terminates()`
10140 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10141 /// classification, `Some(_)` classification on every
10142 /// [`HorizonKind::ALL`] variant) so a future regression on
10143 /// either side of the resolver fails HERE at the parity
10144 /// boundary. Byte-for-byte peer of the eight sibling two-surface
10145 /// parity pins on the SAME `Cow`-resolver carrier — the NINTH
10146 /// classification-axis two-surface parity contract on the
10147 /// ephemeral surface, and the FIRST via a derived-nullary-
10148 /// boolean predicate rather than a variant-equality probe.
10149 #[test]
10150 fn horizon_terminates_matches_point_peer_through_lowered_classification() {
10151 // Absent classification: both surfaces resolve through the SAME
10152 // default and agree.
10153 let eph = empty_ephemeral();
10154 let lowered: ProcessSpec = eph.clone().into();
10155 assert_eq!(
10156 eph.horizon_terminates(),
10157 lowered.classification.horizon_terminates(),
10158 "None-classification parity drift",
10159 );
10160 // Authored classification: both surfaces read the same authored
10161 // horizon.kind and route through the same projection.
10162 for populated in HorizonKind::ALL {
10163 let classification = Classification::gate_compute_with_axis(populated);
10164 let mut eph = empty_ephemeral();
10165 eph.classification = Some(classification);
10166 let lowered: ProcessSpec = eph.clone().into();
10167 assert_eq!(
10168 eph.horizon_terminates(),
10169 lowered.classification.horizon_terminates(),
10170 "authored horizon.kind={populated:?}: parity drift",
10171 );
10172 }
10173 }
10174
10175 // ── EphemeralSpec::horizon_requires_metric_axes pins ─────────────
10176 //
10177 // Fail-before-pass-after granularity: `horizon_requires_metric_axes`
10178 // did not exist pre-lift on `impl EphemeralSpec` — every consumer
10179 // walking the "does this ephemeral spec's horizon require metric
10180 // axes?" question went through
10181 // `.resolved_classification().horizon.kind.requires_metric_axes()`
10182 // or through the lowered `ProcessSpec`'s
10183 // `spec.classification.horizon.kind.requires_metric_axes()`. Post-
10184 // lift the antisymmetric peer of `horizon_terminates` routes
10185 // through the SAME [`Self::resolved_classification`] resolver +
10186 // the sibling substrate primitive
10187 // [`crate::classification::Classification::horizon_requires_metric_axes`],
10188 // so the two-surface parity contract holds by construction — a
10189 // regression on either side of the resolver fails at these pins
10190 // before landing at the operator-facing `metric-axes-required`
10191 // fixed tag in `tatara-check`.
10192
10193 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10194 /// [`Classification`] carries a specific [`HorizonKind`] variant
10195 /// answers [`Self::horizon_requires_metric_axes`] matching the
10196 /// closed set's own [`HorizonKind::requires_metric_axes`] truth
10197 /// table. Sweep [`HorizonKind::ALL`] so a regression that (a)
10198 /// hard-coded the body to a fixed answer, (b) inverted the
10199 /// projection, or (c) crossed the wires with the antisymmetric
10200 /// partner [`HorizonKind::terminates`] fails HERE at the
10201 /// substrate primitive before drifting through the
10202 /// `metric-axes-required` fixed tag or the peer point surface.
10203 #[test]
10204 fn horizon_requires_metric_axes_returns_horizon_kind_projection_per_kind() {
10205 for populated in HorizonKind::ALL {
10206 let classification = Classification::gate_compute_with_axis(populated);
10207 let mut spec = empty_ephemeral();
10208 spec.classification = Some(classification);
10209 assert_eq!(
10210 spec.horizon_requires_metric_axes(),
10211 populated.requires_metric_axes(),
10212 "authored horizon.kind={populated:?}: horizon_requires_metric_axes() drift",
10213 );
10214 }
10215 }
10216
10217 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10218 /// with `classification: None` routes through the
10219 /// [`Self::resolved_classification`] resolver's substrate default
10220 /// [`Classification::gate_compute`], which uses
10221 /// [`crate::classification::Horizon::default`] whose `kind`
10222 /// defaults to [`HorizonKind::Bounded`] via `#[default]`, and
10223 /// [`HorizonKind::Bounded::requires_metric_axes`] projects
10224 /// `false`, so [`Self::horizon_requires_metric_axes`] returns
10225 /// `false`. Pins the default-arm short-circuit through THREE
10226 /// layers of `Default` ([`Classification::gate_compute`] →
10227 /// [`Horizon::default`] → [`HorizonKind::default`]) reaching this
10228 /// derived-nullary predicate — mirror image of
10229 /// `horizon_terminates_probes_true_on_absent_classification`.
10230 #[test]
10231 fn horizon_requires_metric_axes_probes_false_on_absent_classification() {
10232 let spec = empty_ephemeral();
10233 assert!(spec.classification.is_none());
10234 assert!(
10235 !spec.horizon_requires_metric_axes(),
10236 "absent classification (defaults to gate_compute, horizon.kind=Bounded → requires_metric_axes=false)",
10237 );
10238 }
10239
10240 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10241 /// identically through [`Self::horizon_requires_metric_axes`]
10242 /// AND through
10243 /// `<eph.clone().into::<ProcessSpec>>().classification.horizon_requires_metric_axes()`
10244 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10245 /// classification, `Some(_)` classification on every
10246 /// [`HorizonKind::ALL`] variant) so a future regression on
10247 /// either side of the resolver fails HERE at the parity
10248 /// boundary. Byte-for-byte peer of the sibling
10249 /// `horizon_terminates_matches_point_peer_through_lowered_classification`.
10250 #[test]
10251 fn horizon_requires_metric_axes_matches_point_peer_through_lowered_classification() {
10252 // Absent classification.
10253 let eph = empty_ephemeral();
10254 let lowered: ProcessSpec = eph.clone().into();
10255 assert_eq!(
10256 eph.horizon_requires_metric_axes(),
10257 lowered.classification.horizon_requires_metric_axes(),
10258 "None-classification parity drift",
10259 );
10260 // Authored classification.
10261 for populated in HorizonKind::ALL {
10262 let classification = Classification::gate_compute_with_axis(populated);
10263 let mut eph = empty_ephemeral();
10264 eph.classification = Some(classification);
10265 let lowered: ProcessSpec = eph.clone().into();
10266 assert_eq!(
10267 eph.horizon_requires_metric_axes(),
10268 lowered.classification.horizon_requires_metric_axes(),
10269 "authored horizon.kind={populated:?}: parity drift",
10270 );
10271 }
10272 }
10273
10274 // ── EphemeralSpec::calm_requires_coordination pins ───────────────
10275 //
10276 // Fail-before-pass-after granularity: `calm_requires_coordination`
10277 // did not exist pre-lift on `impl EphemeralSpec` — every consumer
10278 // walking the "does this ephemeral spec require coordination?"
10279 // question went through
10280 // `.resolved_classification().calm.requires_coordination()` or
10281 // through the lowered `ProcessSpec`'s
10282 // `spec.classification.calm.requires_coordination()`. Post-lift the
10283 // THIRD derived-nullary-boolean peer on the ephemeral surface
10284 // (first on the calm axis, after the two horizon-axis peers)
10285 // routes through the SAME [`Self::resolved_classification`]
10286 // resolver + the sibling substrate primitive
10287 // [`crate::classification::Classification::calm_requires_coordination`],
10288 // so the two-surface parity contract holds by construction — a
10289 // regression on either side of the resolver fails at these pins
10290 // before landing at the operator-facing `coordination-required`
10291 // fixed tag in `tatara-check`.
10292
10293 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10294 /// [`Classification`] carries a specific [`CalmClassification`]
10295 /// variant answers [`Self::calm_requires_coordination`] matching
10296 /// the closed set's own
10297 /// [`CalmClassification::requires_coordination`] truth table.
10298 /// Sweep [`CalmClassification::ALL`] so a regression that (a)
10299 /// hard-coded the body to a fixed answer, (b) inverted the
10300 /// projection, or (c) crossed the wires with a sibling
10301 /// classification-axis probe fails HERE at the substrate primitive
10302 /// before drifting through the `coordination-required` fixed tag
10303 /// or the peer point surface.
10304 #[test]
10305 fn calm_requires_coordination_returns_calm_projection_per_kind() {
10306 for populated in CalmClassification::ALL {
10307 let mut classification = Classification::gate_compute();
10308 classification.calm = populated;
10309 let mut spec = empty_ephemeral();
10310 spec.classification = Some(classification);
10311 assert_eq!(
10312 spec.calm_requires_coordination(),
10313 populated.requires_coordination(),
10314 "authored calm={populated:?}: calm_requires_coordination() drift",
10315 );
10316 }
10317 }
10318
10319 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10320 /// with `classification: None` routes through the
10321 /// [`Self::resolved_classification`] resolver's substrate default
10322 /// [`Classification::gate_compute`], which carries
10323 /// [`CalmClassification::default = Monotone`], and
10324 /// [`CalmClassification::Monotone::requires_coordination`] projects
10325 /// `false`, so [`Self::calm_requires_coordination`] returns
10326 /// `false`. Pins the default-arm short-circuit through TWO layers
10327 /// of `Default` ([`Classification::gate_compute`] →
10328 /// [`CalmClassification::default`]) reaching this derived-nullary
10329 /// predicate — distinct from the sibling `horizon_*` absent-
10330 /// classification pins by ONE structural degree (those walk THREE
10331 /// layers of `Default` because horizon has a nested-struct wrapper;
10332 /// this walks TWO because `calm` is a direct scalar). A regression
10333 /// that dropped the resolver hop (silently answering `true` on an
10334 /// absent classification, as if the operator's absence meant
10335 /// "requires coordination") fails HERE at ONE narrow ephemeral-
10336 /// surface site.
10337 #[test]
10338 fn calm_requires_coordination_probes_false_on_absent_classification() {
10339 let spec = empty_ephemeral();
10340 assert!(spec.classification.is_none());
10341 assert!(
10342 !spec.calm_requires_coordination(),
10343 "absent classification (defaults to gate_compute, calm=Monotone → requires_coordination=false)",
10344 );
10345 }
10346
10347 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10348 /// identically through [`Self::calm_requires_coordination`] AND
10349 /// through
10350 /// `<eph.clone().into::<ProcessSpec>>().classification.calm_requires_coordination()`
10351 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10352 /// classification, `Some(_)` classification on every
10353 /// [`CalmClassification::ALL`] variant) so a future regression on
10354 /// either side of the resolver fails HERE at the parity boundary.
10355 /// Byte-for-byte peer of the sibling
10356 /// `horizon_terminates_matches_point_peer_through_lowered_classification`
10357 /// on the calm axis.
10358 #[test]
10359 fn calm_requires_coordination_matches_point_peer_through_lowered_classification() {
10360 // Absent classification.
10361 let eph = empty_ephemeral();
10362 let lowered: ProcessSpec = eph.clone().into();
10363 assert_eq!(
10364 eph.calm_requires_coordination(),
10365 lowered.classification.calm_requires_coordination(),
10366 "None-classification parity drift",
10367 );
10368 // Authored classification.
10369 for populated in CalmClassification::ALL {
10370 let mut classification = Classification::gate_compute();
10371 classification.calm = populated;
10372 let mut eph = empty_ephemeral();
10373 eph.classification = Some(classification);
10374 let lowered: ProcessSpec = eph.clone().into();
10375 assert_eq!(
10376 eph.calm_requires_coordination(),
10377 lowered.classification.calm_requires_coordination(),
10378 "authored calm={populated:?}: parity drift",
10379 );
10380 }
10381 }
10382
10383 // ── EphemeralSpec::data_is_regulated pins ────────────────────────
10384 //
10385 // Fail-before-pass-after granularity: `data_is_regulated` did not
10386 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
10387 // the "does this ephemeral spec carry regulated data?" question
10388 // went through
10389 // `.resolved_classification().data_classification.is_regulated()`
10390 // or through the lowered `ProcessSpec`'s
10391 // `spec.classification.data_classification.is_regulated()`. Post-
10392 // lift the FOURTH derived-nullary-boolean peer on the ephemeral
10393 // surface (first on the data axis, after two horizon-axis peers
10394 // and one calm-axis peer) routes through the SAME
10395 // [`Self::resolved_classification`] resolver + the sibling
10396 // substrate primitive
10397 // [`crate::classification::Classification::data_is_regulated`],
10398 // so the two-surface parity contract holds by construction — a
10399 // regression on either side of the resolver fails at these pins
10400 // before landing at the operator-facing `data-regulated` fixed
10401 // tag in `tatara-check`.
10402
10403 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10404 /// [`Classification`] carries a specific [`DataClassification`]
10405 /// variant answers [`Self::data_is_regulated`] matching the
10406 /// closed set's own [`DataClassification::is_regulated`] truth
10407 /// table. Sweep [`DataClassification::ALL`] so a regression that
10408 /// (a) hard-coded the body to a fixed answer, (b) inverted the
10409 /// projection, or (c) crossed the wires with a sibling
10410 /// classification-axis probe fails HERE at the substrate
10411 /// primitive before drifting through the `data-regulated` fixed
10412 /// tag or the peer point surface.
10413 #[test]
10414 fn data_is_regulated_returns_data_classification_projection_per_kind() {
10415 for populated in DataClassification::ALL {
10416 let mut classification = Classification::gate_compute();
10417 classification.data_classification = populated;
10418 let mut spec = empty_ephemeral();
10419 spec.classification = Some(classification);
10420 assert_eq!(
10421 spec.data_is_regulated(),
10422 populated.is_regulated(),
10423 "authored data_classification={populated:?}: data_is_regulated() drift",
10424 );
10425 }
10426 }
10427
10428 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10429 /// with `classification: None` routes through the
10430 /// [`Self::resolved_classification`] resolver's substrate default
10431 /// [`Classification::gate_compute`], which carries
10432 /// [`DataClassification::default = Internal`], and
10433 /// [`DataClassification::Internal::is_regulated`] projects
10434 /// `false`, so [`Self::data_is_regulated`] returns `false`. Pins
10435 /// the default-arm short-circuit through TWO layers of `Default`
10436 /// ([`Classification::gate_compute`] →
10437 /// [`DataClassification::default`]) reaching this derived-nullary
10438 /// predicate — byte-for-byte structural peer of the sibling
10439 /// `calm_requires_coordination_probes_false_on_absent_classification`
10440 /// on the classification-data axis, distinct from the two
10441 /// `horizon_*` absent-classification pins by ONE structural
10442 /// degree (those walk THREE layers because horizon has a nested-
10443 /// struct wrapper; this walks TWO because `data_classification`
10444 /// is a direct scalar). A regression that dropped the resolver
10445 /// hop (silently answering `true` on an absent classification,
10446 /// as if the operator's absence meant "regulated data") fails
10447 /// HERE at ONE narrow ephemeral-surface site.
10448 #[test]
10449 fn data_is_regulated_probes_false_on_absent_classification() {
10450 let spec = empty_ephemeral();
10451 assert!(spec.classification.is_none());
10452 assert!(
10453 !spec.data_is_regulated(),
10454 "absent classification (defaults to gate_compute, data_classification=Internal → is_regulated=false)",
10455 );
10456 }
10457
10458 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10459 /// identically through [`Self::data_is_regulated`] AND through
10460 /// `<eph.clone().into::<ProcessSpec>>().classification.data_is_regulated()`
10461 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10462 /// classification, `Some(_)` classification on every
10463 /// [`DataClassification::ALL`] variant) so a future regression on
10464 /// either side of the resolver fails HERE at the parity boundary.
10465 /// Byte-for-byte peer of the sibling
10466 /// `calm_requires_coordination_matches_point_peer_through_lowered_classification`
10467 /// on the data axis.
10468 #[test]
10469 fn data_is_regulated_matches_point_peer_through_lowered_classification() {
10470 // Absent classification.
10471 let eph = empty_ephemeral();
10472 let lowered: ProcessSpec = eph.clone().into();
10473 assert_eq!(
10474 eph.data_is_regulated(),
10475 lowered.classification.data_is_regulated(),
10476 "None-classification parity drift",
10477 );
10478 // Authored classification.
10479 for populated in DataClassification::ALL {
10480 let mut classification = Classification::gate_compute();
10481 classification.data_classification = populated;
10482 let mut eph = empty_ephemeral();
10483 eph.classification = Some(classification);
10484 let lowered: ProcessSpec = eph.clone().into();
10485 assert_eq!(
10486 eph.data_is_regulated(),
10487 lowered.classification.data_is_regulated(),
10488 "authored data_classification={populated:?}: parity drift",
10489 );
10490 }
10491 }
10492
10493 // ── EphemeralSpec::data_is_restricted pins ───────────────────────
10494 //
10495 // Fail-before-pass-after granularity: `data_is_restricted` did not
10496 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
10497 // the "does this ephemeral spec require access controls?" question
10498 // went through
10499 // `.resolved_classification().data_classification.is_restricted()`
10500 // or through the lowered `ProcessSpec`'s
10501 // `spec.classification.data_classification.is_restricted()`. Post-
10502 // lift the FIFTH derived-nullary-boolean peer on the ephemeral
10503 // surface (second on the data axis, after
10504 // [`Self::data_is_regulated`] opened the axis) routes through the
10505 // SAME [`Self::resolved_classification`] resolver + the sibling
10506 // substrate primitive
10507 // [`crate::classification::Classification::data_is_restricted`],
10508 // so the two-surface parity contract holds by construction — a
10509 // regression on either side of the resolver fails at these pins
10510 // before landing at the operator-facing `data-restricted` fixed
10511 // tag in `tatara-check`. FIRST direct-scalar ephemeral-surface
10512 // peer whose absent-classification baseline projects to `true`
10513 // rather than `false`.
10514
10515 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10516 /// [`Classification`] carries a specific [`DataClassification`]
10517 /// variant answers [`Self::data_is_restricted`] matching the
10518 /// closed set's own [`DataClassification::is_restricted`] truth
10519 /// table. Sweep [`DataClassification::ALL`] so a regression that
10520 /// (a) hard-coded the body to a fixed answer, (b) inverted the
10521 /// projection, or (c) crossed the wires with the sibling
10522 /// [`DataClassification::is_regulated`] projection fails HERE at
10523 /// the substrate primitive before drifting through the
10524 /// `data-restricted` fixed tag or the peer point surface.
10525 #[test]
10526 fn data_is_restricted_returns_data_classification_projection_per_kind() {
10527 for populated in DataClassification::ALL {
10528 let mut classification = Classification::gate_compute();
10529 classification.data_classification = populated;
10530 let mut spec = empty_ephemeral();
10531 spec.classification = Some(classification);
10532 assert_eq!(
10533 spec.data_is_restricted(),
10534 populated.is_restricted(),
10535 "authored data_classification={populated:?}: data_is_restricted() drift",
10536 );
10537 }
10538 }
10539
10540 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10541 /// with `classification: None` routes through the
10542 /// [`Self::resolved_classification`] resolver's substrate default
10543 /// [`Classification::gate_compute`], which carries
10544 /// [`DataClassification::default = Internal`], and
10545 /// [`DataClassification::Internal::is_restricted`] projects
10546 /// `true`, so [`Self::data_is_restricted`] returns `true`. Pins
10547 /// the default-arm short-circuit through TWO layers of `Default`
10548 /// ([`Classification::gate_compute`] →
10549 /// [`DataClassification::default`]) reaching this derived-nullary
10550 /// predicate. FIRST direct-scalar ephemeral-surface peer whose
10551 /// absent-classification baseline answers `true`, not `false`
10552 /// (the four earlier direct-scalar peers on this surface —
10553 /// `data_is_regulated`, `calm_requires_coordination`, plus the
10554 /// nested-struct `horizon_requires_metric_axes` — all project
10555 /// `false` on the same absent classification, and only the
10556 /// sibling nested-struct `horizon_terminates` projects `true`).
10557 /// A regression that dropped the resolver hop (silently answering
10558 /// `false` on an absent classification, as if the operator's
10559 /// absence meant "freely distributable"), or that inverted the
10560 /// projection while the closed-set primitive stayed intact,
10561 /// fails HERE at ONE narrow ephemeral-surface site.
10562 #[test]
10563 fn data_is_restricted_probes_true_on_absent_classification() {
10564 let spec = empty_ephemeral();
10565 assert!(spec.classification.is_none());
10566 assert!(
10567 spec.data_is_restricted(),
10568 "absent classification (defaults to gate_compute, data_classification=Internal → is_restricted=true)",
10569 );
10570 }
10571
10572 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10573 /// identically through [`Self::data_is_restricted`] AND through
10574 /// `<eph.clone().into::<ProcessSpec>>().classification.data_is_restricted()`
10575 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10576 /// classification, `Some(_)` classification on every
10577 /// [`DataClassification::ALL`] variant) so a future regression on
10578 /// either side of the resolver fails HERE at the parity boundary.
10579 /// Byte-for-byte peer of the sibling
10580 /// `data_is_regulated_matches_point_peer_through_lowered_classification`
10581 /// on the same classification-data axis, published a second time
10582 /// through the antisymmetric closed-set projection.
10583 #[test]
10584 fn data_is_restricted_matches_point_peer_through_lowered_classification() {
10585 // Absent classification.
10586 let eph = empty_ephemeral();
10587 let lowered: ProcessSpec = eph.clone().into();
10588 assert_eq!(
10589 eph.data_is_restricted(),
10590 lowered.classification.data_is_restricted(),
10591 "None-classification parity drift",
10592 );
10593 // Authored classification.
10594 for populated in DataClassification::ALL {
10595 let mut classification = Classification::gate_compute();
10596 classification.data_classification = populated;
10597 let mut eph = empty_ephemeral();
10598 eph.classification = Some(classification);
10599 let lowered: ProcessSpec = eph.clone().into();
10600 assert_eq!(
10601 eph.data_is_restricted(),
10602 lowered.classification.data_is_restricted(),
10603 "authored data_classification={populated:?}: parity drift",
10604 );
10605 }
10606 }
10607
10608 /// COMPOSED IMPLICATION pin — the ephemeral-surface counterpart of
10609 /// the closed-set-internal
10610 /// `data_classification_regulated_implies_restricted` and its
10611 /// parent-composed peer
10612 /// `classification_data_is_regulated_implies_data_is_restricted_over_all`:
10613 /// for every ([`EphemeralSpec`] with authored classification
10614 /// carrying every [`DataClassification`] variant, plus the
10615 /// absent-classification case), the resolver-hop probe pair
10616 /// satisfies `data_is_regulated() ⇒ data_is_restricted()`. Pins
10617 /// the implication contract at the ephemeral-surface site so a
10618 /// regression that (a) inverted the ephemeral
10619 /// [`Self::data_is_regulated`] resolver hop, (b) inverted the
10620 /// ephemeral [`Self::data_is_restricted`] resolver hop, or (c)
10621 /// crossed their wires while the underlying substrate primitives
10622 /// stayed intact fails HERE. FIRST ephemeral-surface corner-peer
10623 /// pair whose two projections carry a non-trivial closed-set-
10624 /// internal implication relationship.
10625 #[test]
10626 fn ephemeral_data_is_regulated_implies_data_is_restricted_over_all() {
10627 // Absent classification.
10628 let eph = empty_ephemeral();
10629 assert!(
10630 !eph.data_is_regulated() || eph.data_is_restricted(),
10631 "None-classification: data_is_regulated ⇒ data_is_restricted violated",
10632 );
10633 // Authored classification.
10634 for populated in DataClassification::ALL {
10635 let mut classification = Classification::gate_compute();
10636 classification.data_classification = populated;
10637 let mut eph = empty_ephemeral();
10638 eph.classification = Some(classification);
10639 assert!(
10640 !eph.data_is_regulated() || eph.data_is_restricted(),
10641 "authored data_classification={populated:?}: data_is_regulated ⇒ data_is_restricted violated",
10642 );
10643 }
10644 }
10645
10646 // ── EphemeralSpec::point_is_endomorphic pins ─────────────────────
10647 //
10648 // Fail-before-pass-after granularity: `point_is_endomorphic` did
10649 // not exist pre-lift on `impl EphemeralSpec` — every consumer
10650 // walking the "does this ephemeral spec's point-type project to
10651 // the 1→1 endomorphic bucket?" question went through
10652 // `.resolved_classification().point_type.is_endomorphic()` or the
10653 // lowered `ProcessSpec`'s
10654 // `spec.classification.point_type.is_endomorphic()`. Post-lift the
10655 // SIXTH derived-nullary-boolean peer on the ephemeral surface
10656 // (first on the `point_type` axis) routes through the SAME
10657 // [`Self::resolved_classification`] resolver + the sibling
10658 // substrate primitive
10659 // [`crate::classification::Classification::point_is_endomorphic`],
10660 // so the two-surface parity contract holds by construction — a
10661 // regression on either side of the resolver fails at these pins
10662 // before landing at the operator-facing `endomorphic-point` fixed
10663 // tag in `tatara-check`.
10664
10665 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10666 /// [`Classification`] carries a specific [`ConvergencePointType`]
10667 /// variant answers [`Self::point_is_endomorphic`] matching the
10668 /// closed set's own [`ConvergencePointType::is_endomorphic`] truth
10669 /// table. Sweep [`ConvergencePointType::ALL`] so a regression that
10670 /// (a) hard-coded the body to a fixed answer, (b) inverted the
10671 /// projection, or (c) crossed the wires with the sibling
10672 /// [`ConvergencePointType::is_diffusive`] /
10673 /// [`ConvergencePointType::is_convergent`] projections fails
10674 /// HERE at the substrate primitive before drifting through the
10675 /// `endomorphic-point` fixed tag or the peer point surface.
10676 #[test]
10677 fn point_is_endomorphic_returns_point_type_projection_per_kind() {
10678 for populated in ConvergencePointType::ALL {
10679 let mut classification = Classification::gate_compute();
10680 classification.point_type = populated;
10681 let mut spec = empty_ephemeral();
10682 spec.classification = Some(classification);
10683 assert_eq!(
10684 spec.point_is_endomorphic(),
10685 populated.is_endomorphic(),
10686 "authored point_type={populated:?}: point_is_endomorphic() drift",
10687 );
10688 }
10689 }
10690
10691 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10692 /// with `classification: None` routes through the
10693 /// [`Self::resolved_classification`] resolver's substrate default
10694 /// [`Classification::gate_compute`], which carries
10695 /// [`ConvergencePointType::Gate`] (a convergent barrier, not an
10696 /// endomorphism), and
10697 /// [`ConvergencePointType::Gate::is_endomorphic`] projects `false`,
10698 /// so [`Self::point_is_endomorphic`] returns `false`. Pins the
10699 /// resolver's chosen-field baseline at ONE narrow site — a
10700 /// regression that dropped the resolver hop, or that promoted
10701 /// [`ConvergencePointType::Transform`] to the gate-compute
10702 /// baseline (silently retargeting every unadorned ephemeral
10703 /// spec's topology bucket), fails HERE at ONE narrow ephemeral-
10704 /// surface site. FIRST direct-scalar ephemeral-surface peer whose
10705 /// absent-classification baseline is a chosen-field answer on the
10706 /// resolver's [`Classification::gate_compute`] default rather
10707 /// than a substrate-`#[default]` short-circuit on the closed-set
10708 /// side ([`ConvergencePointType`] has no `impl Default`).
10709 #[test]
10710 fn point_is_endomorphic_probes_false_on_absent_classification() {
10711 let spec = empty_ephemeral();
10712 assert!(spec.classification.is_none());
10713 assert!(
10714 !spec.point_is_endomorphic(),
10715 "absent classification (defaults to gate_compute, point_type=Gate → is_endomorphic=false)",
10716 );
10717 }
10718
10719 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10720 /// identically through [`Self::point_is_endomorphic`] AND through
10721 /// `<eph.clone().into::<ProcessSpec>>().classification.point_is_endomorphic()`
10722 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10723 /// classification, `Some(_)` classification on every
10724 /// [`ConvergencePointType::ALL`] variant) so a future regression
10725 /// on either side of the resolver fails HERE at the parity
10726 /// boundary. Byte-for-byte peer of the sibling
10727 /// `data_is_restricted_matches_point_peer_through_lowered_classification`
10728 /// on a DIFFERENT closed-set axis, published a first time through
10729 /// the `point_type` closed-set projection.
10730 #[test]
10731 fn point_is_endomorphic_matches_point_peer_through_lowered_classification() {
10732 // Absent classification.
10733 let eph = empty_ephemeral();
10734 let lowered: ProcessSpec = eph.clone().into();
10735 assert_eq!(
10736 eph.point_is_endomorphic(),
10737 lowered.classification.point_is_endomorphic(),
10738 "None-classification parity drift",
10739 );
10740 // Authored classification.
10741 for populated in ConvergencePointType::ALL {
10742 let mut classification = Classification::gate_compute();
10743 classification.point_type = populated;
10744 let mut eph = empty_ephemeral();
10745 eph.classification = Some(classification);
10746 let lowered: ProcessSpec = eph.clone().into();
10747 assert_eq!(
10748 eph.point_is_endomorphic(),
10749 lowered.classification.point_is_endomorphic(),
10750 "authored point_type={populated:?}: parity drift",
10751 );
10752 }
10753 }
10754
10755 // ── EphemeralSpec::point_is_diffusive pins ───────────────────────
10756 //
10757 // Fail-before-pass-after granularity: `point_is_diffusive` did not
10758 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
10759 // the "does this ephemeral spec's point-type project to the 1→N
10760 // diffusive fan-out bucket?" question went through
10761 // `.resolved_classification().point_type.is_diffusive()` or the
10762 // lowered `ProcessSpec`'s
10763 // `spec.classification.point_type.is_diffusive()`. Post-lift the
10764 // SEVENTH derived-nullary-boolean peer on the ephemeral surface
10765 // (SECOND on the `point_type` axis) routes through the SAME
10766 // [`Self::resolved_classification`] resolver + the sibling
10767 // substrate primitive
10768 // [`crate::classification::Classification::point_is_diffusive`],
10769 // so the two-surface parity contract holds by construction.
10770
10771 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10772 /// [`Classification`] carries a specific [`ConvergencePointType`]
10773 /// variant answers [`Self::point_is_diffusive`] matching the
10774 /// closed set's own [`ConvergencePointType::is_diffusive`] truth
10775 /// table. Sweep [`ConvergencePointType::ALL`] so a regression that
10776 /// (a) hard-coded the body to a fixed answer, (b) inverted the
10777 /// projection, or (c) crossed the wires with the sibling
10778 /// [`ConvergencePointType::is_endomorphic`] /
10779 /// [`ConvergencePointType::is_convergent`] projections fails HERE
10780 /// at the substrate primitive before drifting through the
10781 /// `diffusive-point` fixed tag or the peer point surface.
10782 #[test]
10783 fn point_is_diffusive_returns_point_type_projection_per_kind() {
10784 for populated in ConvergencePointType::ALL {
10785 let mut classification = Classification::gate_compute();
10786 classification.point_type = populated;
10787 let mut spec = empty_ephemeral();
10788 spec.classification = Some(classification);
10789 assert_eq!(
10790 spec.point_is_diffusive(),
10791 populated.is_diffusive(),
10792 "authored point_type={populated:?}: point_is_diffusive() drift",
10793 );
10794 }
10795 }
10796
10797 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10798 /// with `classification: None` routes through the
10799 /// [`Self::resolved_classification`] resolver's substrate default
10800 /// [`Classification::gate_compute`], which carries
10801 /// [`ConvergencePointType::Gate`] (a convergent barrier, not a
10802 /// diffusive fan-out), and
10803 /// [`ConvergencePointType::Gate::is_diffusive`] projects `false`,
10804 /// so [`Self::point_is_diffusive`] returns `false`. Pins the
10805 /// resolver's chosen-field baseline at ONE narrow site.
10806 #[test]
10807 fn point_is_diffusive_probes_false_on_absent_classification() {
10808 let spec = empty_ephemeral();
10809 assert!(spec.classification.is_none());
10810 assert!(
10811 !spec.point_is_diffusive(),
10812 "absent classification (defaults to gate_compute, point_type=Gate → is_diffusive=false)",
10813 );
10814 }
10815
10816 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10817 /// identically through [`Self::point_is_diffusive`] AND through
10818 /// `<eph.clone().into::<ProcessSpec>>().classification.point_is_diffusive()`
10819 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10820 /// classification, `Some(_)` classification on every
10821 /// [`ConvergencePointType::ALL`] variant) so a future regression
10822 /// on either side of the resolver fails HERE at the parity
10823 /// boundary. Byte-for-byte peer of
10824 /// `point_is_endomorphic_matches_point_peer_through_lowered_classification`
10825 /// on the SAME closed-set axis via a sibling projection.
10826 #[test]
10827 fn point_is_diffusive_matches_point_peer_through_lowered_classification() {
10828 // Absent classification.
10829 let eph = empty_ephemeral();
10830 let lowered: ProcessSpec = eph.clone().into();
10831 assert_eq!(
10832 eph.point_is_diffusive(),
10833 lowered.classification.point_is_diffusive(),
10834 "None-classification parity drift",
10835 );
10836 // Authored classification.
10837 for populated in ConvergencePointType::ALL {
10838 let mut classification = Classification::gate_compute();
10839 classification.point_type = populated;
10840 let mut eph = empty_ephemeral();
10841 eph.classification = Some(classification);
10842 let lowered: ProcessSpec = eph.clone().into();
10843 assert_eq!(
10844 eph.point_is_diffusive(),
10845 lowered.classification.point_is_diffusive(),
10846 "authored point_type={populated:?}: parity drift",
10847 );
10848 }
10849 }
10850
10851 /// MUTEX pin — [`Self::point_is_endomorphic`] AND
10852 /// [`Self::point_is_diffusive`] are NEVER simultaneously true for
10853 /// ANY [`EphemeralSpec`] (authored or defaulted), since the
10854 /// underlying [`ConvergencePointType`] closed set carves its
10855 /// eight variants into THREE disjoint buckets. Sweep the absent-
10856 /// classification case + every [`ConvergencePointType::ALL`]
10857 /// variant so a regression that crossed the wires between the
10858 /// two ephemeral-surface corner peers (one probe silently
10859 /// composing the wrong closed-set arm at the resolver-hop layer)
10860 /// fails HERE rather than at every downstream consumer that
10861 /// trusts the two probes partition the resolver's output into
10862 /// disjoint buckets. FIRST ephemeral-surface corner-peer pair on
10863 /// the `point_type` axis whose two projections carry a non-
10864 /// trivial closed-set-internal MUTEX relationship (distinct from
10865 /// the sibling `data`-axis pair whose two projections carry a
10866 /// non-trivial IMPLICATION relationship, sealed by
10867 /// `ephemeral_data_is_regulated_implies_data_is_restricted_over_all`).
10868 #[test]
10869 fn ephemeral_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all() {
10870 // Absent classification.
10871 let eph = empty_ephemeral();
10872 assert!(
10873 !(eph.point_is_endomorphic() && eph.point_is_diffusive()),
10874 "None-classification: point_is_endomorphic AND point_is_diffusive both true (mutex violated)",
10875 );
10876 // Authored classification.
10877 for populated in ConvergencePointType::ALL {
10878 let mut classification = Classification::gate_compute();
10879 classification.point_type = populated;
10880 let mut eph = empty_ephemeral();
10881 eph.classification = Some(classification);
10882 assert!(
10883 !(eph.point_is_endomorphic() && eph.point_is_diffusive()),
10884 "authored point_type={populated:?}: point_is_endomorphic AND point_is_diffusive both true (mutex violated)",
10885 );
10886 }
10887 }
10888
10889 // ── EphemeralSpec::point_is_convergent pins ──────────────────────
10890 //
10891 // Fail-before-pass-after granularity: `point_is_convergent` did
10892 // not exist pre-lift on `impl EphemeralSpec` — every consumer
10893 // walking the "does this ephemeral spec's point-type project to
10894 // the N→1 convergent fan-in bucket?" question went through
10895 // `.resolved_classification().point_type.is_convergent()` or the
10896 // lowered `ProcessSpec`'s
10897 // `spec.classification.point_type.is_convergent()`. Post-lift the
10898 // EIGHTH derived-nullary-boolean peer on the ephemeral surface
10899 // (THIRD on the `point_type` axis) routes through the SAME
10900 // [`Self::resolved_classification`] resolver + the sibling
10901 // substrate primitive
10902 // [`crate::classification::Classification::point_is_convergent`],
10903 // so the two-surface parity contract holds by construction, AND
10904 // the THREE `point_type`-axis peers on this surface close into
10905 // the FULL three-way XOR partition contract.
10906
10907 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
10908 /// [`Classification`] carries a specific [`ConvergencePointType`]
10909 /// variant answers [`Self::point_is_convergent`] matching the
10910 /// closed set's own [`ConvergencePointType::is_convergent`] truth
10911 /// table. Sweep [`ConvergencePointType::ALL`] so a regression that
10912 /// (a) hard-coded the body to a fixed answer, (b) inverted the
10913 /// projection, or (c) crossed the wires with the sibling
10914 /// [`ConvergencePointType::is_endomorphic`] /
10915 /// [`ConvergencePointType::is_diffusive`] projections fails HERE
10916 /// at the substrate primitive before drifting through the
10917 /// `convergent-point` fixed tag or the peer point surface.
10918 #[test]
10919 fn point_is_convergent_returns_point_type_projection_per_kind() {
10920 for populated in ConvergencePointType::ALL {
10921 let mut classification = Classification::gate_compute();
10922 classification.point_type = populated;
10923 let mut spec = empty_ephemeral();
10924 spec.classification = Some(classification);
10925 assert_eq!(
10926 spec.point_is_convergent(),
10927 populated.is_convergent(),
10928 "authored point_type={populated:?}: point_is_convergent() drift",
10929 );
10930 }
10931 }
10932
10933 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
10934 /// with `classification: None` routes through the
10935 /// [`Self::resolved_classification`] resolver's substrate default
10936 /// [`Classification::gate_compute`], which carries
10937 /// [`ConvergencePointType::Gate`] (the canonical convergent
10938 /// barrier), and [`ConvergencePointType::Gate::is_convergent`]
10939 /// projects `true`, so [`Self::point_is_convergent`] returns
10940 /// `true`. Pins the resolver's chosen-field baseline at ONE
10941 /// narrow site — FIRST direct-scalar ephemeral-surface peer whose
10942 /// absent-classification baseline projects `true` through the
10943 /// resolver's chosen-field answer, mirror-inverted from the two
10944 /// sibling `point_is_endomorphic` / `point_is_diffusive`
10945 /// ephemeral-surface baselines which both project `false`.
10946 #[test]
10947 fn point_is_convergent_probes_true_on_absent_classification() {
10948 let spec = empty_ephemeral();
10949 assert!(spec.classification.is_none());
10950 assert!(
10951 spec.point_is_convergent(),
10952 "absent classification (defaults to gate_compute, point_type=Gate → is_convergent=true)",
10953 );
10954 }
10955
10956 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
10957 /// identically through [`Self::point_is_convergent`] AND through
10958 /// `<eph.clone().into::<ProcessSpec>>().classification.point_is_convergent()`
10959 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
10960 /// classification, `Some(_)` classification on every
10961 /// [`ConvergencePointType::ALL`] variant) so a future regression
10962 /// on either side of the resolver fails HERE at the parity
10963 /// boundary. Byte-for-byte peer of
10964 /// `point_is_endomorphic_matches_point_peer_through_lowered_classification`
10965 /// and
10966 /// `point_is_diffusive_matches_point_peer_through_lowered_classification`
10967 /// on the SAME closed-set axis via a sibling projection.
10968 #[test]
10969 fn point_is_convergent_matches_point_peer_through_lowered_classification() {
10970 // Absent classification.
10971 let eph = empty_ephemeral();
10972 let lowered: ProcessSpec = eph.clone().into();
10973 assert_eq!(
10974 eph.point_is_convergent(),
10975 lowered.classification.point_is_convergent(),
10976 "None-classification parity drift",
10977 );
10978 // Authored classification.
10979 for populated in ConvergencePointType::ALL {
10980 let mut classification = Classification::gate_compute();
10981 classification.point_type = populated;
10982 let mut eph = empty_ephemeral();
10983 eph.classification = Some(classification);
10984 let lowered: ProcessSpec = eph.clone().into();
10985 assert_eq!(
10986 eph.point_is_convergent(),
10987 lowered.classification.point_is_convergent(),
10988 "authored point_type={populated:?}: parity drift",
10989 );
10990 }
10991 }
10992
10993 /// THREE-WAY XOR PARTITION pin — for the absent-classification
10994 /// baseline AND every [`ConvergencePointType::ALL`] variant,
10995 /// EXACTLY ONE of [`Self::point_is_endomorphic`],
10996 /// [`Self::point_is_diffusive`], and [`Self::point_is_convergent`]
10997 /// returns `true`. Closes the mutex pair
10998 /// `ephemeral_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`
10999 /// into the FULL ternary XOR partition contract on the ephemeral
11000 /// surface — the resolver-hop peer of the parent-composed
11001 /// `classification_point_type_probes_form_three_way_xor_partition_over_all`
11002 /// test. Guarantees the absent-classification case lands in the
11003 /// convergent bucket (`gate_compute` → Gate → is_convergent =
11004 /// true), so every unadorned `(defephemeral …)` audits under a
11005 /// definite non-empty topology bucket.
11006 #[test]
11007 fn ephemeral_point_type_probes_form_three_way_xor_partition_over_all() {
11008 // Absent classification.
11009 let eph = empty_ephemeral();
11010 let buckets = [
11011 eph.point_is_endomorphic(),
11012 eph.point_is_diffusive(),
11013 eph.point_is_convergent(),
11014 ];
11015 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11016 assert_eq!(
11017 hits, 1,
11018 "None-classification: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
11019 );
11020 // Authored classification.
11021 for populated in ConvergencePointType::ALL {
11022 let mut classification = Classification::gate_compute();
11023 classification.point_type = populated;
11024 let mut eph = empty_ephemeral();
11025 eph.classification = Some(classification);
11026 let buckets = [
11027 eph.point_is_endomorphic(),
11028 eph.point_is_diffusive(),
11029 eph.point_is_convergent(),
11030 ];
11031 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11032 assert_eq!(
11033 hits, 1,
11034 "authored point_type={populated:?}: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
11035 );
11036 }
11037 }
11038
11039 // ── EphemeralSpec::substrate_is_resource pins ────────────────────
11040 //
11041 // Fail-before-pass-after granularity: `substrate_is_resource` did
11042 // not exist pre-lift on `impl EphemeralSpec` — every consumer
11043 // walking the "does this ephemeral spec's substrate project to
11044 // the resource plane?" question went through
11045 // `.resolved_classification().substrate.is_resource()` or the
11046 // lowered `ProcessSpec`'s
11047 // `spec.classification.substrate.is_resource()`. Post-lift the
11048 // NINTH derived-nullary-boolean peer on the ephemeral surface
11049 // (FIRST on the `substrate` axis) routes through the SAME
11050 // [`Self::resolved_classification`] resolver + the sibling
11051 // substrate primitive
11052 // [`crate::classification::Classification::substrate_is_resource`],
11053 // so the two-surface parity contract holds by construction.
11054
11055 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11056 /// [`Classification`] carries a specific
11057 /// [`crate::classification::SubstrateType`] variant answers
11058 /// [`Self::substrate_is_resource`] matching the closed set's own
11059 /// [`crate::classification::SubstrateType::is_resource`] truth
11060 /// table. Sweep [`crate::classification::SubstrateType::ALL`]
11061 /// so a regression that (a) hard-coded the body to a fixed
11062 /// answer, (b) inverted the projection, or (c) crossed the wires
11063 /// with the sibling
11064 /// [`crate::classification::SubstrateType::is_policy`] /
11065 /// [`crate::classification::SubstrateType::is_telemetry`]
11066 /// projections fails HERE at the substrate primitive before
11067 /// drifting through the `resource-substrate` fixed tag or the
11068 /// peer point surface.
11069 #[test]
11070 fn substrate_is_resource_returns_substrate_projection_per_kind() {
11071 for populated in SubstrateType::ALL {
11072 let mut classification = Classification::gate_compute();
11073 classification.substrate = populated;
11074 let mut spec = empty_ephemeral();
11075 spec.classification = Some(classification);
11076 assert_eq!(
11077 spec.substrate_is_resource(),
11078 populated.is_resource(),
11079 "authored substrate={populated:?}: substrate_is_resource() drift",
11080 );
11081 }
11082 }
11083
11084 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11085 /// with `classification: None` routes through the
11086 /// [`Self::resolved_classification`] resolver's substrate default
11087 /// [`Classification::gate_compute`], which carries
11088 /// [`crate::classification::SubstrateType::Compute`] (the
11089 /// canonical resource-plane substrate), and
11090 /// [`crate::classification::SubstrateType::Compute::is_resource`]
11091 /// projects `true`, so [`Self::substrate_is_resource`] returns
11092 /// `true`. Pins the resolver's chosen-field baseline at ONE
11093 /// narrow site — mirror-aligned with the sibling
11094 /// `point_is_convergent_probes_true_on_absent_classification`
11095 /// baseline (both projections on `gate_compute` chosen fields
11096 /// answer `true`).
11097 #[test]
11098 fn substrate_is_resource_probes_true_on_absent_classification() {
11099 let spec = empty_ephemeral();
11100 assert!(spec.classification.is_none());
11101 assert!(
11102 spec.substrate_is_resource(),
11103 "absent classification (defaults to gate_compute, substrate=Compute → is_resource=true)",
11104 );
11105 }
11106
11107 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11108 /// identically through [`Self::substrate_is_resource`] AND through
11109 /// `<eph.clone().into::<ProcessSpec>>().classification.substrate_is_resource()`
11110 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11111 /// classification, `Some(_)` classification on every
11112 /// [`crate::classification::SubstrateType::ALL`] variant) so a
11113 /// future regression on either side of the resolver fails HERE
11114 /// at the parity boundary. Byte-for-byte peer of
11115 /// `point_is_convergent_matches_point_peer_through_lowered_classification`
11116 /// on a sibling classification axis.
11117 #[test]
11118 fn substrate_is_resource_matches_point_peer_through_lowered_classification() {
11119 // Absent classification.
11120 let eph = empty_ephemeral();
11121 let lowered: ProcessSpec = eph.clone().into();
11122 assert_eq!(
11123 eph.substrate_is_resource(),
11124 lowered.classification.substrate_is_resource(),
11125 "None-classification parity drift",
11126 );
11127 // Authored classification.
11128 for populated in SubstrateType::ALL {
11129 let mut classification = Classification::gate_compute();
11130 classification.substrate = populated;
11131 let mut eph = empty_ephemeral();
11132 eph.classification = Some(classification);
11133 let lowered: ProcessSpec = eph.clone().into();
11134 assert_eq!(
11135 eph.substrate_is_resource(),
11136 lowered.classification.substrate_is_resource(),
11137 "authored substrate={populated:?}: parity drift",
11138 );
11139 }
11140 }
11141
11142 // ── EphemeralSpec::substrate_is_policy pins ──────────────────────
11143 //
11144 // Fail-before-pass-after granularity: `substrate_is_policy` did
11145 // not exist pre-lift on `impl EphemeralSpec` — every consumer
11146 // walking the "does this ephemeral spec's substrate project to
11147 // the policy plane?" question went through
11148 // `.resolved_classification().substrate.is_policy()` or the
11149 // lowered `ProcessSpec`'s
11150 // `spec.classification.substrate.is_policy()`. Post-lift the
11151 // TENTH derived-nullary-boolean peer on the ephemeral surface
11152 // (SECOND on the `substrate` axis) routes through the SAME
11153 // [`Self::resolved_classification`] resolver + the sibling
11154 // substrate primitive
11155 // [`crate::classification::Classification::substrate_is_policy`],
11156 // so the two-surface parity contract holds by construction, AND
11157 // the two `substrate`-axis peers on this surface open the
11158 // MUTEX pair on the axis via
11159 // `ephemeral_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`.
11160
11161 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11162 /// [`Classification`] carries a specific
11163 /// [`crate::classification::SubstrateType`] variant answers
11164 /// [`Self::substrate_is_policy`] matching the closed set's own
11165 /// [`crate::classification::SubstrateType::is_policy`] truth
11166 /// table. Sweep [`crate::classification::SubstrateType::ALL`]
11167 /// so a regression that (a) hard-coded the body to a fixed
11168 /// answer, (b) inverted the projection, or (c) crossed the wires
11169 /// with the sibling
11170 /// [`crate::classification::SubstrateType::is_resource`] /
11171 /// [`crate::classification::SubstrateType::is_telemetry`]
11172 /// projections fails HERE at the substrate primitive before
11173 /// drifting through the `policy-substrate` fixed tag or the
11174 /// peer point surface.
11175 #[test]
11176 fn substrate_is_policy_returns_substrate_projection_per_kind() {
11177 for populated in SubstrateType::ALL {
11178 let mut classification = Classification::gate_compute();
11179 classification.substrate = populated;
11180 let mut spec = empty_ephemeral();
11181 spec.classification = Some(classification);
11182 assert_eq!(
11183 spec.substrate_is_policy(),
11184 populated.is_policy(),
11185 "authored substrate={populated:?}: substrate_is_policy() drift",
11186 );
11187 }
11188 }
11189
11190 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11191 /// with `classification: None` routes through the
11192 /// [`Self::resolved_classification`] resolver's substrate default
11193 /// [`Classification::gate_compute`], which carries
11194 /// [`crate::classification::SubstrateType::Compute`] (the
11195 /// canonical resource-plane substrate, NOT a policy plane), and
11196 /// [`crate::classification::SubstrateType::Compute::is_policy`]
11197 /// projects `false`, so [`Self::substrate_is_policy`] returns
11198 /// `false`. Pins the resolver's chosen-field baseline at ONE
11199 /// narrow site — mirror-inverted from the sibling
11200 /// `substrate_is_resource_probes_true_on_absent_classification`
11201 /// (both projections on `gate_compute`'s chosen `substrate`
11202 /// field, but the sibling answers `true` where this one
11203 /// answers `false` — the closed set's disjoint plane partition
11204 /// forbids both being true).
11205 #[test]
11206 fn substrate_is_policy_probes_false_on_absent_classification() {
11207 let spec = empty_ephemeral();
11208 assert!(spec.classification.is_none());
11209 assert!(
11210 !spec.substrate_is_policy(),
11211 "absent classification (defaults to gate_compute, substrate=Compute → is_policy=false)",
11212 );
11213 }
11214
11215 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11216 /// identically through [`Self::substrate_is_policy`] AND through
11217 /// `<eph.clone().into::<ProcessSpec>>().classification.substrate_is_policy()`
11218 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11219 /// classification, `Some(_)` classification on every
11220 /// [`crate::classification::SubstrateType::ALL`] variant) so a
11221 /// future regression on either side of the resolver fails HERE
11222 /// at the parity boundary. Byte-for-byte peer of
11223 /// `substrate_is_resource_matches_point_peer_through_lowered_classification`
11224 /// on the SAME closed-set axis via a sibling projection.
11225 #[test]
11226 fn substrate_is_policy_matches_point_peer_through_lowered_classification() {
11227 // Absent classification.
11228 let eph = empty_ephemeral();
11229 let lowered: ProcessSpec = eph.clone().into();
11230 assert_eq!(
11231 eph.substrate_is_policy(),
11232 lowered.classification.substrate_is_policy(),
11233 "None-classification parity drift",
11234 );
11235 // Authored classification.
11236 for populated in SubstrateType::ALL {
11237 let mut classification = Classification::gate_compute();
11238 classification.substrate = populated;
11239 let mut eph = empty_ephemeral();
11240 eph.classification = Some(classification);
11241 let lowered: ProcessSpec = eph.clone().into();
11242 assert_eq!(
11243 eph.substrate_is_policy(),
11244 lowered.classification.substrate_is_policy(),
11245 "authored substrate={populated:?}: parity drift",
11246 );
11247 }
11248 }
11249
11250 /// MUTEX pin — [`Self::substrate_is_resource`] AND
11251 /// [`Self::substrate_is_policy`] are NEVER simultaneously true
11252 /// for ANY [`EphemeralSpec`] (authored or defaulted), since the
11253 /// underlying [`crate::classification::SubstrateType`] closed set
11254 /// carves its eight variants into THREE disjoint buckets. Sweep
11255 /// the absent-classification case + every
11256 /// [`crate::classification::SubstrateType::ALL`] variant so a
11257 /// regression that crossed the wires between the two ephemeral-
11258 /// surface corner peers (one probe silently composing the wrong
11259 /// closed-set arm at the resolver-hop layer) fails HERE rather
11260 /// than at every downstream consumer that trusts the two probes
11261 /// partition the resolver's output into disjoint buckets.
11262 /// FIRST ephemeral-surface `substrate`-axis corner-peer pair
11263 /// carrying a non-trivial MUTEX relationship — structural twin
11264 /// of the sibling `point_type`-axis MUTEX pair sealed on this
11265 /// surface by
11266 /// `ephemeral_point_is_endomorphic_and_point_is_diffusive_are_mutex_over_all`.
11267 #[test]
11268 fn ephemeral_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all() {
11269 // Absent classification.
11270 let eph = empty_ephemeral();
11271 assert!(
11272 !(eph.substrate_is_resource() && eph.substrate_is_policy()),
11273 "None-classification: substrate_is_resource AND substrate_is_policy both true (mutex violated)",
11274 );
11275 // Authored classification.
11276 for populated in SubstrateType::ALL {
11277 let mut classification = Classification::gate_compute();
11278 classification.substrate = populated;
11279 let mut eph = empty_ephemeral();
11280 eph.classification = Some(classification);
11281 assert!(
11282 !(eph.substrate_is_resource() && eph.substrate_is_policy()),
11283 "authored substrate={populated:?}: substrate_is_resource AND substrate_is_policy both true (mutex violated)",
11284 );
11285 }
11286 }
11287
11288 // ── EphemeralSpec::substrate_is_telemetry pins ───────────────────
11289 //
11290 // Fail-before-pass-after granularity: `substrate_is_telemetry`
11291 // did not exist pre-lift on `impl EphemeralSpec` — every consumer
11292 // walking the "does this ephemeral spec's substrate project to
11293 // the telemetry plane?" question went through
11294 // `.resolved_classification().substrate.is_telemetry()` or the
11295 // lowered `ProcessSpec`'s
11296 // `spec.classification.substrate.is_telemetry()`. Post-lift the
11297 // ELEVENTH derived-nullary-boolean peer on the ephemeral surface
11298 // (THIRD on the `substrate` axis) routes through the SAME
11299 // [`Self::resolved_classification`] resolver + the sibling
11300 // substrate primitive
11301 // [`crate::classification::Classification::substrate_is_telemetry`],
11302 // so the two-surface parity contract holds by construction, AND
11303 // the three `substrate`-axis peers on this surface CLOSE the
11304 // axis into the FULL three-way XOR partition contract via
11305 // `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`.
11306
11307 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11308 /// [`Classification`] carries a specific
11309 /// [`crate::classification::SubstrateType`] variant answers
11310 /// [`Self::substrate_is_telemetry`] matching the closed set's own
11311 /// [`crate::classification::SubstrateType::is_telemetry`] truth
11312 /// table. Sweep [`crate::classification::SubstrateType::ALL`]
11313 /// so a regression that (a) hard-coded the body to a fixed
11314 /// answer, (b) inverted the projection, or (c) crossed the wires
11315 /// with the sibling
11316 /// [`crate::classification::SubstrateType::is_resource`] /
11317 /// [`crate::classification::SubstrateType::is_policy`]
11318 /// projections fails HERE at the substrate primitive before
11319 /// drifting through the `telemetry-substrate` fixed tag or the
11320 /// peer point surface.
11321 #[test]
11322 fn substrate_is_telemetry_returns_substrate_projection_per_kind() {
11323 for populated in SubstrateType::ALL {
11324 let mut classification = Classification::gate_compute();
11325 classification.substrate = populated;
11326 let mut spec = empty_ephemeral();
11327 spec.classification = Some(classification);
11328 assert_eq!(
11329 spec.substrate_is_telemetry(),
11330 populated.is_telemetry(),
11331 "authored substrate={populated:?}: substrate_is_telemetry() drift",
11332 );
11333 }
11334 }
11335
11336 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11337 /// with `classification: None` routes through the
11338 /// [`Self::resolved_classification`] resolver's substrate default
11339 /// [`Classification::gate_compute`], which carries
11340 /// [`crate::classification::SubstrateType::Compute`] (the
11341 /// canonical resource-plane substrate, NOT a telemetry plane),
11342 /// and
11343 /// [`crate::classification::SubstrateType::Compute::is_telemetry`]
11344 /// projects `false`, so [`Self::substrate_is_telemetry`] returns
11345 /// `false`. Pins the resolver's chosen-field baseline at ONE
11346 /// narrow site — aligned with the sibling
11347 /// `substrate_is_policy_probes_false_on_absent_classification`
11348 /// (both projections on `gate_compute`'s chosen `substrate`
11349 /// field project `false` since `Compute` lives in the resource
11350 /// plane), mirror-inverted from
11351 /// `substrate_is_resource_probes_true_on_absent_classification`.
11352 #[test]
11353 fn substrate_is_telemetry_probes_false_on_absent_classification() {
11354 let spec = empty_ephemeral();
11355 assert!(spec.classification.is_none());
11356 assert!(
11357 !spec.substrate_is_telemetry(),
11358 "absent classification (defaults to gate_compute, substrate=Compute → is_telemetry=false)",
11359 );
11360 }
11361
11362 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11363 /// identically through [`Self::substrate_is_telemetry`] AND
11364 /// through
11365 /// `<eph.clone().into::<ProcessSpec>>().classification.substrate_is_telemetry()`
11366 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11367 /// classification, `Some(_)` classification on every
11368 /// [`crate::classification::SubstrateType::ALL`] variant) so a
11369 /// future regression on either side of the resolver fails HERE
11370 /// at the parity boundary. Byte-for-byte peer of
11371 /// `substrate_is_policy_matches_point_peer_through_lowered_classification`
11372 /// on the SAME closed-set axis via a sibling projection.
11373 #[test]
11374 fn substrate_is_telemetry_matches_point_peer_through_lowered_classification() {
11375 // Absent classification.
11376 let eph = empty_ephemeral();
11377 let lowered: ProcessSpec = eph.clone().into();
11378 assert_eq!(
11379 eph.substrate_is_telemetry(),
11380 lowered.classification.substrate_is_telemetry(),
11381 "None-classification parity drift",
11382 );
11383 // Authored classification.
11384 for populated in SubstrateType::ALL {
11385 let mut classification = Classification::gate_compute();
11386 classification.substrate = populated;
11387 let mut eph = empty_ephemeral();
11388 eph.classification = Some(classification);
11389 let lowered: ProcessSpec = eph.clone().into();
11390 assert_eq!(
11391 eph.substrate_is_telemetry(),
11392 lowered.classification.substrate_is_telemetry(),
11393 "authored substrate={populated:?}: parity drift",
11394 );
11395 }
11396 }
11397
11398 /// MUTEX pin — [`Self::substrate_is_resource`] AND
11399 /// [`Self::substrate_is_telemetry`] are NEVER simultaneously true
11400 /// for ANY [`EphemeralSpec`] (authored or defaulted). Second
11401 /// ephemeral-surface `substrate`-axis corner-peer MUTEX pin —
11402 /// peer of
11403 /// `ephemeral_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
11404 /// on a sibling closed-set projection.
11405 #[test]
11406 fn ephemeral_substrate_is_resource_and_substrate_is_telemetry_are_mutex_over_all() {
11407 // Absent classification.
11408 let eph = empty_ephemeral();
11409 assert!(
11410 !(eph.substrate_is_resource() && eph.substrate_is_telemetry()),
11411 "None-classification: substrate_is_resource AND substrate_is_telemetry both true (mutex violated)",
11412 );
11413 // Authored classification.
11414 for populated in SubstrateType::ALL {
11415 let mut classification = Classification::gate_compute();
11416 classification.substrate = populated;
11417 let mut eph = empty_ephemeral();
11418 eph.classification = Some(classification);
11419 assert!(
11420 !(eph.substrate_is_resource() && eph.substrate_is_telemetry()),
11421 "authored substrate={populated:?}: substrate_is_resource AND substrate_is_telemetry both true (mutex violated)",
11422 );
11423 }
11424 }
11425
11426 /// MUTEX pin — [`Self::substrate_is_policy`] AND
11427 /// [`Self::substrate_is_telemetry`] are NEVER simultaneously true
11428 /// for ANY [`EphemeralSpec`] (authored or defaulted). Third
11429 /// ephemeral-surface `substrate`-axis corner-peer MUTEX pin —
11430 /// completes the three pairwise MUTEX relations alongside
11431 /// `ephemeral_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
11432 /// and
11433 /// `ephemeral_substrate_is_resource_and_substrate_is_telemetry_are_mutex_over_all`.
11434 #[test]
11435 fn ephemeral_substrate_is_policy_and_substrate_is_telemetry_are_mutex_over_all() {
11436 // Absent classification.
11437 let eph = empty_ephemeral();
11438 assert!(
11439 !(eph.substrate_is_policy() && eph.substrate_is_telemetry()),
11440 "None-classification: substrate_is_policy AND substrate_is_telemetry both true (mutex violated)",
11441 );
11442 // Authored classification.
11443 for populated in SubstrateType::ALL {
11444 let mut classification = Classification::gate_compute();
11445 classification.substrate = populated;
11446 let mut eph = empty_ephemeral();
11447 eph.classification = Some(classification);
11448 assert!(
11449 !(eph.substrate_is_policy() && eph.substrate_is_telemetry()),
11450 "authored substrate={populated:?}: substrate_is_policy AND substrate_is_telemetry both true (mutex violated)",
11451 );
11452 }
11453 }
11454
11455 /// THREE-WAY XOR PARTITION pin — for the absent-classification
11456 /// baseline AND every [`crate::classification::SubstrateType::ALL`]
11457 /// variant, EXACTLY ONE of [`Self::substrate_is_resource`],
11458 /// [`Self::substrate_is_policy`], and
11459 /// [`Self::substrate_is_telemetry`] returns `true`. CLOSES the
11460 /// three pairwise MUTEX pins on the substrate axis
11461 /// (`substrate_is_resource ⇒ ¬substrate_is_policy`,
11462 /// `substrate_is_resource ⇒ ¬substrate_is_telemetry`,
11463 /// `substrate_is_policy ⇒ ¬substrate_is_telemetry`) into the
11464 /// FULL ternary XOR partition contract on the ephemeral surface
11465 /// — the resolver-hop peer of the parent-composed
11466 /// `classification_substrate_probes_form_three_way_xor_partition_over_all`
11467 /// test. Structural twin of the sibling `point_type`-axis
11468 /// ternary lift sealed on this surface by
11469 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`.
11470 /// Guarantees the absent-classification case lands in the
11471 /// resource bucket (`gate_compute` → Compute → is_resource =
11472 /// true), so every unadorned `(defephemeral …)` audits under a
11473 /// definite non-empty plane bucket.
11474 #[test]
11475 fn ephemeral_substrate_probes_form_three_way_xor_partition_over_all() {
11476 // Absent classification.
11477 let eph = empty_ephemeral();
11478 let buckets = [
11479 eph.substrate_is_resource(),
11480 eph.substrate_is_policy(),
11481 eph.substrate_is_telemetry(),
11482 ];
11483 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11484 assert_eq!(
11485 hits, 1,
11486 "None-classification: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
11487 );
11488 // Authored classification.
11489 for populated in SubstrateType::ALL {
11490 let mut classification = Classification::gate_compute();
11491 classification.substrate = populated;
11492 let mut eph = empty_ephemeral();
11493 eph.classification = Some(classification);
11494 let buckets = [
11495 eph.substrate_is_resource(),
11496 eph.substrate_is_policy(),
11497 eph.substrate_is_telemetry(),
11498 ];
11499 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11500 assert_eq!(
11501 hits, 1,
11502 "authored substrate={populated:?}: probes {buckets:?} — exactly one must be true (three-way XOR partition violated)",
11503 );
11504 }
11505 }
11506
11507 // ── EphemeralSpec::calm_is_monotone pins ─────────────────────────
11508 //
11509 // Fail-before-pass-after granularity: `calm_is_monotone` did not
11510 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
11511 // the "can this ephemeral spec participate in gossip-only writes?"
11512 // question went through the antisymmetric
11513 // `!self.calm_requires_coordination()` or through
11514 // `.resolved_classification().calm.is_monotone()`. Post-lift the
11515 // TWELFTH derived-nullary-boolean peer on the ephemeral surface
11516 // (SECOND on the calm axis, closing that axis into a binary XOR
11517 // partition on this surface) routes through the SAME
11518 // [`Self::resolved_classification`] resolver + the sibling
11519 // substrate primitive
11520 // [`crate::classification::Classification::calm_is_monotone`], so
11521 // the two-surface parity contract holds by construction, AND the
11522 // two calm-axis peers on this surface CLOSE the axis into the
11523 // FULL binary XOR partition contract via
11524 // `ephemeral_calm_probes_form_binary_xor_partition_over_all`.
11525
11526 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11527 /// [`Classification`] carries a specific
11528 /// [`crate::classification::CalmClassification`] variant answers
11529 /// [`Self::calm_is_monotone`] matching the closed set's own
11530 /// [`crate::classification::CalmClassification::is_monotone`]
11531 /// truth table. Sweep
11532 /// [`crate::classification::CalmClassification::ALL`] so a
11533 /// regression that (a) hard-coded the body to a fixed answer,
11534 /// (b) inverted the projection, or (c) crossed the wires with
11535 /// the sibling
11536 /// [`crate::classification::CalmClassification::requires_coordination`]
11537 /// projection fails HERE at the substrate primitive before
11538 /// drifting through the `monotone-calm` fixed tag or the peer
11539 /// point surface.
11540 #[test]
11541 fn calm_is_monotone_returns_calm_projection_per_kind() {
11542 for populated in CalmClassification::ALL {
11543 let mut classification = Classification::gate_compute();
11544 classification.calm = populated;
11545 let mut spec = empty_ephemeral();
11546 spec.classification = Some(classification);
11547 assert_eq!(
11548 spec.calm_is_monotone(),
11549 populated.is_monotone(),
11550 "authored calm={populated:?}: calm_is_monotone() drift",
11551 );
11552 }
11553 }
11554
11555 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11556 /// with `classification: None` routes through the
11557 /// [`Self::resolved_classification`] resolver's substrate default
11558 /// [`Classification::gate_compute`], which carries
11559 /// [`crate::classification::CalmClassification::default = Monotone`]
11560 /// via `#[default]`, and
11561 /// [`crate::classification::CalmClassification::Monotone::is_monotone`]
11562 /// projects `true`, so [`Self::calm_is_monotone`] returns
11563 /// `true`. Pins the resolver's default-arm short-circuit through
11564 /// TWO layers of `Default` ([`Classification::gate_compute`] →
11565 /// [`crate::classification::CalmClassification::default`])
11566 /// reaching this derived-nullary predicate. Mirror-inverted from
11567 /// the sibling
11568 /// `calm_requires_coordination_probes_false_on_absent_classification`
11569 /// (both walk the SAME defaulted `calm` field, so
11570 /// `requires_coordination = false` ⇒ `is_monotone = true` on the
11571 /// closed set's disjoint XOR partition). Guarantees every
11572 /// unadorned `(defephemeral …)` reads as gossip-eligible under
11573 /// the positive CALM framing.
11574 #[test]
11575 fn calm_is_monotone_probes_true_on_absent_classification() {
11576 let spec = empty_ephemeral();
11577 assert!(spec.classification.is_none());
11578 assert!(
11579 spec.calm_is_monotone(),
11580 "absent classification (defaults to gate_compute, calm=Monotone → is_monotone=true)",
11581 );
11582 }
11583
11584 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11585 /// identically through [`Self::calm_is_monotone`] AND through
11586 /// `<eph.clone().into::<ProcessSpec>>().classification.calm_is_monotone()`
11587 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11588 /// classification, `Some(_)` classification on every
11589 /// [`crate::classification::CalmClassification::ALL`] variant) so
11590 /// a future regression on either side of the resolver fails HERE
11591 /// at the parity boundary. Byte-for-byte peer of
11592 /// `calm_requires_coordination_matches_point_peer_through_lowered_classification`
11593 /// on the SAME closed-set axis via the antisymmetric projection.
11594 #[test]
11595 fn calm_is_monotone_matches_point_peer_through_lowered_classification() {
11596 // Absent classification.
11597 let eph = empty_ephemeral();
11598 let lowered: ProcessSpec = eph.clone().into();
11599 assert_eq!(
11600 eph.calm_is_monotone(),
11601 lowered.classification.calm_is_monotone(),
11602 "None-classification parity drift",
11603 );
11604 // Authored classification.
11605 for populated in CalmClassification::ALL {
11606 let mut classification = Classification::gate_compute();
11607 classification.calm = populated;
11608 let mut eph = empty_ephemeral();
11609 eph.classification = Some(classification);
11610 let lowered: ProcessSpec = eph.clone().into();
11611 assert_eq!(
11612 eph.calm_is_monotone(),
11613 lowered.classification.calm_is_monotone(),
11614 "authored calm={populated:?}: parity drift",
11615 );
11616 }
11617 }
11618
11619 /// MUTEX pin — [`Self::calm_requires_coordination`] AND
11620 /// [`Self::calm_is_monotone`] are NEVER simultaneously true for
11621 /// ANY [`EphemeralSpec`] (authored or defaulted). FIRST
11622 /// ephemeral-surface `calm`-axis corner-peer MUTEX pin — the
11623 /// calm axis's counterpart to the sibling substrate-axis
11624 /// `ephemeral_substrate_is_resource_and_substrate_is_policy_are_mutex_over_all`
11625 /// on a binary (rather than ternary) closed set.
11626 #[test]
11627 fn ephemeral_calm_requires_coordination_and_calm_is_monotone_are_mutex_over_all() {
11628 // Absent classification.
11629 let eph = empty_ephemeral();
11630 assert!(
11631 !(eph.calm_requires_coordination() && eph.calm_is_monotone()),
11632 "None-classification: calm_requires_coordination AND calm_is_monotone both true (mutex violated)",
11633 );
11634 // Authored classification.
11635 for populated in CalmClassification::ALL {
11636 let mut classification = Classification::gate_compute();
11637 classification.calm = populated;
11638 let mut eph = empty_ephemeral();
11639 eph.classification = Some(classification);
11640 assert!(
11641 !(eph.calm_requires_coordination() && eph.calm_is_monotone()),
11642 "authored calm={populated:?}: calm_requires_coordination AND calm_is_monotone both true (mutex violated)",
11643 );
11644 }
11645 }
11646
11647 /// BINARY XOR PARTITION pin — for the absent-classification
11648 /// baseline AND every
11649 /// [`crate::classification::CalmClassification::ALL`] variant,
11650 /// EXACTLY ONE of [`Self::calm_is_monotone`] and
11651 /// [`Self::calm_requires_coordination`] returns `true`. CLOSES
11652 /// the calm-axis MUTEX pin
11653 /// (`calm_requires_coordination ⇒ ¬calm_is_monotone`) into the
11654 /// FULL binary XOR partition contract on the ephemeral surface
11655 /// — the resolver-hop peer of the parent-composed
11656 /// `classification_calm_probes_form_binary_xor_partition_over_all`
11657 /// test. Binary counterpart of the ternary XOR partitions sealed
11658 /// on the sibling `point_type` and `substrate` axes by
11659 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
11660 /// and
11661 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`.
11662 /// Guarantees the absent-classification case lands in the
11663 /// monotone bucket (`gate_compute` → CalmClassification::Monotone
11664 /// → is_monotone = true), so every unadorned `(defephemeral …)`
11665 /// audits under a definite non-empty CALM bucket.
11666 #[test]
11667 fn ephemeral_calm_probes_form_binary_xor_partition_over_all() {
11668 // Absent classification.
11669 let eph = empty_ephemeral();
11670 let buckets = [eph.calm_is_monotone(), eph.calm_requires_coordination()];
11671 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11672 assert_eq!(
11673 hits, 1,
11674 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
11675 );
11676 // Authored classification.
11677 for populated in CalmClassification::ALL {
11678 let mut classification = Classification::gate_compute();
11679 classification.calm = populated;
11680 let mut eph = empty_ephemeral();
11681 eph.classification = Some(classification);
11682 let buckets = [eph.calm_is_monotone(), eph.calm_requires_coordination()];
11683 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11684 assert_eq!(
11685 hits, 1,
11686 "authored calm={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
11687 );
11688 }
11689 }
11690
11691 // ── EphemeralSpec::data_is_public pins ───────────────────────────
11692 //
11693 // Fail-before-pass-after granularity: `data_is_public` did not
11694 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
11695 // the "is this ephemeral spec's dataset publicly distributable?"
11696 // question went through the antisymmetric
11697 // `!self.data_is_restricted()` or through
11698 // `.resolved_classification().data_classification.is_public()`.
11699 // Post-lift the THIRTEENTH derived-nullary-boolean peer on the
11700 // ephemeral surface (THIRD on the data axis, closing that axis
11701 // into a binary XOR partition on this surface) routes through the
11702 // SAME [`Self::resolved_classification`] resolver + the sibling
11703 // substrate primitive
11704 // [`crate::classification::Classification::data_is_public`], so
11705 // the two-surface parity contract holds by construction, AND the
11706 // two-way public/restricted split on this surface CLOSES the
11707 // data axis into the FULL binary XOR partition contract via
11708 // `ephemeral_data_probes_form_binary_xor_partition_over_all`.
11709
11710 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11711 /// [`Classification`] carries a specific
11712 /// [`crate::classification::DataClassification`] variant answers
11713 /// [`Self::data_is_public`] matching the closed set's own
11714 /// [`crate::classification::DataClassification::is_public`] truth
11715 /// table. Sweep
11716 /// [`crate::classification::DataClassification::ALL`] so a
11717 /// regression that (a) hard-coded the body to a fixed answer,
11718 /// (b) inverted the projection, or (c) crossed the wires with
11719 /// the sibling
11720 /// [`crate::classification::DataClassification::is_restricted`]
11721 /// projection fails HERE at the substrate primitive before
11722 /// drifting through the `public-data` fixed tag or the peer
11723 /// point surface.
11724 #[test]
11725 fn data_is_public_returns_data_projection_per_kind() {
11726 for populated in DataClassification::ALL {
11727 let mut classification = Classification::gate_compute();
11728 classification.data_classification = populated;
11729 let mut spec = empty_ephemeral();
11730 spec.classification = Some(classification);
11731 assert_eq!(
11732 spec.data_is_public(),
11733 populated.is_public(),
11734 "authored data_classification={populated:?}: data_is_public() drift",
11735 );
11736 }
11737 }
11738
11739 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11740 /// with `classification: None` routes through the
11741 /// [`Self::resolved_classification`] resolver's substrate default
11742 /// [`Classification::gate_compute`], which carries
11743 /// [`crate::classification::DataClassification::default = Internal`]
11744 /// via `#[default]`, and
11745 /// [`crate::classification::DataClassification::Internal::is_public`]
11746 /// projects `false`, so [`Self::data_is_public`] returns `false`.
11747 /// Pins the resolver's default-arm short-circuit through TWO
11748 /// layers of `Default` ([`Classification::gate_compute`] →
11749 /// [`crate::classification::DataClassification::default`])
11750 /// reaching this derived-nullary predicate. Mirror-inverted from
11751 /// the sibling
11752 /// `data_is_restricted_probes_true_on_absent_classification`
11753 /// (both walk the SAME defaulted `data_classification` field, so
11754 /// `is_restricted = true` ⇒ `is_public = false` on the closed
11755 /// set's disjoint XOR partition). Guarantees every unadorned
11756 /// `(defephemeral …)` audits under the access-controlled default
11757 /// rather than silently promoting an unadorned dataset onto the
11758 /// freely-distributable path.
11759 #[test]
11760 fn data_is_public_probes_false_on_absent_classification() {
11761 let spec = empty_ephemeral();
11762 assert!(spec.classification.is_none());
11763 assert!(
11764 !spec.data_is_public(),
11765 "absent classification (defaults to gate_compute, data_classification=Internal → is_public=false)",
11766 );
11767 }
11768
11769 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11770 /// identically through [`Self::data_is_public`] AND through
11771 /// `<eph.clone().into::<ProcessSpec>>().classification.data_is_public()`
11772 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11773 /// classification, `Some(_)` classification on every
11774 /// [`crate::classification::DataClassification::ALL`] variant) so
11775 /// a future regression on either side of the resolver fails HERE
11776 /// at the parity boundary. Byte-for-byte peer of
11777 /// `data_is_restricted_matches_point_peer_through_lowered_classification`
11778 /// on the SAME closed-set axis via the antisymmetric projection.
11779 #[test]
11780 fn data_is_public_matches_point_peer_through_lowered_classification() {
11781 // Absent classification.
11782 let eph = empty_ephemeral();
11783 let lowered: ProcessSpec = eph.clone().into();
11784 assert_eq!(
11785 eph.data_is_public(),
11786 lowered.classification.data_is_public(),
11787 "None-classification parity drift",
11788 );
11789 // Authored classification.
11790 for populated in DataClassification::ALL {
11791 let mut classification = Classification::gate_compute();
11792 classification.data_classification = populated;
11793 let mut eph = empty_ephemeral();
11794 eph.classification = Some(classification);
11795 let lowered: ProcessSpec = eph.clone().into();
11796 assert_eq!(
11797 eph.data_is_public(),
11798 lowered.classification.data_is_public(),
11799 "authored data_classification={populated:?}: parity drift",
11800 );
11801 }
11802 }
11803
11804 /// MUTEX pin — [`Self::data_is_regulated`] AND
11805 /// [`Self::data_is_public`] are NEVER simultaneously true for ANY
11806 /// [`EphemeralSpec`] (authored or defaulted). FIRST ephemeral-
11807 /// surface data-axis antisymmetric MUTEX pin against the
11808 /// positive-distribution framing: sealed on the closed set by
11809 /// `data_classification_regulated_implies_not_public` and lifted
11810 /// through the resolver hop as a substrate-wide contract on this
11811 /// surface.
11812 #[test]
11813 fn ephemeral_data_is_regulated_and_data_is_public_are_mutex_over_all() {
11814 // Absent classification.
11815 let eph = empty_ephemeral();
11816 assert!(
11817 !(eph.data_is_regulated() && eph.data_is_public()),
11818 "None-classification: data_is_regulated AND data_is_public both true (mutex violated)",
11819 );
11820 // Authored classification.
11821 for populated in DataClassification::ALL {
11822 let mut classification = Classification::gate_compute();
11823 classification.data_classification = populated;
11824 let mut eph = empty_ephemeral();
11825 eph.classification = Some(classification);
11826 assert!(
11827 !(eph.data_is_regulated() && eph.data_is_public()),
11828 "authored data_classification={populated:?}: data_is_regulated AND data_is_public both true (mutex violated)",
11829 );
11830 }
11831 }
11832
11833 /// BINARY XOR PARTITION pin — for the absent-classification
11834 /// baseline AND every
11835 /// [`crate::classification::DataClassification::ALL`] variant,
11836 /// EXACTLY ONE of [`Self::data_is_public`] and
11837 /// [`Self::data_is_restricted`] returns `true`. CLOSES the data-
11838 /// axis MUTEX pin (`data_is_regulated ⇒ ¬data_is_public`) into
11839 /// the FULL binary XOR partition contract on the ephemeral
11840 /// surface — the resolver-hop peer of the parent-composed
11841 /// `classification_data_probes_form_binary_xor_partition_over_all`
11842 /// test. Binary counterpart of the ternary XOR partitions sealed
11843 /// on the sibling `point_type` and `substrate` axes by
11844 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
11845 /// and
11846 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`.
11847 /// Guarantees the absent-classification case lands in the
11848 /// access-controlled bucket (`gate_compute` →
11849 /// DataClassification::Internal → is_public = false,
11850 /// is_restricted = true), so every unadorned `(defephemeral …)`
11851 /// audits under a definite non-empty distribution bucket.
11852 #[test]
11853 fn ephemeral_data_probes_form_binary_xor_partition_over_all() {
11854 // Absent classification.
11855 let eph = empty_ephemeral();
11856 let buckets = [eph.data_is_public(), eph.data_is_restricted()];
11857 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11858 assert_eq!(
11859 hits, 1,
11860 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
11861 );
11862 // Authored classification.
11863 for populated in DataClassification::ALL {
11864 let mut classification = Classification::gate_compute();
11865 classification.data_classification = populated;
11866 let mut eph = empty_ephemeral();
11867 eph.classification = Some(classification);
11868 let buckets = [eph.data_is_public(), eph.data_is_restricted()];
11869 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
11870 assert_eq!(
11871 hits, 1,
11872 "authored data_classification={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
11873 );
11874 }
11875 }
11876
11877 // ── EphemeralSpec::direction_prefers_lower pins ─────────────────
11878 //
11879 // Fail-before-pass-after granularity: `direction_prefers_lower`
11880 // did not exist pre-lift on `impl EphemeralSpec` — every consumer
11881 // walking the "does this ephemeral spec's rate-window evaluator
11882 // treat decreasing values as improvement?" question went through
11883 // `.resolved_classification().horizon.direction.unwrap_or_default().prefers_lower()`.
11884 // Post-lift the FOURTEENTH derived-nullary-boolean peer on the
11885 // ephemeral surface (FIRST on the optimization-direction axis,
11886 // opening the SIXTH classification axis into the fixed-tag algebra)
11887 // routes through the SAME [`Self::resolved_classification`] resolver
11888 // + the sibling substrate primitive
11889 // [`crate::classification::Classification::direction_prefers_lower`],
11890 // so the two-surface parity contract holds by construction.
11891
11892 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
11893 /// [`Classification`] carries `Some(variant)` on `horizon.direction`
11894 /// answers [`Self::direction_prefers_lower`] matching the closed
11895 /// set's own
11896 /// [`crate::classification::OptimizationDirection::prefers_lower`]
11897 /// truth table. Sweep
11898 /// [`crate::classification::OptimizationDirection::ALL`] so a
11899 /// regression that (a) hard-coded the body to a fixed answer,
11900 /// (b) inverted the projection, (c) dropped the `.unwrap_or_default()`
11901 /// hop, or (d) crossed the wires with a sibling classification-axis
11902 /// probe fails HERE at the substrate primitive before drifting
11903 /// through the `prefers-lower-direction` fixed tag or the peer
11904 /// point surface.
11905 #[test]
11906 fn direction_prefers_lower_returns_direction_projection_per_kind() {
11907 for populated in OptimizationDirection::ALL {
11908 let mut classification = Classification::gate_compute();
11909 classification.horizon.direction = Some(populated);
11910 let mut spec = empty_ephemeral();
11911 spec.classification = Some(classification);
11912 assert_eq!(
11913 spec.direction_prefers_lower(),
11914 populated.prefers_lower(),
11915 "authored horizon.direction={populated:?}: direction_prefers_lower() drift",
11916 );
11917 }
11918 }
11919
11920 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
11921 /// with `classification: None` routes through the
11922 /// [`Self::resolved_classification`] resolver's substrate default
11923 /// [`Classification::gate_compute`], which carries
11924 /// `horizon: Horizon::default()` whose `direction` field is `None`,
11925 /// so `unwrap_or_default()` defaults to
11926 /// [`crate::classification::OptimizationDirection::Minimize`] via
11927 /// `#[default]`, and `Minimize.prefers_lower()` projects `true`,
11928 /// so [`Self::direction_prefers_lower`] returns `true`. Pins the
11929 /// resolver's default-arm short-circuit through THREE layers of
11930 /// `Default` ([`Classification::gate_compute`] →
11931 /// [`crate::classification::Horizon::default`] with `direction: None`
11932 /// → [`crate::classification::OptimizationDirection::default =
11933 /// Minimize`]) reaching this derived-nullary predicate. Guarantees
11934 /// every unadorned `(defephemeral …)` reads under the lower-is-
11935 /// better polarity default (safe under the asymptotic-health
11936 /// rate-window evaluator convention: an operator must deliberately
11937 /// opt into Maximize polarity).
11938 #[test]
11939 fn direction_prefers_lower_probes_true_on_absent_classification() {
11940 let spec = empty_ephemeral();
11941 assert!(spec.classification.is_none());
11942 assert!(
11943 spec.direction_prefers_lower(),
11944 "absent classification (defaults to gate_compute, horizon.direction=None → unwrap_or_default=Minimize → prefers_lower=true)",
11945 );
11946 }
11947
11948 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
11949 /// identically through [`Self::direction_prefers_lower`] AND through
11950 /// `<eph.clone().into::<ProcessSpec>>().classification.direction_prefers_lower()`
11951 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
11952 /// classification, `Some(_)` classification on every
11953 /// [`crate::classification::OptimizationDirection::ALL`] variant) so
11954 /// a future regression on either side of the resolver fails HERE
11955 /// at the parity boundary. Byte-for-byte peer of
11956 /// `calm_is_monotone_matches_point_peer_through_lowered_classification`
11957 /// on the analog closed-set axis via the same resolver-hop shape.
11958 #[test]
11959 fn direction_prefers_lower_matches_point_peer_through_lowered_classification() {
11960 // Absent classification.
11961 let eph = empty_ephemeral();
11962 let lowered: ProcessSpec = eph.clone().into();
11963 assert_eq!(
11964 eph.direction_prefers_lower(),
11965 lowered.classification.direction_prefers_lower(),
11966 "None-classification parity drift",
11967 );
11968 // Authored classification.
11969 for populated in OptimizationDirection::ALL {
11970 let mut classification = Classification::gate_compute();
11971 classification.horizon.direction = Some(populated);
11972 let mut eph = empty_ephemeral();
11973 eph.classification = Some(classification);
11974 let lowered: ProcessSpec = eph.clone().into();
11975 assert_eq!(
11976 eph.direction_prefers_lower(),
11977 lowered.classification.direction_prefers_lower(),
11978 "authored horizon.direction={populated:?}: parity drift",
11979 );
11980 }
11981 }
11982
11983 // ── EphemeralSpec::direction_prefers_higher pins ────────────────
11984 //
11985 // Fail-before-pass-after granularity: `direction_prefers_higher`
11986 // did not exist pre-lift on `impl EphemeralSpec` — the positive
11987 // higher-is-better framing peer of
11988 // [`Self::direction_prefers_lower`] had no ephemeral-surface
11989 // substrate owner. Post-lift the FIFTEENTH derived-nullary-boolean
11990 // peer on the ephemeral surface (SECOND on the optimization-
11991 // direction axis, CLOSING the SIXTH classification axis into a
11992 // binary XOR partition on this surface) routes through the SAME
11993 // [`Self::resolved_classification`] resolver + the sibling
11994 // substrate primitive
11995 // [`crate::classification::Classification::direction_prefers_higher`],
11996 // so the two-surface parity contract holds by construction, AND
11997 // the two-way lower/higher split on this surface CLOSES the
11998 // optimization-direction axis into the FULL binary XOR partition
11999 // contract via
12000 // `ephemeral_direction_probes_form_binary_xor_partition_over_all`.
12001
12002 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
12003 /// [`Classification`] carries `Some(variant)` on `horizon.direction`
12004 /// answers [`Self::direction_prefers_higher`] matching the closed
12005 /// set's own
12006 /// [`crate::classification::OptimizationDirection::prefers_higher`]
12007 /// truth table. Sweep
12008 /// [`crate::classification::OptimizationDirection::ALL`] so a
12009 /// regression that (a) hard-coded the body to a fixed answer,
12010 /// (b) inverted the projection, (c) dropped the `.unwrap_or_default()`
12011 /// hop, or (d) crossed the wires with a sibling classification-
12012 /// axis probe fails HERE at the substrate primitive before
12013 /// drifting through the `prefers-higher-direction` fixed tag or
12014 /// the peer point surface.
12015 #[test]
12016 fn direction_prefers_higher_returns_direction_projection_per_kind() {
12017 for populated in OptimizationDirection::ALL {
12018 let mut classification = Classification::gate_compute();
12019 classification.horizon.direction = Some(populated);
12020 let mut spec = empty_ephemeral();
12021 spec.classification = Some(classification);
12022 assert_eq!(
12023 spec.direction_prefers_higher(),
12024 populated.prefers_higher(),
12025 "authored horizon.direction={populated:?}: direction_prefers_higher() drift",
12026 );
12027 }
12028 }
12029
12030 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
12031 /// with `classification: None` routes through the
12032 /// [`Self::resolved_classification`] resolver's substrate default
12033 /// [`Classification::gate_compute`], which carries
12034 /// `horizon: Horizon::default()` whose `direction` field is `None`,
12035 /// so `unwrap_or_default()` defaults to
12036 /// [`crate::classification::OptimizationDirection::Minimize`] via
12037 /// `#[default]`, and `Minimize.prefers_higher()` projects `false`,
12038 /// so [`Self::direction_prefers_higher`] returns `false`. Pins
12039 /// the resolver's default-arm short-circuit through THREE layers
12040 /// of `Default` ([`Classification::gate_compute`] →
12041 /// [`crate::classification::Horizon::default`] with `direction:
12042 /// None` → [`crate::classification::OptimizationDirection::default =
12043 /// Minimize`]) reaching this derived-nullary predicate. Guarantees
12044 /// every unadorned `(defephemeral …)` reads UNDER the lower-is-
12045 /// better polarity default (safe under the asymptotic-health
12046 /// rate-window evaluator convention: an operator must
12047 /// deliberately opt into Maximize polarity). Mirror-inverted from
12048 /// the sibling `direction_prefers_lower_probes_true_on_absent_classification`
12049 /// baseline on the same resolver walk.
12050 #[test]
12051 fn direction_prefers_higher_probes_false_on_absent_classification() {
12052 let spec = empty_ephemeral();
12053 assert!(spec.classification.is_none());
12054 assert!(
12055 !spec.direction_prefers_higher(),
12056 "absent classification (defaults to gate_compute, horizon.direction=None → unwrap_or_default=Minimize → prefers_higher=false)",
12057 );
12058 }
12059
12060 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
12061 /// identically through [`Self::direction_prefers_higher`] AND
12062 /// through
12063 /// `<eph.clone().into::<ProcessSpec>>().classification.direction_prefers_higher()`
12064 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
12065 /// classification, `Some(_)` classification on every
12066 /// [`crate::classification::OptimizationDirection::ALL`] variant)
12067 /// so a future regression on either side of the resolver fails
12068 /// HERE at the parity boundary. Byte-for-byte peer of
12069 /// `direction_prefers_lower_matches_point_peer_through_lowered_classification`
12070 /// on the antisymmetric closed-set arm via the same resolver-hop
12071 /// shape.
12072 #[test]
12073 fn direction_prefers_higher_matches_point_peer_through_lowered_classification() {
12074 // Absent classification.
12075 let eph = empty_ephemeral();
12076 let lowered: ProcessSpec = eph.clone().into();
12077 assert_eq!(
12078 eph.direction_prefers_higher(),
12079 lowered.classification.direction_prefers_higher(),
12080 "None-classification parity drift",
12081 );
12082 // Authored classification.
12083 for populated in OptimizationDirection::ALL {
12084 let mut classification = Classification::gate_compute();
12085 classification.horizon.direction = Some(populated);
12086 let mut eph = empty_ephemeral();
12087 eph.classification = Some(classification);
12088 let lowered: ProcessSpec = eph.clone().into();
12089 assert_eq!(
12090 eph.direction_prefers_higher(),
12091 lowered.classification.direction_prefers_higher(),
12092 "authored horizon.direction={populated:?}: parity drift",
12093 );
12094 }
12095 }
12096
12097 /// BINARY XOR PARTITION pin — for the absent-classification
12098 /// baseline AND every
12099 /// [`crate::classification::OptimizationDirection::ALL`] variant,
12100 /// EXACTLY ONE of [`Self::direction_prefers_lower`] and
12101 /// [`Self::direction_prefers_higher`] returns `true`. CLOSES the
12102 /// optimization-direction axis into the FULL binary XOR partition
12103 /// contract on the ephemeral surface — the resolver-hop peer of
12104 /// the parent-composed
12105 /// `classification_direction_probes_form_binary_xor_partition_over_all`
12106 /// test. Binary counterpart of the ternary XOR partitions sealed
12107 /// on the sibling `point_type` and `substrate` axes by
12108 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
12109 /// and
12110 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`,
12111 /// structural twin of the calm/data binary partitions
12112 /// `ephemeral_calm_probes_form_binary_xor_partition_over_all` and
12113 /// `ephemeral_data_probes_form_binary_xor_partition_over_all`.
12114 /// This pin is the SIXTH (and final) classification axis to reach
12115 /// the closed XOR partition landmark on the ephemeral resolver-
12116 /// hop surface — ALL SIX classification axes (horizon, calm,
12117 /// data, point, substrate, optimization-direction) now have
12118 /// their partitions closed on the ephemeral surface at this
12119 /// corner. Guarantees the absent-classification case lands in
12120 /// the definite lower-is-better bucket (`gate_compute` →
12121 /// Horizon::default → direction: None →
12122 /// OptimizationDirection::default = Minimize → prefers_lower =
12123 /// true, prefers_higher = false), so every unadorned
12124 /// `(defephemeral …)` audits under a definite non-empty polarity
12125 /// bucket.
12126 #[test]
12127 fn ephemeral_direction_probes_form_binary_xor_partition_over_all() {
12128 // Absent classification.
12129 let eph = empty_ephemeral();
12130 let buckets = [
12131 eph.direction_prefers_lower(),
12132 eph.direction_prefers_higher(),
12133 ];
12134 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12135 assert_eq!(
12136 hits, 1,
12137 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12138 );
12139 // Authored classification.
12140 for populated in OptimizationDirection::ALL {
12141 let mut classification = Classification::gate_compute();
12142 classification.horizon.direction = Some(populated);
12143 let mut eph = empty_ephemeral();
12144 eph.classification = Some(classification);
12145 let buckets = [
12146 eph.direction_prefers_lower(),
12147 eph.direction_prefers_higher(),
12148 ];
12149 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12150 assert_eq!(
12151 hits, 1,
12152 "authored horizon.direction={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12153 );
12154 }
12155 }
12156
12157 // ── EphemeralSpec::input_arity_is_one pins ──────────────────────
12158 //
12159 // Fail-before-pass-after granularity: `input_arity_is_one` did not
12160 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
12161 // the "does this ephemeral spec's DAG-composition input port
12162 // accept a single upstream edge?" question went through
12163 // `.resolved_classification().point_type.input_arity().is_one()`.
12164 // Post-lift the SIXTEENTH derived-nullary-boolean peer on the
12165 // ephemeral surface (FIRST on the input-arity axis, opening the
12166 // SEVENTH classification axis into the fixed-tag algebra + the
12167 // derived-typed-projection stratum on this surface for the first
12168 // time) routes through the SAME [`Self::resolved_classification`]
12169 // resolver + the sibling substrate primitive
12170 // [`crate::classification::Classification::input_arity_is_one`],
12171 // so the two-surface parity contract holds by construction.
12172
12173 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
12174 /// [`Classification`] carries `point_type: kind` answers
12175 /// [`Self::input_arity_is_one`] matching the closed set's own
12176 /// [`crate::classification::ConvergencePointType::input_arity`]
12177 /// truth table projected through [`Arity::is_one`]. Sweep
12178 /// [`crate::classification::ConvergencePointType::ALL`] so a
12179 /// regression that (a) hard-coded the body to a fixed answer,
12180 /// (b) inverted the projection, (c) dropped the resolver hop, or
12181 /// (d) crossed the wires with the sibling `output_arity`
12182 /// projection (which disagrees on six of eight variants) fails
12183 /// HERE at the substrate primitive before drifting through the
12184 /// future `single-input-arity` fixed tag or the peer point
12185 /// surface.
12186 #[test]
12187 fn input_arity_is_one_returns_input_arity_projection_per_kind() {
12188 for populated in ConvergencePointType::ALL {
12189 let mut classification = Classification::gate_compute();
12190 classification.point_type = populated;
12191 let mut spec = empty_ephemeral();
12192 spec.classification = Some(classification);
12193 assert_eq!(
12194 spec.input_arity_is_one(),
12195 populated.input_arity().is_one(),
12196 "authored point_type={populated:?}: input_arity_is_one() drift",
12197 );
12198 }
12199 }
12200
12201 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
12202 /// with `classification: None` routes through the
12203 /// [`Self::resolved_classification`] resolver's substrate default
12204 /// [`Classification::gate_compute`], which carries `point_type:
12205 /// Gate` and `Gate.input_arity() = Many`, so
12206 /// [`Self::input_arity_is_one`] returns `false`. Pins the
12207 /// resolver's default-arm short-circuit reaching this derived-
12208 /// nullary predicate — every unadorned `(defephemeral …)` lands
12209 /// in the multi-input bucket under the substrate default. Mirror-
12210 /// inverted from the sibling `input_arity_is_many` baseline on
12211 /// the same resolver walk (the XOR partition forces exactly one
12212 /// bucket per baseline).
12213 #[test]
12214 fn input_arity_is_one_probes_false_on_absent_classification() {
12215 let spec = empty_ephemeral();
12216 assert!(spec.classification.is_none());
12217 assert!(
12218 !spec.input_arity_is_one(),
12219 "absent classification (defaults to gate_compute, point_type=Gate → input_arity=Many → is_one=false)",
12220 );
12221 }
12222
12223 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
12224 /// identically through [`Self::input_arity_is_one`] AND through
12225 /// `<eph.clone().into::<ProcessSpec>>().classification.input_arity_is_one()`
12226 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
12227 /// classification, `Some(_)` classification on every
12228 /// [`crate::classification::ConvergencePointType::ALL`] variant)
12229 /// so a future regression on either side of the resolver fails
12230 /// HERE at the parity boundary. Byte-for-byte peer of
12231 /// `direction_prefers_lower_matches_point_peer_through_lowered_classification`
12232 /// on the same resolver-hop shape.
12233 #[test]
12234 fn input_arity_is_one_matches_point_peer_through_lowered_classification() {
12235 // Absent classification.
12236 let eph = empty_ephemeral();
12237 let lowered: ProcessSpec = eph.clone().into();
12238 assert_eq!(
12239 eph.input_arity_is_one(),
12240 lowered.classification.input_arity_is_one(),
12241 "None-classification parity drift",
12242 );
12243 // Authored classification.
12244 for populated in ConvergencePointType::ALL {
12245 let mut classification = Classification::gate_compute();
12246 classification.point_type = populated;
12247 let mut eph = empty_ephemeral();
12248 eph.classification = Some(classification);
12249 let lowered: ProcessSpec = eph.clone().into();
12250 assert_eq!(
12251 eph.input_arity_is_one(),
12252 lowered.classification.input_arity_is_one(),
12253 "authored point_type={populated:?}: parity drift",
12254 );
12255 }
12256 }
12257
12258 // ── EphemeralSpec::input_arity_is_many pins ─────────────────────
12259 //
12260 // Fail-before-pass-after granularity: `input_arity_is_many` did
12261 // not exist pre-lift on `impl EphemeralSpec` — the multi-input
12262 // framing peer of [`Self::input_arity_is_one`] had no ephemeral-
12263 // surface substrate owner. Post-lift the SEVENTEENTH derived-
12264 // nullary-boolean peer on the ephemeral surface (SECOND on the
12265 // input-arity axis, CLOSING the SEVENTH classification axis into
12266 // a binary XOR partition on this surface) routes through the SAME
12267 // [`Self::resolved_classification`] resolver + the sibling
12268 // substrate primitive
12269 // [`crate::classification::Classification::input_arity_is_many`],
12270 // so the two-surface parity contract holds by construction, AND
12271 // the two-way single/many split on this surface CLOSES the
12272 // input-arity axis into the FULL binary XOR partition contract
12273 // via `ephemeral_input_arity_probes_form_binary_xor_partition_over_all`.
12274
12275 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
12276 /// [`Classification`] carries `point_type: kind` answers
12277 /// [`Self::input_arity_is_many`] matching the closed set's own
12278 /// [`crate::classification::ConvergencePointType::input_arity`]
12279 /// truth table projected through [`Arity::is_many`]. Sweep
12280 /// [`crate::classification::ConvergencePointType::ALL`] so a
12281 /// regression that (a) hard-coded the body to a fixed answer,
12282 /// (b) inverted the projection, (c) dropped the resolver hop, or
12283 /// (d) crossed the wires with the sibling `output_arity`
12284 /// projection fails HERE at the substrate primitive before
12285 /// drifting through the future `multi-input-arity` fixed tag or
12286 /// the peer point surface.
12287 #[test]
12288 fn input_arity_is_many_returns_input_arity_projection_per_kind() {
12289 for populated in ConvergencePointType::ALL {
12290 let mut classification = Classification::gate_compute();
12291 classification.point_type = populated;
12292 let mut spec = empty_ephemeral();
12293 spec.classification = Some(classification);
12294 assert_eq!(
12295 spec.input_arity_is_many(),
12296 populated.input_arity().is_many(),
12297 "authored point_type={populated:?}: input_arity_is_many() drift",
12298 );
12299 }
12300 }
12301
12302 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
12303 /// with `classification: None` routes through the
12304 /// [`Self::resolved_classification`] resolver's substrate default
12305 /// [`Classification::gate_compute`], which carries `point_type:
12306 /// Gate` and `Gate.input_arity() = Many`, so
12307 /// [`Self::input_arity_is_many`] returns `true`. Pins the
12308 /// resolver's default-arm short-circuit reaching this derived-
12309 /// nullary predicate — every unadorned `(defephemeral …)` lands
12310 /// in the multi-input bucket under the substrate default. Mirror-
12311 /// inverted from the sibling `input_arity_is_one` baseline on
12312 /// the same resolver walk (the XOR partition forces exactly one
12313 /// bucket per baseline).
12314 #[test]
12315 fn input_arity_is_many_probes_true_on_absent_classification() {
12316 let spec = empty_ephemeral();
12317 assert!(spec.classification.is_none());
12318 assert!(
12319 spec.input_arity_is_many(),
12320 "absent classification (defaults to gate_compute, point_type=Gate → input_arity=Many → is_many=true)",
12321 );
12322 }
12323
12324 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
12325 /// identically through [`Self::input_arity_is_many`] AND through
12326 /// `<eph.clone().into::<ProcessSpec>>().classification.input_arity_is_many()`
12327 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
12328 /// classification, `Some(_)` classification on every
12329 /// [`crate::classification::ConvergencePointType::ALL`] variant)
12330 /// so a future regression on either side of the resolver fails
12331 /// HERE at the parity boundary. Byte-for-byte peer of
12332 /// `input_arity_is_one_matches_point_peer_through_lowered_classification`
12333 /// on the antisymmetric closed-set arm via the same resolver-hop
12334 /// shape.
12335 #[test]
12336 fn input_arity_is_many_matches_point_peer_through_lowered_classification() {
12337 // Absent classification.
12338 let eph = empty_ephemeral();
12339 let lowered: ProcessSpec = eph.clone().into();
12340 assert_eq!(
12341 eph.input_arity_is_many(),
12342 lowered.classification.input_arity_is_many(),
12343 "None-classification parity drift",
12344 );
12345 // Authored classification.
12346 for populated in ConvergencePointType::ALL {
12347 let mut classification = Classification::gate_compute();
12348 classification.point_type = populated;
12349 let mut eph = empty_ephemeral();
12350 eph.classification = Some(classification);
12351 let lowered: ProcessSpec = eph.clone().into();
12352 assert_eq!(
12353 eph.input_arity_is_many(),
12354 lowered.classification.input_arity_is_many(),
12355 "authored point_type={populated:?}: parity drift",
12356 );
12357 }
12358 }
12359
12360 /// BINARY XOR PARTITION pin — for the absent-classification
12361 /// baseline AND every
12362 /// [`crate::classification::ConvergencePointType::ALL`] variant,
12363 /// EXACTLY ONE of [`Self::input_arity_is_one`] and
12364 /// [`Self::input_arity_is_many`] returns `true`. CLOSES the
12365 /// input-arity axis into the FULL binary XOR partition contract
12366 /// on the ephemeral surface — the resolver-hop peer of the
12367 /// parent-composed
12368 /// `classification_input_arity_probes_form_binary_xor_partition_over_all`
12369 /// test. Binary counterpart of the ternary XOR partitions sealed
12370 /// on the sibling `point_type` and `substrate` axes by
12371 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
12372 /// and
12373 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`,
12374 /// structural twin of the calm/data/direction binary partitions
12375 /// `ephemeral_calm_probes_form_binary_xor_partition_over_all`,
12376 /// `ephemeral_data_probes_form_binary_xor_partition_over_all`,
12377 /// and
12378 /// `ephemeral_direction_probes_form_binary_xor_partition_over_all`.
12379 /// This pin is the SEVENTH classification axis to reach the
12380 /// closed XOR partition landmark on the ephemeral resolver-hop
12381 /// surface — the FIRST closed axis on the derived-typed-
12382 /// projection stratum of this surface, opening the stratum beyond
12383 /// the six stored classification slots. Guarantees the absent-
12384 /// classification case lands in the definite multi-input bucket
12385 /// (`gate_compute` → point_type=Gate → input_arity=Many →
12386 /// is_one=false, is_many=true), so every unadorned
12387 /// `(defephemeral …)` audits under a definite non-empty input-
12388 /// arity bucket.
12389 #[test]
12390 fn ephemeral_input_arity_probes_form_binary_xor_partition_over_all() {
12391 // Absent classification.
12392 let eph = empty_ephemeral();
12393 let buckets = [eph.input_arity_is_one(), eph.input_arity_is_many()];
12394 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12395 assert_eq!(
12396 hits, 1,
12397 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12398 );
12399 // Authored classification.
12400 for populated in ConvergencePointType::ALL {
12401 let mut classification = Classification::gate_compute();
12402 classification.point_type = populated;
12403 let mut eph = empty_ephemeral();
12404 eph.classification = Some(classification);
12405 let buckets = [eph.input_arity_is_one(), eph.input_arity_is_many()];
12406 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12407 assert_eq!(
12408 hits, 1,
12409 "authored point_type={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12410 );
12411 }
12412 }
12413
12414 // ── EphemeralSpec::output_arity_is_one pins ─────────────────────
12415 //
12416 // Fail-before-pass-after granularity: `output_arity_is_one` did not
12417 // exist pre-lift on `impl EphemeralSpec` — every consumer walking
12418 // the "does this ephemeral spec's DAG-composition output port emit
12419 // to a single downstream edge?" question went through
12420 // `.resolved_classification().point_type.output_arity().is_one()`.
12421 // Post-lift the EIGHTEENTH derived-nullary-boolean peer on the
12422 // ephemeral surface (FIRST on the output-arity axis, opening the
12423 // EIGHTH classification axis into the fixed-tag algebra + the
12424 // SECOND peer on the derived-typed-projection stratum after
12425 // [`Self::input_arity_is_one`]) routes through the SAME
12426 // [`Self::resolved_classification`] resolver + the sibling
12427 // substrate primitive
12428 // [`crate::classification::Classification::output_arity_is_one`],
12429 // so the two-surface parity contract holds by construction.
12430
12431 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
12432 /// [`Classification`] carries `point_type: kind` answers
12433 /// [`Self::output_arity_is_one`] matching the closed set's own
12434 /// [`crate::classification::ConvergencePointType::output_arity`]
12435 /// truth table projected through [`Arity::is_one`]. Sweep
12436 /// [`crate::classification::ConvergencePointType::ALL`] so a
12437 /// regression that (a) hard-coded the body to a fixed answer,
12438 /// (b) inverted the projection, (c) dropped the resolver hop, or
12439 /// (d) crossed the wires with the sibling `input_arity`
12440 /// projection (which disagrees on six of eight variants) fails
12441 /// HERE at the substrate primitive before drifting through the
12442 /// future `single-output-arity` fixed tag or the peer point
12443 /// surface.
12444 #[test]
12445 fn output_arity_is_one_returns_output_arity_projection_per_kind() {
12446 for populated in ConvergencePointType::ALL {
12447 let mut classification = Classification::gate_compute();
12448 classification.point_type = populated;
12449 let mut spec = empty_ephemeral();
12450 spec.classification = Some(classification);
12451 assert_eq!(
12452 spec.output_arity_is_one(),
12453 populated.output_arity().is_one(),
12454 "authored point_type={populated:?}: output_arity_is_one() drift",
12455 );
12456 }
12457 }
12458
12459 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
12460 /// with `classification: None` routes through the
12461 /// [`Self::resolved_classification`] resolver's substrate default
12462 /// [`Classification::gate_compute`], which carries `point_type:
12463 /// Gate` and `Gate.output_arity() = One`, so
12464 /// [`Self::output_arity_is_one`] returns `true`. Pins the
12465 /// resolver's default-arm short-circuit reaching this derived-
12466 /// nullary predicate — every unadorned `(defephemeral …)` lands
12467 /// in the single-output bucket under the substrate default.
12468 /// Mirror-inverted from the sibling `output_arity_is_many`
12469 /// baseline on the same resolver walk (the XOR partition forces
12470 /// exactly one bucket per baseline). Note the workspace-baseline
12471 /// answer FLIPS between the input-arity and output-arity axes on
12472 /// the exact same absent-classification baseline: the input-arity
12473 /// sibling `input_arity_is_one` answers `false`, but this
12474 /// output-arity peer answers `true` — direct evidence at the
12475 /// resolver-hop layer that the two axes carve the closed set
12476 /// into structurally different partitions.
12477 #[test]
12478 fn output_arity_is_one_probes_true_on_absent_classification() {
12479 let spec = empty_ephemeral();
12480 assert!(spec.classification.is_none());
12481 assert!(
12482 spec.output_arity_is_one(),
12483 "absent classification (defaults to gate_compute, point_type=Gate → output_arity=One → is_one=true)",
12484 );
12485 }
12486
12487 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
12488 /// identically through [`Self::output_arity_is_one`] AND through
12489 /// `<eph.clone().into::<ProcessSpec>>().classification.output_arity_is_one()`
12490 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
12491 /// classification, `Some(_)` classification on every
12492 /// [`crate::classification::ConvergencePointType::ALL`] variant)
12493 /// so a future regression on either side of the resolver fails
12494 /// HERE at the parity boundary. Byte-for-byte peer of
12495 /// `input_arity_is_one_matches_point_peer_through_lowered_classification`
12496 /// on the sibling output-arity projection via the same
12497 /// resolver-hop shape.
12498 #[test]
12499 fn output_arity_is_one_matches_point_peer_through_lowered_classification() {
12500 // Absent classification.
12501 let eph = empty_ephemeral();
12502 let lowered: ProcessSpec = eph.clone().into();
12503 assert_eq!(
12504 eph.output_arity_is_one(),
12505 lowered.classification.output_arity_is_one(),
12506 "None-classification parity drift",
12507 );
12508 // Authored classification.
12509 for populated in ConvergencePointType::ALL {
12510 let mut classification = Classification::gate_compute();
12511 classification.point_type = populated;
12512 let mut eph = empty_ephemeral();
12513 eph.classification = Some(classification);
12514 let lowered: ProcessSpec = eph.clone().into();
12515 assert_eq!(
12516 eph.output_arity_is_one(),
12517 lowered.classification.output_arity_is_one(),
12518 "authored point_type={populated:?}: parity drift",
12519 );
12520 }
12521 }
12522
12523 // ── EphemeralSpec::output_arity_is_many pins ────────────────────
12524 //
12525 // Fail-before-pass-after granularity: `output_arity_is_many` did
12526 // not exist pre-lift on `impl EphemeralSpec` — the multi-output
12527 // framing peer of [`Self::output_arity_is_one`] had no ephemeral-
12528 // surface substrate owner. Post-lift the NINETEENTH derived-
12529 // nullary-boolean peer on the ephemeral surface (SECOND on the
12530 // output-arity axis, CLOSING the EIGHTH classification axis into
12531 // a binary XOR partition on this surface) routes through the SAME
12532 // [`Self::resolved_classification`] resolver + the sibling
12533 // substrate primitive
12534 // [`crate::classification::Classification::output_arity_is_many`],
12535 // so the two-surface parity contract holds by construction, AND
12536 // the two-way single/many split on this surface CLOSES the
12537 // output-arity axis into the FULL binary XOR partition contract
12538 // via `ephemeral_output_arity_probes_form_binary_xor_partition_over_all`,
12539 // completing the DAG-composition arity PAIR on the ephemeral
12540 // derived-typed-projection stratum.
12541
12542 /// PER-VARIANT pin — an [`EphemeralSpec`] whose authored
12543 /// [`Classification`] carries `point_type: kind` answers
12544 /// [`Self::output_arity_is_many`] matching the closed set's own
12545 /// [`crate::classification::ConvergencePointType::output_arity`]
12546 /// truth table projected through [`Arity::is_many`]. Sweep
12547 /// [`crate::classification::ConvergencePointType::ALL`] so a
12548 /// regression that (a) hard-coded the body to a fixed answer,
12549 /// (b) inverted the projection, (c) dropped the resolver hop, or
12550 /// (d) crossed the wires with the sibling `input_arity`
12551 /// projection fails HERE at the substrate primitive before
12552 /// drifting through the future `multi-output-arity` fixed tag or
12553 /// the peer point surface.
12554 #[test]
12555 fn output_arity_is_many_returns_output_arity_projection_per_kind() {
12556 for populated in ConvergencePointType::ALL {
12557 let mut classification = Classification::gate_compute();
12558 classification.point_type = populated;
12559 let mut spec = empty_ephemeral();
12560 spec.classification = Some(classification);
12561 assert_eq!(
12562 spec.output_arity_is_many(),
12563 populated.output_arity().is_many(),
12564 "authored point_type={populated:?}: output_arity_is_many() drift",
12565 );
12566 }
12567 }
12568
12569 /// ABSENT-CLASSIFICATION SHORT-CIRCUIT pin — an [`EphemeralSpec`]
12570 /// with `classification: None` routes through the
12571 /// [`Self::resolved_classification`] resolver's substrate default
12572 /// [`Classification::gate_compute`], which carries `point_type:
12573 /// Gate` and `Gate.output_arity() = One`, so
12574 /// [`Self::output_arity_is_many`] returns `false`. Pins the
12575 /// resolver's default-arm short-circuit reaching this derived-
12576 /// nullary predicate — every unadorned `(defephemeral …)` lands
12577 /// in the single-output bucket under the substrate default.
12578 /// Mirror-inverted from the sibling `output_arity_is_one`
12579 /// baseline on the same resolver walk (the XOR partition forces
12580 /// exactly one bucket per baseline).
12581 #[test]
12582 fn output_arity_is_many_probes_false_on_absent_classification() {
12583 let spec = empty_ephemeral();
12584 assert!(spec.classification.is_none());
12585 assert!(
12586 !spec.output_arity_is_many(),
12587 "absent classification (defaults to gate_compute, point_type=Gate → output_arity=One → is_many=false)",
12588 );
12589 }
12590
12591 /// TWO-SURFACE PARITY pin — the SAME [`EphemeralSpec`] classifies
12592 /// identically through [`Self::output_arity_is_many`] AND through
12593 /// `<eph.clone().into::<ProcessSpec>>().classification.output_arity_is_many()`
12594 /// on the mechanically-lowered `ProcessSpec`. Sweeps (`None`
12595 /// classification, `Some(_)` classification on every
12596 /// [`crate::classification::ConvergencePointType::ALL`] variant)
12597 /// so a future regression on either side of the resolver fails
12598 /// HERE at the parity boundary. Byte-for-byte peer of
12599 /// `output_arity_is_one_matches_point_peer_through_lowered_classification`
12600 /// on the antisymmetric closed-set arm via the same resolver-hop
12601 /// shape.
12602 #[test]
12603 fn output_arity_is_many_matches_point_peer_through_lowered_classification() {
12604 // Absent classification.
12605 let eph = empty_ephemeral();
12606 let lowered: ProcessSpec = eph.clone().into();
12607 assert_eq!(
12608 eph.output_arity_is_many(),
12609 lowered.classification.output_arity_is_many(),
12610 "None-classification parity drift",
12611 );
12612 // Authored classification.
12613 for populated in ConvergencePointType::ALL {
12614 let mut classification = Classification::gate_compute();
12615 classification.point_type = populated;
12616 let mut eph = empty_ephemeral();
12617 eph.classification = Some(classification);
12618 let lowered: ProcessSpec = eph.clone().into();
12619 assert_eq!(
12620 eph.output_arity_is_many(),
12621 lowered.classification.output_arity_is_many(),
12622 "authored point_type={populated:?}: parity drift",
12623 );
12624 }
12625 }
12626
12627 /// BINARY XOR PARTITION pin — for the absent-classification
12628 /// baseline AND every
12629 /// [`crate::classification::ConvergencePointType::ALL`] variant,
12630 /// EXACTLY ONE of [`Self::output_arity_is_one`] and
12631 /// [`Self::output_arity_is_many`] returns `true`. CLOSES the
12632 /// output-arity axis into the FULL binary XOR partition contract
12633 /// on the ephemeral surface — the resolver-hop peer of the
12634 /// parent-composed
12635 /// `classification_output_arity_probes_form_binary_xor_partition_over_all`
12636 /// test. Binary counterpart of the ternary XOR partitions sealed
12637 /// on the sibling `point_type` and `substrate` axes by
12638 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
12639 /// and
12640 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`,
12641 /// structural twin of the calm/data/direction/input-arity binary
12642 /// partitions on this surface. This pin is the EIGHTH
12643 /// classification axis to reach the closed XOR partition landmark
12644 /// on the ephemeral resolver-hop surface — the SECOND closed axis
12645 /// on the derived-typed-projection stratum of this surface,
12646 /// completing the DAG-composition arity PAIR on the ephemeral
12647 /// stratum after the input-arity closure. Guarantees the absent-
12648 /// classification case lands in the definite single-output bucket
12649 /// (`gate_compute` → point_type=Gate → output_arity=One →
12650 /// is_one=true, is_many=false), so every unadorned
12651 /// `(defephemeral …)` audits under a definite non-empty
12652 /// output-arity bucket.
12653 #[test]
12654 fn ephemeral_output_arity_probes_form_binary_xor_partition_over_all() {
12655 // Absent classification.
12656 let eph = empty_ephemeral();
12657 let buckets = [eph.output_arity_is_one(), eph.output_arity_is_many()];
12658 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12659 assert_eq!(
12660 hits, 1,
12661 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12662 );
12663 // Authored classification.
12664 for populated in ConvergencePointType::ALL {
12665 let mut classification = Classification::gate_compute();
12666 classification.point_type = populated;
12667 let mut eph = empty_ephemeral();
12668 eph.classification = Some(classification);
12669 let buckets = [eph.output_arity_is_one(), eph.output_arity_is_many()];
12670 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12671 assert_eq!(
12672 hits, 1,
12673 "authored point_type={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12674 );
12675 }
12676 }
12677
12678 /// BINARY XOR PARTITION pin — for the absent-classification
12679 /// baseline AND every
12680 /// [`crate::classification::HorizonKind::ALL`] variant, EXACTLY
12681 /// ONE of [`Self::horizon_terminates`] and
12682 /// [`Self::horizon_requires_metric_axes`] returns `true`. CLOSES
12683 /// the horizon axis into the FULL binary XOR partition contract
12684 /// on the ephemeral surface — the resolver-hop peer of the
12685 /// parent-composed
12686 /// `classification_horizon_probes_form_binary_xor_partition_over_all`
12687 /// test. Binary counterpart of the ternary XOR partitions sealed
12688 /// on the sibling `point_type` and `substrate` axes by
12689 /// `ephemeral_point_type_probes_form_three_way_xor_partition_over_all`
12690 /// and
12691 /// `ephemeral_substrate_probes_form_three_way_xor_partition_over_all`,
12692 /// structural twin of the calm/data binary partitions
12693 /// `ephemeral_calm_probes_form_binary_xor_partition_over_all`
12694 /// and
12695 /// `ephemeral_data_probes_form_binary_xor_partition_over_all`.
12696 /// This pin is the FIFTH (and final) classification axis to reach
12697 /// the closed XOR partition landmark on the ephemeral resolver-
12698 /// hop surface, sealing every classification axis under the
12699 /// SAME `hits == 1` bucket-array contract. Guarantees the absent-
12700 /// classification case lands in the definite terminating bucket
12701 /// (`gate_compute` → HorizonKind::Bounded → terminates = true,
12702 /// requires_metric_axes = false), so every unadorned
12703 /// `(defephemeral …)` audits under a definite non-empty horizon
12704 /// bucket. Rewritten from the earlier binary-XOR-only form
12705 /// (walked as `a ^ b`) into the canonical bucket-array shape
12706 /// shared with the calm/data partitions.
12707 #[test]
12708 fn ephemeral_horizon_probes_form_binary_xor_partition_over_all() {
12709 // Absent classification.
12710 let eph = empty_ephemeral();
12711 let buckets = [eph.horizon_terminates(), eph.horizon_requires_metric_axes()];
12712 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12713 assert_eq!(
12714 hits, 1,
12715 "None-classification: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12716 );
12717 // Authored classification.
12718 for populated in HorizonKind::ALL {
12719 let classification = Classification::gate_compute_with_axis(populated);
12720 let mut eph = empty_ephemeral();
12721 eph.classification = Some(classification);
12722 let buckets = [eph.horizon_terminates(), eph.horizon_requires_metric_axes()];
12723 let hits: u32 = buckets.iter().map(|b| u32::from(*b)).sum();
12724 assert_eq!(
12725 hits, 1,
12726 "authored horizon.kind={populated:?}: probes {buckets:?} — exactly one must be true (binary XOR partition violated)",
12727 );
12728 }
12729 }
12730
12731 // ── EphemeralSpec::has_routing_form pins ─────────────────────────
12732 //
12733 // Fail-before-pass-after granularity: `has_routing_form` did not
12734 // exist pre-lift on `impl EphemeralSpec` — the point-surface
12735 // `routing-form-<kind>` prefix family in tatara-check routed
12736 // through `spec.routing.as_ref().is_some_and(|r| r.has_form(k))`
12737 // inline, so the ephemeral surface had no matching primitive to
12738 // publish the SAME `routing-form-<kind>` prefix family through
12739 // the `strip_and_classify_prefixed_kind` substrate. Post-lift the
12740 // Option-gated derived-scalar-child probe body lives at ONE
12741 // inherent site on [`EphemeralSpec`] and every consumer (this
12742 // module's peer-symmetry tests, tatara-check's ephemeral
12743 // require-tag classifier, any future audit dispatcher walking
12744 // [`RoutingForm::ALL`] over the ephemeral surface) binds through
12745 // the SAME `has_routing_form(kind)` shape.
12746
12747 fn routing_spec(is_stable: bool) -> RoutingSpec {
12748 use crate::routing::{RoutingBackend, RoutingHostname};
12749 RoutingSpec {
12750 hostnames: vec![RoutingHostname::content_hashed("api")],
12751 backend: RoutingBackend::plain("svc", 80),
12752 stable_name_claim: is_stable,
12753 priority: 0,
12754 }
12755 }
12756
12757 /// POPULATED-slot pin — a populated `routing` slot answers `true`
12758 /// exactly for the [`RoutingForm`] variant its
12759 /// [`RoutingSpec::has_form`] derived-scalar arm agrees with, and
12760 /// `false` for every other variant. Sweep the two-boolean × ALL
12761 /// cross so a regression that (a) hard-coded the arm to a single
12762 /// variant, (b) dropped the Option-parent gate (silently reading
12763 /// through `.unwrap_or_default()` on an absent routing slot), or
12764 /// (c) crossed the wires from
12765 /// [`RoutingForm::from_is_stable`] to a fixed variant fails
12766 /// HERE before landing at the operator-facing checks.lisp
12767 /// surface.
12768 #[test]
12769 fn has_routing_form_returns_true_iff_populated_routing_derives_form_per_kind() {
12770 for is_stable in [true, false] {
12771 let populated = RoutingForm::from_is_stable(is_stable);
12772 let mut spec = empty_ephemeral();
12773 spec.routing = Some(routing_spec(is_stable));
12774 for query in RoutingForm::ALL {
12775 let expected = query == populated;
12776 assert_eq!(
12777 spec.has_routing_form(query),
12778 expected,
12779 "ephemeral routing.stable_name_claim={is_stable} (derives {populated:?}): query {query:?} drifted",
12780 );
12781 }
12782 }
12783 }
12784
12785 /// OPTION-PARENT SHORT-CIRCUIT pin — an [`EphemeralSpec`] whose
12786 /// `routing` slot is `None` returns `false` for every
12787 /// [`RoutingForm`] variant, INCLUDING the closed set's
12788 /// derived-default [`RoutingForm::Instance`]. Locks the
12789 /// Option-parent silencing contract so a regression that dropped
12790 /// the `spec.routing.as_ref()` gate (silently probing an absent
12791 /// routing slot as if it carried the defaulted `Instance` form)
12792 /// fails HERE. Peer to
12793 /// [`evaluate_point_require_tag_returns_false_on_absent_routing_for_every_routing_form_kind`]
12794 /// on the point surface — the two-surface symmetry means both
12795 /// classifiers publish the SAME Option-parent silencing at ONE
12796 /// substrate site per surface.
12797 #[test]
12798 fn has_routing_form_returns_false_on_absent_routing_for_every_kind() {
12799 let spec = empty_ephemeral();
12800 assert!(spec.routing.is_none());
12801 for kind in RoutingForm::ALL {
12802 assert!(
12803 !spec.has_routing_form(kind),
12804 "absent ephemeral routing must return false for {kind:?}",
12805 );
12806 }
12807 }
12808
12809 /// DEFAULT-ARM SHORT-CIRCUIT pin — an [`EphemeralSpec`] whose
12810 /// `routing` slot is a [`RoutingSpec`] with `stable_name_claim`
12811 /// at its `#[serde(default)]` (bool default = `false`) answers
12812 /// `true` on [`RoutingForm::Instance`] and `false` on every other
12813 /// variant WITHOUT the operator naming the routing-form axis on
12814 /// the routing spec. Peer to
12815 /// [`evaluate_point_require_tag_returns_true_on_default_routing_form_for_instance_only`]
12816 /// on the point surface — both surfaces read the derived-child
12817 /// arm through the ONE substrate composer
12818 /// [`RoutingForm::from_is_stable`], so a future normalization at
12819 /// the derivation lands at ONE site and every downstream
12820 /// (routing-form require-tag families on both surfaces,
12821 /// closed-set audit dispatchers) picks it up mechanically.
12822 #[test]
12823 fn has_routing_form_probes_instance_only_on_default_populated_routing() {
12824 let mut spec = empty_ephemeral();
12825 spec.routing = Some(routing_spec(bool::default()));
12826 for kind in RoutingForm::ALL {
12827 let expected = kind == RoutingForm::Instance;
12828 assert_eq!(
12829 spec.has_routing_form(kind),
12830 expected,
12831 "default-populated ephemeral routing (stable_name_claim=false → Instance) baseline: query {kind:?} must be {expected}",
12832 );
12833 }
12834 }
12835
12836 /// TWO-SURFACE SYMMETRY pin — an [`EphemeralSpec`] and the
12837 /// [`ProcessSpec`] it lowers to through `From<EphemeralSpec>`
12838 /// answer identically on every [`RoutingForm`] × `is_stable`
12839 /// combination. Locks the byte-for-byte parity between
12840 /// [`EphemeralSpec::has_routing_form`] (this new primitive) and
12841 /// the point surface's `spec.routing.as_ref().is_some_and(|r|
12842 /// r.has_form(k))` inline projection at the tatara-check dispatch
12843 /// site. A regression that (a) diverged the ephemeral probe from
12844 /// the lowered point probe (e.g., dropped the Option-parent gate
12845 /// on ONE side, crossed the derived-child arm on the OTHER), or
12846 /// (b) diverged the `From<EphemeralSpec>` lowering's
12847 /// `routing: e.routing` copy from byte-for-byte forwarding, fails
12848 /// HERE at the two-surface boundary.
12849 #[test]
12850 fn has_routing_form_matches_point_peer_through_lowered_routing() {
12851 for is_stable in [true, false] {
12852 let mut authored = empty_ephemeral();
12853 authored.routing = Some(routing_spec(is_stable));
12854 let lowered: ProcessSpec = authored.clone().into();
12855 for kind in RoutingForm::ALL {
12856 let ephemeral_answer = authored.has_routing_form(kind);
12857 let point_answer = lowered.routing.as_ref().is_some_and(|r| r.has_form(kind));
12858 assert_eq!(
12859 ephemeral_answer, point_answer,
12860 "two-surface routing-form parity drift: stable_name_claim={is_stable}, kind={kind:?}",
12861 );
12862 }
12863 }
12864 }
12865
12866 // ── EphemeralSpec::has_applicable_exports_at substrate pins ───────
12867 //
12868 // Fail-before-pass-after granularity: `has_applicable_exports_at`
12869 // did not exist pre-lift on `impl EphemeralSpec` — the peer
12870 // `EphemeralLifetime::has_applicable_exports` on the lowered
12871 // `ProcessSpec` surface routed through the compound
12872 // `.iter().any(|e| e.when.fires_on(phase))` chain inline, so the
12873 // sugar surface had no matching primitive to publish an
12874 // `exports-fire-on-<phase>` prefix family through the
12875 // `strip_and_classify_prefixed_kind` substrate. Post-lift the
12876 // compound-`(when, phase) → fires_on(phase)` probe body lives at
12877 // ONE slice-level substrate site (`ExportSpecSliceExt::has_applicable_at`),
12878 // this ephemeral surface routes through it directly, and the
12879 // point surface reaches the same primitive through
12880 // `spec.lifetime.resolved_ephemeral().is_some_and(|e|
12881 // e.exports.has_applicable_at(phase))`.
12882
12883 fn export_at(when: crate::export::ExportTrigger) -> ExportSpec {
12884 use crate::export::{ArtifactSource, ReceiptsSource, StdoutChannel, VectorChannel};
12885 ExportSpec {
12886 source: ArtifactSource {
12887 receipts: Some(ReceiptsSource::default()),
12888 ..ArtifactSource::default()
12889 },
12890 channel: VectorChannel {
12891 stdout: Some(StdoutChannel::default()),
12892 ..VectorChannel::default()
12893 },
12894 when,
12895 experiment_id_override: None,
12896 }
12897 }
12898
12899 /// EMPTY-EXPORTS pin — an ephemeral spec with an empty `exports`
12900 /// vec returns `false` for EVERY [`ProcessPhase`]. Sweep
12901 /// [`ProcessPhase::ALL`] so a new variant added without a matching
12902 /// arm in [`crate::export::ExportTrigger::fires_on`] surfaces at
12903 /// rustc's exhaustiveness gate on the `ALL` literal (arity forced
12904 /// by `[Self; 11]`) rather than as a silent false-positive at
12905 /// every downstream `exports-fire-on-<phase>` ephemeral require-tag
12906 /// callsite.
12907 #[test]
12908 fn has_applicable_exports_at_returns_false_on_empty_exports_for_every_phase() {
12909 let spec = empty_ephemeral();
12910 assert!(spec.exports.is_empty());
12911 for phase in ProcessPhase::ALL {
12912 assert!(
12913 !spec.has_applicable_exports_at(phase),
12914 "empty-exports ephemeral must return false for {phase:?}",
12915 );
12916 }
12917 }
12918
12919 /// PER-TRIGGER × PER-PHASE pin — an ephemeral spec with a single
12920 /// export answers `has_applicable_exports_at` identically to the
12921 /// [`crate::export::ExportTrigger::fires_on`] truth table on that
12922 /// (trigger, phase) pair, for every combination. Sweep the
12923 /// [`crate::export::ExportTrigger::ALL`] × [`ProcessPhase::ALL`]
12924 /// cross so a regression that (a) short-circuited to raw `when ==
12925 /// kind` equality, (b) missed `Always`'s dual-phase coverage, or
12926 /// (c) inverted a non-terminal phase to return `true` fails HERE
12927 /// at the substrate primitive rather than at each downstream
12928 /// `exports-fire-on-<phase>` classifier callsite.
12929 #[test]
12930 fn has_applicable_exports_at_matches_fires_on_truth_table_per_pair() {
12931 for trigger in crate::export::ExportTrigger::ALL {
12932 let mut spec = empty_ephemeral();
12933 spec.exports = vec![export_at(trigger)];
12934 for phase in ProcessPhase::ALL {
12935 let expected = trigger.fires_on(phase);
12936 assert_eq!(
12937 spec.has_applicable_exports_at(phase),
12938 expected,
12939 "ephemeral trigger={trigger:?} phase={phase:?} drifted from fires_on",
12940 );
12941 }
12942 }
12943 }
12944
12945 /// TWO-SURFACE SYMMETRY pin — an [`EphemeralSpec`] and the
12946 /// [`ProcessSpec`] it lowers to through `From<EphemeralSpec>`
12947 /// answer identically on every [`ProcessPhase`] × trigger
12948 /// combination. Locks the byte-for-byte parity between
12949 /// [`EphemeralSpec::has_applicable_exports_at`] (this new primitive)
12950 /// and the point surface's `spec.lifetime.resolved_ephemeral()
12951 /// .is_some_and(|e| e.exports.has_applicable_at(phase))` projection
12952 /// at the tatara-check dispatch site. A regression that (a)
12953 /// diverged the ephemeral probe from the lowered-lifetime probe,
12954 /// (b) diverged the `From<EphemeralSpec>` lowering's
12955 /// `exports: e.exports` copy from byte-for-byte forwarding, fails
12956 /// HERE at the two-surface boundary.
12957 #[test]
12958 fn has_applicable_exports_at_matches_point_peer_through_lowered_exports() {
12959 for trigger in crate::export::ExportTrigger::ALL {
12960 let mut authored = empty_ephemeral();
12961 authored.exports = vec![export_at(trigger)];
12962 let lowered: ProcessSpec = authored.clone().into();
12963 for phase in ProcessPhase::ALL {
12964 let ephemeral_answer = authored.has_applicable_exports_at(phase);
12965 let point_answer = lowered
12966 .lifetime
12967 .resolved_ephemeral()
12968 .is_some_and(|e| e.exports.has_applicable_at(phase));
12969 assert_eq!(
12970 ephemeral_answer, point_answer,
12971 "two-surface exports-fire-on parity drift: trigger={trigger:?}, phase={phase:?}",
12972 );
12973 }
12974 }
12975 }
12976
12977 /// SUBSTRATE-DELEGATION pin (EphemeralSpec saturation-predicate
12978 /// triad) — the three `is_*_kind_saturated` methods on
12979 /// [`EphemeralSpec`] delegate to the slice-level substrate primitive
12980 /// [`ConditionSliceExt::is_kind_saturated`] over the two
12981 /// `Vec<Condition>` slots (precondition + postcondition) and
12982 /// compose the union via `ConditionKind::ALL.iter().all(|k|
12983 /// has_condition_kind(*k))`. Two-surface parity pin against
12984 /// [`crate::boundary::Boundary::is_condition_kind_saturated`] on the
12985 /// point-domain [`ProcessSpec`] surface — the two struct-level
12986 /// saturation callers compose against the SAME slice-level
12987 /// substrate primitive so a regression at the per-slice `all`
12988 /// short-circuit fails at that primitive's tests rather than as
12989 /// silent drift at either sugar-surface arm.
12990 #[test]
12991 fn is_condition_kind_saturated_triad_delegates_to_slice_is_kind_saturated() {
12992 // Empty ephemeral spec — every arm returns false.
12993 let spec = empty_ephemeral();
12994 assert!(
12995 !spec.is_precondition_kind_saturated(),
12996 "empty ephemeral must return false on is_precondition_kind_saturated",
12997 );
12998 assert!(
12999 !spec.is_postcondition_kind_saturated(),
13000 "empty ephemeral must return false on is_postcondition_kind_saturated",
13001 );
13002 assert!(
13003 !spec.is_condition_kind_saturated(),
13004 "empty ephemeral must return false on is_condition_kind_saturated",
13005 );
13006 assert_eq!(
13007 spec.is_condition_kind_saturated(),
13008 spec.missing_condition_kinds().is_empty(),
13009 "empty is_condition_kind_saturated must equal missing_condition_kinds().is_empty()",
13010 );
13011
13012 // Single-populated per side — sweep ALL × ALL.
13013 for pre_kind in ConditionKind::ALL {
13014 for post_kind in ConditionKind::ALL {
13015 let mut spec = empty_ephemeral();
13016 spec.preconditions.push(cond(pre_kind));
13017 spec.postconditions.push(cond(post_kind));
13018 assert_eq!(
13019 spec.is_precondition_kind_saturated(),
13020 spec.preconditions.is_kind_saturated(),
13021 "EphemeralSpec::is_precondition_kind_saturated must delegate verbatim to \
13022 preconditions.is_kind_saturated() for pre={pre_kind:?} post={post_kind:?}",
13023 );
13024 assert_eq!(
13025 spec.is_postcondition_kind_saturated(),
13026 spec.postconditions.is_kind_saturated(),
13027 "EphemeralSpec::is_postcondition_kind_saturated must delegate verbatim to \
13028 postconditions.is_kind_saturated() for pre={pre_kind:?} post={post_kind:?}",
13029 );
13030 let expected_union = ConditionKind::ALL
13031 .iter()
13032 .all(|k| pre_kind == *k || post_kind == *k);
13033 assert_eq!(
13034 spec.is_condition_kind_saturated(),
13035 expected_union,
13036 "EphemeralSpec::is_condition_kind_saturated must equal all-ALL-covered-by-either-slice \
13037 for pre={pre_kind:?} post={post_kind:?}",
13038 );
13039
13040 // Two-surface parity: lowered ProcessSpec's Boundary
13041 // must agree bit-for-bit with the ephemeral sugar
13042 // triad on every arm.
13043 let lowered: ProcessSpec = spec.clone().into();
13044 assert_eq!(
13045 spec.is_precondition_kind_saturated(),
13046 lowered.boundary.is_precondition_kind_saturated(),
13047 "two-surface is_precondition_kind_saturated parity drift for pre={pre_kind:?} post={post_kind:?}",
13048 );
13049 assert_eq!(
13050 spec.is_postcondition_kind_saturated(),
13051 lowered.boundary.is_postcondition_kind_saturated(),
13052 "two-surface is_postcondition_kind_saturated parity drift for pre={pre_kind:?} post={post_kind:?}",
13053 );
13054 assert_eq!(
13055 spec.is_condition_kind_saturated(),
13056 lowered.boundary.is_condition_kind_saturated(),
13057 "two-surface is_condition_kind_saturated parity drift for pre={pre_kind:?} post={post_kind:?}",
13058 );
13059 }
13060 }
13061
13062 // Saturated ephemeral — both slices carry every ConditionKind,
13063 // every arm returns true.
13064 let mut spec = empty_ephemeral();
13065 for k in ConditionKind::ALL {
13066 spec.preconditions.push(cond(k));
13067 spec.postconditions.push(cond(k));
13068 }
13069 assert!(
13070 spec.is_precondition_kind_saturated(),
13071 "saturated ephemeral must return true on is_precondition_kind_saturated",
13072 );
13073 assert!(
13074 spec.is_postcondition_kind_saturated(),
13075 "saturated ephemeral must return true on is_postcondition_kind_saturated",
13076 );
13077 assert!(
13078 spec.is_condition_kind_saturated(),
13079 "saturated ephemeral must return true on is_condition_kind_saturated",
13080 );
13081 }
13082
13083 /// SUBSTRATE-DELEGATION pin (EphemeralSpec at-least-one halfspace
13084 /// triad) — the three `has_any_missing_*_condition_kind` methods
13085 /// on [`EphemeralSpec`] delegate to the slice-level substrate
13086 /// primitive
13087 /// [`crate::boundary::ConditionSliceExt::has_any_missing_kind`]
13088 /// over the two `Vec<Condition>` slots (precondition +
13089 /// postcondition) and compose the union via
13090 /// `!self.is_condition_kind_saturated()`. Two-surface parity pin
13091 /// against
13092 /// [`crate::boundary::Boundary::has_any_missing_condition_kind`] on
13093 /// the point-domain [`ProcessSpec`] surface — the two struct-level
13094 /// at-least-one halfspace callers compose against the SAME slice-
13095 /// level substrate primitive so a regression at the per-slice
13096 /// `all` short-circuit under negation fails at that primitive's
13097 /// tests rather than as silent drift at either sugar-surface arm.
13098 #[test]
13099 fn has_any_missing_condition_kind_triad_delegates_to_slice_has_any_missing_kind() {
13100 // Empty ephemeral spec — every arm returns true (every kind is
13101 // missing from every slice + from the union).
13102 let spec = empty_ephemeral();
13103 assert!(
13104 spec.has_any_missing_precondition_kind(),
13105 "empty ephemeral must return true on has_any_missing_precondition_kind",
13106 );
13107 assert!(
13108 spec.has_any_missing_postcondition_kind(),
13109 "empty ephemeral must return true on has_any_missing_postcondition_kind",
13110 );
13111 assert!(
13112 spec.has_any_missing_condition_kind(),
13113 "empty ephemeral must return true on has_any_missing_condition_kind",
13114 );
13115 assert_eq!(
13116 spec.has_any_missing_condition_kind(),
13117 !spec.is_condition_kind_saturated(),
13118 "empty has_any_missing_condition_kind must equal !is_condition_kind_saturated()",
13119 );
13120
13121 // Single-populated per side — sweep ALL × ALL, then pin the
13122 // (pre, post, union) triad + two-surface parity against the
13123 // lowered ProcessSpec's Boundary.
13124 for pre_kind in ConditionKind::ALL {
13125 for post_kind in ConditionKind::ALL {
13126 let mut spec = empty_ephemeral();
13127 spec.preconditions.push(cond(pre_kind));
13128 spec.postconditions.push(cond(post_kind));
13129 assert_eq!(
13130 spec.has_any_missing_precondition_kind(),
13131 spec.preconditions.has_any_missing_kind(),
13132 "EphemeralSpec::has_any_missing_precondition_kind must delegate verbatim to \
13133 preconditions.has_any_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
13134 );
13135 assert_eq!(
13136 spec.has_any_missing_postcondition_kind(),
13137 spec.postconditions.has_any_missing_kind(),
13138 "EphemeralSpec::has_any_missing_postcondition_kind must delegate verbatim to \
13139 postconditions.has_any_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
13140 );
13141 let expected_union = !ConditionKind::ALL
13142 .iter()
13143 .all(|k| pre_kind == *k || post_kind == *k);
13144 assert_eq!(
13145 spec.has_any_missing_condition_kind(),
13146 expected_union,
13147 "EphemeralSpec::has_any_missing_condition_kind must equal \
13148 !all-ALL-covered-by-either-slice \
13149 for pre={pre_kind:?} post={post_kind:?}",
13150 );
13151
13152 // Two-surface parity: lowered ProcessSpec's Boundary
13153 // must agree bit-for-bit with the ephemeral sugar
13154 // triad on every arm.
13155 let lowered: ProcessSpec = spec.clone().into();
13156 assert_eq!(
13157 spec.has_any_missing_precondition_kind(),
13158 lowered.boundary.has_any_missing_precondition_kind(),
13159 "two-surface has_any_missing_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13160 );
13161 assert_eq!(
13162 spec.has_any_missing_postcondition_kind(),
13163 lowered.boundary.has_any_missing_postcondition_kind(),
13164 "two-surface has_any_missing_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13165 );
13166 assert_eq!(
13167 spec.has_any_missing_condition_kind(),
13168 lowered.boundary.has_any_missing_condition_kind(),
13169 "two-surface has_any_missing_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13170 );
13171 }
13172 }
13173
13174 // Saturated ephemeral — both slices carry every ConditionKind,
13175 // every arm returns false.
13176 let mut spec = empty_ephemeral();
13177 for k in ConditionKind::ALL {
13178 spec.preconditions.push(cond(k));
13179 spec.postconditions.push(cond(k));
13180 }
13181 assert!(
13182 !spec.has_any_missing_precondition_kind(),
13183 "saturated ephemeral must return false on has_any_missing_precondition_kind",
13184 );
13185 assert!(
13186 !spec.has_any_missing_postcondition_kind(),
13187 "saturated ephemeral must return false on has_any_missing_postcondition_kind",
13188 );
13189 assert!(
13190 !spec.has_any_missing_condition_kind(),
13191 "saturated ephemeral must return false on has_any_missing_condition_kind",
13192 );
13193 }
13194
13195 /// SUBSTRATE-DELEGATION pin (EphemeralSpec at-least-one halfspace
13196 /// triad on the closed-set-inversion axis) — the three
13197 /// `has_any_distinct_*_condition_kind` methods on
13198 /// [`EphemeralSpec`] delegate to the slice-level substrate
13199 /// primitive
13200 /// [`crate::boundary::ConditionSliceExt::has_any_distinct_kind`]
13201 /// over the two `Vec<Condition>` slots (precondition +
13202 /// postcondition) and compose the union via a SHORT-CIRCUITING
13203 /// closed-set walk over [`ConditionKind::ALL`] under
13204 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
13205 /// against
13206 /// [`crate::boundary::Boundary::has_any_distinct_condition_kind`]
13207 /// on the point-domain [`ProcessSpec`] surface — the two struct-
13208 /// level at-least-one halfspace callers compose against the SAME
13209 /// slice-level substrate primitive so a regression at the per-
13210 /// slice `any` short-circuit fails at that primitive's tests
13211 /// rather than as silent drift at either sugar-surface arm.
13212 #[test]
13213 fn has_any_distinct_condition_kind_triad_delegates_to_slice_has_any_distinct_kind() {
13214 // Empty ephemeral spec — every arm returns false (no kind
13215 // present in either slice).
13216 let spec = empty_ephemeral();
13217 assert!(
13218 !spec.has_any_distinct_precondition_kind(),
13219 "empty ephemeral must return false on has_any_distinct_precondition_kind",
13220 );
13221 assert!(
13222 !spec.has_any_distinct_postcondition_kind(),
13223 "empty ephemeral must return false on has_any_distinct_postcondition_kind",
13224 );
13225 assert!(
13226 !spec.has_any_distinct_condition_kind(),
13227 "empty ephemeral must return false on has_any_distinct_condition_kind",
13228 );
13229
13230 // Single-populated per side — sweep ALL × ALL, then pin the
13231 // (pre, post, union) triad + two-surface parity against the
13232 // lowered ProcessSpec's Boundary.
13233 for pre_kind in ConditionKind::ALL {
13234 for post_kind in ConditionKind::ALL {
13235 let mut spec = empty_ephemeral();
13236 spec.preconditions.push(cond(pre_kind));
13237 spec.postconditions.push(cond(post_kind));
13238 assert_eq!(
13239 spec.has_any_distinct_precondition_kind(),
13240 spec.preconditions.has_any_distinct_kind(),
13241 "EphemeralSpec::has_any_distinct_precondition_kind must delegate verbatim to \
13242 preconditions.has_any_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13243 );
13244 assert_eq!(
13245 spec.has_any_distinct_postcondition_kind(),
13246 spec.postconditions.has_any_distinct_kind(),
13247 "EphemeralSpec::has_any_distinct_postcondition_kind must delegate verbatim to \
13248 postconditions.has_any_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13249 );
13250 assert!(
13251 spec.has_any_distinct_precondition_kind(),
13252 "single-populated preconditions must return true on has_any_distinct_precondition_kind for pre={pre_kind:?}",
13253 );
13254 assert!(
13255 spec.has_any_distinct_postcondition_kind(),
13256 "single-populated postconditions must return true on has_any_distinct_postcondition_kind for post={post_kind:?}",
13257 );
13258 assert!(
13259 spec.has_any_distinct_condition_kind(),
13260 "single-populated-per-side must return true on has_any_distinct_condition_kind for pre={pre_kind:?} post={post_kind:?}",
13261 );
13262
13263 // Two-surface parity: lowered ProcessSpec's Boundary
13264 // must agree bit-for-bit with the ephemeral sugar
13265 // triad on every arm.
13266 let lowered: ProcessSpec = spec.clone().into();
13267 assert_eq!(
13268 spec.has_any_distinct_precondition_kind(),
13269 lowered.boundary.has_any_distinct_precondition_kind(),
13270 "two-surface has_any_distinct_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13271 );
13272 assert_eq!(
13273 spec.has_any_distinct_postcondition_kind(),
13274 lowered.boundary.has_any_distinct_postcondition_kind(),
13275 "two-surface has_any_distinct_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13276 );
13277 assert_eq!(
13278 spec.has_any_distinct_condition_kind(),
13279 lowered.boundary.has_any_distinct_condition_kind(),
13280 "two-surface has_any_distinct_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13281 );
13282 }
13283 }
13284
13285 // Single-populated precondition only — precondition arm true,
13286 // postcondition arm false, union true.
13287 for pre_kind in ConditionKind::ALL {
13288 let mut spec = empty_ephemeral();
13289 spec.preconditions.push(cond(pre_kind));
13290 assert!(
13291 spec.has_any_distinct_precondition_kind(),
13292 "pre-only ephemeral must return true on has_any_distinct_precondition_kind for pre={pre_kind:?}",
13293 );
13294 assert!(
13295 !spec.has_any_distinct_postcondition_kind(),
13296 "pre-only ephemeral must return false on has_any_distinct_postcondition_kind for pre={pre_kind:?}",
13297 );
13298 assert!(
13299 spec.has_any_distinct_condition_kind(),
13300 "pre-only ephemeral must return true on has_any_distinct_condition_kind for pre={pre_kind:?}",
13301 );
13302 }
13303
13304 // Saturated ephemeral — both slices carry every ConditionKind,
13305 // every arm returns true.
13306 let mut spec = empty_ephemeral();
13307 for k in ConditionKind::ALL {
13308 spec.preconditions.push(cond(k));
13309 spec.postconditions.push(cond(k));
13310 }
13311 assert!(
13312 spec.has_any_distinct_precondition_kind(),
13313 "saturated ephemeral must return true on has_any_distinct_precondition_kind",
13314 );
13315 assert!(
13316 spec.has_any_distinct_postcondition_kind(),
13317 "saturated ephemeral must return true on has_any_distinct_postcondition_kind",
13318 );
13319 assert!(
13320 spec.has_any_distinct_condition_kind(),
13321 "saturated ephemeral must return true on has_any_distinct_condition_kind",
13322 );
13323 }
13324
13325 /// SUBSTRATE-DELEGATION pin (EphemeralSpec singleton-coverage
13326 /// triad on the closed-set-inversion axis) — the three
13327 /// `has_unique_distinct_*_condition_kind` methods on
13328 /// [`EphemeralSpec`] delegate to the slice-level substrate
13329 /// primitive
13330 /// [`crate::boundary::ConditionSliceExt::has_unique_distinct_kind`]
13331 /// over the two `Vec<Condition>` slots (precondition +
13332 /// postcondition) and compose the union via a two-step-short-
13333 /// circuit walk over [`ConditionKind::ALL`] under
13334 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
13335 /// against
13336 /// [`crate::boundary::Boundary::has_unique_distinct_condition_kind`]
13337 /// on the point-domain [`ProcessSpec`] surface — the two struct-
13338 /// level singleton-coverage callers compose against the SAME
13339 /// slice-level substrate primitive so a regression at the per-
13340 /// slice two-step short-circuit walk fails at that primitive's
13341 /// tests rather than as silent drift at either sugar-surface arm.
13342 #[test]
13343 fn has_unique_distinct_condition_kind_triad_delegates_to_slice_has_unique_distinct_kind() {
13344 // Empty ephemeral spec — every arm returns false (0 distinct,
13345 // not exactly 1).
13346 let spec = empty_ephemeral();
13347 assert!(
13348 !spec.has_unique_distinct_precondition_kind(),
13349 "empty ephemeral must return false on has_unique_distinct_precondition_kind",
13350 );
13351 assert!(
13352 !spec.has_unique_distinct_postcondition_kind(),
13353 "empty ephemeral must return false on has_unique_distinct_postcondition_kind",
13354 );
13355 assert!(
13356 !spec.has_unique_distinct_condition_kind(),
13357 "empty ephemeral must return false on has_unique_distinct_condition_kind",
13358 );
13359 assert_eq!(
13360 spec.has_unique_distinct_condition_kind(),
13361 spec.distinct_condition_kind_count() == 1,
13362 "empty has_unique_distinct_condition_kind must equal (distinct_condition_kind_count() == 1)",
13363 );
13364
13365 // Single-populated per side — sweep ALL × ALL. Every per-
13366 // slice arm returns true; the union returns true iff the two
13367 // populated kinds coincide (union covers exactly one kind).
13368 for pre_kind in ConditionKind::ALL {
13369 for post_kind in ConditionKind::ALL {
13370 let mut spec = empty_ephemeral();
13371 spec.preconditions.push(cond(pre_kind));
13372 spec.postconditions.push(cond(post_kind));
13373 assert_eq!(
13374 spec.has_unique_distinct_precondition_kind(),
13375 spec.preconditions.has_unique_distinct_kind(),
13376 "EphemeralSpec::has_unique_distinct_precondition_kind must delegate verbatim to \
13377 preconditions.has_unique_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13378 );
13379 assert_eq!(
13380 spec.has_unique_distinct_postcondition_kind(),
13381 spec.postconditions.has_unique_distinct_kind(),
13382 "EphemeralSpec::has_unique_distinct_postcondition_kind must delegate verbatim to \
13383 postconditions.has_unique_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13384 );
13385 let covered_count = ConditionKind::ALL
13386 .into_iter()
13387 .filter(|k| *k == pre_kind || *k == post_kind)
13388 .count();
13389 let expected_union = covered_count == 1;
13390 assert_eq!(
13391 spec.has_unique_distinct_condition_kind(),
13392 expected_union,
13393 "EphemeralSpec::has_unique_distinct_condition_kind must equal \
13394 (covered-ALL-count == 1) for pre={pre_kind:?} post={post_kind:?}",
13395 );
13396
13397 // Two-surface parity: lowered ProcessSpec's Boundary
13398 // must agree bit-for-bit with the ephemeral sugar
13399 // triad on every arm.
13400 let lowered: ProcessSpec = spec.clone().into();
13401 assert_eq!(
13402 spec.has_unique_distinct_precondition_kind(),
13403 lowered.boundary.has_unique_distinct_precondition_kind(),
13404 "two-surface has_unique_distinct_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13405 );
13406 assert_eq!(
13407 spec.has_unique_distinct_postcondition_kind(),
13408 lowered.boundary.has_unique_distinct_postcondition_kind(),
13409 "two-surface has_unique_distinct_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13410 );
13411 assert_eq!(
13412 spec.has_unique_distinct_condition_kind(),
13413 lowered.boundary.has_unique_distinct_condition_kind(),
13414 "two-surface has_unique_distinct_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13415 );
13416 }
13417 }
13418
13419 // Saturated ephemeral — every arm returns false on N ≥ 2 (N
13420 // distinct, not exactly 1).
13421 if ConditionKind::ALL.len() >= 2 {
13422 let mut spec = empty_ephemeral();
13423 for k in ConditionKind::ALL {
13424 spec.preconditions.push(cond(k));
13425 spec.postconditions.push(cond(k));
13426 }
13427 assert!(
13428 !spec.has_unique_distinct_precondition_kind(),
13429 "saturated ephemeral must return false on has_unique_distinct_precondition_kind",
13430 );
13431 assert!(
13432 !spec.has_unique_distinct_postcondition_kind(),
13433 "saturated ephemeral must return false on has_unique_distinct_postcondition_kind",
13434 );
13435 assert!(
13436 !spec.has_unique_distinct_condition_kind(),
13437 "saturated ephemeral must return false on has_unique_distinct_condition_kind",
13438 );
13439 }
13440 }
13441
13442 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality-many-arm
13443 /// triad on the closed-set-inversion axis) — the three
13444 /// `has_multiple_distinct_*_condition_kind` methods on
13445 /// [`EphemeralSpec`] delegate to the slice-level substrate
13446 /// primitive
13447 /// [`crate::boundary::ConditionSliceExt::has_multiple_distinct_kinds`]
13448 /// over the two `Vec<Condition>` slots (precondition +
13449 /// postcondition) and compose the union via a two-step-short-
13450 /// circuit walk over [`ConditionKind::ALL`] under
13451 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
13452 /// against
13453 /// [`crate::boundary::Boundary::has_multiple_distinct_condition_kind`]
13454 /// on the point-domain [`ProcessSpec`] surface — the two struct-
13455 /// level many-distinct callers compose against the SAME slice-
13456 /// level substrate primitive so a regression at the per-slice
13457 /// two-step short-circuit walk fails at that primitive's tests
13458 /// rather than as silent drift at either sugar-surface arm.
13459 #[test]
13460 fn has_multiple_distinct_condition_kind_triad_delegates_to_slice_has_multiple_distinct_kinds() {
13461 // Empty ephemeral spec — every arm returns false (0 distinct,
13462 // not ≥ 2).
13463 let spec = empty_ephemeral();
13464 assert!(
13465 !spec.has_multiple_distinct_precondition_kind(),
13466 "empty ephemeral must return false on has_multiple_distinct_precondition_kind",
13467 );
13468 assert!(
13469 !spec.has_multiple_distinct_postcondition_kind(),
13470 "empty ephemeral must return false on has_multiple_distinct_postcondition_kind",
13471 );
13472 assert!(
13473 !spec.has_multiple_distinct_condition_kind(),
13474 "empty ephemeral must return false on has_multiple_distinct_condition_kind",
13475 );
13476 assert_eq!(
13477 spec.has_multiple_distinct_condition_kind(),
13478 spec.distinct_condition_kind_count() >= 2,
13479 "empty has_multiple_distinct_condition_kind must equal (distinct_condition_kind_count() >= 2)",
13480 );
13481
13482 // Single-populated per side — sweep ALL × ALL. Every per-slice
13483 // arm returns false (1 distinct per slice, not ≥ 2); the
13484 // union returns true iff the two kinds DIFFER (union covers 2
13485 // distinct kinds).
13486 assert!(
13487 ConditionKind::ALL.len() >= 2,
13488 "test assumes ConditionKind::ALL has ≥ 2 variants",
13489 );
13490 for pre_kind in ConditionKind::ALL {
13491 for post_kind in ConditionKind::ALL {
13492 let mut spec = empty_ephemeral();
13493 spec.preconditions.push(cond(pre_kind));
13494 spec.postconditions.push(cond(post_kind));
13495 assert_eq!(
13496 spec.has_multiple_distinct_precondition_kind(),
13497 spec.preconditions.has_multiple_distinct_kinds(),
13498 "EphemeralSpec::has_multiple_distinct_precondition_kind must delegate verbatim to \
13499 preconditions.has_multiple_distinct_kinds() for pre={pre_kind:?} post={post_kind:?}",
13500 );
13501 assert_eq!(
13502 spec.has_multiple_distinct_postcondition_kind(),
13503 spec.postconditions.has_multiple_distinct_kinds(),
13504 "EphemeralSpec::has_multiple_distinct_postcondition_kind must delegate verbatim to \
13505 postconditions.has_multiple_distinct_kinds() for pre={pre_kind:?} post={post_kind:?}",
13506 );
13507 let covered_count = ConditionKind::ALL
13508 .into_iter()
13509 .filter(|k| *k == pre_kind || *k == post_kind)
13510 .count();
13511 let expected_union = covered_count >= 2;
13512 assert_eq!(
13513 spec.has_multiple_distinct_condition_kind(),
13514 expected_union,
13515 "EphemeralSpec::has_multiple_distinct_condition_kind must equal \
13516 (covered-ALL-count >= 2) for pre={pre_kind:?} post={post_kind:?}",
13517 );
13518
13519 // Two-surface parity: lowered ProcessSpec's Boundary
13520 // must agree bit-for-bit with the ephemeral sugar
13521 // triad on every arm.
13522 let lowered: ProcessSpec = spec.clone().into();
13523 assert_eq!(
13524 spec.has_multiple_distinct_precondition_kind(),
13525 lowered.boundary.has_multiple_distinct_precondition_kind(),
13526 "two-surface has_multiple_distinct_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13527 );
13528 assert_eq!(
13529 spec.has_multiple_distinct_postcondition_kind(),
13530 lowered.boundary.has_multiple_distinct_postcondition_kind(),
13531 "two-surface has_multiple_distinct_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13532 );
13533 assert_eq!(
13534 spec.has_multiple_distinct_condition_kind(),
13535 lowered.boundary.has_multiple_distinct_condition_kind(),
13536 "two-surface has_multiple_distinct_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13537 );
13538 }
13539 }
13540
13541 // Saturated ephemeral — every arm returns true on N ≥ 2 (N
13542 // distinct, ≥ 2).
13543 let mut spec = empty_ephemeral();
13544 for k in ConditionKind::ALL {
13545 spec.preconditions.push(cond(k));
13546 spec.postconditions.push(cond(k));
13547 }
13548 assert!(
13549 spec.has_multiple_distinct_precondition_kind(),
13550 "saturated ephemeral must return true on has_multiple_distinct_precondition_kind",
13551 );
13552 assert!(
13553 spec.has_multiple_distinct_postcondition_kind(),
13554 "saturated ephemeral must return true on has_multiple_distinct_postcondition_kind",
13555 );
13556 assert!(
13557 spec.has_multiple_distinct_condition_kind(),
13558 "saturated ephemeral must return true on has_multiple_distinct_condition_kind",
13559 );
13560 }
13561
13562 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality "≤ 1" triad
13563 /// on the closed-set-inversion axis) — the three
13564 /// `has_at_most_one_distinct_*_condition_kind` methods on
13565 /// [`EphemeralSpec`] delegate to the slice-level substrate
13566 /// primitive
13567 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_distinct_kind`]
13568 /// over the two `Vec<Condition>` slots (precondition +
13569 /// postcondition) and compose the union via a definitional
13570 /// negation of the many-arm two-step-short-circuit walk over
13571 /// [`ConditionKind::ALL`] under
13572 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
13573 /// against
13574 /// [`crate::boundary::Boundary::has_at_most_one_distinct_condition_kind`]
13575 /// on the point-domain [`ProcessSpec`] surface — the two struct-
13576 /// level empty-or-singleton callers compose against the SAME
13577 /// slice-level substrate primitive so a regression at the per-
13578 /// slice "≤ 1" negation fails at that primitive's tests rather
13579 /// than as silent drift at either sugar-surface arm.
13580 #[test]
13581 fn has_at_most_one_distinct_condition_kind_triad_delegates_to_slice_has_at_most_one_distinct_kind(
13582 ) {
13583 // Empty ephemeral spec — every arm returns true (0 distinct,
13584 // ≤ 1).
13585 let spec = empty_ephemeral();
13586 assert!(
13587 spec.has_at_most_one_distinct_precondition_kind(),
13588 "empty ephemeral must return true on has_at_most_one_distinct_precondition_kind",
13589 );
13590 assert!(
13591 spec.has_at_most_one_distinct_postcondition_kind(),
13592 "empty ephemeral must return true on has_at_most_one_distinct_postcondition_kind",
13593 );
13594 assert!(
13595 spec.has_at_most_one_distinct_condition_kind(),
13596 "empty ephemeral must return true on has_at_most_one_distinct_condition_kind",
13597 );
13598 assert_eq!(
13599 spec.has_at_most_one_distinct_condition_kind(),
13600 spec.distinct_condition_kind_count() <= 1,
13601 "empty has_at_most_one_distinct_condition_kind must equal (distinct_condition_kind_count() <= 1)",
13602 );
13603
13604 // Single-populated per side — sweep ALL × ALL. Every per-slice
13605 // arm returns true (1 distinct per slice, ≤ 1); the union
13606 // returns true iff the two kinds COINCIDE (union has 1
13607 // distinct), otherwise the union has 2 distinct and drops to
13608 // false.
13609 assert!(
13610 ConditionKind::ALL.len() >= 2,
13611 "test assumes ConditionKind::ALL has ≥ 2 variants",
13612 );
13613 for pre_kind in ConditionKind::ALL {
13614 for post_kind in ConditionKind::ALL {
13615 let mut spec = empty_ephemeral();
13616 spec.preconditions.push(cond(pre_kind));
13617 spec.postconditions.push(cond(post_kind));
13618 assert_eq!(
13619 spec.has_at_most_one_distinct_precondition_kind(),
13620 spec.preconditions.has_at_most_one_distinct_kind(),
13621 "EphemeralSpec::has_at_most_one_distinct_precondition_kind must delegate verbatim to \
13622 preconditions.has_at_most_one_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13623 );
13624 assert_eq!(
13625 spec.has_at_most_one_distinct_postcondition_kind(),
13626 spec.postconditions.has_at_most_one_distinct_kind(),
13627 "EphemeralSpec::has_at_most_one_distinct_postcondition_kind must delegate verbatim to \
13628 postconditions.has_at_most_one_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
13629 );
13630 let covered_count = ConditionKind::ALL
13631 .into_iter()
13632 .filter(|k| *k == pre_kind || *k == post_kind)
13633 .count();
13634 let expected_union = covered_count <= 1;
13635 assert_eq!(
13636 spec.has_at_most_one_distinct_condition_kind(),
13637 expected_union,
13638 "EphemeralSpec::has_at_most_one_distinct_condition_kind must equal \
13639 (covered-ALL-count <= 1) for pre={pre_kind:?} post={post_kind:?}",
13640 );
13641
13642 // Two-surface parity: lowered ProcessSpec's Boundary
13643 // must agree bit-for-bit with the ephemeral sugar
13644 // triad on every arm.
13645 let lowered: ProcessSpec = spec.clone().into();
13646 assert_eq!(
13647 spec.has_at_most_one_distinct_precondition_kind(),
13648 lowered.boundary.has_at_most_one_distinct_precondition_kind(),
13649 "two-surface has_at_most_one_distinct_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13650 );
13651 assert_eq!(
13652 spec.has_at_most_one_distinct_postcondition_kind(),
13653 lowered.boundary.has_at_most_one_distinct_postcondition_kind(),
13654 "two-surface has_at_most_one_distinct_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13655 );
13656 assert_eq!(
13657 spec.has_at_most_one_distinct_condition_kind(),
13658 lowered.boundary.has_at_most_one_distinct_condition_kind(),
13659 "two-surface has_at_most_one_distinct_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
13660 );
13661 }
13662 }
13663
13664 // Saturated ephemeral — every arm returns false on N ≥ 2 (N
13665 // distinct, not ≤ 1).
13666 let mut spec = empty_ephemeral();
13667 for k in ConditionKind::ALL {
13668 spec.preconditions.push(cond(k));
13669 spec.postconditions.push(cond(k));
13670 }
13671 assert!(
13672 !spec.has_at_most_one_distinct_precondition_kind(),
13673 "saturated ephemeral must return false on has_at_most_one_distinct_precondition_kind",
13674 );
13675 assert!(
13676 !spec.has_at_most_one_distinct_postcondition_kind(),
13677 "saturated ephemeral must return false on has_at_most_one_distinct_postcondition_kind",
13678 );
13679 assert!(
13680 !spec.has_at_most_one_distinct_condition_kind(),
13681 "saturated ephemeral must return false on has_at_most_one_distinct_condition_kind",
13682 );
13683 }
13684
13685 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality zero-
13686 /// endpoint triad) — the three `is_*_condition_kind_empty` methods
13687 /// on [`EphemeralSpec`] delegate to the slice-level substrate
13688 /// primitive
13689 /// [`crate::boundary::ConditionSliceExt::is_kind_empty`] over the
13690 /// two `Vec<Condition>` slots (precondition + postcondition) and
13691 /// compose the union via a definitional negation of the at-least-
13692 /// one halfspace primitive
13693 /// [`EphemeralSpec::has_any_distinct_condition_kind`]. Two-surface
13694 /// parity pin against
13695 /// [`crate::boundary::Boundary::is_condition_kind_empty`] on the
13696 /// point-domain [`ProcessSpec`] surface — the two struct-level
13697 /// zero-endpoint callers compose against the SAME slice-level
13698 /// substrate primitive so a regression at the per-slice zero-
13699 /// endpoint short-circuit fails at that primitive's tests rather
13700 /// than as silent drift at either sugar-surface arm.
13701 #[test]
13702 fn is_condition_kind_empty_triad_delegates_to_slice_is_kind_empty() {
13703 // Empty ephemeral spec — every arm returns true (0 distinct,
13704 // = 0).
13705 let spec = empty_ephemeral();
13706 assert!(
13707 spec.is_precondition_kind_empty(),
13708 "empty ephemeral must return true on is_precondition_kind_empty",
13709 );
13710 assert!(
13711 spec.is_postcondition_kind_empty(),
13712 "empty ephemeral must return true on is_postcondition_kind_empty",
13713 );
13714 assert!(
13715 spec.is_condition_kind_empty(),
13716 "empty ephemeral must return true on is_condition_kind_empty",
13717 );
13718
13719 // Two-surface parity: EphemeralSpec's three arms are byte-for-
13720 // byte equal to the lowered ProcessSpec's Boundary arms across
13721 // every sweep arm.
13722 let lowered: ProcessSpec = spec.clone().into();
13723 assert_eq!(
13724 spec.is_precondition_kind_empty(),
13725 lowered.boundary.is_precondition_kind_empty(),
13726 "empty ephemeral is_precondition_kind_empty must equal lowered Boundary is_precondition_kind_empty",
13727 );
13728 assert_eq!(
13729 spec.is_postcondition_kind_empty(),
13730 lowered.boundary.is_postcondition_kind_empty(),
13731 "empty ephemeral is_postcondition_kind_empty must equal lowered Boundary is_postcondition_kind_empty",
13732 );
13733 assert_eq!(
13734 spec.is_condition_kind_empty(),
13735 lowered.boundary.is_condition_kind_empty(),
13736 "empty ephemeral is_condition_kind_empty must equal lowered Boundary is_condition_kind_empty",
13737 );
13738
13739 // Single-populated per side — every per-slice arm returns
13740 // false; the union always returns false.
13741 assert!(
13742 !ConditionKind::ALL.is_empty(),
13743 "test assumes ConditionKind::ALL has ≥ 1 variants",
13744 );
13745 for pre_kind in ConditionKind::ALL {
13746 for post_kind in ConditionKind::ALL {
13747 let mut spec = empty_ephemeral();
13748 spec.preconditions.push(cond(pre_kind));
13749 spec.postconditions.push(cond(post_kind));
13750 assert_eq!(
13751 spec.is_precondition_kind_empty(),
13752 spec.preconditions.is_kind_empty(),
13753 "EphemeralSpec::is_precondition_kind_empty must delegate verbatim to \
13754 preconditions.is_kind_empty() for pre={pre_kind:?} post={post_kind:?}",
13755 );
13756 assert_eq!(
13757 spec.is_postcondition_kind_empty(),
13758 spec.postconditions.is_kind_empty(),
13759 "EphemeralSpec::is_postcondition_kind_empty must delegate verbatim to \
13760 postconditions.is_kind_empty() for pre={pre_kind:?} post={post_kind:?}",
13761 );
13762 assert!(
13763 !spec.is_precondition_kind_empty(),
13764 "single-populated preconditions must return false on is_precondition_kind_empty for pre={pre_kind:?}",
13765 );
13766 assert!(
13767 !spec.is_postcondition_kind_empty(),
13768 "single-populated postconditions must return false on is_postcondition_kind_empty for post={post_kind:?}",
13769 );
13770 assert!(
13771 !spec.is_condition_kind_empty(),
13772 "single-populated union must return false on is_condition_kind_empty for pre={pre_kind:?} post={post_kind:?}",
13773 );
13774 assert_eq!(
13775 spec.is_condition_kind_empty(),
13776 !spec.has_any_distinct_condition_kind(),
13777 "EphemeralSpec::is_condition_kind_empty must equal !has_any_distinct_condition_kind() for pre={pre_kind:?} post={post_kind:?}",
13778 );
13779 // Two-surface parity with lowered Boundary.
13780 let lowered: ProcessSpec = spec.clone().into();
13781 assert_eq!(
13782 spec.is_precondition_kind_empty(),
13783 lowered.boundary.is_precondition_kind_empty(),
13784 "EphemeralSpec::is_precondition_kind_empty must equal lowered Boundary::is_precondition_kind_empty for pre={pre_kind:?} post={post_kind:?}",
13785 );
13786 assert_eq!(
13787 spec.is_postcondition_kind_empty(),
13788 lowered.boundary.is_postcondition_kind_empty(),
13789 "EphemeralSpec::is_postcondition_kind_empty must equal lowered Boundary::is_postcondition_kind_empty for pre={pre_kind:?} post={post_kind:?}",
13790 );
13791 assert_eq!(
13792 spec.is_condition_kind_empty(),
13793 lowered.boundary.is_condition_kind_empty(),
13794 "EphemeralSpec::is_condition_kind_empty must equal lowered Boundary::is_condition_kind_empty for pre={pre_kind:?} post={post_kind:?}",
13795 );
13796 }
13797 }
13798
13799 // Saturated ephemeral spec — every arm returns false on N ≥ 1
13800 // (every kind PRESENT across the union, not = 0).
13801 let mut spec = empty_ephemeral();
13802 for k in ConditionKind::ALL {
13803 spec.preconditions.push(cond(k));
13804 spec.postconditions.push(cond(k));
13805 }
13806 assert!(
13807 !spec.is_precondition_kind_empty(),
13808 "saturated ephemeral must return false on is_precondition_kind_empty",
13809 );
13810 assert!(
13811 !spec.is_postcondition_kind_empty(),
13812 "saturated ephemeral must return false on is_postcondition_kind_empty",
13813 );
13814 assert!(
13815 !spec.is_condition_kind_empty(),
13816 "saturated ephemeral must return false on is_condition_kind_empty",
13817 );
13818 }
13819
13820 /// SUBSTRATE-DELEGATION pin (EphemeralSpec parent-state middle-arm
13821 /// triad) — the three `is_*_condition_kind_partially_covered`
13822 /// methods on [`EphemeralSpec`] delegate to the slice-level
13823 /// substrate primitive
13824 /// [`crate::boundary::ConditionSliceExt::is_kind_partially_covered`]
13825 /// over the two `Vec<Condition>` slots (precondition +
13826 /// postcondition) and compose the union via the paired-halfspace
13827 /// body `has_any_distinct_condition_kind() && has_any_missing_condition_kind()`.
13828 /// Two-surface parity pin against
13829 /// [`crate::boundary::Boundary::is_condition_kind_partially_covered`]
13830 /// on the point-domain [`ProcessSpec`] surface — the two
13831 /// struct-level middle-arm callers compose against the SAME
13832 /// slice-level substrate primitive so a regression at the per-
13833 /// slice fused short-circuit walk fails at that primitive's tests
13834 /// rather than as silent drift at either sugar-surface arm.
13835 #[test]
13836 fn is_condition_kind_partially_covered_triad_delegates_to_slice_is_kind_partially_covered() {
13837 // Empty ephemeral spec — every arm returns false on any N ≥ 1
13838 // closed set (0 distinct hits the empty arm).
13839 assert!(
13840 !ConditionKind::ALL.is_empty(),
13841 "test assumes ConditionKind::ALL has ≥ 1 variants",
13842 );
13843 let spec = empty_ephemeral();
13844 assert!(
13845 !spec.is_precondition_kind_partially_covered(),
13846 "empty ephemeral must return false on is_precondition_kind_partially_covered",
13847 );
13848 assert!(
13849 !spec.is_postcondition_kind_partially_covered(),
13850 "empty ephemeral must return false on is_postcondition_kind_partially_covered",
13851 );
13852 assert!(
13853 !spec.is_condition_kind_partially_covered(),
13854 "empty ephemeral must return false on is_condition_kind_partially_covered",
13855 );
13856
13857 // Two-surface parity: EphemeralSpec's three arms are byte-for-
13858 // byte equal to the lowered ProcessSpec's Boundary arms.
13859 let lowered: ProcessSpec = spec.clone().into();
13860 assert_eq!(
13861 spec.is_precondition_kind_partially_covered(),
13862 lowered.boundary.is_precondition_kind_partially_covered(),
13863 "empty ephemeral is_precondition_kind_partially_covered must equal lowered Boundary is_precondition_kind_partially_covered",
13864 );
13865 assert_eq!(
13866 spec.is_postcondition_kind_partially_covered(),
13867 lowered.boundary.is_postcondition_kind_partially_covered(),
13868 "empty ephemeral is_postcondition_kind_partially_covered must equal lowered Boundary is_postcondition_kind_partially_covered",
13869 );
13870 assert_eq!(
13871 spec.is_condition_kind_partially_covered(),
13872 lowered.boundary.is_condition_kind_partially_covered(),
13873 "empty ephemeral is_condition_kind_partially_covered must equal lowered Boundary is_condition_kind_partially_covered",
13874 );
13875
13876 // Single-populated per side — every per-slice arm returns
13877 // true on any N ≥ 2 closed set; union true iff coverage
13878 // leaves ≥ 1 ALL variant uncovered.
13879 if ConditionKind::ALL.len() >= 2 {
13880 for pre_kind in ConditionKind::ALL {
13881 for post_kind in ConditionKind::ALL {
13882 let mut spec = empty_ephemeral();
13883 spec.preconditions.push(cond(pre_kind));
13884 spec.postconditions.push(cond(post_kind));
13885 assert_eq!(
13886 spec.is_precondition_kind_partially_covered(),
13887 spec.preconditions.is_kind_partially_covered(),
13888 "EphemeralSpec::is_precondition_kind_partially_covered must delegate verbatim to \
13889 preconditions.is_kind_partially_covered() for pre={pre_kind:?} post={post_kind:?}",
13890 );
13891 assert_eq!(
13892 spec.is_postcondition_kind_partially_covered(),
13893 spec.postconditions.is_kind_partially_covered(),
13894 "EphemeralSpec::is_postcondition_kind_partially_covered must delegate verbatim to \
13895 postconditions.is_kind_partially_covered() for pre={pre_kind:?} post={post_kind:?}",
13896 );
13897 assert!(
13898 spec.is_precondition_kind_partially_covered(),
13899 "single-populated preconditions must return true on is_precondition_kind_partially_covered for pre={pre_kind:?}",
13900 );
13901 assert!(
13902 spec.is_postcondition_kind_partially_covered(),
13903 "single-populated postconditions must return true on is_postcondition_kind_partially_covered for post={post_kind:?}",
13904 );
13905 let covered_count = if pre_kind == post_kind { 1 } else { 2 };
13906 let expected_union = ConditionKind::ALL.len() > covered_count;
13907 assert_eq!(
13908 spec.is_condition_kind_partially_covered(),
13909 expected_union,
13910 "EphemeralSpec::is_condition_kind_partially_covered must equal \
13911 (ConditionKind::ALL.len() > covered-kinds-count) for pre={pre_kind:?} post={post_kind:?}",
13912 );
13913 // Two-surface parity with lowered Boundary.
13914 let lowered: ProcessSpec = spec.clone().into();
13915 assert_eq!(
13916 spec.is_precondition_kind_partially_covered(),
13917 lowered.boundary.is_precondition_kind_partially_covered(),
13918 "EphemeralSpec::is_precondition_kind_partially_covered must equal lowered Boundary::is_precondition_kind_partially_covered for pre={pre_kind:?} post={post_kind:?}",
13919 );
13920 assert_eq!(
13921 spec.is_postcondition_kind_partially_covered(),
13922 lowered.boundary.is_postcondition_kind_partially_covered(),
13923 "EphemeralSpec::is_postcondition_kind_partially_covered must equal lowered Boundary::is_postcondition_kind_partially_covered for pre={pre_kind:?} post={post_kind:?}",
13924 );
13925 assert_eq!(
13926 spec.is_condition_kind_partially_covered(),
13927 lowered.boundary.is_condition_kind_partially_covered(),
13928 "EphemeralSpec::is_condition_kind_partially_covered must equal lowered Boundary::is_condition_kind_partially_covered for pre={pre_kind:?} post={post_kind:?}",
13929 );
13930 // Trichotomy partition on the union axis.
13931 assert_eq!(
13932 usize::from(spec.is_condition_kind_empty())
13933 + usize::from(spec.is_condition_kind_partially_covered())
13934 + usize::from(spec.is_condition_kind_saturated()),
13935 1,
13936 "EphemeralSpec union trichotomy partition violated for pre={pre_kind:?} post={post_kind:?}",
13937 );
13938 }
13939 }
13940 }
13941
13942 // Saturated ephemeral spec — every arm returns false on any
13943 // N ≥ 1 closed set (0 missing hits the saturated arm).
13944 let mut spec = empty_ephemeral();
13945 for k in ConditionKind::ALL {
13946 spec.preconditions.push(cond(k));
13947 spec.postconditions.push(cond(k));
13948 }
13949 assert!(
13950 !spec.is_precondition_kind_partially_covered(),
13951 "saturated ephemeral must return false on is_precondition_kind_partially_covered",
13952 );
13953 assert!(
13954 !spec.is_postcondition_kind_partially_covered(),
13955 "saturated ephemeral must return false on is_postcondition_kind_partially_covered",
13956 );
13957 assert!(
13958 !spec.is_condition_kind_partially_covered(),
13959 "saturated ephemeral must return false on is_condition_kind_partially_covered",
13960 );
13961 }
13962
13963 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality-mid-endpoint
13964 /// triad) — the three `has_unique_missing_*_condition_kind`
13965 /// methods on [`EphemeralSpec`] delegate to the slice-level
13966 /// substrate primitive
13967 /// [`crate::boundary::ConditionSliceExt::has_unique_missing_kind`]
13968 /// over the two `Vec<Condition>` slots (precondition +
13969 /// postcondition) and compose the union via a two-step-short-
13970 /// circuit walk over [`ConditionKind::ALL`] under negated
13971 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
13972 /// against
13973 /// [`crate::boundary::Boundary::has_unique_missing_condition_kind`]
13974 /// on the point-domain [`ProcessSpec`] surface — the two struct-
13975 /// level near-saturation-endpoint callers compose against the
13976 /// SAME slice-level substrate primitive so a regression at the
13977 /// per-slice two-step short-circuit walk under negation fails at
13978 /// that primitive's tests rather than as silent drift at either
13979 /// sugar-surface arm.
13980 #[test]
13981 fn has_unique_missing_condition_kind_triad_delegates_to_slice_has_unique_missing_kind() {
13982 // Empty ephemeral spec — every arm returns false (all N
13983 // missing, not exactly 1) on any N ≥ 2 closed set.
13984 assert!(
13985 ConditionKind::ALL.len() >= 2,
13986 "test assumes ConditionKind::ALL has ≥ 2 variants",
13987 );
13988 let spec = empty_ephemeral();
13989 assert!(
13990 !spec.has_unique_missing_precondition_kind(),
13991 "empty ephemeral must return false on has_unique_missing_precondition_kind",
13992 );
13993 assert!(
13994 !spec.has_unique_missing_postcondition_kind(),
13995 "empty ephemeral must return false on has_unique_missing_postcondition_kind",
13996 );
13997 assert!(
13998 !spec.has_unique_missing_condition_kind(),
13999 "empty ephemeral must return false on has_unique_missing_condition_kind",
14000 );
14001 assert_eq!(
14002 spec.has_unique_missing_condition_kind(),
14003 spec.missing_condition_kind_count() == 1,
14004 "empty has_unique_missing_condition_kind must equal (missing_condition_kind_count() == 1)",
14005 );
14006
14007 // Single-populated per side — sweep ALL × ALL on N ≥ 3 closed
14008 // sets. Every per-slice arm returns false; the union returns
14009 // true iff exactly one ALL variant is uncovered.
14010 if ConditionKind::ALL.len() >= 3 {
14011 for pre_kind in ConditionKind::ALL {
14012 for post_kind in ConditionKind::ALL {
14013 let mut spec = empty_ephemeral();
14014 spec.preconditions.push(cond(pre_kind));
14015 spec.postconditions.push(cond(post_kind));
14016 assert_eq!(
14017 spec.has_unique_missing_precondition_kind(),
14018 spec.preconditions.has_unique_missing_kind(),
14019 "EphemeralSpec::has_unique_missing_precondition_kind must delegate verbatim to \
14020 preconditions.has_unique_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
14021 );
14022 assert_eq!(
14023 spec.has_unique_missing_postcondition_kind(),
14024 spec.postconditions.has_unique_missing_kind(),
14025 "EphemeralSpec::has_unique_missing_postcondition_kind must delegate verbatim to \
14026 postconditions.has_unique_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
14027 );
14028 let uncovered = ConditionKind::ALL
14029 .into_iter()
14030 .filter(|k| *k != pre_kind && *k != post_kind)
14031 .count();
14032 let expected_union = uncovered == 1;
14033 assert_eq!(
14034 spec.has_unique_missing_condition_kind(),
14035 expected_union,
14036 "EphemeralSpec::has_unique_missing_condition_kind must equal \
14037 (uncovered-ALL-count == 1) for pre={pre_kind:?} post={post_kind:?}",
14038 );
14039
14040 // Two-surface parity: lowered ProcessSpec's
14041 // Boundary must agree bit-for-bit with the
14042 // ephemeral sugar triad on every arm.
14043 let lowered: ProcessSpec = spec.clone().into();
14044 assert_eq!(
14045 spec.has_unique_missing_precondition_kind(),
14046 lowered.boundary.has_unique_missing_precondition_kind(),
14047 "two-surface has_unique_missing_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14048 );
14049 assert_eq!(
14050 spec.has_unique_missing_postcondition_kind(),
14051 lowered.boundary.has_unique_missing_postcondition_kind(),
14052 "two-surface has_unique_missing_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14053 );
14054 assert_eq!(
14055 spec.has_unique_missing_condition_kind(),
14056 lowered.boundary.has_unique_missing_condition_kind(),
14057 "two-surface has_unique_missing_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14058 );
14059 }
14060 }
14061 }
14062
14063 // Near-saturation-endpoint per side — each slice carries
14064 // every ConditionKind except one. Every per-slice arm returns
14065 // true; the union returns true iff BOTH slices omit the SAME
14066 // kind.
14067 for pre_omit in ConditionKind::ALL {
14068 for post_omit in ConditionKind::ALL {
14069 let mut spec = empty_ephemeral();
14070 for k in ConditionKind::ALL {
14071 if k != pre_omit {
14072 spec.preconditions.push(cond(k));
14073 }
14074 if k != post_omit {
14075 spec.postconditions.push(cond(k));
14076 }
14077 }
14078 assert!(
14079 spec.has_unique_missing_precondition_kind(),
14080 "near-saturation-endpoint precondition slice (omitting {pre_omit:?}) must return true on has_unique_missing_precondition_kind",
14081 );
14082 assert!(
14083 spec.has_unique_missing_postcondition_kind(),
14084 "near-saturation-endpoint postcondition slice (omitting {post_omit:?}) must return true on has_unique_missing_postcondition_kind",
14085 );
14086 let expected_union = pre_omit == post_omit;
14087 assert_eq!(
14088 spec.has_unique_missing_condition_kind(),
14089 expected_union,
14090 "EphemeralSpec::has_unique_missing_condition_kind on both-slices-near-saturated must equal (pre_omit == post_omit) for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14091 );
14092
14093 // Two-surface parity for near-saturation arm.
14094 let lowered: ProcessSpec = spec.clone().into();
14095 assert_eq!(
14096 spec.has_unique_missing_precondition_kind(),
14097 lowered.boundary.has_unique_missing_precondition_kind(),
14098 "two-surface has_unique_missing_precondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14099 );
14100 assert_eq!(
14101 spec.has_unique_missing_postcondition_kind(),
14102 lowered.boundary.has_unique_missing_postcondition_kind(),
14103 "two-surface has_unique_missing_postcondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14104 );
14105 assert_eq!(
14106 spec.has_unique_missing_condition_kind(),
14107 lowered.boundary.has_unique_missing_condition_kind(),
14108 "two-surface has_unique_missing_condition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14109 );
14110 }
14111 }
14112
14113 // Saturated ephemeral — every arm returns false (0 missing,
14114 // not exactly 1).
14115 let mut spec = empty_ephemeral();
14116 for k in ConditionKind::ALL {
14117 spec.preconditions.push(cond(k));
14118 spec.postconditions.push(cond(k));
14119 }
14120 assert!(
14121 !spec.has_unique_missing_precondition_kind(),
14122 "saturated ephemeral must return false on has_unique_missing_precondition_kind",
14123 );
14124 assert!(
14125 !spec.has_unique_missing_postcondition_kind(),
14126 "saturated ephemeral must return false on has_unique_missing_postcondition_kind",
14127 );
14128 assert!(
14129 !spec.has_unique_missing_condition_kind(),
14130 "saturated ephemeral must return false on has_unique_missing_condition_kind",
14131 );
14132 }
14133
14134 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality-many-arm
14135 /// triad) — the three `has_multiple_missing_*_condition_kind`
14136 /// methods on [`EphemeralSpec`] delegate to the slice-level
14137 /// substrate primitive
14138 /// [`crate::boundary::ConditionSliceExt::has_multiple_missing_kinds`]
14139 /// over the two `Vec<Condition>` slots (precondition +
14140 /// postcondition) and compose the union via a two-step-short-
14141 /// circuit walk over [`ConditionKind::ALL`] under negated
14142 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
14143 /// against
14144 /// [`crate::boundary::Boundary::has_multiple_missing_condition_kind`]
14145 /// on the point-domain [`ProcessSpec`] surface — the two struct-
14146 /// level cardinality-many-arm callers compose against the SAME
14147 /// slice-level substrate primitive so a regression at the per-
14148 /// slice two-step short-circuit walk under negation fails at that
14149 /// primitive's tests rather than as silent drift at either sugar-
14150 /// surface arm.
14151 #[test]
14152 fn has_multiple_missing_condition_kind_triad_delegates_to_slice_has_multiple_missing_kinds() {
14153 // Empty ephemeral spec — every arm returns true (all N
14154 // missing, ≥ 2) on any N ≥ 2 closed set.
14155 assert!(
14156 ConditionKind::ALL.len() >= 2,
14157 "test assumes ConditionKind::ALL has ≥ 2 variants",
14158 );
14159 let spec = empty_ephemeral();
14160 assert!(
14161 spec.has_multiple_missing_precondition_kind(),
14162 "empty ephemeral must return true on has_multiple_missing_precondition_kind",
14163 );
14164 assert!(
14165 spec.has_multiple_missing_postcondition_kind(),
14166 "empty ephemeral must return true on has_multiple_missing_postcondition_kind",
14167 );
14168 assert!(
14169 spec.has_multiple_missing_condition_kind(),
14170 "empty ephemeral must return true on has_multiple_missing_condition_kind",
14171 );
14172 assert_eq!(
14173 spec.has_multiple_missing_condition_kind(),
14174 spec.missing_condition_kind_count() >= 2,
14175 "empty has_multiple_missing_condition_kind must equal (missing_condition_kind_count() >= 2)",
14176 );
14177
14178 // Single-populated per side — sweep ALL × ALL on N ≥ 3 closed
14179 // sets. Every per-slice arm returns true; the union returns
14180 // true iff ≥ 2 ALL variants are uncovered.
14181 if ConditionKind::ALL.len() >= 3 {
14182 for pre_kind in ConditionKind::ALL {
14183 for post_kind in ConditionKind::ALL {
14184 let mut spec = empty_ephemeral();
14185 spec.preconditions.push(cond(pre_kind));
14186 spec.postconditions.push(cond(post_kind));
14187 assert_eq!(
14188 spec.has_multiple_missing_precondition_kind(),
14189 spec.preconditions.has_multiple_missing_kinds(),
14190 "EphemeralSpec::has_multiple_missing_precondition_kind must delegate verbatim to \
14191 preconditions.has_multiple_missing_kinds() for pre={pre_kind:?} post={post_kind:?}",
14192 );
14193 assert_eq!(
14194 spec.has_multiple_missing_postcondition_kind(),
14195 spec.postconditions.has_multiple_missing_kinds(),
14196 "EphemeralSpec::has_multiple_missing_postcondition_kind must delegate verbatim to \
14197 postconditions.has_multiple_missing_kinds() for pre={pre_kind:?} post={post_kind:?}",
14198 );
14199 let uncovered = ConditionKind::ALL
14200 .into_iter()
14201 .filter(|k| *k != pre_kind && *k != post_kind)
14202 .count();
14203 let expected_union = uncovered >= 2;
14204 assert_eq!(
14205 spec.has_multiple_missing_condition_kind(),
14206 expected_union,
14207 "EphemeralSpec::has_multiple_missing_condition_kind must equal \
14208 (uncovered-ALL-count >= 2) for pre={pre_kind:?} post={post_kind:?}",
14209 );
14210
14211 // Two-surface parity: lowered ProcessSpec's
14212 // Boundary must agree bit-for-bit with the
14213 // ephemeral sugar triad on every arm.
14214 let lowered: ProcessSpec = spec.clone().into();
14215 assert_eq!(
14216 spec.has_multiple_missing_precondition_kind(),
14217 lowered.boundary.has_multiple_missing_precondition_kind(),
14218 "two-surface has_multiple_missing_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14219 );
14220 assert_eq!(
14221 spec.has_multiple_missing_postcondition_kind(),
14222 lowered.boundary.has_multiple_missing_postcondition_kind(),
14223 "two-surface has_multiple_missing_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14224 );
14225 assert_eq!(
14226 spec.has_multiple_missing_condition_kind(),
14227 lowered.boundary.has_multiple_missing_condition_kind(),
14228 "two-surface has_multiple_missing_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14229 );
14230 }
14231 }
14232 }
14233
14234 // Near-saturation-endpoint per side — each slice carries
14235 // every ConditionKind except one. Every per-slice arm returns
14236 // false (exactly 1 missing per slice, not ≥ 2). The union
14237 // has at most 1 missing (pre and post's omissions either
14238 // coincide → 1 missing, or differ → 0 missing), so the union
14239 // is always false on this arm.
14240 for pre_omit in ConditionKind::ALL {
14241 for post_omit in ConditionKind::ALL {
14242 let mut spec = empty_ephemeral();
14243 for k in ConditionKind::ALL {
14244 if k != pre_omit {
14245 spec.preconditions.push(cond(k));
14246 }
14247 if k != post_omit {
14248 spec.postconditions.push(cond(k));
14249 }
14250 }
14251 assert!(
14252 !spec.has_multiple_missing_precondition_kind(),
14253 "near-saturation-endpoint precondition slice (omitting {pre_omit:?}) must return false on has_multiple_missing_precondition_kind",
14254 );
14255 assert!(
14256 !spec.has_multiple_missing_postcondition_kind(),
14257 "near-saturation-endpoint postcondition slice (omitting {post_omit:?}) must return false on has_multiple_missing_postcondition_kind",
14258 );
14259 assert!(
14260 !spec.has_multiple_missing_condition_kind(),
14261 "EphemeralSpec::has_multiple_missing_condition_kind on both-slices-near-saturated must always be false (union missing ≤ 1) for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14262 );
14263
14264 // Two-surface parity for near-saturation arm.
14265 let lowered: ProcessSpec = spec.clone().into();
14266 assert_eq!(
14267 spec.has_multiple_missing_precondition_kind(),
14268 lowered.boundary.has_multiple_missing_precondition_kind(),
14269 "two-surface has_multiple_missing_precondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14270 );
14271 assert_eq!(
14272 spec.has_multiple_missing_postcondition_kind(),
14273 lowered.boundary.has_multiple_missing_postcondition_kind(),
14274 "two-surface has_multiple_missing_postcondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14275 );
14276 assert_eq!(
14277 spec.has_multiple_missing_condition_kind(),
14278 lowered.boundary.has_multiple_missing_condition_kind(),
14279 "two-surface has_multiple_missing_condition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14280 );
14281 }
14282 }
14283
14284 // Saturated ephemeral — every arm returns false (0 missing,
14285 // not ≥ 2).
14286 let mut spec = empty_ephemeral();
14287 for k in ConditionKind::ALL {
14288 spec.preconditions.push(cond(k));
14289 spec.postconditions.push(cond(k));
14290 }
14291 assert!(
14292 !spec.has_multiple_missing_precondition_kind(),
14293 "saturated ephemeral must return false on has_multiple_missing_precondition_kind",
14294 );
14295 assert!(
14296 !spec.has_multiple_missing_postcondition_kind(),
14297 "saturated ephemeral must return false on has_multiple_missing_postcondition_kind",
14298 );
14299 assert!(
14300 !spec.has_multiple_missing_condition_kind(),
14301 "saturated ephemeral must return false on has_multiple_missing_condition_kind",
14302 );
14303 }
14304
14305 /// SUBSTRATE-DELEGATION pin (EphemeralSpec cardinality "≤ 1"
14306 /// triad) — the three `has_at_most_one_missing_*_condition_kind`
14307 /// methods on [`EphemeralSpec`] delegate to the slice-level
14308 /// substrate primitive
14309 /// [`crate::boundary::ConditionSliceExt::has_at_most_one_missing_kind`]
14310 /// over the two `Vec<Condition>` slots (precondition +
14311 /// postcondition) and compose the union via
14312 /// `!self.has_multiple_missing_condition_kind()` — a definitional
14313 /// negation of the many-arm union primitive. Two-surface parity
14314 /// pin against
14315 /// [`crate::boundary::Boundary::has_at_most_one_missing_condition_kind`]
14316 /// on the point-domain [`ProcessSpec`] surface — the two struct-
14317 /// level cardinality "≤ 1" callers compose against the SAME
14318 /// slice-level substrate primitive so a regression at the per-
14319 /// slice "≤ 1" negation fails at that primitive's tests rather
14320 /// than as silent drift at either sugar-surface arm.
14321 #[test]
14322 fn has_at_most_one_missing_condition_kind_triad_delegates_to_slice_has_at_most_one_missing_kind(
14323 ) {
14324 // Empty ephemeral spec — every arm returns false (all N
14325 // missing, not ≤ 1) on any N ≥ 2 closed set.
14326 assert!(
14327 ConditionKind::ALL.len() >= 2,
14328 "test assumes ConditionKind::ALL has ≥ 2 variants",
14329 );
14330 let spec = empty_ephemeral();
14331 assert!(
14332 !spec.has_at_most_one_missing_precondition_kind(),
14333 "empty ephemeral must return false on has_at_most_one_missing_precondition_kind",
14334 );
14335 assert!(
14336 !spec.has_at_most_one_missing_postcondition_kind(),
14337 "empty ephemeral must return false on has_at_most_one_missing_postcondition_kind",
14338 );
14339 assert!(
14340 !spec.has_at_most_one_missing_condition_kind(),
14341 "empty ephemeral must return false on has_at_most_one_missing_condition_kind",
14342 );
14343 assert_eq!(
14344 spec.has_at_most_one_missing_condition_kind(),
14345 spec.missing_condition_kind_count() <= 1,
14346 "empty has_at_most_one_missing_condition_kind must equal (missing_condition_kind_count() <= 1)",
14347 );
14348
14349 // Single-populated per side — sweep ALL × ALL on N ≥ 3
14350 // closed sets. Every per-slice arm returns false; the union
14351 // returns true iff ≤ 1 ALL variant is uncovered.
14352 if ConditionKind::ALL.len() >= 3 {
14353 for pre_kind in ConditionKind::ALL {
14354 for post_kind in ConditionKind::ALL {
14355 let mut spec = empty_ephemeral();
14356 spec.preconditions.push(cond(pre_kind));
14357 spec.postconditions.push(cond(post_kind));
14358 assert_eq!(
14359 spec.has_at_most_one_missing_precondition_kind(),
14360 spec.preconditions.has_at_most_one_missing_kind(),
14361 "EphemeralSpec::has_at_most_one_missing_precondition_kind must delegate verbatim to \
14362 preconditions.has_at_most_one_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
14363 );
14364 assert_eq!(
14365 spec.has_at_most_one_missing_postcondition_kind(),
14366 spec.postconditions.has_at_most_one_missing_kind(),
14367 "EphemeralSpec::has_at_most_one_missing_postcondition_kind must delegate verbatim to \
14368 postconditions.has_at_most_one_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
14369 );
14370 let uncovered = ConditionKind::ALL
14371 .into_iter()
14372 .filter(|k| *k != pre_kind && *k != post_kind)
14373 .count();
14374 let expected_union = uncovered <= 1;
14375 assert_eq!(
14376 spec.has_at_most_one_missing_condition_kind(),
14377 expected_union,
14378 "EphemeralSpec::has_at_most_one_missing_condition_kind must equal \
14379 (uncovered-ALL-count <= 1) for pre={pre_kind:?} post={post_kind:?}",
14380 );
14381
14382 // Two-surface parity: lowered ProcessSpec's
14383 // Boundary must agree bit-for-bit with the
14384 // ephemeral sugar triad on every arm.
14385 let lowered: ProcessSpec = spec.clone().into();
14386 assert_eq!(
14387 spec.has_at_most_one_missing_precondition_kind(),
14388 lowered.boundary.has_at_most_one_missing_precondition_kind(),
14389 "two-surface has_at_most_one_missing_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14390 );
14391 assert_eq!(
14392 spec.has_at_most_one_missing_postcondition_kind(),
14393 lowered.boundary.has_at_most_one_missing_postcondition_kind(),
14394 "two-surface has_at_most_one_missing_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14395 );
14396 assert_eq!(
14397 spec.has_at_most_one_missing_condition_kind(),
14398 lowered.boundary.has_at_most_one_missing_condition_kind(),
14399 "two-surface has_at_most_one_missing_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?}",
14400 );
14401 }
14402 }
14403 }
14404
14405 // Near-saturation-endpoint per side — each slice carries
14406 // every ConditionKind except one. Every per-slice arm returns
14407 // true (exactly 1 missing per slice, ≤ 1). The union has ≤ 1
14408 // missing (pre and post's omissions either coincide → 1
14409 // missing, or differ → 0 missing), so the union is always
14410 // true on this arm.
14411 for pre_omit in ConditionKind::ALL {
14412 for post_omit in ConditionKind::ALL {
14413 let mut spec = empty_ephemeral();
14414 for k in ConditionKind::ALL {
14415 if k != pre_omit {
14416 spec.preconditions.push(cond(k));
14417 }
14418 if k != post_omit {
14419 spec.postconditions.push(cond(k));
14420 }
14421 }
14422 assert!(
14423 spec.has_at_most_one_missing_precondition_kind(),
14424 "near-saturation-endpoint precondition slice (omitting {pre_omit:?}) must return true on has_at_most_one_missing_precondition_kind",
14425 );
14426 assert!(
14427 spec.has_at_most_one_missing_postcondition_kind(),
14428 "near-saturation-endpoint postcondition slice (omitting {post_omit:?}) must return true on has_at_most_one_missing_postcondition_kind",
14429 );
14430 assert!(
14431 spec.has_at_most_one_missing_condition_kind(),
14432 "EphemeralSpec::has_at_most_one_missing_condition_kind on both-slices-near-saturated must always be true (union missing ≤ 1) for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14433 );
14434
14435 // Two-surface parity for near-saturation arm.
14436 let lowered: ProcessSpec = spec.clone().into();
14437 assert_eq!(
14438 spec.has_at_most_one_missing_precondition_kind(),
14439 lowered.boundary.has_at_most_one_missing_precondition_kind(),
14440 "two-surface has_at_most_one_missing_precondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14441 );
14442 assert_eq!(
14443 spec.has_at_most_one_missing_postcondition_kind(),
14444 lowered.boundary.has_at_most_one_missing_postcondition_kind(),
14445 "two-surface has_at_most_one_missing_postcondition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14446 );
14447 assert_eq!(
14448 spec.has_at_most_one_missing_condition_kind(),
14449 lowered.boundary.has_at_most_one_missing_condition_kind(),
14450 "two-surface has_at_most_one_missing_condition_kind near-saturation parity drift for pre_omit={pre_omit:?} post_omit={post_omit:?}",
14451 );
14452 }
14453 }
14454
14455 // Saturated ephemeral — every arm returns true (0 missing,
14456 // ≤ 1).
14457 let mut spec = empty_ephemeral();
14458 for k in ConditionKind::ALL {
14459 spec.preconditions.push(cond(k));
14460 spec.postconditions.push(cond(k));
14461 }
14462 assert!(
14463 spec.has_at_most_one_missing_precondition_kind(),
14464 "saturated ephemeral must return true on has_at_most_one_missing_precondition_kind",
14465 );
14466 assert!(
14467 spec.has_at_most_one_missing_postcondition_kind(),
14468 "saturated ephemeral must return true on has_at_most_one_missing_postcondition_kind",
14469 );
14470 assert!(
14471 spec.has_at_most_one_missing_condition_kind(),
14472 "saturated ephemeral must return true on has_at_most_one_missing_condition_kind",
14473 );
14474 }
14475
14476 /// SUBSTRATE-DELEGATION pin (EphemeralSpec per-kind-complement
14477 /// triad) — the three `lacks_*_condition_kind` methods on
14478 /// [`EphemeralSpec`] delegate to the slice-level substrate primitive
14479 /// [`ConditionSliceExt::lacks_kind`] over the two `Vec<Condition>`
14480 /// slots (precondition + postcondition) and compose the union via
14481 /// `!self.has_condition_kind(kind)`. Two-surface parity pin against
14482 /// [`crate::boundary::Boundary::lacks_condition_kind`] on the
14483 /// point-domain [`ProcessSpec`] surface — the two struct-level
14484 /// per-kind-complement callers compose against the SAME slice-level
14485 /// substrate primitive so a regression at the per-slice negation
14486 /// fails at that primitive's tests rather than as silent drift at
14487 /// either sugar-surface arm. Also pins the composition laws
14488 /// `lacks_*_condition_kind(k) == !has_*_condition_kind(k)` at each
14489 /// arm AND `lacks_condition_kind(k) == lacks_precondition_kind(k) &&
14490 /// lacks_postcondition_kind(k)` (the union AND-composition dual of
14491 /// `has`'s OR-composition).
14492 #[test]
14493 fn lacks_condition_kind_triad_delegates_to_slice_lacks_kind() {
14494 // Empty ephemeral spec — every arm returns true on every kind.
14495 let spec = empty_ephemeral();
14496 for kind in ConditionKind::ALL {
14497 assert!(
14498 spec.lacks_precondition_kind(kind),
14499 "empty ephemeral must return true on lacks_precondition_kind for {kind:?}",
14500 );
14501 assert!(
14502 spec.lacks_postcondition_kind(kind),
14503 "empty ephemeral must return true on lacks_postcondition_kind for {kind:?}",
14504 );
14505 assert!(
14506 spec.lacks_condition_kind(kind),
14507 "empty ephemeral must return true on lacks_condition_kind for {kind:?}",
14508 );
14509 assert_eq!(
14510 spec.lacks_condition_kind(kind),
14511 !spec.has_condition_kind(kind),
14512 "empty lacks_condition_kind must equal !has_condition_kind for {kind:?}",
14513 );
14514 }
14515
14516 // Single-populated per side — sweep ALL × ALL, then probe every
14517 // ConditionKind on the (pre, post, union) triad + two-surface
14518 // parity against the lowered ProcessSpec's Boundary.
14519 for pre_kind in ConditionKind::ALL {
14520 for post_kind in ConditionKind::ALL {
14521 let mut spec = empty_ephemeral();
14522 spec.preconditions.push(cond(pre_kind));
14523 spec.postconditions.push(cond(post_kind));
14524 let lowered: ProcessSpec = spec.clone().into();
14525 for probe in ConditionKind::ALL {
14526 assert_eq!(
14527 spec.lacks_precondition_kind(probe),
14528 spec.preconditions.lacks_kind(probe),
14529 "EphemeralSpec::lacks_precondition_kind must delegate verbatim to preconditions.lacks_kind for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14530 );
14531 assert_eq!(
14532 spec.lacks_postcondition_kind(probe),
14533 spec.postconditions.lacks_kind(probe),
14534 "EphemeralSpec::lacks_postcondition_kind must delegate verbatim to postconditions.lacks_kind for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14535 );
14536 let expected_union = pre_kind != probe && post_kind != probe;
14537 assert_eq!(
14538 spec.lacks_condition_kind(probe),
14539 expected_union,
14540 "EphemeralSpec::lacks_condition_kind must equal all-ALL-absent-in-both-slices for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14541 );
14542 assert_eq!(
14543 spec.lacks_condition_kind(probe),
14544 !spec.has_condition_kind(probe),
14545 "EphemeralSpec::lacks_condition_kind must equal !has_condition_kind for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14546 );
14547 assert_eq!(
14548 spec.lacks_condition_kind(probe),
14549 spec.lacks_precondition_kind(probe)
14550 && spec.lacks_postcondition_kind(probe),
14551 "EphemeralSpec::lacks_condition_kind must equal AND-of-half-slice-arms for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14552 );
14553
14554 // Two-surface parity: lowered ProcessSpec's Boundary
14555 // must agree bit-for-bit with the ephemeral sugar
14556 // triad on every arm.
14557 assert_eq!(
14558 spec.lacks_precondition_kind(probe),
14559 lowered.boundary.lacks_precondition_kind(probe),
14560 "two-surface lacks_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14561 );
14562 assert_eq!(
14563 spec.lacks_postcondition_kind(probe),
14564 lowered.boundary.lacks_postcondition_kind(probe),
14565 "two-surface lacks_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14566 );
14567 assert_eq!(
14568 spec.lacks_condition_kind(probe),
14569 lowered.boundary.lacks_condition_kind(probe),
14570 "two-surface lacks_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14571 );
14572 }
14573 }
14574 }
14575
14576 // Saturated ephemeral — both slices carry every ConditionKind,
14577 // every arm returns false on every kind.
14578 let mut spec = empty_ephemeral();
14579 for k in ConditionKind::ALL {
14580 spec.preconditions.push(cond(k));
14581 spec.postconditions.push(cond(k));
14582 }
14583 for kind in ConditionKind::ALL {
14584 assert!(
14585 !spec.lacks_precondition_kind(kind),
14586 "saturated ephemeral must return false on lacks_precondition_kind for {kind:?}",
14587 );
14588 assert!(
14589 !spec.lacks_postcondition_kind(kind),
14590 "saturated ephemeral must return false on lacks_postcondition_kind for {kind:?}",
14591 );
14592 assert!(
14593 !spec.lacks_condition_kind(kind),
14594 "saturated ephemeral must return false on lacks_condition_kind for {kind:?}",
14595 );
14596 }
14597 }
14598
14599 /// TRIAD delegation pin — the (precondition, postcondition,
14600 /// condition-union) kind-scoped strict-refinement triad on
14601 /// [`EphemeralSpec`] agrees byte-for-byte with the slice-level
14602 /// substrate primitive
14603 /// [`crate::boundary::ConditionSliceExt::has_only_kind`] on every
14604 /// authored arrangement AND with the lowered
14605 /// [`ProcessSpec::boundary`]'s kind-scoped strict-refinement
14606 /// triad through the `From<EphemeralSpec>` bridge — the two-
14607 /// surface parity contract at the well-formed-diagonal arm.
14608 ///
14609 /// Sweeps [`ConditionKind::ALL`] × [`ConditionKind::ALL`] over
14610 /// single-populated-per-side arrangements (the well-formed
14611 /// diagonal), probing every [`ConditionKind`] at the union arm
14612 /// against the DERIVED oracle `pre_kind == probe && post_kind ==
14613 /// probe`. Also sweeps the single-side-only-populated arms (the
14614 /// union carries a singleton distinct set — pins the union arm
14615 /// reaches the union primitive, not the (pre AND post) AND-
14616 /// composition). A regression at the union arm's fused walk or
14617 /// at the `From<EphemeralSpec>` bridge surfaces HERE.
14618 #[test]
14619 fn has_only_condition_kind_triad_delegates_to_slice_has_only_kind() {
14620 // Empty ephemeral spec — every arm returns false on every
14621 // kind (no kind is populated, so no kind is "only").
14622 let spec = empty_ephemeral();
14623 for kind in ConditionKind::ALL {
14624 assert!(
14625 !spec.has_only_precondition_kind(kind),
14626 "empty ephemeral must return false on has_only_precondition_kind for {kind:?}",
14627 );
14628 assert!(
14629 !spec.has_only_postcondition_kind(kind),
14630 "empty ephemeral must return false on has_only_postcondition_kind for {kind:?}",
14631 );
14632 assert!(
14633 !spec.has_only_condition_kind(kind),
14634 "empty ephemeral must return false on has_only_condition_kind for {kind:?}",
14635 );
14636 }
14637
14638 // Single-populated per side — sweep ALL × ALL, then probe
14639 // every ConditionKind on the (pre, post, union) triad + two-
14640 // surface parity against the lowered ProcessSpec's Boundary.
14641 for pre_kind in ConditionKind::ALL {
14642 for post_kind in ConditionKind::ALL {
14643 let mut spec = empty_ephemeral();
14644 spec.preconditions.push(cond(pre_kind));
14645 spec.postconditions.push(cond(post_kind));
14646 let lowered: ProcessSpec = spec.clone().into();
14647 for probe in ConditionKind::ALL {
14648 assert_eq!(
14649 spec.has_only_precondition_kind(probe),
14650 spec.preconditions.has_only_kind(probe),
14651 "EphemeralSpec::has_only_precondition_kind must delegate verbatim to preconditions.has_only_kind for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14652 );
14653 assert_eq!(
14654 spec.has_only_postcondition_kind(probe),
14655 spec.postconditions.has_only_kind(probe),
14656 "EphemeralSpec::has_only_postcondition_kind must delegate verbatim to postconditions.has_only_kind for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14657 );
14658 let expected_union = pre_kind == probe && post_kind == probe;
14659 assert_eq!(
14660 spec.has_only_condition_kind(probe),
14661 expected_union,
14662 "EphemeralSpec::has_only_condition_kind must equal (pre_kind == probe && post_kind == probe) for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14663 );
14664
14665 // Two-surface parity: lowered ProcessSpec's
14666 // Boundary must agree bit-for-bit with the
14667 // ephemeral sugar triad on every arm.
14668 assert_eq!(
14669 spec.has_only_precondition_kind(probe),
14670 lowered.boundary.has_only_precondition_kind(probe),
14671 "two-surface has_only_precondition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14672 );
14673 assert_eq!(
14674 spec.has_only_postcondition_kind(probe),
14675 lowered.boundary.has_only_postcondition_kind(probe),
14676 "two-surface has_only_postcondition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14677 );
14678 assert_eq!(
14679 spec.has_only_condition_kind(probe),
14680 lowered.boundary.has_only_condition_kind(probe),
14681 "two-surface has_only_condition_kind parity drift for pre={pre_kind:?} post={post_kind:?} probe={probe:?}",
14682 );
14683 }
14684 }
14685 }
14686
14687 // Single-side-only populated — the union carries a singleton
14688 // distinct set; the union arm returns `true` for the populated
14689 // kind and `false` for every other kind, DESPITE the empty
14690 // side's `has_only_kind` returning `false`. Pins that the
14691 // union arm reaches the union primitive
14692 // [`Self::has_condition_kind`], not the (pre AND post) AND-
14693 // composition of the per-slice arms. Also pins two-surface
14694 // parity on the single-side arrangement.
14695 for populated in ConditionKind::ALL {
14696 let mut spec = empty_ephemeral();
14697 spec.preconditions.push(cond(populated));
14698 let lowered: ProcessSpec = spec.clone().into();
14699 for probe in ConditionKind::ALL {
14700 let expected = probe == populated;
14701 assert_eq!(
14702 spec.has_only_condition_kind(probe),
14703 expected,
14704 "pre-only ephemeral populated={populated:?} must return {expected} on has_only_condition_kind({probe:?})",
14705 );
14706 assert_eq!(
14707 spec.has_only_condition_kind(probe),
14708 lowered.boundary.has_only_condition_kind(probe),
14709 "two-surface pre-only has_only_condition_kind parity drift for populated={populated:?} probe={probe:?}",
14710 );
14711 }
14712
14713 let mut spec = empty_ephemeral();
14714 spec.postconditions.push(cond(populated));
14715 let lowered: ProcessSpec = spec.clone().into();
14716 for probe in ConditionKind::ALL {
14717 let expected = probe == populated;
14718 assert_eq!(
14719 spec.has_only_condition_kind(probe),
14720 expected,
14721 "post-only ephemeral populated={populated:?} must return {expected} on has_only_condition_kind({probe:?})",
14722 );
14723 assert_eq!(
14724 spec.has_only_condition_kind(probe),
14725 lowered.boundary.has_only_condition_kind(probe),
14726 "two-surface post-only has_only_condition_kind parity drift for populated={populated:?} probe={probe:?}",
14727 );
14728 }
14729 }
14730
14731 // Saturated ephemeral — both slices carry every ConditionKind,
14732 // every arm returns false on every kind (N distinct kinds, no
14733 // kind is "only").
14734 let mut spec = empty_ephemeral();
14735 for k in ConditionKind::ALL {
14736 spec.preconditions.push(cond(k));
14737 spec.postconditions.push(cond(k));
14738 }
14739 for kind in ConditionKind::ALL {
14740 assert!(
14741 !spec.has_only_precondition_kind(kind),
14742 "saturated ephemeral must return false on has_only_precondition_kind for {kind:?}",
14743 );
14744 assert!(
14745 !spec.has_only_postcondition_kind(kind),
14746 "saturated ephemeral must return false on has_only_postcondition_kind for {kind:?}",
14747 );
14748 assert!(
14749 !spec.has_only_condition_kind(kind),
14750 "saturated ephemeral must return false on has_only_condition_kind for {kind:?}",
14751 );
14752 }
14753 }
14754
14755 /// TRIAD delegation pin — the (precondition, postcondition,
14756 /// condition-union) kind-scoped strict-refinement-on-missing triad
14757 /// on [`EphemeralSpec`] agrees byte-for-byte with the slice-level
14758 /// substrate primitive
14759 /// [`crate::boundary::ConditionSliceExt::lacks_only_kind`] on every
14760 /// authored arrangement, AND agrees bit-for-bit with the lowered
14761 /// [`ProcessSpec::boundary`]'s triad via the [`From`] bridge.
14762 ///
14763 /// Sweeps [`ConditionKind::ALL`] × [`ConditionKind::ALL`] over
14764 /// single-populated-per-side arrangements + near-saturation-per-
14765 /// side arrangements + single-side-only near-saturation
14766 /// arrangements. The union arm is probed against the DERIVED
14767 /// oracle `spec.missing_condition_kinds() == vec![probe]`, and
14768 /// the per-slice arms delegate to the slice substrate primitive
14769 /// verbatim. Two-surface parity ensures a regression at the
14770 /// `From<EphemeralSpec>` bridge (a re-ordered condition Vec, a
14771 /// dropped ClosedLoopAuth default) surfaces HERE at the union arm.
14772 #[test]
14773 fn lacks_only_condition_kind_triad_delegates_to_slice_lacks_only_kind() {
14774 // Empty ephemeral spec — every kind is missing on N ≥ 2, so
14775 // no kind is "only" missing on any arm.
14776 let spec = empty_ephemeral();
14777 let lowered: ProcessSpec = spec.clone().into();
14778 for kind in ConditionKind::ALL {
14779 assert_eq!(
14780 spec.lacks_only_precondition_kind(kind),
14781 spec.preconditions.lacks_only_kind(kind),
14782 "empty ephemeral lacks_only_precondition_kind must delegate to preconditions.lacks_only_kind for {kind:?}",
14783 );
14784 assert_eq!(
14785 spec.lacks_only_postcondition_kind(kind),
14786 spec.postconditions.lacks_only_kind(kind),
14787 "empty ephemeral lacks_only_postcondition_kind must delegate to postconditions.lacks_only_kind for {kind:?}",
14788 );
14789 assert_eq!(
14790 spec.lacks_only_condition_kind(kind),
14791 lowered.boundary.lacks_only_condition_kind(kind),
14792 "two-surface empty lacks_only_condition_kind parity drift for {kind:?}",
14793 );
14794 }
14795
14796 // Near-saturation per side — build an ephemeral spec whose both
14797 // sides carry every kind except one; sweep every omitted kind
14798 // and probe every ConditionKind on the (pre, post, union) triad.
14799 for omitted in ConditionKind::ALL {
14800 let mut spec = empty_ephemeral();
14801 for k in ConditionKind::ALL {
14802 if k != omitted {
14803 spec.preconditions.push(cond(k));
14804 spec.postconditions.push(cond(k));
14805 }
14806 }
14807 let lowered: ProcessSpec = spec.clone().into();
14808 for probe in ConditionKind::ALL {
14809 let expected = probe == omitted;
14810 assert_eq!(
14811 spec.lacks_only_precondition_kind(probe),
14812 expected,
14813 "near-saturation ephemeral omitted={omitted:?} must return {expected} on lacks_only_precondition_kind({probe:?})",
14814 );
14815 assert_eq!(
14816 spec.lacks_only_postcondition_kind(probe),
14817 expected,
14818 "near-saturation ephemeral omitted={omitted:?} must return {expected} on lacks_only_postcondition_kind({probe:?})",
14819 );
14820 assert_eq!(
14821 spec.lacks_only_condition_kind(probe),
14822 expected,
14823 "near-saturation ephemeral omitted={omitted:?} must return {expected} on lacks_only_condition_kind({probe:?})",
14824 );
14825 assert_eq!(
14826 spec.lacks_only_condition_kind(probe),
14827 spec.missing_condition_kinds() == vec![probe],
14828 "near-saturation ephemeral omitted={omitted:?} must agree with missing_condition_kinds() == vec![{probe:?}]",
14829 );
14830
14831 // Two-surface parity via lowered ProcessSpec.
14832 assert_eq!(
14833 spec.lacks_only_precondition_kind(probe),
14834 lowered.boundary.lacks_only_precondition_kind(probe),
14835 "two-surface lacks_only_precondition_kind parity drift for omitted={omitted:?} probe={probe:?}",
14836 );
14837 assert_eq!(
14838 spec.lacks_only_postcondition_kind(probe),
14839 lowered.boundary.lacks_only_postcondition_kind(probe),
14840 "two-surface lacks_only_postcondition_kind parity drift for omitted={omitted:?} probe={probe:?}",
14841 );
14842 assert_eq!(
14843 spec.lacks_only_condition_kind(probe),
14844 lowered.boundary.lacks_only_condition_kind(probe),
14845 "two-surface lacks_only_condition_kind parity drift for omitted={omitted:?} probe={probe:?}",
14846 );
14847 }
14848 }
14849
14850 // Single-side-only near-saturation — the populated side covers
14851 // every kind except one; the OTHER side is empty. The union
14852 // still has missing set `{omitted}` (the populated side's hole
14853 // wins), so the union arm returns `true` for `omitted` and
14854 // `false` for every other kind, DESPITE the empty side's
14855 // `lacks_only_kind` returning `false` on every kind for N ≥ 2.
14856 // Pins that the union arm reaches the union primitive, not the
14857 // (pre AND post) AND-composition.
14858 for omitted in ConditionKind::ALL {
14859 let mut spec = empty_ephemeral();
14860 for k in ConditionKind::ALL {
14861 if k != omitted {
14862 spec.preconditions.push(cond(k));
14863 }
14864 }
14865 let lowered: ProcessSpec = spec.clone().into();
14866 for probe in ConditionKind::ALL {
14867 let expected = probe == omitted;
14868 assert_eq!(
14869 spec.lacks_only_condition_kind(probe),
14870 expected,
14871 "pre-only near-saturation ephemeral omitted={omitted:?} must return {expected} on lacks_only_condition_kind({probe:?})",
14872 );
14873 assert_eq!(
14874 spec.lacks_only_condition_kind(probe),
14875 lowered.boundary.lacks_only_condition_kind(probe),
14876 "two-surface pre-only near-saturation lacks_only_condition_kind parity drift for omitted={omitted:?} probe={probe:?}",
14877 );
14878 }
14879 }
14880
14881 // Saturated ephemeral — every kind populated, no kind missing,
14882 // every arm returns false on every kind.
14883 let mut spec = empty_ephemeral();
14884 for k in ConditionKind::ALL {
14885 spec.preconditions.push(cond(k));
14886 spec.postconditions.push(cond(k));
14887 }
14888 for kind in ConditionKind::ALL {
14889 assert!(
14890 !spec.lacks_only_precondition_kind(kind),
14891 "saturated ephemeral must return false on lacks_only_precondition_kind for {kind:?}",
14892 );
14893 assert!(
14894 !spec.lacks_only_postcondition_kind(kind),
14895 "saturated ephemeral must return false on lacks_only_postcondition_kind for {kind:?}",
14896 );
14897 assert!(
14898 !spec.lacks_only_condition_kind(kind),
14899 "saturated ephemeral must return false on lacks_only_condition_kind for {kind:?}",
14900 );
14901 }
14902 }
14903
14904 /// SUBSTRATE-DELEGATION pin (EphemeralSpec unique-distinct-kind
14905 /// witnessing triad on the closed-set-inversion axis) — the three
14906 /// `unique_distinct_*_condition_kind` methods on [`EphemeralSpec`]
14907 /// delegate to the slice-level substrate primitive
14908 /// [`crate::boundary::ConditionSliceExt::unique_distinct_kind`]
14909 /// over the two `Vec<Condition>` slots (precondition +
14910 /// postcondition) and compose the union via a two-step-short-
14911 /// circuit walk over [`ConditionKind::ALL`] under
14912 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
14913 /// against
14914 /// [`crate::boundary::Boundary::unique_distinct_condition_kind`]
14915 /// on the point-domain [`ProcessSpec`] surface — the two struct-
14916 /// level singleton-coverage witnesses compose against the SAME
14917 /// slice-level substrate primitive so a regression at the per-
14918 /// slice two-step short-circuit witnessing walk fails at that
14919 /// primitive's tests rather than as silent drift at either sugar-
14920 /// surface arm.
14921 #[test]
14922 fn unique_distinct_condition_kind_triad_delegates_to_slice_unique_distinct_kind() {
14923 // Empty ephemeral spec — every arm returns None.
14924 let spec = empty_ephemeral();
14925 assert_eq!(
14926 spec.unique_distinct_precondition_kind(),
14927 None,
14928 "empty ephemeral must return None on unique_distinct_precondition_kind",
14929 );
14930 assert_eq!(
14931 spec.unique_distinct_postcondition_kind(),
14932 None,
14933 "empty ephemeral must return None on unique_distinct_postcondition_kind",
14934 );
14935 assert_eq!(
14936 spec.unique_distinct_condition_kind(),
14937 None,
14938 "empty ephemeral must return None on unique_distinct_condition_kind",
14939 );
14940
14941 // Single-populated per side — sweep ALL × ALL.
14942 for pre_kind in ConditionKind::ALL {
14943 for post_kind in ConditionKind::ALL {
14944 let mut spec = empty_ephemeral();
14945 spec.preconditions.push(cond(pre_kind));
14946 spec.postconditions.push(cond(post_kind));
14947
14948 assert_eq!(
14949 spec.unique_distinct_precondition_kind(),
14950 spec.preconditions.unique_distinct_kind(),
14951 "EphemeralSpec::unique_distinct_precondition_kind must delegate verbatim to \
14952 preconditions.unique_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
14953 );
14954 assert_eq!(
14955 spec.unique_distinct_precondition_kind(),
14956 Some(pre_kind),
14957 "EphemeralSpec::unique_distinct_precondition_kind must equal Some(pre_kind) on \
14958 single-populated preconditions for pre={pre_kind:?} post={post_kind:?}",
14959 );
14960 assert_eq!(
14961 spec.unique_distinct_postcondition_kind(),
14962 spec.postconditions.unique_distinct_kind(),
14963 "EphemeralSpec::unique_distinct_postcondition_kind must delegate verbatim to \
14964 postconditions.unique_distinct_kind() for pre={pre_kind:?} post={post_kind:?}",
14965 );
14966 assert_eq!(
14967 spec.unique_distinct_postcondition_kind(),
14968 Some(post_kind),
14969 "EphemeralSpec::unique_distinct_postcondition_kind must equal Some(post_kind) on \
14970 single-populated postconditions for pre={pre_kind:?} post={post_kind:?}",
14971 );
14972
14973 let covered: Vec<ConditionKind> = ConditionKind::ALL
14974 .into_iter()
14975 .filter(|k| pre_kind == *k || post_kind == *k)
14976 .collect();
14977 let expected_union = if covered.len() == 1 {
14978 Some(covered[0])
14979 } else {
14980 None
14981 };
14982 assert_eq!(
14983 spec.unique_distinct_condition_kind(),
14984 expected_union,
14985 "EphemeralSpec::unique_distinct_condition_kind must equal Some(k) iff the \
14986 ALL-entries covered by either half-slice sum to exactly one for \
14987 pre={pre_kind:?} post={post_kind:?}",
14988 );
14989
14990 // Boolean-witness composition laws.
14991 assert_eq!(
14992 spec.unique_distinct_condition_kind().is_some(),
14993 spec.has_unique_distinct_condition_kind(),
14994 "unique_distinct_condition_kind().is_some() must equal \
14995 has_unique_distinct_condition_kind() for pre={pre_kind:?} post={post_kind:?}",
14996 );
14997
14998 // Two-surface parity — lowered ProcessSpec's Boundary
14999 // must agree bit-for-bit with the ephemeral sugar
15000 // triad on every arm.
15001 let lowered: ProcessSpec = spec.clone().into();
15002 assert_eq!(
15003 spec.unique_distinct_precondition_kind(),
15004 lowered.boundary.unique_distinct_precondition_kind(),
15005 "two-surface unique_distinct_precondition_kind parity drift for \
15006 pre={pre_kind:?} post={post_kind:?}",
15007 );
15008 assert_eq!(
15009 spec.unique_distinct_postcondition_kind(),
15010 lowered.boundary.unique_distinct_postcondition_kind(),
15011 "two-surface unique_distinct_postcondition_kind parity drift for \
15012 pre={pre_kind:?} post={post_kind:?}",
15013 );
15014 assert_eq!(
15015 spec.unique_distinct_condition_kind(),
15016 lowered.boundary.unique_distinct_condition_kind(),
15017 "two-surface unique_distinct_condition_kind parity drift for \
15018 pre={pre_kind:?} post={post_kind:?}",
15019 );
15020 }
15021 }
15022
15023 // Saturated ephemeral — every arm returns None on N ≥ 2.
15024 if ConditionKind::ALL.len() >= 2 {
15025 let mut spec = empty_ephemeral();
15026 for k in ConditionKind::ALL {
15027 spec.preconditions.push(cond(k));
15028 spec.postconditions.push(cond(k));
15029 }
15030 assert_eq!(
15031 spec.unique_distinct_precondition_kind(),
15032 None,
15033 "saturated ephemeral must return None on unique_distinct_precondition_kind",
15034 );
15035 assert_eq!(
15036 spec.unique_distinct_postcondition_kind(),
15037 None,
15038 "saturated ephemeral must return None on unique_distinct_postcondition_kind",
15039 );
15040 assert_eq!(
15041 spec.unique_distinct_condition_kind(),
15042 None,
15043 "saturated ephemeral must return None on unique_distinct_condition_kind",
15044 );
15045 }
15046 }
15047
15048 /// SUBSTRATE-DELEGATION pin (EphemeralSpec unique-missing-kind
15049 /// witnessing triad on the closed-set-complement axis) — the three
15050 /// `unique_missing_*_condition_kind` methods on [`EphemeralSpec`]
15051 /// delegate to the slice-level substrate primitive
15052 /// [`crate::boundary::ConditionSliceExt::unique_missing_kind`]
15053 /// over the two `Vec<Condition>` slots (precondition +
15054 /// postcondition) and compose the union via a two-step-short-
15055 /// circuit walk over [`ConditionKind::ALL`] under a NEGATED
15056 /// [`EphemeralSpec::has_condition_kind`]. Two-surface parity pin
15057 /// against
15058 /// [`crate::boundary::Boundary::unique_missing_condition_kind`]
15059 /// on the point-domain [`ProcessSpec`] surface.
15060 #[test]
15061 fn unique_missing_condition_kind_triad_delegates_to_slice_unique_missing_kind() {
15062 // Empty ephemeral spec — every arm returns None on N ≥ 2
15063 // (every kind is missing, not exactly one).
15064 let spec = empty_ephemeral();
15065 if ConditionKind::ALL.len() >= 2 {
15066 assert_eq!(
15067 spec.unique_missing_precondition_kind(),
15068 None,
15069 "empty ephemeral must return None on unique_missing_precondition_kind on N ≥ 2",
15070 );
15071 assert_eq!(
15072 spec.unique_missing_postcondition_kind(),
15073 None,
15074 "empty ephemeral must return None on unique_missing_postcondition_kind on N ≥ 2",
15075 );
15076 assert_eq!(
15077 spec.unique_missing_condition_kind(),
15078 None,
15079 "empty ephemeral must return None on unique_missing_condition_kind on N ≥ 2",
15080 );
15081 }
15082
15083 // Single-populated per side — sweep ALL × ALL.
15084 for pre_kind in ConditionKind::ALL {
15085 for post_kind in ConditionKind::ALL {
15086 let mut spec = empty_ephemeral();
15087 spec.preconditions.push(cond(pre_kind));
15088 spec.postconditions.push(cond(post_kind));
15089
15090 assert_eq!(
15091 spec.unique_missing_precondition_kind(),
15092 spec.preconditions.unique_missing_kind(),
15093 "EphemeralSpec::unique_missing_precondition_kind must delegate verbatim to \
15094 preconditions.unique_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
15095 );
15096 assert_eq!(
15097 spec.unique_missing_postcondition_kind(),
15098 spec.postconditions.unique_missing_kind(),
15099 "EphemeralSpec::unique_missing_postcondition_kind must delegate verbatim to \
15100 postconditions.unique_missing_kind() for pre={pre_kind:?} post={post_kind:?}",
15101 );
15102
15103 let missing: Vec<ConditionKind> = ConditionKind::ALL
15104 .into_iter()
15105 .filter(|k| pre_kind != *k && post_kind != *k)
15106 .collect();
15107 let expected_union = if missing.len() == 1 {
15108 Some(missing[0])
15109 } else {
15110 None
15111 };
15112 assert_eq!(
15113 spec.unique_missing_condition_kind(),
15114 expected_union,
15115 "EphemeralSpec::unique_missing_condition_kind must equal Some(k) iff the \
15116 ALL-entries NOT covered by either half-slice sum to exactly one for \
15117 pre={pre_kind:?} post={post_kind:?}",
15118 );
15119
15120 // Boolean-witness composition laws.
15121 assert_eq!(
15122 spec.unique_missing_condition_kind().is_some(),
15123 spec.has_unique_missing_condition_kind(),
15124 "unique_missing_condition_kind().is_some() must equal \
15125 has_unique_missing_condition_kind() for pre={pre_kind:?} post={post_kind:?}",
15126 );
15127
15128 // Two-surface parity.
15129 let lowered: ProcessSpec = spec.clone().into();
15130 assert_eq!(
15131 spec.unique_missing_precondition_kind(),
15132 lowered.boundary.unique_missing_precondition_kind(),
15133 "two-surface unique_missing_precondition_kind parity drift for \
15134 pre={pre_kind:?} post={post_kind:?}",
15135 );
15136 assert_eq!(
15137 spec.unique_missing_postcondition_kind(),
15138 lowered.boundary.unique_missing_postcondition_kind(),
15139 "two-surface unique_missing_postcondition_kind parity drift for \
15140 pre={pre_kind:?} post={post_kind:?}",
15141 );
15142 assert_eq!(
15143 spec.unique_missing_condition_kind(),
15144 lowered.boundary.unique_missing_condition_kind(),
15145 "two-surface unique_missing_condition_kind parity drift for \
15146 pre={pre_kind:?} post={post_kind:?}",
15147 );
15148 }
15149 }
15150
15151 // Saturated ephemeral — every arm returns None (zero missing).
15152 let mut spec = empty_ephemeral();
15153 for k in ConditionKind::ALL {
15154 spec.preconditions.push(cond(k));
15155 spec.postconditions.push(cond(k));
15156 }
15157 assert_eq!(
15158 spec.unique_missing_precondition_kind(),
15159 None,
15160 "saturated ephemeral must return None on unique_missing_precondition_kind",
15161 );
15162 assert_eq!(
15163 spec.unique_missing_postcondition_kind(),
15164 None,
15165 "saturated ephemeral must return None on unique_missing_postcondition_kind",
15166 );
15167 assert_eq!(
15168 spec.unique_missing_condition_kind(),
15169 None,
15170 "saturated ephemeral must return None on unique_missing_condition_kind",
15171 );
15172
15173 // Near-saturation arm: exactly one ALL entry missing on each
15174 // side (populate every kind except `hole`).
15175 for hole in ConditionKind::ALL {
15176 let mut spec = empty_ephemeral();
15177 for k in ConditionKind::ALL {
15178 if k != hole {
15179 spec.preconditions.push(cond(k));
15180 spec.postconditions.push(cond(k));
15181 }
15182 }
15183 assert_eq!(
15184 spec.unique_missing_precondition_kind(),
15185 Some(hole),
15186 "near-saturation ephemeral must return Some(hole={hole:?}) on unique_missing_precondition_kind",
15187 );
15188 assert_eq!(
15189 spec.unique_missing_postcondition_kind(),
15190 Some(hole),
15191 "near-saturation ephemeral must return Some(hole={hole:?}) on unique_missing_postcondition_kind",
15192 );
15193 assert_eq!(
15194 spec.unique_missing_condition_kind(),
15195 Some(hole),
15196 "near-saturation ephemeral must return Some(hole={hole:?}) on unique_missing_condition_kind",
15197 );
15198 }
15199 }
15200
15201 /// SUBSTRATE-DELEGATION pin (EphemeralSpec per-kind cardinality
15202 /// "≥ 2" many-arm triad on the count axis) — the three
15203 /// `has_multiple_of_*_condition_kind` methods on
15204 /// [`EphemeralSpec`] delegate to the slice-level substrate
15205 /// primitive
15206 /// [`crate::boundary::ConditionSliceExt::has_multiple_of_kind`]
15207 /// over the two `Vec<Condition>` slots and compose the union via
15208 /// a two-step-short-circuit walk over the chained per-kind
15209 /// iterator [`EphemeralSpec::iter_condition_kind`]. Sweeps: (a)
15210 /// the empty spec (every arm returns `false` on every kind); (b)
15211 /// a single-populated-per-side arrangement where each per-slice
15212 /// arm returns `false` but the union goes true iff pre and post
15213 /// carry the SAME kind; (c) the saturated-doubled spec (every
15214 /// arm returns `true` on every kind). Also verifies TWO-SURFACE
15215 /// PARITY — the ephemeral-side arm agrees with the lowered
15216 /// [`crate::boundary::Boundary`] arm through the same slice-
15217 /// level substrate primitive. A regression at either surface
15218 /// fails HERE rather than as silent drift between the two.
15219 #[test]
15220 fn has_multiple_of_condition_kind_triad_delegates_to_slice_has_multiple_of_kind() {
15221 // Empty ephemeral — every arm returns false on every kind.
15222 let spec = empty_ephemeral();
15223 for kind in ConditionKind::ALL {
15224 assert!(
15225 !spec.has_multiple_of_precondition_kind(kind),
15226 "empty ephemeral must return false on has_multiple_of_precondition_kind({kind:?})",
15227 );
15228 assert!(
15229 !spec.has_multiple_of_postcondition_kind(kind),
15230 "empty ephemeral must return false on has_multiple_of_postcondition_kind({kind:?})",
15231 );
15232 assert!(
15233 !spec.has_multiple_of_condition_kind(kind),
15234 "empty ephemeral must return false on has_multiple_of_condition_kind({kind:?})",
15235 );
15236 }
15237
15238 // Single-populated-per-side sweep — per-slice arms stay
15239 // false; union goes true iff pre and post carry the SAME
15240 // kind. Also verifies two-surface parity with Boundary.
15241 for pre_kind in ConditionKind::ALL {
15242 for post_kind in ConditionKind::ALL {
15243 let mut spec = empty_ephemeral();
15244 spec.preconditions.push(cond(pre_kind));
15245 spec.postconditions.push(cond(post_kind));
15246 let lowered: ProcessSpec = spec.clone().into();
15247
15248 for query in ConditionKind::ALL {
15249 assert_eq!(
15250 spec.has_multiple_of_precondition_kind(query),
15251 spec.preconditions.has_multiple_of_kind(query),
15252 "EphemeralSpec::has_multiple_of_precondition_kind must delegate \
15253 verbatim to preconditions.has_multiple_of_kind for \
15254 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15255 );
15256 assert_eq!(
15257 spec.has_multiple_of_postcondition_kind(query),
15258 spec.postconditions.has_multiple_of_kind(query),
15259 "EphemeralSpec::has_multiple_of_postcondition_kind must delegate \
15260 verbatim to postconditions.has_multiple_of_kind for \
15261 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15262 );
15263
15264 let expected_union = pre_kind == query && post_kind == query;
15265 assert_eq!(
15266 spec.has_multiple_of_condition_kind(query),
15267 expected_union,
15268 "EphemeralSpec::has_multiple_of_condition_kind({query:?}) must equal \
15269 (pre == query && post == query) for pre={pre_kind:?} post={post_kind:?}",
15270 );
15271
15272 // Two-surface parity with lowered Boundary.
15273 assert_eq!(
15274 spec.has_multiple_of_condition_kind(query),
15275 lowered.boundary.has_multiple_of_condition_kind(query),
15276 "two-surface has_multiple_of_condition_kind({query:?}) parity drift \
15277 for pre={pre_kind:?} post={post_kind:?}",
15278 );
15279 assert_eq!(
15280 spec.has_multiple_of_precondition_kind(query),
15281 lowered.boundary.has_multiple_of_precondition_kind(query),
15282 "two-surface has_multiple_of_precondition_kind({query:?}) parity drift",
15283 );
15284 assert_eq!(
15285 spec.has_multiple_of_postcondition_kind(query),
15286 lowered.boundary.has_multiple_of_postcondition_kind(query),
15287 "two-surface has_multiple_of_postcondition_kind({query:?}) parity drift",
15288 );
15289 }
15290 }
15291 }
15292
15293 // Saturated-doubled spec — every arm returns true on every
15294 // kind (every slice carries every kind twice).
15295 let mut spec = empty_ephemeral();
15296 for k in ConditionKind::ALL {
15297 spec.preconditions.push(cond(k));
15298 spec.preconditions.push(cond(k));
15299 spec.postconditions.push(cond(k));
15300 spec.postconditions.push(cond(k));
15301 }
15302 for kind in ConditionKind::ALL {
15303 assert!(
15304 spec.has_multiple_of_precondition_kind(kind),
15305 "saturated-doubled ephemeral must return true on has_multiple_of_precondition_kind({kind:?})",
15306 );
15307 assert!(
15308 spec.has_multiple_of_postcondition_kind(kind),
15309 "saturated-doubled ephemeral must return true on has_multiple_of_postcondition_kind({kind:?})",
15310 );
15311 assert!(
15312 spec.has_multiple_of_condition_kind(kind),
15313 "saturated-doubled ephemeral must return true on has_multiple_of_condition_kind({kind:?})",
15314 );
15315 }
15316 }
15317
15318 /// Every arm of the (precondition, postcondition, condition-union)
15319 /// per-kind cardinality "= 1" mid-endpoint triad on
15320 /// [`EphemeralSpec`] delegates verbatim to the slice-level
15321 /// substrate primitive
15322 /// [`crate::boundary::ConditionSliceExt::has_unique_of_kind`].
15323 /// Sweeps three arrangements: (a) an empty ephemeral (every arm
15324 /// returns `false` on every kind); (b) a single-populated-per-
15325 /// side sweep where per-slice arms fire iff their side's kind
15326 /// equals `query`, and the union arm fires iff EXACTLY ONE of
15327 /// `{pre, post}` equals `query` (chain sums to 1 on disjoint,
15328 /// 2 on shared); (c) the saturated-singleton spec (every kind
15329 /// appears exactly once on every slice — per-slice arms return
15330 /// `true` on every kind, union returns `false` on every kind
15331 /// as `= 2` chain matches). Also verifies TWO-SURFACE PARITY —
15332 /// the ephemeral-side arm agrees with the lowered
15333 /// [`crate::boundary::Boundary`] arm through the same slice-
15334 /// level substrate primitive.
15335 #[test]
15336 fn has_unique_of_condition_kind_triad_delegates_to_slice_has_unique_of_kind() {
15337 // Empty ephemeral — every arm returns false on every kind.
15338 let spec = empty_ephemeral();
15339 for kind in ConditionKind::ALL {
15340 assert!(
15341 !spec.has_unique_of_precondition_kind(kind),
15342 "empty ephemeral must return false on has_unique_of_precondition_kind({kind:?})",
15343 );
15344 assert!(
15345 !spec.has_unique_of_postcondition_kind(kind),
15346 "empty ephemeral must return false on has_unique_of_postcondition_kind({kind:?})",
15347 );
15348 assert!(
15349 !spec.has_unique_of_condition_kind(kind),
15350 "empty ephemeral must return false on has_unique_of_condition_kind({kind:?})",
15351 );
15352 }
15353
15354 // Single-populated-per-side sweep — per-slice arm fires iff
15355 // its side's kind equals `query`; union arm fires iff
15356 // EXACTLY ONE of {pre, post} equals `query`. Also verifies
15357 // two-surface parity with Boundary.
15358 for pre_kind in ConditionKind::ALL {
15359 for post_kind in ConditionKind::ALL {
15360 let mut spec = empty_ephemeral();
15361 spec.preconditions.push(cond(pre_kind));
15362 spec.postconditions.push(cond(post_kind));
15363 let lowered: ProcessSpec = spec.clone().into();
15364
15365 for query in ConditionKind::ALL {
15366 assert_eq!(
15367 spec.has_unique_of_precondition_kind(query),
15368 spec.preconditions.has_unique_of_kind(query),
15369 "EphemeralSpec::has_unique_of_precondition_kind must delegate \
15370 verbatim to preconditions.has_unique_of_kind for \
15371 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15372 );
15373 assert_eq!(
15374 spec.has_unique_of_postcondition_kind(query),
15375 spec.postconditions.has_unique_of_kind(query),
15376 "EphemeralSpec::has_unique_of_postcondition_kind must delegate \
15377 verbatim to postconditions.has_unique_of_kind for \
15378 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15379 );
15380
15381 let expected_union = (pre_kind == query) ^ (post_kind == query);
15382 assert_eq!(
15383 spec.has_unique_of_condition_kind(query),
15384 expected_union,
15385 "EphemeralSpec::has_unique_of_condition_kind({query:?}) must equal \
15386 ((pre == query) XOR (post == query)) for \
15387 pre={pre_kind:?} post={post_kind:?}",
15388 );
15389
15390 // Two-surface parity with lowered Boundary.
15391 assert_eq!(
15392 spec.has_unique_of_condition_kind(query),
15393 lowered.boundary.has_unique_of_condition_kind(query),
15394 "two-surface has_unique_of_condition_kind({query:?}) parity drift \
15395 for pre={pre_kind:?} post={post_kind:?}",
15396 );
15397 assert_eq!(
15398 spec.has_unique_of_precondition_kind(query),
15399 lowered.boundary.has_unique_of_precondition_kind(query),
15400 "two-surface has_unique_of_precondition_kind({query:?}) parity drift",
15401 );
15402 assert_eq!(
15403 spec.has_unique_of_postcondition_kind(query),
15404 lowered.boundary.has_unique_of_postcondition_kind(query),
15405 "two-surface has_unique_of_postcondition_kind({query:?}) parity drift",
15406 );
15407 }
15408 }
15409 }
15410
15411 // Saturated-singleton spec — every kind appears exactly once
15412 // on every slice; per-slice arms return true on every kind,
15413 // union returns false on every kind (= 2 chain matches).
15414 let mut spec = empty_ephemeral();
15415 for k in ConditionKind::ALL {
15416 spec.preconditions.push(cond(k));
15417 spec.postconditions.push(cond(k));
15418 }
15419 for kind in ConditionKind::ALL {
15420 assert!(
15421 spec.has_unique_of_precondition_kind(kind),
15422 "saturated-singleton ephemeral must return true on has_unique_of_precondition_kind({kind:?})",
15423 );
15424 assert!(
15425 spec.has_unique_of_postcondition_kind(kind),
15426 "saturated-singleton ephemeral must return true on has_unique_of_postcondition_kind({kind:?})",
15427 );
15428 assert!(
15429 !spec.has_unique_of_condition_kind(kind),
15430 "saturated-singleton ephemeral must return false on union has_unique_of_condition_kind({kind:?}) (2 chain matches)",
15431 );
15432 }
15433 }
15434
15435 // ── EphemeralSpec::has_at_most_one_of_(pre|post|)condition_kind ─
15436 //
15437 // Two-surface parity contract with
15438 // `Boundary::has_at_most_one_of_condition_kind` on the "≤ 1"
15439 // per-kind negation arm. Ephemeral composes against the SAME
15440 // slice-level substrate primitive
15441 // `ConditionSliceExt::has_at_most_one_of_kind` via delegation on
15442 // each side and via the definitional negation of
15443 // `has_multiple_of_condition_kind` on the union chain. Regression
15444 // at either the per-slice negation walk or the ephemeral→boundary
15445 // lowering fails here.
15446
15447 /// EphemeralSpec triad delegation + two-surface parity pin —
15448 /// sweeps every kind on every reachable arrangement of a single
15449 /// condition-per-side spec, asserts each per-slice arm delegates
15450 /// verbatim to the slice-level primitive, and asserts the union
15451 /// arm agrees with the lowered [`ProcessSpec`]'s
15452 /// [`Boundary::has_at_most_one_of_condition_kind`] on every
15453 /// arm. Also pins the trichotomy-union arm equivalence
15454 /// `has_at_most_one_of_condition_kind == lacks_condition_kind ||
15455 /// has_unique_of_condition_kind` and the tetrachotomy partition
15456 /// (`{≤ 1, ≥ 2}` exactly one arm on every arrangement).
15457 #[test]
15458 fn has_at_most_one_of_condition_kind_triad_delegates_to_slice_has_at_most_one_of_kind() {
15459 // Empty ephemeral — every arm returns true on every kind
15460 // (0 matches, `≤ 1`).
15461 let spec = empty_ephemeral();
15462 for kind in ConditionKind::ALL {
15463 assert!(
15464 spec.has_at_most_one_of_precondition_kind(kind),
15465 "empty ephemeral must return true on has_at_most_one_of_precondition_kind({kind:?})",
15466 );
15467 assert!(
15468 spec.has_at_most_one_of_postcondition_kind(kind),
15469 "empty ephemeral must return true on has_at_most_one_of_postcondition_kind({kind:?})",
15470 );
15471 assert!(
15472 spec.has_at_most_one_of_condition_kind(kind),
15473 "empty ephemeral must return true on has_at_most_one_of_condition_kind({kind:?})",
15474 );
15475 }
15476
15477 // Single-populated-per-side sweep — per-slice arms always
15478 // fire; union arm fires iff at most one of `{pre, post}`
15479 // equals `query` (`!(pre_hit && post_hit)`). Also verifies
15480 // two-surface parity with Boundary on every arm.
15481 for pre_kind in ConditionKind::ALL {
15482 for post_kind in ConditionKind::ALL {
15483 let mut spec = empty_ephemeral();
15484 spec.preconditions.push(cond(pre_kind));
15485 spec.postconditions.push(cond(post_kind));
15486 let lowered: ProcessSpec = spec.clone().into();
15487
15488 for query in ConditionKind::ALL {
15489 assert_eq!(
15490 spec.has_at_most_one_of_precondition_kind(query),
15491 spec.preconditions.has_at_most_one_of_kind(query),
15492 "EphemeralSpec::has_at_most_one_of_precondition_kind must delegate \
15493 verbatim to preconditions.has_at_most_one_of_kind for \
15494 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15495 );
15496 assert_eq!(
15497 spec.has_at_most_one_of_postcondition_kind(query),
15498 spec.postconditions.has_at_most_one_of_kind(query),
15499 "EphemeralSpec::has_at_most_one_of_postcondition_kind must delegate \
15500 verbatim to postconditions.has_at_most_one_of_kind for \
15501 pre={pre_kind:?} post={post_kind:?} query={query:?}",
15502 );
15503
15504 let pre_hit = pre_kind == query;
15505 let post_hit = post_kind == query;
15506 let expected_union = !(pre_hit && post_hit);
15507 assert_eq!(
15508 spec.has_at_most_one_of_condition_kind(query),
15509 expected_union,
15510 "EphemeralSpec::has_at_most_one_of_condition_kind({query:?}) must equal \
15511 !(pre_hit && post_hit) for pre={pre_kind:?} post={post_kind:?}",
15512 );
15513
15514 // Definitional negation of the many-arm peer.
15515 assert_eq!(
15516 spec.has_at_most_one_of_condition_kind(query),
15517 !spec.has_multiple_of_condition_kind(query),
15518 "EphemeralSpec::has_at_most_one_of_condition_kind({query:?}) drifted \
15519 from !has_multiple_of_condition_kind for pre={pre_kind:?} \
15520 post={post_kind:?}",
15521 );
15522
15523 // Trichotomy-union arm: {= 0} ∪ {= 1} == {≤ 1}.
15524 assert_eq!(
15525 spec.has_at_most_one_of_condition_kind(query),
15526 spec.lacks_condition_kind(query)
15527 || spec.has_unique_of_condition_kind(query),
15528 "EphemeralSpec::has_at_most_one_of_condition_kind({query:?}) drifted \
15529 from (lacks || has_unique) trichotomy-union for pre={pre_kind:?} \
15530 post={post_kind:?}",
15531 );
15532
15533 // Two-surface parity with lowered Boundary.
15534 assert_eq!(
15535 spec.has_at_most_one_of_condition_kind(query),
15536 lowered.boundary.has_at_most_one_of_condition_kind(query),
15537 "two-surface has_at_most_one_of_condition_kind({query:?}) parity drift \
15538 for pre={pre_kind:?} post={post_kind:?}",
15539 );
15540 assert_eq!(
15541 spec.has_at_most_one_of_precondition_kind(query),
15542 lowered.boundary.has_at_most_one_of_precondition_kind(query),
15543 "two-surface has_at_most_one_of_precondition_kind({query:?}) parity \
15544 drift for pre={pre_kind:?} post={post_kind:?}",
15545 );
15546 assert_eq!(
15547 spec.has_at_most_one_of_postcondition_kind(query),
15548 lowered
15549 .boundary
15550 .has_at_most_one_of_postcondition_kind(query),
15551 "two-surface has_at_most_one_of_postcondition_kind({query:?}) parity \
15552 drift for pre={pre_kind:?} post={post_kind:?}",
15553 );
15554
15555 // {≤ 1, ≥ 2} Boolean-negation partition at the
15556 // union level — EXACTLY ONE arm fires.
15557 let at_most_one = spec.has_at_most_one_of_condition_kind(query);
15558 let multiple = spec.has_multiple_of_condition_kind(query);
15559 assert_ne!(
15560 at_most_one, multiple,
15561 "union {{≤ 1, ≥ 2}} Boolean-negation partition for query={query:?} \
15562 (pre={pre_kind:?} post={post_kind:?}) must fire EXACTLY one arm",
15563 );
15564 }
15565 }
15566 }
15567
15568 // Saturated-singleton spec — every kind appears exactly once
15569 // on every slice. Per-slice arms return true on every kind;
15570 // union returns false on every kind (2 chain matches, not ≤ 1).
15571 let mut spec = empty_ephemeral();
15572 for k in ConditionKind::ALL {
15573 spec.preconditions.push(cond(k));
15574 spec.postconditions.push(cond(k));
15575 }
15576 for kind in ConditionKind::ALL {
15577 assert!(
15578 spec.has_at_most_one_of_precondition_kind(kind),
15579 "saturated-singleton ephemeral must return true on has_at_most_one_of_precondition_kind({kind:?})",
15580 );
15581 assert!(
15582 spec.has_at_most_one_of_postcondition_kind(kind),
15583 "saturated-singleton ephemeral must return true on has_at_most_one_of_postcondition_kind({kind:?})",
15584 );
15585 assert!(
15586 !spec.has_at_most_one_of_condition_kind(kind),
15587 "saturated-singleton ephemeral must return false on union has_at_most_one_of_condition_kind({kind:?}) (2 chain matches)",
15588 );
15589 }
15590 }
15591
15592 // ── EphemeralSpec::unique_of_(pre|post|)condition_kind triad ────
15593 //
15594 // Two-surface parity contract with
15595 // `Boundary::unique_of_condition_kind` on the per-kind `= 1`
15596 // `Option<&Condition>` witnessing arm. Both surfaces compose
15597 // against the SAME slice-level substrate primitive
15598 // `ConditionSliceExt::unique_of_kind` via delegation on each side
15599 // and via a two-step short-circuit walk over
15600 // `iter_condition_kind` on the union chain.
15601
15602 /// Ephemeral triad delegation + two-surface parity pin — sweeps
15603 /// every kind on every reachable `(pre_kind, post_kind, query)`
15604 /// arrangement of a single-condition-per-side spec, asserts each
15605 /// per-slice arm delegates verbatim to the slice-level primitive,
15606 /// asserts the union arm equals the chained two-step short-
15607 /// circuit walk, and asserts the ephemeral-side arm agrees with
15608 /// the lowered [`Boundary`] arm through the same slice-level
15609 /// substrate primitive.
15610 #[test]
15611 fn unique_of_condition_kind_triad_delegates_to_slice_unique_of_kind() {
15612 use crate::boundary::ConditionSliceExt as _;
15613
15614 // Empty ephemeral — every arm returns None on every kind.
15615 let spec = empty_ephemeral();
15616 for kind in ConditionKind::ALL {
15617 assert!(
15618 spec.unique_of_precondition_kind(kind).is_none(),
15619 "empty ephemeral must return None on unique_of_precondition_kind({kind:?})",
15620 );
15621 assert!(
15622 spec.unique_of_postcondition_kind(kind).is_none(),
15623 "empty ephemeral must return None on unique_of_postcondition_kind({kind:?})",
15624 );
15625 assert!(
15626 spec.unique_of_condition_kind(kind).is_none(),
15627 "empty ephemeral must return None on unique_of_condition_kind({kind:?})",
15628 );
15629 }
15630
15631 // Single-populated-per-side sweep with two-surface parity.
15632 for pre_kind in ConditionKind::ALL {
15633 for post_kind in ConditionKind::ALL {
15634 let mut spec = empty_ephemeral();
15635 spec.preconditions.push(cond(pre_kind));
15636 spec.postconditions.push(cond(post_kind));
15637
15638 let lowered: ProcessSpec = spec.clone().into();
15639 let boundary = &lowered.boundary;
15640
15641 for query in ConditionKind::ALL {
15642 // Per-side delegation pins.
15643 assert_eq!(
15644 spec.unique_of_precondition_kind(query)
15645 .map(|c| c as *const Condition),
15646 spec.preconditions
15647 .unique_of_kind(query)
15648 .map(|c| c as *const Condition),
15649 "EphemeralSpec::unique_of_precondition_kind must delegate verbatim to \
15650 preconditions.unique_of_kind for pre={pre_kind:?} post={post_kind:?} \
15651 query={query:?}",
15652 );
15653 assert_eq!(
15654 spec.unique_of_postcondition_kind(query)
15655 .map(|c| c as *const Condition),
15656 spec.postconditions
15657 .unique_of_kind(query)
15658 .map(|c| c as *const Condition),
15659 "EphemeralSpec::unique_of_postcondition_kind must delegate verbatim to \
15660 postconditions.unique_of_kind for pre={pre_kind:?} post={post_kind:?} \
15661 query={query:?}",
15662 );
15663
15664 // Boolean-projection composition-law pin.
15665 assert_eq!(
15666 spec.unique_of_condition_kind(query).is_some(),
15667 spec.has_unique_of_condition_kind(query),
15668 "EphemeralSpec::unique_of_condition_kind({query:?}).is_some() drifted \
15669 from has_unique_of_condition_kind for pre={pre_kind:?} \
15670 post={post_kind:?}",
15671 );
15672 assert_eq!(
15673 spec.unique_of_condition_kind(query).map(|c| c.kind),
15674 if spec.has_unique_of_condition_kind(query) {
15675 Some(query)
15676 } else {
15677 None
15678 },
15679 "EphemeralSpec::unique_of_condition_kind({query:?}).map(kind) must yield \
15680 Some({query:?}) iff has_unique_of_condition_kind for pre={pre_kind:?} \
15681 post={post_kind:?}",
15682 );
15683
15684 // Union arm shape — XOR of side-hits.
15685 let pre_hit = pre_kind == query;
15686 let post_hit = post_kind == query;
15687 assert_eq!(
15688 spec.unique_of_condition_kind(query).is_some(),
15689 pre_hit ^ post_hit,
15690 "EphemeralSpec::unique_of_condition_kind({query:?}).is_some() must equal \
15691 (pre_hit XOR post_hit) for pre={pre_kind:?} post={post_kind:?}",
15692 );
15693
15694 // Two-surface parity — the lowered Boundary's
15695 // triad yields the SAME Option<kind> shape on
15696 // every arm. Pointer identities differ (the
15697 // lowered Boundary carries cloned Conditions),
15698 // so parity holds at the kind projection.
15699 assert_eq!(
15700 spec.unique_of_precondition_kind(query).map(|c| c.kind),
15701 boundary.unique_of_precondition_kind(query).map(|c| c.kind),
15702 "ephemeral unique_of_precondition_kind({query:?}) kind drifted from \
15703 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15704 );
15705 assert_eq!(
15706 spec.unique_of_postcondition_kind(query).map(|c| c.kind),
15707 boundary.unique_of_postcondition_kind(query).map(|c| c.kind),
15708 "ephemeral unique_of_postcondition_kind({query:?}) kind drifted from \
15709 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15710 );
15711 assert_eq!(
15712 spec.unique_of_condition_kind(query).map(|c| c.kind),
15713 boundary.unique_of_condition_kind(query).map(|c| c.kind),
15714 "ephemeral unique_of_condition_kind({query:?}) kind drifted from \
15715 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15716 );
15717 }
15718 }
15719 }
15720
15721 // Doubled-post sweep — union collapses to None on the
15722 // doubled kind (`≥ 2` chain matches).
15723 for doubled in ConditionKind::ALL {
15724 let mut spec = empty_ephemeral();
15725 spec.postconditions.push(cond(doubled));
15726 spec.postconditions.push(cond(doubled));
15727 assert!(
15728 spec.unique_of_postcondition_kind(doubled).is_none(),
15729 "doubled postconditions must collapse unique_of_postcondition_kind({doubled:?}) \
15730 to None",
15731 );
15732 assert!(
15733 spec.unique_of_condition_kind(doubled).is_none(),
15734 "doubled postconditions must collapse union unique_of_condition_kind({doubled:?}) \
15735 to None",
15736 );
15737 }
15738 }
15739
15740 // ── EphemeralSpec::last_(pre|post|)condition_kind triad ────────
15741 //
15742 // Two-surface parity contract with `Boundary::last_condition_kind`
15743 // on the per-kind latest-position `Option<&Condition>` witnessing
15744 // arm. Both surfaces compose against the SAME slice-level
15745 // substrate primitive `ConditionSliceExt::last_of_kind` via
15746 // delegation on each side and via
15747 // `iter_condition_kind(k).last()` on the union chain.
15748
15749 /// Ephemeral triad delegation + two-surface parity pin — sweeps
15750 /// every kind on every reachable `(pre_kind, post_kind, query)`
15751 /// arrangement of a single-condition-per-side spec, asserts each
15752 /// per-slice arm delegates verbatim to the slice-level primitive,
15753 /// asserts the union arm equals the chained `iter_condition_kind
15754 /// (k).last()` walk (post-side wins on dual hits), and asserts the
15755 /// ephemeral-side arm agrees with the lowered [`Boundary`] arm
15756 /// through the same slice-level substrate primitive.
15757 #[test]
15758 fn last_condition_kind_triad_delegates_to_slice_last_of_kind() {
15759 use crate::boundary::ConditionSliceExt as _;
15760
15761 // Empty ephemeral — every arm returns None on every kind.
15762 let spec = empty_ephemeral();
15763 for kind in ConditionKind::ALL {
15764 assert!(
15765 spec.last_precondition_kind(kind).is_none(),
15766 "empty ephemeral must return None on last_precondition_kind({kind:?})",
15767 );
15768 assert!(
15769 spec.last_postcondition_kind(kind).is_none(),
15770 "empty ephemeral must return None on last_postcondition_kind({kind:?})",
15771 );
15772 assert!(
15773 spec.last_condition_kind(kind).is_none(),
15774 "empty ephemeral must return None on last_condition_kind({kind:?})",
15775 );
15776 }
15777
15778 // Single-populated-per-side sweep with two-surface parity.
15779 for pre_kind in ConditionKind::ALL {
15780 for post_kind in ConditionKind::ALL {
15781 let mut spec = empty_ephemeral();
15782 spec.preconditions.push(cond(pre_kind));
15783 spec.postconditions.push(cond(post_kind));
15784
15785 let lowered: ProcessSpec = spec.clone().into();
15786 let boundary = &lowered.boundary;
15787
15788 for query in ConditionKind::ALL {
15789 // Per-side delegation pins.
15790 assert_eq!(
15791 spec.last_precondition_kind(query)
15792 .map(|c| c as *const Condition),
15793 spec.preconditions
15794 .last_of_kind(query)
15795 .map(|c| c as *const Condition),
15796 "EphemeralSpec::last_precondition_kind must delegate verbatim to \
15797 preconditions.last_of_kind for pre={pre_kind:?} post={post_kind:?} \
15798 query={query:?}",
15799 );
15800 assert_eq!(
15801 spec.last_postcondition_kind(query)
15802 .map(|c| c as *const Condition),
15803 spec.postconditions
15804 .last_of_kind(query)
15805 .map(|c| c as *const Condition),
15806 "EphemeralSpec::last_postcondition_kind must delegate verbatim to \
15807 postconditions.last_of_kind for pre={pre_kind:?} post={post_kind:?} \
15808 query={query:?}",
15809 );
15810
15811 // Boolean-projection composition-law pin.
15812 assert_eq!(
15813 spec.last_condition_kind(query).is_some(),
15814 spec.has_condition_kind(query),
15815 "EphemeralSpec::last_condition_kind({query:?}).is_some() drifted from \
15816 has_condition_kind for pre={pre_kind:?} post={post_kind:?}",
15817 );
15818 assert_eq!(
15819 spec.last_condition_kind(query).map(|c| c.kind),
15820 if spec.has_condition_kind(query) {
15821 Some(query)
15822 } else {
15823 None
15824 },
15825 "EphemeralSpec::last_condition_kind({query:?}).map(kind) must yield \
15826 Some({query:?}) iff has_condition_kind for pre={pre_kind:?} \
15827 post={post_kind:?}",
15828 );
15829
15830 // Endpoint-swap composition law: post-side wins.
15831 assert_eq!(
15832 spec.last_condition_kind(query)
15833 .map(|c| c as *const Condition),
15834 spec.last_postcondition_kind(query)
15835 .or_else(|| spec.last_precondition_kind(query))
15836 .map(|c| c as *const Condition),
15837 "EphemeralSpec::last_condition_kind drifted from postcondition-first \
15838 `or_else(precondition-side)` composition for pre={pre_kind:?} \
15839 post={post_kind:?} query={query:?}",
15840 );
15841
15842 // Union-arm shape — post wins when both hit.
15843 let pre_hit = pre_kind == query;
15844 let post_hit = post_kind == query;
15845 let last = spec.last_condition_kind(query);
15846 assert_eq!(
15847 last.is_some(),
15848 pre_hit || post_hit,
15849 "EphemeralSpec::last_condition_kind({query:?}).is_some() must equal \
15850 (pre_hit OR post_hit) for pre={pre_kind:?} post={post_kind:?}",
15851 );
15852 if post_hit {
15853 assert!(
15854 std::ptr::eq(last.unwrap(), &spec.postconditions[0]),
15855 "last_condition_kind must point at postconditions slot when post \
15856 hits for pre={pre_kind:?} post={post_kind:?} query={query:?}",
15857 );
15858 } else if pre_hit {
15859 assert!(
15860 std::ptr::eq(last.unwrap(), &spec.preconditions[0]),
15861 "last_condition_kind must point at preconditions slot when only pre \
15862 hits for pre={pre_kind:?} post={post_kind:?} query={query:?}",
15863 );
15864 }
15865
15866 // Two-surface parity — the lowered Boundary's
15867 // triad yields the SAME Option<kind> shape on
15868 // every arm.
15869 assert_eq!(
15870 spec.last_precondition_kind(query).map(|c| c.kind),
15871 boundary.last_precondition_kind(query).map(|c| c.kind),
15872 "ephemeral last_precondition_kind({query:?}) kind drifted from \
15873 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15874 );
15875 assert_eq!(
15876 spec.last_postcondition_kind(query).map(|c| c.kind),
15877 boundary.last_postcondition_kind(query).map(|c| c.kind),
15878 "ephemeral last_postcondition_kind({query:?}) kind drifted from \
15879 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15880 );
15881 assert_eq!(
15882 spec.last_condition_kind(query).map(|c| c.kind),
15883 boundary.last_condition_kind(query).map(|c| c.kind),
15884 "ephemeral last_condition_kind({query:?}) kind drifted from \
15885 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
15886 );
15887 }
15888 }
15889 }
15890
15891 // Doubled-post sweep — union yields the LATER post slot,
15892 // distinct from the earlier one.
15893 for doubled in ConditionKind::ALL {
15894 let mut spec = empty_ephemeral();
15895 spec.postconditions.push(cond(doubled));
15896 spec.postconditions.push(cond(doubled));
15897 let last_post = spec.last_postcondition_kind(doubled);
15898 let last_union = spec.last_condition_kind(doubled);
15899 assert!(
15900 std::ptr::eq(last_post.unwrap(), &spec.postconditions[1]),
15901 "doubled-post last_postcondition_kind({doubled:?}) must point at slot[1]",
15902 );
15903 assert!(
15904 std::ptr::eq(last_union.unwrap(), &spec.postconditions[1]),
15905 "doubled-post last_condition_kind({doubled:?}) must point at slot[1]",
15906 );
15907 }
15908 }
15909
15910 // ── EphemeralSpec::all_of_(pre|post|)condition_kind triad ─────
15911 //
15912 // Two-surface parity contract with `Boundary::all_of_condition_kind`
15913 // on the per-kind materialized `Vec<&Condition>`-witnessing arm.
15914 // Both surfaces compose against the SAME slice-level substrate
15915 // primitive `ConditionSliceExt::all_of_kind` via delegation on
15916 // each side and via `iter_condition_kind(k).collect()` on the
15917 // union chain. Closes the (iter, Vec, scalar) triad on the
15918 // per-kind axis at the ephemeral surface.
15919
15920 /// Ephemeral triad delegation + two-surface parity pin for
15921 /// `all_of_(pre|post|)condition_kind`. Sweeps every kind on every
15922 /// reachable `(pre_kind, post_kind, query)` arrangement of a
15923 /// single-condition-per-side spec, asserts each per-slice arm
15924 /// delegates verbatim to the slice-level primitive, asserts the
15925 /// union arm equals the chained `iter_condition_kind(k).collect()`
15926 /// walk (pre-then-post order), and asserts the ephemeral-side arm
15927 /// agrees with the lowered [`Boundary`] arm on the projected kind
15928 /// sequence. Vec composition laws pinned: `.len() == count`,
15929 /// `.is_empty() == !has`, `.first() == find`, `.last() == last_of`.
15930 #[test]
15931 fn all_of_condition_kind_triad_delegates_to_slice_all_of_kind() {
15932 use crate::boundary::ConditionSliceExt as _;
15933
15934 // Empty ephemeral — every arm returns an empty vec on every kind.
15935 let spec = empty_ephemeral();
15936 for kind in ConditionKind::ALL {
15937 assert!(
15938 spec.all_of_precondition_kind(kind).is_empty(),
15939 "empty ephemeral all_of_precondition_kind({kind:?}) must be empty",
15940 );
15941 assert!(
15942 spec.all_of_postcondition_kind(kind).is_empty(),
15943 "empty ephemeral all_of_postcondition_kind({kind:?}) must be empty",
15944 );
15945 assert!(
15946 spec.all_of_condition_kind(kind).is_empty(),
15947 "empty ephemeral all_of_condition_kind({kind:?}) must be empty",
15948 );
15949 }
15950
15951 // Single-populated-per-side sweep with two-surface parity.
15952 for pre_kind in ConditionKind::ALL {
15953 for post_kind in ConditionKind::ALL {
15954 let mut spec = empty_ephemeral();
15955 spec.preconditions.push(cond(pre_kind));
15956 spec.postconditions.push(cond(post_kind));
15957
15958 let lowered: ProcessSpec = spec.clone().into();
15959 let boundary = &lowered.boundary;
15960
15961 for query in ConditionKind::ALL {
15962 // Per-side delegation pins — pointer identity of
15963 // every &Condition entry.
15964 let via_arm_pre: Vec<*const Condition> = spec
15965 .all_of_precondition_kind(query)
15966 .into_iter()
15967 .map(|c| c as *const Condition)
15968 .collect();
15969 let via_slice_pre: Vec<*const Condition> = spec
15970 .preconditions
15971 .all_of_kind(query)
15972 .into_iter()
15973 .map(|c| c as *const Condition)
15974 .collect();
15975 assert_eq!(
15976 via_arm_pre, via_slice_pre,
15977 "EphemeralSpec::all_of_precondition_kind must delegate verbatim to \
15978 preconditions.all_of_kind for pre={pre_kind:?} post={post_kind:?} \
15979 query={query:?}",
15980 );
15981 let via_arm_post: Vec<*const Condition> = spec
15982 .all_of_postcondition_kind(query)
15983 .into_iter()
15984 .map(|c| c as *const Condition)
15985 .collect();
15986 let via_slice_post: Vec<*const Condition> = spec
15987 .postconditions
15988 .all_of_kind(query)
15989 .into_iter()
15990 .map(|c| c as *const Condition)
15991 .collect();
15992 assert_eq!(
15993 via_arm_post, via_slice_post,
15994 "EphemeralSpec::all_of_postcondition_kind must delegate verbatim to \
15995 postconditions.all_of_kind for pre={pre_kind:?} post={post_kind:?} \
15996 query={query:?}",
15997 );
15998
15999 // Union-arm composition-law pins.
16000 let union = spec.all_of_condition_kind(query);
16001 assert_eq!(
16002 union.len(),
16003 spec.count_condition_kind(query),
16004 "all_of_condition_kind({query:?}).len() drifted from count for \
16005 pre={pre_kind:?} post={post_kind:?}",
16006 );
16007 assert_eq!(
16008 union.is_empty(),
16009 !spec.has_condition_kind(query),
16010 "all_of_condition_kind({query:?}).is_empty() drifted from \
16011 !has for pre={pre_kind:?} post={post_kind:?}",
16012 );
16013 assert_eq!(
16014 union.first().copied().map(|c| c as *const Condition),
16015 spec.find_condition_kind(query)
16016 .map(|c| c as *const Condition),
16017 "all_of_condition_kind({query:?}).first() drifted from find for \
16018 pre={pre_kind:?} post={post_kind:?}",
16019 );
16020 assert_eq!(
16021 union.last().copied().map(|c| c as *const Condition),
16022 spec.last_condition_kind(query)
16023 .map(|c| c as *const Condition),
16024 "all_of_condition_kind({query:?}).last() drifted from last for \
16025 pre={pre_kind:?} post={post_kind:?}",
16026 );
16027
16028 // Iter/Vec parity on the ephemeral surface.
16029 let via_iter: Vec<*const Condition> = spec
16030 .iter_condition_kind(query)
16031 .map(|c| c as *const Condition)
16032 .collect();
16033 let via_all: Vec<*const Condition> = spec
16034 .all_of_condition_kind(query)
16035 .into_iter()
16036 .map(|c| c as *const Condition)
16037 .collect();
16038 assert_eq!(
16039 via_iter, via_all,
16040 "EphemeralSpec::all_of_condition_kind({query:?}) must match \
16041 iter_condition_kind(k).collect() for pre={pre_kind:?} post={post_kind:?}",
16042 );
16043
16044 // Two-surface parity — the lowered Boundary's
16045 // triad yields the SAME kind sequence on every arm.
16046 let ephemeral_pre_kinds: Vec<_> = spec
16047 .all_of_precondition_kind(query)
16048 .into_iter()
16049 .map(|c| c.kind)
16050 .collect();
16051 let boundary_pre_kinds: Vec<_> = boundary
16052 .all_of_precondition_kind(query)
16053 .into_iter()
16054 .map(|c| c.kind)
16055 .collect();
16056 assert_eq!(
16057 ephemeral_pre_kinds, boundary_pre_kinds,
16058 "ephemeral all_of_precondition_kind({query:?}) kinds drifted from \
16059 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
16060 );
16061 let ephemeral_post_kinds: Vec<_> = spec
16062 .all_of_postcondition_kind(query)
16063 .into_iter()
16064 .map(|c| c.kind)
16065 .collect();
16066 let boundary_post_kinds: Vec<_> = boundary
16067 .all_of_postcondition_kind(query)
16068 .into_iter()
16069 .map(|c| c.kind)
16070 .collect();
16071 assert_eq!(
16072 ephemeral_post_kinds, boundary_post_kinds,
16073 "ephemeral all_of_postcondition_kind({query:?}) kinds drifted from \
16074 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
16075 );
16076 let ephemeral_union_kinds: Vec<_> = spec
16077 .all_of_condition_kind(query)
16078 .into_iter()
16079 .map(|c| c.kind)
16080 .collect();
16081 let boundary_union_kinds: Vec<_> = boundary
16082 .all_of_condition_kind(query)
16083 .into_iter()
16084 .map(|c| c.kind)
16085 .collect();
16086 assert_eq!(
16087 ephemeral_union_kinds, boundary_union_kinds,
16088 "ephemeral all_of_condition_kind({query:?}) kinds drifted from \
16089 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
16090 );
16091 }
16092 }
16093 }
16094
16095 // Doubled-post sweep — union yields BOTH post slots in walk order.
16096 for doubled in ConditionKind::ALL {
16097 let mut spec = empty_ephemeral();
16098 spec.postconditions.push(cond(doubled));
16099 spec.postconditions.push(cond(doubled));
16100 let all_post = spec.all_of_postcondition_kind(doubled);
16101 let all_union = spec.all_of_condition_kind(doubled);
16102 assert_eq!(all_post.len(), 2);
16103 assert_eq!(all_union.len(), 2);
16104 assert!(
16105 std::ptr::eq(all_post[0], &spec.postconditions[0])
16106 && std::ptr::eq(all_post[1], &spec.postconditions[1]),
16107 "doubled-post all_of_postcondition_kind({doubled:?}) must walk in slice order",
16108 );
16109 assert!(
16110 std::ptr::eq(all_union[0], &spec.postconditions[0])
16111 && std::ptr::eq(all_union[1], &spec.postconditions[1]),
16112 "doubled-post all_of_condition_kind({doubled:?}) must walk in slice order",
16113 );
16114 }
16115 }
16116
16117 /// Ephemeral surface's index-domain triad — sweeps every
16118 /// `(pre_kind, post_kind, query)` arrangement of a
16119 /// single-condition-per-side spec, asserts each per-slice arm
16120 /// delegates verbatim to
16121 /// [`crate::boundary::ConditionSliceExt::position_of_kind`], and
16122 /// pins the union arm against the `or_else` composition of the
16123 /// two half-slice arms. Also asserts two-surface parity — the
16124 /// lowered [`Boundary`]'s triad yields the SAME `Option<usize>`
16125 /// on every arm.
16126 #[test]
16127 fn position_of_condition_kind_triad_delegates_to_slice_position_of_kind() {
16128 use crate::boundary::ConditionSliceExt as _;
16129
16130 // Empty ephemeral — every arm returns None on every kind.
16131 let spec = empty_ephemeral();
16132 for kind in ConditionKind::ALL {
16133 assert!(
16134 spec.position_of_precondition_kind(kind).is_none(),
16135 "empty ephemeral position_of_precondition_kind({kind:?}) must be None",
16136 );
16137 assert!(
16138 spec.position_of_postcondition_kind(kind).is_none(),
16139 "empty ephemeral position_of_postcondition_kind({kind:?}) must be None",
16140 );
16141 assert!(
16142 spec.position_of_condition_kind(kind).is_none(),
16143 "empty ephemeral position_of_condition_kind({kind:?}) must be None",
16144 );
16145 }
16146
16147 // Single-populated-per-side sweep with two-surface parity.
16148 for pre_kind in ConditionKind::ALL {
16149 for post_kind in ConditionKind::ALL {
16150 let mut spec = empty_ephemeral();
16151 spec.preconditions.push(cond(pre_kind));
16152 spec.postconditions.push(cond(post_kind));
16153
16154 let lowered: ProcessSpec = spec.clone().into();
16155 let boundary = &lowered.boundary;
16156
16157 for query in ConditionKind::ALL {
16158 // Per-side delegation pins.
16159 assert_eq!(
16160 spec.position_of_precondition_kind(query),
16161 spec.preconditions.position_of_kind(query),
16162 "EphemeralSpec::position_of_precondition_kind must delegate verbatim to \
16163 preconditions.position_of_kind for pre={pre_kind:?} post={post_kind:?} \
16164 query={query:?}",
16165 );
16166 assert_eq!(
16167 spec.position_of_postcondition_kind(query),
16168 spec.postconditions.position_of_kind(query),
16169 "EphemeralSpec::position_of_postcondition_kind must delegate verbatim to \
16170 postconditions.position_of_kind for pre={pre_kind:?} post={post_kind:?} \
16171 query={query:?}",
16172 );
16173
16174 // Union-arm composition-law pin — or_else of the
16175 // two half-slice arms.
16176 let union = spec.position_of_condition_kind(query);
16177 let via_or_else = spec
16178 .position_of_precondition_kind(query)
16179 .or_else(|| spec.position_of_postcondition_kind(query));
16180 assert_eq!(
16181 union, via_or_else,
16182 "position_of_condition_kind({query:?}) must equal the or_else of the \
16183 two half-slice arms for pre={pre_kind:?} post={post_kind:?}",
16184 );
16185 assert_eq!(
16186 union.is_some(),
16187 spec.has_condition_kind(query),
16188 "position_of_condition_kind({query:?}).is_some() drifted from \
16189 has_condition_kind for pre={pre_kind:?} post={post_kind:?}",
16190 );
16191
16192 // Two-surface parity — lowered Boundary agrees on
16193 // every arm.
16194 assert_eq!(
16195 spec.position_of_precondition_kind(query),
16196 boundary.position_of_precondition_kind(query),
16197 "ephemeral position_of_precondition_kind({query:?}) drifted from lowered \
16198 Boundary for pre={pre_kind:?} post={post_kind:?}",
16199 );
16200 assert_eq!(
16201 spec.position_of_postcondition_kind(query),
16202 boundary.position_of_postcondition_kind(query),
16203 "ephemeral position_of_postcondition_kind({query:?}) drifted from \
16204 lowered Boundary for pre={pre_kind:?} post={post_kind:?}",
16205 );
16206 assert_eq!(
16207 spec.position_of_condition_kind(query),
16208 boundary.position_of_condition_kind(query),
16209 "ephemeral position_of_condition_kind({query:?}) drifted from lowered \
16210 Boundary for pre={pre_kind:?} post={post_kind:?}",
16211 );
16212 }
16213 }
16214 }
16215
16216 // Doubled-post sweep — position_of_kind returns index 0 of
16217 // the postconditions slice; union arm equals the postcondition
16218 // arm because preconditions is empty.
16219 for doubled in ConditionKind::ALL {
16220 let mut spec = empty_ephemeral();
16221 spec.postconditions.push(cond(doubled));
16222 spec.postconditions.push(cond(doubled));
16223 assert_eq!(
16224 spec.position_of_postcondition_kind(doubled),
16225 Some(0),
16226 "doubled-post position_of_postcondition_kind({doubled:?}) must equal Some(0)",
16227 );
16228 assert_eq!(
16229 spec.position_of_condition_kind(doubled),
16230 Some(0),
16231 "doubled-post position_of_condition_kind({doubled:?}) must fall through to \
16232 postconditions and yield Some(0)",
16233 );
16234 }
16235 }
16236}